diff --git a/src/communication/http/httpClient.ts b/src/communication/http/httpClient.ts index 0538018..d3f4e90 100644 --- a/src/communication/http/httpClient.ts +++ b/src/communication/http/httpClient.ts @@ -52,13 +52,10 @@ export abstract class HttpClient { queryParams?: Record, retryConfig?: IAxiosRetryConfig, auth?: AxiosBasicCredentials, - headers?: unknown + headers?: Record ): Promise { try { - const reqConfig = retryConfig ? { ...this.axiosOptions, 'axios-retry': retryConfig } : { ...this.axiosOptions }; - reqConfig.params = queryParams; - reqConfig.auth = auth; - reqConfig.headers = headers; + const reqConfig = this.getRequestConfig(retryConfig, queryParams, auth, headers); const res = await this.axiosClient.get(url, reqConfig); return res.data; } catch (err) { @@ -73,13 +70,10 @@ export abstract class HttpClient { queryParams?: Record, retryConfig?: IAxiosRetryConfig, auth?: AxiosBasicCredentials, - headers?: unknown + headers?: Record ): Promise { try { - const reqConfig = retryConfig ? { ...this.axiosOptions, 'axios-retry': retryConfig } : this.axiosOptions; - reqConfig.params = queryParams; - reqConfig.auth = auth; - reqConfig.headers = headers; + const reqConfig = this.getRequestConfig(retryConfig, queryParams, auth, headers); const res = await this.axiosClient.post(url, body, reqConfig); return res.data; } catch (err) { @@ -94,13 +88,10 @@ export abstract class HttpClient { queryParams?: Record, retryConfig?: IAxiosRetryConfig, auth?: AxiosBasicCredentials, - headers?: unknown + headers?: Record ): Promise { try { - const reqConfig = retryConfig ? { ...this.axiosOptions, 'axios-retry': retryConfig } : this.axiosOptions; - reqConfig.params = queryParams; - reqConfig.auth = auth; - reqConfig.headers = headers; + const reqConfig = this.getRequestConfig(retryConfig, queryParams, auth, headers); const res = await this.axiosClient.put(url, body, reqConfig); return res.data; } catch (err) { @@ -114,13 +105,10 @@ export abstract class HttpClient { queryParams?: Record, retryConfig?: IAxiosRetryConfig, auth?: AxiosBasicCredentials, - headers?: unknown + headers?: Record ): Promise { try { - const reqConfig = retryConfig ? { ...this.axiosOptions, 'axios-retry': retryConfig } : this.axiosOptions; - reqConfig.params = queryParams; - reqConfig.auth = auth; - reqConfig.headers = headers; + const reqConfig = this.getRequestConfig(retryConfig, queryParams, auth, headers); const res = await this.axiosClient.delete(url, reqConfig); return res.data; } catch (err) { @@ -134,13 +122,10 @@ export abstract class HttpClient { queryParams?: Record, retryConfig?: IAxiosRetryConfig, auth?: AxiosBasicCredentials, - headers?: unknown + headers?: Record ): Promise { try { - const reqConfig = retryConfig ? { ...this.axiosOptions, 'axios-retry': retryConfig } : this.axiosOptions; - reqConfig.params = queryParams; - reqConfig.auth = auth; - reqConfig.headers = headers; + const reqConfig = this.getRequestConfig(retryConfig, queryParams, auth, headers); const res = await this.axiosClient.head(url, reqConfig); return res.data; } catch (err) { @@ -154,13 +139,10 @@ export abstract class HttpClient { queryParams?: Record, retryConfig?: IAxiosRetryConfig, auth?: AxiosBasicCredentials, - headers?: unknown + headers?: Record ): Promise { try { - const reqConfig = retryConfig ? { ...this.axiosOptions, 'axios-retry': retryConfig } : this.axiosOptions; - reqConfig.params = queryParams; - reqConfig.auth = auth; - reqConfig.headers = headers; + const reqConfig = this.getRequestConfig(retryConfig, queryParams, auth, headers); const res = await this.axiosClient.options(url, reqConfig); return res.data; } catch (err) { @@ -175,13 +157,10 @@ export abstract class HttpClient { queryParams?: Record, retryConfig?: IAxiosRetryConfig, auth?: AxiosBasicCredentials, - headers?: unknown + headers?: Record ): Promise { try { - const reqConfig = retryConfig ? { ...this.axiosOptions, 'axios-retry': retryConfig } : this.axiosOptions; - reqConfig.params = queryParams; - reqConfig.auth = auth; - reqConfig.headers = headers; + const reqConfig = this.getRequestConfig(retryConfig, queryParams, auth, headers); const res = await this.axiosClient.patch(url, body, reqConfig); return res.data; } catch (err) { @@ -190,6 +169,25 @@ export abstract class HttpClient { } } + protected getRequestConfig( + retryConfig: IAxiosRetryConfig | undefined, + queryParams: Record | undefined, + auth: AxiosBasicCredentials | undefined, + headers: Record | undefined + ): AxiosRequestConfig { + const reqConfig = retryConfig ? { ...this.axiosOptions, 'axios-retry': retryConfig } : this.axiosOptions; + if (queryParams !== undefined) { + reqConfig.params = reqConfig.params !== undefined ? { ...(reqConfig.params as Record), ...queryParams } : queryParams; + } + if (auth !== undefined) { + reqConfig.auth = auth; + } + if (headers !== undefined) { + reqConfig.headers = reqConfig.headers !== undefined ? { ...(reqConfig.headers as Record), ...headers } : headers; + } + return reqConfig; + } + private wrapError(url: string, err: AxiosError, body?: unknown): HttpError { const message = readProperty(err, 'response.data.message', undefined) as string | undefined; switch (err.response?.status) { diff --git a/tests/unit/communication/http/httpClient.spec.ts b/tests/unit/communication/http/httpClient.spec.ts index cdb1889..0d5df17 100644 --- a/tests/unit/communication/http/httpClient.spec.ts +++ b/tests/unit/communication/http/httpClient.spec.ts @@ -1,5 +1,5 @@ import { BadRequestError } from '@map-colonies/error-types'; -import { AxiosError } from 'axios'; +import { AxiosError, AxiosRequestConfig } from 'axios'; import { exponentialDelay, IAxiosRetryConfig } from 'axios-retry'; import { HttpClient } from '../../../../src'; import { axiosMocks, initAxiosMock } from '../../../mocks/externalDeps/axios'; @@ -13,6 +13,10 @@ class TestClient extends HttpClient { public callDelete = this.delete.bind(this); public callHead = this.head.bind(this); public callOptions = this.options.bind(this); + public callGetRequestConfig = this.getRequestConfig.bind(this); + public setGlobalConfig(config: AxiosRequestConfig): void { + this.axiosOptions = config; + } } const testUrl = 'http://test/test'; @@ -90,6 +94,89 @@ describe('HttpClient', function () { }; expect(action).toThrow(); }); + + it('global configurations are used when not overridden', () => { + const globalConfig: AxiosRequestConfig = { + 'axios-retry': { + retries: 1, + }, + auth: { + username: 'a', + password: 'b', + }, + params: { + test1: 1, + test2: 2, + }, + headers: { + test3: 3, + test4: 4, + }, + }; + client.setGlobalConfig(globalConfig); + const reqConf = client.callGetRequestConfig(undefined, undefined, undefined, undefined); + expect(reqConf).toEqual(globalConfig); + }); + + it('request configs are added to global configurations', () => { + const globalConfig: AxiosRequestConfig = { + 'axios-retry': { + retries: 1, + }, + auth: { + username: 'a', + password: 'b', + }, + params: { + test1: 1, + test2: 2, + }, + headers: { + test3: 3, + test4: 4, + }, + }; + const retryOverride = { + retries: 3, + }; + const queryOverride = { + test1: 4, + test3: 3, + }; + const authOverride = { + username: 't', + password: 't', + }; + const headerOverride = { + test3: 6, + test5: 5, + }; + + client.setGlobalConfig(globalConfig); + const reqConf = client.callGetRequestConfig(retryOverride, queryOverride, authOverride, headerOverride); + + const expectedConfig = { + 'axios-retry': { + retries: 3, + }, + auth: { + username: 't', + password: 't', + }, + params: { + test1: 4, + test2: 2, + test3: 3, + }, + headers: { + test3: 6, + test4: 4, + test5: 5, + }, + }; + + expect(reqConf).toEqual(expectedConfig); + }); }); describe('GET', () => {