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