mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00

Data services that implement *Data interfaces should include the appropriate test functions in their specs. These go over all methods in the interface & check that they're "wired up" correctly. See e.g. the change in ExternalSourceDataService for an issue that is easy to miss but was highlighted by these new tests
226 lines
8.6 KiB
TypeScript
226 lines
8.6 KiB
TypeScript
/**
|
|
* The contents of this file are subject to the license and copyright
|
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
|
* tree and available online at
|
|
*
|
|
* http://www.dspace.org/license/
|
|
*/
|
|
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 { FindListOptions } from '../find-list-options.model';
|
|
import { Observable, of as observableOf } from 'rxjs';
|
|
import { CreateData, CreateDataImpl } from './create-data';
|
|
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
|
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 { 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';
|
|
import { DSpaceObject } from '../../shared/dspace-object.model';
|
|
|
|
/**
|
|
* Tests whether calls to `CreateData` methods are correctly patched through in a concrete data service that implements it
|
|
*/
|
|
export function testCreateDataImplementation(serviceFactory: () => CreateData<any>) {
|
|
let service;
|
|
|
|
describe('CreateData implementation', () => {
|
|
const OBJ = Object.assign(new DSpaceObject(), {
|
|
uuid: '08eec68f-45e4-47a3-80c5-f0beb5627079',
|
|
});
|
|
const PARAMS = [
|
|
new RequestParam('abc', 123), new RequestParam('def', 456),
|
|
];
|
|
|
|
beforeAll(() => {
|
|
service = serviceFactory();
|
|
|
|
(service as any).createData = jasmine.createSpyObj('createData', {
|
|
create: 'TEST create',
|
|
});
|
|
});
|
|
|
|
it('should handle calls to create', () => {
|
|
const out: any = service.create(OBJ, ...PARAMS);
|
|
|
|
expect((service as any).createData.create).toHaveBeenCalledWith(OBJ, ...PARAMS);
|
|
expect(out).toBe('TEST create');
|
|
});
|
|
});
|
|
}
|
|
|
|
const endpoint = 'https://rest.api/core';
|
|
|
|
class TestService extends CreateDataImpl<any> {
|
|
constructor(
|
|
protected requestService: RequestService,
|
|
protected rdbService: RemoteDataBuildService,
|
|
protected objectCache: ObjectCacheService,
|
|
protected halService: HALEndpointService,
|
|
protected notificationsService: NotificationsService,
|
|
) {
|
|
super('test', requestService, rdbService, objectCache, halService, notificationsService, undefined);
|
|
}
|
|
|
|
public getEndpoint(options: FindListOptions = {}, linkPath: string = this.linkPath): Observable<string> {
|
|
return observableOf(endpoint);
|
|
}
|
|
}
|
|
|
|
describe('CreateDataImpl', () => {
|
|
let service: TestService;
|
|
let requestService;
|
|
let halService;
|
|
let rdbService;
|
|
let objectCache;
|
|
let notificationsService;
|
|
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();
|
|
halService = new HALEndpointServiceStub('url') as any;
|
|
rdbService = getMockRemoteDataBuildService();
|
|
objectCache = {
|
|
|
|
addPatch: () => {
|
|
/* empty */
|
|
},
|
|
getObjectBySelfLink: () => {
|
|
/* empty */
|
|
},
|
|
getByHref: () => {
|
|
/* empty */
|
|
},
|
|
} as any;
|
|
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' };
|
|
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(
|
|
requestService,
|
|
rdbService,
|
|
objectCache,
|
|
halService,
|
|
notificationsService,
|
|
);
|
|
}
|
|
|
|
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');
|
|
});
|
|
|
|
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();
|
|
});
|
|
});
|
|
});
|
|
});
|