Skip to content
Closed
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
2 changes: 1 addition & 1 deletion .github/workflows/sonar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ jobs:
-Dsonar.projectKey=${{ secrets.SONAR_PROJECT }}
-Dsonar.sonar.sourceEncoding=UTF-8
-Dsonar.javascript.lcov.reportPaths=coverage/lcov.info
-Dsonar.coverage.exclusions=**/storage/**,**/**.config.js,**/*.test.tsx,**/icons/**,**/docs/**,**/cli/**,**/__mocks__/**,**/android/**,**/ios/**,env.js
-Dsonar.coverage.exclusions=**/storage/**,**/**.config.js,**/*.test.ts,**/*.test.tsx,**/*.spec.ts,**/*.spec.tsx,**/icons/**,**/docs/**,**/cli/**,**/__mocks__/**,**/android/**,**/ios/**,env.js
14 changes: 14 additions & 0 deletions src/api/common/axios.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { InternalAxiosRequestConfig } from 'axios';

declare module 'axios' {
// TODO: remove this when axios typings are updated
// PR: https://github.com/axios/axios/pull/6138
interface AxiosInterceptorManager<V> {
handlers: Array<{
fulfilled: ((value: V) => V | Promise<V>) | null;
rejected: ((error: any) => any) | null;
synchronous: boolean;
runWhen: (config: InternalAxiosRequestConfig) => boolean | null;
}>;
}
}
138 changes: 138 additions & 0 deletions src/api/common/interceptors.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import type { AxiosResponse, InternalAxiosRequestConfig } from 'axios';
import { AxiosError, AxiosHeaders } from 'axios';

import interceptors from '@/api/common/interceptors';

import { client } from './client';

const testRequestInterceptors = () => {
describe('request interceptors', () => {
describe('when the request has data', () => {
const restConfig = {
baseURL: 'http://localhost:3000',
url: '/test',
headers: new AxiosHeaders({
'Content-Type': 'application/json',
}),
};

const config: InternalAxiosRequestConfig = {
data: {
fooBar: 'foo',
barBaz: 'bar',
},
...restConfig,
};

let interceptedConfig: InternalAxiosRequestConfig;

beforeEach(async () => {
const { fulfilled } = client.interceptors.request.handlers[0];

if (!fulfilled) {
return;
}

interceptedConfig = await fulfilled(config);
});

it('should convert the data to snake_case', () => {
expect(interceptedConfig.data).toEqual({
foo_bar: 'foo',
bar_baz: 'bar',
});
});

it('should not modify the rest of the config', () => {
expect(interceptedConfig).toMatchObject(config);
});
});

describe('when the request has no data', () => {
const config: InternalAxiosRequestConfig = {
baseURL: 'http://localhost:3000',
url: '/test',
headers: new AxiosHeaders({
'Content-Type': 'application/json',
}),
};

let interceptedConfig: InternalAxiosRequestConfig;

beforeEach(async () => {
const { fulfilled } = client.interceptors.request.handlers[0];

if (!fulfilled) {
return;
}

interceptedConfig = await fulfilled(config);
});

it('should not modify the config', () => {
expect(interceptedConfig).toEqual(config);
});
});
});
};

const testResponseInterceptors = () => {
describe('response interceptors', () => {
describe('when the response is successful', () => {
const response: AxiosResponse = {
status: 200,
statusText: 'OK',
headers: {},
config: {
headers: new AxiosHeaders({}),
},
data: {
foo_bar: 'foo',
bar_baz: 'bar',
},
};

let interceptedResponse: AxiosResponse;

beforeEach(async () => {
const { fulfilled } = client.interceptors.response.handlers[0];

if (!fulfilled) {
return;
}

interceptedResponse = await fulfilled(response);
});

it('camelizes the response data', async () => {
expect(interceptedResponse.data).toEqual({
fooBar: 'foo',
barBaz: 'bar',
});
});
});

describe('when the response is an error', () => {
const axiosError = new AxiosError('API error');

it('throws the same error', async () => {
const { rejected } = client.interceptors.response.handlers[0];

if (!rejected) {
return;
}

await expect(rejected(axiosError)).rejects.toEqual(axiosError);
});
});
});
};

describe('interceptors', () => {
beforeAll(() => {
interceptors();
});

testRequestInterceptors();
testResponseInterceptors();
});