mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-11 12:03:03 +00:00
refactored getScopeEndpoint method for Collection- and CommunityDataService
This commit is contained in:
@@ -41,7 +41,5 @@ export class TopLevelCommunityListComponent {
|
|||||||
elementsPerPage: data.pageSize,
|
elementsPerPage: data.pageSize,
|
||||||
sort: { field: data.sortField, direction: data.sortDirection }
|
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);
|
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 metadatumKey = 'dc.date.issued';
|
||||||
const linkName = 'items';
|
const linkName = 'items';
|
||||||
const expected = new BrowseEndpointRequest(browsesEndpointURL);
|
const expected = new BrowseEndpointRequest(browsesEndpointURL);
|
||||||
|
@@ -1,25 +1,18 @@
|
|||||||
import { Inject, Injectable } from '@angular/core';
|
import { Inject, Injectable } from '@angular/core';
|
||||||
import { Store } from '@ngrx/store';
|
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 { GLOBAL_CONFIG, GlobalConfig } from '../../../config';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||||
import { CommunityDataService } from './community-data.service';
|
import { NormalizedCollection } from '../cache/models/normalized-collection.model';
|
||||||
import { FindByIDRequest } from './request.models';
|
|
||||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||||
import { NormalizedCommunity } from '../cache/models/normalized-community.model';
|
import { ResponseCacheService } from '../cache/response-cache.service';
|
||||||
import { isNotEmpty } from '../../shared/empty.util';
|
import { CoreState } from '../core.reducers';
|
||||||
import { ResponseCacheEntry } from '../cache/response-cache.reducer';
|
import { Collection } from '../shared/collection.model';
|
||||||
import { DSOSuccessResponse, RestResponse } from '../cache/response-cache.models';
|
import { ComColDataService } from './comcol-data.service';
|
||||||
|
import { CommunityDataService } from './community-data.service';
|
||||||
|
import { RequestService } from './request.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CollectionDataService extends DataService<NormalizedCollection, Collection> {
|
export class CollectionDataService extends ComColDataService<NormalizedCollection, Collection> {
|
||||||
protected linkName = 'collections';
|
protected linkName = 'collections';
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@@ -28,47 +21,9 @@ export class CollectionDataService extends DataService<NormalizedCollection, Col
|
|||||||
protected rdbService: RemoteDataBuildService,
|
protected rdbService: RemoteDataBuildService,
|
||||||
protected store: Store<CoreState>,
|
protected store: Store<CoreState>,
|
||||||
@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
|
@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
|
||||||
private cds: CommunityDataService,
|
protected cds: CommunityDataService,
|
||||||
protected objectCache: ObjectCacheService
|
protected objectCache: ObjectCacheService
|
||||||
) {
|
) {
|
||||||
super(NormalizedCollection);
|
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 { 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 { 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 { 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 scheduler: TestScheduler;
|
||||||
let service: CollectionDataService;
|
let service: TestService;
|
||||||
let responseCache: ResponseCacheService;
|
let responseCache: ResponseCacheService;
|
||||||
let requestService: RequestService;
|
let requestService: RequestService;
|
||||||
let cds: CommunityDataService;
|
let cds: CommunityDataService;
|
||||||
@@ -27,7 +52,7 @@ describe('CollectionDataService', () => {
|
|||||||
const scopeID = 'd9d30c0c-69b7-4369-8397-ca67c888974d';
|
const scopeID = 'd9d30c0c-69b7-4369-8397-ca67c888974d';
|
||||||
const communitiesEndpoint = 'https://rest.api/core/communities';
|
const communitiesEndpoint = 'https://rest.api/core/communities';
|
||||||
const communityEndpoint = `${communitiesEndpoint}/${scopeID}`;
|
const communityEndpoint = `${communitiesEndpoint}/${scopeID}`;
|
||||||
const scopedCollectionsEndpoint = `${communityEndpoint}/collections`;
|
const scopedEndpoint = `${communityEndpoint}/${LINK_NAME}`;
|
||||||
|
|
||||||
function initMockCommunityDataService(): CommunityDataService {
|
function initMockCommunityDataService(): CommunityDataService {
|
||||||
return jasmine.createSpyObj('responseCache', {
|
return jasmine.createSpyObj('responseCache', {
|
||||||
@@ -53,15 +78,15 @@ describe('CollectionDataService', () => {
|
|||||||
getByUUID: cold('d-', {
|
getByUUID: cold('d-', {
|
||||||
d: {
|
d: {
|
||||||
_links: {
|
_links: {
|
||||||
collections: scopedCollectionsEndpoint
|
[LINK_NAME]: scopedEndpoint
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initTestCollectionDataService(): CollectionDataService {
|
function initTestService(): TestService {
|
||||||
return new CollectionDataService(
|
return new TestService(
|
||||||
responseCache,
|
responseCache,
|
||||||
requestService,
|
requestService,
|
||||||
rdbService,
|
rdbService,
|
||||||
@@ -77,12 +102,12 @@ describe('CollectionDataService', () => {
|
|||||||
scheduler = getTestScheduler();
|
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();
|
cds = initMockCommunityDataService();
|
||||||
requestService = initMockRequestService();
|
requestService = initMockRequestService();
|
||||||
objectCache = initMockObjectCacheService();
|
objectCache = initMockObjectCacheService();
|
||||||
responseCache = initMockResponceCacheService(true);
|
responseCache = initMockResponceCacheService(true);
|
||||||
service = initTestCollectionDataService();
|
service = initTestService();
|
||||||
|
|
||||||
const expected = new FindByIDRequest(communityEndpoint, scopeID);
|
const expected = new FindByIDRequest(communityEndpoint, scopeID);
|
||||||
|
|
||||||
@@ -101,7 +126,7 @@ describe('CollectionDataService', () => {
|
|||||||
requestService = initMockRequestService();
|
requestService = initMockRequestService();
|
||||||
objectCache = initMockObjectCacheService();
|
objectCache = initMockObjectCacheService();
|
||||||
responseCache = initMockResponceCacheService(true);
|
responseCache = initMockResponceCacheService(true);
|
||||||
service = initTestCollectionDataService();
|
service = initTestService();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fetch the scope Community from the cache', () => {
|
it('should fetch the scope Community from the cache', () => {
|
||||||
@@ -110,9 +135,9 @@ describe('CollectionDataService', () => {
|
|||||||
expect(objectCache.getByUUID).toHaveBeenCalledWith(scopeID, NormalizedCommunity);
|
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 result = service.getScopedEndpoint(scopeID);
|
||||||
const expected = cold('--e-', { e: scopedCollectionsEndpoint });
|
const expected = cold('--e-', { e: scopedEndpoint });
|
||||||
|
|
||||||
expect(result).toBeObservable(expected);
|
expect(result).toBeObservable(expected);
|
||||||
});
|
});
|
||||||
@@ -124,7 +149,7 @@ describe('CollectionDataService', () => {
|
|||||||
requestService = initMockRequestService();
|
requestService = initMockRequestService();
|
||||||
objectCache = initMockObjectCacheService();
|
objectCache = initMockObjectCacheService();
|
||||||
responseCache = initMockResponceCacheService(false);
|
responseCache = initMockResponceCacheService(false);
|
||||||
service = initTestCollectionDataService();
|
service = initTestService();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error', () => {
|
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 { Inject, Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { Store } from '@ngrx/store';
|
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 { GLOBAL_CONFIG, GlobalConfig } from '../../../config';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||||
import { isNotEmpty } from '../../shared/empty.util';
|
import { NormalizedCommunity } from '../cache/models/normalized-community.model';
|
||||||
import { FindByIDRequest } from './request.models';
|
|
||||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
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()
|
@Injectable()
|
||||||
export class CommunityDataService extends DataService<NormalizedCommunity, Community> {
|
export class CommunityDataService extends ComColDataService<NormalizedCommunity, Community> {
|
||||||
protected linkName = 'communities';
|
protected linkName = 'communities';
|
||||||
|
protected cds = this;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected responseCache: ResponseCacheService,
|
protected responseCache: ResponseCacheService,
|
||||||
@@ -29,33 +26,4 @@ export class CommunityDataService extends DataService<NormalizedCommunity, Commu
|
|||||||
) {
|
) {
|
||||||
super(NormalizedCommunity);
|
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;
|
protected abstract EnvConfig: GlobalConfig;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private normalizedResourceType: GenericConstructor<TNormalized>,
|
protected normalizedResourceType: GenericConstructor<TNormalized>,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user