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

This file was deleted.

2,382 changes: 1,455 additions & 927 deletions .pnp.cjs
100644 → 100755

Large diffs are not rendered by default.

26 changes: 13 additions & 13 deletions .pnp.loader.mjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

934 changes: 0 additions & 934 deletions .yarn/releases/yarn-4.5.3.cjs

This file was deleted.

942 changes: 942 additions & 0 deletions .yarn/releases/yarn-4.9.4.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ enableGlobalCache: false

nodeLinker: pnp

yarnPath: .yarn/releases/yarn-4.5.3.cjs
yarnPath: .yarn/releases/yarn-4.9.4.cjs
5 changes: 1 addition & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "root",
"private": true,
"version": "4.6.0",
"packageManager": "yarn@4.5.3",
"packageManager": "yarn@4.9.4",
"type": "module",
"scripts": {
"build": "nx run-many -t build",
Expand Down Expand Up @@ -36,9 +36,6 @@
"prettier-plugin-sort-json": "^3.1.0",
"typescript": "^5.7.2"
},
"resolutions": {
"axios": "1.8.2"
},
"workspaces": [
"packages/*"
]
Expand Down
4 changes: 3 additions & 1 deletion packages/commons/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
},
"dependencies": {
"@types/parse-path": "^7.0.3",
"axios": "^1.8.2",
"axios": "^1.11.0",
"parse-path": "^7.0.0",
"path-to-regexp": "^8.2.0",
"type-fest": "^4.30.0"
Expand All @@ -52,11 +52,13 @@
"@types/jest": "^29.5.14",
"@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.18.0",
"axios": "^1.11.0",
"eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-json": "^3.1.0",
"eslint-plugin-prettier": "^5.2.1",
"jest": "^29.7.0",
"nock": "^14.0.10",
"prettier": "^3.4.2",
"prettier-plugin-jsdoc": "^1.3.0",
"prettier-plugin-pkgsort": "^0.2.1",
Expand Down
177 changes: 158 additions & 19 deletions packages/commons/src/core/ApiClientBase.test.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,186 @@
import { Axios } from "axios";
import { beforeEach, jest } from "@jest/globals";
import axios from "axios";
import { expect, jest } from "@jest/globals";
import ApiClientBase from "./ApiClientBase.js";
import nock from "nock";

const requestFn = jest.fn();

const mockedAxios = Object.assign(Object.create(Axios.prototype), {
request: requestFn,
});
let apiHistory: {
method: string;
path: string;
body: string;
headers: string[];
}[] = [];

class TestClient extends ApiClientBase {
public testRequest = this.requestFunctionFactory({
path: "/test",
public testRequestWillSucceed = this.requestFunctionFactory({
path: "/200",
method: "GET",
operationId: "test",
});

public testRequestWillFail = this.requestFunctionFactory({
path: "/500",
method: "GET",
operationId: "fail",
});

public testNetworkError = this.requestFunctionFactory({
path: "/networkErrorUrl",
method: "GET",
operationId: "networkError",
});
}
const testClient = new TestClient(mockedAxios);

axios.defaults.baseURL = "http://www.example.com";
const testClient = new TestClient(axios);
let testApi: nock.Scope;

beforeEach(() => {
jest.resetAllMocks();
});
apiHistory = [];

testApi = nock("http://www.example.com")
.get("/200")
.reply(200, { success: 1 })
.get("/networkErrorUrl")
.replyWithError(
Object.assign(new Error("Network Error"), { code: "ERR_NETWORK" }),
)
.get("/500")
.reply(500, { fail: 1 });

testApi.on("request", (req, interceptor, body) => {
apiHistory.push({
method: req.method,
path: req.path,
body: body,
headers: req.headers,
});
});
});
test("onBeforeRequest is called before actual request", async () => {
const onBeforeRequest = jest.fn(() => {
expect(requestFn).not.toHaveBeenCalled();
expect(apiHistory).toHaveLength(0);
});

await testClient.testRequest(undefined, {
await testClient.testRequestWillSucceed(undefined, {
onBeforeRequest,
});

expect(onBeforeRequest).toHaveBeenCalledTimes(1);
expect(requestFn).toHaveBeenCalledTimes(1);
expect(apiHistory).toHaveLength(1);
});

test("onBeforeRequest configured in default options is called before actual request", async () => {
const onBeforeRequest = jest.fn(() => {
expect(requestFn).not.toHaveBeenCalled();
expect(apiHistory).toHaveLength(0);
});

testClient.defaultRequestOptions.onBeforeRequest = onBeforeRequest;
await testClient.testRequest(undefined);
await testClient.testRequestWillSucceed();

expect(onBeforeRequest).toHaveBeenCalledTimes(1);
expect(requestFn).toHaveBeenCalledTimes(1);
expect(apiHistory).toHaveLength(1);
});

test("test client will work with axiosInstance", async () => {
const axiosInstance = axios.create({
headers: {
TEST_FROM_INSTANCE: 1,
},
});
const testClient = new TestClient(axiosInstance);
await testClient.testRequestWillSucceed();

expect(apiHistory).toHaveLength(1);
expect(apiHistory.at(0)).toHaveProperty("headers.test_from_instance", "1");
});

test("test client will work with config", async () => {
const testClient = new TestClient({
headers: {
TEST_FROM_CONFIG: 1,
},
});
await testClient.testRequestWillSucceed();

expect(apiHistory).toHaveLength(1);
expect(apiHistory.at(0)).toHaveProperty("headers.test_from_config", "1");
});

test("test client will work with axios default", async () => {
axios.defaults.headers = {
TEST_FROM_DEFAULT: 1,
} as never;
const testClient = new TestClient(axios);
await testClient.testRequestWillSucceed();

expect(apiHistory).toHaveLength(1);
expect(apiHistory.at(0)).toHaveProperty("headers.test_from_default", "1");
});

test("test client will work with axios default param", async () => {
axios.defaults.headers = {
TEST_FROM_DEFAULT_PARAM: 1,
} as never;
const testClient = new TestClient();
await testClient.testRequestWillSucceed();

expect(apiHistory).toHaveLength(1);
expect(apiHistory.at(0)).toHaveProperty(
"headers.test_from_default_param",
"1",
);
});

test("test request will resolved with receive data", async () => {
const response = testClient.testRequestWillSucceed();
await expect(response).resolves.toHaveProperty("data.success", 1);
});

test("test request will be resolved even when status check fails", async () => {
const success = jest.fn();
const fail = jest.fn();

axios.interceptors.response.use(
(response) => {
success(response.config.url);
return response;
},
(error) => {
fail(error.config.url);
throw error;
},
);

const response = testClient.testRequestWillFail();

// check resolves
await expect(response).resolves.toHaveProperty("data.fail", 1);

// check interceptor call
expect(success).toBeCalledTimes(0);
expect(fail).toBeCalledWith("500");
});

test("test request will rejects on network error", async () => {
const success = jest.fn();
const fail = jest.fn();

axios.interceptors.response.use(
(response) => {
success(response.config.url);
return response;
},
(error) => {
fail(error.config.url);
throw error;
},
);

const response = testClient.testNetworkError();

// check rejects
await expect(response).rejects.toThrowError("Network Error");

// check interceptor call
expect(success).toBeCalledTimes(0);
expect(fail).toBeCalledWith("networkErrorUrl");
});
Loading