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