Finished refactoring, guards, docs, tests

This commit is contained in:
lotte
2019-01-02 16:51:41 +01:00
parent e0ed960d4c
commit 1ebd6f0e86
41 changed files with 600 additions and 553 deletions

View File

@@ -1,11 +1,8 @@
<div class="container">
<div class="row">
<div class="col-12 pb-4">
<ng-container *ngVar="(parentUUID$ | async)?.payload as parent">
<h2 *ngIf="!parent" id="header" class="border-bottom pb-2">{{ 'collection.create.head' | translate }}</h2>
<h2 *ngIf="parent" id="sub-header" class="border-bottom pb-2">{{ 'collection.create.sub-head' | translate:{ parent: parent.name } }}</h2>
</ng-container>
<div class="row">
<div class="col-12 pb-4">
<h2 id="sub-header" class="border-bottom pb-2">{{'collection.create.sub-head' | translate:{ parent: (parentRD$| async)?.payload.name } }}</h2>
</div>
</div>
</div>
<ds-collection-form (submitForm)="onSubmit($event)"></ds-collection-form>
<ds-collection-form (submitForm)="onSubmit($event)"></ds-collection-form>
</div>

View File

@@ -1,108 +0,0 @@
import { SharedModule } from '../../shared/shared.module';
import { Community } from '../../core/shared/community.model';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { CommonModule, Location } from '@angular/common';
import { Router } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';
import { Observable } from 'rxjs';
import { CommunityDataService } from '../../core/data/community-data.service';
import { RouteService } from '../../shared/services/route.service';
import { RemoteData } from '../../core/data/remote-data';
import { CreateCollectionPageComponent } from './create-collection-page.component';
import { CollectionDataService } from '../../core/data/collection-data.service';
import { Collection } from '../../core/shared/collection.model';
import { RouterTestingModule } from '@angular/router/testing';
import { CollectionFormComponent } from '../collection-form/collection-form.component';
import { of as observableOf } from 'rxjs';
import { NO_ERRORS_SCHEMA } from '@angular/core';
describe('CreateCollectionPageComponent', () => {
let comp: CreateCollectionPageComponent;
let fixture: ComponentFixture<CreateCollectionPageComponent>;
let collectionDataService: CollectionDataService;
let communityDataService: CommunityDataService;
let routeService: RouteService;
let router: Router;
const community = Object.assign(new Community(), {
uuid: 'a20da287-e174-466a-9926-f66b9300d347',
metadata: [{
key: 'dc.title',
value: 'test collection'
}]
});
const collection = Object.assign(new Collection(), {
uuid: 'ce41d451-97ed-4a9c-94a1-7de34f16a9f4',
metadata: [{
key: 'dc.title',
value: 'new collection'
}] });
const collectionDataServiceStub = {
create: (col, uuid?) => observableOf(new RemoteData(false, false, true, undefined, collection))
};
const communityDataServiceStub = {
findById: (uuid) => observableOf(new RemoteData(false, false, true, null, Object.assign(new Community(), {
uuid: uuid,
metadata: [{
key: 'dc.title',
value: community.name
}]
})))
};
const routeServiceStub = {
getQueryParameterValue: (param) => observableOf(community.uuid)
};
const routerStub = {
navigate: (commands) => commands
};
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), SharedModule, CommonModule, RouterTestingModule],
declarations: [CreateCollectionPageComponent],
providers: [
{ provide: CollectionDataService, useValue: collectionDataServiceStub },
{ provide: CommunityDataService, useValue: communityDataServiceStub },
{ provide: RouteService, useValue: routeServiceStub },
{ provide: Router, useValue: routerStub }
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(CreateCollectionPageComponent);
comp = fixture.componentInstance;
fixture.detectChanges();
collectionDataService = (comp as any).collectionDataService;
communityDataService = (comp as any).communityDataService;
routeService = (comp as any).routeService;
router = (comp as any).router;
});
describe('onSubmit', () => {
const data = {
metadata: [{
key: 'dc.title',
value:'test'
}]
};
it('should navigate when successful', () => {
spyOn(router, 'navigate');
comp.onSubmit(data);
fixture.detectChanges();
expect(router.navigate).toHaveBeenCalled();
});
it('should not navigate on failure', () => {
spyOn(router, 'navigate');
spyOn(collectionDataService, 'create').and.returnValue(observableOf(new RemoteData(true, true, false, undefined, collection)));
comp.onSubmit(data);
fixture.detectChanges();
expect(router.navigate).not.toHaveBeenCalled();
});
});
});

View File

@@ -2,18 +2,21 @@ import { Component } from '@angular/core';
import { CommunityDataService } from '../../core/data/community-data.service';
import { RouteService } from '../../shared/services/route.service';
import { Router } from '@angular/router';
import { CreateComColPageComponent } from '../../comcol-forms/create-comcol-page/create-comcol-page.component';
import { CreateComColPageComponent } from '../../shared/comcol-forms/create-comcol-page/create-comcol-page.component';
import { NormalizedCollection } from '../../core/cache/models/normalized-collection.model';
import { Collection } from '../../core/shared/collection.model';
import { CollectionDataService } from '../../core/data/collection-data.service';
/**
* Component that represents the page where a user can create a new Collection
*/
@Component({
selector: 'ds-create-community',
styleUrls: ['./create-community-page.component.scss'],
templateUrl: './create-community-page.component.html'
selector: 'ds-create-collection',
styleUrls: ['./create-collection-page.component.scss'],
templateUrl: './create-collection-page.component.html'
})
export class CreateCommunityPageComponent extends CreateComColPageComponent<Collection, NormalizedCollection> {
protected frontendURL = 'collections';
export class CreateCollectionPageComponent extends CreateComColPageComponent<Collection, NormalizedCollection> {
protected frontendURL = '/collections/';
public constructor(
protected communityDataService: CommunityDataService,

View File

@@ -0,0 +1,67 @@
import { CreateCollectionPageGuard } from './create-collection-page.guard';
import { MockRouter } from '../../shared/mocks/mock-router';
import { RemoteData } from '../../core/data/remote-data';
import { Community } from '../../core/shared/community.model';
import { of as observableOf } from 'rxjs';
import { first } from 'rxjs/operators';
describe('CreateCollectionPageGuard', () => {
describe('canActivate', () => {
let guard: CreateCollectionPageGuard;
let router;
let communityDataServiceStub: any;
beforeEach(() => {
communityDataServiceStub = {
findById: (id: string) => {
if (id === 'valid-id') {
return observableOf(new RemoteData(false, false, true, null, new Community()));
} else if (id === 'invalid-id') {
return observableOf(new RemoteData(false, false, true, null, undefined));
} else if (id === 'error-id') {
return observableOf(new RemoteData(false, false, false, null, new Community()));
}
}
};
router = new MockRouter();
guard = new CreateCollectionPageGuard(router, communityDataServiceStub);
});
it('should return true when the parent ID resolves to a community', () => {
guard.canActivate({ queryParams: { parent: 'valid-id' } } as any, undefined)
.pipe(first())
.subscribe(
(canActivate) =>
expect(canActivate).toEqual(true)
);
});
it('should return false when no parent ID has been provided', () => {
guard.canActivate({ queryParams: { } } as any, undefined)
.pipe(first())
.subscribe(
(canActivate) =>
expect(canActivate).toEqual(false)
);
});
it('should return false when the parent ID does not resolve to a community', () => {
guard.canActivate({ queryParams: { parent: 'invalid-id' } } as any, undefined)
.pipe(first())
.subscribe(
(canActivate) =>
expect(canActivate).toEqual(false)
);
});
it('should return false when the parent ID resolves to an error response', () => {
guard.canActivate({ queryParams: { parent: 'error-id' } } as any, undefined)
.pipe(first())
.subscribe(
(canActivate) =>
expect(canActivate).toEqual(false)
);
});
});
});

View File

@@ -0,0 +1,46 @@
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
import { hasNoValue, hasValue } from '../../shared/empty.util';
import { CommunityDataService } from '../../core/data/community-data.service';
import { RemoteData } from '../../core/data/remote-data';
import { Community } from '../../core/shared/community.model';
import { getFinishedRemoteData } from '../../core/shared/operators';
import { map, tap } from 'rxjs/operators';
import { Observable, of as observableOf } from 'rxjs';
/**
* Prevent creation of a collection without a parent community provided
* @class CreateCollectionPageGuard
*/
@Injectable()
export class CreateCollectionPageGuard implements CanActivate {
public constructor(private router: Router, private communityService: CommunityDataService) {
}
/**
* True when either a parent ID query parameter has been provided and the parent ID resolves to a valid parent community
* Reroutes to a 404 page when the page cannot be activated
* @method canActivate
*/
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
const parentID = route.queryParams.parent;
if (hasNoValue(parentID)) {
this.router.navigate(['/404']);
return observableOf(false);
}
const parent: Observable<RemoteData<Community>> = this.communityService.findById(parentID)
.pipe(
getFinishedRemoteData(),
);
return parent.pipe(
map((communityRD: RemoteData<Community>) => hasValue(communityRD) && communityRD.hasSucceeded && hasValue(communityRD.payload)),
tap((isValid: boolean) => {
if (!isValid) {
this.router.navigate(['/404']);
}
})
);
}
}