mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-11 20:13:07 +00:00
refactored getScopeEndpoint method for Collection- and CommunityDataService
This commit is contained in:
@@ -41,7 +41,5 @@ export class TopLevelCommunityListComponent {
|
||||
elementsPerPage: data.pageSize,
|
||||
sort: { field: data.sortField, direction: data.sortDirection }
|
||||
});
|
||||
this.cds.getScopedEndpoint('7669c72a-3f2a-451f-a3b9-9210e7a4c02f')
|
||||
.subscribe((c) => console.log('communities', c))
|
||||
}
|
||||
}
|
||||
|
@@ -142,7 +142,7 @@ describe('BrowseService', () => {
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
|
||||
it('should configure a new BrowseEndpointRequest', (done) => {
|
||||
it('should configure a new BrowseEndpointRequest', (done: DoneFn) => {
|
||||
const metadatumKey = 'dc.date.issued';
|
||||
const linkName = 'items';
|
||||
const expected = new BrowseEndpointRequest(browsesEndpointURL);
|
||||
|
@@ -1,25 +1,18 @@
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { Store } from '@ngrx/store';
|
||||
|
||||
import { DataService } from './data.service';
|
||||
import { Collection } from '../shared/collection.model';
|
||||
import { ResponseCacheService } from '../cache/response-cache.service';
|
||||
import { NormalizedCollection } from '../cache/models/normalized-collection.model';
|
||||
import { CoreState } from '../core.reducers';
|
||||
import { RequestService } from './request.service';
|
||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||
import { GLOBAL_CONFIG, GlobalConfig } from '../../../config';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { CommunityDataService } from './community-data.service';
|
||||
import { FindByIDRequest } from './request.models';
|
||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||
import { NormalizedCollection } from '../cache/models/normalized-collection.model';
|
||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||
import { NormalizedCommunity } from '../cache/models/normalized-community.model';
|
||||
import { isNotEmpty } from '../../shared/empty.util';
|
||||
import { ResponseCacheEntry } from '../cache/response-cache.reducer';
|
||||
import { DSOSuccessResponse, RestResponse } from '../cache/response-cache.models';
|
||||
import { ResponseCacheService } from '../cache/response-cache.service';
|
||||
import { CoreState } from '../core.reducers';
|
||||
import { Collection } from '../shared/collection.model';
|
||||
import { ComColDataService } from './comcol-data.service';
|
||||
import { CommunityDataService } from './community-data.service';
|
||||
import { RequestService } from './request.service';
|
||||
|
||||
@Injectable()
|
||||
export class CollectionDataService extends DataService<NormalizedCollection, Collection> {
|
||||
export class CollectionDataService extends ComColDataService<NormalizedCollection, Collection> {
|
||||
protected linkName = 'collections';
|
||||
|
||||
constructor(
|
||||
@@ -28,47 +21,9 @@ export class CollectionDataService extends DataService<NormalizedCollection, Col
|
||||
protected rdbService: RemoteDataBuildService,
|
||||
protected store: Store<CoreState>,
|
||||
@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
|
||||
private cds: CommunityDataService,
|
||||
protected cds: CommunityDataService,
|
||||
protected objectCache: ObjectCacheService
|
||||
) {
|
||||
super(NormalizedCollection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the scoped endpoint URL by fetching the object with
|
||||
* the given scopeID and returning its HAL link with this
|
||||
* data-service's linkName
|
||||
*
|
||||
* @param {string} scopeID
|
||||
* the id of the scope object
|
||||
* @return { Observable<string> }
|
||||
* an Observable<string> containing the scoped URL
|
||||
*/
|
||||
public getScopedEndpoint(scopeID: string): Observable<string> {
|
||||
const scopeCommunityHrefObs = this.cds.getEndpoint()
|
||||
.flatMap((endpoint: string) => this.cds.getFindByIDHref(endpoint, scopeID))
|
||||
.filter((href: string) => isNotEmpty(href))
|
||||
.take(1)
|
||||
.do((href: string) => {
|
||||
const request = new FindByIDRequest(href, scopeID);
|
||||
setTimeout(() => {
|
||||
this.requestService.configure(request);
|
||||
}, 0);
|
||||
});
|
||||
|
||||
const [successResponse, errorResponse] = scopeCommunityHrefObs
|
||||
.flatMap((href: string) => this.responseCache.get(href))
|
||||
.map((entry: ResponseCacheEntry) => entry.response)
|
||||
.share()
|
||||
.partition((response: RestResponse) => response.isSuccessful);
|
||||
|
||||
return Observable.merge(
|
||||
errorResponse.flatMap((response: DSOSuccessResponse) =>
|
||||
Observable.throw(new Error(`The Community with scope ${scopeID} couldn't be retrieved`))),
|
||||
successResponse
|
||||
.flatMap((response: DSOSuccessResponse) => this.objectCache.getByUUID(scopeID, NormalizedCommunity))
|
||||
.map((nc: NormalizedCommunity) => nc._links[this.linkName])
|
||||
.filter((href) => isNotEmpty(href))
|
||||
).distinctUntilChanged();
|
||||
}
|
||||
}
|
||||
|
@@ -1,20 +1,45 @@
|
||||
import { CollectionDataService } from './collection-data.service';
|
||||
import { ResponseCacheService } from '../cache/response-cache.service';
|
||||
import { RequestService } from './request.service';
|
||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||
import { CoreState } from '../core.reducers';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { GlobalConfig } from '../../../config';
|
||||
import { CommunityDataService } from './community-data.service';
|
||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||
import { cold, getTestScheduler, hot } from 'jasmine-marbles';
|
||||
import { FindByIDRequest } from './request.models';
|
||||
import { NormalizedCommunity } from '../cache/models/normalized-community.model';
|
||||
import { TestScheduler } from 'rxjs/Rx';
|
||||
import { GlobalConfig } from '../../../config';
|
||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||
import { NormalizedCommunity } from '../cache/models/normalized-community.model';
|
||||
import { CacheableObject } from '../cache/object-cache.reducer';
|
||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||
import { ResponseCacheService } from '../cache/response-cache.service';
|
||||
import { CoreState } from '../core.reducers';
|
||||
import { ComColDataService } from './comcol-data.service';
|
||||
import { CommunityDataService } from './community-data.service';
|
||||
import { FindByIDRequest } from './request.models';
|
||||
import { RequestService } from './request.service';
|
||||
|
||||
describe('CollectionDataService', () => {
|
||||
const LINK_NAME = 'test';
|
||||
|
||||
/* tslint:disable:max-classes-per-file */
|
||||
class NormalizedTestObject implements CacheableObject {
|
||||
self: string;
|
||||
}
|
||||
|
||||
class TestService extends ComColDataService<NormalizedTestObject, any> {
|
||||
protected linkName = LINK_NAME;
|
||||
|
||||
constructor(
|
||||
protected responseCache: ResponseCacheService,
|
||||
protected requestService: RequestService,
|
||||
protected rdbService: RemoteDataBuildService,
|
||||
protected store: Store<CoreState>,
|
||||
protected EnvConfig: GlobalConfig,
|
||||
protected cds: CommunityDataService,
|
||||
protected objectCache: ObjectCacheService
|
||||
) {
|
||||
super(NormalizedTestObject);
|
||||
}
|
||||
}
|
||||
/* tslint:enable:max-classes-per-file */
|
||||
|
||||
describe('ComColDataService', () => {
|
||||
let scheduler: TestScheduler;
|
||||
let service: CollectionDataService;
|
||||
let service: TestService;
|
||||
let responseCache: ResponseCacheService;
|
||||
let requestService: RequestService;
|
||||
let cds: CommunityDataService;
|
||||
@@ -27,7 +52,7 @@ describe('CollectionDataService', () => {
|
||||
const scopeID = 'd9d30c0c-69b7-4369-8397-ca67c888974d';
|
||||
const communitiesEndpoint = 'https://rest.api/core/communities';
|
||||
const communityEndpoint = `${communitiesEndpoint}/${scopeID}`;
|
||||
const scopedCollectionsEndpoint = `${communityEndpoint}/collections`;
|
||||
const scopedEndpoint = `${communityEndpoint}/${LINK_NAME}`;
|
||||
|
||||
function initMockCommunityDataService(): CommunityDataService {
|
||||
return jasmine.createSpyObj('responseCache', {
|
||||
@@ -53,15 +78,15 @@ describe('CollectionDataService', () => {
|
||||
getByUUID: cold('d-', {
|
||||
d: {
|
||||
_links: {
|
||||
collections: scopedCollectionsEndpoint
|
||||
[LINK_NAME]: scopedEndpoint
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function initTestCollectionDataService(): CollectionDataService {
|
||||
return new CollectionDataService(
|
||||
function initTestService(): TestService {
|
||||
return new TestService(
|
||||
responseCache,
|
||||
requestService,
|
||||
rdbService,
|
||||
@@ -77,12 +102,12 @@ describe('CollectionDataService', () => {
|
||||
scheduler = getTestScheduler();
|
||||
});
|
||||
|
||||
it('should configure a new FindByIDRequest for the scope Community', (done) => {
|
||||
it('should configure a new FindByIDRequest for the scope Community', (done: DoneFn) => {
|
||||
cds = initMockCommunityDataService();
|
||||
requestService = initMockRequestService();
|
||||
objectCache = initMockObjectCacheService();
|
||||
responseCache = initMockResponceCacheService(true);
|
||||
service = initTestCollectionDataService();
|
||||
service = initTestService();
|
||||
|
||||
const expected = new FindByIDRequest(communityEndpoint, scopeID);
|
||||
|
||||
@@ -101,7 +126,7 @@ describe('CollectionDataService', () => {
|
||||
requestService = initMockRequestService();
|
||||
objectCache = initMockObjectCacheService();
|
||||
responseCache = initMockResponceCacheService(true);
|
||||
service = initTestCollectionDataService();
|
||||
service = initTestService();
|
||||
});
|
||||
|
||||
it('should fetch the scope Community from the cache', () => {
|
||||
@@ -110,9 +135,9 @@ describe('CollectionDataService', () => {
|
||||
expect(objectCache.getByUUID).toHaveBeenCalledWith(scopeID, NormalizedCommunity);
|
||||
});
|
||||
|
||||
it('should return the endpoint to fetch collections within the given scope', () => {
|
||||
it('should return the endpoint to fetch resources within the given scope', () => {
|
||||
const result = service.getScopedEndpoint(scopeID);
|
||||
const expected = cold('--e-', { e: scopedCollectionsEndpoint });
|
||||
const expected = cold('--e-', { e: scopedEndpoint });
|
||||
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
@@ -124,7 +149,7 @@ describe('CollectionDataService', () => {
|
||||
requestService = initMockRequestService();
|
||||
objectCache = initMockObjectCacheService();
|
||||
responseCache = initMockResponceCacheService(false);
|
||||
service = initTestCollectionDataService();
|
||||
service = initTestService();
|
||||
});
|
||||
|
||||
it('should throw an error', () => {
|
54
src/app/core/data/comcol-data.service.ts
Normal file
54
src/app/core/data/comcol-data.service.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { isNotEmpty } from '../../shared/empty.util';
|
||||
import { NormalizedCommunity } from '../cache/models/normalized-community.model';
|
||||
import { CacheableObject } from '../cache/object-cache.reducer';
|
||||
import { DSOSuccessResponse, RestResponse } from '../cache/response-cache.models';
|
||||
import { ResponseCacheEntry } from '../cache/response-cache.reducer';
|
||||
import { CommunityDataService } from './community-data.service';
|
||||
|
||||
import { DataService } from './data.service';
|
||||
import { FindByIDRequest } from './request.models';
|
||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||
|
||||
export abstract class ComColDataService<TNormalized extends CacheableObject, TDomain> extends DataService<TNormalized, TDomain> {
|
||||
protected abstract cds: CommunityDataService;
|
||||
protected abstract objectCache: ObjectCacheService;
|
||||
|
||||
/**
|
||||
* Get the scoped endpoint URL by fetching the object with
|
||||
* the given scopeID and returning its HAL link with this
|
||||
* data-service's linkName
|
||||
*
|
||||
* @param {string} scopeID
|
||||
* the id of the scope object
|
||||
* @return { Observable<string> }
|
||||
* an Observable<string> containing the scoped URL
|
||||
*/
|
||||
public getScopedEndpoint(scopeID: string): Observable<string> {
|
||||
const scopeCommunityHrefObs = this.cds.getEndpoint()
|
||||
.flatMap((endpoint: string) => this.cds.getFindByIDHref(endpoint, scopeID))
|
||||
.filter((href: string) => isNotEmpty(href))
|
||||
.take(1)
|
||||
.do((href: string) => {
|
||||
const request = new FindByIDRequest(href, scopeID);
|
||||
setTimeout(() => {
|
||||
this.requestService.configure(request);
|
||||
}, 0);
|
||||
});
|
||||
|
||||
const [successResponse, errorResponse] = scopeCommunityHrefObs
|
||||
.flatMap((href: string) => this.responseCache.get(href))
|
||||
.map((entry: ResponseCacheEntry) => entry.response)
|
||||
.share()
|
||||
.partition((response: RestResponse) => response.isSuccessful);
|
||||
|
||||
return Observable.merge(
|
||||
errorResponse.flatMap((response: DSOSuccessResponse) =>
|
||||
Observable.throw(new Error(`The Community with scope ${scopeID} couldn't be retrieved`))),
|
||||
successResponse
|
||||
.flatMap((response: DSOSuccessResponse) => this.objectCache.getByUUID(scopeID, NormalizedCommunity))
|
||||
.map((nc: NormalizedCommunity) => nc._links[this.linkName])
|
||||
.filter((href) => isNotEmpty(href))
|
||||
).distinctUntilChanged();
|
||||
}
|
||||
}
|
@@ -1,23 +1,20 @@
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
|
||||
import { Store } from '@ngrx/store';
|
||||
|
||||
import { DataService } from './data.service';
|
||||
import { Community } from '../shared/community.model';
|
||||
import { ResponseCacheService } from '../cache/response-cache.service';
|
||||
import { NormalizedCommunity } from '../cache/models/normalized-community.model';
|
||||
import { CoreState } from '../core.reducers';
|
||||
import { RequestService } from './request.service';
|
||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||
import { GLOBAL_CONFIG, GlobalConfig } from '../../../config';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { isNotEmpty } from '../../shared/empty.util';
|
||||
import { FindByIDRequest } from './request.models';
|
||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||
import { NormalizedCommunity } from '../cache/models/normalized-community.model';
|
||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||
import { ResponseCacheService } from '../cache/response-cache.service';
|
||||
import { CoreState } from '../core.reducers';
|
||||
import { Community } from '../shared/community.model';
|
||||
import { ComColDataService } from './comcol-data.service';
|
||||
import { RequestService } from './request.service';
|
||||
|
||||
@Injectable()
|
||||
export class CommunityDataService extends DataService<NormalizedCommunity, Community> {
|
||||
export class CommunityDataService extends ComColDataService<NormalizedCommunity, Community> {
|
||||
protected linkName = 'communities';
|
||||
protected cds = this;
|
||||
|
||||
constructor(
|
||||
protected responseCache: ResponseCacheService,
|
||||
@@ -29,33 +26,4 @@ export class CommunityDataService extends DataService<NormalizedCommunity, Commu
|
||||
) {
|
||||
super(NormalizedCommunity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the scoped endpoint URL by fetching the object with
|
||||
* the given scopeID and returning its HAL link with this
|
||||
* data-service's linkName
|
||||
*
|
||||
* @param {string} scopeID
|
||||
* the id of the scope object
|
||||
* @return { Observable<string> }
|
||||
* an Observable<string> containing the scoped URL
|
||||
*/
|
||||
public getScopedEndpoint(scopeID: string): Observable<string> {
|
||||
this.getEndpoint()
|
||||
.map((endpoint: string) => this.getFindByIDHref(endpoint, scopeID))
|
||||
.filter((href: string) => isNotEmpty(href))
|
||||
.take(1)
|
||||
.subscribe((href: string) => {
|
||||
const request = new FindByIDRequest(href, scopeID);
|
||||
setTimeout(() => {
|
||||
this.requestService.configure(request);
|
||||
}, 0);
|
||||
});
|
||||
|
||||
return this.objectCache.getByUUID(scopeID, NormalizedCommunity)
|
||||
.map((nc: NormalizedCommunity) => nc._links[this.linkName])
|
||||
.filter((href) => isNotEmpty(href))
|
||||
.distinctUntilChanged();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@ export abstract class DataService<TNormalized extends CacheableObject, TDomain>
|
||||
protected abstract EnvConfig: GlobalConfig;
|
||||
|
||||
constructor(
|
||||
private normalizedResourceType: GenericConstructor<TNormalized>,
|
||||
protected normalizedResourceType: GenericConstructor<TNormalized>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
Reference in New Issue
Block a user