Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 33 additions & 35 deletions src/communication/http/httpClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,10 @@ export abstract class HttpClient {
queryParams?: Record<string, unknown>,
retryConfig?: IAxiosRetryConfig,
auth?: AxiosBasicCredentials,
headers?: unknown
headers?: Record<string, unknown>
): Promise<T> {
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<T>(url, reqConfig);
return res.data;
} catch (err) {
Expand All @@ -73,13 +70,10 @@ export abstract class HttpClient {
queryParams?: Record<string, unknown>,
retryConfig?: IAxiosRetryConfig,
auth?: AxiosBasicCredentials,
headers?: unknown
headers?: Record<string, unknown>
): Promise<T> {
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<T>(url, body, reqConfig);
return res.data;
} catch (err) {
Expand All @@ -94,13 +88,10 @@ export abstract class HttpClient {
queryParams?: Record<string, unknown>,
retryConfig?: IAxiosRetryConfig,
auth?: AxiosBasicCredentials,
headers?: unknown
headers?: Record<string, unknown>
): Promise<T> {
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<T>(url, body, reqConfig);
return res.data;
} catch (err) {
Expand All @@ -114,13 +105,10 @@ export abstract class HttpClient {
queryParams?: Record<string, unknown>,
retryConfig?: IAxiosRetryConfig,
auth?: AxiosBasicCredentials,
headers?: unknown
headers?: Record<string, unknown>
): Promise<T> {
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<T>(url, reqConfig);
return res.data;
} catch (err) {
Expand All @@ -134,13 +122,10 @@ export abstract class HttpClient {
queryParams?: Record<string, unknown>,
retryConfig?: IAxiosRetryConfig,
auth?: AxiosBasicCredentials,
headers?: unknown
headers?: Record<string, unknown>
): Promise<T> {
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<T>(url, reqConfig);
return res.data;
} catch (err) {
Expand All @@ -154,13 +139,10 @@ export abstract class HttpClient {
queryParams?: Record<string, unknown>,
retryConfig?: IAxiosRetryConfig,
auth?: AxiosBasicCredentials,
headers?: unknown
headers?: Record<string, unknown>
): Promise<T> {
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<T>(url, reqConfig);
return res.data;
} catch (err) {
Expand All @@ -175,13 +157,10 @@ export abstract class HttpClient {
queryParams?: Record<string, unknown>,
retryConfig?: IAxiosRetryConfig,
auth?: AxiosBasicCredentials,
headers?: unknown
headers?: Record<string, unknown>
): Promise<T> {
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<T>(url, body, reqConfig);
return res.data;
} catch (err) {
Expand All @@ -190,6 +169,25 @@ export abstract class HttpClient {
}
}

protected getRequestConfig(
retryConfig: IAxiosRetryConfig | undefined,
queryParams: Record<string, unknown> | undefined,
auth: AxiosBasicCredentials | undefined,
headers: Record<string, unknown> | undefined
): AxiosRequestConfig {
const reqConfig = retryConfig ? { ...this.axiosOptions, 'axios-retry': retryConfig } : this.axiosOptions;
if (queryParams !== undefined) {
reqConfig.params = reqConfig.params !== undefined ? { ...(reqConfig.params as Record<string, unknown>), ...queryParams } : queryParams;
}
if (auth !== undefined) {
reqConfig.auth = auth;
}
if (headers !== undefined) {
reqConfig.headers = reqConfig.headers !== undefined ? { ...(reqConfig.headers as Record<string, unknown>), ...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) {
Expand Down
89 changes: 88 additions & 1 deletion tests/unit/communication/http/httpClient.spec.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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';
Expand Down Expand Up @@ -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', () => {
Expand Down