From d3e6dd53972e7a34a4a6af36b37c707b644a0c04 Mon Sep 17 00:00:00 2001 From: Kristof De Langhe <kristof.delanghe@atmire.com> Date: Wed, 22 Aug 2018 16:10:55 +0200 Subject: [PATCH] 54472: Authorization + tests (intermediate) --- .../collection-page-routing.module.ts | 3 +- .../community-page-routing.module.ts | 3 +- .../create-community-page.component.spec.ts | 69 +++++++++++ src/app/core/data/comcol-data.service.spec.ts | 110 +++++++++++++++--- src/app/core/data/comcol-data.service.ts | 2 +- 5 files changed, 168 insertions(+), 19 deletions(-) create mode 100644 src/app/+community-page/create-community-page/create-community-page.component.spec.ts diff --git a/src/app/+collection-page/collection-page-routing.module.ts b/src/app/+collection-page/collection-page-routing.module.ts index 1bd53dd2b3..35faae7b02 100644 --- a/src/app/+collection-page/collection-page-routing.module.ts +++ b/src/app/+collection-page/collection-page-routing.module.ts @@ -3,11 +3,12 @@ import { RouterModule } from '@angular/router'; import { CollectionPageComponent } from './collection-page.component'; import { CreateCollectionPageComponent } from './create-collection-page/create-collection-page.component'; +import { AuthenticatedGuard } from '../core/auth/authenticated.guard'; @NgModule({ imports: [ RouterModule.forChild([ - { path: 'create', component: CreateCollectionPageComponent }, + { path: 'create', component: CreateCollectionPageComponent, canActivate: [AuthenticatedGuard] }, { path: ':id', component: CollectionPageComponent, pathMatch: 'full' } ]) ] diff --git a/src/app/+community-page/community-page-routing.module.ts b/src/app/+community-page/community-page-routing.module.ts index 249b01ea18..13d75628b9 100644 --- a/src/app/+community-page/community-page-routing.module.ts +++ b/src/app/+community-page/community-page-routing.module.ts @@ -3,11 +3,12 @@ import { RouterModule } from '@angular/router'; import { CommunityPageComponent } from './community-page.component'; import { CreateCommunityPageComponent } from './create-community-page/create-community-page.component'; +import { AuthenticatedGuard } from '../core/auth/authenticated.guard'; @NgModule({ imports: [ RouterModule.forChild([ - { path: 'create', component: CreateCommunityPageComponent }, + { path: 'create', component: CreateCommunityPageComponent, canActivate: [AuthenticatedGuard] }, { path: ':id', component: CommunityPageComponent, pathMatch: 'full' } ]) ] diff --git a/src/app/+community-page/create-community-page/create-community-page.component.spec.ts b/src/app/+community-page/create-community-page/create-community-page.component.spec.ts new file mode 100644 index 0000000000..990a9895b9 --- /dev/null +++ b/src/app/+community-page/create-community-page/create-community-page.component.spec.ts @@ -0,0 +1,69 @@ +import { CreateCommunityPageComponent } from './create-community-page.component'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { CommunityDataService } from '../../core/data/community-data.service'; +import { RouteService } from '../../shared/services/route.service'; +import { Router } from '@angular/router'; +import { TranslateModule } from '@ngx-translate/core'; +import { Observable } from 'rxjs/Observable'; +import { RemoteData } from '../../core/data/remote-data'; +import { Community } from '../../core/shared/community.model'; +import { DSOSuccessResponse } from '../../core/cache/response-cache.models'; +import { BrowserModule } from '@angular/platform-browser'; +import { SharedModule } from '../../shared/shared.module'; +import { CommonModule } from '@angular/common'; +import { CommunityFormComponent } from '../community-form/community-form.component'; + +describe('CreateCommunityPageComponent', () => { + let comp: CreateCommunityPageComponent; + let fixture: ComponentFixture<CreateCommunityPageComponent>; + let communityDataService: CommunityDataService; + let routeService: RouteService; + let router: any = {}; + + const community = Object.assign(new Community(), { + uuid: 'a20da287-e174-466a-9926-f66b9300d347', + name: 'test community' + }); + + const communityDataServiceStub = { + findById: (uuid) => Observable.of(new RemoteData(false, false, true, null, Object.assign(new Community(), { + uuid: uuid, + name: community.name + }))), + create: (com, uuid?) => Observable.of({ + response: new DSOSuccessResponse(null,'200',null) + }) + }; + const routeServiceStub = { + getQueryParameterValue: (param) => Observable.of(community.uuid) + }; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot(), SharedModule, CommonModule], + declarations: [CreateCommunityPageComponent, CommunityFormComponent], + providers: [ + { provide: CommunityDataService, useValue: communityDataServiceStub }, + { provide: RouteService, useValue: routeServiceStub }, + { provide: Router, useValue: router } + ] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CreateCommunityPageComponent); + comp = fixture.componentInstance; + fixture.detectChanges(); + communityDataService = (comp as any).communityDataService; + routeService = (comp as any).routeService; + router = (comp as any).router; + }); + + it('should navigate on successful submit', () => { + spyOn(router, 'navigateByUrl'); + comp.onSubmit({ + name: 'test' + }); + expect(router.navigateByUrl).toHaveBeenCalled(); + }); +}); diff --git a/src/app/core/data/comcol-data.service.spec.ts b/src/app/core/data/comcol-data.service.spec.ts index b5727fb22f..5f440dd442 100644 --- a/src/app/core/data/comcol-data.service.spec.ts +++ b/src/app/core/data/comcol-data.service.spec.ts @@ -1,6 +1,6 @@ import { Store } from '@ngrx/store'; import { cold, getTestScheduler, hot } from 'jasmine-marbles'; -import { TestScheduler } from 'rxjs/Rx'; +import { Observable, TestScheduler } from 'rxjs/Rx'; import { GlobalConfig } from '../../../config'; import { getMockRequestService } from '../../shared/mocks/mock-request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; @@ -14,6 +14,8 @@ import { FindByIDRequest } from './request.models'; import { RequestService } from './request.service'; import { NormalizedObject } from '../cache/models/normalized-object.model'; import { HALEndpointService } from '../shared/hal-endpoint.service'; +import { Community } from '../shared/community.model'; +import { AuthService } from '../auth/auth.service'; const LINK_NAME = 'test'; @@ -32,6 +34,7 @@ class TestService extends ComColDataService<NormalizedTestObject, any> { protected cds: CommunityDataService, protected objectCache: ObjectCacheService, protected halService: HALEndpointService, + protected authService: AuthService, protected linkPath: string ) { super(); @@ -46,7 +49,8 @@ describe('ComColDataService', () => { let requestService: RequestService; let cds: CommunityDataService; let objectCache: ObjectCacheService; - const halService: any = {}; + let authService: AuthService; + let halService: any = {}; const rdbService = {} as RemoteDataBuildService; const store = {} as Store<CoreState>; @@ -57,6 +61,11 @@ describe('ComColDataService', () => { const communityEndpoint = `${communitiesEndpoint}/${scopeID}`; const scopedEndpoint = `${communityEndpoint}/${LINK_NAME}`; const serviceEndpoint = `https://rest.api/core/${LINK_NAME}`; + const authHeader = 'Bearer eyJhbGciOiJIUzI1NiJ9.eyJlaWQiOiJhNjA4NmIzNC0zOTE4LTQ1YjctOGRkZC05MzI5YTcwMmEyNmEiLCJzZyI6W10sImV4cCI6MTUzNDk0MDcyNX0.RV5GAtiX6cpwBN77P_v16iG9ipeyiO7faNYSNMzq_sQ'; + + const mockHalService = { + getEndpoint: (linkPath) => Observable.of(communitiesEndpoint) + }; function initMockCommunityDataService(): CommunityDataService { return jasmine.createSpyObj('responseCache', { @@ -85,6 +94,14 @@ describe('ComColDataService', () => { }); } + function initMockAuthService(): AuthService { + return jasmine.createSpyObj('authService', { + buildAuthHeader: cold('c-', { + c: authHeader + }) + }); + } + function initTestService(): TestService { return new TestService( responseCache, @@ -95,22 +112,27 @@ describe('ComColDataService', () => { cds, objectCache, halService, + authService, LINK_NAME ); } + beforeEach(() => { + cds = initMockCommunityDataService(); + requestService = getMockRequestService(); + objectCache = initMockObjectCacheService(); + responseCache = initMockResponseCacheService(true); + halService = mockHalService; + authService = initMockAuthService(); + service = initTestService(); + }); + describe('getScopedEndpoint', () => { beforeEach(() => { scheduler = getTestScheduler(); }); it('should configure a new FindByIDRequest for the scope Community', () => { - cds = initMockCommunityDataService(); - requestService = getMockRequestService(); - objectCache = initMockObjectCacheService(); - responseCache = initMockResponseCacheService(true); - service = initTestService(); - const expected = new FindByIDRequest(requestService.generateRequestId(), communityEndpoint, scopeID); scheduler.schedule(() => service.getScopedEndpoint(scopeID).subscribe()); @@ -120,14 +142,6 @@ describe('ComColDataService', () => { }); describe('if the scope Community can be found', () => { - beforeEach(() => { - cds = initMockCommunityDataService(); - requestService = getMockRequestService(); - objectCache = initMockObjectCacheService(); - responseCache = initMockResponseCacheService(true); - service = initTestService(); - }); - it('should fetch the scope Community from the cache', () => { scheduler.schedule(() => service.getScopedEndpoint(scopeID).subscribe()); scheduler.flush(); @@ -160,4 +174,68 @@ describe('ComColDataService', () => { }); }); + + describe('create', () => { + let community: Community; + const name = 'test community'; + + beforeEach(() => { + community = Object.assign(new Community(), { + name: name + }); + spyOn(service, 'buildCreateParams'); + }); + + describe('when creating a top-level community', () => { + it('should build params without parent UUID', () => { + scheduler.schedule(() => service.create(community).subscribe()); + scheduler.flush(); + expect(service.buildCreateParams).toHaveBeenCalledWith(community); + }); + }); + + describe('when creating a community part of another community', () => { + let parentCommunity: Community; + const parentName = 'test parent community'; + const parentUUID = 'a20da287-e174-466a-9926-f66b9300d347'; + + beforeEach(() => { + parentCommunity = Object.assign(new Community(), { + id: parentUUID, + uuid: parentUUID, + name: parentName + }); + }); + + it('should build params with parent UUID', () => { + scheduler.schedule(() => service.create(community, parentUUID).subscribe()); + scheduler.flush(); + expect(service.buildCreateParams).toHaveBeenCalledWith(community, parentUUID); + }); + }); + }); + + describe('buildCreateParams', () => { + let community: Community; + const name = 'test community'; + let parentCommunity: Community; + const parentName = 'test parent community'; + const parentUUID = 'a20da287-e174-466a-9926-f66b9300d347'; + + beforeEach(() => { + community = Object.assign(new Community(), { + name: name + }); + parentCommunity = Object.assign(new Community(), { + id: parentUUID, + uuid: parentUUID, + name: parentName + }); + }); + + it('should return the correct url parameters', () => { + expect(service.buildCreateParams(community, parentUUID)).toEqual('?name=' + name + '&parent=' + parentUUID); + }); + }); + }); diff --git a/src/app/core/data/comcol-data.service.ts b/src/app/core/data/comcol-data.service.ts index b7a87913de..a57f5fa910 100644 --- a/src/app/core/data/comcol-data.service.ts +++ b/src/app/core/data/comcol-data.service.ts @@ -75,7 +75,7 @@ export abstract class ComColDataService<TNormalized extends NormalizedObject, TD const headers = new HttpHeaders(); headers.append('Authentication', this.authService.buildAuthHeader()); options.headers = headers; - return new PostRequest(this.requestService.generateRequestId(), endpointURL + ((parentUUID) ? this.buildCreateParams(comcol, parentUUID) : this.buildCreateParams(comcol))); + return new PostRequest(this.requestService.generateRequestId(), endpointURL + ((parentUUID) ? this.buildCreateParams(comcol, parentUUID) : this.buildCreateParams(comcol)), options); }), configureRequest(this.requestService), map((request: RestRequest) => request.href), -- GitLab