@@ -23,7 +23,6 @@ jest.mock('../../../utils/mail', () => ({
2323 }
2424} ) ) ;
2525jest . mock ( '../helpers' , ( ) => ( {
26- // userResponse: jest.fn(),
2726 ...jest . requireActual ( '../helpers' ) ,
2827 saveUser : jest . fn ( ) ,
2928 generateToken : jest . fn ( )
@@ -33,6 +32,9 @@ describe('user.controller > auth management', () => {
3332 let request : any ;
3433 let response : any ;
3534 let next : MockNext ;
35+ let mockToken : string ;
36+ let mockUser : Partial < UserDocument > ;
37+ const fixedTime = 100000000 ;
3638
3739 beforeEach ( ( ) => {
3840 request = new MockRequest ( ) ;
@@ -47,11 +49,6 @@ describe('user.controller > auth management', () => {
4749 } ) ;
4850
4951 describe ( 'resetPasswordInitiate' , ( ) => {
50- const fixedTime = 100000000 ;
51- let mockToken : string ;
52- let saveMock : jest . Mock ;
53- let mockUser : Partial < UserDocument > ;
54-
5552 beforeAll ( ( ) => {
5653 jest . useFakeTimers ( ) . setSystemTime ( fixedTime ) ;
5754 } ) ;
@@ -69,30 +66,27 @@ describe('user.controller > auth management', () => {
6966 } ) ;
7067
7168 describe ( 'if the user is found' , ( ) => {
72- beforeEach ( ( ) => {
69+ beforeEach ( async ( ) => {
7370 mockToken = 'mock-token' ;
74- saveMock = jest . fn ( ) . mockResolvedValue ( null ) ;
7571 mockUser = createMockUser ( {
7672 email : 'test@example.com' ,
77- save : saveMock
73+ save : jest . fn ( ) . mockResolvedValue ( null )
7874 } ) ;
7975
8076 ( generateToken as jest . Mock ) . mockResolvedValue ( mockToken ) ;
8177 User . findByEmail = jest . fn ( ) . mockResolvedValue ( mockUser ) ;
8278
8379 request . body = { email : 'test@example.com' } ;
8480 request . headers . host = 'localhost:3000' ;
85- } ) ;
86- it ( 'sets a resetPasswordToken with an expiry of 1h to the user' , async ( ) => {
87- await resetPasswordInitiate ( request , response , next ) ;
8881
82+ await resetPasswordInitiate ( request , response , next ) ;
83+ } ) ;
84+ it ( 'sets a resetPasswordToken with an expiry of 1h to the user' , ( ) => {
8985 expect ( mockUser . resetPasswordToken ) . toBe ( mockToken ) ;
9086 expect ( mockUser . resetPasswordExpires ) . toBe ( fixedTime + 3600000 ) ;
91- expect ( saveMock ) . toHaveBeenCalled ( ) ;
87+ expect ( mockUser . save ) . toHaveBeenCalled ( ) ;
9288 } ) ;
93- it ( 'sends the reset password email' , async ( ) => {
94- await resetPasswordInitiate ( request , response , next ) ;
95-
89+ it ( 'sends the reset password email' , ( ) => {
9690 expect ( mailerService . send ) . toHaveBeenCalledWith (
9791 expect . objectContaining ( {
9892 to : 'test@example.com' ,
@@ -102,9 +96,7 @@ describe('user.controller > auth management', () => {
10296 } )
10397 ) ;
10498 } ) ;
105- it ( 'returns a success message that does not indicate if the user exists, for security purposes' , async ( ) => {
106- await resetPasswordInitiate ( request , response , next ) ;
107-
99+ it ( 'returns a success message that does not indicate if the user exists, for security purposes' , ( ) => {
108100 expect ( response . json ) . toHaveBeenCalledWith ( {
109101 success : true ,
110102 message :
@@ -115,11 +107,6 @@ describe('user.controller > auth management', () => {
115107 describe ( 'if the user is not found' , ( ) => {
116108 beforeEach ( ( ) => {
117109 mockToken = 'mock-token' ;
118- saveMock = jest . fn ( ) . mockResolvedValue ( { } ) ;
119- mockUser = createMockUser ( {
120- email : 'test@example.com' ,
121- save : saveMock
122- } ) ;
123110
124111 ( generateToken as jest . Mock ) . mockResolvedValue ( mockToken ) ;
125112 User . findByEmail = jest . fn ( ) . mockResolvedValue ( null ) ;
@@ -144,10 +131,9 @@ describe('user.controller > auth management', () => {
144131 } ) ;
145132 it ( 'returns unsuccessful for all other errors' , async ( ) => {
146133 mockToken = 'mock-token' ;
147- saveMock = jest . fn ( ) . mockResolvedValue ( { } ) ;
148134 mockUser = createMockUser ( {
149135 email : 'test@example.com' ,
150- save : saveMock
136+ save : jest . fn ( ) . mockResolvedValue ( null )
151137 } ) ;
152138
153139 ( generateToken as jest . Mock ) . mockRejectedValue (
@@ -167,15 +153,16 @@ describe('user.controller > auth management', () => {
167153 } ) ;
168154
169155 describe ( 'validateResetPasswordToken' , ( ) => {
170- const fixedTime = 100000000 ;
171156 beforeAll ( ( ) => jest . useFakeTimers ( ) . setSystemTime ( fixedTime ) ) ;
172157 afterAll ( ( ) => jest . useRealTimers ( ) ) ;
173158
174159 it ( 'calls User.findone with the correct token and expiry' , async ( ) => {
175160 User . findOne = jest . fn ( ) . mockReturnValue ( {
176161 exec : jest . fn ( )
177162 } ) ;
163+
178164 request . params = { token : 'some-token' } ;
165+
179166 await validateResetPasswordToken ( request , response , next ) ;
180167
181168 expect ( User . findOne ) . toHaveBeenCalledWith ( {
@@ -189,7 +176,9 @@ describe('user.controller > auth management', () => {
189176 User . findOne = jest . fn ( ) . mockReturnValue ( {
190177 exec : jest . fn ( ) . mockResolvedValue ( null )
191178 } ) ;
179+
192180 request . params = { token : 'invalid-token' } ;
181+
193182 await validateResetPasswordToken ( request , response , next ) ;
194183 } ) ;
195184 it ( 'returns a 401' , ( ) => {
@@ -214,7 +203,9 @@ describe('user.controller > auth management', () => {
214203 User . findOne = jest . fn ( ) . mockReturnValue ( {
215204 exec : jest . fn ( ) . mockResolvedValue ( fakeUser )
216205 } ) ;
206+
217207 request . params = { token : 'valid-token' } ;
208+
218209 await validateResetPasswordToken ( request , response , next ) ;
219210 } ) ;
220211 it ( 'returns a success response' , ( ) => {
@@ -224,15 +215,16 @@ describe('user.controller > auth management', () => {
224215 } ) ;
225216
226217 describe ( 'updatePassword' , ( ) => {
227- const fixedTime = 100000000 ;
228218 beforeAll ( ( ) => jest . useFakeTimers ( ) . setSystemTime ( fixedTime ) ) ;
229219 afterAll ( ( ) => jest . useRealTimers ( ) ) ;
230220
231221 it ( 'calls User.findone with the correct token and expiry' , async ( ) => {
232222 User . findOne = jest . fn ( ) . mockReturnValue ( {
233223 exec : jest . fn ( )
234224 } ) ;
225+
235226 request . params = { token : 'some-token' } ;
227+
236228 await updatePassword ( request , response , next ) ;
237229
238230 expect ( User . findOne ) . toHaveBeenCalledWith ( {
@@ -246,7 +238,9 @@ describe('user.controller > auth management', () => {
246238 User . findOne = jest . fn ( ) . mockReturnValue ( {
247239 exec : jest . fn ( ) . mockResolvedValue ( null )
248240 } ) ;
241+
249242 request . params = { token : 'invalid-token' } ;
243+
250244 await updatePassword ( request , response , next ) ;
251245 } ) ;
252246 it ( 'returns a 401' , ( ) => {
@@ -261,9 +255,9 @@ describe('user.controller > auth management', () => {
261255 } ) ;
262256
263257 describe ( 'and when there is a user with valid token' , ( ) => {
264- const fakeSanitisedUser = createMockUser ( { email : 'test@example.com' } ) ;
265- const fakeUser = {
266- ...fakeSanitisedUser ,
258+ const sanitisedMockUser = createMockUser ( { email : 'test@example.com' } ) ;
259+ mockUser = {
260+ ...sanitisedMockUser ,
267261 password : 'oldpassword' ,
268262 resetPasswordToken : 'valid-token' ,
269263 resetPasswordExpires : fixedTime + 10000 , // still valid
@@ -272,36 +266,35 @@ describe('user.controller > auth management', () => {
272266
273267 beforeEach ( async ( ) => {
274268 User . findOne = jest . fn ( ) . mockReturnValue ( {
275- exec : jest . fn ( ) . mockResolvedValue ( fakeUser )
269+ exec : jest . fn ( ) . mockResolvedValue ( mockUser )
276270 } ) ;
271+
277272 request . params = { token : 'valid-token' } ;
278273 request . setBody ( {
279274 password : 'newpassword'
280275 } ) ;
276+
281277 // simulate logging in after resetting the password works
282278 request . logIn = jest . fn ( ( user , cb ) => {
283279 request . user = user ;
284280 cb ( null ) ;
285281 } ) ;
282+
286283 await updatePassword ( request , response , next ) ;
287284 } ) ;
288285 it ( 'calls user.save with the updated password and removes the reset password token' , ( ) => {
289- expect ( fakeUser . password ) . toBe ( 'newpassword' ) ;
290- expect ( fakeUser . resetPasswordToken ) . toBeUndefined ( ) ;
291- expect ( fakeUser . resetPasswordExpires ) . toBeUndefined ( ) ;
292- expect ( fakeUser . save ) . toHaveBeenCalled ( ) ;
286+ expect ( mockUser . password ) . toBe ( 'newpassword' ) ;
287+ expect ( mockUser . resetPasswordToken ) . toBeUndefined ( ) ;
288+ expect ( mockUser . resetPasswordExpires ) . toBeUndefined ( ) ;
289+ expect ( mockUser . save ) . toHaveBeenCalled ( ) ;
293290 } ) ;
294291 it ( 'returns a success response with the sanitised user' , ( ) => {
295- expect ( response . json ) . toHaveBeenCalledWith ( fakeSanitisedUser ) ;
292+ expect ( response . json ) . toHaveBeenCalledWith ( sanitisedMockUser ) ;
296293 } ) ;
297294 } ) ;
298295 } ) ;
299296
300297 describe ( 'updateSettings' , ( ) => {
301- const fixedTime = 100000000 ; // arbitrary fixed timestamp
302- let saveMock : jest . Mock ;
303- let mockUser : Partial < UserDocument > ;
304-
305298 beforeAll ( ( ) => {
306299 jest . useFakeTimers ( ) . setSystemTime ( fixedTime ) ;
307300 } ) ;
@@ -313,7 +306,12 @@ describe('user.controller > auth management', () => {
313306 describe ( 'if the user is not found' , ( ) => {
314307 beforeEach ( async ( ) => {
315308 User . findById = jest . fn ( ) . mockResolvedValue ( null ) ;
309+
316310 request . user = { id : 'nonexistent-id' } ;
311+
312+ ( saveUser as jest . Mock ) . mockResolvedValue ( null ) ;
313+ ( generateToken as jest . Mock ) . mockResolvedValue ( 'token12343' ) ;
314+
317315 await updateSettings ( request , response , next ) ;
318316 } ) ;
319317
@@ -333,12 +331,17 @@ describe('user.controller > auth management', () => {
333331 const startingUser = createMockUser ( {
334332 username : 'oldusername' ,
335333 email : 'old@email.com' ,
336- id : 'valid-id'
334+ id : 'valid-id' ,
335+ comparePassword : jest . fn ( ) . mockResolvedValue ( true )
337336 } ) ;
338337
339338 beforeEach ( ( ) => {
340339 User . findById = jest . fn ( ) . mockResolvedValue ( startingUser ) ;
340+
341341 request . user = { id : 'valid-id' } ;
342+
343+ ( saveUser as jest . Mock ) . mockResolvedValue ( null ) ;
344+ ( generateToken as jest . Mock ) . mockResolvedValue ( 'token12343' ) ;
342345 } ) ;
343346
344347 describe ( 'and when there is a username in the request' , ( ) => {
@@ -348,33 +351,17 @@ describe('user.controller > auth management', () => {
348351 } ) ;
349352 await updateSettings ( request , response , next ) ;
350353 } ) ;
351- it ( 'calls saveUser with the new username ' , ( ) => {
354+ it ( 'calls saveUser' , ( ) => {
352355 expect ( saveUser ) . toHaveBeenCalledWith ( response , {
353356 ...startingUser ,
354357 username : 'newusername'
355358 } ) ;
356359 } ) ;
357360 } ) ;
358361
359- describe ( 'and when there is an email in the request' , ( ) => {
360- beforeEach ( async ( ) => {
361- request . setBody ( {
362- username : 'oldusername' ,
363- email : 'new@email.com'
364- } ) ;
365- await updateSettings ( request , response , next ) ;
366- } ) ;
367- it ( 'calls saveUser with the new email' , ( ) => {
368- expect ( saveUser ) . toHaveBeenCalledWith ( response , {
369- ...startingUser ,
370- email : 'new@email.com'
371- } ) ;
372- } ) ;
373- it ( 'sends an email to confirm the email update' , ( ) => { } ) ;
374- } ) ;
375-
376362 // currently frontend doesn't seem to call the below
377363 describe ( 'and when there is a newPassword in the request' , ( ) => {
364+ beforeEach ( async ( ) => { } ) ;
378365 describe ( 'and the current password is not provided' , ( ) => {
379366 it ( 'returns 401 with a "current password not provided" message' , ( ) => { } ) ;
380367 it ( 'does not save the user with the new password' , ( ) => { } ) ;
0 commit comments