chore(api): migrate tests to Vitest v4 (#65950)

This commit is contained in:
Jeevankumar S
2026-02-21 08:43:50 +05:30
committed by GitHub
parent b249098466
commit eb44f8b43c
9 changed files with 125 additions and 171 deletions
+2 -2
View File
@@ -51,7 +51,7 @@
"@types/nodemailer": "6.4.22",
"@types/supertest": "2.0.16",
"@types/validator": "13.15.10",
"@vitest/ui": "^3.2.4",
"@vitest/ui": "^4.0.15",
"dotenv-cli": "7.4.4",
"eslint": "^9.39.1",
"eslint-plugin-jsdoc": "48.11.0",
@@ -60,7 +60,7 @@
"supertest": "6.3.3",
"tsx": "4.21.0",
"typescript": "5.9.3",
"vitest": "^3.2.4"
"vitest": "^4.0.15"
},
"engines": {
"node": ">=24",
@@ -1,4 +1,5 @@
import { describe, it, expect, beforeAll, afterAll, vi } from 'vitest';
import type { MockInstance } from 'vitest';
import {
ExamEnvironmentAnswer,
ExamEnvironmentQuestionType
@@ -29,7 +30,7 @@ import {
// generate a valid exam.
// Another option is to call `generateExam` hundreds of times in a loop test :shrug:
describe('Exam Environment mocked Math.random', () => {
let spy: ReturnType<typeof vi.spyOn>;
let spy: MockInstance;
beforeAll(() => {
spy = vi.spyOn(Math, 'random').mockReturnValue(0.123456789);
});
+7 -7
View File
@@ -50,8 +50,8 @@ describe('findOrCreateUser', () => {
afterEach(async () => {
await fastify.prisma.user.deleteMany({ where: { email } });
await fastify.prisma.dripCampaign.deleteMany({ where: { email } });
await fastify.close();
vi.clearAllMocks();
vi.restoreAllMocks();
captureException.mockReset();
});
test('should send a message to Sentry if there are multiple users with the same email', async () => {
@@ -130,9 +130,10 @@ describe('findOrCreateUser', () => {
test('should not prevent user creation if drip campaign record creation fails', async () => {
vi.spyOn(fastify.gb, 'isOn').mockImplementationOnce(() => true);
// Mock dripCampaign.create to throw an error
const createSpy = vi
.spyOn(fastify.prisma.dripCampaign, 'create')
const originalCreate = fastify.prisma.dripCampaign.create;
fastify.prisma.dripCampaign.create = vi
.fn()
.mockRejectedValueOnce(new Error('Database error'));
const user = await findOrCreateUser(fastify, email);
@@ -140,7 +141,6 @@ describe('findOrCreateUser', () => {
expect(user).toBeDefined();
expect(user.id).toBeTruthy();
// Verify error was captured by Sentry
expect(captureException).toHaveBeenCalledTimes(1);
expect(captureException).toHaveBeenCalledWith(
expect.objectContaining({
@@ -148,7 +148,7 @@ describe('findOrCreateUser', () => {
})
);
createSpy.mockRestore();
fastify.prisma.dripCampaign.create = originalCreate;
});
test('should not create drip campaign for existing users', async () => {
+4 -5
View File
@@ -424,11 +424,10 @@ describe('certificate routes', () => {
}
});
vi.spyOn(fastifyTestInstance.prisma.user, 'update').mockImplementation(
() => {
throw new Error('test');
}
);
vi.spyOn(fastifyTestInstance.prisma, 'user', 'get').mockReturnValue({
...fastifyTestInstance.prisma.user,
update: vi.fn().mockRejectedValueOnce(new Error('test'))
});
const response = await superRequest('/certificate/verify', {
method: 'PUT',
+10 -4
View File
@@ -378,11 +378,17 @@ describe('challengeRoutes', () => {
// function with undefined when restoring a prisma function (for some
// reason)
test('Should return an error response if something goes wrong', async () => {
const originalUserToken = fastifyTestInstance.prisma.userToken;
vi.spyOn(
fastifyTestInstance.prisma.userToken,
'findUnique'
).mockImplementationOnce(() => {
throw new Error('Database error');
fastifyTestInstance.prisma,
'userToken',
'get'
).mockReturnValue({
...originalUserToken,
findUnique: vi.fn().mockImplementationOnce(() => {
throw new Error('Database error');
})
});
const tokenResponse = await superPost('/user/user-token');
const token = (tokenResponse.body as { userToken: string }).userToken;
+25 -24
View File
@@ -124,30 +124,31 @@ const generateMockSubCreate = (status: string) => () =>
const defaultError = () =>
Promise.reject(new Error('Stripe encountered an error'));
vi.mock('stripe', () => {
return {
default: vi.fn().mockImplementation(() => {
return {
customers: {
create: mockCustomerCreate,
update: mockCustomerUpdate
},
paymentMethods: {
attach: mockAttachPaymentMethod
},
subscriptions: {
create: mockSubCreate,
retrieve: mockSubRetrieve
},
checkout: {
sessions: {
create: mockCheckoutSessionCreate
}
}
};
})
};
});
vi.mock('stripe', () => ({
default: class {
constructor() {}
customers = {
create: mockCustomerCreate,
update: mockCustomerUpdate
};
paymentMethods = {
attach: mockAttachPaymentMethod
};
subscriptions = {
create: mockSubCreate,
retrieve: mockSubRetrieve
};
checkout = {
sessions: {
create: mockCheckoutSessionCreate
}
};
}
}));
describe('Donate', () => {
let setCookies: string[];
+8 -7
View File
@@ -602,16 +602,17 @@ Please wait 5 minutes to resend an authentication link.`
// function with undefined when restoring a prisma function (for some
// reason)
test('PUT sends an email to the new email address', async () => {
const originalAuthToken = fastifyTestInstance.prisma.authToken;
vi.spyOn(
fastifyTestInstance.prisma.authToken,
'create'
).mockImplementationOnce(() =>
// @ts-expect-error This is a mock implementation, all we're
// interested in is the id.
Promise.resolve({
fastifyTestInstance.prisma,
'authToken',
'get'
).mockReturnValue({
...originalAuthToken,
create: vi.fn().mockResolvedValue({
id: '123'
})
);
});
await superPut('/update-my-email').send({
email: unusedEmailOne
});
+21 -25
View File
@@ -66,31 +66,27 @@ const generateMockSubCreate = (status: string) => () =>
}
}
});
vi.mock('stripe', () => {
return {
default: vi.fn().mockImplementation(() => {
return {
customers: {
create: mockCustomerCreate,
update: mockCustomerUpdate
},
paymentMethods: {
attach: mockAttachPaymentMethod
},
subscriptions: {
create: mockSubCreate,
retrieve: mockSubRetrieve
},
checkout: {
sessions: {
create: mockCheckoutSessionCreate
}
}
};
})
};
});
vi.mock('stripe', () => ({
default: class {
constructor() {}
customers = {
create: mockCustomerCreate,
update: mockCustomerUpdate
};
paymentMethods = {
attach: mockAttachPaymentMethod
};
subscriptions = {
create: mockSubCreate,
retrieve: mockSubRetrieve
};
checkout = {
sessions: {
create: mockCheckoutSessionCreate
}
};
}
}));
describe('Donate', () => {
let setCookies: string[];
setupServer();
+46 -96
View File
@@ -217,8 +217,8 @@ importers:
specifier: 13.15.10
version: 13.15.10
'@vitest/ui':
specifier: ^3.2.4
version: 3.2.4(vitest@3.2.4)
specifier: ^4.0.15
version: 4.0.15(vitest@4.0.15)
dotenv-cli:
specifier: 7.4.4
version: 7.4.4
@@ -244,8 +244,8 @@ importers:
specifier: 5.9.3
version: 5.9.3
vitest:
specifier: ^3.2.4
version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.13)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@26.1.0)(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
specifier: ^4.0.15
version: 4.0.15(@opentelemetry/api@1.9.0)(@types/node@24.10.13)(@vitest/ui@4.0.15)(jiti@2.6.1)(jsdom@26.1.0)(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
client:
dependencies:
@@ -20769,15 +20769,6 @@ snapshots:
chai: 6.2.2
tinyrainbow: 3.0.3
'@vitest/mocker@3.2.4(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.1.3(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))':
dependencies:
'@vitest/spy': 3.2.4
estree-walker: 3.0.3
magic-string: 0.30.17
optionalDependencies:
msw: 2.12.10(@types/node@24.10.13)(typescript@5.9.3)
vite: 7.1.3(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
'@vitest/mocker@3.2.4(msw@2.12.10(@types/node@25.2.3)(typescript@5.9.3))(vite@7.1.3(@types/node@25.2.3)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))':
dependencies:
'@vitest/spy': 3.2.4
@@ -20860,7 +20851,7 @@ snapshots:
sirv: 3.0.2
tinyglobby: 0.2.14
tinyrainbow: 2.0.0
vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.13)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@26.1.0)(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
vitest: 3.2.4(@types/debug@4.1.12)(@types/node@25.2.3)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@26.1.0)(msw@2.12.10(@types/node@25.2.3)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
'@vitest/ui@4.0.15(vitest@4.0.15)':
dependencies:
@@ -20871,7 +20862,7 @@ snapshots:
sirv: 3.0.2
tinyglobby: 0.2.15
tinyrainbow: 3.0.3
vitest: 4.0.15(@opentelemetry/api@1.9.0)(@types/node@25.2.3)(@vitest/ui@4.0.15)(jiti@2.6.1)(jsdom@26.1.0)(msw@2.12.10(@types/node@25.2.3)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
vitest: 4.0.15(@opentelemetry/api@1.9.0)(@types/node@24.10.13)(@vitest/ui@4.0.15)(jiti@2.6.1)(jsdom@26.1.0)(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
'@vitest/utils@3.2.4':
dependencies:
@@ -30436,27 +30427,6 @@ snapshots:
unist-util-stringify-position: 2.0.3
vfile-message: 2.0.4
vite-node@3.2.4(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1):
dependencies:
cac: 6.7.14
debug: 4.4.1
es-module-lexer: 1.7.0
pathe: 2.0.3
vite: 7.1.3(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
transitivePeerDependencies:
- '@types/node'
- jiti
- less
- lightningcss
- sass
- sass-embedded
- stylus
- sugarss
- supports-color
- terser
- tsx
- yaml
vite-node@3.2.4(@types/node@25.2.3)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1):
dependencies:
cac: 6.7.14
@@ -30478,22 +30448,6 @@ snapshots:
- tsx
- yaml
vite@7.1.3(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1):
dependencies:
esbuild: 0.25.9
fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3
postcss: 8.5.6
rollup: 4.46.2
tinyglobby: 0.2.14
optionalDependencies:
'@types/node': 24.10.13
fsevents: 2.3.3
jiti: 2.6.1
terser: 5.46.0
tsx: 4.21.0
yaml: 2.8.1
vite@7.1.3(@types/node@25.2.3)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1):
dependencies:
esbuild: 0.25.9
@@ -30580,50 +30534,6 @@ snapshots:
- debug
- typescript
vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.10.13)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@26.1.0)(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1):
dependencies:
'@types/chai': 5.2.2
'@vitest/expect': 3.2.4
'@vitest/mocker': 3.2.4(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.1.3(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
'@vitest/pretty-format': 3.2.4
'@vitest/runner': 3.2.4
'@vitest/snapshot': 3.2.4
'@vitest/spy': 3.2.4
'@vitest/utils': 3.2.4
chai: 5.2.1
debug: 4.4.1
expect-type: 1.2.2
magic-string: 0.30.17
pathe: 2.0.3
picomatch: 4.0.3
std-env: 3.9.0
tinybench: 2.9.0
tinyexec: 0.3.2
tinyglobby: 0.2.14
tinypool: 1.1.1
tinyrainbow: 2.0.0
vite: 7.1.3(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
vite-node: 3.2.4(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
why-is-node-running: 2.3.0
optionalDependencies:
'@types/debug': 4.1.12
'@types/node': 24.10.13
'@vitest/ui': 3.2.4(vitest@3.2.4)
jsdom: 26.1.0
transitivePeerDependencies:
- jiti
- less
- lightningcss
- msw
- sass
- sass-embedded
- stylus
- sugarss
- supports-color
- terser
- tsx
- yaml
vitest@3.2.4(@types/debug@4.1.12)(@types/node@25.2.3)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@26.1.0)(msw@2.12.10(@types/node@25.2.3)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1):
dependencies:
'@types/chai': 5.2.2
@@ -30748,6 +30658,46 @@ snapshots:
- tsx
- yaml
vitest@4.0.15(@opentelemetry/api@1.9.0)(@types/node@24.10.13)(@vitest/ui@4.0.15)(jiti@2.6.1)(jsdom@26.1.0)(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1):
dependencies:
'@vitest/expect': 4.0.15
'@vitest/mocker': 4.0.15(msw@2.12.10(@types/node@24.10.13)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
'@vitest/pretty-format': 4.0.15
'@vitest/runner': 4.0.15
'@vitest/snapshot': 4.0.15
'@vitest/spy': 4.0.15
'@vitest/utils': 4.0.15
es-module-lexer: 1.7.0
expect-type: 1.3.0
magic-string: 0.30.21
obug: 2.1.1
pathe: 2.0.3
picomatch: 4.0.3
std-env: 3.10.0
tinybench: 2.9.0
tinyexec: 1.0.2
tinyglobby: 0.2.15
tinyrainbow: 3.0.3
vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
why-is-node-running: 2.3.0
optionalDependencies:
'@opentelemetry/api': 1.9.0
'@types/node': 24.10.13
'@vitest/ui': 4.0.15(vitest@4.0.15)
jsdom: 26.1.0
transitivePeerDependencies:
- jiti
- less
- lightningcss
- msw
- sass
- sass-embedded
- stylus
- sugarss
- terser
- tsx
- yaml
vitest@4.0.15(@opentelemetry/api@1.9.0)(@types/node@25.2.3)(@vitest/ui@4.0.15)(jiti@2.6.1)(jsdom@26.1.0)(msw@2.12.10(@types/node@25.2.3)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1):
dependencies:
'@vitest/expect': 4.0.15