diff --git a/ui/src/app/metadata/configuration/component/metadata-configuration.component.spec.ts b/ui/src/app/metadata/configuration/component/metadata-configuration.component.spec.ts
index c17a469af..3feb146b5 100644
--- a/ui/src/app/metadata/configuration/component/metadata-configuration.component.spec.ts
+++ b/ui/src/app/metadata/configuration/component/metadata-configuration.component.spec.ts
@@ -66,10 +66,10 @@ describe('Metadata Configuration Component', () => {
}));
describe('edit method', () => {
- it('should call router.navigate', () => {
- spyOn(router, 'navigate');
+ it('should call onEdit.emit', () => {
+ spyOn(app.onEdit, 'emit');
app.edit('foo');
- expect(router.navigate).toHaveBeenCalled();
+ expect(app.onEdit.emit).toHaveBeenCalled();
});
});
diff --git a/ui/src/app/metadata/configuration/reducer/index.spec.ts b/ui/src/app/metadata/configuration/reducer/index.spec.ts
index 8a1aa3cb7..d9dff5a83 100644
--- a/ui/src/app/metadata/configuration/reducer/index.spec.ts
+++ b/ui/src/app/metadata/configuration/reducer/index.spec.ts
@@ -1,143 +1,31 @@
import {
- getConfigurationSectionsFn,
getConfigurationModelNameFn,
getConfigurationModelEnabledFn,
- assignValueToProperties,
- getLimitedPropertiesFn,
getConfigurationModelTypeFn,
getSelectedVersionNumberFn,
getSelectedIsCurrentFn
} from './index';
-import { SCHEMA as schema } from '../../../../testing/form-schema.stub';
+
import { Metadata } from '../../domain/domain.type';
-import { MockMetadataWizard } from '../../../../testing/mockMetadataWizard';
describe('Configuration Reducer', () => {
- const model = {
- name: 'foo',
- serviceEnabled: true,
- foo: {
- bar: 'bar',
- baz: 'baz'
- },
- list: [
- 'super',
- 'cool'
- ]
- };
-
- const props = [
- {
- id: 'name',
- items: null,
- name: 'label.metadata-provider-name-dashboard-display-only',
- properties: [],
- type: 'string',
- value: null,
- widget: { id: 'string', help: 'message.must-be-unique' }
- },
- {
- id: 'serviceEnabled',
- items: null,
- name: 'serviceEnabled',
- properties: [],
- type: 'string',
- value: null,
- widget: { id: 'select', disabled: true }
- },
- {
- id: 'foo',
- items: null,
- name: 'foo',
- type: 'object',
- properties: [
- {
- id: 'bar',
- name: 'bar',
- type: 'string',
- properties: []
- },
- {
- id: 'baz',
- name: 'baz',
- type: 'string',
- properties: []
- }
- ]
- },
- {
- id: 'list',
- name: 'list',
- type: 'array',
- items: {
- type: 'string'
- },
- widget: {
- id: 'datalist',
- data: [
- { key: 'super', label: 'super' },
- { key: 'cool', label: 'cool' },
- { key: 'notcool', label: 'notcool' }
- ]
- }
- }
- ];
-
- const definition = MockMetadataWizard;
-
- describe('getConfigurationSectionsFn', () => {
- it('should parse the schema, definition, and model into a MetadataConfiguration', () => {
- const config = getConfigurationSectionsFn([model], definition, schema);
- expect(config.sections).toBeDefined();
- });
- });
describe('getConfigurationModelNameFn function', () => {
it('should return the name attribute', () => {
expect(getConfigurationModelNameFn({ serviceProviderName: 'foo' } as Metadata)).toBe('foo');
expect(getConfigurationModelNameFn({ name: 'bar' } as Metadata)).toBe('bar');
- expect(getConfigurationModelNameFn(null)).toBe(false);
+ expect(getConfigurationModelNameFn(null)).toBe('');
});
});
describe('getConfigurationModelEnabledFn function', () => {
- it('should return the name attribute', () => {
+ it('should return the enabled attribute', () => {
expect(getConfigurationModelEnabledFn({ serviceEnabled: true } as Metadata)).toBe(true);
expect(getConfigurationModelEnabledFn({ enabled: true } as Metadata)).toBe(true);
expect(getConfigurationModelEnabledFn(null)).toBe(false);
});
});
- describe('assignValueToProperties function', () => {
- it('should assign appropriate values to the given schema properties', () => {
- const assigned = assignValueToProperties([model], props, definition);
- expect(assigned[0].value).toEqual(['foo']);
- expect(assigned[1].value).toEqual([true]);
- });
-
- it('should assign differences when passed multiple models', () => {
- const assigned = assignValueToProperties([model, {
- ...model,
- name: 'bar',
- list: [
- 'super',
- 'notcool'
- ]
- }], props, definition);
- expect(assigned[0].differences).toBe(true);
- });
- });
-
- describe('getLimitedPropertiesFn function', () => {
- it('should filter properties without differences', () => {
- const assigned = assignValueToProperties([model, {
- ...model,
- name: 'bar'
- }], props, definition);
- expect(getLimitedPropertiesFn(assigned).length).toBe(1);
- });
- });
-
describe('getConfigurationModelTypeFn function ', () => {
it('should return provider type if the object has an @type property', () => {
const md = { '@type': 'FilebackedHttpMetadataResolver' } as Metadata;
diff --git a/ui/src/app/metadata/configuration/reducer/index.ts b/ui/src/app/metadata/configuration/reducer/index.ts
index 1053ada29..58e92562f 100644
--- a/ui/src/app/metadata/configuration/reducer/index.ts
+++ b/ui/src/app/metadata/configuration/reducer/index.ts
@@ -8,15 +8,13 @@ import * as fromVersion from './version.reducer';
import * as fromRestore from './restore.reducer';
import * as fromFilter from './filter.reducer';
-import * as utils from '../../domain/utility/configuration';
-import { getConfigurationSectionsFn } from './utilities';
+import { getConfigurationSectionsFn, getLimitedPropertiesFn } from './utilities';
import { getModel } from '../../../wizard/reducer';
import { getInCollectionFn } from '../../domain/domain.util';
import { Metadata } from '../../domain/domain.type';
import * as fromResolver from '../../resolver/reducer';
import * as fromProvider from '../../provider/reducer';
-import { SectionProperty } from '../model/section';
export interface ConfigurationState {
configuration: fromConfiguration.State;
@@ -136,26 +134,6 @@ export const getComparisonConfigurationCount = createSelector(getComparisonConfi
export const getViewChangedOnly = createSelector(getCompareState, fromCompare.getViewChangedOnly);
-export const getLimitedPropertiesFn = (properties: SectionProperty[]) => {
- return ([
- ...properties
- .filter(p => p.differences)
- .map(p => {
- const parsed = { ...p };
- if (p.widget && p.widget.data) {
- parsed.widget = {
- ...p.widget,
- data: p.widget.data.filter(item => item.differences)
- };
- }
- if (p.properties) {
- parsed.properties = getLimitedPropertiesFn(p.properties);
- }
- return parsed;
- })
- ]);
-};
-
export const getLimitedConfigurationsFn = (configurations, limited) => configurations ? ({
...configurations,
sections: limited ? configurations.sections :
diff --git a/ui/src/app/metadata/configuration/reducer/utilities.spec.ts b/ui/src/app/metadata/configuration/reducer/utilities.spec.ts
new file mode 100644
index 000000000..0d8234bb5
--- /dev/null
+++ b/ui/src/app/metadata/configuration/reducer/utilities.spec.ts
@@ -0,0 +1,120 @@
+import {
+ getConfigurationSectionsFn,
+ getLimitedPropertiesFn,
+ assignValueToProperties
+} from './utilities';
+
+import { SCHEMA as schema } from '../../../../testing/form-schema.stub';
+import { MockMetadataWizard } from '../../../../testing/mockMetadataWizard';
+
+describe('config reducer utilities', () => {
+
+ const model = {
+ name: 'foo',
+ serviceEnabled: true,
+ foo: {
+ bar: 'bar',
+ baz: 'baz'
+ },
+ list: [
+ 'super',
+ 'cool'
+ ]
+ };
+
+ const props = [
+ {
+ id: 'name',
+ items: null,
+ name: 'label.metadata-provider-name-dashboard-display-only',
+ properties: [],
+ type: 'string',
+ value: null,
+ widget: { id: 'string', help: 'message.must-be-unique' }
+ },
+ {
+ id: 'serviceEnabled',
+ items: null,
+ name: 'serviceEnabled',
+ properties: [],
+ type: 'string',
+ value: null,
+ widget: { id: 'select', disabled: true }
+ },
+ {
+ id: 'foo',
+ items: null,
+ name: 'foo',
+ type: 'object',
+ properties: [
+ {
+ id: 'bar',
+ name: 'bar',
+ type: 'string',
+ properties: []
+ },
+ {
+ id: 'baz',
+ name: 'baz',
+ type: 'string',
+ properties: []
+ }
+ ]
+ },
+ {
+ id: 'list',
+ name: 'list',
+ type: 'array',
+ items: {
+ type: 'string'
+ },
+ widget: {
+ id: 'datalist',
+ data: [
+ { key: 'super', label: 'super' },
+ { key: 'cool', label: 'cool' },
+ { key: 'notcool', label: 'notcool' }
+ ]
+ }
+ }
+ ];
+
+ const definition = MockMetadataWizard;
+
+ describe('assignValueToProperties function', () => {
+ it('should assign appropriate values to the given schema properties', () => {
+ const assigned = assignValueToProperties([model], props, definition);
+ expect(assigned[0].value).toEqual(['foo']);
+ expect(assigned[1].value).toEqual([true]);
+ });
+
+ it('should assign differences when passed multiple models', () => {
+ const assigned = assignValueToProperties([model, {
+ ...model,
+ name: 'bar',
+ list: [
+ 'super',
+ 'notcool'
+ ]
+ }], props, definition);
+ expect(assigned[0].differences).toBe(true);
+ });
+ });
+
+ describe('getLimitedPropertiesFn function', () => {
+ it('should filter properties without differences', () => {
+ const assigned = assignValueToProperties([model, {
+ ...model,
+ name: 'bar'
+ }], props, definition);
+ expect(getLimitedPropertiesFn(assigned).length).toBe(1);
+ });
+ });
+
+ describe('getConfigurationSectionsFn', () => {
+ it('should parse the schema, definition, and model into a MetadataConfiguration', () => {
+ const config = getConfigurationSectionsFn([model], definition, schema);
+ expect(config.sections).toBeDefined();
+ });
+ });
+});
diff --git a/ui/src/app/metadata/configuration/reducer/utilities.ts b/ui/src/app/metadata/configuration/reducer/utilities.ts
index 16668a027..f2481e99c 100644
--- a/ui/src/app/metadata/configuration/reducer/utilities.ts
+++ b/ui/src/app/metadata/configuration/reducer/utilities.ts
@@ -2,6 +2,7 @@ import { MetadataConfiguration } from '../model/metadata-configuration';
import { WizardStep } from '../../../wizard/model';
import * as utils from '../../domain/utility/configuration';
import { getSplitSchema } from '../../../wizard/reducer';
+import { SectionProperty } from '../model/section';
export const getConfigurationSectionsFn = (models, definition, schema): MetadataConfiguration => {
return !definition || !schema || !models ? null :
@@ -82,3 +83,23 @@ export const assignValueToProperties = (models, properties, definition: any): an
}
});
};
+
+export const getLimitedPropertiesFn = (properties: SectionProperty[]) => {
+ return ([
+ ...properties
+ .filter(p => p.differences)
+ .map(p => {
+ const parsed = { ...p };
+ if (p.widget && p.widget.data) {
+ parsed.widget = {
+ ...p.widget,
+ data: p.widget.data.filter(item => item.differences)
+ };
+ }
+ if (p.properties) {
+ parsed.properties = getLimitedPropertiesFn(p.properties);
+ }
+ return parsed;
+ })
+ ]);
+};
\ No newline at end of file
diff --git a/ui/src/app/metadata/configuration/service/configuration.service.spec.ts b/ui/src/app/metadata/configuration/service/configuration.service.spec.ts
index 43fd99c05..e191471a0 100644
--- a/ui/src/app/metadata/configuration/service/configuration.service.spec.ts
+++ b/ui/src/app/metadata/configuration/service/configuration.service.spec.ts
@@ -9,7 +9,7 @@ import { of } from 'rxjs';
import { MetadataProviderService } from '../../domain/service/provider.service';
import { Metadata } from '../../domain/domain.type';
import { SCHEMA } from '../../../../testing/form-schema.stub';
-import { getConfigurationSectionsFn } from '../reducer';
+import { getConfigurationSectionsFn } from '../reducer/utilities';
describe(`Configuration Service`, () => {
diff --git a/ui/src/app/metadata/domain/component/wizard-summary.component.html b/ui/src/app/metadata/domain/component/wizard-summary.component.html
new file mode 100644
index 000000000..349f7cb74
--- /dev/null
+++ b/ui/src/app/metadata/domain/component/wizard-summary.component.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ui/src/app/metadata/domain/component/wizard-summary.component.spec.ts b/ui/src/app/metadata/domain/component/wizard-summary.component.spec.ts
new file mode 100644
index 000000000..43712bd48
--- /dev/null
+++ b/ui/src/app/metadata/domain/component/wizard-summary.component.spec.ts
@@ -0,0 +1,103 @@
+import { Component, ViewChild } from '@angular/core';
+import { TestBed, async, ComponentFixture } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbDropdownModule, NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { WizardSummaryComponent } from './wizard-summary.component';
+import { SchemaFormModule, WidgetRegistry, DefaultWidgetRegistry } from 'ngx-schema-form';
+import { Wizard } from '../../../wizard/model';
+import { MetadataProvider } from '../../domain/model';
+import { SummaryPropertyComponent } from './summary-property.component';
+import { SCHEMA } from '../../../../testing/form-schema.stub';
+import { MockI18nModule } from '../../../../testing/i18n.stub';
+import { MetadataProviderWizard } from '../../provider/model';
+import { AttributesService } from '../service/attributes.service';
+import { MockAttributeService } from '../../../../testing/attributes.stub';
+
+@Component({
+ template: `
+
+ `
+})
+class TestHostComponent {
+ @ViewChild(WizardSummaryComponent)
+ public componentUnderTest: WizardSummaryComponent;
+
+ private _summary;
+
+ get summary(): { definition: Wizard, schema: { [id: string]: any }, model: any } {
+ return this._summary;
+ }
+
+ set summary(summary: { definition: Wizard, schema: { [id: string]: any }, model: any }) {
+ this._summary = summary;
+ }
+}
+
+describe('Wizard Summary Component', () => {
+
+ let fixture: ComponentFixture;
+ let instance: TestHostComponent;
+ let app: WizardSummaryComponent;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ NgbDropdownModule,
+ NgbPopoverModule,
+ RouterTestingModule,
+ SchemaFormModule.forRoot(),
+ MockI18nModule
+ ],
+ declarations: [
+ WizardSummaryComponent,
+ SummaryPropertyComponent,
+ TestHostComponent
+ ],
+ providers: [
+ { provide: WidgetRegistry, useClass: DefaultWidgetRegistry },
+ { provide: AttributesService, useClass: MockAttributeService }
+ ]
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(TestHostComponent);
+ instance = fixture.componentInstance;
+ app = instance.componentUnderTest;
+ fixture.detectChanges();
+ }));
+
+ it('should instantiate the component', async(() => {
+ expect(app).toBeTruthy();
+ }));
+
+ describe('gotoPage function', () => {
+ it('should emit an empty string if page is null', () => {
+ spyOn(app.onPageSelect, 'emit');
+ app.gotoPage();
+ expect(app.onPageSelect.emit).toHaveBeenCalledWith('');
+ });
+
+ it('should emit the provided page', () => {
+ spyOn(app.onPageSelect, 'emit');
+ app.gotoPage('foo');
+ expect(app.onPageSelect.emit).toHaveBeenCalledWith('foo');
+ });
+ });
+
+ describe('ngOnChanges', () => {
+ it('should set columns and sections if summary is provided', () => {
+ instance.summary = {
+ model: {
+ name: 'foo',
+ '@type': 'MetadataProvider'
+ },
+ schema: SCHEMA,
+ definition: MetadataProviderWizard
+ };
+ fixture.detectChanges();
+ expect(app.sections).toBeDefined();
+ expect(app.columns).toBeDefined();
+ });
+ });
+});
diff --git a/ui/src/app/metadata/domain/component/wizard-summary.component.ts b/ui/src/app/metadata/domain/component/wizard-summary.component.ts
new file mode 100644
index 000000000..73a701491
--- /dev/null
+++ b/ui/src/app/metadata/domain/component/wizard-summary.component.ts
@@ -0,0 +1,80 @@
+import { Component, Input, SimpleChanges, OnChanges, Output, EventEmitter } from '@angular/core';
+
+import { Wizard, WizardStep } from '../../../wizard/model';
+import { MetadataProvider, MetadataResolver } from '../../domain/model';
+import { Property } from '../model/property';
+import { getSplitSchema } from '../../../wizard/reducer';
+import { getStepProperties } from '../utility/configuration';
+
+interface Section {
+ id: string;
+ index: number;
+ label: string;
+ pageNumber: number;
+ properties: Property[];
+}
+
+@Component({
+ selector: 'wizard-summary',
+ templateUrl: './wizard-summary.component.html',
+ styleUrls: []
+})
+
+export class WizardSummaryComponent implements OnChanges {
+ @Input() summary: { definition: Wizard, schema: { [id: string]: any }, model: any };
+
+ @Output() onPageSelect: EventEmitter = new EventEmitter();
+
+ sections: Section[];
+ columns: Array[];
+ steps: WizardStep[];
+
+ constructor() { }
+
+ ngOnChanges(changes: SimpleChanges): void {
+ if (changes.summary && this.summary) {
+ const schema = this.summary.schema;
+ const model = this.summary.model;
+ const def = this.summary.definition;
+ const steps = def.steps;
+
+ this.sections = steps
+ .filter(step => step.id !== 'summary')
+ .map(
+ (step: WizardStep, num: number) => {
+ const { id, index, label } = step;
+ const split = getSplitSchema(schema, step);
+ const properties = getStepProperties(
+ split,
+ def.formatter(model),
+ schema.definitions || {}
+ );
+ return ({
+ id,
+ pageNumber: num + 1,
+ index,
+ label,
+ properties
+ });
+ }
+ );
+
+ this.columns = this.sections.reduce((resultArray, item, index) => {
+ const chunkIndex = Math.floor(index / Math.round(this.sections.length / 2));
+
+ if (!resultArray[chunkIndex]) {
+ resultArray[chunkIndex] = [];
+ }
+
+ resultArray[chunkIndex].push(item);
+
+ return resultArray;
+ }, []);
+ }
+ }
+
+ gotoPage(page: string = ''): void {
+ this.onPageSelect.emit(page);
+ }
+}
+
diff --git a/ui/src/app/metadata/domain/domain.module.ts b/ui/src/app/metadata/domain/domain.module.ts
index b109734a6..49e1fe685 100644
--- a/ui/src/app/metadata/domain/domain.module.ts
+++ b/ui/src/app/metadata/domain/domain.module.ts
@@ -22,8 +22,10 @@ import { UnsavedEntityComponent } from './component/unsaved-entity.dialog';
import { EditorNavComponent } from './component/editor-nav.component';
import { RouterModule } from '@angular/router';
import { SharedModule } from '../../shared/shared.module';
+import { WizardSummaryComponent } from './component/wizard-summary.component';
export const COMPONENTS = [
+ WizardSummaryComponent,
PreviewDialogComponent,
UnsavedEntityComponent,
SummaryPropertyComponent,
diff --git a/ui/src/app/metadata/provider/model/dynamic-http.provider.form.spec.ts b/ui/src/app/metadata/provider/model/dynamic-http.provider.form.spec.ts
index bafe25f4b..f561b4e99 100644
--- a/ui/src/app/metadata/provider/model/dynamic-http.provider.form.spec.ts
+++ b/ui/src/app/metadata/provider/model/dynamic-http.provider.form.spec.ts
@@ -1,5 +1,51 @@
import { DynamicHttpMetadataProviderWizard } from './dynamic-http.provider.form';
+const schema = {
+ 'type': 'object',
+ 'required': [
+ '@type',
+ 'content'
+ ],
+ 'properties': {
+ '@type': {
+ 'title': 'label.md-request-type',
+ 'description': 'tooltip.md-request-type',
+ 'type': 'string',
+ 'widget': {
+ 'id': 'select'
+ },
+ 'oneOf': [
+ {
+ 'enum': [
+ 'MetadataQueryProtocol'
+ ],
+ 'description': 'value.md-query-protocol'
+ },
+ {
+ 'enum': [
+ 'Regex'
+ ],
+ 'description': 'value.regex'
+ }
+ ]
+ },
+ 'content': {
+ 'title': 'label.md-request-value',
+ 'description': 'tooltip.md-request-value',
+ 'type': 'string'
+ },
+ 'match': {
+ 'title': 'label.match',
+ 'description': 'tooltip.match',
+ 'type': 'string',
+ 'visibleIf': {
+ '@type': [
+ 'Regex'
+ ]
+ }
+ }
+ }
+};
describe('DynamicHttpMetadataProviderWizard', () => {
@@ -122,4 +168,43 @@ describe('DynamicHttpMetadataProviderWizard', () => {
]);
});
});
+
+ describe('validators', () => {
+ let validators,
+ metadataRequestURLConstructionScheme,
+ metadataRequestURLConstructionSchemeContent,
+ metadataRequestURLConstructionSchemeType,
+ metadataRequestURLConstructionSchemeMatch;
+
+ beforeEach(() => {
+ validators = getValidators([], []);
+ });
+
+ describe('metadataRequestURLConstructionScheme', () => {
+ it('should check other validators and propagate those errors up', () => {
+ const value = {
+ content: null,
+ '@type': null,
+ match: 'foo'
+ };
+ const property = { value, schema, properties: null };
+ property.properties = {
+ content: {
+ path: 'content',
+ parent: property
+ },
+ '@type': {
+ path: '@type',
+ parent: property
+ },
+ match: {
+ path: 'match',
+ parent: property
+ }
+ };
+ const validator = validators['/metadataRequestURLConstructionScheme'];
+ expect(validator(value, property, null).length).toBe(2);
+ });
+ });
+ });
});
diff --git a/ui/src/app/metadata/provider/model/utilities.spec.ts b/ui/src/app/metadata/provider/model/utilities.spec.ts
new file mode 100644
index 000000000..5affea1ae
--- /dev/null
+++ b/ui/src/app/metadata/provider/model/utilities.spec.ts
@@ -0,0 +1,33 @@
+import { metadataFilterProcessor } from './utilities';
+
+describe('provider model utilities', () => {
+ describe('metadata filter processor function', () => {
+ it('should return null if no schema provided', () => {
+ expect(metadataFilterProcessor(null)).toBe(null);
+ });
+
+ it('should return the schema if no properties are detected', () => {
+ const schema = {};
+ expect(metadataFilterProcessor(schema)).toBe(schema);
+ });
+
+ it('should return the schema if no metadataFilters property exists in the schema', () => {
+ const schema = { properties: { foo: 'bar' } };
+ expect(metadataFilterProcessor(schema)).toBe(schema);
+ });
+
+ it('should turn the filters into an object if provided ', () => {
+ const schema = { properties: { metadataFilters: {
+ type: 'array',
+ items: [
+ {
+ $id: 'foo',
+ type: 'string'
+ }
+ ]
+ } } };
+ const processed = metadataFilterProcessor(schema);
+ expect(processed.properties.metadataFilters.properties.foo.type).toBe('string');
+ });
+ });
+});
diff --git a/ui/src/app/metadata/provider/model/utilities.ts b/ui/src/app/metadata/provider/model/utilities.ts
index aea90bc21..dc415bae1 100644
--- a/ui/src/app/metadata/provider/model/utilities.ts
+++ b/ui/src/app/metadata/provider/model/utilities.ts
@@ -1,5 +1,4 @@
export const metadataFilterProcessor = (schema) => {
- console.log(schema);
if (!schema) {
return null;
}
@@ -20,6 +19,5 @@ export const metadataFilterProcessor = (schema) => {
}
}
});
- console.log(processed);
return processed;
};
diff --git a/ui/src/app/metadata/resolver/container/resolver-wizard.component.spec.ts b/ui/src/app/metadata/resolver/container/resolver-wizard.component.spec.ts
index 3cec9bf25..58191efeb 100644
--- a/ui/src/app/metadata/resolver/container/resolver-wizard.component.spec.ts
+++ b/ui/src/app/metadata/resolver/container/resolver-wizard.component.spec.ts
@@ -2,7 +2,7 @@ import { Component, ViewChild } from '@angular/core';
import { TestBed, async, ComponentFixture } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { StoreModule, Store, combineReducers } from '@ngrx/store';
-import { RouterStateSnapshot, ActivatedRouteSnapshot } from '@angular/router';
+import { RouterStateSnapshot } from '@angular/router';
import { NgbDropdownModule, NgbPopoverModule, NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { of } from 'rxjs';
@@ -18,6 +18,7 @@ import { MockWizardModule } from '../../../../testing/wizard.stub';
import { NgbModalStub } from '../../../../testing/modal.stub';
import { MetadataResolver } from '../../domain/model';
import { DifferentialService } from '../../../core/service/differential.service';
+import { MetadataConfigurationComponentStub } from '../../../../testing/metadata-configuration.stub';
@Component({
template: `
@@ -85,7 +86,8 @@ describe('Resolver Wizard Component', () => {
],
declarations: [
ResolverWizardComponent,
- TestHostComponent
+ TestHostComponent,
+ MetadataConfigurationComponentStub
],
providers: [
DifferentialService,
diff --git a/ui/src/app/wizard/reducer/index.ts b/ui/src/app/wizard/reducer/index.ts
index 027ac1673..255710be0 100644
--- a/ui/src/app/wizard/reducer/index.ts
+++ b/ui/src/app/wizard/reducer/index.ts
@@ -129,7 +129,7 @@ export const getSchemaLockedFn = (step, locked) => step ? step.locked ? locked :
export const getLocked = createSelector(getCurrent, getLockedStatus, getSchemaLockedFn);
export const getSchemaProcessedFn = (schema, definition) =>
- definition.schemaPreprocessor ? definition.schemaPreprocessor(schema) : schema;
+ definition && definition.schemaPreprocessor ? definition.schemaPreprocessor(schema) : schema;
export const getSchemaObject = createSelector(getState, fromWizard.getSchema);
export const getProcessedSchema = createSelector(getSchemaObject, getWizardDefinition, getSchemaProcessedFn);