From e0298a4df051ac4e06c58b522151d6b5f1623abd Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Fri, 7 Jun 2019 14:41:55 -0700 Subject: [PATCH] SHIBUI-1267 Updated unit test coverage --- .../array-property.component.spec.ts | 115 ++++++++++++++++++ .../component/array-property.component.ts | 4 - .../configuration-property.component.spec.ts | 69 +++++++++++ .../configuration-property.component.ts | 6 +- .../object-property.component.spec.ts | 60 +++++++++ .../component/object-property.component.ts | 8 -- .../primitive-property.component.spec.ts | 60 +++++++++ .../domain/utility/configuration.spec.ts | 2 +- ui/src/testing/form-schema.stub.ts | 25 ++++ 9 files changed, 335 insertions(+), 14 deletions(-) create mode 100644 ui/src/app/metadata/configuration/component/array-property.component.spec.ts create mode 100644 ui/src/app/metadata/configuration/component/configuration-property.component.spec.ts create mode 100644 ui/src/app/metadata/configuration/component/object-property.component.spec.ts create mode 100644 ui/src/app/metadata/configuration/component/primitive-property.component.spec.ts 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': [