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