Implement contact form on server side
[oweals/peertube.git] / server / tests / api / check-params / users.ts
1 /* tslint:disable:no-unused-expression */
2
3 import { omit } from 'lodash'
4 import 'mocha'
5 import { join } from 'path'
6 import { UserRole, VideoImport, VideoImportState } from '../../../../shared'
7
8 import {
9   createUser, flushTests, getMyUserInformation, getMyUserVideoRating, getUsersList, immutableAssign, killallServers, makeGetRequest,
10   makePostBodyRequest, makeUploadRequest, makePutBodyRequest, registerUser, removeUser, runServer, ServerInfo, setAccessTokensToServers,
11   updateUser, uploadVideo, userLogin, deleteMe, unblockUser, blockUser
12 } from '../../../../shared/utils'
13 import {
14   checkBadCountPagination,
15   checkBadSortPagination,
16   checkBadStartPagination
17 } from '../../../../shared/utils/requests/check-api-params'
18 import { getMagnetURI, getMyVideoImports, getYoutubeVideoUrl, importVideo } from '../../../../shared/utils/videos/video-imports'
19 import { VideoPrivacy } from '../../../../shared/models/videos'
20 import { waitJobs } from '../../../../shared/utils/server/jobs'
21 import { expect } from 'chai'
22
23 describe('Test users API validators', function () {
24   const path = '/api/v1/users/'
25   let userId: number
26   let rootId: number
27   let videoId: number
28   let server: ServerInfo
29   let serverWithRegistrationDisabled: ServerInfo
30   let userAccessToken = ''
31   let channelId: number
32   const user = {
33     username: 'user1',
34     password: 'my super password'
35   }
36
37   // ---------------------------------------------------------------
38
39   before(async function () {
40     this.timeout(30000)
41
42     await flushTests()
43
44     server = await runServer(1)
45     serverWithRegistrationDisabled = await runServer(2)
46
47     await setAccessTokensToServers([ server ])
48
49     const videoQuota = 42000000
50     await createUser(server.url, server.accessToken, user.username, user.password, videoQuota)
51     userAccessToken = await userLogin(server, user)
52
53     {
54       const res = await getMyUserInformation(server.url, server.accessToken)
55       channelId = res.body.videoChannels[ 0 ].id
56     }
57
58     {
59       const res = await uploadVideo(server.url, server.accessToken, {})
60       videoId = res.body.video.id
61     }
62   })
63
64   describe('When listing users', function () {
65     it('Should fail with a bad start pagination', async function () {
66       await checkBadStartPagination(server.url, path, server.accessToken)
67     })
68
69     it('Should fail with a bad count pagination', async function () {
70       await checkBadCountPagination(server.url, path, server.accessToken)
71     })
72
73     it('Should fail with an incorrect sort', async function () {
74       await checkBadSortPagination(server.url, path, server.accessToken)
75     })
76
77     it('Should fail with a non authenticated user', async function () {
78       await makeGetRequest({
79         url: server.url,
80         path,
81         statusCodeExpected: 401
82       })
83     })
84
85     it('Should fail with a non admin user', async function () {
86       await makeGetRequest({
87         url: server.url,
88         path,
89         token: userAccessToken,
90         statusCodeExpected: 403
91       })
92     })
93   })
94
95   describe('When adding a new user', function () {
96     const baseCorrectParams = {
97       username: 'user2',
98       email: 'test@example.com',
99       password: 'my super password',
100       videoQuota: -1,
101       videoQuotaDaily: -1,
102       role: UserRole.USER
103     }
104
105     it('Should fail with a too small username', async function () {
106       const fields = immutableAssign(baseCorrectParams, { username: '' })
107
108       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
109     })
110
111     it('Should fail with a too long username', async function () {
112       const fields = immutableAssign(baseCorrectParams, { username: 'super'.repeat(50) })
113
114       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
115     })
116
117     it('Should fail with a not lowercase username', async function () {
118       const fields = immutableAssign(baseCorrectParams, { username: 'Toto' })
119
120       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
121     })
122
123     it('Should fail with an incorrect username', async function () {
124       const fields = immutableAssign(baseCorrectParams, { username: 'my username' })
125
126       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
127     })
128
129     it('Should fail with a missing email', async function () {
130       const fields = omit(baseCorrectParams, 'email')
131
132       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
133     })
134
135     it('Should fail with an invalid email', async function () {
136       const fields = immutableAssign(baseCorrectParams, { email: 'test_example.com' })
137
138       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
139     })
140
141     it('Should fail with a too small password', async function () {
142       const fields = immutableAssign(baseCorrectParams, { password: 'bla' })
143
144       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
145     })
146
147     it('Should fail with a too long password', async function () {
148       const fields = immutableAssign(baseCorrectParams, { password: 'super'.repeat(61) })
149
150       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
151     })
152
153     it('Should fail with an non authenticated user', async function () {
154       await makePostBodyRequest({
155         url: server.url,
156         path,
157         token: 'super token',
158         fields: baseCorrectParams,
159         statusCodeExpected: 401
160       })
161     })
162
163     it('Should fail if we add a user with the same username', async function () {
164       const fields = immutableAssign(baseCorrectParams, { username: 'user1' })
165
166       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 409 })
167     })
168
169     it('Should fail if we add a user with the same email', async function () {
170       const fields = immutableAssign(baseCorrectParams, { email: 'user1@example.com' })
171
172       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 409 })
173     })
174
175     it('Should fail without a videoQuota', async function () {
176       const fields = omit(baseCorrectParams, 'videoQuota')
177
178       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
179     })
180
181     it('Should fail without a videoQuotaDaily', async function () {
182       const fields = omit(baseCorrectParams, 'videoQuotaDaily')
183
184       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
185     })
186
187     it('Should fail with an invalid videoQuota', async function () {
188       const fields = immutableAssign(baseCorrectParams, { videoQuota: -5 })
189
190       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
191     })
192
193     it('Should fail with an invalid videoQuotaDaily', async function () {
194       const fields = immutableAssign(baseCorrectParams, { videoQuotaDaily: -7 })
195
196       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
197     })
198
199     it('Should fail without a user role', async function () {
200       const fields = omit(baseCorrectParams, 'role')
201
202       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
203     })
204
205     it('Should fail with an invalid user role', async function () {
206       const fields = immutableAssign(baseCorrectParams, { role: 88989 })
207
208       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
209     })
210
211     it('Should fail with a "peertube" username', async function () {
212       const fields = immutableAssign(baseCorrectParams, { username: 'peertube' })
213
214       await makePostBodyRequest({
215         url: server.url,
216         path,
217         token: server.accessToken,
218         fields,
219         statusCodeExpected: 409
220       })
221     })
222
223     it('Should succeed with the correct params', async function () {
224       await makePostBodyRequest({
225         url: server.url,
226         path,
227         token: server.accessToken,
228         fields: baseCorrectParams,
229         statusCodeExpected: 200
230       })
231     })
232
233     it('Should fail with a non admin user', async function () {
234       const user = {
235         username: 'user1',
236         password: 'my super password'
237       }
238       userAccessToken = await userLogin(server, user)
239
240       const fields = {
241         username: 'user3',
242         email: 'test@example.com',
243         password: 'my super password',
244         videoQuota: 42000000
245       }
246       await makePostBodyRequest({ url: server.url, path, token: userAccessToken, fields, statusCodeExpected: 403 })
247     })
248   })
249
250   describe('When updating my account', function () {
251     it('Should fail with an invalid email attribute', async function () {
252       const fields = {
253         email: 'blabla'
254       }
255
256       await makePutBodyRequest({ url: server.url, path: path + 'me', token: server.accessToken, fields })
257     })
258
259     it('Should fail with a too small password', async function () {
260       const fields = {
261         currentPassword: 'my super password',
262         password: 'bla'
263       }
264
265       await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
266     })
267
268     it('Should fail with a too long password', async function () {
269       const fields = {
270         currentPassword: 'my super password',
271         password: 'super'.repeat(61)
272       }
273
274       await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
275     })
276
277     it('Should fail without the current password', async function () {
278       const fields = {
279         currentPassword: 'my super password',
280         password: 'super'.repeat(61)
281       }
282
283       await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
284     })
285
286     it('Should fail with an invalid current password', async function () {
287       const fields = {
288         currentPassword: 'my super password fail',
289         password: 'super'.repeat(61)
290       }
291
292       await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields, statusCodeExpected: 401 })
293     })
294
295     it('Should fail with an invalid NSFW policy attribute', async function () {
296       const fields = {
297         nsfwPolicy: 'hello'
298       }
299
300       await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
301     })
302
303     it('Should fail with an invalid autoPlayVideo attribute', async function () {
304       const fields = {
305         autoPlayVideo: -1
306       }
307
308       await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
309     })
310
311     it('Should fail with an invalid videosHistoryEnabled attribute', async function () {
312       const fields = {
313         videosHistoryEnabled: -1
314       }
315
316       await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
317     })
318
319     it('Should fail with an non authenticated user', async function () {
320       const fields = {
321         currentPassword: 'my super password',
322         password: 'my super password'
323       }
324
325       await makePutBodyRequest({ url: server.url, path: path + 'me', token: 'super token', fields, statusCodeExpected: 401 })
326     })
327
328     it('Should fail with a too long description', async function () {
329       const fields = {
330         description: 'super'.repeat(201)
331       }
332
333       await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
334     })
335
336     it('Should succeed to change password with the correct params', async function () {
337       const fields = {
338         currentPassword: 'my super password',
339         password: 'my super password',
340         nsfwPolicy: 'blur',
341         autoPlayVideo: false,
342         email: 'super_email@example.com'
343       }
344
345       await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields, statusCodeExpected: 204 })
346     })
347
348     it('Should succeed without password change with the correct params', async function () {
349       const fields = {
350         nsfwPolicy: 'blur',
351         autoPlayVideo: false,
352         email: 'super_email@example.com'
353       }
354
355       await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields, statusCodeExpected: 204 })
356     })
357   })
358
359   describe('When updating my avatar', function () {
360     it('Should fail without an incorrect input file', async function () {
361       const fields = {}
362       const attaches = {
363         'avatarfile': join(__dirname, '..', '..', 'fixtures', 'video_short.mp4')
364       }
365       await makeUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches })
366     })
367
368     it('Should fail with a big file', async function () {
369       const fields = {}
370       const attaches = {
371         'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar-big.png')
372       }
373       await makeUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches })
374     })
375
376     it('Should fail with an unauthenticated user', async function () {
377       const fields = {}
378       const attaches = {
379         'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png')
380       }
381       await makeUploadRequest({
382         url: server.url,
383         path: path + '/me/avatar/pick',
384         fields,
385         attaches,
386         statusCodeExpected: 401
387       })
388     })
389
390     it('Should succeed with the correct params', async function () {
391       const fields = {}
392       const attaches = {
393         'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png')
394       }
395       await makeUploadRequest({
396         url: server.url,
397         path: path + '/me/avatar/pick',
398         token: server.accessToken,
399         fields,
400         attaches,
401         statusCodeExpected: 200
402       })
403     })
404   })
405
406   describe('When getting a user', function () {
407     before(async function () {
408       const res = await getUsersList(server.url, server.accessToken)
409
410       userId = res.body.data[1].id
411     })
412
413     it('Should fail with an non authenticated user', async function () {
414       await makeGetRequest({ url: server.url, path: path + userId, token: 'super token', statusCodeExpected: 401 })
415     })
416
417     it('Should fail with a non admin user', async function () {
418       await makeGetRequest({ url: server.url, path, token: userAccessToken, statusCodeExpected: 403 })
419     })
420
421     it('Should succeed with the correct params', async function () {
422       await makeGetRequest({ url: server.url, path: path + userId, token: server.accessToken, statusCodeExpected: 200 })
423     })
424   })
425
426   describe('When updating a user', function () {
427
428     before(async function () {
429       const res = await getUsersList(server.url, server.accessToken)
430
431       userId = res.body.data[1].id
432       rootId = res.body.data[2].id
433     })
434
435     it('Should fail with an invalid email attribute', async function () {
436       const fields = {
437         email: 'blabla'
438       }
439
440       await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
441     })
442
443     it('Should fail with an invalid emailVerified attribute', async function () {
444       const fields = {
445         emailVerified: 'yes'
446       }
447
448       await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
449     })
450
451     it('Should fail with an invalid videoQuota attribute', async function () {
452       const fields = {
453         videoQuota: -90
454       }
455
456       await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
457     })
458
459     it('Should fail with an invalid user role attribute', async function () {
460       const fields = {
461         role: 54878
462       }
463
464       await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
465     })
466
467     it('Should fail with an non authenticated user', async function () {
468       const fields = {
469         videoQuota: 42
470       }
471
472       await makePutBodyRequest({ url: server.url, path: path + userId, token: 'super token', fields, statusCodeExpected: 401 })
473     })
474
475     it('Should fail when updating root role', async function () {
476       const fields = {
477         role: UserRole.MODERATOR
478       }
479
480       await makePutBodyRequest({ url: server.url, path: path + rootId, token: server.accessToken, fields })
481     })
482
483     it('Should succeed with the correct params', async function () {
484       const fields = {
485         email: 'email@example.com',
486         emailVerified: true,
487         videoQuota: 42,
488         role: UserRole.USER
489       }
490
491       await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields, statusCodeExpected: 204 })
492     })
493   })
494
495   describe('When getting my information', function () {
496     it('Should fail with a non authenticated user', async function () {
497       await getMyUserInformation(server.url, 'fake_token', 401)
498     })
499
500     it('Should success with the correct parameters', async function () {
501       await getMyUserInformation(server.url, userAccessToken)
502     })
503   })
504
505   describe('When getting my video rating', function () {
506     it('Should fail with a non authenticated user', async function () {
507       await getMyUserVideoRating(server.url, 'fake_token', videoId, 401)
508     })
509
510     it('Should fail with an incorrect video uuid', async function () {
511       await getMyUserVideoRating(server.url, server.accessToken, 'blabla', 400)
512     })
513
514     it('Should fail with an unknown video', async function () {
515       await getMyUserVideoRating(server.url, server.accessToken, '4da6fde3-88f7-4d16-b119-108df5630b06', 404)
516     })
517
518     it('Should succeed with the correct parameters', async function () {
519       await getMyUserVideoRating(server.url, server.accessToken, videoId)
520     })
521   })
522
523   describe('When blocking/unblocking/removing user', function () {
524     it('Should fail with an incorrect id', async function () {
525       await removeUser(server.url, 'blabla', server.accessToken, 400)
526       await blockUser(server.url, 'blabla', server.accessToken, 400)
527       await unblockUser(server.url, 'blabla', server.accessToken, 400)
528     })
529
530     it('Should fail with the root user', async function () {
531       await removeUser(server.url, rootId, server.accessToken, 400)
532       await blockUser(server.url, rootId, server.accessToken, 400)
533       await unblockUser(server.url, rootId, server.accessToken, 400)
534     })
535
536     it('Should return 404 with a non existing id', async function () {
537       await removeUser(server.url, 4545454, server.accessToken, 404)
538       await blockUser(server.url, 4545454, server.accessToken, 404)
539       await unblockUser(server.url, 4545454, server.accessToken, 404)
540     })
541
542     it('Should fail with a non admin user', async function () {
543       await removeUser(server.url, userId, userAccessToken, 403)
544       await blockUser(server.url, userId, userAccessToken, 403)
545       await unblockUser(server.url, userId, userAccessToken, 403)
546     })
547   })
548
549   describe('When deleting our account', function () {
550     it('Should fail with with the root account', async function () {
551       await deleteMe(server.url, server.accessToken, 400)
552     })
553   })
554
555   describe('When register a new user', function () {
556     const registrationPath = path + '/register'
557     const baseCorrectParams = {
558       username: 'user3',
559       email: 'test3@example.com',
560       password: 'my super password'
561     }
562
563     it('Should fail with a too small username', async function () {
564       const fields = immutableAssign(baseCorrectParams, { username: '' })
565
566       await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
567     })
568
569     it('Should fail with a too long username', async function () {
570       const fields = immutableAssign(baseCorrectParams, { username: 'super'.repeat(50) })
571
572       await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
573     })
574
575     it('Should fail with an incorrect username', async function () {
576       const fields = immutableAssign(baseCorrectParams, { username: 'my username' })
577
578       await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
579     })
580
581     it('Should fail with a missing email', async function () {
582       const fields = omit(baseCorrectParams, 'email')
583
584       await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
585     })
586
587     it('Should fail with an invalid email', async function () {
588       const fields = immutableAssign(baseCorrectParams, { email: 'test_example.com' })
589
590       await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
591     })
592
593     it('Should fail with a too small password', async function () {
594       const fields = immutableAssign(baseCorrectParams, { password: 'bla' })
595
596       await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
597     })
598
599     it('Should fail with a too long password', async function () {
600       const fields = immutableAssign(baseCorrectParams, { password: 'super'.repeat(61) })
601
602       await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
603     })
604
605     it('Should fail if we register a user with the same username', async function () {
606       const fields = immutableAssign(baseCorrectParams, { username: 'root' })
607
608       await makePostBodyRequest({
609         url: server.url,
610         path: registrationPath,
611         token: server.accessToken,
612         fields,
613         statusCodeExpected: 409
614       })
615     })
616
617     it('Should fail with a "peertube" username', async function () {
618       const fields = immutableAssign(baseCorrectParams, { username: 'peertube' })
619
620       await makePostBodyRequest({
621         url: server.url,
622         path: registrationPath,
623         token: server.accessToken,
624         fields,
625         statusCodeExpected: 409
626       })
627     })
628
629     it('Should fail if we register a user with the same email', async function () {
630       const fields = immutableAssign(baseCorrectParams, { email: 'admin1@example.com' })
631
632       await makePostBodyRequest({
633         url: server.url,
634         path: registrationPath,
635         token: server.accessToken,
636         fields,
637         statusCodeExpected: 409
638       })
639     })
640
641     it('Should succeed with the correct params', async function () {
642       await makePostBodyRequest({
643         url: server.url,
644         path: registrationPath,
645         token: server.accessToken,
646         fields: baseCorrectParams,
647         statusCodeExpected: 204
648       })
649     })
650
651     it('Should fail on a server with registration disabled', async function () {
652       const fields = {
653         username: 'user4',
654         email: 'test4@example.com',
655         password: 'my super password 4'
656       }
657
658       await makePostBodyRequest({
659         url: serverWithRegistrationDisabled.url,
660         path: registrationPath,
661         token: serverWithRegistrationDisabled.accessToken,
662         fields,
663         statusCodeExpected: 403
664       })
665     })
666   })
667
668   describe('When registering multiple users on a server with users limit', function () {
669     it('Should fail when after 3 registrations', async function () {
670       await registerUser(server.url, 'user42', 'super password', 403)
671     })
672   })
673
674   describe('When having a video quota', function () {
675     it('Should fail with a user having too many videos', async function () {
676       await updateUser({
677         url: server.url,
678         userId: rootId,
679         accessToken: server.accessToken,
680         videoQuota: 42
681       })
682
683       await uploadVideo(server.url, server.accessToken, {}, 403)
684     })
685
686     it('Should fail with a registered user having too many videos', async function () {
687       this.timeout(30000)
688
689       const user = {
690         username: 'user3',
691         password: 'my super password'
692       }
693       userAccessToken = await userLogin(server, user)
694
695       const videoAttributes = { fixture: 'video_short2.webm' }
696       await uploadVideo(server.url, userAccessToken, videoAttributes)
697       await uploadVideo(server.url, userAccessToken, videoAttributes)
698       await uploadVideo(server.url, userAccessToken, videoAttributes)
699       await uploadVideo(server.url, userAccessToken, videoAttributes)
700       await uploadVideo(server.url, userAccessToken, videoAttributes)
701       await uploadVideo(server.url, userAccessToken, videoAttributes, 403)
702     })
703
704     it('Should fail to import with HTTP/Torrent/magnet', async function () {
705       this.timeout(120000)
706
707       const baseAttributes = {
708         channelId: 1,
709         privacy: VideoPrivacy.PUBLIC
710       }
711       await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { targetUrl: getYoutubeVideoUrl() }))
712       await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { magnetUri: getMagnetURI() }))
713       await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { torrentfile: 'video-720p.torrent' }))
714
715       await waitJobs([ server ])
716
717       const res = await getMyVideoImports(server.url, server.accessToken)
718
719       expect(res.body.total).to.equal(3)
720       const videoImports: VideoImport[] = res.body.data
721       expect(videoImports).to.have.lengthOf(3)
722
723       for (const videoImport of videoImports) {
724         expect(videoImport.state.id).to.equal(VideoImportState.FAILED)
725         expect(videoImport.error).not.to.be.undefined
726         expect(videoImport.error).to.contain('user video quota is exceeded')
727       }
728     })
729   })
730
731   describe('When having a daily video quota', function () {
732     it('Should fail with a user having too many videos', async function () {
733       await updateUser({
734         url: server.url,
735         userId: rootId,
736         accessToken: server.accessToken,
737         videoQuotaDaily: 42
738       })
739
740       await uploadVideo(server.url, server.accessToken, {}, 403)
741     })
742   })
743
744   describe('When having an absolute and daily video quota', function () {
745     it('Should fail if exceeding total quota', async function () {
746       await updateUser({
747         url: server.url,
748         userId: rootId,
749         accessToken: server.accessToken,
750         videoQuota: 42,
751         videoQuotaDaily: 1024 * 1024 * 1024
752       })
753
754       await uploadVideo(server.url, server.accessToken, {}, 403)
755     })
756
757     it('Should fail if exceeding daily quota', async function () {
758       await updateUser({
759         url: server.url,
760         userId: rootId,
761         accessToken: server.accessToken,
762         videoQuota: 1024 * 1024 * 1024,
763         videoQuotaDaily: 42
764       })
765
766       await uploadVideo(server.url, server.accessToken, {}, 403)
767     })
768   })
769
770   describe('When asking a password reset', function () {
771     const path = '/api/v1/users/ask-reset-password'
772
773     it('Should fail with a missing email', async function () {
774       const fields = {}
775
776       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
777     })
778
779     it('Should fail with an invalid email', async function () {
780       const fields = { email: 'hello' }
781
782       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
783     })
784
785     it('Should success with the correct params', async function () {
786       const fields = { email: 'admin@example.com' }
787
788       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 })
789     })
790   })
791
792   describe('When asking for an account verification email', function () {
793     const path = '/api/v1/users/ask-send-verify-email'
794
795     it('Should fail with a missing email', async function () {
796       const fields = {}
797
798       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
799     })
800
801     it('Should fail with an invalid email', async function () {
802       const fields = { email: 'hello' }
803
804       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
805     })
806
807     it('Should succeed with the correct params', async function () {
808       const fields = { email: 'admin@example.com' }
809
810       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 })
811     })
812   })
813
814   after(async function () {
815     killallServers([ server, serverWithRegistrationDisabled ])
816
817     // Keep the logs if the test failed
818     if (this['ok']) {
819       await flushTests()
820     }
821   })
822 })