diff --git a/ui/src/app/metadata/configuration/component/array-property.component.spec.ts b/ui/src/app/metadata/configuration/component/array-property.component.spec.ts
new file mode 100644
index 000000000..453d9d484
--- /dev/null
+++ b/ui/src/app/metadata/configuration/component/array-property.component.spec.ts
@@ -0,0 +1,115 @@
+import { Component, ViewChild, Input } 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 { Property } from '../../domain/model/property';
+import { MockI18nModule } from '../../../../testing/i18n.stub';
+import { SCHEMA } from '../../../../testing/form-schema.stub';
+import { getStepProperty } from '../../domain/utility/configuration';
+import { ArrayPropertyComponent } from './array-property.component';
+import { AttributesService } from '../../domain/service/attributes.service';
+import { MockAttributeService } from '../../../../testing/attributes.stub';
+import { of } from 'rxjs';
+
+@Component({
+ template: `
+
+ `
+})
+class TestHostComponent {
+ @ViewChild(ArrayPropertyComponent)
+ public componentUnderTest: ArrayPropertyComponent;
+
+ property: Property = getStepProperty(SCHEMA.properties.list, {
+ name: 'foo',
+ type: 'baz',
+ description: 'foo bar baz',
+ list: []
+ }, SCHEMA.definitions);
+
+ setProperty(property: Property): void {
+ this.property = property;
+ }
+}
+
+describe('Array Property Component', () => {
+
+ let fixture: ComponentFixture;
+ let instance: TestHostComponent;
+ let app: ArrayPropertyComponent;
+ let service: AttributesService;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ NgbPopoverModule,
+ MockI18nModule,
+ RouterTestingModule
+ ],
+ declarations: [
+ ArrayPropertyComponent,
+ TestHostComponent
+ ],
+ providers: [
+ { provide: AttributesService, useClass: MockAttributeService }
+ ]
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(TestHostComponent);
+ instance = fixture.componentInstance;
+ app = instance.componentUnderTest;
+ service = TestBed.get(AttributesService);
+ fixture.detectChanges();
+ }));
+
+ it('should accept a property input', async(() => {
+ expect(app).toBeTruthy();
+ }));
+
+ describe('attributeList$ getter', () => {
+ it('should return an empty list when no data or dataUrl is set', () => {
+ app.attributeList$.subscribe((list) => {
+ expect(list).toEqual([]);
+ });
+ });
+ it('should return a list of data items from the schema', () => {
+ const datalist = [
+ { key: 'foo', label: 'foo' },
+ { key: 'bar', label: 'bar' },
+ { key: 'baz', label: 'baz' },
+ ];
+ instance.setProperty({
+ ...instance.property,
+ widget: {
+ id: 'datalist',
+ data: datalist
+ }
+ });
+ fixture.detectChanges();
+ app.attributeList$.subscribe(list => {
+ expect(list).toEqual(datalist);
+ });
+ });
+
+ it('should call the attribute service with a provided dataUrl', () => {
+ const datalist = [
+ { key: 'foo', label: 'foo' },
+ { key: 'bar', label: 'bar' },
+ { key: 'baz', label: 'baz' },
+ ];
+ spyOn(service, 'query').and.returnValue(of(datalist));
+ instance.setProperty({
+ ...instance.property,
+ widget: {
+ id: 'datalist',
+ dataUrl: '/foo'
+ }
+ });
+ fixture.detectChanges();
+ app.attributeList$.subscribe(list => {
+ expect(list).toEqual(datalist);
+ });
+ });
+ });
+});
diff --git a/ui/src/app/metadata/configuration/component/array-property.component.ts b/ui/src/app/metadata/configuration/component/array-property.component.ts
index 77c8fcab0..ff9cd0ac4 100644
--- a/ui/src/app/metadata/configuration/component/array-property.component.ts
+++ b/ui/src/app/metadata/configuration/component/array-property.component.ts
@@ -19,10 +19,6 @@ export class ArrayPropertyComponent extends ConfigurationPropertyComponent {
super();
}
- getKeys(schema): string[] {
- return Object.keys(schema.properties);
- }
-
get attributeList$(): Observable<{ key: string, label: string }[]> {
if (this.property.widget && this.property.widget.hasOwnProperty('data')) {
return of(this.property.widget.data);
diff --git a/ui/src/app/metadata/configuration/component/configuration-property.component.spec.ts b/ui/src/app/metadata/configuration/component/configuration-property.component.spec.ts
new file mode 100644
index 000000000..5ef0452e0
--- /dev/null
+++ b/ui/src/app/metadata/configuration/component/configuration-property.component.spec.ts
@@ -0,0 +1,69 @@
+import { Component, ViewChild, Input } 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 { Property } from '../../domain/model/property';
+import { MockI18nModule } from '../../../../testing/i18n.stub';
+import { SCHEMA } from '../../../../testing/form-schema.stub';
+import { getStepProperties, getStepProperty } from '../../domain/utility/configuration';
+import { ConfigurationPropertyComponent } from './configuration-property.component';
+
+@Component({
+ template: `
+
+ `
+})
+class TestHostComponent {
+ @ViewChild(ConfigurationPropertyComponent)
+ public componentUnderTest: ConfigurationPropertyComponent;
+
+ property: Property = getStepProperty(SCHEMA.properties.name, {
+ name: 'foo',
+ type: 'baz',
+ description: 'foo bar baz'
+ }, SCHEMA.definitions);
+}
+
+describe('Configuration Property Component', () => {
+
+ let fixture: ComponentFixture;
+ let instance: TestHostComponent;
+ let app: ConfigurationPropertyComponent;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ NgbPopoverModule,
+ MockI18nModule,
+ RouterTestingModule
+ ],
+ declarations: [
+ ConfigurationPropertyComponent,
+ TestHostComponent
+ ]
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(TestHostComponent);
+ instance = fixture.componentInstance;
+ app = instance.componentUnderTest;
+ fixture.detectChanges();
+ }));
+
+ it('should accept a property input', async(() => {
+ expect(app).toBeTruthy();
+ }));
+
+ describe('getKeys method', () => {
+ it('should return the property`s child keys', () => {
+ expect(app.getKeys({ properties: { foo: 'bar', baz: 'bar' } })).toEqual(['foo', 'baz']);
+ });
+ });
+
+ describe('getItemType method', () => {
+ it('should return the item`s type', () => {
+ expect(app.getItemType({ widget: { id: 'string' } } as Property)).toBe('string');
+ expect(app.getItemType({} as Property)).toBe('default');
+ });
+ });
+});
diff --git a/ui/src/app/metadata/configuration/component/configuration-property.component.ts b/ui/src/app/metadata/configuration/component/configuration-property.component.ts
index 91e97e87b..bcdd45711 100644
--- a/ui/src/app/metadata/configuration/component/configuration-property.component.ts
+++ b/ui/src/app/metadata/configuration/component/configuration-property.component.ts
@@ -3,7 +3,7 @@ import { Property } from '../../domain/model/property';
@Component({
selector: 'configuration-property',
- templateUrl: './configuration-property.component.html',
+ template: `{{ property | json }}`,
styleUrls: []
})
@@ -12,6 +12,10 @@ export class ConfigurationPropertyComponent {
constructor() { }
+ getKeys(schema): string[] {
+ return Object.keys(schema.properties);
+ }
+
getItemType(items: Property): string {
return items.widget ? items.widget.id : 'default';
}
diff --git a/ui/src/app/metadata/configuration/component/object-property.component.spec.ts b/ui/src/app/metadata/configuration/component/object-property.component.spec.ts
new file mode 100644
index 000000000..6299b20d5
--- /dev/null
+++ b/ui/src/app/metadata/configuration/component/object-property.component.spec.ts
@@ -0,0 +1,60 @@
+import { Component, ViewChild, Input } 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 { Property } from '../../domain/model/property';
+import { MockI18nModule } from '../../../../testing/i18n.stub';
+import { ObjectPropertyComponent } from './object-property.component';
+import { SCHEMA } from '../../../../testing/form-schema.stub';
+import { getStepProperties, getStepProperty } from '../../domain/utility/configuration';
+import { PrimitivePropertyComponent } from './primitive-property.component';
+import { ArrayPropertyComponent } from './array-property.component';
+
+@Component({
+ template: `
+
+ `
+})
+class TestHostComponent {
+ @ViewChild(ObjectPropertyComponent)
+ public componentUnderTest: ObjectPropertyComponent;
+
+ property: Property = getStepProperty(SCHEMA.properties.name, {
+ name: 'foo',
+ type: 'baz',
+ description: 'foo bar baz'
+ }, SCHEMA.definitions);
+}
+
+describe('Object Property Component', () => {
+
+ let fixture: ComponentFixture;
+ let instance: TestHostComponent;
+ let app: ObjectPropertyComponent;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ NgbPopoverModule,
+ MockI18nModule,
+ RouterTestingModule
+ ],
+ declarations: [
+ ObjectPropertyComponent,
+ PrimitivePropertyComponent,
+ ArrayPropertyComponent,
+ TestHostComponent
+ ]
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(TestHostComponent);
+ instance = fixture.componentInstance;
+ app = instance.componentUnderTest;
+ fixture.detectChanges();
+ }));
+
+ it('should accept a property input', async(() => {
+ expect(app).toBeTruthy();
+ }));
+});
diff --git a/ui/src/app/metadata/configuration/component/object-property.component.ts b/ui/src/app/metadata/configuration/component/object-property.component.ts
index db107da92..f7892877e 100644
--- a/ui/src/app/metadata/configuration/component/object-property.component.ts
+++ b/ui/src/app/metadata/configuration/component/object-property.component.ts
@@ -14,13 +14,5 @@ export class ObjectPropertyComponent extends ConfigurationPropertyComponent {
constructor() {
super();
}
-
- getKeys(schema): string[] {
- return Object.keys(schema.properties);
- }
-
- getItemType(items: Property): string {
- return items.widget ? items.widget.id : 'default';
- }
}
diff --git a/ui/src/app/metadata/configuration/component/primitive-property.component.spec.ts b/ui/src/app/metadata/configuration/component/primitive-property.component.spec.ts
new file mode 100644
index 000000000..9ce81bfb5
--- /dev/null
+++ b/ui/src/app/metadata/configuration/component/primitive-property.component.spec.ts
@@ -0,0 +1,60 @@
+import { Component, ViewChild, Input } from '@angular/core';
+import { TestBed, async, ComponentFixture } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
+import { Property } from '../../domain/model/property';
+import { MockI18nModule } from '../../../../testing/i18n.stub';
+import { PrimitivePropertyComponent } from './primitive-property.component';
+
+@Component({
+ template: `
+
+ `
+})
+class TestHostComponent {
+ @ViewChild(PrimitivePropertyComponent)
+ public componentUnderTest: PrimitivePropertyComponent;
+
+ property: Property = {
+ title: 'foo',
+ type: 'string',
+ name: 'foo',
+ value: ['bar'],
+ items: null,
+ properties: null,
+ widget: {
+ id: 'string'
+ }
+ };
+}
+
+describe('Primitive Property Component', () => {
+
+ let fixture: ComponentFixture;
+ let instance: TestHostComponent;
+ let app: PrimitivePropertyComponent;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ NgbDropdownModule,
+ MockI18nModule,
+ RouterTestingModule
+ ],
+ declarations: [
+ PrimitivePropertyComponent,
+ TestHostComponent
+ ],
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(TestHostComponent);
+ instance = fixture.componentInstance;
+ app = instance.componentUnderTest;
+ fixture.detectChanges();
+ }));
+
+ it('should accept a property input', async(() => {
+ expect(app).toBeTruthy();
+ }));
+});
diff --git a/ui/src/app/metadata/domain/utility/configuration.spec.ts b/ui/src/app/metadata/domain/utility/configuration.spec.ts
index b331a8647..d9a5a653f 100644
--- a/ui/src/app/metadata/domain/utility/configuration.spec.ts
+++ b/ui/src/app/metadata/domain/utility/configuration.spec.ts
@@ -10,7 +10,7 @@ describe('domain utility functions', () => {
});
it('should return a formatted list of properties', () => {
- expect(getStepProperties(SCHEMA, {}).length).toBe(2);
+ expect(getStepProperties(SCHEMA, {}).length).toBe(3);
});
});
diff --git a/ui/src/testing/form-schema.stub.ts b/ui/src/testing/form-schema.stub.ts
index f317b1199..1ef7d42ae 100644
--- a/ui/src/testing/form-schema.stub.ts
+++ b/ui/src/testing/form-schema.stub.ts
@@ -30,6 +30,31 @@ export const SCHEMA = {
'description': 'FileBackedHttpMetadataProvider'
}
]
+ },
+ 'list': {
+ 'title': 'label.retained-roles',
+ 'description': 'tooltip.retained-roles',
+ 'type': 'array',
+ 'items': {
+ 'widget': {
+ 'id': 'select'
+ },
+ 'type': 'string',
+ 'oneOf': [
+ {
+ 'enum': [
+ 'SPSSODescriptor'
+ ],
+ 'description': 'value.spdescriptor'
+ },
+ {
+ 'enum': [
+ 'AttributeAuthorityDescriptor'
+ ],
+ 'description': 'value.attr-auth-descriptor'
+ }
+ ]
+ }
}
},
'required': [