Skip to content

Commit

Permalink
[api] migrate testing framework (Jest > Vitest) (#3555)
Browse files Browse the repository at this point in the history
  • Loading branch information
freemvmt authored Aug 29, 2024
1 parent 3110a90 commit 3984823
Show file tree
Hide file tree
Showing 47 changed files with 977 additions and 3,082 deletions.
19 changes: 3 additions & 16 deletions api.planx.uk/.eslintrc
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint", "jest"],
"plugins": ["@typescript-eslint"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"prettier",
"plugin:jest/recommended"
"prettier"
],
"rules": {
"@typescript-eslint/no-explicit-any": "warn",
Expand All @@ -18,18 +17,6 @@
}
],
"@typescript-eslint/no-non-null-assertion": "off",
"jest/expect-expect": [
"error",
{
"assertFunctionNames": [
"expect",
// Allow Supertest expect() calls
"get.expect",
"post.expect",
"supertest.**.expect"
]
}
],
"no-nested-ternary": "error"
},
"globals": {
Expand All @@ -44,7 +31,7 @@
"URLSearchParams": "readonly",
"exports": "readonly",
"fetch": "readonly",
"jest": "readonly",
"vi": "readonly",
"test": "readonly",
"describe": "readonly",
"it": "readonly",
Expand Down
2 changes: 1 addition & 1 deletion api.planx.uk/client/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ test("getClient() throws an error if a store is not set", () => {
});

test("getClient() returns a client if store is set", () => {
const getStoreMock = jest.spyOn(userContext, "getStore");
const getStoreMock = vi.spyOn(userContext, "getStore");
getStoreMock.mockReturnValue({
user: {
sub: "123",
Expand Down
49 changes: 0 additions & 49 deletions api.planx.uk/jest.config.ts

This file was deleted.

11 changes: 0 additions & 11 deletions api.planx.uk/jest.setup.js

This file was deleted.

58 changes: 33 additions & 25 deletions api.planx.uk/lib/hasura/metadata/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,40 @@
import { createScheduledEvent, RequiredScheduledEventArgs } from "./index.js";
import Axios, { AxiosError } from "axios";
import axios from "axios";
import type { Mocked } from "vitest";

jest.mock("axios", () => ({
...jest.requireActual("axios"),
post: jest.fn(),
}));
const mockAxios = Axios as jest.Mocked<typeof Axios>;
describe("Creation of scheduled event", () => {
vi.mock("axios", async (importOriginal) => {
const actualAxios = await importOriginal<typeof import("axios")>();
return {
default: {
...actualAxios,
post: vi.fn(),
},
};
});
const mockAxios = axios as Mocked<typeof axios>;

const mockScheduledEvent: RequiredScheduledEventArgs = {
webhook: "test url",
schedule_at: new Date(),
comment: "test comment",
payload: {},
};
const mockScheduledEvent: RequiredScheduledEventArgs = {
webhook: "test url",
schedule_at: new Date(),
comment: "test comment",
payload: {},
};

test("createScheduledEvent returns an error if request fails", async () => {
mockAxios.post.mockRejectedValue(new Error());
await expect(createScheduledEvent(mockScheduledEvent)).rejects.toThrow();
});
test("returns an error if request fails", async () => {
mockAxios.post.mockRejectedValue(new Error());
await expect(createScheduledEvent(mockScheduledEvent)).rejects.toThrow();
});

test("createScheduledEvent returns an error if Axios errors", async () => {
mockAxios.post.mockRejectedValue(new AxiosError());
await expect(createScheduledEvent(mockScheduledEvent)).rejects.toThrow();
});
test("returns an error if axios errors", async () => {
mockAxios.post.mockRejectedValue(new axios.AxiosError());
await expect(createScheduledEvent(mockScheduledEvent)).rejects.toThrow();
});

test("createScheduledEvent returns response data on success", async () => {
mockAxios.post.mockResolvedValue({ data: "test data" });
await expect(createScheduledEvent(mockScheduledEvent)).resolves.toBe(
"test data",
);
test("returns response data on success", async () => {
mockAxios.post.mockResolvedValue({ data: "test data" });
await expect(createScheduledEvent(mockScheduledEvent)).resolves.toBe(
"test data",
);
});
});
44 changes: 26 additions & 18 deletions api.planx.uk/lib/hasura/schema/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
import { runSQL } from "./index.js";
import Axios, { AxiosError } from "axios";
import axios from "axios";
import type { Mocked } from "vitest";

jest.mock("axios", () => ({
...jest.requireActual("axios"),
post: jest.fn(),
}));
const mockAxios = Axios as jest.Mocked<typeof Axios>;
describe("runSQL", () => {
vi.mock("axios", async (importOriginal) => {
const actualAxios = await importOriginal<typeof import("axios")>();
return {
default: {
...actualAxios,
post: vi.fn(),
},
};
});
const mockAxios = axios as Mocked<typeof axios>;

const sql = "SELECT * FROM TEST";
const sql = "SELECT * FROM TEST";

test("runSQL returns an error if request fails", async () => {
mockAxios.post.mockRejectedValue(new Error());
await expect(runSQL(sql)).rejects.toThrow();
});
test("returns an error if request fails", async () => {
mockAxios.post.mockRejectedValue(new Error());
await expect(runSQL(sql)).rejects.toThrow();
});

test("runSQL returns an error if Axios errors", async () => {
mockAxios.post.mockRejectedValue(new AxiosError());
await expect(runSQL(sql)).rejects.toThrow();
});
test("returns an error if Axios errors", async () => {
mockAxios.post.mockRejectedValue(new axios.AxiosError());
await expect(runSQL(sql)).rejects.toThrow();
});

test("runSQL returns response data on success", async () => {
mockAxios.post.mockResolvedValue({ data: "test data" });
await expect(runSQL(sql)).resolves.toBe("test data");
test("returns response data on success", async () => {
mockAxios.post.mockResolvedValue({ data: "test data" });
await expect(runSQL(sql)).resolves.toBe("test data");
});
});
2 changes: 1 addition & 1 deletion api.planx.uk/lib/notify/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { sendEmail } from "./index.js";
import { NotifyClient } from "notifications-node-client";
import { NotifyConfig } from "../../types.js";

jest.mock("notifications-node-client");
vi.mock("notifications-node-client");

const TEST_EMAIL = "[email protected]";
const mockConfig: NotifyConfig = {
Expand Down
10 changes: 6 additions & 4 deletions api.planx.uk/modules/admin/session/csv.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ import { authHeader } from "../../../tests/mockJWT.js";
const endpoint = (strings: TemplateStringsArray) =>
`/admin/session/${strings[0]}/csv`;

const mockGenerateCSVData = jest.fn().mockResolvedValue([
const mockGenerateCSVData = vi.fn().mockResolvedValue([
{
question: "Is this a test?",
responses: [{ value: "Yes" }],
metadata: {},
},
]);
jest.mock("@opensystemslab/planx-core", () => {
vi.mock("@opensystemslab/planx-core", () => {
return {
CoreDomainClient: jest.fn().mockImplementation(() => ({
CoreDomainClient: vi.fn().mockImplementation(() => ({
export: {
csvData: () => mockGenerateCSVData(),
},
Expand All @@ -23,7 +23,9 @@ jest.mock("@opensystemslab/planx-core", () => {
});

describe("CSV data admin endpoint", () => {
afterEach(() => jest.clearAllMocks());
afterEach(() => {
vi.clearAllMocks();
});
const auth = authHeader({ role: "platformAdmin" });

it("requires a user to be logged in", async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import { expectedPlanningPermissionPayload } from "../../../tests/mocks/digitalP
const endpoint = (strings: TemplateStringsArray) =>
`/admin/session/${strings[0]}/digital-planning-application`;

const mockGenerateDigitalPlanningApplicationPayload = jest
const mockGenerateDigitalPlanningApplicationPayload = vi
.fn()
.mockResolvedValue(expectedPlanningPermissionPayload);

jest.mock("@opensystemslab/planx-core", () => {
vi.mock("@opensystemslab/planx-core", () => {
return {
CoreDomainClient: jest.fn().mockImplementation(() => ({
CoreDomainClient: vi.fn().mockImplementation(() => ({
export: {
digitalPlanningDataPayload: () =>
mockGenerateDigitalPlanningApplicationPayload(),
Expand Down
8 changes: 5 additions & 3 deletions api.planx.uk/modules/admin/session/html.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { authHeader } from "../../../tests/mockJWT.js";
const endpoint = (strings: TemplateStringsArray) =>
`/admin/session/${strings[0]}/html`;

const mockGenerateHTMLData = jest.fn().mockResolvedValue({
const mockGenerateHTMLData = vi.fn().mockResolvedValue({
responses: [
{
question: "Is this a test?",
Expand All @@ -15,7 +15,7 @@ const mockGenerateHTMLData = jest.fn().mockResolvedValue({
],
redactedResponses: [],
});
jest.mock("../../../client", () => {
vi.mock("../../../client", () => {
return {
$api: {
export: {
Expand All @@ -26,7 +26,9 @@ jest.mock("../../../client", () => {
});

describe("HTML data admin endpoint", () => {
afterEach(() => jest.clearAllMocks());
afterEach(() => {
vi.clearAllMocks();
});

it("requires a user to be logged in", () => {
return supertest(app)
Expand Down
4 changes: 2 additions & 2 deletions api.planx.uk/modules/admin/session/oneAppXML.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import { authHeader } from "../../../tests/mockJWT.js";
const endpoint = (strings: TemplateStringsArray) =>
`/admin/session/${strings[0]}/xml`;

const mockGenerateOneAppXML = jest
const mockGenerateOneAppXML = vi
.fn()
.mockResolvedValue("<dummy:xml></dummy:xml>");

jest.mock("../../../client", () => {
vi.mock("../../../client", () => {
return {
$api: {
export: {
Expand Down
4 changes: 3 additions & 1 deletion api.planx.uk/modules/admin/session/summary.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ describe("Session summary admin endpoint", () => {
});
});

afterEach(() => jest.clearAllMocks());
afterEach(() => {
vi.clearAllMocks();
});

it("requires a user to be logged in", async () => {
await supertest(app)
Expand Down
10 changes: 6 additions & 4 deletions api.planx.uk/modules/admin/session/zip.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@ import supertest from "supertest";
import app from "../../../server.js";
import { authHeader } from "../../../tests/mockJWT.js";

jest.mock("../../send/utils/exportZip", () => ({
buildSubmissionExportZip: jest.fn().mockResolvedValue({
vi.mock("../../send/utils/exportZip", () => ({
buildSubmissionExportZip: vi.fn().mockResolvedValue({
filename: "tests/mocks/test.zip",
remove: jest.fn,
remove: vi.fn,
}),
}));

const endpoint = (strings: TemplateStringsArray) =>
`/admin/session/${strings[0]}/zip`;

describe("zip data admin endpoint", () => {
afterEach(() => jest.clearAllMocks());
afterEach(() => {
vi.clearAllMocks();
});

it("requires a user to be logged in", async () => {
await supertest(app)
Expand Down
4 changes: 2 additions & 2 deletions api.planx.uk/modules/auth/service.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { checkUserCanAccessEnv } from "./service.js";

const mockIsStagingOnly = jest.fn();
const mockIsStagingOnly = vi.fn();

jest.mock("../../client", () => {
vi.mock("../../client", () => {
return {
$api: {
user: {
Expand Down
Loading

0 comments on commit 3984823

Please sign in to comment.