Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: replace jest with vitest on backend (fehmer) #5314

Merged
merged 4 commits into from
Apr 17, 2024
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
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
Loading