diff --git a/ui/src/app/metadata/domain/service/filter.service.spec.ts b/ui/src/app/metadata/domain/service/filter.service.spec.ts new file mode 100644 index 000000000..1410f6723 --- /dev/null +++ b/ui/src/app/metadata/domain/service/filter.service.spec.ts @@ -0,0 +1,74 @@ +import { TestBed, async, inject } from '@angular/core/testing'; +import { HttpTestingController, HttpClientTestingModule } from '@angular/common/http/testing'; +import { HttpClientModule, HttpRequest } from '@angular/common/http'; +import { MetadataFilterService } from './filter.service'; +import { EntityAttributesFilter } from '../entity'; + +describe(`Metadata Filter Service`, () => { + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ + HttpClientModule, + HttpClientTestingModule + ], + providers: [ + MetadataFilterService + ] + }); + }); + + describe('query method', () => { + it(`should send an expected GET[] request`, async(inject([MetadataFilterService, HttpTestingController], + (service: MetadataFilterService, backend: HttpTestingController) => { + service.query().subscribe(); + + backend.expectOne((req: HttpRequest) => { + return req.url === `${service.base}${service.endpoint}` + && req.method === 'GET'; + }, `GET MetadataResolvers collection`); + } + ))); + }); + describe('find method', () => { + it(`should send an expected GET request`, async(inject([MetadataFilterService, HttpTestingController], + (service: MetadataFilterService, backend: HttpTestingController) => { + const id = 'foo'; + service.find(id).subscribe(); + + backend.expectOne((req: HttpRequest) => { + return req.url === `${service.base}${service.endpoint}/${id}` + && req.method === 'GET'; + }, `GET MetadataResolvers collection`); + } + ))); + }); + describe('update method', () => { + it(`should send an expected PUT request`, async(inject([MetadataFilterService, HttpTestingController], + (service: MetadataFilterService, backend: HttpTestingController) => { + const id = 'foo'; + const filter = new EntityAttributesFilter({ id }); + service.update(filter).subscribe(); + + backend.expectOne((req: HttpRequest) => { + return req.url === `${service.base}${service.endpoint}/${id}` + && req.method === 'PUT'; + }, `PUT (update) MetadataResolvers collection`); + } + ))); + }); + describe('save method', () => { + it(`should send an expected POST request`, async(inject([MetadataFilterService, HttpTestingController], + (service: MetadataFilterService, backend: HttpTestingController) => { + const id = 'foo'; + const filter = new EntityAttributesFilter({ id }); + service.save(filter).subscribe(); + + backend.expectOne((req: HttpRequest) => { + return req.url === `${service.base}${service.endpoint}` + && req.method === 'POST'; + }, `POST MetadataResolvers collection`); + } + ))); + }); +}); diff --git a/ui/src/app/metadata/provider/container/provider-wizard-step.component.spec.ts b/ui/src/app/metadata/provider/container/provider-wizard-step.component.spec.ts new file mode 100644 index 000000000..6e93c612b --- /dev/null +++ b/ui/src/app/metadata/provider/container/provider-wizard-step.component.spec.ts @@ -0,0 +1,62 @@ +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 { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; + +import { ProviderWizardStepComponent } from './provider-wizard-step.component'; +import * as fromRoot from '../reducer'; +import { SchemaFormModule, WidgetRegistry, DefaultWidgetRegistry } from 'ngx-schema-form'; +import * as fromWizard from '../../../wizard/reducer'; + +@Component({ + template: ` + + ` +}) +class TestHostComponent { + @ViewChild(ProviderWizardStepComponent) + public componentUnderTest: ProviderWizardStepComponent; +} + +describe('Provider Wizard Step Component', () => { + + let fixture: ComponentFixture; + let instance: TestHostComponent; + let app: ProviderWizardStepComponent; + let store: Store; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + NgbDropdownModule.forRoot(), + RouterTestingModule, + SchemaFormModule.forRoot(), + StoreModule.forRoot({ + provider: combineReducers(fromRoot.reducers), + wizard: combineReducers(fromWizard.reducers) + }) + ], + declarations: [ + ProviderWizardStepComponent, + TestHostComponent + ], + providers: [ + { provide: WidgetRegistry, useClass: DefaultWidgetRegistry } + ] + }).compileComponents(); + + store = TestBed.get(Store); + spyOn(store, 'dispatch'); + + fixture = TestBed.createComponent(TestHostComponent); + instance = fixture.componentInstance; + app = instance.componentUnderTest; + fixture.detectChanges(); + })); + + it('should instantiate the component', async(() => { + expect(app).toBeTruthy(); + })); +}); diff --git a/ui/src/app/metadata/provider/container/provider-wizard.component.spec.ts b/ui/src/app/metadata/provider/container/provider-wizard.component.spec.ts new file mode 100644 index 000000000..043663260 --- /dev/null +++ b/ui/src/app/metadata/provider/container/provider-wizard.component.spec.ts @@ -0,0 +1,63 @@ +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 { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; + +import { ProviderWizardComponent } from './provider-wizard.component'; +import * as fromRoot from '../reducer'; +import { WizardModule } from '../../../wizard/wizard.module'; +import { ProviderWizardSummaryComponent } from '../component/provider-wizard-summary.component'; +import { SummaryPropertyComponent } from '../component/summary-property.component'; +import * as fromWizard from '../../../wizard/reducer'; + +@Component({ + template: ` + + ` +}) +class TestHostComponent { + @ViewChild(ProviderWizardComponent) + public componentUnderTest: ProviderWizardComponent; +} + +describe('Provider Wizard Component', () => { + + let fixture: ComponentFixture; + let instance: TestHostComponent; + let app: ProviderWizardComponent; + let store: Store; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + WizardModule, + NgbDropdownModule.forRoot(), + RouterTestingModule, + StoreModule.forRoot({ + provider: combineReducers(fromRoot.reducers), + wizard: combineReducers(fromWizard.reducers) + }) + ], + declarations: [ + ProviderWizardComponent, + SummaryPropertyComponent, + ProviderWizardSummaryComponent, + TestHostComponent + ] + }).compileComponents(); + + store = TestBed.get(Store); + spyOn(store, 'dispatch'); + + fixture = TestBed.createComponent(TestHostComponent); + instance = fixture.componentInstance; + app = instance.componentUnderTest; + fixture.detectChanges(); + })); + + it('should instantiate the component', async(() => { + expect(app).toBeTruthy(); + })); +}); diff --git a/ui/src/app/metadata/provider/model/file-backed-http.provider.form.spec.ts b/ui/src/app/metadata/provider/model/file-backed-http.provider.form.spec.ts new file mode 100644 index 000000000..4bba62c7d --- /dev/null +++ b/ui/src/app/metadata/provider/model/file-backed-http.provider.form.spec.ts @@ -0,0 +1,110 @@ +import { FileBackedHttpMetadataProviderWizard } from './file-backed-http.provider.form'; +import { FileBackedHttpMetadataProvider } from '../../domain/model/providers'; + +describe('FileBackedHttpMetadataProviderWizard', () => { + + const parser = FileBackedHttpMetadataProviderWizard.translate.parser; + const formatter = FileBackedHttpMetadataProviderWizard.translate.formatter; + + const requiredValidUntilFilter = { + maxValidityInterval: 1, + '@type': 'RequiredValidUntil' + }; + + const signatureValidationFilter = { + requireSignedRoot: true, + certificateFile: 'foo', + '@type': 'SignatureValidation' + }; + + const entityRoleWhiteListFilter = { + retainedRoles: ['foo', 'bar'], + removeRolelessEntityDescriptors: true, + removeEmptyEntitiesDescriptors: true, + '@type': 'EntityRoleWhiteList' + }; + + describe('parser', () => { + it('should transform the filters object to an array', () => { + let model = { + name: 'foo', + '@type': 'FileBackedHttpMetadataProvider', + enabled: true, + resourceId: 'foo', + metadataFilters: { + RequiredValidUntil: requiredValidUntilFilter, + SignatureValidation: signatureValidationFilter, + EntityRoleWhiteList: entityRoleWhiteListFilter + } + }; + expect( + parser(model) + ).toEqual( + { + ...model, + metadataFilters: [ + requiredValidUntilFilter, + signatureValidationFilter, + entityRoleWhiteListFilter + ] + } + ); + }); + + it('should return the object if metadataFilters is not provided', () => { + let model = { + name: 'foo', + '@type': 'FileBackedHttpMetadataProvider', + enabled: true, + resourceId: 'foo' + }; + expect( + parser(model) + ).toEqual( + model + ); + }); + }); + + describe('formatter', () => { + it('should transform the filters object to an array', () => { + let model = { + name: 'foo', + '@type': 'FileBackedHttpMetadataProvider', + enabled: true, + resourceId: 'foo', + metadataFilters: [ + requiredValidUntilFilter, + signatureValidationFilter, + entityRoleWhiteListFilter + ] + }; + expect( + formatter(model) + ).toEqual( + { + ...model, + metadataFilters: { + RequiredValidUntil: requiredValidUntilFilter, + SignatureValidation: signatureValidationFilter, + EntityRoleWhiteList: entityRoleWhiteListFilter + } + } + ); + }); + + it('should return the object if metadataFilters is not provided', () => { + let model = { + name: 'foo', + '@type': 'FileBackedHttpMetadataProvider', + enabled: true, + resourceId: 'foo' + }; + expect( + formatter(model) + ).toEqual( + model + ); + }); + }); +}); diff --git a/ui/src/app/metadata/provider/model/file-backed-http.provider.form.ts b/ui/src/app/metadata/provider/model/file-backed-http.provider.form.ts index 5208783c2..41723be8f 100644 --- a/ui/src/app/metadata/provider/model/file-backed-http.provider.form.ts +++ b/ui/src/app/metadata/provider/model/file-backed-http.provider.form.ts @@ -5,25 +5,8 @@ export const FileBackedHttpMetadataProviderWizard: Wizard changes.metadataFilters ? ({ + parser: (changes: any): FileBackedHttpMetadataProvider => changes.metadataFilters ? ({ ...changes, - httpMetadataResolverAttributes: { - httpClientRef: null, - connectionRequestTimeout: null, - connectionTimeout: null, - socketTimeout: null, - disregardTLSCertificate: false, - tlsTrustEngineRef: null, - httpClientSecurityParametersRef: null, - proxyHost: null, - proxyPort: null, - proxyUser: null, - proxyPassword: null, - httpCaching: null, - httpCacheDirectory: null, - httpMaxCacheEntries: null, - httpMaxCacheEntrySize: null - }, metadataFilters: [ ...Object.keys(changes.metadataFilters).reduce((collection, filterName) => ([ ...collection, @@ -34,7 +17,7 @@ export const FileBackedHttpMetadataProviderWizard: Wizard changes.metadataFilters ? ({ + formatter: (changes: FileBackedHttpMetadataProvider): any => changes.metadataFilters ? ({ ...changes, metadataFilters: { ...(changes.metadataFilters || []).reduce((collection, filter) => ({ diff --git a/ui/src/app/metadata/provider/reducer/collection.reducer.spec.ts b/ui/src/app/metadata/provider/reducer/collection.reducer.spec.ts new file mode 100644 index 000000000..1631c189f --- /dev/null +++ b/ui/src/app/metadata/provider/reducer/collection.reducer.spec.ts @@ -0,0 +1,50 @@ +import { reducer } from './collection.reducer'; +import * as fromProvider from './collection.reducer'; +import { + ProviderCollectionActionTypes, + LoadProviderSuccess, + UpdateProviderSuccess +} from '../action/collection.action'; + +const snapshot: fromProvider.CollectionState = { + ids: [], + entities: {}, + selectedProviderId: null, + loaded: false +}; + +describe('Provider Reducer', () => { + describe('undefined action', () => { + it('should return the default state', () => { + const result = reducer(snapshot, {} as any); + + expect(result).toEqual(snapshot); + }); + }); + + describe(`${ProviderCollectionActionTypes.LOAD_PROVIDER_SUCCESS}`, () => { + it('should add the loaded providers to the collection', () => { + spyOn(fromProvider.adapter, 'addAll').and.callThrough(); + const providers = [ + { resourceId: 'foo', name: 'foo', '@type': 'foo', enabled: true, createdDate: new Date().toLocaleDateString() }, + { resourceId: 'bar', name: 'bar', '@type': 'bar', enabled: false, createdDate: new Date().toLocaleDateString() } + ]; + const action = new LoadProviderSuccess(providers); + const result = reducer(snapshot, action); + expect(fromProvider.adapter.addAll).toHaveBeenCalled(); + }); + }); + + describe(`${ProviderCollectionActionTypes.UPDATE_PROVIDER_SUCCESS}`, () => { + it('should add the loaded providers to the collection', () => { + spyOn(fromProvider.adapter, 'updateOne').and.callThrough(); + const update = { + id: 'foo', + changes: { resourceId: 'foo', name: 'bar', createdDate: new Date().toLocaleDateString() }, + }; + const action = new UpdateProviderSuccess(update); + const result = reducer(snapshot, action); + expect(fromProvider.adapter.updateOne).toHaveBeenCalled(); + }); + }); +}); diff --git a/ui/src/app/metadata/provider/reducer/editor.reducer.spec.ts b/ui/src/app/metadata/provider/reducer/editor.reducer.spec.ts new file mode 100644 index 000000000..e69de29bb