mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
added tests and docs
This commit is contained in:
@@ -83,7 +83,7 @@ describe('CollectionItemMapperComponent', () => {
|
||||
const itemDataServiceStub = {
|
||||
mapToCollection: () => of(new RestResponse(true, 200, 'OK'))
|
||||
};
|
||||
const activatedRouteStub = new ActivatedRouteStub({}, { collection: mockCollectionRD });
|
||||
const activatedRouteStub = new ActivatedRouteStub({}, { dso: mockCollectionRD });
|
||||
const translateServiceStub = {
|
||||
get: () => of('test-message of collection ' + mockCollection.name),
|
||||
onLangChange: new EventEmitter(),
|
||||
|
@@ -5,14 +5,28 @@ import { hasNoValue, hasValue, isNotUndefined } from '../shared/empty.util';
|
||||
import { filter, map, switchMap, tap } from 'rxjs/operators';
|
||||
import { combineLatest, Observable, Subscription, of as observableOf } from 'rxjs';
|
||||
|
||||
/**
|
||||
* Component representing the breadcrumbs of a page
|
||||
*/
|
||||
@Component({
|
||||
selector: 'ds-breadcrumbs',
|
||||
templateUrl: './breadcrumbs.component.html',
|
||||
styleUrls: ['./breadcrumbs.component.scss']
|
||||
})
|
||||
export class BreadcrumbsComponent implements OnInit, OnDestroy {
|
||||
/**
|
||||
* List of breadcrumbs for this page
|
||||
*/
|
||||
breadcrumbs: Breadcrumb[];
|
||||
|
||||
/**
|
||||
* Whether or not to show breadcrumbs on this page
|
||||
*/
|
||||
showBreadcrumbs: boolean;
|
||||
|
||||
/**
|
||||
* Subscription to unsubscribe from on destroy
|
||||
*/
|
||||
subscription: Subscription;
|
||||
|
||||
constructor(
|
||||
@@ -21,6 +35,9 @@ export class BreadcrumbsComponent implements OnInit, OnDestroy {
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the breadcrumbs on init for this page
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.subscription = this.router.events.pipe(
|
||||
filter((e): e is NavigationEnd => e instanceof NavigationEnd),
|
||||
@@ -32,6 +49,10 @@ export class BreadcrumbsComponent implements OnInit, OnDestroy {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that recursively resolves breadcrumbs
|
||||
* @param route The route to get the breadcrumb from
|
||||
*/
|
||||
resolveBreadcrumbs(route: ActivatedRoute): Observable<Breadcrumb[]> {
|
||||
const data = route.snapshot.data;
|
||||
const routeConfig = route.snapshot.routeConfig;
|
||||
@@ -56,12 +77,18 @@ export class BreadcrumbsComponent implements OnInit, OnDestroy {
|
||||
return !last ? this.resolveBreadcrumbs(route.firstChild) : observableOf([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribe from subscription
|
||||
*/
|
||||
ngOnDestroy(): void {
|
||||
if (hasValue(this.subscription)) {
|
||||
this.subscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the state of the breadcrumbs
|
||||
*/
|
||||
reset() {
|
||||
this.breadcrumbs = [];
|
||||
this.showBreadcrumbs = true;
|
||||
|
@@ -1,6 +1,15 @@
|
||||
import { Breadcrumb } from '../../breadcrumbs/breadcrumb/breadcrumb.model';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
/**
|
||||
* Service to calculate breadcrumbs for a single part of the route
|
||||
*/
|
||||
export interface BreadcrumbsService<T> {
|
||||
|
||||
/**
|
||||
* Method to calculate the breadcrumbs for a part of the route
|
||||
* @param key The key used to resolve the breadcrumb
|
||||
* @param url The url to use as a link for this breadcrumb
|
||||
*/
|
||||
getBreadcrumbs(key: T, url: string): Observable<Breadcrumb[]>;
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@ import { Collection } from '../shared/collection.model';
|
||||
import { CollectionDataService } from '../data/collection-data.service';
|
||||
|
||||
/**
|
||||
* The class that resolve the BreadcrumbConfig object for a route
|
||||
* The class that resolves the BreadcrumbConfig object for a Collection
|
||||
*/
|
||||
@Injectable()
|
||||
export class CollectionBreadcrumbResolver extends DSOBreadcrumbResolver<Collection> {
|
||||
|
@@ -5,7 +5,7 @@ import { CommunityDataService } from '../data/community-data.service';
|
||||
import { Community } from '../shared/community.model';
|
||||
|
||||
/**
|
||||
* The class that resolve the BreadcrumbConfig object for a route
|
||||
* The class that resolves the BreadcrumbConfig object for a Community
|
||||
*/
|
||||
@Injectable()
|
||||
export class CommunityBreadcrumbResolver extends DSOBreadcrumbResolver<Community> {
|
||||
|
34
src/app/core/breadcrumbs/dso-breadcrumb.resolver.spec.ts
Normal file
34
src/app/core/breadcrumbs/dso-breadcrumb.resolver.spec.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { DSOBreadcrumbResolver } from './dso-breadcrumb.resolver';
|
||||
import { Collection } from '../shared/collection.model';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils';
|
||||
import { getTestScheduler } from 'jasmine-marbles';
|
||||
|
||||
describe('DSOBreadcrumbResolver', () => {
|
||||
describe('resolve', () => {
|
||||
let resolver: DSOBreadcrumbResolver<Collection>;
|
||||
let collectionService: any;
|
||||
let dsoBreadcrumbService: any;
|
||||
let testCollection: Collection;
|
||||
let uuid;
|
||||
let breadcrumbUrl;
|
||||
let currentUrl;
|
||||
|
||||
beforeEach(() => {
|
||||
uuid = '1234-65487-12354-1235';
|
||||
breadcrumbUrl = '/collections/' + uuid;
|
||||
currentUrl = breadcrumbUrl + '/edit';
|
||||
testCollection = Object.assign(new Collection(), { uuid });
|
||||
dsoBreadcrumbService = {};
|
||||
collectionService = {
|
||||
findById: (id: string) => createSuccessfulRemoteDataObject$(testCollection)
|
||||
};
|
||||
resolver = new DSOBreadcrumbResolver(dsoBreadcrumbService, collectionService);
|
||||
});
|
||||
|
||||
it('should resolve a breadcrumb config for the correct DSO', () => {
|
||||
const resolvedConfig = resolver.resolve({ params: { id: uuid } } as any, { url: currentUrl } as any);
|
||||
const expectedConfig = { provider: dsoBreadcrumbService, key: testCollection, url: breadcrumbUrl };
|
||||
getTestScheduler().expectObservable(resolvedConfig).toBe('(a|)', { a: expectedConfig})
|
||||
});
|
||||
});
|
||||
});
|
@@ -10,7 +10,7 @@ import { DSpaceObject } from '../shared/dspace-object.model';
|
||||
import { ChildHALResource } from '../shared/child-hal-resource.model';
|
||||
|
||||
/**
|
||||
* The class that resolve the BreadcrumbConfig object for a route
|
||||
* The class that resolves the BreadcrumbConfig object for a DSpaceObject
|
||||
*/
|
||||
@Injectable()
|
||||
export class DSOBreadcrumbResolver<T extends ChildHALResource & DSpaceObject> implements Resolve<BreadcrumbConfig<T>> {
|
||||
@@ -18,7 +18,7 @@ export class DSOBreadcrumbResolver<T extends ChildHALResource & DSpaceObject> im
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for resolving a site object
|
||||
* Method for resolving a breadcrumb config object
|
||||
* @param {ActivatedRouteSnapshot} route The current ActivatedRouteSnapshot
|
||||
* @param {RouterStateSnapshot} state The current RouterStateSnapshot
|
||||
* @returns BreadcrumbConfig object
|
||||
|
@@ -5,20 +5,15 @@ import { LinkService } from '../cache/builders/link.service';
|
||||
import { Item } from '../shared/item.model';
|
||||
import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils';
|
||||
import { DSpaceObject } from '../shared/dspace-object.model';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { RemoteData } from '../data/remote-data';
|
||||
import { hasValue } from '../../shared/empty.util';
|
||||
import { Community } from '../shared/community.model';
|
||||
import { Collection } from '../shared/collection.model';
|
||||
import { Breadcrumb } from '../../breadcrumbs/breadcrumb/breadcrumb.model';
|
||||
import { getItemPageRoute } from '../../+item-page/item-page-routing.module';
|
||||
import { getCommunityPageRoute } from '../../+community-page/community-page-routing.module';
|
||||
import { getCollectionPageRoute } from '../../+collection-page/collection-page-routing.module';
|
||||
import { cold, getTestScheduler } from 'jasmine-marbles';
|
||||
import { getTestScheduler } from 'jasmine-marbles';
|
||||
import { getDSOPath } from '../../app-routing.module';
|
||||
import { DSONameService } from './dso-name.service';
|
||||
|
||||
fdescribe('DSOBreadcrumbsService', () => {
|
||||
describe('DSOBreadcrumbsService', () => {
|
||||
let service: DSOBreadcrumbsService;
|
||||
let linkService: any;
|
||||
let testItem;
|
||||
@@ -33,7 +28,7 @@ fdescribe('DSOBreadcrumbsService', () => {
|
||||
let collectionUUID;
|
||||
let communityUUID;
|
||||
|
||||
let objects: DSpaceObject[];
|
||||
let dsoNameService;
|
||||
|
||||
function init() {
|
||||
itemPath = '/items/';
|
||||
@@ -47,7 +42,9 @@ fdescribe('DSOBreadcrumbsService', () => {
|
||||
testCommunity = Object.assign(new Community(),
|
||||
{
|
||||
type: 'community',
|
||||
name: 'community',
|
||||
metadata: {
|
||||
'dc.title': [{value: 'community'}]
|
||||
},
|
||||
uuid: communityUUID,
|
||||
parentCommunity: observableOf(Object.assign(createSuccessfulRemoteDataObject(undefined), { statusCode: 204 })),
|
||||
|
||||
@@ -61,7 +58,9 @@ fdescribe('DSOBreadcrumbsService', () => {
|
||||
testCollection = Object.assign(new Collection(),
|
||||
{
|
||||
type: 'collection',
|
||||
name: 'collection',
|
||||
metadata: {
|
||||
'dc.title': [{value: 'collection'}]
|
||||
},
|
||||
uuid: collectionUUID,
|
||||
parentCommunity: createSuccessfulRemoteDataObject$(testCommunity),
|
||||
_links: {
|
||||
@@ -74,7 +73,9 @@ fdescribe('DSOBreadcrumbsService', () => {
|
||||
testItem = Object.assign(new Item(),
|
||||
{
|
||||
type: 'item',
|
||||
name: 'item',
|
||||
metadata: {
|
||||
'dc.title': [{value: 'item'}]
|
||||
},
|
||||
uuid: itemUUID,
|
||||
owningCollection: createSuccessfulRemoteDataObject$(testCollection),
|
||||
_links: {
|
||||
@@ -84,15 +85,15 @@ fdescribe('DSOBreadcrumbsService', () => {
|
||||
}
|
||||
);
|
||||
|
||||
objects = [testItem, testCollection, testCommunity];
|
||||
|
||||
dsoNameService = { getName: (dso) => getName(dso) }
|
||||
}
|
||||
|
||||
beforeEach(async(() => {
|
||||
init();
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
{ provide: LinkService, useValue: getMockLinkService() }
|
||||
{ provide: LinkService, useValue: getMockLinkService() },
|
||||
{ provide: DSONameService, useValue: dsoNameService }
|
||||
]
|
||||
}).compileComponents();
|
||||
}));
|
||||
@@ -100,18 +101,22 @@ fdescribe('DSOBreadcrumbsService', () => {
|
||||
beforeEach(() => {
|
||||
linkService = TestBed.get(LinkService);
|
||||
linkService.resolveLink.and.callFake((object, link) => object);
|
||||
service = new DSOBreadcrumbsService(linkService);
|
||||
service = new DSOBreadcrumbsService(linkService, dsoNameService);
|
||||
});
|
||||
|
||||
describe('getBreadcrumbs', () => {
|
||||
it('should return the breadcrumbs based on an Item', () => {
|
||||
const breadcrumbs = service.getBreadcrumbs(testItem, testItem._links.self);
|
||||
const expectedCrumbs = [
|
||||
new Breadcrumb(testCommunity.name, getDSOPath(testCommunity)),
|
||||
new Breadcrumb(testCollection.name, getDSOPath(testCollection)),
|
||||
new Breadcrumb(testItem.name, getDSOPath(testItem)),
|
||||
new Breadcrumb(getName(testCommunity), getDSOPath(testCommunity)),
|
||||
new Breadcrumb(getName(testCollection), getDSOPath(testCollection)),
|
||||
new Breadcrumb(getName(testItem), getDSOPath(testItem)),
|
||||
];
|
||||
getTestScheduler().expectObservable(breadcrumbs).toBe('(a|)', { a: expectedCrumbs });
|
||||
})
|
||||
});
|
||||
|
||||
function getName(dso: DSpaceObject): string {
|
||||
return dso.metadata['dc.title'][0].value
|
||||
}
|
||||
});
|
||||
|
@@ -12,6 +12,9 @@ import { RemoteData } from '../data/remote-data';
|
||||
import { hasValue } from '../../shared/empty.util';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
/**
|
||||
* Service to calculate DSpaceObject breadcrumbs for a single part of the route
|
||||
*/
|
||||
@Injectable()
|
||||
export class DSOBreadcrumbsService implements BreadcrumbsService<ChildHALResource & DSpaceObject> {
|
||||
constructor(
|
||||
@@ -21,6 +24,12 @@ export class DSOBreadcrumbsService implements BreadcrumbsService<ChildHALResourc
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to recursively calculate the breadcrumbs
|
||||
* This method returns the name and url of the key and all its parent DSO's recursively, top down
|
||||
* @param key The key (a DSpaceObject) used to resolve the breadcrumb
|
||||
* @param url The url to use as a link for this breadcrumb
|
||||
*/
|
||||
getBreadcrumbs(key: ChildHALResource & DSpaceObject, url: string): Observable<Breadcrumb[]> {
|
||||
const label = this.dsoNameService.getName(key);
|
||||
const crumb = new Breadcrumb(label, url);
|
||||
|
28
src/app/core/breadcrumbs/i18n-breadcrumb.resolver.spec.ts
Normal file
28
src/app/core/breadcrumbs/i18n-breadcrumb.resolver.spec.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { I18nBreadcrumbResolver } from './i18n-breadcrumb.resolver';
|
||||
|
||||
describe('I18nBreadcrumbResolver', () => {
|
||||
describe('resolve', () => {
|
||||
let resolver: I18nBreadcrumbResolver;
|
||||
let i18nBreadcrumbService: any;
|
||||
let i18nKey: string;
|
||||
let path: string;
|
||||
beforeEach(() => {
|
||||
i18nKey = 'example.key';
|
||||
path = 'rest.com/path/to/breadcrumb';
|
||||
i18nBreadcrumbService = {};
|
||||
resolver = new I18nBreadcrumbResolver(i18nBreadcrumbService);
|
||||
});
|
||||
|
||||
it('should resolve the breadcrumb config', () => {
|
||||
const resolvedConfig = resolver.resolve({ data: { breadcrumbKey: i18nKey }, url: [path] } as any, {} as any);
|
||||
const expectedConfig = { provider: i18nBreadcrumbService, key: i18nKey, url: path };
|
||||
expect(resolvedConfig).toEqual(expectedConfig);
|
||||
});
|
||||
|
||||
it('should resolve throw an error when no breadcrumbKey is defined', () => {
|
||||
expect(() => {
|
||||
resolver.resolve({ data: {} } as any, undefined)
|
||||
}).toThrow();
|
||||
});
|
||||
});
|
||||
});
|
@@ -5,7 +5,7 @@ import { I18nBreadcrumbsService } from './i18n-breadcrumbs.service';
|
||||
import { hasNoValue } from '../../shared/empty.util';
|
||||
|
||||
/**
|
||||
* The class that resolve the BreadcrumbConfig object for a route
|
||||
* The class that resolves a BreadcrumbConfig object with an i18n key string for a route
|
||||
*/
|
||||
@Injectable()
|
||||
export class I18nBreadcrumbResolver implements Resolve<BreadcrumbConfig<string>> {
|
||||
|
@@ -3,7 +3,7 @@ import { Breadcrumb } from '../../breadcrumbs/breadcrumb/breadcrumb.model';
|
||||
import { getTestScheduler } from 'jasmine-marbles';
|
||||
import { BREADCRUMB_MESSAGE_POSTFIX, I18nBreadcrumbsService } from './i18n-breadcrumbs.service';
|
||||
|
||||
fdescribe('I18nBreadcrumbsService', () => {
|
||||
describe('I18nBreadcrumbsService', () => {
|
||||
let service: I18nBreadcrumbsService;
|
||||
let exampleString;
|
||||
let exampleURL;
|
||||
|
@@ -3,10 +3,22 @@ import { BreadcrumbsService } from './breadcrumbs.service';
|
||||
import { Observable, of as observableOf } from 'rxjs';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
/**
|
||||
* The postfix for i18n breadcrumbs
|
||||
*/
|
||||
export const BREADCRUMB_MESSAGE_POSTFIX = '.breadcrumbs';
|
||||
|
||||
/**
|
||||
* Service to calculate i18n breadcrumbs for a single part of the route
|
||||
*/
|
||||
@Injectable()
|
||||
export class I18nBreadcrumbsService implements BreadcrumbsService<string> {
|
||||
|
||||
/**
|
||||
* Method to calculate the breadcrumbs
|
||||
* @param key The key used to resolve the breadcrumb
|
||||
* @param url The url to use as a link for this breadcrumb
|
||||
*/
|
||||
getBreadcrumbs(key: string, url: string): Observable<Breadcrumb[]> {
|
||||
return observableOf([new Breadcrumb(key + BREADCRUMB_MESSAGE_POSTFIX, url)]);
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@ import { Item } from '../shared/item.model';
|
||||
import { DSOBreadcrumbResolver } from './dso-breadcrumb.resolver';
|
||||
|
||||
/**
|
||||
* The class that resolve the BreadcrumbConfig object for a route
|
||||
* The class that resolves the BreadcrumbConfig object for an Item
|
||||
*/
|
||||
@Injectable()
|
||||
export class ItemBreadcrumbResolver extends DSOBreadcrumbResolver<Item> {
|
||||
|
@@ -13,7 +13,7 @@ const mockItem = Object.assign(new Item(), { metadata: { 'dc.description': [{ va
|
||||
const virtMD = Object.assign(new MetadataValue(), { value: organisation });
|
||||
const mockItemMetadataRepresentation = Object.assign(new ItemMetadataRepresentation(virtMD), mockItem);
|
||||
|
||||
describe('OrgUnitItemMetadataListElementComponent', () => {
|
||||
fdescribe('OrgUnitItemMetadataListElementComponent', () => {
|
||||
let comp: OrgUnitItemMetadataListElementComponent;
|
||||
let fixture: ComponentFixture<OrgUnitItemMetadataListElementComponent>;
|
||||
|
||||
|
Reference in New Issue
Block a user