Skip to content

Commit e265978

Browse files
committed
chore: mock reset
1 parent 39ae089 commit e265978

2 files changed

Lines changed: 142 additions & 133 deletions

File tree

Lines changed: 136 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { expect, it, vi } from 'vitest';
1+
import { beforeEach, describe, expect, it, vi } from 'vitest';
22
import { buildSession } from '../../factories/sessionFactory';
33

44
vi.unmock('../../../src/services/sessionService');
@@ -33,207 +33,214 @@ vi.mock('jsonwebtoken', () => ({
3333
},
3434
}));
3535

36-
it('returns payload when valid', async () => {
37-
const jose = await import('jose');
38-
const { getPublicKeyByKid } = await import('../../../src/utils/signingKeyStore');
39-
40-
(getPublicKeyByKid as any).mockResolvedValue('pem');
41-
42-
(jose.jwtVerify as any).mockResolvedValue({
43-
payload: {
44-
typ: 'access',
45-
sub: 'user',
46-
sid: 'session',
47-
},
36+
describe('sessionService', () => {
37+
beforeEach(() => {
38+
vi.resetModules();
39+
vi.clearAllMocks();
4840
});
4941

50-
const { verifyJwtWithKid } = await import('../../../src/services/sessionService');
42+
it('returns payload when valid', async () => {
43+
const jose = await import('jose');
44+
const { getPublicKeyByKid } = await import('../../../src/utils/signingKeyStore');
5145

52-
const result = await verifyJwtWithKid('token', 'access');
46+
(getPublicKeyByKid as any).mockResolvedValue('pem');
5347

54-
expect(result).toBeDefined();
55-
});
48+
(jose.jwtVerify as any).mockResolvedValue({
49+
payload: {
50+
typ: 'access',
51+
sub: 'user',
52+
sid: 'session',
53+
},
54+
});
5655

57-
it('returns null on mismatch type', async () => {
58-
const jose = await import('jose');
56+
const { verifyJwtWithKid } = await import('../../../src/services/sessionService');
5957

60-
(jose.jwtVerify as any).mockResolvedValue({
61-
payload: { typ: 'wrong' },
58+
const result = await verifyJwtWithKid('token', 'access');
59+
60+
expect(result).toBeDefined();
6261
});
6362

64-
const { verifyJwtWithKid } = await import('../../../src/services/sessionService');
63+
it('returns null on mismatch type', async () => {
64+
const jose = await import('jose');
6565

66-
const result = await verifyJwtWithKid('token', 'access');
66+
(jose.jwtVerify as any).mockResolvedValue({
67+
payload: { typ: 'wrong' },
68+
});
6769

68-
expect(result).toBeNull();
69-
});
70+
const { verifyJwtWithKid } = await import('../../../src/services/sessionService');
7071

71-
it('returns null on error', async () => {
72-
const jose = await import('jose');
72+
const result = await verifyJwtWithKid('token', 'access');
7373

74-
(jose.jwtVerify as any).mockRejectedValue(new Error('fail'));
74+
expect(result).toBeNull();
75+
});
7576

76-
const { verifyJwtWithKid } = await import('../../../src/services/sessionService');
77+
it('returns null on error', async () => {
78+
const jose = await import('jose');
7779

78-
const result = await verifyJwtWithKid('token');
80+
(jose.jwtVerify as any).mockRejectedValue(new Error('fail'));
7981

80-
expect(result).toBeNull();
81-
});
82+
const { verifyJwtWithKid } = await import('../../../src/services/sessionService');
8283

83-
it.skip('returns parsed access token', async () => {
84-
const { verifyJwtWithKid } = await import('../../../src/services/sessionService');
84+
const result = await verifyJwtWithKid('token');
8585

86-
vi.spyOn(
87-
await import('../../../src/services/sessionService'),
88-
'verifyJwtWithKid',
89-
).mockResolvedValue({
90-
sub: 'user',
91-
sid: 'session',
92-
roles: ['admin'],
93-
} as any);
86+
expect(result).toBeNull();
87+
});
9488

95-
const { validateAccessToken } = await import('../../../src/services/sessionService');
89+
it.skip('returns parsed access token', async () => {
90+
const { verifyJwtWithKid } = await import('../../../src/services/sessionService');
9691

97-
const result = await validateAccessToken('token');
92+
vi.spyOn(
93+
await import('../../../src/services/sessionService'),
94+
'verifyJwtWithKid',
95+
).mockResolvedValue({
96+
sub: 'user',
97+
sid: 'session',
98+
roles: ['admin'],
99+
} as any);
98100

99-
expect(result).toEqual({
100-
userId: 'user',
101-
sessionId: 'session',
102-
roles: ['admin'],
103-
});
104-
});
101+
const { validateAccessToken } = await import('../../../src/services/sessionService');
105102

106-
it('returns null if payload invalid', async () => {
107-
const mod = await import('../../../src/services/sessionService');
103+
const result = await validateAccessToken('token');
108104

109-
vi.spyOn(mod, 'verifyJwtWithKid').mockResolvedValue(null);
105+
expect(result).toEqual({
106+
userId: 'user',
107+
sessionId: 'session',
108+
roles: ['admin'],
109+
});
110+
});
110111

111-
const result = await mod.validateAccessToken('token');
112+
it('returns null if payload invalid', async () => {
113+
const mod = await import('../../../src/services/sessionService');
112114

113-
expect(result).toBeNull();
114-
});
115+
vi.spyOn(mod, 'verifyJwtWithKid').mockResolvedValue(null);
115116

116-
it('returns null if session missing', async () => {
117-
const { Session } = await import('../../../src/models/sessions');
117+
const result = await mod.validateAccessToken('token');
118118

119-
(Session.findByPk as any).mockResolvedValue(null);
119+
expect(result).toBeNull();
120+
});
120121

121-
const { validateSessionRecord } = await import('../../../src/services/sessionService');
122+
it('returns null if session missing', async () => {
123+
const { Session } = await import('../../../src/models/sessions');
122124

123-
const result = await validateSessionRecord('id');
125+
(Session.findByPk as any).mockResolvedValue(null);
124126

125-
expect(result).toBeNull();
126-
});
127+
const { validateSessionRecord } = await import('../../../src/services/sessionService');
127128

128-
it('returns null if revoked', async () => {
129-
const { Session } = await import('../../../src/models/sessions');
129+
const result = await validateSessionRecord('id');
130130

131-
(Session.findByPk as any).mockResolvedValue(buildSession({ revokedAt: new Date() }));
131+
expect(result).toBeNull();
132+
});
132133

133-
const { validateSessionRecord } = await import('../../../src/services/sessionService');
134+
it('returns null if revoked', async () => {
135+
const { Session } = await import('../../../src/models/sessions');
134136

135-
const result = await validateSessionRecord('id');
137+
(Session.findByPk as any).mockResolvedValue(buildSession({ revokedAt: new Date() }));
136138

137-
expect(result).toBeNull();
138-
});
139+
const { validateSessionRecord } = await import('../../../src/services/sessionService');
139140

140-
it('returns session if valid', async () => {
141-
const { Session } = await import('../../../src/models/sessions');
141+
const result = await validateSessionRecord('id');
142142

143-
const session = buildSession();
143+
expect(result).toBeNull();
144+
});
144145

145-
(Session.findByPk as any).mockResolvedValue(session);
146+
it('returns session if valid', async () => {
147+
const { Session } = await import('../../../src/models/sessions');
146148

147-
const { validateSessionRecord } = await import('../../../src/services/sessionService');
149+
const session = buildSession();
148150

149-
const result = await validateSessionRecord('id');
151+
(Session.findByPk as any).mockResolvedValue(session);
150152

151-
expect(result).toBe(session);
152-
});
153+
const { validateSessionRecord } = await import('../../../src/services/sessionService');
153154

154-
it('revokes chain', async () => {
155-
const { Session } = await import('../../../src/models/sessions');
155+
const result = await validateSessionRecord('id');
156156

157-
const session = buildSession({
158-
replacedBySessionId: 'next',
157+
expect(result).toBe(session);
159158
});
160159

161-
(Session.findByPk as any).mockResolvedValue(null);
160+
it('revokes chain', async () => {
161+
const { Session } = await import('../../../src/models/sessions');
162162

163-
const { revokeSessionChain } = await import('../../../src/services/sessionService');
163+
const session = buildSession({
164+
replacedBySessionId: 'next',
165+
});
164166

165-
await revokeSessionChain(session as any);
167+
(Session.findByPk as any).mockResolvedValue(null);
166168

167-
expect(session.save).toHaveBeenCalled();
168-
});
169+
const { revokeSessionChain } = await import('../../../src/services/sessionService');
169170

170-
it('revokes session immediately', async () => {
171-
const session = buildSession();
171+
await revokeSessionChain(session as any);
172172

173-
const { hardRevokeSession } = await import('../../../src/services/sessionService');
174-
175-
await hardRevokeSession(session as any);
173+
expect(session.save).toHaveBeenCalled();
174+
});
176175

177-
expect(session.save).toHaveBeenCalled();
178-
});
176+
it('revokes session immediately', async () => {
177+
const session = buildSession();
179178

180-
it('returns user if found', async () => {
181-
const { User } = await import('../../../src/models/users');
179+
const { hardRevokeSession } = await import('../../../src/services/sessionService');
182180

183-
(User.findOne as any).mockResolvedValue({ id: 'user' });
181+
await hardRevokeSession(session as any);
184182

185-
const { getUserFromSession } = await import('../../../src/services/sessionService');
183+
expect(session.save).toHaveBeenCalled();
184+
});
186185

187-
const result = await getUserFromSession({ userId: 'user' } as any);
186+
it('returns user if found', async () => {
187+
const { User } = await import('../../../src/models/users');
188188

189-
expect(result).toBeTruthy();
190-
});
189+
(User.findOne as any).mockResolvedValue({ id: 'user' });
191190

192-
it('returns null if not found', async () => {
193-
const { User } = await import('../../../src/models/users');
191+
const { getUserFromSession } = await import('../../../src/services/sessionService');
194192

195-
(User.findOne as any).mockResolvedValue(null);
193+
const result = await getUserFromSession({ userId: 'user' } as any);
196194

197-
const { getUserFromSession } = await import('../../../src/services/sessionService');
195+
expect(result).toBeTruthy();
196+
});
198197

199-
const result = await getUserFromSession({ userId: 'user' } as any);
198+
it('returns null if not found', async () => {
199+
const { User } = await import('../../../src/models/users');
200200

201-
expect(result).toBeNull();
202-
});
201+
(User.findOne as any).mockResolvedValue(null);
203202

204-
it('returns user when valid', async () => {
205-
const { getSecret } = await import('../../../src/utils/secretsStore');
206-
const jwt = await import('jsonwebtoken');
207-
const { User } = await import('../../../src/models/users');
203+
const { getUserFromSession } = await import('../../../src/services/sessionService');
208204

209-
(getSecret as any).mockResolvedValue('secret');
205+
const result = await getUserFromSession({ userId: 'user' } as any);
210206

211-
(jwt.default.verify as any).mockReturnValue({
212-
sub: 'user',
207+
expect(result).toBeNull();
213208
});
214209

215-
(User.findOne as any).mockResolvedValue({ id: 'user' });
210+
it('returns user when valid', async () => {
211+
const { getSecret } = await import('../../../src/utils/secretsStore');
212+
const jwt = await import('jsonwebtoken');
213+
const { User } = await import('../../../src/models/users');
216214

217-
const { validateBearerToken } = await import('../../../src/services/sessionService');
215+
(getSecret as any).mockResolvedValue('secret');
218216

219-
const result = await validateBearerToken('token');
217+
(jwt.default.verify as any).mockReturnValue({
218+
sub: 'user',
219+
});
220220

221-
expect(result).toBeTruthy();
222-
});
221+
(User.findOne as any).mockResolvedValue({ id: 'user' });
223222

224-
it('returns null if jwt fails', async () => {
225-
const { getSecret } = await import('../../../src/utils/secretsStore');
226-
const jwt = await import('jsonwebtoken');
223+
const { validateBearerToken } = await import('../../../src/services/sessionService');
227224

228-
(getSecret as any).mockResolvedValue('secret');
225+
const result = await validateBearerToken('token');
229226

230-
(jwt.default.verify as any).mockImplementation(() => {
231-
throw new Error('fail');
227+
expect(result).toBeTruthy();
232228
});
233229

234-
const { validateBearerToken } = await import('../../../src/services/sessionService');
230+
it('returns null if jwt fails', async () => {
231+
const { getSecret } = await import('../../../src/utils/secretsStore');
232+
const jwt = await import('jsonwebtoken');
235233

236-
const result = await validateBearerToken('token');
234+
(getSecret as any).mockResolvedValue('secret');
237235

238-
expect(result).toBeNull();
236+
(jwt.default.verify as any).mockImplementation(() => {
237+
throw new Error('fail');
238+
});
239+
240+
const { validateBearerToken } = await import('../../../src/services/sessionService');
241+
242+
const result = await validateBearerToken('token');
243+
244+
expect(result).toBeNull();
245+
});
239246
});

tests/unit/utils/otp.spec.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, expect, it, vi } from 'vitest';
1+
import { beforeEach, describe, expect, it, vi } from 'vitest';
22

33
vi.unmock('../../../src/utils/otp.js');
44
vi.mock('../../../src/services/messagingService.js', () => ({
@@ -38,9 +38,11 @@ function buildUser(overrides: any = {}) {
3838
}
3939

4040
describe('OTP utils', () => {
41-
// ---------------------------
42-
// Random generators
43-
// ---------------------------
41+
beforeEach(() => {
42+
vi.resetModules();
43+
vi.clearAllMocks();
44+
});
45+
4446
describe('generateRandomEmailOTP', () => {
4547
it('returns 6 uppercase letters', () => {
4648
const otp = generateRandomEmailOTP();

0 commit comments

Comments
 (0)