From fc0b56154749f4638a6e0781e8b857b1c9d6a281 Mon Sep 17 00:00:00 2001 From: Mohamed Khelif Date: Wed, 24 Jan 2024 16:46:58 -0500 Subject: [PATCH] DEVPROD-801 Remove axios (#2238) --- package.json | 1 - src/utils/request.test.js | 27 ---------------------- src/utils/request.test.ts | 48 +++++++++++++++++++++++++++++++++++++++ src/utils/request.ts | 42 ++++++++++------------------------ yarn.lock | 11 +-------- 5 files changed, 61 insertions(+), 68 deletions(-) delete mode 100644 src/utils/request.test.js create mode 100644 src/utils/request.test.ts diff --git a/package.json b/package.json index 40dd7ee1fb..0ffde827dc 100644 --- a/package.json +++ b/package.json @@ -103,7 +103,6 @@ "@sentry/types": "7.56.0", "ansi_up": "6.0.2", "antd": "4.20.0", - "axios": "1.6.1", "date-fns": "2.28.0", "date-fns-tz": "2.0.0", "deep-object-diff": "1.1.9", diff --git a/src/utils/request.test.js b/src/utils/request.test.js deleted file mode 100644 index 74bad5dce6..0000000000 --- a/src/utils/request.test.js +++ /dev/null @@ -1,27 +0,0 @@ -import axios from "axios"; -import { post } from "./request"; - -const API_URL = "/some/endpoint"; - -const jsonMessage = "got JSON response"; - -const mockApi = { - statusText: "OK", - data: jsonMessage, -}; - -jest.mock("axios"); - -test("posts", async () => { - axios.post.mockImplementationOnce(() => Promise.resolve(mockApi)); - const response = await post(API_URL, {}); - expect(response.data).toBe(jsonMessage); -}); - -test("should handle a bad response", async () => { - const errorCallback = jest.fn(); - axios.post.mockImplementationOnce(() => Promise.resolve(jsonMessage)); - - expect(await post(API_URL, {}, { onFailure: errorCallback })).toBe(undefined); - expect(errorCallback).toHaveBeenCalledTimes(1); -}); diff --git a/src/utils/request.test.ts b/src/utils/request.test.ts new file mode 100644 index 0000000000..6dbfbf19f7 --- /dev/null +++ b/src/utils/request.test.ts @@ -0,0 +1,48 @@ +import { post } from "./request"; + +describe("post", () => { + afterEach(() => { + jest.clearAllMocks(); + }); + + it("should make a POST request and return the response for a successful request", async () => { + const url = "/api/resource"; + const body = { key: "value" }; + const fetchMock = jest.fn().mockResolvedValue({ + ok: true, + }); + + jest.spyOn(global, "fetch").mockImplementation(fetchMock); + + const response = await post(url, body); + + expect(response).toStrictEqual({ ok: true }); + expect(fetchMock).toHaveBeenCalledWith("/api/resource", { + method: "POST", + body: JSON.stringify(body), + credentials: "include", + }); + }); + + it("should handle and report an error for a failed request", async () => { + const url = "/api/resource"; + const body = { key: "value" }; + const fetchMock = jest.fn().mockResolvedValue({ + ok: false, + status: 500, + statusText: "Internal Server Error", + }); + const errorReportingMock = jest.fn(); + jest.spyOn(console, "error").mockImplementation(errorReportingMock); + jest.spyOn(global, "fetch").mockImplementation(fetchMock); + + await post(url, body); + + expect(fetchMock).toHaveBeenCalledWith("/api/resource", { + method: "POST", + body: JSON.stringify(body), + credentials: "include", + }); + expect(errorReportingMock).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/utils/request.ts b/src/utils/request.ts index ab8c55a8a9..a4846eb22e 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -1,44 +1,26 @@ -import axios from "axios"; import { getUiUrl } from "./environmentVariables"; import { reportError } from "./errorReporting"; -type optionsType = { - onFailure?: (e) => void; -}; -export const post = async ( - url: string, - body: unknown, - options: optionsType = {}, -) => { +export const post = async (url: string, body: unknown) => { try { - const response = await axios.post( - `${getUiUrl()}${url}`, - { body }, - { withCredentials: true }, - ); - if (isBadResponse(response)) { - throw new Error(getErrorMessage(response, "POST")); + const response = await fetch(`${getUiUrl()}${url}`, { + method: "POST", + body: JSON.stringify(body), + credentials: "include", + }); + if (!response.ok) { + throw new Error(await getErrorMessage(response, "POST")); } return response; - } catch (e) { - if (options.onFailure) { - options.onFailure(e); - } + } catch (e: any) { handleError(e); } }; -const isBadResponse = (response) => - !response || (response && response.statusText !== "OK"); - -type responseType = { - status: number; - statusText: string; +const getErrorMessage = async (response: Response, method: string) => { + const { status, statusText } = response; + return `${method} Error: ${status} - ${statusText}`; }; -const getErrorMessage = (response: responseType, method: string) => - response - ? `${method} Error: ${response.status} - ${response.statusText}` - : `${method} Error: Did not receive a response from the server`; const handleError = (error: string) => { reportError(new Error(error)).warning(); diff --git a/yarn.lock b/yarn.lock index 6324e4a24c..2afa84ae57 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7000,15 +7000,6 @@ axe-core@=4.7.0: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.0.tgz#34ba5a48a8b564f67e103f0aa5768d76e15bbbbf" integrity sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ== -axios@1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.1.tgz#76550d644bf0a2d469a01f9244db6753208397d7" - integrity sha512-vfBmhDpKafglh0EldBEbVuoe7DyAavGSLWhuSm5ZSEKQnHhBf0xAAwybbNH1IkrJNGnS/VG4I5yxig1pCEXE4g== - dependencies: - follow-redirects "^1.15.0" - form-data "^4.0.0" - proxy-from-env "^1.1.0" - axobject-query@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.2.1.tgz#39c378a6e3b06ca679f29138151e45b2b32da62a" @@ -9674,7 +9665,7 @@ focus-trap@6.9.4, focus-trap@^6.9.4: dependencies: tabbable "^5.3.3" -follow-redirects@^1.0.0, follow-redirects@^1.15.0: +follow-redirects@^1.0.0: version "1.15.4" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf" integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==