e1954c64f53332485d134f506b0a84f0620dba1a
[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 } 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
12 } from '../../utils'
13 import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
14
15 describe('Test users API validators', function () {
16   const path = '/api/v1/users/'
17   let userId: number
18   let rootId: number
19   let videoId: number
20   let server: ServerInfo
21   let serverWithRegistrationDisabled: ServerInfo
22   let userAccessToken = ''
23   const user = {
24     username: 'user1',
25     password: 'my super password'
26   }
27
28   // ---------------------------------------------------------------
29
30   before(async function () {
31     this.timeout(30000)
32
33     await flushTests()
34
35     server = await runServer(1)
36     serverWithRegistrationDisabled = await runServer(2)
37
38     await setAccessTokensToServers([ server ])
39
40     const videoQuota = 42000000
41     await createUser(server.url, server.accessToken, user.username, user.password, videoQuota)
42     userAccessToken = await userLogin(server, user)
43
44     const res = await uploadVideo(server.url, server.accessToken, {})
45     videoId = res.body.video.id
46   })
47
48   describe('When listing users', function () {
49     it('Should fail with a bad start pagination', async function () {
50       await checkBadStartPagination(server.url, path, server.accessToken)
51     })
52
53     it('Should fail with a bad count pagination', async function () {
54       await checkBadCountPagination(server.url, path, server.accessToken)
55     })
56
57     it('Should fail with an incorrect sort', async function () {
58       await checkBadSortPagination(server.url, path, server.accessToken)
59     })
60
61     it('Should fail with a non authenticated user', async function () {
62       await makeGetRequest({
63         url: server.url,
64         path,
65         statusCodeExpected: 401
66       })
67     })
68
69     it('Should fail with a non admin user', async function () {
70       await makeGetRequest({
71         url: server.url,
72         path,
73         token: userAccessToken,
74         statusCodeExpected: 403
75       })
76     })
77   })
78
79   describe('When adding a new user', function () {
80     const baseCorrectParams = {
81       username: 'user2',
82       email: 'test@example.com',
83       password: 'my super password',
84       videoQuota: -1,
85       role: UserRole.USER
86     }
87
88     it('Should fail with a too small username', async function () {
89       const fields = immutableAssign(baseCorrectParams, { username: 'fi' })
90
91       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
92     })
93
94     it('Should fail with a too long username', async function () {
95       const fields = immutableAssign(baseCorrectParams, { username: 'my_super_username_which_is_very_long' })
96
97       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
98     })
99
100     it('Should fail with a not lowercase username', async function () {
101       const fields = immutableAssign(baseCorrectParams, { username: 'Toto' })
102
103       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
104     })
105
106     it('Should fail with an incorrect username', async function () {
107       const fields = immutableAssign(baseCorrectParams, { username: 'my username' })
108
109       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
110     })
111
112     it('Should fail with a missing email', async function () {
113       const fields = omit(baseCorrectParams, 'email')
114
115       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
116     })
117
118     it('Should fail with an invalid email', async function () {
119       const fields = immutableAssign(baseCorrectParams, { email: 'test_example.com' })
120
121       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
122     })
123
124     it('Should fail with a too small password', async function () {
125       const fields = immutableAssign(baseCorrectParams, { password: 'bla' })
126
127       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
128     })
129
130     it('Should fail with a too long password', async function () {
131       const fields = immutableAssign(baseCorrectParams, { password: 'super'.repeat(61) })
132
133       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
134     })
135
136     it('Should fail with an non authenticated user', async function () {
137       await makePostBodyRequest({
138         url: server.url,
139         path,
140         token: 'super token',
141         fields: baseCorrectParams,
142         statusCodeExpected: 401
143       })
144     })
145
146     it('Should fail if we add a user with the same username', async function () {
147       const fields = immutableAssign(baseCorrectParams, { username: 'user1' })
148
149       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 409 })
150     })
151
152     it('Should fail if we add a user with the same email', async function () {
153       const fields = immutableAssign(baseCorrectParams, { email: 'user1@example.com' })
154
155       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 409 })
156     })
157
158     it('Should fail without a videoQuota', async function () {
159       const fields = omit(baseCorrectParams, 'videoQuota')
160
161       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
162     })
163
164     it('Should fail with an invalid videoQuota', async function () {
165       const fields = immutableAssign(baseCorrectParams, { videoQuota: -5 })
166
167       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
168     })
169
170     it('Should fail without a user role', async function () {
171       const fields = omit(baseCorrectParams, 'role')
172
173       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
174     })
175
176     it('Should fail with an invalid user role', async function () {
177       const fields = immutableAssign(baseCorrectParams, { role: 88989 })
178
179       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
180     })
181
182     it('Should fail with a "peertube" username', async function () {
183       const fields = immutableAssign(baseCorrectParams, { username: 'peertube' })
184
185       await makePostBodyRequest({
186         url: server.url,
187         path,
188         token: server.accessToken,
189         fields,
190         statusCodeExpected: 409
191       })
192     })
193
194     it('Should succeed with the correct params', async function () {
195       await makePostBodyRequest({
196         url: server.url,
197         path,
198         token: server.accessToken,
199         fields: baseCorrectParams,
200         statusCodeExpected: 200
201       })
202     })
203
204     it('Should fail with a non admin user', async function () {
205       const user = {
206         username: 'user1',
207         password: 'my super password'
208       }
209       userAccessToken = await userLogin(server, user)
210
211       const fields = {
212         username: 'user3',
213         email: 'test@example.com',
214         password: 'my super password',
215         videoQuota: 42000000
216       }
217       await makePostBodyRequest({ url: server.url, path, token: userAccessToken, fields, statusCodeExpected: 403 })
218     })
219   })
220
221   describe('When updating my account', function () {
222     it('Should fail with an invalid email attribute', async function () {
223       const fields = {
224         email: 'blabla'
225       }
226
227       await makePutBodyRequest({ url: server.url, path: path + 'me', token: server.accessToken, fields })
228     })
229
230     it('Should fail with a too small password', async function () {
231       const fields = {
232         password: 'bla'
233       }
234
235       await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
236     })
237
238     it('Should fail with a too long password', async function () {
239       const fields = {
240         password: 'super'.repeat(61)
241       }
242
243       await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
244     })
245
246     it('Should fail with an invalid NSFW policy attribute', async function () {
247       const fields = {
248         nsfwPolicy: 'hello'
249       }
250
251       await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
252     })
253
254     it('Should fail with an invalid autoPlayVideo attribute', async function () {
255       const fields = {
256         autoPlayVideo: -1
257       }
258
259       await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
260     })
261
262     it('Should fail with an non authenticated user', async function () {
263       const fields = {
264         password: 'my super password'
265       }
266
267       await makePutBodyRequest({ url: server.url, path: path + 'me', token: 'super token', fields, statusCodeExpected: 401 })
268     })
269
270     it('Should fail with a too long description', async function () {
271       const fields = {
272         description: 'super'.repeat(60)
273       }
274
275       await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
276     })
277
278     it('Should succeed with the correct params', async function () {
279       const fields = {
280         password: 'my super password',
281         nsfwPolicy: 'blur',
282         autoPlayVideo: false,
283         email: 'super_email@example.com'
284       }
285
286       await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields, statusCodeExpected: 204 })
287     })
288   })
289
290   describe('When updating my avatar', function () {
291     it('Should fail without an incorrect input file', async function () {
292       const fields = {}
293       const attaches = {
294         'avatarfile': join(__dirname, '..', '..', 'fixtures', 'video_short.mp4')
295       }
296       await makeUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches })
297     })
298
299     it('Should fail with a big file', async function () {
300       const fields = {}
301       const attaches = {
302         'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar-big.png')
303       }
304       await makeUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches })
305     })
306
307     it('Should fail with an unauthenticated user', async function () {
308       const fields = {}
309       const attaches = {
310         'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png')
311       }
312       await makeUploadRequest({
313         url: server.url,
314         path: path + '/me/avatar/pick',
315         fields,
316         attaches,
317         statusCodeExpected: 401
318       })
319     })
320
321     it('Should succeed with the correct params', async function () {
322       const fields = {}
323       const attaches = {
324         'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png')
325       }
326       await makeUploadRequest({
327         url: server.url,
328         path: path + '/me/avatar/pick',
329         token: server.accessToken,
330         fields,
331         attaches,
332         statusCodeExpected: 200
333       })
334     })
335   })
336
337   describe('When getting a user', function () {
338     before(async function () {
339       const res = await getUsersList(server.url, server.accessToken)
340
341       userId = res.body.data[1].id
342     })
343
344     it('Should fail with an non authenticated user', async function () {
345       await makeGetRequest({ url: server.url, path: path + userId, token: 'super token', statusCodeExpected: 401 })
346     })
347
348     it('Should fail with a non admin user', async function () {
349       await makeGetRequest({ url: server.url, path, token: userAccessToken, statusCodeExpected: 403 })
350     })
351
352     it('Should succeed with the correct params', async function () {
353       await makeGetRequest({ url: server.url, path: path + userId, token: server.accessToken, statusCodeExpected: 200 })
354     })
355   })
356
357   describe('When updating a user', function () {
358
359     before(async function () {
360       const res = await getUsersList(server.url, server.accessToken)
361
362       userId = res.body.data[1].id
363       rootId = res.body.data[2].id
364     })
365
366     it('Should fail with an invalid email attribute', async function () {
367       const fields = {
368         email: 'blabla'
369       }
370
371       await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
372     })
373
374     it('Should fail with an invalid videoQuota attribute', async function () {
375       const fields = {
376         videoQuota: -90
377       }
378
379       await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
380     })
381
382     it('Should fail with an invalid user role attribute', async function () {
383       const fields = {
384         role: 54878
385       }
386
387       await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
388     })
389
390     it('Should fail with an non authenticated user', async function () {
391       const fields = {
392         videoQuota: 42
393       }
394
395       await makePutBodyRequest({ url: server.url, path: path + userId, token: 'super token', fields, statusCodeExpected: 401 })
396     })
397
398     it('Should fail when updating root role', async function () {
399       const fields = {
400         role: UserRole.MODERATOR
401       }
402
403       await makePutBodyRequest({ url: server.url, path: path + rootId, token: server.accessToken, fields })
404     })
405
406     it('Should succeed with the correct params', async function () {
407       const fields = {
408         email: 'email@example.com',
409         videoQuota: 42,
410         role: UserRole.MODERATOR
411       }
412
413       await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields, statusCodeExpected: 204 })
414       userAccessToken = await userLogin(server, user)
415     })
416   })
417
418   describe('When getting my information', function () {
419     it('Should fail with a non authenticated user', async function () {
420       await getMyUserInformation(server.url, 'fake_token', 401)
421     })
422
423     it('Should success with the correct parameters', async function () {
424       await getMyUserInformation(server.url, userAccessToken)
425     })
426   })
427
428   describe('When getting my video rating', function () {
429     it('Should fail with a non authenticated user', async function () {
430       await getMyUserVideoRating(server.url, 'fake_token', videoId, 401)
431     })
432
433     it('Should fail with an incorrect video uuid', async function () {
434       await getMyUserVideoRating(server.url, server.accessToken, 'blabla', 400)
435     })
436
437     it('Should fail with an unknown video', async function () {
438       await getMyUserVideoRating(server.url, server.accessToken, '4da6fde3-88f7-4d16-b119-108df5630b06', 404)
439     })
440
441     it('Should succeed with the correct parameters', async function () {
442       await getMyUserVideoRating(server.url, server.accessToken, videoId)
443     })
444   })
445
446   describe('When removing an user', function () {
447     it('Should fail with an incorrect id', async function () {
448       await removeUser(server.url, 'blabla', server.accessToken, 400)
449     })
450
451     it('Should fail with the root user', async function () {
452       await removeUser(server.url, rootId, server.accessToken, 400)
453     })
454
455     it('Should return 404 with a non existing id', async function () {
456       await removeUser(server.url, 4545454, server.accessToken, 404)
457     })
458   })
459
460   describe('When register a new user', function () {
461     const registrationPath = path + '/register'
462     const baseCorrectParams = {
463       username: 'user3',
464       email: 'test3@example.com',
465       password: 'my super password'
466     }
467
468     it('Should fail with a too small username', async function () {
469       const fields = immutableAssign(baseCorrectParams, { username: 'ji' })
470
471       await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
472     })
473
474     it('Should fail with a too long username', async function () {
475       const fields = immutableAssign(baseCorrectParams, { username: 'my_super_username_which_is_very_long' })
476
477       await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
478     })
479
480     it('Should fail with an incorrect username', async function () {
481       const fields = immutableAssign(baseCorrectParams, { username: 'my username' })
482
483       await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
484     })
485
486     it('Should fail with a missing email', async function () {
487       const fields = omit(baseCorrectParams, 'email')
488
489       await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
490     })
491
492     it('Should fail with an invalid email', async function () {
493       const fields = immutableAssign(baseCorrectParams, { email: 'test_example.com' })
494
495       await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
496     })
497
498     it('Should fail with a too small password', async function () {
499       const fields = immutableAssign(baseCorrectParams, { password: 'bla' })
500
501       await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
502     })
503
504     it('Should fail with a too long password', async function () {
505       const fields = immutableAssign(baseCorrectParams, { password: 'super'.repeat(61) })
506
507       await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
508     })
509
510     it('Should fail if we register a user with the same username', async function () {
511       const fields = immutableAssign(baseCorrectParams, { username: 'root' })
512
513       await makePostBodyRequest({
514         url: server.url,
515         path: registrationPath,
516         token: server.accessToken,
517         fields,
518         statusCodeExpected: 409
519       })
520     })
521
522     it('Should fail with a "peertube" username', async function () {
523       const fields = immutableAssign(baseCorrectParams, { username: 'peertube' })
524
525       await makePostBodyRequest({
526         url: server.url,
527         path: registrationPath,
528         token: server.accessToken,
529         fields,
530         statusCodeExpected: 409
531       })
532     })
533
534     it('Should fail if we register a user with the same email', async function () {
535       const fields = immutableAssign(baseCorrectParams, { email: 'admin1@example.com' })
536
537       await makePostBodyRequest({
538         url: server.url,
539         path: registrationPath,
540         token: server.accessToken,
541         fields,
542         statusCodeExpected: 409
543       })
544     })
545
546     it('Should succeed with the correct params', async function () {
547       await makePostBodyRequest({
548         url: server.url,
549         path: registrationPath,
550         token: server.accessToken,
551         fields: baseCorrectParams,
552         statusCodeExpected: 204
553       })
554     })
555
556     it('Should fail on a server with registration disabled', async function () {
557       const fields = {
558         username: 'user4',
559         email: 'test4@example.com',
560         password: 'my super password 4'
561       }
562
563       await makePostBodyRequest({
564         url: serverWithRegistrationDisabled.url,
565         path: registrationPath,
566         token: serverWithRegistrationDisabled.accessToken,
567         fields,
568         statusCodeExpected: 403
569       })
570     })
571   })
572
573   describe('When registering multiple users on a server with users limit', function () {
574     it('Should fail when after 3 registrations', async function () {
575       await registerUser(server.url, 'user42', 'super password', 403)
576     })
577   })
578
579   describe('When having a video quota', function () {
580     it('Should fail with a user having too many video', async function () {
581       await updateUser({
582         url: server.url,
583         userId: rootId,
584         accessToken: server.accessToken,
585         videoQuota: 42
586       })
587
588       await uploadVideo(server.url, server.accessToken, {}, 403)
589     })
590
591     it('Should fail with a registered user having too many video', async function () {
592       this.timeout(30000)
593
594       const user = {
595         username: 'user3',
596         password: 'my super password'
597       }
598       userAccessToken = await userLogin(server, user)
599
600       const videoAttributes = { fixture: 'video_short2.webm' }
601       await uploadVideo(server.url, userAccessToken, videoAttributes)
602       await uploadVideo(server.url, userAccessToken, videoAttributes)
603       await uploadVideo(server.url, userAccessToken, videoAttributes)
604       await uploadVideo(server.url, userAccessToken, videoAttributes)
605       await uploadVideo(server.url, userAccessToken, videoAttributes)
606       await uploadVideo(server.url, userAccessToken, videoAttributes, 403)
607     })
608   })
609
610   describe('When asking a password reset', function () {
611     const path = '/api/v1/users/ask-reset-password'
612
613     it('Should fail with a missing email', async function () {
614       const fields = {}
615
616       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
617     })
618
619     it('Should fail with an invalid email', async function () {
620       const fields = { email: 'hello' }
621
622       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
623     })
624
625     it('Should success with the correct params', async function () {
626       const fields = { email: 'admin@example.com' }
627
628       await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 })
629     })
630   })
631
632   after(async function () {
633     killallServers([ server, serverWithRegistrationDisabled ])
634
635     // Keep the logs if the test failed
636     if (this['ok']) {
637       await flushTests()
638     }
639   })
640 })