1 /* tslint:disable:no-unused-expression */
3 import { omit } from 'lodash'
5 import { join } from 'path'
6 import { UserRole, VideoImport, VideoImportState } from '../../../../shared'
9 createUser, flushTests, getMyUserInformation, getMyUserVideoRating, getUsersList, immutableAssign, killallServers, makeGetRequest,
10 makePostBodyRequest, makeUploadRequest, makePutBodyRequest, registerUser, removeUser, runServer, ServerInfo, setAccessTokensToServers,
11 updateUser, uploadVideo, userLogin, deleteMe, unblockUser, blockUser
12 } from '../../../../shared/utils'
14 checkBadCountPagination,
15 checkBadSortPagination,
16 checkBadStartPagination
17 } from '../../../../shared/utils/requests/check-api-params'
18 import { getMagnetURI, getMyVideoImports, getYoutubeVideoUrl, importVideo } from '../../../../shared/utils/videos/video-imports'
19 import { VideoPrivacy } from '../../../../shared/models/videos'
20 import { waitJobs } from '../../../../shared/utils/server/jobs'
21 import { expect } from 'chai'
23 describe('Test users API validators', function () {
24 const path = '/api/v1/users/'
28 let server: ServerInfo
29 let serverWithRegistrationDisabled: ServerInfo
30 let userAccessToken = ''
34 password: 'my super password'
37 // ---------------------------------------------------------------
39 before(async function () {
44 server = await runServer(1)
45 serverWithRegistrationDisabled = await runServer(2)
47 await setAccessTokensToServers([ server ])
49 const videoQuota = 42000000
50 await createUser(server.url, server.accessToken, user.username, user.password, videoQuota)
51 userAccessToken = await userLogin(server, user)
54 const res = await getMyUserInformation(server.url, server.accessToken)
55 channelId = res.body.videoChannels[ 0 ].id
59 const res = await uploadVideo(server.url, server.accessToken, {})
60 videoId = res.body.video.id
64 describe('When listing users', function () {
65 it('Should fail with a bad start pagination', async function () {
66 await checkBadStartPagination(server.url, path, server.accessToken)
69 it('Should fail with a bad count pagination', async function () {
70 await checkBadCountPagination(server.url, path, server.accessToken)
73 it('Should fail with an incorrect sort', async function () {
74 await checkBadSortPagination(server.url, path, server.accessToken)
77 it('Should fail with a non authenticated user', async function () {
78 await makeGetRequest({
81 statusCodeExpected: 401
85 it('Should fail with a non admin user', async function () {
86 await makeGetRequest({
89 token: userAccessToken,
90 statusCodeExpected: 403
95 describe('When adding a new user', function () {
96 const baseCorrectParams = {
98 email: 'test@example.com',
99 password: 'my super password',
105 it('Should fail with a too small username', async function () {
106 const fields = immutableAssign(baseCorrectParams, { username: '' })
108 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
111 it('Should fail with a too long username', async function () {
112 const fields = immutableAssign(baseCorrectParams, { username: 'super'.repeat(50) })
114 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
117 it('Should fail with a not lowercase username', async function () {
118 const fields = immutableAssign(baseCorrectParams, { username: 'Toto' })
120 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
123 it('Should fail with an incorrect username', async function () {
124 const fields = immutableAssign(baseCorrectParams, { username: 'my username' })
126 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
129 it('Should fail with a missing email', async function () {
130 const fields = omit(baseCorrectParams, 'email')
132 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
135 it('Should fail with an invalid email', async function () {
136 const fields = immutableAssign(baseCorrectParams, { email: 'test_example.com' })
138 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
141 it('Should fail with a too small password', async function () {
142 const fields = immutableAssign(baseCorrectParams, { password: 'bla' })
144 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
147 it('Should fail with a too long password', async function () {
148 const fields = immutableAssign(baseCorrectParams, { password: 'super'.repeat(61) })
150 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
153 it('Should fail with an non authenticated user', async function () {
154 await makePostBodyRequest({
157 token: 'super token',
158 fields: baseCorrectParams,
159 statusCodeExpected: 401
163 it('Should fail if we add a user with the same username', async function () {
164 const fields = immutableAssign(baseCorrectParams, { username: 'user1' })
166 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 409 })
169 it('Should fail if we add a user with the same email', async function () {
170 const fields = immutableAssign(baseCorrectParams, { email: 'user1@example.com' })
172 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 409 })
175 it('Should fail without a videoQuota', async function () {
176 const fields = omit(baseCorrectParams, 'videoQuota')
178 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
181 it('Should fail without a videoQuotaDaily', async function () {
182 const fields = omit(baseCorrectParams, 'videoQuotaDaily')
184 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
187 it('Should fail with an invalid videoQuota', async function () {
188 const fields = immutableAssign(baseCorrectParams, { videoQuota: -5 })
190 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
193 it('Should fail with an invalid videoQuotaDaily', async function () {
194 const fields = immutableAssign(baseCorrectParams, { videoQuotaDaily: -7 })
196 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
199 it('Should fail without a user role', async function () {
200 const fields = omit(baseCorrectParams, 'role')
202 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
205 it('Should fail with an invalid user role', async function () {
206 const fields = immutableAssign(baseCorrectParams, { role: 88989 })
208 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
211 it('Should fail with a "peertube" username', async function () {
212 const fields = immutableAssign(baseCorrectParams, { username: 'peertube' })
214 await makePostBodyRequest({
217 token: server.accessToken,
219 statusCodeExpected: 409
223 it('Should succeed with the correct params', async function () {
224 await makePostBodyRequest({
227 token: server.accessToken,
228 fields: baseCorrectParams,
229 statusCodeExpected: 200
233 it('Should fail with a non admin user', async function () {
236 password: 'my super password'
238 userAccessToken = await userLogin(server, user)
242 email: 'test@example.com',
243 password: 'my super password',
246 await makePostBodyRequest({ url: server.url, path, token: userAccessToken, fields, statusCodeExpected: 403 })
250 describe('When updating my account', function () {
251 it('Should fail with an invalid email attribute', async function () {
256 await makePutBodyRequest({ url: server.url, path: path + 'me', token: server.accessToken, fields })
259 it('Should fail with a too small password', async function () {
261 currentPassword: 'my super password',
265 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
268 it('Should fail with a too long password', async function () {
270 currentPassword: 'my super password',
271 password: 'super'.repeat(61)
274 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
277 it('Should fail without the current password', async function () {
279 currentPassword: 'my super password',
280 password: 'super'.repeat(61)
283 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
286 it('Should fail with an invalid current password', async function () {
288 currentPassword: 'my super password fail',
289 password: 'super'.repeat(61)
292 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields, statusCodeExpected: 401 })
295 it('Should fail with an invalid NSFW policy attribute', async function () {
300 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
303 it('Should fail with an invalid autoPlayVideo attribute', async function () {
308 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
311 it('Should fail with an non authenticated user', async function () {
313 currentPassword: 'my super password',
314 password: 'my super password'
317 await makePutBodyRequest({ url: server.url, path: path + 'me', token: 'super token', fields, statusCodeExpected: 401 })
320 it('Should fail with a too long description', async function () {
322 description: 'super'.repeat(201)
325 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
328 it('Should succeed to change password with the correct params', async function () {
330 currentPassword: 'my super password',
331 password: 'my super password',
333 autoPlayVideo: false,
334 email: 'super_email@example.com'
337 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields, statusCodeExpected: 204 })
340 it('Should succeed without password change with the correct params', async function () {
343 autoPlayVideo: false,
344 email: 'super_email@example.com'
347 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields, statusCodeExpected: 204 })
351 describe('When updating my avatar', function () {
352 it('Should fail without an incorrect input file', async function () {
355 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'video_short.mp4')
357 await makeUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches })
360 it('Should fail with a big file', async function () {
363 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar-big.png')
365 await makeUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches })
368 it('Should fail with an unauthenticated user', async function () {
371 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png')
373 await makeUploadRequest({
375 path: path + '/me/avatar/pick',
378 statusCodeExpected: 401
382 it('Should succeed with the correct params', async function () {
385 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png')
387 await makeUploadRequest({
389 path: path + '/me/avatar/pick',
390 token: server.accessToken,
393 statusCodeExpected: 200
398 describe('When getting a user', function () {
399 before(async function () {
400 const res = await getUsersList(server.url, server.accessToken)
402 userId = res.body.data[1].id
405 it('Should fail with an non authenticated user', async function () {
406 await makeGetRequest({ url: server.url, path: path + userId, token: 'super token', statusCodeExpected: 401 })
409 it('Should fail with a non admin user', async function () {
410 await makeGetRequest({ url: server.url, path, token: userAccessToken, statusCodeExpected: 403 })
413 it('Should succeed with the correct params', async function () {
414 await makeGetRequest({ url: server.url, path: path + userId, token: server.accessToken, statusCodeExpected: 200 })
418 describe('When updating a user', function () {
420 before(async function () {
421 const res = await getUsersList(server.url, server.accessToken)
423 userId = res.body.data[1].id
424 rootId = res.body.data[2].id
427 it('Should fail with an invalid email attribute', async function () {
432 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
435 it('Should fail with an invalid emailVerified attribute', async function () {
440 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
443 it('Should fail with an invalid videoQuota attribute', async function () {
448 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
451 it('Should fail with an invalid user role attribute', async function () {
456 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
459 it('Should fail with an non authenticated user', async function () {
464 await makePutBodyRequest({ url: server.url, path: path + userId, token: 'super token', fields, statusCodeExpected: 401 })
467 it('Should fail when updating root role', async function () {
469 role: UserRole.MODERATOR
472 await makePutBodyRequest({ url: server.url, path: path + rootId, token: server.accessToken, fields })
475 it('Should succeed with the correct params', async function () {
477 email: 'email@example.com',
480 role: UserRole.MODERATOR
483 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields, statusCodeExpected: 204 })
484 userAccessToken = await userLogin(server, user)
488 describe('When getting my information', function () {
489 it('Should fail with a non authenticated user', async function () {
490 await getMyUserInformation(server.url, 'fake_token', 401)
493 it('Should success with the correct parameters', async function () {
494 await getMyUserInformation(server.url, userAccessToken)
498 describe('When getting my video rating', function () {
499 it('Should fail with a non authenticated user', async function () {
500 await getMyUserVideoRating(server.url, 'fake_token', videoId, 401)
503 it('Should fail with an incorrect video uuid', async function () {
504 await getMyUserVideoRating(server.url, server.accessToken, 'blabla', 400)
507 it('Should fail with an unknown video', async function () {
508 await getMyUserVideoRating(server.url, server.accessToken, '4da6fde3-88f7-4d16-b119-108df5630b06', 404)
511 it('Should succeed with the correct parameters', async function () {
512 await getMyUserVideoRating(server.url, server.accessToken, videoId)
516 describe('When blocking/unblocking/removing user', function () {
517 it('Should fail with an incorrect id', async function () {
518 await removeUser(server.url, 'blabla', server.accessToken, 400)
519 await blockUser(server.url, 'blabla', server.accessToken, 400)
520 await unblockUser(server.url, 'blabla', server.accessToken, 400)
523 it('Should fail with the root user', async function () {
524 await removeUser(server.url, rootId, server.accessToken, 400)
525 await blockUser(server.url, rootId, server.accessToken, 400)
526 await unblockUser(server.url, rootId, server.accessToken, 400)
529 it('Should return 404 with a non existing id', async function () {
530 await removeUser(server.url, 4545454, server.accessToken, 404)
531 await blockUser(server.url, 4545454, server.accessToken, 404)
532 await unblockUser(server.url, 4545454, server.accessToken, 404)
535 it('Should fail with a non admin user', async function () {
536 await removeUser(server.url, userId, userAccessToken, 403)
537 await blockUser(server.url, userId, userAccessToken, 403)
538 await unblockUser(server.url, userId, userAccessToken, 403)
542 describe('When deleting our account', function () {
543 it('Should fail with with the root account', async function () {
544 await deleteMe(server.url, server.accessToken, 400)
548 describe('When register a new user', function () {
549 const registrationPath = path + '/register'
550 const baseCorrectParams = {
552 email: 'test3@example.com',
553 password: 'my super password'
556 it('Should fail with a too small username', async function () {
557 const fields = immutableAssign(baseCorrectParams, { username: '' })
559 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
562 it('Should fail with a too long username', async function () {
563 const fields = immutableAssign(baseCorrectParams, { username: 'super'.repeat(50) })
565 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
568 it('Should fail with an incorrect username', async function () {
569 const fields = immutableAssign(baseCorrectParams, { username: 'my username' })
571 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
574 it('Should fail with a missing email', async function () {
575 const fields = omit(baseCorrectParams, 'email')
577 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
580 it('Should fail with an invalid email', async function () {
581 const fields = immutableAssign(baseCorrectParams, { email: 'test_example.com' })
583 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
586 it('Should fail with a too small password', async function () {
587 const fields = immutableAssign(baseCorrectParams, { password: 'bla' })
589 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
592 it('Should fail with a too long password', async function () {
593 const fields = immutableAssign(baseCorrectParams, { password: 'super'.repeat(61) })
595 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
598 it('Should fail if we register a user with the same username', async function () {
599 const fields = immutableAssign(baseCorrectParams, { username: 'root' })
601 await makePostBodyRequest({
603 path: registrationPath,
604 token: server.accessToken,
606 statusCodeExpected: 409
610 it('Should fail with a "peertube" username', async function () {
611 const fields = immutableAssign(baseCorrectParams, { username: 'peertube' })
613 await makePostBodyRequest({
615 path: registrationPath,
616 token: server.accessToken,
618 statusCodeExpected: 409
622 it('Should fail if we register a user with the same email', async function () {
623 const fields = immutableAssign(baseCorrectParams, { email: 'admin1@example.com' })
625 await makePostBodyRequest({
627 path: registrationPath,
628 token: server.accessToken,
630 statusCodeExpected: 409
634 it('Should succeed with the correct params', async function () {
635 await makePostBodyRequest({
637 path: registrationPath,
638 token: server.accessToken,
639 fields: baseCorrectParams,
640 statusCodeExpected: 204
644 it('Should fail on a server with registration disabled', async function () {
647 email: 'test4@example.com',
648 password: 'my super password 4'
651 await makePostBodyRequest({
652 url: serverWithRegistrationDisabled.url,
653 path: registrationPath,
654 token: serverWithRegistrationDisabled.accessToken,
656 statusCodeExpected: 403
661 describe('When registering multiple users on a server with users limit', function () {
662 it('Should fail when after 3 registrations', async function () {
663 await registerUser(server.url, 'user42', 'super password', 403)
667 describe('When having a video quota', function () {
668 it('Should fail with a user having too many videos', async function () {
672 accessToken: server.accessToken,
676 await uploadVideo(server.url, server.accessToken, {}, 403)
679 it('Should fail with a registered user having too many videos', async function () {
684 password: 'my super password'
686 userAccessToken = await userLogin(server, user)
688 const videoAttributes = { fixture: 'video_short2.webm' }
689 await uploadVideo(server.url, userAccessToken, videoAttributes)
690 await uploadVideo(server.url, userAccessToken, videoAttributes)
691 await uploadVideo(server.url, userAccessToken, videoAttributes)
692 await uploadVideo(server.url, userAccessToken, videoAttributes)
693 await uploadVideo(server.url, userAccessToken, videoAttributes)
694 await uploadVideo(server.url, userAccessToken, videoAttributes, 403)
697 it('Should fail to import with HTTP/Torrent/magnet', async function () {
700 const baseAttributes = {
702 privacy: VideoPrivacy.PUBLIC
704 await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { targetUrl: getYoutubeVideoUrl() }))
705 await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { magnetUri: getMagnetURI() }))
706 await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { torrentfile: 'video-720p.torrent' }))
708 await waitJobs([ server ])
710 const res = await getMyVideoImports(server.url, server.accessToken)
712 expect(res.body.total).to.equal(3)
713 const videoImports: VideoImport[] = res.body.data
714 expect(videoImports).to.have.lengthOf(3)
716 for (const videoImport of videoImports) {
717 expect(videoImport.state.id).to.equal(VideoImportState.FAILED)
718 expect(videoImport.error).not.to.be.undefined
719 expect(videoImport.error).to.contain('user video quota is exceeded')
724 describe('When having a daily video quota', function () {
725 it('Should fail with a user having too many videos', async function () {
729 accessToken: server.accessToken,
733 await uploadVideo(server.url, server.accessToken, {}, 403)
737 describe('When having an absolute and daily video quota', function () {
738 it('Should fail if exceeding total quota', async function () {
742 accessToken: server.accessToken,
744 videoQuotaDaily: 1024 * 1024 * 1024
747 await uploadVideo(server.url, server.accessToken, {}, 403)
750 it('Should fail if exceeding daily quota', async function () {
754 accessToken: server.accessToken,
755 videoQuota: 1024 * 1024 * 1024,
759 await uploadVideo(server.url, server.accessToken, {}, 403)
763 describe('When asking a password reset', function () {
764 const path = '/api/v1/users/ask-reset-password'
766 it('Should fail with a missing email', async function () {
769 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
772 it('Should fail with an invalid email', async function () {
773 const fields = { email: 'hello' }
775 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
778 it('Should success with the correct params', async function () {
779 const fields = { email: 'admin@example.com' }
781 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 })
785 describe('When asking for an account verification email', function () {
786 const path = '/api/v1/users/ask-send-verify-email'
788 it('Should fail with a missing email', async function () {
791 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
794 it('Should fail with an invalid email', async function () {
795 const fields = { email: 'hello' }
797 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
800 it('Should succeed with the correct params', async function () {
801 const fields = { email: 'admin@example.com' }
803 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 })
807 after(async function () {
808 killallServers([ server, serverWithRegistrationDisabled ])
810 // Keep the logs if the test failed