mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
93803: Add tests for create, search & put
This commit is contained in:
@@ -16,10 +16,11 @@ import { NotificationsService } from '../../../shared/notifications/notification
|
||||
import { getMockRequestService } from '../../../shared/mocks/request.service.mock';
|
||||
import { HALEndpointServiceStub } from '../../../shared/testing/hal-endpoint-service.stub';
|
||||
import { getMockRemoteDataBuildService } from '../../../shared/mocks/remote-data-build.service.mock';
|
||||
import { followLink } from '../../../shared/utils/follow-link-config.model';
|
||||
import { TestScheduler } from 'rxjs/testing';
|
||||
import { RemoteData } from '../remote-data';
|
||||
import { RequestEntryState } from '../request-entry-state.model';
|
||||
import { createFailedRemoteDataObject, createSuccessfulRemoteDataObject } from '../../../shared/remote-data.utils';
|
||||
import { RequestParam } from '../../cache/models/request-param.model';
|
||||
import { RestRequestMethod } from '../rest-request-method';
|
||||
|
||||
const endpoint = 'https://rest.api/core';
|
||||
|
||||
@@ -31,10 +32,10 @@ class TestService extends CreateDataImpl<any> {
|
||||
protected halService: HALEndpointService,
|
||||
protected notificationsService: NotificationsService,
|
||||
) {
|
||||
super(undefined, requestService, rdbService, objectCache, halService, notificationsService, undefined);
|
||||
super('test', requestService, rdbService, objectCache, halService, notificationsService, undefined);
|
||||
}
|
||||
|
||||
public getBrowseEndpoint(options: FindListOptions = {}, linkPath: string = this.linkPath): Observable<string> {
|
||||
public getEndpoint(options: FindListOptions = {}, linkPath: string = this.linkPath): Observable<string> {
|
||||
return observableOf(endpoint);
|
||||
}
|
||||
}
|
||||
@@ -46,10 +47,14 @@ describe('CreateDataImpl', () => {
|
||||
let rdbService;
|
||||
let objectCache;
|
||||
let notificationsService;
|
||||
let selfLink;
|
||||
let linksToFollow;
|
||||
let testScheduler;
|
||||
let remoteDataMocks;
|
||||
let obj;
|
||||
|
||||
let MOCK_SUCCEEDED_RD;
|
||||
let MOCK_FAILED_RD;
|
||||
|
||||
let buildFromRequestUUIDSpy: jasmine.Spy;
|
||||
let createOnEndpointSpy: jasmine.Spy;
|
||||
|
||||
function initTestService(): TestService {
|
||||
requestService = getMockRequestService();
|
||||
@@ -67,19 +72,14 @@ describe('CreateDataImpl', () => {
|
||||
/* empty */
|
||||
},
|
||||
} as any;
|
||||
notificationsService = {} as NotificationsService;
|
||||
selfLink = 'https://rest.api/endpoint/1698f1d3-be98-4c51-9fd8-6bfedcbd59b7';
|
||||
linksToFollow = [
|
||||
followLink('a'),
|
||||
followLink('b'),
|
||||
];
|
||||
|
||||
testScheduler = new TestScheduler((actual, expected) => {
|
||||
// asserting the two objects are equal
|
||||
// e.g. using chai.
|
||||
expect(actual).toEqual(expected);
|
||||
notificationsService = jasmine.createSpyObj('notificationsService', {
|
||||
error: undefined,
|
||||
});
|
||||
|
||||
obj = {
|
||||
uuid: '1698f1d3-be98-4c51-9fd8-6bfedcbd59b7',
|
||||
};
|
||||
|
||||
const timeStamp = new Date().getTime();
|
||||
const msToLive = 15 * 60 * 1000;
|
||||
const payload = { foo: 'bar' };
|
||||
@@ -106,7 +106,88 @@ describe('CreateDataImpl', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
service = initTestService();
|
||||
|
||||
buildFromRequestUUIDSpy = spyOn(rdbService, 'buildFromRequestUUID').and.callThrough();
|
||||
createOnEndpointSpy = spyOn(service, 'createOnEndpoint').and.callThrough();
|
||||
|
||||
MOCK_SUCCEEDED_RD = createSuccessfulRemoteDataObject({});
|
||||
MOCK_FAILED_RD = createFailedRemoteDataObject('something went wrong');
|
||||
});
|
||||
|
||||
// todo: add specs (there were no ceate specs in original DataService suite!)
|
||||
describe('create', () => {
|
||||
it('should POST the object to the root endpoint with the given parameters and return the remote data', (done) => {
|
||||
const params = [
|
||||
new RequestParam('abc', 123), new RequestParam('def', 456)
|
||||
];
|
||||
buildFromRequestUUIDSpy.and.returnValue(observableOf(remoteDataMocks.Success));
|
||||
|
||||
service.create(obj, ...params).subscribe(out => {
|
||||
expect(createOnEndpointSpy).toHaveBeenCalledWith(obj, jasmine.anything());
|
||||
expect(requestService.send).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
method: RestRequestMethod.POST,
|
||||
uuid: requestService.generateRequestId(),
|
||||
href: 'https://rest.api/core?abc=123&def=456',
|
||||
body: JSON.stringify(obj),
|
||||
}));
|
||||
expect(buildFromRequestUUIDSpy).toHaveBeenCalledWith(requestService.generateRequestId());
|
||||
expect(out).toEqual(remoteDataMocks.Success);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('createOnEndpoint', () => {
|
||||
beforeEach(() => {
|
||||
buildFromRequestUUIDSpy.and.returnValue(observableOf(remoteDataMocks.Success));
|
||||
});
|
||||
|
||||
it('should send a POST request with the object as JSON', (done) => {
|
||||
service.createOnEndpoint(obj, observableOf('https://rest.api/core/custom?search')).subscribe(out => {
|
||||
expect(requestService.send).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
method: RestRequestMethod.POST,
|
||||
body: JSON.stringify(obj),
|
||||
}));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should send the POST request to the given endpoint', (done) => {
|
||||
|
||||
service.createOnEndpoint(obj, observableOf('https://rest.api/core/custom?search')).subscribe(out => {
|
||||
expect(requestService.send).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
method: RestRequestMethod.POST,
|
||||
href: 'https://rest.api/core/custom?search',
|
||||
}));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the remote data for the sent request', (done) => {
|
||||
service.createOnEndpoint(obj, observableOf('https://rest.api/core/custom?search')).subscribe(out => {
|
||||
expect(requestService.send).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
method: RestRequestMethod.POST,
|
||||
uuid: requestService.generateRequestId(),
|
||||
}));
|
||||
expect(buildFromRequestUUIDSpy).toHaveBeenCalledWith(requestService.generateRequestId());
|
||||
expect(notificationsService.error).not.toHaveBeenCalled();
|
||||
expect(out).toEqual(remoteDataMocks.Success);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should show an error notification if the request fails', (done) => {
|
||||
buildFromRequestUUIDSpy.and.returnValue(observableOf(remoteDataMocks.Error));
|
||||
|
||||
service.createOnEndpoint(obj, observableOf('https://rest.api/core/custom?search')).subscribe(out => {
|
||||
expect(requestService.send).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
method: RestRequestMethod.POST,
|
||||
uuid: requestService.generateRequestId(),
|
||||
}));
|
||||
expect(buildFromRequestUUIDSpy).toHaveBeenCalledWith(requestService.generateRequestId());
|
||||
expect(notificationsService.error).toHaveBeenCalled();
|
||||
expect(out).toEqual(remoteDataMocks.Error);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -15,11 +15,11 @@ import { Observable, of as observableOf } from 'rxjs';
|
||||
import { getMockRequestService } from '../../../shared/mocks/request.service.mock';
|
||||
import { HALEndpointServiceStub } from '../../../shared/testing/hal-endpoint-service.stub';
|
||||
import { getMockRemoteDataBuildService } from '../../../shared/mocks/remote-data-build.service.mock';
|
||||
import { followLink } from '../../../shared/utils/follow-link-config.model';
|
||||
import { TestScheduler } from 'rxjs/testing';
|
||||
import { RemoteData } from '../remote-data';
|
||||
import { RequestEntryState } from '../request-entry-state.model';
|
||||
import { PutDataImpl } from './put-data';
|
||||
import { RestRequestMethod } from '../rest-request-method';
|
||||
import { DSpaceObject } from '../../shared/dspace-object.model';
|
||||
|
||||
const endpoint = 'https://rest.api/core';
|
||||
|
||||
@@ -45,10 +45,11 @@ describe('PutDataImpl', () => {
|
||||
let rdbService;
|
||||
let objectCache;
|
||||
let selfLink;
|
||||
let linksToFollow;
|
||||
let testScheduler;
|
||||
let remoteDataMocks;
|
||||
|
||||
let obj;
|
||||
let buildFromRequestUUIDSpy: jasmine.Spy;
|
||||
|
||||
function initTestService(): TestService {
|
||||
requestService = getMockRequestService();
|
||||
halService = new HALEndpointServiceStub('url') as any;
|
||||
@@ -66,16 +67,6 @@ describe('PutDataImpl', () => {
|
||||
},
|
||||
} as any;
|
||||
selfLink = 'https://rest.api/endpoint/1698f1d3-be98-4c51-9fd8-6bfedcbd59b7';
|
||||
linksToFollow = [
|
||||
followLink('a'),
|
||||
followLink('b'),
|
||||
];
|
||||
|
||||
testScheduler = new TestScheduler((actual, expected) => {
|
||||
// asserting the two objects are equal
|
||||
// e.g. using chai.
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
|
||||
const timeStamp = new Date().getTime();
|
||||
const msToLive = 15 * 60 * 1000;
|
||||
@@ -102,7 +93,56 @@ describe('PutDataImpl', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
service = initTestService();
|
||||
|
||||
obj = Object.assign(new DSpaceObject(), {
|
||||
uuid: '1698f1d3-be98-4c51-9fd8-6bfedcbd59b7',
|
||||
metadata: { // recognized properties will be serialized
|
||||
['dc.title']: [
|
||||
{ language: 'en', value: 'some object' },
|
||||
]
|
||||
},
|
||||
data: [ 1, 2, 3, 4 ], // unrecognized properties won't be serialized
|
||||
_links: { self: { href: selfLink } },
|
||||
});
|
||||
|
||||
|
||||
buildFromRequestUUIDSpy = spyOn(rdbService, 'buildFromRequestUUID').and.returnValue(observableOf(remoteDataMocks.Success));
|
||||
});
|
||||
|
||||
// todo: add specs (there were no put specs in original DataService suite!)
|
||||
describe('put', () => {
|
||||
it('should send a PUT request with the serialized object', (done) => {
|
||||
service.put(obj).subscribe(() => {
|
||||
expect(requestService.send).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
method: RestRequestMethod.PUT,
|
||||
body: { // _links are not serialized
|
||||
uuid: obj.uuid,
|
||||
metadata: obj.metadata
|
||||
},
|
||||
}));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should send the PUT request to the object\'s self link', (done) => {
|
||||
service.put(obj).subscribe(() => {
|
||||
expect(requestService.send).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
method: RestRequestMethod.PUT,
|
||||
href: selfLink,
|
||||
}));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the remote data for the sent request', (done) => {
|
||||
service.put(obj).subscribe(out => {
|
||||
expect(requestService.send).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
method: RestRequestMethod.PUT,
|
||||
uuid: requestService.generateRequestId(),
|
||||
}));
|
||||
expect(buildFromRequestUUIDSpy).toHaveBeenCalledWith(requestService.generateRequestId());
|
||||
expect(out).toEqual(remoteDataMocks.Success);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -5,21 +5,13 @@
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
import { SearchData, SearchDataImpl } from './search-data';
|
||||
import createSpyObj = jasmine.createSpyObj;
|
||||
import { constructSearchEndpointDefault, SearchData, SearchDataImpl } from './search-data';
|
||||
import { FindListOptions } from '../find-list-options.model';
|
||||
import { followLink } from '../../../shared/utils/follow-link-config.model';
|
||||
import { RequestService } from '../request.service';
|
||||
import { RemoteDataBuildService } from '../../cache/builders/remote-data-build.service';
|
||||
import { ObjectCacheService } from '../../cache/object-cache.service';
|
||||
import { HALEndpointService } from '../../shared/hal-endpoint.service';
|
||||
import { Observable, of as observableOf } from 'rxjs';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { getMockRequestService } from '../../../shared/mocks/request.service.mock';
|
||||
import { HALEndpointServiceStub } from '../../../shared/testing/hal-endpoint-service.stub';
|
||||
import { getMockRemoteDataBuildService } from '../../../shared/mocks/remote-data-build.service.mock';
|
||||
import { TestScheduler } from 'rxjs/testing';
|
||||
import { RemoteData } from '../remote-data';
|
||||
import { RequestEntryState } from '../request-entry-state.model';
|
||||
import createSpyObj = jasmine.createSpyObj;
|
||||
|
||||
/**
|
||||
* Tests whether calls to `SearchData` methods are correctly patched through in a concrete data service that implements it
|
||||
@@ -61,80 +53,42 @@ export function testSearchDataImplementation(service: SearchData<any>, methods =
|
||||
|
||||
const endpoint = 'https://rest.api/core';
|
||||
|
||||
class TestService extends SearchDataImpl<any> {
|
||||
constructor(
|
||||
protected requestService: RequestService,
|
||||
protected rdbService: RemoteDataBuildService,
|
||||
protected objectCache: ObjectCacheService,
|
||||
protected halService: HALEndpointService,
|
||||
) {
|
||||
super(undefined, requestService, rdbService, objectCache, halService, undefined);
|
||||
}
|
||||
|
||||
public getBrowseEndpoint(options: FindListOptions = {}, linkPath: string = this.linkPath): Observable<string> {
|
||||
return observableOf(endpoint);
|
||||
}
|
||||
}
|
||||
|
||||
describe('SearchDataImpl', () => {
|
||||
let service: TestService;
|
||||
let service: SearchDataImpl<any>;
|
||||
let requestService;
|
||||
let halService;
|
||||
let rdbService;
|
||||
let objectCache;
|
||||
let selfLink;
|
||||
let linksToFollow;
|
||||
let testScheduler;
|
||||
let remoteDataMocks;
|
||||
|
||||
function initTestService(): TestService {
|
||||
let constructSearchEndpointSpy;
|
||||
let options;
|
||||
|
||||
function initTestService(): SearchDataImpl<any> {
|
||||
requestService = getMockRequestService();
|
||||
halService = new HALEndpointServiceStub('url') as any;
|
||||
halService = jasmine.createSpyObj('halService', {
|
||||
getEndpoint: observableOf(endpoint),
|
||||
});
|
||||
rdbService = getMockRemoteDataBuildService();
|
||||
objectCache = {
|
||||
|
||||
addPatch: () => {
|
||||
/* empty */
|
||||
},
|
||||
getObjectBySelfLink: () => {
|
||||
/* empty */
|
||||
},
|
||||
getByHref: () => {
|
||||
/* empty */
|
||||
},
|
||||
} as any;
|
||||
selfLink = 'https://rest.api/endpoint/1698f1d3-be98-4c51-9fd8-6bfedcbd59b7';
|
||||
linksToFollow = [
|
||||
followLink('a'),
|
||||
followLink('b'),
|
||||
];
|
||||
|
||||
testScheduler = new TestScheduler((actual, expected) => {
|
||||
// asserting the two objects are equal
|
||||
// e.g. using chai.
|
||||
expect(actual).toEqual(expected);
|
||||
constructSearchEndpointSpy = jasmine.createSpy('constructSearchEndpointSpy').and.callFake(constructSearchEndpointDefault);
|
||||
|
||||
options = Object.assign(new FindListOptions(), {
|
||||
elementsPerPage: 5,
|
||||
currentPage: 3,
|
||||
});
|
||||
|
||||
const timeStamp = new Date().getTime();
|
||||
const msToLive = 15 * 60 * 1000;
|
||||
const payload = { foo: 'bar' };
|
||||
const statusCodeSuccess = 200;
|
||||
const statusCodeError = 404;
|
||||
const errorMessage = 'not found';
|
||||
remoteDataMocks = {
|
||||
RequestPending: new RemoteData(undefined, msToLive, timeStamp, RequestEntryState.RequestPending, undefined, undefined, undefined),
|
||||
ResponsePending: new RemoteData(undefined, msToLive, timeStamp, RequestEntryState.ResponsePending, undefined, undefined, undefined),
|
||||
Success: new RemoteData(timeStamp, msToLive, timeStamp, RequestEntryState.Success, undefined, payload, statusCodeSuccess),
|
||||
SuccessStale: new RemoteData(timeStamp, msToLive, timeStamp, RequestEntryState.SuccessStale, undefined, payload, statusCodeSuccess),
|
||||
Error: new RemoteData(timeStamp, msToLive, timeStamp, RequestEntryState.Error, errorMessage, undefined, statusCodeError),
|
||||
ErrorStale: new RemoteData(timeStamp, msToLive, timeStamp, RequestEntryState.ErrorStale, errorMessage, undefined, statusCodeError),
|
||||
};
|
||||
|
||||
return new TestService(
|
||||
return new SearchDataImpl(
|
||||
'test',
|
||||
requestService,
|
||||
rdbService,
|
||||
objectCache,
|
||||
undefined,
|
||||
halService,
|
||||
undefined,
|
||||
constructSearchEndpointSpy,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -142,5 +96,56 @@ describe('SearchDataImpl', () => {
|
||||
service = initTestService();
|
||||
});
|
||||
|
||||
// todo: add specs (there were no search specs in original DataService suite!)
|
||||
describe('getSearchEndpoint', () => {
|
||||
it('should return the search endpoint for the given method', (done) => {
|
||||
(service as any).getSearchEndpoint('testMethod').subscribe(searchEndpoint => {
|
||||
expect(halService.getEndpoint).toHaveBeenCalledWith('test');
|
||||
expect(searchEndpoint).toBe('https://rest.api/core/search/testMethod');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should use constructSearchEndpoint to construct the search endpoint', (done) => {
|
||||
(service as any).getSearchEndpoint('testMethod').subscribe(() => {
|
||||
expect(constructSearchEndpointSpy).toHaveBeenCalledWith('https://rest.api/core', 'testMethod');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSearchByHref', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(service as any, 'getSearchEndpoint').and.callThrough();
|
||||
spyOn(service, 'buildHrefFromFindOptions').and.callThrough();
|
||||
});
|
||||
|
||||
it('should return the search endpoint with additional query parameters', (done) => {
|
||||
service.getSearchByHref('testMethod', options, ...linksToFollow).subscribe(href => {
|
||||
expect((service as any).getSearchEndpoint).toHaveBeenCalledWith('testMethod');
|
||||
expect(service.buildHrefFromFindOptions).toHaveBeenCalledWith(
|
||||
'https://rest.api/core/search/testMethod',
|
||||
options,
|
||||
[],
|
||||
...linksToFollow,
|
||||
);
|
||||
|
||||
expect(href).toBe('https://rest.api/core/search/testMethod?page=2&size=5&embed=a&embed=b');
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('searchBy', () => {
|
||||
it('should patch getSearchEndpoint into findListByHref and return the result', () => {
|
||||
spyOn(service, 'getSearchByHref').and.returnValue('endpoint' as any);
|
||||
spyOn(service, 'findListByHref').and.returnValue('resulting remote data' as any);
|
||||
|
||||
const out: any = service.searchBy('testMethod', options, false, true, ...linksToFollow);
|
||||
|
||||
expect(service.getSearchByHref).toHaveBeenCalledWith('testMethod', options, ...linksToFollow);
|
||||
expect(service.findListByHref).toHaveBeenCalledWith('endpoint', undefined, false, true);
|
||||
expect(out).toBe('resulting remote data');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -110,7 +110,7 @@ export class SearchDataImpl<T extends CacheableObject> extends BaseDataService<T
|
||||
searchBy(searchMethod: string, options: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig<T>[]): Observable<RemoteData<PaginatedList<T>>> {
|
||||
const hrefObs = this.getSearchByHref(searchMethod, options, ...linksToFollow);
|
||||
|
||||
return this.findListByHref(hrefObs, undefined, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
|
||||
return this.findListByHref(hrefObs, undefined, useCachedVersionIfAvailable, reRequestOnStale);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user