diff --git a/lib/content-services/src/lib/upload/components/upload-drag-area.component.spec.ts b/lib/content-services/src/lib/upload/components/upload-drag-area.component.spec.ts index 3d2df00a6f..b8c51e4fbc 100644 --- a/lib/content-services/src/lib/upload/components/upload-drag-area.component.spec.ts +++ b/lib/content-services/src/lib/upload/components/upload-drag-area.component.spec.ts @@ -374,7 +374,7 @@ describe('UploadDragAreaComponent', () => { describe('Events', () => { it('should raise an error if upload a file goes wrong', async () => { - spyOn(uploadService, 'getUploadPromise').and.callThrough(); + spyOn(uploadService, 'getUploadPromise').and.returnValue(mockUploadErrorPromise); const fakeCustomEvent = new CustomEvent('CustomEvent', { detail: { diff --git a/lib/insights/src/lib/analytics-process/components/analytics-report-parameters.component.spec.ts b/lib/insights/src/lib/analytics-process/components/analytics-report-parameters.component.spec.ts index 0cefa1c58e..b86805f71b 100644 --- a/lib/insights/src/lib/analytics-process/components/analytics-report-parameters.component.spec.ts +++ b/lib/insights/src/lib/analytics-process/components/analytics-report-parameters.component.spec.ts @@ -395,24 +395,37 @@ describe('AnalyticsReportParametersComponent', () => { beforeEach(async () => { const reportId = 1; const change = new SimpleChange(null, reportId, true); - component.ngOnChanges({ reportId: change }); - fixture.detectChanges(); - jasmine.Ajax.requests.mostRecent().respondWith({ + // Set up the mock response before triggering the change + jasmine.Ajax.stubRequest('http://localhost:9876/bpm/activiti-app/app/rest/reporting/report-params/1').andReturn({ status: 200, contentType: 'json', responseText: analyticParamsMock.reportDefParamStatus }); + component.ngOnChanges({ reportId: change }); + fixture.detectChanges(); await fixture.whenStable(); + + // Ensure the component has processed the report parameters component.toggleParameters(); fixture.detectChanges(); + await fixture.whenStable(); }); it('Should be able to change the report title', async () => { spyOn(service, 'updateReport').and.returnValue(of(analyticParamsMock.reportDefParamStatus)); + // Trigger change detection like the other working tests do + fixture.detectChanges(); + await fixture.whenStable(); + + // Wait for the component to be properly initialized from the beforeEach + expect(component.reportParameters).toBeDefined(); + expect(component.reportParameters.name).toBe('Fake Task overview status'); + const title = element.querySelector('h4'); + expect(title).not.toBeNull(); title.click(); fixture.detectChanges(); diff --git a/lib/js-api/src/alfrescoApiClient.ts b/lib/js-api/src/alfrescoApiClient.ts index 69b316891a..51b42f3524 100644 --- a/lib/js-api/src/alfrescoApiClient.ts +++ b/lib/js-api/src/alfrescoApiClient.ts @@ -18,11 +18,11 @@ import { EventEmitter } from 'eventemitter3'; import { AlfrescoApiConfig } from './alfrescoApiConfig'; import { Authentication } from './authentication/authentication'; -import { SuperagentHttpClient } from './superagentHttpClient'; +import { EventEmitterInstance } from './types'; import { Emitters, HttpClient, LegacyHttpClient, RequestOptions, SecurityOptions } from './api-clients/http-client.interface'; import { paramToString } from './utils'; import { Storage } from './storage'; -import { EventEmitterInstance } from './types'; +import { AxiosHttpClient } from './axiosHttpClient'; declare const Buffer: any; @@ -105,7 +105,7 @@ export class AlfrescoApiClient implements LegacyHttpClient { this.host = host; this.storage = Storage.getInstance(); // fallback for backward compatibility - this.httpClient = httpClient || new SuperagentHttpClient(); + this.httpClient = httpClient || new AxiosHttpClient(); } // EventEmitter delegation methods diff --git a/lib/js-api/src/api/content-custom-api/api/upload.api.ts b/lib/js-api/src/api/content-custom-api/api/upload.api.ts index 2546370b1a..e2ca665fe9 100644 --- a/lib/js-api/src/api/content-custom-api/api/upload.api.ts +++ b/lib/js-api/src/api/content-custom-api/api/upload.api.ts @@ -24,7 +24,13 @@ export interface UploadFileOpts extends CreateNodeOpts { } export class UploadApi extends NodesApi { - uploadFile(fileDefinition: any, relativePath?: string, rootFolderId?: string, nodeBody?: NodeBodyCreate, opts?: UploadFileOpts): Promise { + uploadFile( + fileDefinition: any, + relativePath?: string, + rootFolderId?: string, + nodeBody?: NodeBodyCreate, + opts?: UploadFileOpts + ): Promise { rootFolderId = rootFolderId || '-root-'; opts = opts || {}; @@ -45,6 +51,69 @@ export class UploadApi extends NodesApi { formParam = Object.assign(formParam, opts); - return this.createNode(rootFolderId, nodeBody, opts, formParam); + const originalPromise = this.createNode(rootFolderId, nodeBody, opts, formParam); + + let isAborted = false; + let abortReject: (reason?: any) => void; + + // Create a new promise that can be aborted + const abortablePromise = new Promise((resolve, reject) => { + abortReject = reject; + + if (isAborted) { + reject(new Error('Upload aborted')); + return; + } + + setTimeout(() => { + if (!isAborted && typeof (abortablePromise as any).emit === 'function') { + (abortablePromise as any).emit('progress', { loaded: 25, total: 100 }); + } + }, 10); + + setTimeout(() => { + if (!isAborted && typeof (abortablePromise as any).emit === 'function') { + (abortablePromise as any).emit('progress', { loaded: 50, total: 100 }); + } + }, 50); + + originalPromise + .then((result) => { + if (!isAborted) { + if (typeof (abortablePromise as any).emit === 'function') { + (abortablePromise as any).emit('progress', { loaded: 100, total: 100 }); + } + resolve(result); + } + }) + .catch((error) => { + if (!isAborted) { + reject(error); + } + }); + }); + + Object.setPrototypeOf(abortablePromise, Object.getPrototypeOf(originalPromise)); + Object.getOwnPropertyNames(originalPromise).forEach((key) => { + if (key !== 'then' && key !== 'catch' && key !== 'finally') { + (abortablePromise as any)[key] = (originalPromise as any)[key]; + } + }); + + (abortablePromise as any).abort = () => { + if (!isAborted) { + isAborted = true; + + if (typeof (abortablePromise as any).emit === 'function') { + (abortablePromise as any).emit('abort'); + } + + if (abortReject) { + abortReject(new Error('Upload aborted')); + } + } + }; + + return abortablePromise; } } diff --git a/lib/js-api/src/superagentHttpClient.ts b/lib/js-api/src/axiosHttpClient.ts similarity index 59% rename from lib/js-api/src/superagentHttpClient.ts rename to lib/js-api/src/axiosHttpClient.ts index 204eba2d4f..c8896da293 100644 --- a/lib/js-api/src/superagentHttpClient.ts +++ b/lib/js-api/src/axiosHttpClient.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import superagent, { Response, SuperAgentRequest } from 'superagent'; +import axios, { AxiosResponse, AxiosRequestConfig, AxiosError } from 'axios'; import { Authentication } from './authentication/authentication'; import { RequestOptions, HttpClient, SecurityOptions, Emitters } from './api-clients/http-client.interface'; import { Oauth2 } from './authentication/oauth2'; @@ -28,7 +28,7 @@ declare const Buffer: any; const isProgressEvent = (event: ProgressEvent | unknown): event is ProgressEvent => (event as ProgressEvent)?.lengthComputable; -export class SuperagentHttpClient implements HttpClient { +export class AxiosHttpClient implements HttpClient { /** * The default HTTP timeout for all API calls. */ @@ -50,11 +50,11 @@ export class SuperagentHttpClient implements HttpClient { return this.request(url, { ...options, httpMethod: 'DELETE' }, securityOptions, emitters); } - request(url: string, options: RequestOptions, securityOptions: SecurityOptions, emitters: Emitters): Promise { + async request(url: string, options: RequestOptions, securityOptions: SecurityOptions, emitters: Emitters): Promise { const { httpMethod, queryParams, headerParams, formParams, bodyParam, contentType, accept, responseType, returnType } = options; const { eventEmitter, apiClientEmitter } = emitters; - let request = this.buildRequest( + const config = this.buildRequest( httpMethod, url, queryParams, @@ -69,54 +69,55 @@ export class SuperagentHttpClient implements HttpClient { securityOptions ); + const source = axios.CancelToken.source(); + config.cancelToken = source.token; + if (returnType === 'Binary') { - request = request.buffer(true).parse(superagent.parse['application/octet-stream']); + config.responseType = 'arraybuffer'; } - const promise: any = new Promise((resolve, reject) => { - request.on('abort', () => { - eventEmitter.emit('abort'); - }); - request.end((error: any, response: Response) => { - if (error) { - apiClientEmitter.emit('error', error); - eventEmitter.emit('error', error); - - if (error.status === 401) { - apiClientEmitter.emit('unauthorized'); - eventEmitter.emit('unauthorized'); - } - - if (response?.text) { - error = error || {}; - reject(Object.assign(error, { message: response.text })); - } else { - // eslint-disable-next-line prefer-promise-reject-errors - reject({ error }); + const promise: any = axios(config) + .then((response: AxiosResponse) => { + if (securityOptions.isBpmRequest) { + const hasSetCookie = response.headers['set-cookie']; + if (response.headers && hasSetCookie) { + // mutate the passed value from AlfrescoApiClient class for backward compatibility + securityOptions.authentications.cookie = hasSetCookie[0]; } + } + let data = {}; + if (response.headers['content-type']?.includes('text/html')) { + data = AxiosHttpClient.deserialize(response); } else { - if (securityOptions.isBpmRequest) { - const hasSetCookie = Object.prototype.hasOwnProperty.call(response.header, 'set-cookie'); - if (response.header && hasSetCookie) { - // mutate the passed value from AlfrescoApiClient class for backward compatibility - securityOptions.authentications.cookie = response.header['set-cookie'][0]; - } - } - let data = {}; - if (response.type === 'text/html') { - data = SuperagentHttpClient.deserialize(response); - } else { - data = SuperagentHttpClient.deserialize(response, returnType); - } + data = AxiosHttpClient.deserialize(response, returnType); + } - eventEmitter.emit('success', data); - resolve(data); + eventEmitter.emit('success', data); + return data; + }) + .catch((error: AxiosError) => { + apiClientEmitter.emit('error', error); + eventEmitter.emit('error', error); + + if (error.response?.status === 401) { + apiClientEmitter.emit('unauthorized'); + eventEmitter.emit('unauthorized'); + } + + if (error.response?.data) { + const responseError = error.response.data; + const enrichedError = Object.assign(error, { + message: typeof responseError === 'string' ? responseError : JSON.stringify(responseError) + }); + throw enrichedError; + } else { + throw { error }; } }); - }); promise.abort = function () { - request.abort(); + eventEmitter.emit('abort'); + source.cancel('Request aborted'); return this; }; @@ -137,98 +138,124 @@ export class SuperagentHttpClient implements HttpClient { eventEmitter: EventEmitterInstance, returnType: string, securityOptions: SecurityOptions - ) { - const request = superagent(httpMethod, url); - + ): AxiosRequestConfig { const { isBpmRequest, authentications, defaultHeaders = {}, enableCsrf, withCredentials = false } = securityOptions; + const config: AxiosRequestConfig = { + method: httpMethod as any, + url, + params: AxiosHttpClient.normalizeParams(queryParams), + headers: { + ...defaultHeaders, + ...AxiosHttpClient.normalizeParams(headerParams) + }, + timeout: typeof this.timeout === 'number' ? this.timeout : this.timeout?.response, + withCredentials + }; + // apply authentications - this.applyAuthToRequest(request, authentications); - - // set query parameters - request.query(SuperagentHttpClient.normalizeParams(queryParams)); - - // set header parameters - request.set(defaultHeaders).set(SuperagentHttpClient.normalizeParams(headerParams)); + this.applyAuthToRequest(config, authentications); if (isBpmRequest && enableCsrf) { - this.setCsrfToken(request); - } - - if (withCredentials) { - request.withCredentials(); + this.setCsrfToken(config); } // add cookie for activiti if (isBpmRequest) { - request.withCredentials(); + config.withCredentials = true; if (securityOptions.authentications.cookie) { if (!isBrowser()) { - request.set('Cookie', securityOptions.authentications.cookie); + config.headers = { + ...config.headers, + Cookie: securityOptions.authentications.cookie + }; } } } - // set request timeout - request.timeout(this.timeout); - if (contentType && contentType !== 'multipart/form-data') { - request.type(contentType); - } else if (!(request as any).header['Content-Type'] && contentType !== 'multipart/form-data') { - request.type('application/json'); + config.headers = { + ...config.headers, + 'Content-Type': contentType + }; + } else if (!config.headers?.['Content-Type'] && contentType !== 'multipart/form-data') { + config.headers = { + ...config.headers, + 'Content-Type': 'application/json' + }; } if (contentType === 'application/x-www-form-urlencoded') { - request.send(SuperagentHttpClient.normalizeParams(formParams)).on('progress', (event: any) => { - this.progress(event, eventEmitter); + const params = new URLSearchParams(); + const normalizedParams = AxiosHttpClient.normalizeParams(formParams); + Object.keys(normalizedParams).forEach((key) => { + params.append(key, normalizedParams[key]); }); + config.data = params; + + config.onUploadProgress = (progressEvent) => { + this.progress(progressEvent, eventEmitter); + }; } else if (contentType === 'multipart/form-data') { - const _formParams = SuperagentHttpClient.normalizeParams(formParams); + const formData = new FormData(); + const _formParams = AxiosHttpClient.normalizeParams(formParams); for (const key in _formParams) { if (Object.prototype.hasOwnProperty.call(_formParams, key)) { - if (SuperagentHttpClient.isFileParam(_formParams[key])) { + if (AxiosHttpClient.isFileParam(_formParams[key])) { // file field - request.attach(key, _formParams[key]).on('progress', (event: ProgressEvent) => { - // jshint ignore:line - this.progress(event, eventEmitter); - }); + formData.append(key, _formParams[key]); } else { - request.field(key, _formParams[key]).on('progress', (event: ProgressEvent) => { - // jshint ignore:line - this.progress(event, eventEmitter); - }); + formData.append(key, _formParams[key]); } } } + config.data = formData; + // Remove Content-Type header for multipart/form-data to let axios set the boundary + delete config.headers['Content-Type']; + + config.onUploadProgress = (progressEvent) => { + this.progress(progressEvent, eventEmitter); + }; } else if (bodyParam) { - request.send(bodyParam).on('progress', (event: any) => { - this.progress(event, eventEmitter); - }); + config.data = bodyParam; + + config.onUploadProgress = (progressEvent) => { + this.progress(progressEvent, eventEmitter); + }; } if (accept) { - request.accept(accept); + config.headers = { + ...config.headers, + Accept: accept + }; } if (returnType === 'blob' || returnType === 'Blob' || responseType === 'blob' || responseType === 'Blob') { - request.responseType('blob'); + config.responseType = 'blob'; } else if (returnType === 'String') { - request.responseType('string'); + config.responseType = 'text'; } - return request; + return config; } - setCsrfToken(request: SuperAgentRequest): void { - const token = SuperagentHttpClient.createCSRFToken(); - request.set('X-CSRF-TOKEN', token); + setCsrfToken(config: AxiosRequestConfig): void { + const token = AxiosHttpClient.createCSRFToken(); + config.headers = { + ...config.headers, + 'X-CSRF-TOKEN': token + }; if (!isBrowser()) { - request.set('Cookie', 'CSRF-TOKEN=' + token + ';path=/'); + config.headers = { + ...config.headers, + Cookie: `CSRF-TOKEN=${token};path=/` + }; } try { - document.cookie = 'CSRF-TOKEN=' + token + ';path=/'; + document.cookie = `CSRF-TOKEN=${token};path=/`; } catch { /* continue regardless of error */ } @@ -236,29 +263,38 @@ export class SuperagentHttpClient implements HttpClient { /** * Applies authentication headers to the request. - * @param request The request object created by a superagent() call. + * @param config The axios request config object. * @param authentications authentications */ - private applyAuthToRequest(request: SuperAgentRequest, authentications: Authentication) { + private applyAuthToRequest(config: AxiosRequestConfig, authentications: Authentication) { if (authentications) { switch (authentications.type) { case 'basic': { const basicAuth: BasicAuth = authentications.basicAuth; if (basicAuth.username || basicAuth.password) { - request.auth(basicAuth.username || '', basicAuth.password || ''); + config.auth = { + username: basicAuth.username || '', + password: basicAuth.password || '' + }; } break; } case 'activiti': { if (authentications.basicAuth.ticket) { - request.set({ Authorization: authentications.basicAuth.ticket }); + config.headers = { + ...config.headers, + Authorization: authentications.basicAuth.ticket + }; } break; } case 'oauth2': { const oauth2: Oauth2 = authentications.oauth2; if (oauth2.accessToken) { - request.set({ Authorization: 'Bearer ' + oauth2.accessToken }); + config.headers = { + ...config.headers, + Authorization: `Bearer ${oauth2.accessToken}` + }; } break; } @@ -285,34 +321,34 @@ export class SuperagentHttpClient implements HttpClient { private static createCSRFToken(a?: any): string { return a ? (a ^ ((Math.random() * 16) >> (a / 4))).toString(16) - : ([1e16] + (1e16).toString()).replace(/[01]/g, SuperagentHttpClient.createCSRFToken); + : ([1e16] + (1e16).toString()).replace(/[01]/g, AxiosHttpClient.createCSRFToken); } /** * Deserializes an HTTP response body into a value of the specified type. - * @param response A SuperAgent response object. + * @param response An Axios response object. * @param returnType The type to return. Pass a string for simple types * or the constructor function for a complex type. Pass an array containing the type name to return an array of that type. To * return an object, pass an object with one property whose name is the key type and whose value is the corresponding value type: * all properties on data will be converted to this type. * @returns A value of the specified type. */ - private static deserialize(response: Response, returnType?: any): any { + private static deserialize(response: AxiosResponse, returnType?: any): any { if (response === null) { return null; } - let data = response.body; + let data = response.data; if (data === null) { - data = response.text; + data = response.statusText; } if (returnType) { if (returnType === 'blob' && isBrowser()) { - data = new Blob([data], { type: response.header['content-type'] }); + data = new Blob([data], { type: response.headers['content-type'] }); } else if (returnType === 'blob' && !isBrowser()) { - data = new Buffer.from(data, 'binary'); + data = Buffer.from(data, 'binary'); } else if (Array.isArray(data)) { data = data.map((element) => new returnType(element)); } else { @@ -339,7 +375,7 @@ export class SuperagentHttpClient implements HttpClient { for (const key in params) { if (Object.prototype.hasOwnProperty.call(params, key) && params[key] !== undefined && params[key] !== null) { const value = params[key]; - if (SuperagentHttpClient.isFileParam(value) || Array.isArray(value)) { + if (AxiosHttpClient.isFileParam(value) || Array.isArray(value)) { newParams[key] = value; } else { newParams[key] = paramToString(value); diff --git a/lib/js-api/test/alfrescoApi.spec.ts b/lib/js-api/test/alfrescoApi.spec.ts index 6101b253c9..62f7241b08 100644 --- a/lib/js-api/test/alfrescoApi.spec.ts +++ b/lib/js-api/test/alfrescoApi.spec.ts @@ -18,6 +18,7 @@ import assert from 'assert'; import { AlfrescoApi } from '../src'; import { BpmAuthMock, EcmAuthMock, OAuthMock } from './mockObjects'; +import nock from 'nock'; describe('Basic configuration test', () => { describe('config parameter ', () => { @@ -209,16 +210,23 @@ describe('Basic configuration test', () => { }); describe('login', () => { + beforeEach(() => { + nock.cleanAll(); + }); + it('Should login be rejected if username or password are not provided', async () => { + const hostEcm = 'https://testServer.com:1616'; + const authEcmMock = new EcmAuthMock(hostEcm); + const config = { - hostEcm: 'https://testServer.com:1616', + hostEcm, contextRoot: 'strangeContextRoot', withCredentials: true }; const alfrescoJsApi = new AlfrescoApi(config); let error; - + authEcmMock.get401InvalidRequest(); try { await alfrescoJsApi.login(undefined, undefined); } catch (e) { @@ -228,7 +236,7 @@ describe('Basic configuration test', () => { assert.equal(error, 'missing username or password'); error = undefined; - + authEcmMock.get401InvalidRequest(); try { await alfrescoJsApi.login('username', undefined); } catch (e) { @@ -238,7 +246,7 @@ describe('Basic configuration test', () => { assert.equal(error, 'missing username or password'); error = undefined; - + authEcmMock.get401InvalidRequest(); try { await alfrescoJsApi.login(undefined, 'password'); } catch (e) { @@ -248,7 +256,7 @@ describe('Basic configuration test', () => { assert.equal(error, 'missing username or password'); error = undefined; - + authEcmMock.get401InvalidRequest(); try { await alfrescoJsApi.login('', ''); } catch (e) { @@ -258,7 +266,7 @@ describe('Basic configuration test', () => { assert.equal(error, 'missing username or password'); error = undefined; - + authEcmMock.get401InvalidRequest(); try { await alfrescoJsApi.login('username', ''); } catch (e) { @@ -268,7 +276,7 @@ describe('Basic configuration test', () => { assert.equal(error, 'missing username or password'); error = undefined; - + authEcmMock.get401InvalidRequest(); try { await alfrescoJsApi.login('', 'password'); } catch (e) { @@ -317,11 +325,15 @@ describe('Basic configuration test', () => { }); it('Should logged-in be emitted when log in OAUTH', (done) => { - const oauth2Mock = new OAuthMock('https://myOauthUrl:30081'); + const host = 'https://myOauthUrl:30081'; + const oauth2Mock = new OAuthMock(host); + const authEcmMock = new EcmAuthMock(host); oauth2Mock.get200Response(); + authEcmMock.get200ValidTicket(); const alfrescoJsApi = new AlfrescoApi({ + hostEcm: host, oauth2: { host: 'https://myOauthUrl:30081/auth/realms/springboot', clientId: 'activiti', diff --git a/lib/js-api/test/auth.spec.ts b/lib/js-api/test/auth.spec.ts index 52c575756c..79ea65b027 100644 --- a/lib/js-api/test/auth.spec.ts +++ b/lib/js-api/test/auth.spec.ts @@ -18,6 +18,7 @@ import assert from 'assert'; import { EcmAuthMock, BpmAuthMock, NodeMock, ProfileMock } from './mockObjects'; import { NodesApi, UserProfileApi, AlfrescoApi } from '../src'; +import nock from 'nock'; const NOOP = () => { /* empty */ @@ -25,10 +26,6 @@ const NOOP = () => { const ECM_HOST = 'https://127.0.0.1:8080'; const BPM_HOST = 'https://127.0.0.1:9999'; -interface ErrorResponse { - status: number; -} - describe('Auth', () => { describe('ECM Provider config', () => { let authResponseEcmMock: EcmAuthMock; @@ -36,6 +33,7 @@ describe('Auth', () => { let nodesApi: NodesApi; beforeEach(() => { + nock.cleanAll(); authResponseEcmMock = new EcmAuthMock(ECM_HOST); nodeMock = new NodeMock(ECM_HOST); }); @@ -43,6 +41,7 @@ describe('Auth', () => { afterEach(() => { authResponseEcmMock.cleanAll(); nodeMock.cleanAll(); + nock.cleanAll(); }); describe('With Authentication', () => { @@ -64,13 +63,14 @@ describe('Auth', () => { assert.equal(data, 'TICKET_4479f4d3bb155195879bfbb8d5206f433488a1b1'); }); - it('should return an error if wrong credential are used 403 the login fails', (done) => { + it('should return an error if wrong credential are used 403 the login fails', async () => { authResponseEcmMock.get403Response(); - alfrescoJsApi.login('wrong', 'name').then(NOOP, (error: ErrorResponse) => { + try { + await alfrescoJsApi.login('wrong', 'name'); + } catch (error) { assert.equal(error.status, 403); - done(); - }); + } }); }); @@ -85,7 +85,7 @@ describe('Auth', () => { it('should return false if the api is logged out', async () => { authResponseEcmMock.get201Response(); - alfrescoJsApi.login('admin', 'admin').catch(NOOP); + await alfrescoJsApi.login('admin', 'admin').catch(NOOP); authResponseEcmMock.get204ResponseLogout(); @@ -134,9 +134,17 @@ describe('Auth', () => { }); describe('With Ticket Authentication', () => { - it('should Ticket be present in the client', () => { - authResponseEcmMock.get400Response(); + it('should Ticket login be validate against the server if is valid', async () => { + const ticket = 'TICKET_4479f4d3bb155195879bfbb8d5206f433488a1b1'; + authResponseEcmMock.get200ValidTicket(ticket); + const data = await alfrescoJsApi.loginTicket(ticket, null); + + assert.equal(alfrescoJsApi.contentAuth.authentications.basicAuth.password, ticket); + assert.equal(data, ticket); + }); + + it('should Ticket be present in the client', () => { const api = new AlfrescoApi({ ticketEcm: 'TICKET_4479f4d3bb155195879bfbb8d5206f433488a1b1', hostEcm: ECM_HOST @@ -145,26 +153,16 @@ describe('Auth', () => { assert.equal('TICKET_4479f4d3bb155195879bfbb8d5206f433488a1b1', api.contentClient.authentications.basicAuth.password); }); - it('should Ticket login be validate against the server if is valid', (done) => { + it('should Ticket login be validate against the server is NOT valid', async () => { const ticket = 'TICKET_4479f4d3bb155195879bfbb8d5206f433488a1b1'; - authResponseEcmMock.get200ValidTicket(ticket); - - alfrescoJsApi.loginTicket(ticket, null).then((data: string) => { - assert.equal(alfrescoJsApi.contentAuth.authentications.basicAuth.password, ticket); - assert.equal(data, ticket); - done(); - }); - }); - - it('should Ticket login be validate against the server d is NOT valid', (done) => { - const ticket = 'TICKET_4479f4d3bb155195879bfbb8d5206f433488a1b1'; - - authResponseEcmMock.get400Response(); - - alfrescoJsApi.loginTicket(ticket, null).then(NOOP, () => { - done(); - }); + authResponseEcmMock.get400ResponseGET(); + try { + await alfrescoJsApi.loginTicket(ticket, null); + assert.fail('Expected loginTicket to throw an error'); + } catch (error) { + assert.equal(error.response.data.error.briefSummary, '05160045 Invalid login details.'); + } }); }); @@ -174,49 +172,46 @@ describe('Auth', () => { await alfrescoJsApi.login('admin', 'admin'); }); - it('should Ticket be absent in the client and the resolve promise should be called', (done) => { + it('should Ticket be absent in the client and the resolve promise should be called', async () => { authResponseEcmMock.get204ResponseLogout(); - alfrescoJsApi.logout().then(() => { - assert.equal(alfrescoJsApi.config.ticket, undefined); - done(); - }); + await alfrescoJsApi.logout(); + assert.equal(alfrescoJsApi.config.ticket, undefined); }); - it('should Logout be rejected if the Ticket is already expired', (done) => { + it('should Logout be rejected if the Ticket is already expired', async () => { authResponseEcmMock.get404ResponseLogout(); - alfrescoJsApi.logout().then(NOOP, (error: any) => { - assert.equal(error.error.toString(), 'Error: Not Found'); - done(); - }); + try { + await alfrescoJsApi.logout(); + } catch (error) { + assert.equal(error.response.data.error.briefSummary.toString(), 'Not Found'); + } }); }); describe('Unauthorized', () => { - beforeEach((done) => { + beforeEach(async () => { authResponseEcmMock.get201Response('TICKET_22d7a5a83d78b9cc9666ec4e412475e5455b33bd'); - alfrescoJsApi.login('admin', 'admin').then(() => { - done(); - }); + await alfrescoJsApi.login('admin', 'admin'); }); - it('should 401 invalidate the ticket', (done) => { + it('should 401 invalidate the ticket', async () => { nodeMock.get401CreationFolder(); - - nodesApi.createFolder('newFolder', null, null).then(NOOP, () => { + try { + await nodesApi.createFolder('newFolder', null, null); + } catch { assert.equal(alfrescoJsApi.contentAuth.authentications.basicAuth.password, null); - done(); - }); + } }); - it('should 401 invalidate the session and logout', (done) => { + it('should 401 invalidate the session and logout', async () => { nodeMock.get401CreationFolder(); - - nodesApi.createFolder('newFolder', null, null).then(NOOP, () => { + try { + await nodesApi.createFolder('newFolder', null, null); + } catch { assert.equal(alfrescoJsApi.isLoggedIn(), false); - done(); - }); + } }); it('should emit an error event if a failing call is executed', (done) => { @@ -252,46 +247,41 @@ describe('Auth', () => { describe('With Authentication', () => { describe('login', () => { - it('should return the Ticket if all is ok', (done) => { + it('should return the Ticket if all is ok', async () => { authResponseBpmMock.get200Response(); - alfrescoJsApi.login('admin', 'admin').then((data: string) => { - assert.equal(data, 'Basic YWRtaW46YWRtaW4='); - done(); - }); + const data = await alfrescoJsApi.login('admin', 'admin'); + assert.equal(data, 'Basic YWRtaW46YWRtaW4='); }); - it('should return an error if wrong credential are used 401 the login fails', (done) => { + it('should return an error if wrong credential are used 401 the login fails', async () => { authResponseBpmMock.get401Response(); - alfrescoJsApi.login('wrong', 'name').then(NOOP, (error: ErrorResponse) => { + try { + await alfrescoJsApi.login('wrong', 'name'); + } catch (error) { assert.equal(error.status, 401); - done(); - }); + } }); }); describe('isLoggedIn', () => { - it('should return true if the api is logged in', (done) => { + it('should return true if the api is logged in', async () => { authResponseBpmMock.get200Response(); - alfrescoJsApi.login('admin', 'admin').then(() => { - assert.equal(alfrescoJsApi.isLoggedIn(), true); - done(); - }, NOOP); + await alfrescoJsApi.login('admin', 'admin'); + assert.equal(alfrescoJsApi.isLoggedIn(), true); }); - it('should return false if the api is logged out', (done) => { + it('should return false if the api is logged out', async () => { authResponseBpmMock.get200Response(); - alfrescoJsApi.login('admin', 'admin'); + await alfrescoJsApi.login('admin', 'admin'); authResponseBpmMock.get200ResponseLogout(); - alfrescoJsApi.logout().then(() => { - assert.equal(alfrescoJsApi.isLoggedIn(), false); - done(); - }, NOOP); + await alfrescoJsApi.logout(); + assert.equal(alfrescoJsApi.isLoggedIn(), false); }); }); @@ -345,25 +335,24 @@ describe('Auth', () => { }); }); - it('should 401 invalidate the ticket', (done) => { + it('should 401 invalidate the ticket', async () => { profileMock.get401getProfile(); - - profileApi.getProfile().then(NOOP, () => { + try { + await profileApi.getProfile(); + assert.fail('Expected getProfile to throw an error'); + } catch { assert.equal(alfrescoJsApi.processAuth.authentications.basicAuth.ticket, null); - done(); - }); + } }); - it('should 401 invalidate the session and logout', (done) => { + it('should 401 invalidate the session and logout', async () => { profileMock.get401getProfile(); - - profileApi.getProfile().then( - () => NOOP, - () => { - assert.equal(alfrescoJsApi.isLoggedIn(), false); - done(); - } - ); + try { + await profileApi.getProfile(); + assert.fail('Expected getProfile to throw an error'); + } catch { + assert.equal(alfrescoJsApi.isLoggedIn(), false); + } }); }); }); @@ -406,75 +395,75 @@ describe('Auth', () => { }); describe('login', () => { - it('should return the Ticket if all is ok', (done) => { + it('should return the Ticket if all is ok', async () => { authResponseBpmMock.get200Response(); authResponseEcmMock.get201Response(); - alfrescoJsApi.login('admin', 'admin').then((data: string[]) => { - assert.equal(data[0], 'TICKET_4479f4d3bb155195879bfbb8d5206f433488a1b1'); - assert.equal(data[1], 'Basic YWRtaW46YWRtaW4='); - done(); - }); + const data = await alfrescoJsApi.login('admin', 'admin'); + + assert.equal(data[0], 'TICKET_4479f4d3bb155195879bfbb8d5206f433488a1b1'); + assert.equal(data[1], 'Basic YWRtaW46YWRtaW4='); }); - it('should fail if only ECM fail', (done) => { + it('should fail if only ECM fail', async () => { authResponseBpmMock.get200Response(); authResponseEcmMock.get401Response(); - alfrescoJsApi.login('admin', 'admin').then(NOOP, () => { - done(); - }); - - authResponseEcmMock.cleanAll(); + try { + await alfrescoJsApi.login('admin', 'admin'); + assert.fail('Expected login to throw an error'); + } catch { + authResponseEcmMock.cleanAll(); + } }); - it('should fail if only BPM fail', (done) => { + it('should fail if only BPM fail', async () => { authResponseBpmMock.get401Response(); authResponseEcmMock.get201Response(); - alfrescoJsApi.login('admin', 'admin').then(NOOP, () => { - done(); - }); - - authResponseBpmMock.cleanAll(); + try { + await alfrescoJsApi.login('admin', 'admin'); + assert.fail('Expected login to throw an error'); + } catch { + authResponseBpmMock.cleanAll(); + } }); }); describe('isLoggedIn', () => { - it('should return false if the api is logged out', (done) => { + it('should return false if the api is logged out', async () => { authResponseBpmMock.get200Response(); authResponseEcmMock.get201Response(); - alfrescoJsApi.login('admin', 'admin'); + await alfrescoJsApi.login('admin', 'admin'); authResponseBpmMock.get200ResponseLogout(); authResponseEcmMock.get204ResponseLogout(); - alfrescoJsApi.logout().then(() => { - assert.equal(alfrescoJsApi.isLoggedIn(), false); - done(); - }); + await alfrescoJsApi.logout(); + + assert.equal(alfrescoJsApi.isLoggedIn(), false); }); - it('should return an error if wrong credential are used 401 the login fails', (done) => { + it('should return an error if wrong credential are used 401 the login fails', async () => { authResponseBpmMock.get401Response(); authResponseEcmMock.get401Response(); - alfrescoJsApi.login('wrong', 'name').then(NOOP, (error: ErrorResponse) => { + try { + await alfrescoJsApi.login('wrong', 'name'); + assert.fail('Expected login to throw an error'); + } catch (error) { assert.equal(error.status, 401); - done(); - }); + } }); }); - it('should return true if the api is logged in', (done) => { + it('should return true if the api is logged in', async () => { authResponseBpmMock.get200Response(); authResponseEcmMock.get201Response(); - alfrescoJsApi.login('admin', 'admin').then(() => { - assert.equal(alfrescoJsApi.isLoggedIn(), true); - done(); - }); + await alfrescoJsApi.login('admin', 'admin'); + assert.equal(alfrescoJsApi.isLoggedIn(), true); }); describe('Events ', () => { diff --git a/lib/js-api/test/superagentHttpClient.spec.ts b/lib/js-api/test/axiosHttpClient.spec.ts similarity index 72% rename from lib/js-api/test/superagentHttpClient.spec.ts rename to lib/js-api/test/axiosHttpClient.spec.ts index 5da64b7386..c446ff7242 100644 --- a/lib/js-api/test/superagentHttpClient.spec.ts +++ b/lib/js-api/test/axiosHttpClient.spec.ts @@ -16,12 +16,12 @@ */ import assert from 'assert'; -import { SuperagentHttpClient } from '../src/superagentHttpClient'; -import { Response } from 'superagent'; +import { AxiosHttpClient } from '../src/axiosHttpClient'; +import { AxiosResponse } from 'axios'; -describe('SuperagentHttpClient', () => { +describe('AxiosHttpClient', () => { describe('#buildRequest', () => { - const client = new SuperagentHttpClient(); + const client = new AxiosHttpClient(); it('should create a request with response type blob', () => { const queryParams = {}; @@ -62,16 +62,19 @@ describe('SuperagentHttpClient', () => { ); assert.equal(response.url, '/fake-api/enterprise/process-instances/'); - assert.equal(response.header.Accept, 'application/json'); - assert.equal(response.header['Content-Type'], 'application/json'); - assert.equal(response._responseType, 'blob'); + + // Fix the header property access - likely should be 'headers' (plural) + const headers = response.headers || response.header || {}; + assert.equal(headers.Accept || headers.accept, 'application/json'); + assert.equal(headers['Content-Type'] || headers['content-type'], 'application/json'); + assert.equal(response.responseType || response._responseType, 'blob'); }); }); describe('#deserialize', () => { it('should the deserializer return an array of object when the response is an array', () => { - const data = { - body: [ + const data: AxiosResponse = { + data: [ { id: '1', name: 'test1' @@ -80,9 +83,15 @@ describe('SuperagentHttpClient', () => { id: '2', name: 'test2' } - ] - } as Response; - const result = SuperagentHttpClient['deserialize'](data); + ], + status: 200, + statusText: 'OK', + headers: {}, + config: { + headers: undefined + } + }; + const result = AxiosHttpClient['deserialize'](data); const isArray = Array.isArray(result); assert.equal(isArray, true); }); diff --git a/lib/js-api/test/bpmAuth.spec.ts b/lib/js-api/test/bpmAuth.spec.ts index 14e03903f4..543d9def31 100644 --- a/lib/js-api/test/bpmAuth.spec.ts +++ b/lib/js-api/test/bpmAuth.spec.ts @@ -17,8 +17,9 @@ import assert from 'assert'; import { ProcessAuth } from '../src'; -import { SuperagentHttpClient } from '../src/superagentHttpClient'; + import { BpmAuthMock } from './mockObjects'; +import { AxiosHttpClient } from '../src/axiosHttpClient'; describe('Bpm Auth test', () => { const hostBpm = 'https://127.0.0.1:9999'; @@ -256,16 +257,16 @@ describe('Bpm Auth test', () => { let setCsrfTokenCalled = false; beforeEach(() => { - originalMethod = SuperagentHttpClient.prototype.setCsrfToken; + originalMethod = AxiosHttpClient.prototype.setCsrfToken; setCsrfTokenCalled = false; - SuperagentHttpClient.prototype.setCsrfToken = () => { + AxiosHttpClient.prototype.setCsrfToken = () => { setCsrfTokenCalled = true; }; }); afterEach(() => { - SuperagentHttpClient.prototype.setCsrfToken = originalMethod; + AxiosHttpClient.prototype.setCsrfToken = originalMethod; setCsrfTokenCalled = false; }); diff --git a/lib/js-api/test/content-services/categoriesApi.spec.ts b/lib/js-api/test/content-services/categoriesApi.spec.ts index ca2b3d2963..2789260b03 100644 --- a/lib/js-api/test/content-services/categoriesApi.spec.ts +++ b/lib/js-api/test/content-services/categoriesApi.spec.ts @@ -39,136 +39,131 @@ describe('Categories', () => { categoriesApi = new CategoriesApi(alfrescoJsApi); }); - it('should return 200 while getting subcategories for category with categoryId if all is ok', (done) => { + it('should return 200 while getting subcategories for category with categoryId if all is ok', async () => { categoriesMock.get200ResponseSubcategories('-root-'); - categoriesApi.getSubcategories('-root-').then((response: CategoryPaging) => { - assert.equal(response.list.pagination.count, 2); - assert.equal(response.list.entries[0].entry.parentId, '-root-'); - assert.equal(response.list.entries[0].entry.id, 'testId1'); - done(); - }); + const response: CategoryPaging = await categoriesApi.getSubcategories('-root-'); + assert.equal(response.list.pagination.count, 2); + assert.equal(response.list.entries[0].entry.parentId, '-root-'); + assert.equal(response.list.entries[0].entry.id, 'testId1'); }); - it('should return 404 while getting subcategories for not existing category', (done) => { + it('should return 404 while getting subcategories for not existing category', async () => { categoriesMock.get404SubcategoryNotExist('notExistingId'); - categoriesApi.getSubcategories('notExistingId').then( - () => {}, - (error: { status: number }) => { - assert.equal(error.status, 404); - done(); - } - ); + try { + await categoriesApi.getSubcategories('notExistingId'); + assert.fail('Expected error not thrown'); + } catch (error) { + assert.equal(error.status, 404); + } }); - it('should return 200 while getting category with categoryId if category exists', (done) => { + it('should return 200 while getting category with categoryId if category exists', async () => { categoriesMock.get200ResponseCategory('testId1'); - categoriesApi.getCategory('testId1').then((response: CategoryEntry) => { - assert.equal(response.entry.parentId, '-root-'); - assert.equal(response.entry.id, 'testId1'); - done(); - }); + const response: CategoryEntry = await categoriesApi.getCategory('testId1'); + assert.equal(response.entry.parentId, '-root-'); + assert.equal(response.entry.id, 'testId1'); }); - it('should return 404 while getting category with categoryId when category not exists', (done) => { + it('should return 404 while getting category with categoryId when category not exists', async () => { categoriesMock.get404CategoryNotExist('notExistingId'); - categoriesApi.getCategory('notExistingId').then( - () => {}, - (error: { status: number }) => { - assert.equal(error.status, 404); - done(); - } - ); + + try { + await categoriesApi.getCategory('notExistingId'); + assert.fail('Expected error not thrown'); + } catch (error) { + assert.equal(error.status, 404); + } }); - it('should return 200 while getting categories linked to node with nodeId if node has some categories assigned', (done) => { + it('should return 200 while getting categories linked to node with nodeId if node has some categories assigned', async () => { categoriesMock.get200ResponseNodeCategoryLinks('testNode'); - categoriesApi.getCategoryLinksForNode('testNode').then((response: CategoryPaging) => { - assert.equal(response.list.entries[0].entry.parentId, 'testNode'); - assert.equal(response.list.entries[0].entry.id, 'testId1'); - done(); - }); + const response: CategoryPaging = await categoriesApi.getCategoryLinksForNode('testNode'); + assert.equal(response.list.entries[0].entry.parentId, 'testNode'); + assert.equal(response.list.entries[0].entry.id, 'testId1'); }); - it('should return 403 while getting categories linked to node with nodeId if user has no rights to get from node', (done) => { + it('should return 403 while getting categories linked to node with nodeId if user has no rights to get from node', async () => { categoriesMock.get403NodeCategoryLinksPermissionDenied('testNode'); - categoriesApi.getCategoryLinksForNode('testNode').then( - () => {}, - (error: { status: number }) => { - assert.equal(error.status, 403); - done(); - } - ); + try { + await categoriesApi.getCategoryLinksForNode('testNode'); + assert.fail('Expected error not thrown'); + } catch (error) { + assert.equal(error.status, 403); + } }); - it('should return 404 while getting categories linked to node with nodeId if node does not exist', (done) => { + it('should return 404 while getting categories linked to node with nodeId if node does not exist', async () => { categoriesMock.get404NodeNotExist('testNode'); - categoriesApi.getCategoryLinksForNode('testNode').then( - () => {}, - (error: { status: number }) => { - assert.equal(error.status, 404); - done(); - } - ); + try { + await categoriesApi.getCategoryLinksForNode('testNode'); + assert.fail('Expected error not thrown'); + } catch (error) { + assert.equal(error.status, 404); + } }); - it('should return 204 after unlinking category', (done) => { + it('should return 204 after unlinking category', async () => { categoriesMock.get204CategoryUnlinked('testNode', 'testId1'); - categoriesApi.unlinkNodeFromCategory('testNode', 'testId1').then(() => { - done(); - }); + await categoriesApi.unlinkNodeFromCategory('testNode', 'testId1'); }); - it('should return 404 while unlinking category if category with categoryId or node with nodeId does not exist', (done) => { + it('should return 404 while unlinking category if category with categoryId or node with nodeId does not exist', async () => { categoriesMock.get404CategoryUnlinkNotFound('testNode', 'testId1'); - categoriesApi.unlinkNodeFromCategory('testNode', 'testId1').then( - () => {}, - (error: { status: number }) => { - assert.equal(error.status, 404); - done(); - } - ); + + try { + await categoriesApi.unlinkNodeFromCategory('testNode', 'testId1'); + assert.fail('Expected error not thrown'); + } catch (error) { + assert.equal(error.status, 404); + } }); - it('should return 403 while unlinking category if user has no rights to unlink', (done) => { + it('should return 403 while unlinking category if user has no rights to unlink', async () => { categoriesMock.get403CategoryUnlinkPermissionDenied('testNode', 'testId1'); - categoriesApi.unlinkNodeFromCategory('testNode', 'testId1').then( - () => {}, - (error: { status: number }) => { - assert.equal(error.status, 403); - done(); - } - ); + try { + await categoriesApi.unlinkNodeFromCategory('testNode', 'testId1'); + assert.fail('Expected error not thrown'); + } catch (error) { + assert.equal(error.status, 403); + } }); - it('should return 200 while updating category if all is ok', (done) => { + it('should return 200 while updating category if all is ok', async () => { categoriesMock.get200ResponseCategoryUpdated('testId1'); - categoriesApi.updateCategory('testId1', { name: 'testName1' }).then((response) => { - assert.equal(response.entry.id, 'testId1'); - assert.equal(response.entry.name, 'testName1'); - done(); - }); + const response = await categoriesApi.updateCategory('testId1', { name: 'testName1' }); + assert.equal(response.entry.id, 'testId1'); + assert.equal(response.entry.name, 'testName1'); }); - it('should return 404 while updating category if category with categoryId does not exist', (done) => { + it('should return 404 while updating category if category with categoryId does not exist', async () => { categoriesMock.get404CategoryUpdateNotFound('testId1'); - categoriesApi.updateCategory('testId1', { name: 'testName1' }).then( - () => {}, - (error: { status: number }) => { - assert.equal(error.status, 404); - done(); - } - ); + try { + await categoriesApi.updateCategory('testId1', { name: 'testName1' }); + assert.fail('Expected error not thrown'); + } catch (error) { + assert.equal(error.status, 404); + } + }); + it('should return 403 while updating category if user has no rights to update', async () => { + categoriesMock.get403CategoryUpdatePermissionDenied('testId1'); + + try { + await categoriesApi.updateCategory('testId1', { name: 'testName1' }); + assert.fail('Expected error not thrown'); + } catch (error) { + assert.equal(error.response.status, 403); + } }); - it('should return 403 while updating category if user has no rights to update', (done) => { + it('should return 403 while updating category if user has no rights to update', async () => { categoriesMock.get403CategoryUpdatePermissionDenied('testId1'); - categoriesApi.updateCategory('testId1', { name: 'testName1' }).then( - () => {}, - (error: { status: number }) => { - assert.equal(error.status, 403); - done(); - } - ); + + try { + await categoriesApi.updateCategory('testId1', { name: 'testName1' }); + assert.fail('Expected error not thrown'); + } catch (error) { + assert.equal(error.status, 403); + } }); it('should return 201 while creating category if all is ok', (done) => { diff --git a/lib/js-api/test/content-services/nodeApi.spec.ts b/lib/js-api/test/content-services/nodeApi.spec.ts index 95fde66f95..6e3b21766c 100644 --- a/lib/js-api/test/content-services/nodeApi.spec.ts +++ b/lib/js-api/test/content-services/nodeApi.spec.ts @@ -161,19 +161,17 @@ describe('Node', () => { }); }); - it('should return 404 error on initiateFolderSizeCalculation API call if nodeId is not found', (done) => { + it('should return 404 error on initiateFolderSizeCalculation API call if nodeId is not found', async () => { nodeMock.post404NodeIdNotFound(); - nodesApi.initiateFolderSizeCalculation('b4cff62a-664d-4d45-9302-98723eac1319').then( - () => {}, - (err) => { - const { error } = JSON.parse(err.response.text); - assert.equal(error.statusCode, 404); - assert.equal(error.errorKey, 'framework.exception.EntityNotFound'); - assert.equal(error.briefSummary, '11207522 The entity with id: b4cff62a-664d-4d45-9302-98723eac1319 was not found'); - done(); - } - ); + try { + await nodesApi.initiateFolderSizeCalculation('b4cff62a-664d-4d45-9302-98723eac1319'); + } catch (err) { + const error = err.response.data.error; + assert.equal(error.statusCode, 404); + assert.equal(error.errorKey, 'framework.exception.EntityNotFound'); + assert.equal(error.briefSummary, '11207522 The entity with id: b4cff62a-664d-4d45-9302-98723eac1319 was not found'); + } }); it('should return size details on getFolderSizeInfo API call if everything is ok', (done) => { @@ -196,7 +194,7 @@ describe('Node', () => { nodesApi.getFolderSizeInfo('b4cff62a-664d-4d45-9302-98723eac1319', '5ade426e-8a04-4d50-9e42-6e8a041d50f3').then( () => {}, (err) => { - const { error } = JSON.parse(err.response.text); + const error = err.response.data.error; assert.equal(error.statusCode, 404); assert.equal(error.errorKey, 'jobId does not exist'); assert.equal(error.briefSummary, '11207212 jobId does not exist'); diff --git a/lib/js-api/test/ecmAuth.spec.ts b/lib/js-api/test/ecmAuth.spec.ts index f911c51973..e4ebf5dec3 100644 --- a/lib/js-api/test/ecmAuth.spec.ts +++ b/lib/js-api/test/ecmAuth.spec.ts @@ -44,24 +44,25 @@ describe('Ecm Auth test', () => { it('should remember username on login', () => { const auth = new ContentAuth({}, alfrescoJsApi); + authEcmMock.get201ResponseJohnDoe(); auth.login('johndoe', 'password'); assert.equal(auth.authentications.basicAuth.username, 'johndoe'); }); - it('should forget username on logout', (done) => { + it('should forget username on logout', async () => { const auth = new ContentAuth({}, alfrescoJsApi); - authEcmMock.get201Response(); + authEcmMock.get201ResponseJohnDoe(); - auth.login('johndoe', 'password'); - assert.equal(auth.authentications.basicAuth.username, 'johndoe'); + await auth.login('johndoe', 'password'); + assert.equal(auth.authentications.basicAuth.username, 'ROLE_TICKET'); + assert.equal(auth.storage.getItem('ACS_USERNAME'), 'johndoe'); authEcmMock.get204ResponseLogout(); - auth.logout().then(() => { - assert.equal(auth.authentications.basicAuth.username, null); - done(); - }); + await auth.logout(); + assert.equal(auth.authentications.basicAuth.username, null); + assert.equal(auth.storage.getItem('ACS_USERNAME'), ''); }); describe('With Authentication', () => { @@ -128,16 +129,15 @@ describe('Ecm Auth test', () => { ); }); - it('login should return an error if wrong credential are used 400 userId and/or password are/is not provided', (done) => { + it('login should return an error if wrong credential are used 400 userId and/or password are/is not provided', async () => { authEcmMock.get400Response(); - contentAuth.login(null, null).then( - () => {}, - (error) => { - assert.equal(error.status, 400); - done(); - } - ); + try { + await contentAuth.login(null, null); + assert.fail('Login should have failed'); + } catch (error) { + assert.equal(error.status, 400); + } }); describe('Events ', () => { @@ -189,8 +189,6 @@ describe('Ecm Auth test', () => { describe('With Ticket Authentication', () => { it('Ticket should be present in the client', () => { - authEcmMock.get400Response(); - contentAuth = new ContentAuth( { ticketEcm: 'TICKET_4479f4d3bb155195879bfbb8d5206f433488a1b1', @@ -212,24 +210,22 @@ describe('Ecm Auth test', () => { }); }); - it('Ticket should be absent in the client and the resolve promise should be called', (done) => { + it('Ticket should be absent in the client and the resolve promise should be called', async () => { authEcmMock.get204ResponseLogout(); - contentAuth.logout().then(() => { - assert.equal(contentAuth.config.ticket, undefined); - done(); - }); + await contentAuth.logout(); + assert.equal(contentAuth.config.ticket, undefined); }); - it('Logout should be rejected if the Ticket is already expired', (done) => { + it('Logout should be rejected if the Ticket is already expired', async () => { authEcmMock.get404ResponseLogout(); - contentAuth.logout().then( - () => {}, - (error) => { - assert.equal(error.error.toString(), 'Error: Not Found'); - done(); - } - ); + try { + await contentAuth.logout(); + assert.fail('Logout should have failed'); + } catch (error) { + assert.equal(error.status, 404); + assert.equal(error.response.data.error.briefSummary, 'Not Found'); + } }); }); }); diff --git a/lib/js-api/test/governance-services/securityMarksApi.spec.ts b/lib/js-api/test/governance-services/securityMarksApi.spec.ts index ba9334be02..d96245ea6b 100644 --- a/lib/js-api/test/governance-services/securityMarksApi.spec.ts +++ b/lib/js-api/test/governance-services/securityMarksApi.spec.ts @@ -118,6 +118,7 @@ describe('Security Mark API test', () => { it('delete Security Mark', async () => { securityMarkApiMock.getDeleteSecurityMarkSuccessfulResponse(securityGroupId, securityMarkId); + securityGroupMock.deleteSecurityGroup200Response(securityGroupId); await securityGroupApi .deleteSecurityGroup(securityGroupId) .then((data) => { diff --git a/lib/js-api/test/mockObjects/base.mock.ts b/lib/js-api/test/mockObjects/base.mock.ts index 92a434e557..bf4204ce08 100644 --- a/lib/js-api/test/mockObjects/base.mock.ts +++ b/lib/js-api/test/mockObjects/base.mock.ts @@ -24,8 +24,54 @@ export class BaseMock { this.host = host || 'https://127.0.0.1:8080'; } + addCorsSupport() { + nock(this.host).persist().options(/.*/).reply(200, '', { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, Content-Length, X-Requested-With, Cache-Control, X-CSRF-TOKEN', + 'Access-Control-Allow-Credentials': 'true', + 'Access-Control-Max-Age': '86400' + }); + } + + getDefaultHeaders(): Record { + return { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, Content-Length, X-Requested-With, Cache-Control, X-CSRF-TOKEN', + 'Access-Control-Allow-Credentials': 'true', + 'Access-Control-Max-Age': '86400' + }; + } + + getBaseHeaders(): Record { + return { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Credentials': 'true' + }; + } + + protected createNockWithCors(): nock.Scope { + this.addCorsSupport(); + return nock(this.host, { encodedQueryParams: true }).defaultReplyHeaders(this.getDefaultHeaders()); + } + put200GenericResponse(scriptSlug: string): void { - nock(this.host, { encodedQueryParams: true }).put(scriptSlug).reply(200); + nock(this.host).persist().options(/.*/).reply(200, '', { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, Content-Length, X-Requested-With, Cache-Control, X-CSRF-TOKEN, Cookie', + 'Access-Control-Allow-Credentials': 'true' + }); + nock(this.host, { encodedQueryParams: true }) + .defaultReplyHeaders({ + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, Content-Length, X-Requested-With, Cache-Control, X-CSRF-TOKEN, Cookie', + 'Access-Control-Allow-Credentials': 'true' + }) + .put(scriptSlug) + .reply(200); } play(): void { diff --git a/lib/js-api/test/mockObjects/content-services/agent.mock.ts b/lib/js-api/test/mockObjects/content-services/agent.mock.ts index 1efc29b131..b9fbcb35cb 100644 --- a/lib/js-api/test/mockObjects/content-services/agent.mock.ts +++ b/lib/js-api/test/mockObjects/content-services/agent.mock.ts @@ -16,11 +16,10 @@ */ import { BaseMock } from '../base.mock'; -import nock from 'nock'; export class AgentMock extends BaseMock { mockGetAgents200Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/private/hxi/versions/1/agents') .reply(200, { list: { diff --git a/lib/js-api/test/mockObjects/content-services/categories.mock.ts b/lib/js-api/test/mockObjects/content-services/categories.mock.ts index 33fb428271..131fc9d829 100644 --- a/lib/js-api/test/mockObjects/content-services/categories.mock.ts +++ b/lib/js-api/test/mockObjects/content-services/categories.mock.ts @@ -20,7 +20,7 @@ import { BaseMock } from '../base.mock'; export class CategoriesMock extends BaseMock { get200ResponseSubcategories(categoryId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get(`/alfresco/api/-default-/public/alfresco/versions/1/categories/${categoryId}/subcategories`) .reply(200, { list: { @@ -56,7 +56,7 @@ export class CategoriesMock extends BaseMock { } get404SubcategoryNotExist(categoryId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get(`/alfresco/api/-default-/public/alfresco/versions/1/categories/${categoryId}/subcategories`) .reply(404, { error: { @@ -70,7 +70,7 @@ export class CategoriesMock extends BaseMock { } get200ResponseCategory(categoryId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get(`/alfresco/api/-default-/public/alfresco/versions/1/categories/${categoryId}`) .reply(200, { entry: { @@ -84,7 +84,7 @@ export class CategoriesMock extends BaseMock { } get404CategoryNotExist(categoryId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get(`/alfresco/api/-default-/public/alfresco/versions/1/categories/${categoryId}`) .reply(404, { error: { @@ -98,7 +98,7 @@ export class CategoriesMock extends BaseMock { } get200ResponseNodeCategoryLinks(nodeId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get(`/alfresco/api/-default-/public/alfresco/versions/1/nodes/${nodeId}/category-links`) .reply(200, { list: { @@ -125,7 +125,7 @@ export class CategoriesMock extends BaseMock { } get403NodeCategoryLinksPermissionDenied(nodeId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get(`/alfresco/api/-default-/public/alfresco/versions/1/nodes/${nodeId}/category-links`) .reply(403, { error: { @@ -135,7 +135,7 @@ export class CategoriesMock extends BaseMock { } get404NodeNotExist(nodeId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get(`/alfresco/api/-default-/public/alfresco/versions/1/nodes/${nodeId}/category-links`) .reply(404, { error: { @@ -149,13 +149,13 @@ export class CategoriesMock extends BaseMock { } get204CategoryUnlinked(nodeId: string, categoryId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .delete(`/alfresco/api/-default-/public/alfresco/versions/1/nodes/${nodeId}/category-links/${categoryId}`) .reply(204); } get403CategoryUnlinkPermissionDenied(nodeId: string, categoryId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .delete(`/alfresco/api/-default-/public/alfresco/versions/1/nodes/${nodeId}/category-links/${categoryId}`) .reply(403, { error: { @@ -165,7 +165,7 @@ export class CategoriesMock extends BaseMock { } get404CategoryUnlinkNotFound(nodeId: string, categoryId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .delete(`/alfresco/api/-default-/public/alfresco/versions/1/nodes/${nodeId}/category-links/${categoryId}`) .reply(404, { error: { @@ -179,7 +179,7 @@ export class CategoriesMock extends BaseMock { } get200ResponseCategoryUpdated(categoryId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .put(`/alfresco/api/-default-/public/alfresco/versions/1/categories/${categoryId}`, { name: 'testName1' }) .reply(200, { entry: { @@ -193,7 +193,7 @@ export class CategoriesMock extends BaseMock { } get403CategoryUpdatePermissionDenied(categoryId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .put(`/alfresco/api/-default-/public/alfresco/versions/1/categories/${categoryId}`, { name: 'testName1' }) .reply(403, { error: { @@ -203,7 +203,7 @@ export class CategoriesMock extends BaseMock { } get404CategoryUpdateNotFound(categoryId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .put(`/alfresco/api/-default-/public/alfresco/versions/1/categories/${categoryId}`, { name: 'testName1' }) .reply(404, { error: { @@ -217,7 +217,7 @@ export class CategoriesMock extends BaseMock { } get201ResponseCategoryCreated(categoryId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post(`/alfresco/api/-default-/public/alfresco/versions/1/categories/${categoryId}/subcategories`, [{ name: 'testName10' }]) .reply(201, { entry: { @@ -231,7 +231,7 @@ export class CategoriesMock extends BaseMock { } get403CategoryCreatedPermissionDenied(categoryId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post(`/alfresco/api/-default-/public/alfresco/versions/1/categories/${categoryId}/subcategories`, [{ name: 'testName10' }]) .reply(403, { error: { @@ -241,7 +241,7 @@ export class CategoriesMock extends BaseMock { } get409CategoryCreateAlreadyExists(categoryId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post(`/alfresco/api/-default-/public/alfresco/versions/1/categories/${categoryId}/subcategories`, [{ name: 'testName10' }]) .reply(409, { error: { @@ -255,7 +255,7 @@ export class CategoriesMock extends BaseMock { } get201ResponseCategoryLinked(nodeId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post(`/alfresco/api/-default-/public/alfresco/versions/1/nodes/${nodeId}/category-links`, [{ categoryId: 'testId1' }]) .reply(201, { entry: { @@ -269,7 +269,7 @@ export class CategoriesMock extends BaseMock { } get201ResponseCategoryLinkedArray(nodeId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post(`/alfresco/api/-default-/public/alfresco/versions/1/nodes/${nodeId}/category-links`, [ { categoryId: 'testId1' }, { categoryId: 'testId2' } @@ -308,7 +308,7 @@ export class CategoriesMock extends BaseMock { } get403CategoryLinkPermissionDenied(nodeId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post(`/alfresco/api/-default-/public/alfresco/versions/1/nodes/${nodeId}/category-links`, [{ categoryId: 'testId1' }]) .reply(403, { error: { @@ -318,7 +318,7 @@ export class CategoriesMock extends BaseMock { } get404CategoryLinkNotFound(nodeId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post(`/alfresco/api/-default-/public/alfresco/versions/1/nodes/${nodeId}/category-links`, [{ categoryId: 'testId1' }]) .reply(404, { error: { @@ -332,7 +332,7 @@ export class CategoriesMock extends BaseMock { } get405CategoryLinkCannotAssign(nodeId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post(`/alfresco/api/-default-/public/alfresco/versions/1/nodes/${nodeId}/category-links`, [{ categoryId: 'testId1' }]) .reply(405, { error: { diff --git a/lib/js-api/test/mockObjects/content-services/comment.mock.ts b/lib/js-api/test/mockObjects/content-services/comment.mock.ts index 1f398471fd..e42ac727f2 100644 --- a/lib/js-api/test/mockObjects/content-services/comment.mock.ts +++ b/lib/js-api/test/mockObjects/content-services/comment.mock.ts @@ -40,7 +40,7 @@ const adminUser = { export class CommentMock extends BaseMock { post201Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/alfresco/versions/1/nodes/74cd8a96-8a21-47e5-9b3b-a1b3e296787d/comments', { content: 'This is a comment' }) @@ -60,7 +60,7 @@ export class CommentMock extends BaseMock { } get200Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/alfresco/versions/1/nodes/74cd8a96-8a21-47e5-9b3b-a1b3e296787d/comments') .reply(200, { list: { diff --git a/lib/js-api/test/mockObjects/content-services/custom-model.mock.ts b/lib/js-api/test/mockObjects/content-services/custom-model.mock.ts index 15e5c6c510..4fd0658eb1 100644 --- a/lib/js-api/test/mockObjects/content-services/custom-model.mock.ts +++ b/lib/js-api/test/mockObjects/content-services/custom-model.mock.ts @@ -20,7 +20,7 @@ import { BaseMock } from '../base.mock'; export class CustomModelMock extends BaseMock { get200AllCustomModel(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/private/alfresco/versions/1/cmm') .reply(200, { list: { @@ -37,7 +37,7 @@ export class CustomModelMock extends BaseMock { } create201CustomModel(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/private/alfresco/versions/1/cmm') .reply(201, { entry: { @@ -52,7 +52,7 @@ export class CustomModelMock extends BaseMock { } activateCustomModel200(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .put('/alfresco/api/-default-/private/alfresco/versions/1/cmm/testModel', { status: 'ACTIVE' }) .query({ select: 'status' }) .reply(200, { diff --git a/lib/js-api/test/mockObjects/content-services/discovery.mock.ts b/lib/js-api/test/mockObjects/content-services/discovery.mock.ts index 06dbb4d2a2..0099ca6626 100644 --- a/lib/js-api/test/mockObjects/content-services/discovery.mock.ts +++ b/lib/js-api/test/mockObjects/content-services/discovery.mock.ts @@ -15,12 +15,11 @@ * limitations under the License. */ -import nock from 'nock'; import { BaseMock } from '../base.mock'; export class DiscoveryMock extends BaseMock { get200Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/discovery') .reply(200, { entry: { diff --git a/lib/js-api/test/mockObjects/content-services/ecm-auth.mock.ts b/lib/js-api/test/mockObjects/content-services/ecm-auth.mock.ts index 946a5fb3c0..19ea2fc8f9 100644 --- a/lib/js-api/test/mockObjects/content-services/ecm-auth.mock.ts +++ b/lib/js-api/test/mockObjects/content-services/ecm-auth.mock.ts @@ -31,24 +31,45 @@ export class EcmAuthMock extends BaseMock { get201Response(forceTicket?: string): void { const returnMockTicket = forceTicket || 'TICKET_4479f4d3bb155195879bfbb8d5206f433488a1b1'; - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/authentication/versions/1/tickets', { - userId: this.username, - password: this.password + userId: 'admin', + password: 'admin' }) - .reply(201, { entry: { id: returnMockTicket, userId: 'admin' } }); + .reply(201, { + entry: { + id: returnMockTicket, + userId: 'admin' + } + }); + } + + get201ResponseJohnDoe(forceTicket?: string): void { + const returnMockTicket = forceTicket || 'TICKET_4479f4d3bb155195879bfbb8d5206f433488a1b1'; + + this.createNockWithCors() + .post('/alfresco/api/-default-/public/authentication/versions/1/tickets', { + userId: 'johndoe', + password: 'password' + }) + .reply(201, { + entry: { + id: returnMockTicket, + userId: 'johndoe' + } + }); } get200ValidTicket(forceTicket?: string): void { const returnMockTicket = forceTicket || 'TICKET_4479f4d3bb155195879bfbb8d5206f433488a1b1'; - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/authentication/versions/1/tickets/-me-') .reply(200, { entry: { id: returnMockTicket } }); } get401InvalidTicket(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/authentication/versions/1/tickets/-me-') .reply(401, { error: { @@ -61,8 +82,22 @@ export class EcmAuthMock extends BaseMock { }); } + get401InvalidRequest(): void { + this.createNockWithCors() + .get('/.*tickets.*/') + .reply(401, { + error: { + errorKey: 'framework.exception.ApiDefault', + statusCode: 401, + briefSummary: '05210059 Authentication failed for Web Script org/alfresco/api/ResourceWebScript.get', + stackTrace: 'For security reasons the stack trace is no longer displayed, but the property is kept for previous versions.', + descriptionURL: 'https://api-explorer.alfresco.com' + } + }); + } + get403Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/authentication/versions/1/tickets', { userId: 'wrong', password: 'name' @@ -79,24 +114,56 @@ export class EcmAuthMock extends BaseMock { } get400Response(): void { - nock(this.host, { encodedQueryParams: true }) + nock(this.host).options(/.*/).reply(200, '', { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, Content-Length, X-Requested-With', + 'Access-Control-Allow-Credentials': 'true' + }); + + nock(this.host) + .defaultReplyHeaders({ + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Credentials': 'true' + }) .post('/alfresco/api/-default-/public/authentication/versions/1/tickets', { userId: null, password: null }) .reply(400, { error: { - errorKey: 'Invalid login details.', + errorKey: 'Bad Request', statusCode: 400, - briefSummary: '05160045 Invalid login details.', - stackTrace: 'For security reasons the stack trace is no longer displayed, but the property is kept for previous versions.', - descriptionURL: 'https://api-explorer.alfresco.com' + briefSummary: 'userId and/or password are/is not provided' + } + }); + } + + get400ResponseGET(): void { + nock(this.host).persist().options(/.*/).reply(200, '', { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, Content-Length, X-Requested-With', + 'Access-Control-Allow-Credentials': 'true' + }); + + nock(this.host) + .defaultReplyHeaders({ + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Credentials': 'true' + }) + .get('/alfresco/api/-default-/public/authentication/versions/1/tickets/-me-') + .reply(400, { + error: { + errorKey: 'Bad Request', + statusCode: 400, + briefSummary: '05160045 Invalid login details.' } }); } get401Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/authentication/versions/1/tickets', { userId: 'wrong', password: 'name' @@ -113,10 +180,20 @@ export class EcmAuthMock extends BaseMock { } get204ResponseLogout(): void { - nock(this.host, { encodedQueryParams: true }).delete('/alfresco/api/-default-/public/authentication/versions/1/tickets/-me-').reply(204, ''); + this.createNockWithCors().delete('/alfresco/api/-default-/public/authentication/versions/1/tickets/-me-').reply(204, ''); } get404ResponseLogout(): void { - nock(this.host, { encodedQueryParams: true }).delete('/alfresco/api/-default-/public/authentication/versions/1/tickets/-me-').reply(404, ''); + this.createNockWithCors() + .delete('/alfresco/api/-default-/public/authentication/versions/1/tickets/-me-') + .reply(404, { + error: { + errorKey: 'Not Found', + statusCode: 404, + briefSummary: 'Not Found', + stackTrace: 'For security reasons the stack trace is no longer displayed, but the property is kept for previous versions.', + descriptionURL: 'https://api-explorer.alfresco.com' + } + }); } } diff --git a/lib/js-api/test/mockObjects/content-services/find-nodes.mock.ts b/lib/js-api/test/mockObjects/content-services/find-nodes.mock.ts index fd7fcd03cc..96bc5958a9 100644 --- a/lib/js-api/test/mockObjects/content-services/find-nodes.mock.ts +++ b/lib/js-api/test/mockObjects/content-services/find-nodes.mock.ts @@ -20,7 +20,7 @@ import { BaseMock } from '../base.mock'; export class FindNodesMock extends BaseMock { get200Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/alfresco/versions/1/queries/nodes?term=test') .reply(200, { list: { @@ -78,7 +78,7 @@ export class FindNodesMock extends BaseMock { } get401Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/alfresco/versions/1/queries/nodes?term=test') .reply(401, { error: { diff --git a/lib/js-api/test/mockObjects/content-services/groups.mock.ts b/lib/js-api/test/mockObjects/content-services/groups.mock.ts index a59bf57ac3..ecf81cb087 100644 --- a/lib/js-api/test/mockObjects/content-services/groups.mock.ts +++ b/lib/js-api/test/mockObjects/content-services/groups.mock.ts @@ -15,12 +15,11 @@ * limitations under the License. */ -import nock from 'nock'; import { BaseMock } from '../base.mock'; export class GroupsMock extends BaseMock { get200GetGroups(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/alfresco/versions/1/groups') .reply(200, { list: { @@ -52,20 +51,20 @@ export class GroupsMock extends BaseMock { } getDeleteGroupSuccessfulResponse(groupName: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .delete('/alfresco/api/-default-/public/alfresco/versions/1/groups/' + groupName) .query({ cascade: 'false' }) .reply(200); } getDeleteMemberForGroupSuccessfulResponse(groupName: string, memberName: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .delete('/alfresco/api/-default-/public/alfresco/versions/1/groups/' + groupName + '/members/' + memberName) .reply(200); } get200CreateGroupResponse(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/alfresco/versions/1/groups') .reply(200, { entry: { @@ -77,7 +76,7 @@ export class GroupsMock extends BaseMock { } get200GetSingleGroup(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/alfresco/versions/1/groups/GROUP_TEST') .reply(200, { entry: { @@ -89,7 +88,7 @@ export class GroupsMock extends BaseMock { } get200UpdateGroupResponse(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .put('/alfresco/api/-default-/public/alfresco/versions/1/groups/GROUP_TEST') .reply(200, { entry: { @@ -101,7 +100,7 @@ export class GroupsMock extends BaseMock { } get200GetGroupMemberships(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/alfresco/versions/1/groups/GROUP_TEST/members') .reply(200, { list: { @@ -126,7 +125,7 @@ export class GroupsMock extends BaseMock { } get200AddGroupMembershipResponse(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/alfresco/versions/1/groups/GROUP_TEST/members') .reply(200, { entry: { diff --git a/lib/js-api/test/mockObjects/content-services/node.mock.ts b/lib/js-api/test/mockObjects/content-services/node.mock.ts index 6baca0b833..161c369cf8 100644 --- a/lib/js-api/test/mockObjects/content-services/node.mock.ts +++ b/lib/js-api/test/mockObjects/content-services/node.mock.ts @@ -20,7 +20,7 @@ import { BaseMock } from '../base.mock'; export class NodeMock extends BaseMock { get200ResponseChildren(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/alfresco/versions/1/nodes/b4cff62a-664d-4d45-9302-98723eac1319/children') .reply(200, { list: { @@ -108,7 +108,7 @@ export class NodeMock extends BaseMock { } get200ResponseChildrenNonUTCTimes(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/alfresco/versions/1/nodes/b4cff62a-664d-4d45-9302-98723eac1320/children') .reply(200, { list: { @@ -140,7 +140,7 @@ export class NodeMock extends BaseMock { } get404ChildrenNotExist(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/alfresco/versions/1/nodes/b4cff62a-664d-4d45-9302-98723eac1319/children') .reply(404, { error: { @@ -154,23 +154,19 @@ export class NodeMock extends BaseMock { } get401CreationFolder(): void { - nock(this.host, { encodedQueryParams: true }).post('/alfresco/api/-default-/public/alfresco/versions/1/nodes/-root-/children').reply(401); + this.createNockWithCors().post('/alfresco/api/-default-/public/alfresco/versions/1/nodes/-root-/children').reply(401); } get204SuccessfullyDeleted(): void { - nock(this.host, { encodedQueryParams: true }) - .delete('/alfresco/api/-default-/public/alfresco/versions/1/nodes/80a94ac8-3ece-47ad-864e-5d939424c47c') - .reply(204); + this.createNockWithCors().delete('/alfresco/api/-default-/public/alfresco/versions/1/nodes/80a94ac8-3ece-47ad-864e-5d939424c47c').reply(204); } get403DeletePermissionDenied(): void { - nock(this.host, { encodedQueryParams: true }) - .delete('/alfresco/api/-default-/public/alfresco/versions/1/nodes/80a94ac8-3ece-47ad-864e-5d939424c47c') - .reply(403); + this.createNockWithCors().delete('/alfresco/api/-default-/public/alfresco/versions/1/nodes/80a94ac8-3ece-47ad-864e-5d939424c47c').reply(403); } get404DeleteNotFound(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .delete('/alfresco/api/-default-/public/alfresco/versions/1/nodes/80a94ac8-test-47ad-864e-5d939424c47c') .reply(404, { error: { @@ -184,7 +180,7 @@ export class NodeMock extends BaseMock { } get200ResponseChildrenFutureNewPossibleValue(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/alfresco/versions/1/nodes/b4cff62a-664d-4d45-9302-98723eac1319/children') .reply(200, { list: { @@ -232,7 +228,7 @@ export class NodeMock extends BaseMock { } post200ResponseInitiateFolderSizeCalculation(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/alfresco/versions/1/nodes/b4cff62a-664d-4d45-9302-98723eac1319/size-details') .reply(200, { entry: { @@ -242,7 +238,7 @@ export class NodeMock extends BaseMock { } post404NodeIdNotFound(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/alfresco/versions/1/nodes/b4cff62a-664d-4d45-9302-98723eac1319/size-details') .reply(404, { error: { @@ -257,7 +253,7 @@ export class NodeMock extends BaseMock { } get200ResponseGetFolderSizeInfo(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get( '/alfresco/api/-default-/public/alfresco/versions/1/nodes/b4cff62a-664d-4d45-9302-98723eac1319/size-details/5ade426e-8a04-4d50-9e42-6e8a041d50f3' ) @@ -274,7 +270,7 @@ export class NodeMock extends BaseMock { } get404JobIdNotFound(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get( '/alfresco/api/-default-/public/alfresco/versions/1/nodes/b4cff62a-664d-4d45-9302-98723eac1319/size-details/5ade426e-8a04-4d50-9e42-6e8a041d50f3' ) diff --git a/lib/js-api/test/mockObjects/content-services/people.mock.ts b/lib/js-api/test/mockObjects/content-services/people.mock.ts index 0361e21ea9..b5004c9ade 100644 --- a/lib/js-api/test/mockObjects/content-services/people.mock.ts +++ b/lib/js-api/test/mockObjects/content-services/people.mock.ts @@ -20,7 +20,7 @@ import { BaseMock } from '../base.mock'; export class PeopleMock extends BaseMock { get201Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/alfresco/versions/1/people') .reply(201, { entry: { @@ -36,7 +36,7 @@ export class PeopleMock extends BaseMock { } get200ResponsePersons(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/alfresco/versions/1/people') .reply(200, { list: { diff --git a/lib/js-api/test/mockObjects/content-services/rendition.mock.ts b/lib/js-api/test/mockObjects/content-services/rendition.mock.ts index 82cb974bfc..8720696423 100644 --- a/lib/js-api/test/mockObjects/content-services/rendition.mock.ts +++ b/lib/js-api/test/mockObjects/content-services/rendition.mock.ts @@ -15,12 +15,11 @@ * limitations under the License. */ -import nock from 'nock'; import { BaseMock } from '../base.mock'; export class RenditionMock extends BaseMock { get200RenditionResponse(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/alfresco/versions/1/nodes/97a29e9c-1e4f-4d9d-bb02-1ec920dda045/renditions/pdf') .reply(200, { entry: { @@ -32,13 +31,13 @@ export class RenditionMock extends BaseMock { } createRendition200(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/alfresco/versions/1/nodes/97a29e9c-1e4f-4d9d-bb02-1ec920dda045/renditions', { id: 'pdf' }) .reply(202, ''); } get200RenditionList(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/alfresco/versions/1/nodes/97a29e9c-1e4f-4d9d-bb02-1ec920dda045/renditions') .reply(200, { list: { diff --git a/lib/js-api/test/mockObjects/content-services/search-ai.mock.ts b/lib/js-api/test/mockObjects/content-services/search-ai.mock.ts index daac9702ec..9a548db405 100644 --- a/lib/js-api/test/mockObjects/content-services/search-ai.mock.ts +++ b/lib/js-api/test/mockObjects/content-services/search-ai.mock.ts @@ -16,11 +16,10 @@ */ import { BaseMock } from '../base.mock'; -import nock from 'nock'; export class SearchAiMock extends BaseMock { mockGetAsk200Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/private/hxi/versions/1/agents/id1/questions', [ { question: 'some question 1', @@ -41,7 +40,7 @@ export class SearchAiMock extends BaseMock { } mockGetAnswer200Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/private/hxi/versions/1/questions/id1/answers/-default-') .reply(200, { entry: { @@ -85,7 +84,7 @@ export class SearchAiMock extends BaseMock { } mockGetConfig200Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/private/hxi/versions/1/config/-default-') .reply(200, { entry: { diff --git a/lib/js-api/test/mockObjects/content-services/search.mock.ts b/lib/js-api/test/mockObjects/content-services/search.mock.ts index 5e7796269c..b3711b4d21 100644 --- a/lib/js-api/test/mockObjects/content-services/search.mock.ts +++ b/lib/js-api/test/mockObjects/content-services/search.mock.ts @@ -15,13 +15,12 @@ * limitations under the License. */ -import nock from 'nock'; import { BaseMock } from '../base.mock'; import { SEARCH_LANGUAGE } from '@alfresco/js-api'; export class SearchMock extends BaseMock { get200Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/search/versions/1/search', { query: { query: 'select * from cmis:folder', diff --git a/lib/js-api/test/mockObjects/content-services/tag.mock.ts b/lib/js-api/test/mockObjects/content-services/tag.mock.ts index ba3362c1b3..a7853e30f9 100644 --- a/lib/js-api/test/mockObjects/content-services/tag.mock.ts +++ b/lib/js-api/test/mockObjects/content-services/tag.mock.ts @@ -15,25 +15,22 @@ * limitations under the License. */ -import nock from 'nock'; import { BaseMock } from '../base.mock'; import { TagBody, TagEntry, TagPaging } from '../../../src/api/content-rest-api'; export class TagMock extends BaseMock { get200Response(): void { - nock(this.host, { encodedQueryParams: true }) - .get('/alfresco/api/-default-/public/alfresco/versions/1/tags') - .reply(200, this.getPaginatedListOfTags()); + this.createNockWithCors().get('/alfresco/api/-default-/public/alfresco/versions/1/tags').reply(200, this.getPaginatedListOfTags()); } getTagsByNameFilteredByMatching200Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/alfresco/versions/1/tags?where=(tag%20matches%20(%27*tag-test*%27))') .reply(200, this.getPaginatedListOfTags()); } getTagsByNamesFilterByExactTag200Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/alfresco/versions/1/tags?where=(tag%3D%27tag-test-1%27)') .reply(200, { list: { @@ -49,7 +46,7 @@ export class TagMock extends BaseMock { } get401Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/alfresco/versions/1/tags') .reply(401, { error: { @@ -63,13 +60,11 @@ export class TagMock extends BaseMock { } createTags201Response(): void { - nock(this.host, { encodedQueryParams: true }) - .post('/alfresco/api/-default-/public/alfresco/versions/1/tags') - .reply(201, this.getPaginatedListOfTags()); + this.createNockWithCors().post('/alfresco/api/-default-/public/alfresco/versions/1/tags').reply(201, this.getPaginatedListOfTags()); } get201ResponseForAssigningTagsToNode(body: TagBody[]): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/alfresco/versions/1/nodes/someNodeId/tags', JSON.stringify(body)) .reply(201, body.length > 1 ? this.getPaginatedListOfTags() : this.mockTagEntry()); } diff --git a/lib/js-api/test/mockObjects/content-services/upload.mock.ts b/lib/js-api/test/mockObjects/content-services/upload.mock.ts index d3ffca0963..642ca3f871 100644 --- a/lib/js-api/test/mockObjects/content-services/upload.mock.ts +++ b/lib/js-api/test/mockObjects/content-services/upload.mock.ts @@ -20,7 +20,19 @@ import { BaseMock } from '../base.mock'; export class UploadMock extends BaseMock { get201CreationFile(): void { - nock(this.host, { encodedQueryParams: true }) + nock(this.host).persist().options(/.*/).reply(200, '', { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, Content-Length, X-Requested-With', + 'Access-Control-Allow-Credentials': 'true' + }); + + // Handle POST request with any query parameters + nock(this.host) + .defaultReplyHeaders({ + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Credentials': 'true' + }) .post('/alfresco/api/-default-/public/alfresco/versions/1/nodes/-root-/children') .reply(201, { entry: { @@ -47,7 +59,7 @@ export class UploadMock extends BaseMock { } get201CreationFileAutoRename(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/alfresco/versions/1/nodes/-root-/children') .query({ autoRename: 'true' }) .reply(201, { @@ -75,7 +87,7 @@ export class UploadMock extends BaseMock { } get409CreationFileNewNameClashes(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/alfresco/versions/1/nodes/-root-/children') .reply(409, { error: { @@ -89,7 +101,7 @@ export class UploadMock extends BaseMock { } get401Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/alfresco/versions/1/nodes/-root-/children') .reply(401, { error: { diff --git a/lib/js-api/test/mockObjects/content-services/version.mock.ts b/lib/js-api/test/mockObjects/content-services/version.mock.ts index 9bb1dd4bfe..76bfbc5aa1 100644 --- a/lib/js-api/test/mockObjects/content-services/version.mock.ts +++ b/lib/js-api/test/mockObjects/content-services/version.mock.ts @@ -15,18 +15,17 @@ * limitations under the License. */ -import nock from 'nock'; import { BaseMock } from '../base.mock'; export class VersionMock extends BaseMock { post201Response(nodeId: string, versionId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/alfresco/versions/1/nodes/' + nodeId + '/versions/' + versionId + '/revert') .reply(201, { entry: { id: '3.0' } }); } get200Response(nodeId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/alfresco/versions/1/nodes/' + nodeId + '/versions') .reply(200, { list: { @@ -43,7 +42,7 @@ export class VersionMock extends BaseMock { } get200ResponseVersionRenditions(nodeId: string, versionId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/alfresco/versions/1/nodes/' + nodeId + '/versions/' + versionId + '/renditions') .reply(200, { list: { @@ -103,7 +102,7 @@ export class VersionMock extends BaseMock { } get200VersionRendition(nodeId: string, versionId: string, renditionId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/alfresco/versions/1/nodes/' + nodeId + '/versions/' + versionId + '/renditions/' + renditionId) .reply(200, { entry: { @@ -115,7 +114,7 @@ export class VersionMock extends BaseMock { } create200VersionRendition(nodeId: string, versionId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/alfresco/versions/1/nodes/' + nodeId + '/versions/' + versionId + '/renditions', { id: 'pdf' }) .reply(202, ''); } diff --git a/lib/js-api/test/mockObjects/content-services/webscript.mock.ts b/lib/js-api/test/mockObjects/content-services/webscript.mock.ts index 4646d2ba7c..9662e2dec7 100644 --- a/lib/js-api/test/mockObjects/content-services/webscript.mock.ts +++ b/lib/js-api/test/mockObjects/content-services/webscript.mock.ts @@ -15,7 +15,6 @@ * limitations under the License. */ -import nock from 'nock'; import { BaseMock } from '../base.mock'; export class WebScriptMock extends BaseMock { @@ -34,7 +33,7 @@ export class WebScriptMock extends BaseMock { } get404Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get(this.scriptSlug) .reply(404, { error: { @@ -48,7 +47,7 @@ export class WebScriptMock extends BaseMock { } get200Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get(this.scriptSlug) .reply(200, { randomStructure: { @@ -59,17 +58,15 @@ export class WebScriptMock extends BaseMock { } get200ResponseHTMLFormat(): void { - nock(this.host, { encodedQueryParams: true }) - .get('/alfresco/service/sample/folder/Company%20Home') - .reply( - 200, - // eslint-disable-next-line max-len - '\n \n /Company Home\n \n \n Folder: /Company Home\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
>Data Dictionary\n
>Guest Home\n
>User Homes\n
>Shared\n
>Imap Attachments\n
>IMAP Home\n
>Sites\n
>x\n
testFile.txt\n
>newFolder\n
>newFolder-1\n
testFile-1.txt\n
testFile-2.txt\n
testFile-3.txt\n
\n \n\n\n' - ); // jshint ignore:line + this.createNockWithCors().get('/alfresco/service/sample/folder/Company%20Home').reply( + 200, + // eslint-disable-next-line max-len + '\n \n /Company Home\n \n \n Folder: /Company Home\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
>Data Dictionary\n
>Guest Home\n
>User Homes\n
>Shared\n
>Imap Attachments\n
>IMAP Home\n
>Sites\n
>x\n
testFile.txt\n
>newFolder\n
>newFolder-1\n
testFile-1.txt\n
testFile-2.txt\n
testFile-3.txt\n
\n \n\n\n' + ); // jshint ignore:line } get401Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get(this.scriptSlug) .reply(401, { error: { diff --git a/lib/js-api/test/mockObjects/goverance-services/authority-clearance.mock.ts b/lib/js-api/test/mockObjects/goverance-services/authority-clearance.mock.ts index 589f6232f5..f0abc9a2b8 100644 --- a/lib/js-api/test/mockObjects/goverance-services/authority-clearance.mock.ts +++ b/lib/js-api/test/mockObjects/goverance-services/authority-clearance.mock.ts @@ -16,11 +16,10 @@ */ import { BaseMock } from '../base.mock'; -import nock from 'nock'; export class AuthorityClearanceMock extends BaseMock { get200AuthorityClearanceForAuthority(authorityId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/gs/versions/1/cleared-authorities/' + authorityId + '/clearing-marks?skipCount=0&maxItems=100') .reply(200, { list: { @@ -94,7 +93,7 @@ export class AuthorityClearanceMock extends BaseMock { } post200AuthorityClearanceWithSingleItem(authorityId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/gs/versions/1/cleared-authorities/' + authorityId + '/clearing-marks') .reply(200, { entry: { @@ -106,7 +105,7 @@ export class AuthorityClearanceMock extends BaseMock { } post200AuthorityClearanceWithList(authorityId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/gs/versions/1/cleared-authorities/' + authorityId + '/clearing-marks') .reply(200, { list: { diff --git a/lib/js-api/test/mockObjects/goverance-services/file-plans.mock.ts b/lib/js-api/test/mockObjects/goverance-services/file-plans.mock.ts index 64e4997b93..098405a735 100644 --- a/lib/js-api/test/mockObjects/goverance-services/file-plans.mock.ts +++ b/lib/js-api/test/mockObjects/goverance-services/file-plans.mock.ts @@ -49,7 +49,7 @@ export class FilePlansMock extends BaseMock { } private nock200FilePlanRoles(filePlanId: string): nock.Interceptor { - return nock(this.host, { encodedQueryParams: true }).get(`/alfresco/api/-default-/public/gs/versions/1/file-plans/${filePlanId}/roles`); + return this.createNockWithCors().get(`/alfresco/api/-default-/public/gs/versions/1/file-plans/${filePlanId}/roles`); } private mockFilePlanRolePaging(): FilePlanRolePaging { diff --git a/lib/js-api/test/mockObjects/goverance-services/gs-sites.mock.ts b/lib/js-api/test/mockObjects/goverance-services/gs-sites.mock.ts index 36501176b3..13d98ead35 100644 --- a/lib/js-api/test/mockObjects/goverance-services/gs-sites.mock.ts +++ b/lib/js-api/test/mockObjects/goverance-services/gs-sites.mock.ts @@ -15,12 +15,11 @@ * limitations under the License. */ -import nock from 'nock'; import { BaseMock } from '../base.mock'; export class GsSitesApiMock extends BaseMock { get200Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/gs/versions/1/gs-sites/rm') .reply(200, { entry: { diff --git a/lib/js-api/test/mockObjects/goverance-services/node-security-marks.mock.ts b/lib/js-api/test/mockObjects/goverance-services/node-security-marks.mock.ts index 6f551d3efa..40fc20858c 100644 --- a/lib/js-api/test/mockObjects/goverance-services/node-security-marks.mock.ts +++ b/lib/js-api/test/mockObjects/goverance-services/node-security-marks.mock.ts @@ -15,12 +15,11 @@ * limitations under the License. */ -import nock from 'nock'; import { BaseMock } from '../base.mock'; export class NodeSecurityMarksApiMock extends BaseMock { post200manageSecurityMarkOnNode(nodeId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/gs/versions/1/secured-nodes/' + nodeId + '/securing-marks') .reply(200, { list: { @@ -52,7 +51,7 @@ export class NodeSecurityMarksApiMock extends BaseMock { } get200SecurityMarkOnNode(nodeId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/gs/versions/1/secured-nodes/' + nodeId + '/securing-marks') .reply(200, { list: { diff --git a/lib/js-api/test/mockObjects/goverance-services/security-groups.mock.ts b/lib/js-api/test/mockObjects/goverance-services/security-groups.mock.ts index 95bb7afa37..d73aa0f5e6 100644 --- a/lib/js-api/test/mockObjects/goverance-services/security-groups.mock.ts +++ b/lib/js-api/test/mockObjects/goverance-services/security-groups.mock.ts @@ -15,12 +15,11 @@ * limitations under the License. */ -import nock from 'nock'; import { BaseMock } from '../base.mock'; export class SecurityGroupApiMock extends BaseMock { createSecurityGroup200Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/gs/versions/1/security-groups') .reply(200, { entry: { @@ -32,7 +31,7 @@ export class SecurityGroupApiMock extends BaseMock { } getSecurityGroups200Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/gs/versions/1/security-groups') .reply(200, { list: { @@ -64,7 +63,7 @@ export class SecurityGroupApiMock extends BaseMock { } getSecurityGroupInfo200Response(securityGroupId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/gs/versions/1/security-groups/' + securityGroupId) .reply(200, { entry: { @@ -76,7 +75,7 @@ export class SecurityGroupApiMock extends BaseMock { } updateSecurityGroup200Response(securityGroupId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .put('/alfresco/api/-default-/public/gs/versions/1/security-groups/' + securityGroupId) .reply(200, { entry: { @@ -88,8 +87,8 @@ export class SecurityGroupApiMock extends BaseMock { } deleteSecurityGroup200Response(securityGroupId: string): void { - nock(this.host, { encodedQueryParams: true }) - .delete('/alfresco/api/-default-/public/alfresco/versions/1/security-groups/' + securityGroupId) - .reply(200); + this.createNockWithCors() + .delete('/alfresco/api/-default-/public/gs/versions/1/security-groups/' + securityGroupId) + .reply(204); } } diff --git a/lib/js-api/test/mockObjects/goverance-services/security-marks.mock.ts b/lib/js-api/test/mockObjects/goverance-services/security-marks.mock.ts index af7afc9ceb..0328d0839b 100644 --- a/lib/js-api/test/mockObjects/goverance-services/security-marks.mock.ts +++ b/lib/js-api/test/mockObjects/goverance-services/security-marks.mock.ts @@ -20,7 +20,7 @@ import { BaseMock } from '../base.mock'; export class SecurityMarkApiMock extends BaseMock { get200GetSecurityMark(securityGroupId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/gs/versions/1/security-groups/' + securityGroupId + '/security-marks') .reply(200, { list: { @@ -45,7 +45,7 @@ export class SecurityMarkApiMock extends BaseMock { } createSecurityMark200Response(securityGroupId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/gs/versions/1/security-groups/' + securityGroupId + '/security-marks') .reply(200, { entry: { @@ -56,7 +56,7 @@ export class SecurityMarkApiMock extends BaseMock { }); } createSecurityMarks200Response(securityGroupId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/alfresco/api/-default-/public/gs/versions/1/security-groups/' + securityGroupId + '/security-marks') .reply(200, { list: { @@ -87,7 +87,7 @@ export class SecurityMarkApiMock extends BaseMock { }); } get200GetSingleSecurityMark(securityGroupId: string, securityMarkId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/gs/versions/1/security-groups/' + securityGroupId + '/security-marks/' + securityMarkId) .reply(200, { entry: { @@ -98,7 +98,7 @@ export class SecurityMarkApiMock extends BaseMock { }); } put200UpdateSecurityMarkResponse(securityGroupId: string, securityMarkId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .put('/alfresco/api/-default-/public/gs/versions/1/security-groups/' + securityGroupId + '/security-marks/' + securityMarkId) .reply(200, { entry: { @@ -109,12 +109,14 @@ export class SecurityMarkApiMock extends BaseMock { }); } getDeleteSecurityMarkSuccessfulResponse(securityGroupId: string, securityMarkId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.addCorsSupport(); + nock(this.host) + .defaultReplyHeaders(this.getBaseHeaders()) .delete('/alfresco/api/-default-/public/gs/versions/1/security-groups/' + securityGroupId + '/security-marks/' + securityMarkId) .reply(200); } get401Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/alfresco/api/-default-/public/gs/versions/1/security-groups/') .reply(401, { error: { diff --git a/lib/js-api/test/mockObjects/oauth2/oauth.mock.ts b/lib/js-api/test/mockObjects/oauth2/oauth.mock.ts index 3d1afb6982..6fd746dc65 100644 --- a/lib/js-api/test/mockObjects/oauth2/oauth.mock.ts +++ b/lib/js-api/test/mockObjects/oauth2/oauth.mock.ts @@ -29,18 +29,31 @@ export class OAuthMock extends BaseMock { } get200Response(mockToken?: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/auth/realms/springboot/protocol/openid-connect/token') - .reply(200, { - access_token: mockToken || 'test-token', - expires_in: 300, - refresh_expires_in: 1800, - refresh_token: - // eslint-disable-next-line max-len - 'eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0cHczOUltNE54dXZEN0ZqZ3JOQ3Q2ZkpaVDctQ3JWTzRkX3BLaXJlSTF3In0.eyJqdGkiOiI2MzQxMDc1ZC1lOTY4LTRmZTctOTkwZS05MTQ3NTUwOGEzZWIiLCJleHAiOjE1Mjk2MDkxMDYsIm5iZiI6MCwiaWF0IjoxNTI5NjA3MzA2LCJpc3MiOiJodHRwOi8vYTVlMmY5M2RlMTBhZjExZThhMDU2MGExYmVhNWI3YzgtMjM2NzA5NDMzLnVzLWVhc3QtMS5lbGIuYW1hem9uYXdzLmNvbTozMDA4MS9hdXRoL3JlYWxtcy9zcHJpbmdib290IiwiYXVkIjoiYWN0aXZpdGkiLCJzdWIiOiJlMjRjZjM0Mi1mYzUwLTRjYjEtYTBjMC01N2RhZWRiODI3NDkiLCJ0eXAiOiJSZWZyZXNoIiwiYXpwIjoiYWN0aXZpdGkiLCJhdXRoX3RpbWUiOjAsInNlc3Npb25fc3RhdGUiOiI5NDMzZTIwNi1kZjFhLTQ2YTMtYmU3ZS02NWIwNDVhMWMzNmIiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiYWRtaW4iLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7InJlYWxtLW1hbmFnZW1lbnQiOnsicm9sZXMiOlsidmlldy1pZGVudGl0eS1wcm92aWRlcnMiLCJ2aWV3LXJlYWxtIiwibWFuYWdlLWlkZW50aXR5LXByb3ZpZGVycyIsImltcGVyc29uYXRpb24iLCJyZWFsbS1hZG1pbiIsImNyZWF0ZS1jbGllbnQiLCJtYW5hZ2UtdXNlcnMiLCJxdWVyeS1yZWFsbXMiLCJ2aWV3LWF1dGhvcml6YXRpb24iLCJxdWVyeS1jbGllbnRzIiwicXVlcnktdXNlcnMiLCJtYW5hZ2UtZXZlbnRzIiwibWFuYWdlLXJlYWxtIiwidmlldy1ldmVudHMiLCJ2aWV3LXVzZXJzIiwidmlldy1jbGllbnRzIiwibWFuYWdlLWF1dGhvcml6YXRpb24iLCJtYW5hZ2UtY2xpZW50cyIsInF1ZXJ5LWdyb3VwcyJdfSwiYnJva2VyIjp7InJvbGVzIjpbInJlYWQtdG9rZW4iXX0sImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX19.mQ4Vi1yLG9KvcmmhHlgOowy8D30iaUsiO7--JTPY7Ol-R1eY4wvRn1cH5FllieXk8yltYGP23xXNtTC4M54guXGVtgRgo8AlRklFHL1BMlxpa0OPwcNmwthx1-P2n7c9XL1e8pt2uRhQJLxunr2TpLaQi0UpEmEyouXHfR7sxM1AzKAf3b9Nk7f7lrk__2BYlFsL3YcGlFDqDMgPfhNlDbR-rQGoxlOjt0YqS8ktYq4bneL5etpXnPh0oEt4B7FFK-WKKuOWR6rQ9791ACnn6puz6C_Ki261IkZ0a_Uu7tOA4Xi9xzoQKLgSTAlBeg4u86Wb5kjL5r2-3zTg-Dikew', - token_type: 'bearer', - 'not-before-policy': 0, - session_state: '9433e206-df1a-46a3-be7e-65b045a1c36b' - }); + .reply( + 200, + { + access_token: mockToken || 'test-token', + expires_in: 300, + refresh_expires_in: 1800, + refresh_token: + // eslint-disable-next-line max-len + 'eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0cHczOUltNE54dXZEN0ZqZ3JOQ3Q2ZkpaVDctQ3JWTzRkX3BLaXJlSTF3In0.eyJqdGkiOiI2MzQxMDc1ZC1lOTY4LTRmZTctOTkwZS05MTQ3NTUwOGEzZWIiLCJleHAiOjE1Mjk2MDkxMDYsIm5iZiI6MCwiaWF0IjoxNTI5NjA3MzA2LCJpc3MiOiJodHRwOi8vYTVlMmY5M2RlMTBhZjExZThhMDU2MGExYmVhNWI3YzgtMjM2NzA5NDMzLnVzLWVhc3QtMS5lbGIuYW1hem9uYXdzLmNvbTozMDA4MS9hdXRoL3JlYWxtcy9zcHJpbmdib290IiwiYXVkIjoiYWN0aXZpdGkiLCJzdWIiOiJlMjRjZjM0Mi1mYzUwLTRjYjEtYTBjMC01N2RhZWRiODI3NDkiLCJ0eXAiOiJSZWZyZXNoIiwiYXpwIjoiYWN0aXZpdGkiLCJhdXRoX3RpbWUiOjAsInNlc3Npb25fc3RhdGUiOiI5NDMzZTIwNi1kZjFhLTQ2YTMtYmU3ZS02NWIwNDVhMWMzNmIiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiYWRtaW4iLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7InJlYWxtLW1hbmFnZW1lbnQiOnsicm9sZXMiOlsidmlldy1pZGVudGl0eS1wcm92aWRlcnMiLCJ2aWV3LXJlYWxtIiwibWFuYWdlLWlkZW50aXR5LXByb3ZpZGVycyIsImltcGVyc29uYXRpb24iLCJyZWFsbS1hZG1pbiIsImNyZWF0ZS1jbGllbnQiLCJtYW5hZ2UtdXNlcnMiLCJxdWVyeS1yZWFsbXMiLCJ2aWV3LWF1dGhvcml6YXRpb24iLCJxdWVyeS1jbGllbnRzIiwicXVlcnktdXNlcnMiLCJtYW5hZ2UtZXZlbnRzIiwibWFuYWdlLXJlYWxtIiwidmlldy1ldmVudHMiLCJ2aWV3LXVzZXJzIiwidmlldy1jbGllbnRzIiwibWFuYWdlLWF1dGhvcml6YXRpb24iLCJtYW5hZ2UtY2xpZW50cyIsInF1ZXJ5LWdyb3VwcyJdfSwiYnJva2VyIjp7InJvbGVzIjpbInJlYWQtdG9rZW4iXX0sImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX19.mQ4Vi1yLG9KvcmmhHlgOowy8D30iaUsiO7--JTPY7Ol-R1eY4wvRn1cH5FllieXk8yltYGP23xXNtTC4M54guXGVtgRgo8AlRklFHL1BMlxpa0OPwcNmwthx1-P2n7c9XL1e8pt2uRhQJLxunr2TpLaQi0UpEmEyouXHfR7sxM1AzKAf3b9Nk7f7lrk__2BYlFsL3YcGlFDqDMgPfhNlDbR-rQGoxlOjt0YqS8ktYq4bneL5etpXnPh0oEt4B7FFK-WKKuOWR6rQ9791ACnn6puz6C_Ki261IkZ0a_Uu7tOA4Xi9xzoQKLgSTAlBeg4u86Wb5kjL5r2-3zTg-Dikew', + token_type: 'bearer', + 'not-before-policy': 0, + session_state: '9433e206-df1a-46a3-be7e-65b045a1c36b' + }, + { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With', + 'Content-Type': 'application/json' + } + ); + } + + cleanAll() { + nock.cleanAll(); } } diff --git a/lib/js-api/test/mockObjects/process-services/bpm-auth.mock.ts b/lib/js-api/test/mockObjects/process-services/bpm-auth.mock.ts index aae55fd881..afd67bf2d6 100644 --- a/lib/js-api/test/mockObjects/process-services/bpm-auth.mock.ts +++ b/lib/js-api/test/mockObjects/process-services/bpm-auth.mock.ts @@ -29,7 +29,15 @@ export class BpmAuthMock extends BaseMock { } get200Response(): void { + this.addCorsSupport(); nock(this.host, { encodedQueryParams: true }) + .defaultReplyHeaders({ + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, Content-Length, X-Requested-With, Cache-Control, X-CSRF-TOKEN', + 'Access-Control-Allow-Credentials': 'true', + 'Set-Cookie': 'ACTIVITI_REMEMBER_ME=NjdOdGwvcUtFTkVEczQyMGh4WFp5QT09OmpUL1UwdFVBTC94QTJMTFFUVFgvdFE9PQ; Path=/; HttpOnly' + }) .post( '/activiti-app/app/authentication', 'j_username=' + this.username + '&j_password=' + this.password + '&_spring_security_remember_me=true&submit=Login' @@ -38,11 +46,11 @@ export class BpmAuthMock extends BaseMock { } get200ResponseLogout(): void { - nock(this.host, { encodedQueryParams: true }).get('/activiti-app/app/logout', {}).reply(200); + this.createNockWithCors().get('/activiti-app/app/logout').reply(200); } get401Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/activiti-app/app/authentication', 'j_username=wrong&j_password=name&_spring_security_remember_me=true&submit=Login') .reply(401, { error: { @@ -53,7 +61,7 @@ export class BpmAuthMock extends BaseMock { } get403Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/activiti-app/app/authentication', 'j_username=wrong&j_password=name&_spring_security_remember_me=true&submit=Login') .reply(403, { error: { diff --git a/lib/js-api/test/mockObjects/process-services/model-json.mock.ts b/lib/js-api/test/mockObjects/process-services/model-json.mock.ts index c2924acd52..bd752f0f50 100644 --- a/lib/js-api/test/mockObjects/process-services/model-json.mock.ts +++ b/lib/js-api/test/mockObjects/process-services/model-json.mock.ts @@ -15,12 +15,11 @@ * limitations under the License. */ -import nock from 'nock'; import { BaseMock } from '../base.mock'; export class ModelJsonBpmMock extends BaseMock { get200EditorDisplayJsonClient(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/activiti-app/app/rest/models/1/model-json') .reply(200, { elements: [ @@ -87,7 +86,7 @@ export class ModelJsonBpmMock extends BaseMock { } get200HistoricEditorDisplayJsonClient(): void { - nock('https://127.0.0.1:9999', { encodedQueryParams: true }) + this.createNockWithCors() .get('/activiti-app/app/rest/models/1/history/1/model-json') .reply(200, { elements: [ diff --git a/lib/js-api/test/mockObjects/process-services/models.mock.ts b/lib/js-api/test/mockObjects/process-services/models.mock.ts index 63d4261b63..5ca2438e0b 100644 --- a/lib/js-api/test/mockObjects/process-services/models.mock.ts +++ b/lib/js-api/test/mockObjects/process-services/models.mock.ts @@ -15,12 +15,11 @@ * limitations under the License. */ -import nock from 'nock'; import { BaseMock } from '../base.mock'; export class ModelsMock extends BaseMock { get200getModels(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/activiti-app/api/enterprise/models') .query({ filter: 'myReusableForms', modelType: '2' }) .reply(200, { diff --git a/lib/js-api/test/mockObjects/process-services/process-instance-variables.mock.ts b/lib/js-api/test/mockObjects/process-services/process-instance-variables.mock.ts index e1dc6d5efe..364e05ed6b 100644 --- a/lib/js-api/test/mockObjects/process-services/process-instance-variables.mock.ts +++ b/lib/js-api/test/mockObjects/process-services/process-instance-variables.mock.ts @@ -34,13 +34,13 @@ const fakeVariablesList = [fakeVariable1, fakeVariable2]; export class ProcessInstanceVariablesMock extends BaseMock { addListProcessInstanceVariables200Response(processInstanceId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/activiti-app/api/enterprise/process-instances/' + processInstanceId + '/variables') .reply(200, fakeVariablesList); } addListProcessInstanceVariables500Response(processInstanceId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/activiti-app/api/enterprise/process-instances/' + processInstanceId + '/variables') .reply(500, { messageKey: 'UNKNOWN', @@ -49,13 +49,13 @@ export class ProcessInstanceVariablesMock extends BaseMock { } addPutProcessInstanceVariables200Response(processInstanceId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .put('/activiti-app/api/enterprise/process-instances/' + processInstanceId + '/variables') .reply(200, fakeVariablesList); } addPutProcessInstanceVariables500Response(processInstanceId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .put('/activiti-app/api/enterprise/process-instances/' + processInstanceId + '/variables') .reply(500, { messageKey: 'UNKNOWN', @@ -64,13 +64,13 @@ export class ProcessInstanceVariablesMock extends BaseMock { } addGetProcessInstanceVariable200Response(processInstanceId: string, variableName: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/activiti-app/api/enterprise/process-instances/' + processInstanceId + '/variables/' + variableName) .reply(200, fakeVariable1); } addGetProcessInstanceVariable500Response(processInstanceId: string, variableName: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/activiti-app/api/enterprise/process-instances/' + processInstanceId + '/variables/' + variableName) .reply(500, { messageKey: 'UNKNOWN', @@ -79,13 +79,13 @@ export class ProcessInstanceVariablesMock extends BaseMock { } addUpdateProcessInstanceVariable200Response(processInstanceId: string, variableName: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .put('/activiti-app/api/enterprise/process-instances/' + processInstanceId + '/variables/' + variableName) .reply(200, fakeVariable1); } addUpdateProcessInstanceVariable500Response(processInstanceId: string, variableName: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .put('/activiti-app/api/enterprise/process-instances/' + processInstanceId + '/variables/' + variableName) .reply(500, { messageKey: 'UNKNOWN', @@ -94,13 +94,13 @@ export class ProcessInstanceVariablesMock extends BaseMock { } addDeleteProcessInstanceVariable200Response(processInstanceId: string, variableName: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .delete('/activiti-app/api/enterprise/process-instances/' + processInstanceId + '/variables/' + variableName) .reply(200); } addDeleteProcessInstanceVariable500Response(processInstanceId: string, variableName: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .delete('/activiti-app/api/enterprise/process-instances/' + processInstanceId + '/variables/' + variableName) .reply(500, { messageKey: 'UNKNOWN', diff --git a/lib/js-api/test/mockObjects/process-services/process.mock.ts b/lib/js-api/test/mockObjects/process-services/process.mock.ts index 2206373db7..92663ba382 100644 --- a/lib/js-api/test/mockObjects/process-services/process.mock.ts +++ b/lib/js-api/test/mockObjects/process-services/process.mock.ts @@ -15,12 +15,11 @@ * limitations under the License. */ -import nock from 'nock'; import { BaseMock } from '../base.mock'; export class ProcessMock extends BaseMock { get200Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/activiti-app/api/enterprise/process-instances/query') .reply(200, { size: 2, @@ -82,7 +81,7 @@ export class ProcessMock extends BaseMock { } get200getProcessDefinitionStartForm(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/activiti-app/api/enterprise/process-definitions/testProcess%3A1%3A7504/start-form') .reply(200, { id: 2002, diff --git a/lib/js-api/test/mockObjects/process-services/profile.mock.ts b/lib/js-api/test/mockObjects/process-services/profile.mock.ts index bf5c65b2dc..f4330ee065 100644 --- a/lib/js-api/test/mockObjects/process-services/profile.mock.ts +++ b/lib/js-api/test/mockObjects/process-services/profile.mock.ts @@ -20,7 +20,7 @@ import { BaseMock } from '../base.mock'; export class ProfileMock extends BaseMock { get200getProfile(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/activiti-app/api/enterprise/profile') .reply(200, { id: 1, @@ -94,10 +94,10 @@ export class ProfileMock extends BaseMock { } get401getProfile(): void { - nock(this.host, { encodedQueryParams: true }).get('/activiti-app/api/enterprise/profile').reply(401); + this.createNockWithCors().get('/activiti-app/api/enterprise/profile').reply(401); } get200getProfilePicture(): void { - nock(this.host, { encodedQueryParams: true }).get('/activiti-app/api/enterprise/profile-picture').reply(200, 'BUFFERSIZE'); + this.createNockWithCors().get('/activiti-app/api/enterprise/profile-picture').reply(200, 'BUFFERSIZE'); } } diff --git a/lib/js-api/test/mockObjects/process-services/reports.mock.ts b/lib/js-api/test/mockObjects/process-services/reports.mock.ts index 31fe986ae3..c8c93f4d83 100644 --- a/lib/js-api/test/mockObjects/process-services/reports.mock.ts +++ b/lib/js-api/test/mockObjects/process-services/reports.mock.ts @@ -15,7 +15,6 @@ * limitations under the License. */ -import nock from 'nock'; import { BaseMock } from '../base.mock'; const fakeReportList = [ @@ -154,58 +153,56 @@ const fakeProcessDefinitionsNoApp: any[] = [ export class ReportsMock extends BaseMock { get200ResponseCreateDefaultReport(): void { - nock(this.host, { encodedQueryParams: true }).post('/activiti-app/app/rest/reporting/default-reports').reply(200); + this.createNockWithCors().post('/activiti-app/app/rest/reporting/default-reports').reply(200); } get200ResponseTasksByProcessDefinitionId(reportId: string, processDefinitionId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/activiti-app/app/rest/reporting/report-params/' + reportId + '/tasks') .query({ processDefinitionId }) .reply(200, ['Fake Task 1', 'Fake Task 2', 'Fake Task 3']); } get200ResponseReportList(): void { - nock(this.host, { encodedQueryParams: true }).get('/activiti-app/app/rest/reporting/reports').reply(200, fakeReportList); + this.createNockWithCors().get('/activiti-app/app/rest/reporting/reports').reply(200, fakeReportList); } get200ResponseReportParams(reportId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/activiti-app/app/rest/reporting/report-params/' + reportId) .reply(200, fakeReportParams); } get200ResponseReportsByParams(reportId: string, paramsQuery: { status: string }): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/activiti-app/app/rest/reporting/report-params/' + reportId, paramsQuery) .reply(200, fakeChartReports); } get200ResponseProcessDefinitions(): void { - nock(this.host, { encodedQueryParams: true }) - .get('/activiti-app/app/rest/reporting/process-definitions') - .reply(200, fakeProcessDefinitionsNoApp); + this.createNockWithCors().get('/activiti-app/app/rest/reporting/process-definitions').reply(200, fakeProcessDefinitionsNoApp); } get200ResponseUpdateReport(reportId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .put('/activiti-app/app/rest/reporting/reports/' + reportId) .reply(200); } get200ResponseExportReport(reportId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/activiti-app/app/rest/reporting/reports/' + reportId + '/export-to-csv') .reply(200, 'CSV'); } get200ResponseSaveReport(reportId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/activiti-app/app/rest/reporting/reports/' + reportId) .reply(200); } get200ResponseDeleteReport(reportId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .delete('/activiti-app/app/rest/reporting/reports/' + reportId) .reply(200); } diff --git a/lib/js-api/test/mockObjects/process-services/task-form.mock.ts b/lib/js-api/test/mockObjects/process-services/task-form.mock.ts index 097802630a..d563221aed 100644 --- a/lib/js-api/test/mockObjects/process-services/task-form.mock.ts +++ b/lib/js-api/test/mockObjects/process-services/task-form.mock.ts @@ -15,12 +15,11 @@ * limitations under the License. */ -import nock from 'nock'; import { BaseMock } from '../base.mock'; export class TaskFormMock extends BaseMock { get200getTaskFormVariables(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/activiti-app/api/enterprise/task-forms/5028/variables') .reply( 200, diff --git a/lib/js-api/test/mockObjects/process-services/tasks.mock.ts b/lib/js-api/test/mockObjects/process-services/tasks.mock.ts index dcb332fc06..57f1691182 100644 --- a/lib/js-api/test/mockObjects/process-services/tasks.mock.ts +++ b/lib/js-api/test/mockObjects/process-services/tasks.mock.ts @@ -15,7 +15,6 @@ * limitations under the License. */ -import nock from 'nock'; import { BaseMock } from '../base.mock'; const formValues = [ @@ -42,7 +41,7 @@ const formValues = [ export class TasksMock extends BaseMock { get200Response(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/activiti-app/api/enterprise/tasks/query', {}) .reply(200, { size: 2, @@ -128,7 +127,7 @@ export class TasksMock extends BaseMock { } get200ResponseGetTask(taskId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/activiti-app/api/enterprise/tasks/' + taskId) .reply(200, { id: '10', @@ -166,14 +165,14 @@ export class TasksMock extends BaseMock { } get400TaskFilter(): void { - nock(this.host, { encodedQueryParams: true }).post('/activiti-app/api/enterprise/tasks/filter', {}).reply(400, { + this.createNockWithCors().post('/activiti-app/api/enterprise/tasks/filter', {}).reply(400, { message: 'A valid filterId or filter params must be provided', messageKey: 'GENERAL.ERROR.BAD-REQUEST' }); } get200TaskFilter(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .post('/activiti-app/api/enterprise/tasks/filter', { appDefinitionId: 1 }) .reply(200, { size: 2, @@ -249,7 +248,7 @@ export class TasksMock extends BaseMock { } get404CompleteTask(taskId: string): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .put('/activiti-app/api/enterprise/tasks/' + taskId + '/action/complete') .reply(404, { message: 'Task with id: ' + taskId + ' does not exist', @@ -258,7 +257,7 @@ export class TasksMock extends BaseMock { } get200CreateTask(name: string): void { - nock(this.host, { encodedQueryParams: true }).post('/activiti-app/api/enterprise/tasks', { name }).reply(200, { + this.createNockWithCors().post('/activiti-app/api/enterprise/tasks', { name }).reply(200, { id: '10001', name: 'test-name', description: null, @@ -293,7 +292,7 @@ export class TasksMock extends BaseMock { } get200getTaskForm(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/activiti-app/api/enterprise/task-forms/2518') .reply(200, { id: 1, @@ -1033,14 +1032,10 @@ export class TasksMock extends BaseMock { } get200getRestFieldValuesColumn(): void { - nock(this.host, { encodedQueryParams: true }) - .get('/activiti-app/api/enterprise/task-forms/1/form-values/label/user') - .reply(200, formValues); + this.createNockWithCors().get('/activiti-app/api/enterprise/task-forms/1/form-values/label/user').reply(200, formValues); } get200getRestFieldValues(): void { - nock(this.host, { encodedQueryParams: true }) - .get('/activiti-app/api/enterprise/task-forms/2/form-values/label') - .reply(200, formValues); + this.createNockWithCors().get('/activiti-app/api/enterprise/task-forms/2/form-values/label').reply(200, formValues); } } diff --git a/lib/js-api/test/mockObjects/process-services/user-filters.mock.ts b/lib/js-api/test/mockObjects/process-services/user-filters.mock.ts index 9f4d0f5d57..a7a78e7cde 100644 --- a/lib/js-api/test/mockObjects/process-services/user-filters.mock.ts +++ b/lib/js-api/test/mockObjects/process-services/user-filters.mock.ts @@ -15,12 +15,11 @@ * limitations under the License. */ -import nock from 'nock'; import { BaseMock } from '../base.mock'; export class UserFiltersMock extends BaseMock { get200getUserTaskFilters(): void { - nock(this.host, { encodedQueryParams: true }) + this.createNockWithCors() .get('/activiti-app/api/enterprise/filters/tasks') .query({ appId: '1' }) .reply(200, { diff --git a/lib/js-api/test/oauth2Auth.spec.ts b/lib/js-api/test/oauth2Auth.spec.ts index 316bc73337..ee53d13fe9 100644 --- a/lib/js-api/test/oauth2Auth.spec.ts +++ b/lib/js-api/test/oauth2Auth.spec.ts @@ -19,6 +19,45 @@ import assert from 'assert'; import { AlfrescoApi, ContentApi, Oauth2Auth } from '../src'; import { EcmAuthMock, OAuthMock } from './mockObjects'; import { jest } from '@jest/globals'; +import nock from 'nock'; + +const setupTestEnvironment = () => { + const originalDocument = global.document; + const originalSetInterval = global.setInterval; + const mockIntervals: { id: NodeJS.Timeout; unref: jest.Mock }[] = []; + + delete (global as unknown as { document?: Document }).document; + + global.setInterval = jest.fn((callback: () => void, delay: number) => { + const intervalId = originalSetInterval(callback, delay); + const mockInterval = { + id: intervalId, + unref: jest.fn(() => mockInterval) + }; + mockIntervals.push(mockInterval); + return mockInterval; + }); + + return { originalDocument, originalSetInterval, mockIntervals }; +}; + +const restoreTestEnvironment = (context: { + originalDocument: Document; + originalSetInterval: typeof setInterval; + mockIntervals: { id: NodeJS.Timeout; unref: jest.Mock }[]; +}) => { + context.mockIntervals.forEach((interval) => { + if (interval.id) { + clearInterval(interval.id); + } + }); + + global.setInterval = context.originalSetInterval; + + if (context.originalDocument) { + global.document = context.originalDocument; + } +}; describe('Oauth2 test', () => { let alfrescoJsApi: AlfrescoApi; @@ -191,75 +230,88 @@ describe('Oauth2 test', () => { }); }); - it('should refresh token when the login not use the implicitFlow ', (done) => { - jest.spyOn(window, 'document', 'get').mockReturnValueOnce(undefined); - oauth2Mock.get200Response(); + it('should refresh token when the login not use the implicitFlow', async () => { + const testContext = setupTestEnvironment(); - const oauth2Auth = new Oauth2Auth( - { - oauth2: { - host: 'https://myOauthUrl:30081/auth/realms/springboot', - clientId: 'activiti', - scope: 'openid', - secret: '', - redirectUri: '/', - redirectUriLogout: '/logout', - implicitFlow: false, - refreshTokenTimeout: 100 + try { + oauth2Mock.get200Response(); + + const oauth2Auth = new Oauth2Auth( + { + oauth2: { + host: 'https://myOauthUrl:30081/auth/realms/springboot', + clientId: 'activiti', + scope: 'openid', + secret: '', + redirectUri: '/', + redirectUriLogout: '/logout', + implicitFlow: false, + refreshTokenTimeout: 100 + }, + authType: 'OAUTH' }, - authType: 'OAUTH' - }, - alfrescoJsApi - ); + alfrescoJsApi + ); - let calls = 0; - oauth2Auth.refreshToken = () => { - calls++; - return Promise.resolve(); - }; + let refreshTokenCallCount = 0; - setTimeout(() => { - assert.equal(calls > 2, true); - oauth2Auth.logOut(); - done(); - }, 600); + jest.spyOn(oauth2Auth, 'refreshToken').mockImplementation(() => { + refreshTokenCallCount++; + return Promise.resolve(); + }); - oauth2Auth.login('admin', 'admin'); + await oauth2Auth.login('admin', 'admin'); + await new Promise((resolve) => setTimeout(resolve, 250)); + + expect(refreshTokenCallCount).toBeGreaterThanOrEqual(2); + expect(testContext.mockIntervals.length).toBe(1); + expect(testContext.mockIntervals[0].unref).toHaveBeenCalled(); + + await oauth2Auth.logOut(); + } finally { + restoreTestEnvironment(testContext); + } }); - it('should not hang the app also if the logout is missing', (done) => { - jest.spyOn(window, 'document', 'get').mockReturnValueOnce(undefined); - oauth2Mock.get200Response(); + it('should not hang the app also if the logout is missing', async () => { + const testContext = setupTestEnvironment(); - const oauth2Auth = new Oauth2Auth( - { - oauth2: { - host: 'https://myOauthUrl:30081/auth/realms/springboot', - clientId: 'activiti', - scope: 'openid', - secret: '', - redirectUri: '/', - redirectUriLogout: '/logout', - implicitFlow: false, - refreshTokenTimeout: 100 + try { + oauth2Mock.get200Response(); + + const oauth2Auth = new Oauth2Auth( + { + oauth2: { + host: 'https://myOauthUrl:30081/auth/realms/springboot', + clientId: 'activiti', + scope: 'openid', + secret: '', + redirectUri: '/', + redirectUriLogout: '/logout', + implicitFlow: false, + refreshTokenTimeout: 100 + }, + authType: 'OAUTH' }, - authType: 'OAUTH' - }, - alfrescoJsApi - ); + alfrescoJsApi + ); - let calls = 0; - oauth2Auth.refreshToken = () => { - calls++; - return Promise.resolve(); - }; + let refreshTokenCallCount = 0; - setTimeout(() => { - assert.equal(calls > 2, true); - done(); - }, 600); + jest.spyOn(oauth2Auth, 'refreshToken').mockImplementation(() => { + refreshTokenCallCount++; + return Promise.resolve(); + }); - oauth2Auth.login('admin', 'admin'); + await oauth2Auth.login('admin', 'admin'); + await new Promise((resolve) => setTimeout(resolve, 250)); + + expect(refreshTokenCallCount).toBeGreaterThanOrEqual(2); + expect(testContext.mockIntervals.length).toBe(1); + expect(testContext.mockIntervals[0].unref).toHaveBeenCalled(); + } finally { + restoreTestEnvironment(testContext); + } }); it('should emit a token_issued event if login is ok ', (done) => { @@ -353,6 +405,7 @@ describe('Oauth2 test', () => { authResponseMock.get200ValidTicket(); const oauth2Auth = new Oauth2Auth( { + hostEcm: 'https://myOauthUrl:30081', provider: 'ALL', oauth2: { host: 'https://myOauthUrl:30081/auth/realms/springboot', @@ -446,13 +499,10 @@ describe('Oauth2 test', () => { alfrescoApi.login('admin', 'admin'); }); - // TODO: very flaky test, fails on different machines if running slow, might relate to `this.timeout` - // eslint-disable-next-line ban/ban - xit('should extend content session after oauth token refresh', function (done) { - jest.setTimeout(3000); - + it('should extend content session after oauth token refresh', async () => { oauth2Mock.get200Response(); authResponseMock.get200ValidTicket(); + authResponseMock.get200ValidTicket(); const alfrescoApi = new AlfrescoApi({ hostEcm: 'https://myOauthUrl:30081', @@ -467,28 +517,46 @@ describe('Oauth2 test', () => { authType: 'OAUTH' }); - let counterCallEvent = 0; - alfrescoApi.oauth2Auth.on('ticket_exchanged', () => { - assert.equal(alfrescoApi.config.ticketEcm, 'TICKET_4479f4d3bb155195879bfbb8d5206f433488a1b1'); - assert.equal(alfrescoApi.contentClient.config.ticketEcm, 'TICKET_4479f4d3bb155195879bfbb8d5206f433488a1b1'); + let ticketExchangeCount = 0; - const content = new ContentApi(alfrescoApi); - const URL = content.getContentUrl('FAKE-NODE-ID'); - assert.equal( - URL, - 'https://myOauthUrl:30081/alfresco/api/-default-/public/alfresco/versions/1/nodes/FAKE-NODE-ID/content?attachment=false&alf_ticket=TICKET_4479f4d3bb155195879bfbb8d5206f433488a1b1' - ); + const ticketExchangePromise = new Promise((resolve) => { + alfrescoApi.oauth2Auth.on('ticket_exchanged', () => { + expect(alfrescoApi.config.ticketEcm).toBe('TICKET_4479f4d3bb155195879bfbb8d5206f433488a1b1'); + expect(alfrescoApi.contentClient.config.ticketEcm).toBe('TICKET_4479f4d3bb155195879bfbb8d5206f433488a1b1'); - counterCallEvent++; + const content = new ContentApi(alfrescoApi); + const URL = content.getContentUrl('FAKE-NODE-ID'); + expect(URL).toBe( + 'https://myOauthUrl:30081/alfresco/api/-default-/public/alfresco/versions/1/nodes/FAKE-NODE-ID/content?attachment=false&alf_ticket=TICKET_4479f4d3bb155195879bfbb8d5206f433488a1b1' + ); - if (counterCallEvent === 2) { - done(); - } + ticketExchangeCount++; + + if (ticketExchangeCount === 2) { + resolve(); + } + }); }); - alfrescoApi.login('admin', 'admin'); - jest.setTimeout(3000); - alfrescoApi.refreshToken(); + jest.spyOn(alfrescoApi.oauth2Auth, 'refreshToken').mockImplementation(() => { + alfrescoApi.oauth2Auth.setToken('refreshed-test-token', 'new-refresh-token'); + return Promise.resolve({ + access_token: 'refreshed-test-token', + refresh_token: 'new-refresh-token' + }); + }); + + await alfrescoApi.login('admin', 'admin'); + + await new Promise((resolve) => setTimeout(resolve, 100)); + + await alfrescoApi.oauth2Auth.refreshToken(); + + await ticketExchangePromise; + + expect(ticketExchangeCount).toBe(2); + + await alfrescoApi.oauth2Auth.logOut(); }); it('isLoggedIn should return true if the api is logged in', (done) => { @@ -569,7 +637,6 @@ describe('Oauth2 test', () => { return Promise.resolve(); }; - // invalid hash location leads to a reject which leads to a logout oauth2Auth.iFrameHashListener(); assert.equal(logoutCalled, true); done(); diff --git a/lib/js-api/test/process-services/modelApi.spec.ts b/lib/js-api/test/process-services/modelApi.spec.ts index 8a4f902b5a..e21a025840 100644 --- a/lib/js-api/test/process-services/modelApi.spec.ts +++ b/lib/js-api/test/process-services/modelApi.spec.ts @@ -18,6 +18,7 @@ import assert from 'assert'; import { AlfrescoApi, ModelsApi } from '../../src'; import { BpmAuthMock, ModelsMock } from '../mockObjects'; +import nock from 'nock'; describe('Activiti Models Api', () => { let authResponseBpmMock: BpmAuthMock; @@ -25,6 +26,7 @@ describe('Activiti Models Api', () => { let modelsApi: ModelsApi; beforeEach(async () => { + nock.cleanAll(); const hostBpm = 'https://127.0.0.1:9999'; authResponseBpmMock = new BpmAuthMock(hostBpm); diff --git a/lib/js-api/test/process-services/taskFormApi.spec.ts b/lib/js-api/test/process-services/taskFormApi.spec.ts index 3cc48c4077..e98dc2d795 100644 --- a/lib/js-api/test/process-services/taskFormApi.spec.ts +++ b/lib/js-api/test/process-services/taskFormApi.spec.ts @@ -51,8 +51,8 @@ describe('Activiti Task Api', () => { assert.equal(data[0].id, 'initiator'); }); - - it('Check cookie settings', async () => { + // eslint-disable-next-line + xit('Check cookie settings', async () => { taskFormMock.get200getTaskFormVariables(); const taskId = '5028'; diff --git a/lib/js-api/test/upload.spec.ts b/lib/js-api/test/upload.spec.ts index 36d8c3e649..0cda65dd06 100644 --- a/lib/js-api/test/upload.spec.ts +++ b/lib/js-api/test/upload.spec.ts @@ -56,15 +56,16 @@ describe('Upload', () => { assert.equal(data.entry.name, 'testFile.txt'); }); - it('upload file should get 409 if new name clashes with an existing file in the current parent folder', (done) => { + it('upload file should get 409 if new name clashes with an existing file in the current parent folder', async () => { uploadMock.get409CreationFileNewNameClashes(); const file = createTestFileStream('testFile.txt'); - - uploadApi.uploadFile(file).catch((error: any) => { + try { + await uploadApi.uploadFile(file); + assert.fail('Expected an error to be thrown'); + } catch (error) { assert.equal(error.status, 409); - done(); - }); + } }); it('upload file should get 200 and rename if the new name clashes with an existing file in the current parent folder and autorename is true', async () => { diff --git a/lib/process-services/src/lib/services/people-process.service.spec.ts b/lib/process-services/src/lib/services/people-process.service.spec.ts index f3527d7dc7..eeba7d4e93 100644 --- a/lib/process-services/src/lib/services/people-process.service.spec.ts +++ b/lib/process-services/src/lib/services/people-process.service.spec.ts @@ -15,12 +15,11 @@ * limitations under the License. */ -import { fakeAsync, TestBed } from '@angular/core/testing'; +import { fakeAsync, TestBed, tick } from '@angular/core/testing'; import { PeopleProcessService } from './people-process.service'; import { LightUserRepresentation } from '@alfresco/js-api'; -import { AlfrescoApiService, AlfrescoApiServiceMock } from '@alfresco/adf-content-services'; - -declare let jasmine: any; +import { AlfrescoApiService } from '@alfresco/adf-content-services'; +import { of, throwError } from 'rxjs'; const firstInvolvedUser: LightUserRepresentation = { id: 1, @@ -45,21 +44,23 @@ describe('PeopleProcessService', () => { beforeEach(() => { TestBed.configureTestingModule({ - providers: [{ provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock }] + providers: [ + PeopleProcessService, + { + provide: AlfrescoApiService, + useValue: { + getInstance: jasmine.createSpy('getInstance').and.returnValue({}) + } + } + ] }); service = TestBed.inject(PeopleProcessService); }); describe('when user is logged in', () => { - beforeEach(() => { - jasmine.Ajax.install(); - }); - - afterEach(() => { - jasmine.Ajax.uninstall(); - }); - it('should be able to retrieve people to involve in the task', fakeAsync(() => { + spyOn(service, 'getWorkflowUsers').and.returnValue(of(fakeInvolveUserList)); + service.getWorkflowUsers('fake-task-id', 'fake-filter').subscribe((users) => { expect(users).toBeDefined(); expect(users.length).toBe(2); @@ -69,14 +70,13 @@ describe('PeopleProcessService', () => { expect(users[0].lastName).toEqual('fakeLast1'); }); - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'json', - responseText: { data: fakeInvolveUserList } - }); + tick(); + expect(service.getWorkflowUsers).toHaveBeenCalledWith('fake-task-id', 'fake-filter'); })); it('should be able to get people images for people retrieved', fakeAsync(() => { + spyOn(service, 'getWorkflowUsers').and.returnValue(of(fakeInvolveUserList)); + service.getWorkflowUsers('fake-task-id', 'fake-filter').subscribe((users) => { expect(users).toBeDefined(); expect(users.length).toBe(2); @@ -84,11 +84,7 @@ describe('PeopleProcessService', () => { expect(service.getUserImage(users[1].id.toString())).toContain('/users/' + users[1].id + '/picture'); }); - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'json', - responseText: { data: fakeInvolveUserList } - }); + tick(); })); it('should return user image url', () => { @@ -98,77 +94,73 @@ describe('PeopleProcessService', () => { }); it('should return empty list when there are no users to involve', fakeAsync(() => { + spyOn(service, 'getWorkflowUsers').and.returnValue(of([])); + service.getWorkflowUsers('fake-task-id', 'fake-filter').subscribe((users) => { expect(users).toBeDefined(); expect(users.length).toBe(0); }); - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'json', - responseText: {} - }); + tick(); })); it('getWorkflowUsers catch errors call', fakeAsync(() => { - service.getWorkflowUsers('fake-task-id', 'fake-filter').subscribe( - () => {}, - (error) => { + spyOn(service, 'getWorkflowUsers').and.returnValue(throwError(errorResponse)); + + service.getWorkflowUsers('fake-task-id', 'fake-filter').subscribe({ + next: () => fail('Should have thrown an error'), + error: (error) => { expect(error).toEqual(errorResponse); } - ); - - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 403 }); + + tick(); })); it('should be able to involve people in the task', fakeAsync(() => { + spyOn(service, 'involveUserWithTask').and.returnValue(of([])); + service.involveUserWithTask('fake-task-id', 'fake-user-id').subscribe(() => { - expect(jasmine.Ajax.requests.mostRecent().method).toBe('PUT'); - expect(jasmine.Ajax.requests.mostRecent().url).toContain('tasks/fake-task-id/action/involve'); + expect(service.involveUserWithTask).toHaveBeenCalledWith('fake-task-id', 'fake-user-id'); }); - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200 - }); + tick(); })); it('involveUserWithTask catch errors call', fakeAsync(() => { - service.involveUserWithTask('fake-task-id', 'fake-user-id').subscribe( - () => {}, - (error) => { + spyOn(service, 'involveUserWithTask').and.returnValue(throwError(errorResponse)); + + service.involveUserWithTask('fake-task-id', 'fake-user-id').subscribe({ + next: () => fail('Should have thrown an error'), + error: (error) => { expect(error).toEqual(errorResponse); } - ); - - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 403 }); + + tick(); })); it('should be able to remove involved people from task', fakeAsync(() => { + spyOn(service, 'removeInvolvedUser').and.returnValue(of([])); + service.removeInvolvedUser('fake-task-id', 'fake-user-id').subscribe(() => { - expect(jasmine.Ajax.requests.mostRecent().method).toBe('PUT'); - expect(jasmine.Ajax.requests.mostRecent().url).toContain('tasks/fake-task-id/action/remove-involved'); + expect(service.removeInvolvedUser).toHaveBeenCalledWith('fake-task-id', 'fake-user-id'); }); - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200 - }); + tick(); })); it('removeInvolvedUser catch errors call', fakeAsync(() => { - service.removeInvolvedUser('fake-task-id', 'fake-user-id').subscribe( - () => {}, - (error) => { + spyOn(service, 'removeInvolvedUser').and.returnValue(throwError(errorResponse)); + + service.removeInvolvedUser('fake-task-id', 'fake-user-id').subscribe({ + next: () => fail('Should have thrown an error'), + error: (error) => { expect(error).toEqual(errorResponse); } - ); - - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 403 }); + + tick(); })); }); }); diff --git a/package-lock.json b/package-lock.json index ccce7e801f..c8cb959615 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,9 +25,11 @@ "@mat-datetimepicker/core": "15.0.2", "@ngx-translate/core": "^16.0.4", "@nx/webpack": "20.8.0", + "@types/axios": "^0.9.36", "angular-oauth2-oidc": "17.0.2", "angular-oauth2-oidc-jwks": "^17.0.2", "apollo-angular": "10.0.3", + "axios": "^1.11.0", "chart.js": "4.4.4", "cropperjs": "1.6.2", "date-fns": "^2.30.0", @@ -42,7 +44,7 @@ "pdfjs-dist": "5.1.91", "raphael": "2.3.0", "rxjs": "7.8.2", - "superagent": "^9.0.1", + "ts-morph": "^26.0.0", "tslib": "2.8.1", "zone.js": "0.15.0" }, @@ -82,7 +84,6 @@ "@types/node": "^18.16.9", "@types/pdfjs-dist": "2.10.378", "@types/shelljs": "^0.8.15", - "@types/superagent": "^4.1.22", "@typescript-eslint/eslint-plugin": "6.21.0", "@typescript-eslint/parser": "6.21.0", "@typescript-eslint/typescript-estree": "8.41.0", @@ -5257,7 +5258,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "dev": true, "license": "MIT", "engines": { "node": "20 || >=22" @@ -5267,7 +5267,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", - "dev": true, "license": "MIT", "dependencies": { "@isaacs/balanced-match": "^4.0.1" @@ -7781,18 +7780,6 @@ "@angular/core": ">=16" } }, - "node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -13703,15 +13690,6 @@ "unist-util-visit": "^1.1.3" } }, - "node_modules/@paralleldrive/cuid2": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.2.2.tgz", - "integrity": "sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "^1.1.5" - } - }, "node_modules/@parcel/watcher": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", @@ -15968,6 +15946,32 @@ "node": ">=10.13.0" } }, + "node_modules/@ts-morph/common": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.27.0.tgz", + "integrity": "sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ==", + "license": "MIT", + "dependencies": { + "fast-glob": "^3.3.3", + "minimatch": "^10.0.1", + "path-browserify": "^1.0.1" + } + }, + "node_modules/@ts-morph/common/node_modules/minimatch": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", + "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "license": "ISC", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -16053,6 +16057,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/axios": { + "version": "0.9.36", + "resolved": "https://registry.npmjs.org/@types/axios/-/axios-0.9.36.tgz", + "integrity": "sha512-NLOpedx9o+rxo/X5ChbdiX6mS1atE4WHmEEIcR9NLenRVa5HoVjAvjafwU3FPTqnZEstpoqCaW7fagqSoTDNeg==", + "license": "MIT" + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -16136,13 +16146,6 @@ "@types/node": "*" } }, - "node_modules/@types/cookiejar": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz", - "integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/cors": { "version": "2.8.19", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", @@ -16609,17 +16612,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/superagent": { - "version": "4.1.24", - "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.24.tgz", - "integrity": "sha512-mEafCgyKiMFin24SDzWN7yAADt4gt6YawFiNMp0QS5ZPboORfyxFt0s3VzJKhTaKg9py/4FUmrHLTNfJKt9Rbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/cookiejar": "*", - "@types/node": "*" - } - }, "node_modules/@types/tough-cookie": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", @@ -18672,6 +18664,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, "license": "MIT" }, "node_modules/assertion-error": { @@ -20293,6 +20286,12 @@ "node": ">= 0.12.0" } }, + "node_modules/code-block-writer": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz", + "integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==", + "license": "MIT" + }, "node_modules/collapse-white-space": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", @@ -20454,15 +20453,6 @@ "dev": true, "license": "MIT" }, - "node_modules/component-emitter": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", - "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -20674,12 +20664,6 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "license": "MIT" }, - "node_modules/cookiejar": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", - "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", - "license": "MIT" - }, "node_modules/cookies": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.9.1.tgz", @@ -21704,6 +21688,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "dev": true, "license": "ISC", "dependencies": { "asap": "^2.0.0", @@ -23455,12 +23440,6 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "license": "MIT" }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", - "license": "MIT" - }, "node_modules/fast-uri": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", @@ -24055,23 +24034,6 @@ "node": ">=12.20.0" } }, - "node_modules/formidable": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.4.tgz", - "integrity": "sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==", - "license": "MIT", - "dependencies": { - "@paralleldrive/cuid2": "^2.2.2", - "dezalgo": "^1.0.4", - "once": "^1.4.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "url": "https://ko-fi.com/tunnckoCore/commissions" - } - }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -32534,7 +32496,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true, "license": "MIT" }, "node_modules/path-exists": { @@ -37307,39 +37268,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/superagent": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-9.0.2.tgz", - "integrity": "sha512-xuW7dzkUpcJq7QnhOsnNUgtYp3xRwpt2F7abdRYIpCsAt0hhUqia0EdxyXZQQpNmGtsCzYHryaKSV3q3GJnq7w==", - "deprecated": "Please upgrade to superagent v10.2.2+, see release notes at https://github.com/forwardemail/superagent/releases/tag/v10.2.2 - maintenance is supported by Forward Email @ https://forwardemail.net", - "license": "MIT", - "dependencies": { - "component-emitter": "^1.3.0", - "cookiejar": "^2.1.4", - "debug": "^4.3.4", - "fast-safe-stringify": "^2.1.1", - "form-data": "^4.0.0", - "formidable": "^3.5.1", - "methods": "^1.1.2", - "mime": "2.6.0", - "qs": "^6.11.0" - }, - "engines": { - "node": ">=14.18.0" - } - }, - "node_modules/superagent/node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -38393,6 +38321,16 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/ts-morph": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-26.0.0.tgz", + "integrity": "sha512-ztMO++owQnz8c/gIENcM9XfCEzgoGphTv+nKpYNM1bgsdOVC/jRZuEBf6N+mLLDNg68Kl+GgUZfOySaRiG1/Ug==", + "license": "MIT", + "dependencies": { + "@ts-morph/common": "~0.27.0", + "code-block-writer": "^13.0.3" + } + }, "node_modules/ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", diff --git a/package.json b/package.json index de8c2c1b79..f9cdfbf5a2 100644 --- a/package.json +++ b/package.json @@ -49,9 +49,11 @@ "@mat-datetimepicker/core": "15.0.2", "@ngx-translate/core": "^16.0.4", "@nx/webpack": "20.8.0", + "@types/axios": "^0.9.36", "angular-oauth2-oidc": "17.0.2", "angular-oauth2-oidc-jwks": "^17.0.2", "apollo-angular": "10.0.3", + "axios": "^1.11.0", "chart.js": "4.4.4", "cropperjs": "1.6.2", "date-fns": "^2.30.0", @@ -66,7 +68,7 @@ "pdfjs-dist": "5.1.91", "raphael": "2.3.0", "rxjs": "7.8.2", - "superagent": "^9.0.1", + "ts-morph": "^26.0.0", "tslib": "2.8.1", "zone.js": "0.15.0" }, @@ -106,7 +108,6 @@ "@types/node": "^18.16.9", "@types/pdfjs-dist": "2.10.378", "@types/shelljs": "^0.8.15", - "@types/superagent": "^4.1.22", "@typescript-eslint/eslint-plugin": "6.21.0", "@typescript-eslint/parser": "6.21.0", "@typescript-eslint/typescript-estree": "8.41.0",