Skip to content

Commit

Permalink
test: replace jest with vitest on backend (fehmer) (#5314)
Browse files Browse the repository at this point in the history
* test: replace jest with vitest on backend

* fix
  • Loading branch information
fehmer authored Apr 17, 2024
1 parent 208f47f commit 9bdbf5c
Show file tree
Hide file tree
Showing 17 changed files with 3,544 additions and 4,496 deletions.
2 changes: 0 additions & 2 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
{
"recommendations": [
"esbenp.prettier-vscode",
"Orta.vscode-jest",
"vitest.explorer",
"ryanluker.vscode-coverage-gutters",
"huntertran.auto-markdown-toc"
]
}
2 changes: 1 addition & 1 deletion backend/__tests__/api/controllers/leaderboard.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const mockApp = request(app);

describe("leaderboards controller test", () => {
it("GET /leaderboards/xp/weekly", async () => {
const configSpy = jest
const configSpy = vi
.spyOn(Configuration, "getCachedConfiguration")
.mockResolvedValue({
leaderboards: {
Expand Down
32 changes: 16 additions & 16 deletions backend/__tests__/api/controllers/result.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ const mockDecodedToken: DecodedIdToken = {
iat: 0,
} as DecodedIdToken;

jest.spyOn(AuthUtils, "verifyIdToken").mockResolvedValue(mockDecodedToken);
vi.spyOn(AuthUtils, "verifyIdToken").mockResolvedValue(mockDecodedToken);

const resultMock = jest.spyOn(ResultDal, "getResults");
const resultMock = vi.spyOn(ResultDal, "getResults");

const mockApp = request(app);

Expand All @@ -33,7 +33,7 @@ describe("result controller test", () => {
});
it("should get latest 1000 results for regular user", async () => {
//GIVEN
jest.spyOn(UserDal, "checkIfUserIsPremium").mockResolvedValue(false);
vi.spyOn(UserDal, "checkIfUserIsPremium").mockResolvedValue(false);
//WHEN
await mockApp
.get("/results")
Expand All @@ -51,7 +51,7 @@ describe("result controller test", () => {
it("should get results filter by onOrAfterTimestamp", async () => {
//GIVEN
const now = Date.now();
jest.spyOn(UserDal, "checkIfUserIsPremium").mockResolvedValue(false);
vi.spyOn(UserDal, "checkIfUserIsPremium").mockResolvedValue(false);
//WHEN
await mockApp
.get("/results")
Expand All @@ -70,7 +70,7 @@ describe("result controller test", () => {
});
it("should get with limit and offset", async () => {
//GIVEN
jest.spyOn(UserDal, "checkIfUserIsPremium").mockResolvedValue(false);
vi.spyOn(UserDal, "checkIfUserIsPremium").mockResolvedValue(false);

//WHEN
await mockApp
Expand All @@ -89,7 +89,7 @@ describe("result controller test", () => {
});
it("should fail exceeding max limit for regular user", async () => {
//GIVEN
jest.spyOn(UserDal, "checkIfUserIsPremium").mockResolvedValue(false);
vi.spyOn(UserDal, "checkIfUserIsPremium").mockResolvedValue(false);

//WHEN
await mockApp
Expand All @@ -112,7 +112,7 @@ describe("result controller test", () => {
});
it("should get with higher max limit for premium user", async () => {
//GIVEN
jest.spyOn(UserDal, "checkIfUserIsPremium").mockResolvedValue(true);
vi.spyOn(UserDal, "checkIfUserIsPremium").mockResolvedValue(true);

//WHEN
await mockApp
Expand All @@ -132,7 +132,7 @@ describe("result controller test", () => {
});
it("should get results if offset/limit is partly outside the max limit", async () => {
//GIVEN
jest.spyOn(UserDal, "checkIfUserIsPremium").mockResolvedValue(false);
vi.spyOn(UserDal, "checkIfUserIsPremium").mockResolvedValue(false);

//WHEN
await mockApp
Expand All @@ -152,7 +152,7 @@ describe("result controller test", () => {
});
it("should fail exceeding 1k limit", async () => {
//GIVEN
jest.spyOn(UserDal, "checkIfUserIsPremium").mockResolvedValue(false);
vi.spyOn(UserDal, "checkIfUserIsPremium").mockResolvedValue(false);

//WHEN
await mockApp
Expand All @@ -171,7 +171,7 @@ describe("result controller test", () => {
});
it("should fail exceeding maxlimit for premium user", async () => {
//GIVEN
jest.spyOn(UserDal, "checkIfUserIsPremium").mockResolvedValue(true);
vi.spyOn(UserDal, "checkIfUserIsPremium").mockResolvedValue(true);

//WHEN
await mockApp
Expand All @@ -194,7 +194,7 @@ describe("result controller test", () => {
});
it("should get results within regular limits for premium users even if premium is globally disabled", async () => {
//GIVEN
jest.spyOn(UserDal, "checkIfUserIsPremium").mockResolvedValue(true);
vi.spyOn(UserDal, "checkIfUserIsPremium").mockResolvedValue(true);
enablePremiumFeatures(false);

//WHEN
Expand All @@ -214,7 +214,7 @@ describe("result controller test", () => {
});
it("should fail exceeding max limit for premium user if premium is globally disabled", async () => {
//GIVEN
jest.spyOn(UserDal, "checkIfUserIsPremium").mockResolvedValue(true);
vi.spyOn(UserDal, "checkIfUserIsPremium").mockResolvedValue(true);
enablePremiumFeatures(false);

//WHEN
Expand All @@ -230,7 +230,7 @@ describe("result controller test", () => {
});
it("should get results with regular limit as default for premium users if premium is globally disabled", async () => {
//GIVEN
jest.spyOn(UserDal, "checkIfUserIsPremium").mockResolvedValue(true);
vi.spyOn(UserDal, "checkIfUserIsPremium").mockResolvedValue(true);
enablePremiumFeatures(false);

//WHEN
Expand Down Expand Up @@ -259,7 +259,7 @@ async function enablePremiumFeatures(premium: boolean): Promise<void> {
users: { premium: { enabled: premium } },
});

jest
.spyOn(Configuration, "getCachedConfiguration")
.mockResolvedValue(mockConfig);
vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue(
mockConfig
);
}
4 changes: 2 additions & 2 deletions backend/__tests__/api/controllers/user.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe("user controller test", () => {
captcha: "captcha",
};

jest.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue({
vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue({
//if stuff breaks this might be the reason
users: {
signUp: true,
Expand Down Expand Up @@ -90,7 +90,7 @@ describe("user controller test", () => {
})
.expect(409);

jest.restoreAllMocks();
vi.restoreAllMocks();
});
});
});
6 changes: 3 additions & 3 deletions backend/__tests__/dal/leaderboards.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ async function enablePremiumFeatures(premium: boolean): Promise<void> {
users: { premium: { enabled: premium } },
});

jest
.spyOn(Configuration, "getCachedConfiguration")
.mockResolvedValue(mockConfig);
vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue(
mockConfig
);
}
2 changes: 1 addition & 1 deletion backend/__tests__/dal/result.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ async function createDummyData(
},
};

jest.spyOn(UserDal, "getUser").mockResolvedValue(dummyUser);
vi.spyOn(UserDal, "getUser").mockResolvedValue(dummyUser);
const tags: string[] = [];
if (tag !== undefined) tags.push(tag);
for (let i = 0; i < count; i++) {
Expand Down
15 changes: 7 additions & 8 deletions backend/__tests__/dal/user.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import _ from "lodash";
import { ObjectId } from "mongodb";
import { updateStreak } from "../../src/dal/user";
import * as UserDAL from "../../src/dal/user";

Expand Down Expand Up @@ -295,7 +294,7 @@ describe("UserDal", () => {
await UserDAL.addUser(testUser.name, testUser.email, testUser.uid);

// when
Date.now = jest.fn(() => 0);
Date.now = vi.fn(() => 0);
await UserDAL.recordAutoBanEvent(testUser.uid, 2, 1);
await UserDAL.recordAutoBanEvent(testUser.uid, 2, 1);
await UserDAL.recordAutoBanEvent(testUser.uid, 2, 1);
Expand All @@ -317,7 +316,7 @@ describe("UserDal", () => {
await UserDAL.addUser(testUser.name, testUser.email, testUser.uid);

// when
Date.now = jest.fn(() => 0);
Date.now = vi.fn(() => 0);
await UserDAL.recordAutoBanEvent(testUser.uid, 2, 1);

// then
Expand All @@ -337,11 +336,11 @@ describe("UserDal", () => {
await UserDAL.addUser(testUser.name, testUser.email, testUser.uid);

// when
Date.now = jest.fn(() => 0);
Date.now = vi.fn(() => 0);
await UserDAL.recordAutoBanEvent(testUser.uid, 2, 1);
await UserDAL.recordAutoBanEvent(testUser.uid, 2, 1);

Date.now = jest.fn(() => 36000000);
Date.now = vi.fn(() => 36000000);

await UserDAL.recordAutoBanEvent(testUser.uid, 2, 1);

Expand Down Expand Up @@ -678,7 +677,7 @@ describe("UserDal", () => {

for (const { date, expectedStreak } of testSteps) {
const milis = new Date(date).getTime();
Date.now = jest.fn(() => milis);
Date.now = vi.fn(() => milis);

const streak = await updateStreak("TestID", milis);

Expand Down Expand Up @@ -736,7 +735,7 @@ describe("UserDal", () => {

for (const { date, expectedStreak } of testSteps) {
const milis = new Date(date).getTime();
Date.now = jest.fn(() => milis);
Date.now = vi.fn(() => milis);

const streak = await updateStreak("TestID", milis);

Expand Down Expand Up @@ -778,7 +777,7 @@ describe("UserDal", () => {

for (const { date, expectedStreak } of testSteps) {
const milis = new Date(date).getTime();
Date.now = jest.fn(() => milis);
Date.now = vi.fn(() => milis);

const streak = await updateStreak("TestID", milis);

Expand Down
16 changes: 8 additions & 8 deletions backend/__tests__/middlewares/auth.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const mockDecodedToken: DecodedIdToken = {
iat: 0,
} as DecodedIdToken;

jest.spyOn(AuthUtils, "verifyIdToken").mockResolvedValue(mockDecodedToken);
vi.spyOn(AuthUtils, "verifyIdToken").mockResolvedValue(mockDecodedToken);

const mockApeKey = {
_id: new ObjectId(),
Expand All @@ -28,9 +28,9 @@ const mockApeKey = {
useCount: 0,
enabled: true,
};
jest.spyOn(ApeKeys, "getApeKey").mockResolvedValue(mockApeKey);
jest.spyOn(ApeKeys, "updateLastUsedOn").mockResolvedValue();
const isDevModeMock = jest.spyOn(Misc, "isDevEnvironment");
vi.spyOn(ApeKeys, "getApeKey").mockResolvedValue(mockApeKey);
vi.spyOn(ApeKeys, "updateLastUsedOn").mockResolvedValue();
const isDevModeMock = vi.spyOn(Misc, "isDevEnvironment");

describe("middlewares/auth", () => {
let mockRequest: Partial<MonkeyTypes.Request>;
Expand Down Expand Up @@ -60,9 +60,9 @@ describe("middlewares/auth", () => {
},
};
mockResponse = {
json: jest.fn(),
json: vi.fn(),
};
nextFunction = jest.fn((error) => {
nextFunction = vi.fn((error) => {
if (error) {
throw error;
}
Expand All @@ -76,7 +76,7 @@ describe("middlewares/auth", () => {

describe("authenticateRequest", () => {
it("should fail if token is not fresh", async () => {
Date.now = jest.fn(() => 60001);
Date.now = vi.fn(() => 60001);

const authenticateRequest = Auth.authenticateRequest({
requireFreshToken: true,
Expand All @@ -100,7 +100,7 @@ describe("middlewares/auth", () => {
expect(nextFunction).toHaveBeenCalledTimes(1);
});
it("should allow the request if token is fresh", async () => {
Date.now = jest.fn(() => 10000);
Date.now = vi.fn(() => 10000);

const authenticateRequest = Auth.authenticateRequest({
requireFreshToken: true,
Expand Down
29 changes: 19 additions & 10 deletions backend/__tests__/setup-tests.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { Collection, Db, MongoClient, WithId } from "mongodb";
import { afterAll, beforeAll, beforeEach, afterEach } from "vitest";
import * as MongoDbMock from "vitest-mongodb";

process.env["MODE"] = "dev";

jest.mock("../src/init/db", () => ({
vi.mock("../src/init/db", () => ({
__esModule: true,
getDb: (): Db => db,
collection: <T>(name: string): Collection<WithId<T>> =>
db.collection<WithId<T>>(name),
}));

jest.mock("../src/utils/logger", () => ({
vi.mock("../src/utils/logger", () => ({
__esModule: true,
default: {
error: console.error,
Expand All @@ -20,7 +22,7 @@ jest.mock("../src/utils/logger", () => ({
},
}));

jest.mock("swagger-stats", () => ({
vi.mock("swagger-stats", () => ({
getMiddleware:
() =>
(_: unknown, __: unknown, next: () => unknown): void => {
Expand All @@ -31,12 +33,11 @@ jest.mock("swagger-stats", () => ({
if (!process.env["REDIS_URI"]) {
// use mock if not set
process.env["REDIS_URI"] = "redis://mock";
jest.mock("ioredis", () => require("ioredis-mock"));
}

// TODO: better approach for this when needed
// https://firebase.google.com/docs/rules/unit-tests#run_local_unit_tests_with_the_version_9_javascript_sdk
jest.mock("firebase-admin", () => ({
vi.mock("firebase-admin", () => ({
__esModule: true,
default: {
auth: (): unknown => ({
Expand All @@ -57,14 +58,21 @@ jest.mock("firebase-admin", () => ({
const collectionsForCleanUp = ["users"];

let db: Db;
let connection: MongoClient;
let client: MongoClient;
beforeAll(async () => {
connection = await MongoClient.connect(global.__MONGO_URI__);
db = connection.db();
await MongoDbMock.setup({
serverOptions: {
binary: {
version: "6.0.12",
},
},
});
client = new MongoClient(globalThis.__MONGO_URI__);
db = client.db();
});

beforeEach(async () => {
if (global.__MONGO_URI__) {
if (globalThis.__MONGO_URI__) {
await Promise.all(
collectionsForCleanUp.map((collection) =>
db.collection(collection).deleteMany({})
Expand All @@ -80,5 +88,6 @@ afterEach(() => {
});

afterAll(async () => {
await connection.close();
await client?.close();
await MongoDbMock.teardown();
});
3 changes: 2 additions & 1 deletion backend/__tests__/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"esModuleInterop": true,
"strictNullChecks": true,
"skipLibCheck": true,
"noEmit": true
"noEmit": true,
"types": ["vitest/globals"]
},
"ts-node": {
"files": true
Expand Down
Loading

0 comments on commit 9bdbf5c

Please sign in to comment.