diff --git a/ui/src/app/metadata/configuration/container/configuration.component.spec.ts b/ui/src/app/metadata/configuration/container/configuration.component.spec.ts index 71bb05ab0..0d2fca0d3 100644 --- a/ui/src/app/metadata/configuration/container/configuration.component.spec.ts +++ b/ui/src/app/metadata/configuration/container/configuration.component.spec.ts @@ -59,4 +59,12 @@ describe('Metadata Configuration Page Component', () => { it('should load metadata objects', async(() => { expect(app).toBeTruthy(); })); + + describe('hasVersion function', () => { + it('should determine if a version is defined', () => { + expect(app.hasVersion([[{id: 'foo'}], { version: 'foo' }])).toBe('foo'); + expect(app.hasVersion([[{ id: 'foo' }], {}])).toBe('foo'); + expect(app.hasVersion([[], {}])).toBeNull(); + }); + }); }); diff --git a/ui/src/app/metadata/configuration/container/configuration.component.ts b/ui/src/app/metadata/configuration/container/configuration.component.ts index 7e8d6f443..295f90257 100644 --- a/ui/src/app/metadata/configuration/container/configuration.component.ts +++ b/ui/src/app/metadata/configuration/container/configuration.component.ts @@ -22,6 +22,8 @@ export class ConfigurationComponent implements OnDestroy { name$: Observable; type$: Observable; + hasVersion = ([collection, params]) => params.version || collection && collection.length > 0 ? collection[0].id : null; + constructor( private store: Store, private routerState: ActivatedRoute @@ -50,10 +52,8 @@ export class ConfigurationComponent implements OnDestroy { withLatestFrom( this.routerState.queryParams ), - map(([collection, params]) => params.version || collection && collection.length ? collection[0].id : null) - ).subscribe(version => { - this.store.dispatch(new SelectVersion(version)); - }); + map(this.hasVersion) + ).subscribe(version => this.store.dispatch(new SelectVersion(version))); this.name$ = this.store.select(fromReducer.getConfigurationModelName); this.type$ = this.store.select(fromReducer.getConfigurationModelType); diff --git a/ui/src/app/metadata/configuration/container/metadata-xml.component.spec.ts b/ui/src/app/metadata/configuration/container/metadata-xml.component.spec.ts index c9129dfaa..5e5815c06 100644 --- a/ui/src/app/metadata/configuration/container/metadata-xml.component.spec.ts +++ b/ui/src/app/metadata/configuration/container/metadata-xml.component.spec.ts @@ -56,4 +56,11 @@ describe('Metadata Xml Page Component', () => { expect(app).toBeTruthy(); expect(store.select).toHaveBeenCalledTimes(3); })); + + describe('preview method', () => { + it('should dispatch an action', () => { + app.preview(); + expect(store.dispatch).toHaveBeenCalled(); + }); + }); }); diff --git a/ui/src/app/metadata/configuration/container/restore.component.spec.ts b/ui/src/app/metadata/configuration/container/restore.component.spec.ts new file mode 100644 index 000000000..433a11ebd --- /dev/null +++ b/ui/src/app/metadata/configuration/container/restore.component.spec.ts @@ -0,0 +1,72 @@ +import { Component, ViewChild, Input } from '@angular/core'; +import { TestBed, async, ComponentFixture } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { StoreModule, combineReducers, Store } from '@ngrx/store'; +import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; + +import * as fromConfiguration from '../reducer'; +import * as fromProviders from '../../provider/reducer'; +import * as fromResolvers from '../../resolver/reducer'; +import { MockI18nModule } from '../../../../testing/i18n.stub'; +import { RestoreComponent } from './restore.component'; +import { of } from 'rxjs'; + +@Component({ + template: ` + + ` +}) +class TestHostComponent { + @ViewChild(RestoreComponent) + public componentUnderTest: RestoreComponent; +} + +describe('Metadata Restore Page Component', () => { + + let fixture: ComponentFixture; + let instance: TestHostComponent; + let app: RestoreComponent; + let store: Store; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + NgbDropdownModule, + StoreModule.forRoot({ + 'metadata-configuration': combineReducers(fromConfiguration.reducers), + 'provider': combineReducers(fromProviders.reducers), + 'resolver': combineReducers(fromResolvers.reducers) + }), + MockI18nModule, + RouterTestingModule + ], + declarations: [ + RestoreComponent, + TestHostComponent + ], + }).compileComponents(); + + store = TestBed.get(Store); + spyOn(store, 'dispatch'); + spyOn(store, 'select').and.callFake(() => of(new Date().toDateString())); + + fixture = TestBed.createComponent(TestHostComponent); + instance = fixture.componentInstance; + app = instance.componentUnderTest; + fixture.detectChanges(); + })); + + it('should load metadata objects', async(() => { + expect(app).toBeTruthy(); + expect(store.select).toHaveBeenCalledTimes(4); + expect(store.dispatch).not.toHaveBeenCalled(); + })); + + describe('restore method', () => { + it('should emit a value from the restore subject', () => { + spyOn(app.subj, 'next').and.callThrough(); + app.restore(); + expect(app.subj.next).toHaveBeenCalled(); + }); + }); +}); diff --git a/ui/src/app/metadata/configuration/container/restore.component.ts b/ui/src/app/metadata/configuration/container/restore.component.ts index feffeb71b..69c6a6f18 100644 --- a/ui/src/app/metadata/configuration/container/restore.component.ts +++ b/ui/src/app/metadata/configuration/container/restore.component.ts @@ -16,7 +16,7 @@ import { withLatestFrom, map, takeUntil } from 'rxjs/operators'; }) export class RestoreComponent implements OnDestroy { - private subj = new Subject(); + readonly subj = new Subject(); restore$ = this.subj.asObservable(); date$ = this.store.select(fromConfiguration.getConfigurationVersionDate); diff --git a/ui/src/app/metadata/configuration/service/history.service.spec.ts b/ui/src/app/metadata/configuration/service/history.service.spec.ts index 0e8bc77a4..0927f8e70 100644 --- a/ui/src/app/metadata/configuration/service/history.service.spec.ts +++ b/ui/src/app/metadata/configuration/service/history.service.spec.ts @@ -1,7 +1,10 @@ import { TestBed, async, inject } from '@angular/core/testing'; -import { HttpClientModule } from '@angular/common/http'; +import { HttpClientModule, HttpRequest } from '@angular/common/http'; import { HttpTestingController, HttpClientTestingModule } from '@angular/common/http/testing'; import { MetadataHistoryService } from './history.service'; +import { of } from 'rxjs'; +import { PATHS } from '../configuration.values'; +import { Metadata } from '../../domain/domain.type'; describe(`Attributes Service`, () => { beforeEach(() => { @@ -25,4 +28,73 @@ describe(`Attributes Service`, () => { } ))); }); + + describe('getVersions method', () => { + it(`should join a list of observables`, async(inject([MetadataHistoryService, HttpTestingController], + (service: MetadataHistoryService) => { + spyOn(service, 'getVersion').and.returnValue(of()); + service.getVersions('foo', ['abc', 'def'], 'resolver').subscribe(history => { + expect(service.getVersion).toHaveBeenCalledTimes(2); + }); + } + ))); + }); + + describe('getVersion method', () => { + it(`should get the primary version of the resource`, async(inject([MetadataHistoryService, HttpTestingController], + (service: MetadataHistoryService, backend: HttpTestingController) => { + const resourceId = 'foo'; + const type = 'resource'; + service.getVersion(resourceId, type).subscribe(); + backend.expectOne((req: HttpRequest) => { + return req.url === `/${service.base}/${PATHS[type]}/${resourceId}` + && req.method === 'GET'; + }, `GET schema by path`); + } + ))); + it(`should get the provided version of the resource`, async(inject([MetadataHistoryService, HttpTestingController], + (service: MetadataHistoryService, backend: HttpTestingController) => { + const resourceId = 'foo'; + const type = 'resource'; + const versionId = '1'; + service.getVersion(resourceId, type, versionId).subscribe(); + backend.expectOne((req: HttpRequest) => { + return req.url === `/${service.base}/${PATHS[type]}/${resourceId}/${service.path}/${versionId}` + && req.method === 'GET'; + }, `GET schema by path`); + } + ))); + }); + + describe('updateVersion method', () => { + it(`should send a put request`, async(inject([MetadataHistoryService, HttpTestingController], + (service: MetadataHistoryService, backend: HttpTestingController) => { + const resourceId = 'foo'; + const type = 'resource'; + const versionId = '1'; + service.updateVersion(resourceId, type, {} as Metadata).subscribe(); + backend.expectOne((req: HttpRequest) => { + return req.url === `/${service.base}/${PATHS[type]}/${resourceId}` + && req.method === 'PUT'; + }, `PUT schema by path`); + } + ))); + }); + + describe('restoreVersion method', () => { + it(`should send a put request`, async(inject([MetadataHistoryService, HttpTestingController], + (service: MetadataHistoryService, backend: HttpTestingController) => { + const resourceId = 'foo'; + const type = 'resource'; + const versionId = '1'; + const response = {version: 'bar'} as Metadata; + spyOn(service, 'getVersions').and.returnValue(of([response, { ...response, version: 'foo' }])); + spyOn(service, 'updateVersion').and.returnValue(of(response)); + service.restoreVersion(resourceId, type, versionId).subscribe(updated => { + expect(service.getVersions).toHaveBeenCalled(); + expect(service.updateVersion).toHaveBeenCalled(); + }); + } + ))); + }); });