55946: Fixed tests and added JSDocs

This commit is contained in:
Kristof De Langhe
2018-11-27 16:45:53 +01:00
parent 2053078a16
commit 930af49030
5 changed files with 70 additions and 21 deletions

View File

@@ -20,7 +20,6 @@ import { FormsModule } from '@angular/forms';
import { SharedModule } from '../../shared/shared.module'; import { SharedModule } from '../../shared/shared.module';
import { Collection } from '../../core/shared/collection.model'; import { Collection } from '../../core/shared/collection.model';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { Observable } from 'rxjs/Observable';
import { PaginatedSearchOptions } from '../../+search-page/paginated-search-options.model'; import { PaginatedSearchOptions } from '../../+search-page/paginated-search-options.model';
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
@@ -28,7 +27,6 @@ import { EventEmitter, NgModule } from '@angular/core';
import { HostWindowService } from '../../shared/host-window.service'; import { HostWindowService } from '../../shared/host-window.service';
import { HostWindowServiceStub } from '../../shared/testing/host-window-service-stub'; import { HostWindowServiceStub } from '../../shared/testing/host-window-service-stub';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { RestResponse } from '../../core/cache/response-cache.models';
import { PaginatedList } from '../../core/data/paginated-list'; import { PaginatedList } from '../../core/data/paginated-list';
import { PageInfo } from '../../core/shared/page-info.model'; import { PageInfo } from '../../core/shared/page-info.model';
import { CollectionDataService } from '../../core/data/collection-data.service'; import { CollectionDataService } from '../../core/data/collection-data.service';
@@ -38,6 +36,9 @@ import { ItemSelectComponent } from '../../shared/object-select/item-select/item
import { ObjectSelectService } from '../../shared/object-select/object-select.service'; import { ObjectSelectService } from '../../shared/object-select/object-select.service';
import { ObjectSelectServiceStub } from '../../shared/testing/object-select-service-stub'; import { ObjectSelectServiceStub } from '../../shared/testing/object-select-service-stub';
import { VarDirective } from '../../shared/utils/var.directive'; import { VarDirective } from '../../shared/utils/var.directive';
import { Observable } from 'rxjs/internal/Observable';
import { of } from 'rxjs/internal/observable/of';
import { RestResponse } from '../../core/cache/response.models';
describe('CollectionItemMapperComponent', () => { describe('CollectionItemMapperComponent', () => {
let comp: CollectionItemMapperComponent; let comp: CollectionItemMapperComponent;
@@ -55,7 +56,7 @@ describe('CollectionItemMapperComponent', () => {
name: 'test-collection' name: 'test-collection'
}); });
const mockCollectionRD: RemoteData<Collection> = new RemoteData<Collection>(false, false, true, null, mockCollection); const mockCollectionRD: RemoteData<Collection> = new RemoteData<Collection>(false, false, true, null, mockCollection);
const mockSearchOptions = Observable.of(new PaginatedSearchOptions({ const mockSearchOptions = of(new PaginatedSearchOptions({
pagination: Object.assign(new PaginationComponentOptions(), { pagination: Object.assign(new PaginationComponentOptions(), {
id: 'search-page-configuration', id: 'search-page-configuration',
pageSize: 10, pageSize: 10,
@@ -71,21 +72,27 @@ describe('CollectionItemMapperComponent', () => {
paginatedSearchOptions: mockSearchOptions paginatedSearchOptions: mockSearchOptions
}; };
const itemDataServiceStub = { const itemDataServiceStub = {
mapToCollection: () => Observable.of(new RestResponse(true, '200')) mapToCollection: () => of(new RestResponse(true, '200'))
}; };
const activatedRouteStub = new ActivatedRouteStub({}, { collection: mockCollectionRD }); const activatedRouteStub = new ActivatedRouteStub({}, { collection: mockCollectionRD });
const translateServiceStub = { const translateServiceStub = {
get: () => Observable.of('test-message of collection ' + mockCollection.name), get: () => of('test-message of collection ' + mockCollection.name),
onLangChange: new EventEmitter(), onLangChange: new EventEmitter(),
onTranslationChange: new EventEmitter(), onTranslationChange: new EventEmitter(),
onDefaultLangChange: new EventEmitter() onDefaultLangChange: new EventEmitter()
}; };
const emptyList = new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), [])); const emptyList = new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), []));
const searchServiceStub = Object.assign(new SearchServiceStub(), { const searchServiceStub = Object.assign(new SearchServiceStub(), {
search: () => Observable.of(emptyList) search: () => of(emptyList),
/* tslint:disable:no-empty */
clearDiscoveryRequests: () => {}
/* tslint:enable:no-empty */
}); });
const collectionDataServiceStub = { const collectionDataServiceStub = {
getMappedItems: () => Observable.of(emptyList) getMappedItems: () => of(emptyList),
/* tslint:disable:no-empty */
clearMappingItemsRequests: () => {}
/* tslint:enable:no-empty */
}; };
beforeEach(async(() => { beforeEach(async(() => {
@@ -139,7 +146,7 @@ describe('CollectionItemMapperComponent', () => {
}); });
it('should display an error message if at least one mapping was unsuccessful', () => { it('should display an error message if at least one mapping was unsuccessful', () => {
spyOn(itemDataService, 'mapToCollection').and.returnValue(Observable.of(new RestResponse(false, '404'))); spyOn(itemDataService, 'mapToCollection').and.returnValue(of(new RestResponse(false, '404')));
comp.mapItems(ids); comp.mapItems(ids);
expect(notificationsService.success).not.toHaveBeenCalled(); expect(notificationsService.success).not.toHaveBeenCalled();
expect(notificationsService.error).toHaveBeenCalled(); expect(notificationsService.error).toHaveBeenCalled();

View File

@@ -8,14 +8,11 @@ import { SearchConfigurationService } from '../../../+search-page/search-service
import { SearchService } from '../../../+search-page/search-service/search.service'; import { SearchService } from '../../../+search-page/search-service/search.service';
import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { ItemDataService } from '../../../core/data/item-data.service'; import { ItemDataService } from '../../../core/data/item-data.service';
import { Collection } from '../../../core/shared/collection.model';
import { RemoteData } from '../../../core/data/remote-data'; import { RemoteData } from '../../../core/data/remote-data';
import { Observable } from 'rxjs/Observable';
import { PaginatedSearchOptions } from '../../../+search-page/paginated-search-options.model'; import { PaginatedSearchOptions } from '../../../+search-page/paginated-search-options.model';
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model'; import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model';
import { RouterStub } from '../../../shared/testing/router-stub'; import { RouterStub } from '../../../shared/testing/router-stub';
import { RestResponse } from '../../../core/cache/response-cache.models';
import { ActivatedRouteStub } from '../../../shared/testing/active-router-stub'; import { ActivatedRouteStub } from '../../../shared/testing/active-router-stub';
import { EventEmitter } from '@angular/core'; import { EventEmitter } from '@angular/core';
import { SearchServiceStub } from '../../../shared/testing/search-service-stub'; import { SearchServiceStub } from '../../../shared/testing/search-service-stub';
@@ -29,9 +26,11 @@ import { HostWindowService } from '../../../shared/host-window.service';
import { HostWindowServiceStub } from '../../../shared/testing/host-window-service-stub'; import { HostWindowServiceStub } from '../../../shared/testing/host-window-service-stub';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { Item } from '../../../core/shared/item.model'; import { Item } from '../../../core/shared/item.model';
import { CollectionDataService } from '../../../core/data/collection-data.service';
import { ObjectSelectService } from '../../../shared/object-select/object-select.service'; import { ObjectSelectService } from '../../../shared/object-select/object-select.service';
import { ObjectSelectServiceStub } from '../../../shared/testing/object-select-service-stub'; import { ObjectSelectServiceStub } from '../../../shared/testing/object-select-service-stub';
import { Observable } from 'rxjs/internal/Observable';
import { of } from 'rxjs/internal/observable/of';
import { RestResponse } from '../../../core/cache/response.models';
describe('ItemCollectionMapperComponent', () => { describe('ItemCollectionMapperComponent', () => {
let comp: ItemCollectionMapperComponent; let comp: ItemCollectionMapperComponent;
@@ -49,7 +48,7 @@ describe('ItemCollectionMapperComponent', () => {
name: 'test-item' name: 'test-item'
}); });
const mockItemRD: RemoteData<Item> = new RemoteData<Item>(false, false, true, null, mockItem); const mockItemRD: RemoteData<Item> = new RemoteData<Item>(false, false, true, null, mockItem);
const mockSearchOptions = Observable.of(new PaginatedSearchOptions({ const mockSearchOptions = of(new PaginatedSearchOptions({
pagination: Object.assign(new PaginationComponentOptions(), { pagination: Object.assign(new PaginationComponentOptions(), {
id: 'search-page-configuration', id: 'search-page-configuration',
pageSize: 10, pageSize: 10,
@@ -65,16 +64,22 @@ describe('ItemCollectionMapperComponent', () => {
}; };
const mockCollectionsRD = new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), [])); const mockCollectionsRD = new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), []));
const itemDataServiceStub = { const itemDataServiceStub = {
mapToCollection: () => Observable.of(new RestResponse(true, '200')), mapToCollection: () => of(new RestResponse(true, '200')),
removeMappingFromCollection: () => Observable.of(new RestResponse(true, '200')), removeMappingFromCollection: () => of(new RestResponse(true, '200')),
getMappedCollections: () => Observable.of(mockCollectionsRD) getMappedCollections: () => of(mockCollectionsRD),
/* tslint:disable:no-empty */
clearMappedCollectionsRequests: () => {}
/* tslint:enable:no-empty */
}; };
const searchServiceStub = Object.assign(new SearchServiceStub(), { const searchServiceStub = Object.assign(new SearchServiceStub(), {
search: () => Observable.of(mockCollectionsRD) search: () => of(mockCollectionsRD),
/* tslint:disable:no-empty */
clearDiscoveryRequests: () => {}
/* tslint:enable:no-empty */
}); });
const activatedRouteStub = new ActivatedRouteStub({}, { item: mockItemRD }); const activatedRouteStub = new ActivatedRouteStub({}, { item: mockItemRD });
const translateServiceStub = { const translateServiceStub = {
get: () => Observable.of('test-message of item ' + mockItem.name), get: () => of('test-message of item ' + mockItem.name),
onLangChange: new EventEmitter(), onLangChange: new EventEmitter(),
onTranslationChange: new EventEmitter(), onTranslationChange: new EventEmitter(),
onDefaultLangChange: new EventEmitter() onDefaultLangChange: new EventEmitter()
@@ -130,7 +135,7 @@ describe('ItemCollectionMapperComponent', () => {
}); });
it('should display an error message if at least one mapping was unsuccessful', () => { it('should display an error message if at least one mapping was unsuccessful', () => {
spyOn(itemDataService, 'mapToCollection').and.returnValue(Observable.of(new RestResponse(false, '404'))); spyOn(itemDataService, 'mapToCollection').and.returnValue(of(new RestResponse(false, '404')));
comp.mapCollections(ids); comp.mapCollections(ids);
expect(notificationsService.success).not.toHaveBeenCalled(); expect(notificationsService.success).not.toHaveBeenCalled();
expect(notificationsService.error).toHaveBeenCalled(); expect(notificationsService.error).toHaveBeenCalled();
@@ -152,7 +157,7 @@ describe('ItemCollectionMapperComponent', () => {
}); });
it('should display an error message if the removal of at least one mapping was unsuccessful', () => { it('should display an error message if the removal of at least one mapping was unsuccessful', () => {
spyOn(itemDataService, 'removeMappingFromCollection').and.returnValue(Observable.of(new RestResponse(false, '404'))); spyOn(itemDataService, 'removeMappingFromCollection').and.returnValue(of(new RestResponse(false, '404')));
comp.removeMappings(ids); comp.removeMappings(ids);
expect(notificationsService.success).not.toHaveBeenCalled(); expect(notificationsService.success).not.toHaveBeenCalled();
expect(notificationsService.error).toHaveBeenCalled(); expect(notificationsService.error).toHaveBeenCalled();

View File

@@ -37,6 +37,10 @@ export class CollectionDataService extends ComColDataService<NormalizedCollectio
super(); super();
} }
/**
* Fetches the endpoint used for mapping items to a collection
* @param collectionId The id of the collection to map items to
*/
getMappingItemsEndpoint(collectionId): Observable<string> { getMappingItemsEndpoint(collectionId): Observable<string> {
return this.halService.getEndpoint(this.linkPath).pipe( return this.halService.getEndpoint(this.linkPath).pipe(
map((endpoint: string) => this.getFindByIDHref(endpoint, collectionId)), map((endpoint: string) => this.getFindByIDHref(endpoint, collectionId)),
@@ -44,6 +48,11 @@ export class CollectionDataService extends ComColDataService<NormalizedCollectio
); );
} }
/**
* Fetches a list of items that are mapped to a collection
* @param collectionId The id of the collection
* @param searchOptions Search options to sort or filter out items
*/
getMappedItems(collectionId: string, searchOptions?: PaginatedSearchOptions): Observable<RemoteData<PaginatedList<DSpaceObject>>> { getMappedItems(collectionId: string, searchOptions?: PaginatedSearchOptions): Observable<RemoteData<PaginatedList<DSpaceObject>>> {
const requestUuid = this.requestService.generateRequestId(); const requestUuid = this.requestService.generateRequestId();
@@ -68,6 +77,10 @@ export class CollectionDataService extends ComColDataService<NormalizedCollectio
return this.rdbService.buildList(href$); return this.rdbService.buildList(href$);
} }
/**
* Clears all requests (from cache) connected to the mappingItems endpoint
* @param collectionId
*/
clearMappingItemsRequests(collectionId: string) { clearMappingItemsRequests(collectionId: string) {
this.getMappingItemsEndpoint(collectionId).pipe(take(1)).subscribe((href: string) => { this.getMappingItemsEndpoint(collectionId).pipe(take(1)).subscribe((href: string) => {
this.requestService.removeByHrefSubstring(href); this.requestService.removeByHrefSubstring(href);

View File

@@ -54,6 +54,12 @@ export class ItemDataService extends DataService<NormalizedItem, Item> {
distinctUntilChanged(),); distinctUntilChanged(),);
} }
/**
* Fetches the endpoint used for mapping an item to a collection,
* or for fetching all collections the item is mapped to if no collection is provided
* @param itemId The item's id
* @param collectionId The collection's id (optional)
*/
public getMappingCollectionsEndpoint(itemId: string, collectionId?: string): Observable<string> { public getMappingCollectionsEndpoint(itemId: string, collectionId?: string): Observable<string> {
return this.halService.getEndpoint(this.linkPath).pipe( return this.halService.getEndpoint(this.linkPath).pipe(
map((endpoint: string) => this.getFindByIDHref(endpoint, itemId)), map((endpoint: string) => this.getFindByIDHref(endpoint, itemId)),
@@ -61,6 +67,11 @@ export class ItemDataService extends DataService<NormalizedItem, Item> {
); );
} }
/**
* Removes the mapping of an item from a collection
* @param itemId The item's id
* @param collectionId The collection's id
*/
public removeMappingFromCollection(itemId: string, collectionId: string): Observable<RestResponse> { public removeMappingFromCollection(itemId: string, collectionId: string): Observable<RestResponse> {
return this.getMappingCollectionsEndpoint(itemId, collectionId).pipe( return this.getMappingCollectionsEndpoint(itemId, collectionId).pipe(
isNotEmptyOperator(), isNotEmptyOperator(),
@@ -72,6 +83,11 @@ export class ItemDataService extends DataService<NormalizedItem, Item> {
); );
} }
/**
* Maps an item to a collection
* @param itemId The item's id
* @param collectionId The collection's id
*/
public mapToCollection(itemId: string, collectionId: string): Observable<RestResponse> { public mapToCollection(itemId: string, collectionId: string): Observable<RestResponse> {
return this.getMappingCollectionsEndpoint(itemId, collectionId).pipe( return this.getMappingCollectionsEndpoint(itemId, collectionId).pipe(
isNotEmptyOperator(), isNotEmptyOperator(),
@@ -83,6 +99,10 @@ export class ItemDataService extends DataService<NormalizedItem, Item> {
); );
} }
/**
* Fetches all collections the item is mapped to
* @param itemId The item's id
*/
public getMappedCollections(itemId: string): Observable<RemoteData<PaginatedList<Collection>>> { public getMappedCollections(itemId: string): Observable<RemoteData<PaginatedList<Collection>>> {
const request$ = this.getMappingCollectionsEndpoint(itemId).pipe( const request$ = this.getMappingCollectionsEndpoint(itemId).pipe(
isNotEmptyOperator(), isNotEmptyOperator(),
@@ -102,6 +122,10 @@ export class ItemDataService extends DataService<NormalizedItem, Item> {
return this.rdbService.toRemoteDataObservable(requestEntry$, payload$); return this.rdbService.toRemoteDataObservable(requestEntry$, payload$);
} }
/**
* Clears all requests (from cache) connected to the mappingCollections endpoint
* @param itemId
*/
public clearMappedCollectionsRequests(itemId: string) { public clearMappedCollectionsRequests(itemId: string) {
this.getMappingCollectionsEndpoint(itemId).pipe(take(1)).subscribe((href: string) => { this.getMappingCollectionsEndpoint(itemId).pipe(take(1)).subscribe((href: string) => {
this.requestService.removeByHrefSubstring(href); this.requestService.removeByHrefSubstring(href);

View File

@@ -17,7 +17,7 @@
<tbody> <tbody>
<tr *ngFor="let collection of collectionsRD?.payload?.page"> <tr *ngFor="let collection of collectionsRD?.payload?.page">
<td><input class="collection-checkbox" [ngModel]="getSelected(collection.id) | async" (change)="switch(collection.id)" type="checkbox" name="{{collection.id}}"></td> <td><input class="collection-checkbox" [ngModel]="getSelected(collection.id) | async" (change)="switch(collection.id)" type="checkbox" name="{{collection.id}}"></td>
<td><a [routerLink]="['/collection', collection.id]">{{collection.name}}</a></td> <td><a [routerLink]="['/collections', collection.id]">{{collection.name}}</a></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>