mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-14 13:33:03 +00:00
68930: rename forwardToRest, embed query param added to getIDHref, tests wip
This commit is contained in:
@@ -177,14 +177,14 @@ describe('DataService', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not include linksToFollow with forwardToRest = false', () => {
|
it('should not include linksToFollow with shootEmbed = false', () => {
|
||||||
const mockFollowLinkConfig: FollowLinkConfig<Item> = Object.assign(new FollowLinkConfig(), {
|
const mockFollowLinkConfig: FollowLinkConfig<Item> = Object.assign(new FollowLinkConfig(), {
|
||||||
name: 'bundles' as any,
|
name: 'bundles' as any,
|
||||||
forwardToRest: false,
|
shootEmbed: false,
|
||||||
});
|
});
|
||||||
const mockFollowLinkConfig2: FollowLinkConfig<Item> = Object.assign(new FollowLinkConfig(), {
|
const mockFollowLinkConfig2: FollowLinkConfig<Item> = Object.assign(new FollowLinkConfig(), {
|
||||||
name: 'owningCollection' as any,
|
name: 'owningCollection' as any,
|
||||||
forwardToRest: false,
|
shootEmbed: false,
|
||||||
});
|
});
|
||||||
const mockFollowLinkConfig3: FollowLinkConfig<Item> = Object.assign(new FollowLinkConfig(), {
|
const mockFollowLinkConfig3: FollowLinkConfig<Item> = Object.assign(new FollowLinkConfig(), {
|
||||||
name: 'templateItemOf' as any,
|
name: 'templateItemOf' as any,
|
||||||
@@ -215,6 +215,75 @@ describe('DataService', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getIDHref', () => {
|
||||||
|
const endpointMock = 'https://dspace7-internal.atmire.com/server/api/core/items';
|
||||||
|
const resourceIdMock = '003c99b4-d4fe-44b0-a945-e12182a7ca89';
|
||||||
|
|
||||||
|
it('should return endpoint', () => {
|
||||||
|
const result = (service as any).getIDHref(endpointMock, resourceIdMock);
|
||||||
|
expect(result).toEqual(endpointMock + '/' + resourceIdMock);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include single linksToFollow as embed', () => {
|
||||||
|
const mockFollowLinkConfig: FollowLinkConfig<Item> = Object.assign(new FollowLinkConfig(), {
|
||||||
|
name: 'bundles' as any,
|
||||||
|
});
|
||||||
|
const expected = `${endpointMock}/${resourceIdMock}?embed=bundles`;
|
||||||
|
const result = (service as any).getIDHref(endpointMock, resourceIdMock, mockFollowLinkConfig);
|
||||||
|
expect(result).toEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include multiple linksToFollow as embed', () => {
|
||||||
|
const mockFollowLinkConfig: FollowLinkConfig<Item> = Object.assign(new FollowLinkConfig(), {
|
||||||
|
name: 'bundles' as any,
|
||||||
|
});
|
||||||
|
const mockFollowLinkConfig2: FollowLinkConfig<Item> = Object.assign(new FollowLinkConfig(), {
|
||||||
|
name: 'owningCollection' as any,
|
||||||
|
});
|
||||||
|
const mockFollowLinkConfig3: FollowLinkConfig<Item> = Object.assign(new FollowLinkConfig(), {
|
||||||
|
name: 'templateItemOf' as any,
|
||||||
|
});
|
||||||
|
const expected = `${endpointMock}/${resourceIdMock}?embed=bundles&embed=owningCollection&embed=templateItemOf`;
|
||||||
|
const result = (service as any).getIDHref(endpointMock, resourceIdMock, mockFollowLinkConfig, mockFollowLinkConfig2, mockFollowLinkConfig3);
|
||||||
|
expect(result).toEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not include linksToFollow with shootEmbed = false', () => {
|
||||||
|
const mockFollowLinkConfig: FollowLinkConfig<Item> = Object.assign(new FollowLinkConfig(), {
|
||||||
|
name: 'bundles' as any,
|
||||||
|
shootEmbed: false,
|
||||||
|
});
|
||||||
|
const mockFollowLinkConfig2: FollowLinkConfig<Item> = Object.assign(new FollowLinkConfig(), {
|
||||||
|
name: 'owningCollection' as any,
|
||||||
|
shootEmbed: false,
|
||||||
|
});
|
||||||
|
const mockFollowLinkConfig3: FollowLinkConfig<Item> = Object.assign(new FollowLinkConfig(), {
|
||||||
|
name: 'templateItemOf' as any,
|
||||||
|
});
|
||||||
|
const expected = `${endpointMock}/${resourceIdMock}?embed=templateItemOf`;
|
||||||
|
const result = (service as any).getIDHref(endpointMock, resourceIdMock, mockFollowLinkConfig, mockFollowLinkConfig2, mockFollowLinkConfig3);
|
||||||
|
expect(result).toEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include nested linksToFollow 3lvl', () => {
|
||||||
|
const mockFollowLinkConfig3: FollowLinkConfig<Item> = Object.assign(new FollowLinkConfig(), {
|
||||||
|
name: 'relationships' as any,
|
||||||
|
});
|
||||||
|
const mockFollowLinkConfig2: FollowLinkConfig<Collection> = Object.assign(new FollowLinkConfig(), {
|
||||||
|
name: 'itemtemplate' as any,
|
||||||
|
linksToFollow: mockFollowLinkConfig3,
|
||||||
|
});
|
||||||
|
const mockFollowLinkConfig: FollowLinkConfig<Item> = Object.assign(new FollowLinkConfig(), {
|
||||||
|
name: 'owningCollection' as any,
|
||||||
|
linksToFollow: mockFollowLinkConfig2,
|
||||||
|
});
|
||||||
|
const expected = `${endpointMock}/${resourceIdMock}?embed=owningCollection/itemtemplate/relationships`;
|
||||||
|
const result = (service as any).getIDHref(endpointMock, resourceIdMock, mockFollowLinkConfig);
|
||||||
|
expect(result).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('patch', () => {
|
describe('patch', () => {
|
||||||
let operations;
|
let operations;
|
||||||
let selfLink;
|
let selfLink;
|
||||||
|
@@ -129,7 +129,6 @@ export abstract class DataService<T extends CacheableObject> {
|
|||||||
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
|
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
|
||||||
*/
|
*/
|
||||||
protected buildHrefFromFindOptions(href: string, options: FindListOptions, extraArgs: string[] = [], ...linksToFollow: Array<FollowLinkConfig<T>>): string {
|
protected buildHrefFromFindOptions(href: string, options: FindListOptions, extraArgs: string[] = [], ...linksToFollow: Array<FollowLinkConfig<T>>): string {
|
||||||
|
|
||||||
let args = [...extraArgs];
|
let args = [...extraArgs];
|
||||||
|
|
||||||
if (hasValue(options.currentPage) && typeof options.currentPage === 'number') {
|
if (hasValue(options.currentPage) && typeof options.currentPage === 'number') {
|
||||||
@@ -145,7 +144,7 @@ export abstract class DataService<T extends CacheableObject> {
|
|||||||
if (hasValue(options.startsWith)) {
|
if (hasValue(options.startsWith)) {
|
||||||
args = [...args, `startsWith=${options.startsWith}`];
|
args = [...args, `startsWith=${options.startsWith}`];
|
||||||
}
|
}
|
||||||
args = this.addEmbedParams(args, linksToFollow);
|
args = this.addEmbedParams(args, ...linksToFollow);
|
||||||
if (isNotEmpty(args)) {
|
if (isNotEmpty(args)) {
|
||||||
return new URLCombiner(href, `?${args.join('&')}`).toString();
|
return new URLCombiner(href, `?${args.join('&')}`).toString();
|
||||||
} else {
|
} else {
|
||||||
@@ -156,15 +155,15 @@ export abstract class DataService<T extends CacheableObject> {
|
|||||||
/**
|
/**
|
||||||
* Adds the embed options to the link for the request
|
* Adds the embed options to the link for the request
|
||||||
* @param args params for the query string
|
* @param args params for the query string
|
||||||
* @param linksToFollow links we want to embed in query string if forwardToRest is true
|
* @param linksToFollow links we want to embed in query string if shootEmbed is true
|
||||||
*/
|
*/
|
||||||
protected addEmbedParams(args: any, linksToFollow: Array<FollowLinkConfig<T>>) {
|
protected addEmbedParams(args: any, ...linksToFollow: Array<FollowLinkConfig<T>>) {
|
||||||
if (linksToFollow !== undefined) {
|
if (linksToFollow !== undefined) {
|
||||||
linksToFollow.forEach((linkToFollow: FollowLinkConfig<T>) => {
|
[...linksToFollow].forEach((linkToFollow: FollowLinkConfig<T>) => {
|
||||||
console.log('linksToFollow', linksToFollow)
|
console.log('linksToFollow', linksToFollow)
|
||||||
if (linkToFollow.forwardToRest) {
|
if (linkToFollow.shootEmbed) {
|
||||||
const embedString = 'embed=' + String(linkToFollow.name);
|
const embedString = 'embed=' + String(linkToFollow.name);
|
||||||
const embedWithNestedString = this.addNestedEmbeds(embedString, linkToFollow.linksToFollow);
|
const embedWithNestedString = this.addNestedEmbeds(embedString, ...linkToFollow.linksToFollow);
|
||||||
args = [...args, embedWithNestedString];
|
args = [...args, embedWithNestedString];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -174,17 +173,18 @@ export abstract class DataService<T extends CacheableObject> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Add the nested followLinks to the embed param, recursively, separated by a /
|
* Add the nested followLinks to the embed param, recursively, separated by a /
|
||||||
* @param embedString
|
* @param embedString embedString so far (recursive)
|
||||||
* @param linksToFollow
|
* @param linksToFollow links we want to embed in query string if shootEmbed is true
|
||||||
*/
|
*/
|
||||||
protected addNestedEmbeds(embedString: string, linksToFollow: Array<FollowLinkConfig<T>>): string {
|
protected addNestedEmbeds(embedString: string, ...linksToFollow: Array<FollowLinkConfig<T>>): string {
|
||||||
let nestEmbed = embedString;
|
let nestEmbed = embedString;
|
||||||
if (linksToFollow !== undefined) {
|
if (linksToFollow !== undefined) {
|
||||||
linksToFollow.forEach((linkToFollow: FollowLinkConfig<T>) => {
|
console.log('linksToFollow addNestedEmbed', linksToFollow);
|
||||||
if (linkToFollow.forwardToRest) {
|
[...linksToFollow].forEach((linkToFollow: FollowLinkConfig<T>) => {
|
||||||
|
if (linkToFollow.shootEmbed) {
|
||||||
nestEmbed = nestEmbed + '/' + String(linkToFollow.name);
|
nestEmbed = nestEmbed + '/' + String(linkToFollow.name);
|
||||||
if (linkToFollow.linksToFollow !== undefined) {
|
if (linkToFollow.linksToFollow !== undefined) {
|
||||||
nestEmbed = this.addNestedEmbeds(nestEmbed, linkToFollow.linksToFollow);
|
nestEmbed = this.addNestedEmbeds(nestEmbed, ...linkToFollow.linksToFollow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -227,12 +227,13 @@ export abstract class DataService<T extends CacheableObject> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the HREF for a specific object based on its identifier
|
* Create the HREF for a specific object based on its identifier; with possible embed query params based on linksToFollow
|
||||||
* @param endpoint The base endpoint for the type of object
|
* @param endpoint The base endpoint for the type of object
|
||||||
* @param resourceID The identifier for the object
|
* @param resourceID The identifier for the object
|
||||||
|
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
|
||||||
*/
|
*/
|
||||||
getIDHref(endpoint, resourceID): string {
|
getIDHref(endpoint, resourceID, ...linksToFollow: Array<FollowLinkConfig<T>>): string {
|
||||||
return `${endpoint}/${resourceID}`;
|
return this.buildHrefFromFindOptions(endpoint + '/' + resourceID, {}, [], ...linksToFollow);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -242,9 +243,9 @@ export abstract class DataService<T extends CacheableObject> {
|
|||||||
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
|
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
|
||||||
*/
|
*/
|
||||||
findById(id: string, ...linksToFollow: Array<FollowLinkConfig<T>>): Observable<RemoteData<T>> {
|
findById(id: string, ...linksToFollow: Array<FollowLinkConfig<T>>): Observable<RemoteData<T>> {
|
||||||
|
console.log('findById');
|
||||||
const hrefObs = this.halService.getEndpoint(this.linkPath).pipe(
|
const hrefObs = this.halService.getEndpoint(this.linkPath).pipe(
|
||||||
map((endpoint: string) => this.getIDHref(endpoint, encodeURIComponent(id))));
|
map((endpoint: string) => this.getIDHref(endpoint, encodeURIComponent(id), ...linksToFollow)));
|
||||||
|
|
||||||
hrefObs.pipe(
|
hrefObs.pipe(
|
||||||
find((href: string) => hasValue(href)))
|
find((href: string) => hasValue(href)))
|
||||||
|
@@ -6,6 +6,7 @@ import { Observable } from 'rxjs';
|
|||||||
import { take, tap } from 'rxjs/operators';
|
import { take, tap } from 'rxjs/operators';
|
||||||
import { hasValue } from '../../shared/empty.util';
|
import { hasValue } from '../../shared/empty.util';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
|
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
|
||||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||||
import { CoreState } from '../core.reducers';
|
import { CoreState } from '../core.reducers';
|
||||||
@@ -45,10 +46,11 @@ export class DsoRedirectDataService extends DataService<any> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getIDHref(endpoint, resourceID): string {
|
getIDHref(endpoint, resourceID, ...linksToFollow: Array<FollowLinkConfig<any>>): string {
|
||||||
// Supporting both identifier (pid) and uuid (dso) endpoints
|
// Supporting both identifier (pid) and uuid (dso) endpoints
|
||||||
return endpoint.replace(/\{\?id\}/, `?id=${resourceID}`)
|
return this.buildHrefFromFindOptions( endpoint.replace(/\{\?id\}/, `?id=${resourceID}`)
|
||||||
.replace(/\{\?uuid\}/, `?uuid=${resourceID}`);
|
.replace(/\{\?uuid\}/, `?uuid=${resourceID}`),
|
||||||
|
{}, [], ...linksToFollow);
|
||||||
}
|
}
|
||||||
|
|
||||||
findByIdAndIDType(id: string, identifierType = IdentifierType.UUID): Observable<RemoteData<FindByIDRequest>> {
|
findByIdAndIDType(id: string, identifierType = IdentifierType.UUID): Observable<RemoteData<FindByIDRequest>> {
|
||||||
|
@@ -3,6 +3,7 @@ import { Injectable } from '@angular/core';
|
|||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
|
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
|
||||||
import { dataService } from '../cache/builders/build-decorators';
|
import { dataService } from '../cache/builders/build-decorators';
|
||||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||||
@@ -31,8 +32,9 @@ class DataServiceImpl extends DataService<DSpaceObject> {
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
getIDHref(endpoint, resourceID): string {
|
getIDHref(endpoint, resourceID, ...linksToFollow: Array<FollowLinkConfig<DSpaceObject>>): string {
|
||||||
return endpoint.replace(/\{\?uuid\}/, `?uuid=${resourceID}`);
|
return this.buildHrefFromFindOptions( endpoint.replace(/\{\?uuid\}/, `?uuid=${resourceID}`),
|
||||||
|
{}, [], ...linksToFollow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -27,7 +27,7 @@ export class FollowLinkConfig<R extends HALResource> {
|
|||||||
/**
|
/**
|
||||||
* Forward to rest which links we're following, so these can already be embedded
|
* Forward to rest which links we're following, so these can already be embedded
|
||||||
*/
|
*/
|
||||||
forwardToRest? = true;
|
shootEmbed? = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,19 +41,19 @@ export class FollowLinkConfig<R extends HALResource> {
|
|||||||
* in a certain way
|
* in a certain way
|
||||||
* @param linksToFollow: a list of {@link FollowLinkConfig}s to
|
* @param linksToFollow: a list of {@link FollowLinkConfig}s to
|
||||||
* use on the retrieved object.
|
* use on the retrieved object.
|
||||||
* @param forwardToRest: boolean to check whether to forward info on followLinks to rest,
|
* @param shootEmbed: boolean to check whether to forward info on followLinks to rest,
|
||||||
* so these can be embedded, default true
|
* so these can be embedded, default true
|
||||||
*/
|
*/
|
||||||
export const followLink = <R extends HALResource>(
|
export const followLink = <R extends HALResource>(
|
||||||
linkName: keyof R['_links'],
|
linkName: keyof R['_links'],
|
||||||
findListOptions?: FindListOptions,
|
findListOptions?: FindListOptions,
|
||||||
forwardToRest = true,
|
shootEmbed = true,
|
||||||
...linksToFollow: Array<FollowLinkConfig<any>>
|
...linksToFollow: Array<FollowLinkConfig<any>>
|
||||||
): FollowLinkConfig<R> => {
|
): FollowLinkConfig<R> => {
|
||||||
return {
|
return {
|
||||||
name: linkName,
|
name: linkName,
|
||||||
findListOptions,
|
findListOptions,
|
||||||
forwardToRest,
|
shootEmbed: shootEmbed,
|
||||||
linksToFollow
|
linksToFollow
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user