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
13 import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
14 import { getMagnetURI, getMyVideoImports, getYoutubeVideoUrl, importVideo } from '../../utils/videos/video-imports'
15 import { VideoPrivacy } from '../../../../shared/models/videos'
16 import { waitJobs } from '../../utils/server/jobs'
17 import { expect } from 'chai'
19 describe('Test users API validators', function () {
20 const path = '/api/v1/users/'
24 let server: ServerInfo
25 let serverWithRegistrationDisabled: ServerInfo
26 let userAccessToken = ''
30 password: 'my super password'
33 // ---------------------------------------------------------------
35 before(async function () {
40 server = await runServer(1)
41 serverWithRegistrationDisabled = await runServer(2)
43 await setAccessTokensToServers([ server ])
45 const videoQuota = 42000000
46 await createUser(server.url, server.accessToken, user.username, user.password, videoQuota)
47 userAccessToken = await userLogin(server, user)
50 const res = await getMyUserInformation(server.url, server.accessToken)
51 channelId = res.body.videoChannels[ 0 ].id
55 const res = await uploadVideo(server.url, server.accessToken, {})
56 videoId = res.body.video.id
60 describe('When listing users', function () {
61 it('Should fail with a bad start pagination', async function () {
62 await checkBadStartPagination(server.url, path, server.accessToken)
65 it('Should fail with a bad count pagination', async function () {
66 await checkBadCountPagination(server.url, path, server.accessToken)
69 it('Should fail with an incorrect sort', async function () {
70 await checkBadSortPagination(server.url, path, server.accessToken)
73 it('Should fail with a non authenticated user', async function () {
74 await makeGetRequest({
77 statusCodeExpected: 401
81 it('Should fail with a non admin user', async function () {
82 await makeGetRequest({
85 token: userAccessToken,
86 statusCodeExpected: 403
91 describe('When adding a new user', function () {
92 const baseCorrectParams = {
94 email: 'test@example.com',
95 password: 'my super password',
101 it('Should fail with a too small username', async function () {
102 const fields = immutableAssign(baseCorrectParams, { username: '' })
104 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
107 it('Should fail with a too long username', async function () {
108 const fields = immutableAssign(baseCorrectParams, { username: 'super'.repeat(11) })
110 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
113 it('Should fail with a not lowercase username', async function () {
114 const fields = immutableAssign(baseCorrectParams, { username: 'Toto' })
116 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
119 it('Should fail with an incorrect username', async function () {
120 const fields = immutableAssign(baseCorrectParams, { username: 'my username' })
122 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
125 it('Should fail with a missing email', async function () {
126 const fields = omit(baseCorrectParams, 'email')
128 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
131 it('Should fail with an invalid email', async function () {
132 const fields = immutableAssign(baseCorrectParams, { email: 'test_example.com' })
134 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
137 it('Should fail with a too small password', async function () {
138 const fields = immutableAssign(baseCorrectParams, { password: 'bla' })
140 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
143 it('Should fail with a too long password', async function () {
144 const fields = immutableAssign(baseCorrectParams, { password: 'super'.repeat(61) })
146 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
149 it('Should fail with an non authenticated user', async function () {
150 await makePostBodyRequest({
153 token: 'super token',
154 fields: baseCorrectParams,
155 statusCodeExpected: 401
159 it('Should fail if we add a user with the same username', async function () {
160 const fields = immutableAssign(baseCorrectParams, { username: 'user1' })
162 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 409 })
165 it('Should fail if we add a user with the same email', async function () {
166 const fields = immutableAssign(baseCorrectParams, { email: 'user1@example.com' })
168 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 409 })
171 it('Should fail without a videoQuota', async function () {
172 const fields = omit(baseCorrectParams, 'videoQuota')
174 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
177 it('Should fail without a videoQuotaDaily', async function () {
178 const fields = omit(baseCorrectParams, 'videoQuotaDaily')
180 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
183 it('Should fail with an invalid videoQuota', async function () {
184 const fields = immutableAssign(baseCorrectParams, { videoQuota: -5 })
186 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
189 it('Should fail with an invalid videoQuotaDaily', async function () {
190 const fields = immutableAssign(baseCorrectParams, { videoQuotaDaily: -7 })
192 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
195 it('Should fail without a user role', async function () {
196 const fields = omit(baseCorrectParams, 'role')
198 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
201 it('Should fail with an invalid user role', async function () {
202 const fields = immutableAssign(baseCorrectParams, { role: 88989 })
204 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
207 it('Should fail with a "peertube" username', async function () {
208 const fields = immutableAssign(baseCorrectParams, { username: 'peertube' })
210 await makePostBodyRequest({
213 token: server.accessToken,
215 statusCodeExpected: 409
219 it('Should succeed with the correct params', async function () {
220 await makePostBodyRequest({
223 token: server.accessToken,
224 fields: baseCorrectParams,
225 statusCodeExpected: 200
229 it('Should fail with a non admin user', async function () {
232 password: 'my super password'
234 userAccessToken = await userLogin(server, user)
238 email: 'test@example.com',
239 password: 'my super password',
242 await makePostBodyRequest({ url: server.url, path, token: userAccessToken, fields, statusCodeExpected: 403 })
246 describe('When updating my account', function () {
247 it('Should fail with an invalid email attribute', async function () {
252 await makePutBodyRequest({ url: server.url, path: path + 'me', token: server.accessToken, fields })
255 it('Should fail with a too small password', async function () {
257 currentPassword: 'my super password',
261 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
264 it('Should fail with a too long password', async function () {
266 currentPassword: 'my super password',
267 password: 'super'.repeat(61)
270 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
273 it('Should fail without the current password', async function () {
275 currentPassword: 'my super password',
276 password: 'super'.repeat(61)
279 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
282 it('Should fail with an invalid current password', async function () {
284 currentPassword: 'my super password fail',
285 password: 'super'.repeat(61)
288 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields, statusCodeExpected: 401 })
291 it('Should fail with an invalid NSFW policy attribute', async function () {
296 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
299 it('Should fail with an invalid autoPlayVideo attribute', async function () {
304 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
307 it('Should fail with an non authenticated user', async function () {
309 currentPassword: 'my super password',
310 password: 'my super password'
313 await makePutBodyRequest({ url: server.url, path: path + 'me', token: 'super token', fields, statusCodeExpected: 401 })
316 it('Should fail with a too long description', async function () {
318 description: 'super'.repeat(201)
321 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
324 it('Should succeed to change password with the correct params', async function () {
326 currentPassword: 'my super password',
327 password: 'my super password',
329 autoPlayVideo: false,
330 email: 'super_email@example.com'
333 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields, statusCodeExpected: 204 })
336 it('Should succeed without password change with the correct params', async function () {
339 autoPlayVideo: false,
340 email: 'super_email@example.com'
343 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields, statusCodeExpected: 204 })
347 describe('When updating my avatar', function () {
348 it('Should fail without an incorrect input file', async function () {
351 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'video_short.mp4')
353 await makeUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches })
356 it('Should fail with a big file', async function () {
359 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar-big.png')
361 await makeUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches })
364 it('Should fail with an unauthenticated user', async function () {
367 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png')
369 await makeUploadRequest({
371 path: path + '/me/avatar/pick',
374 statusCodeExpected: 401
378 it('Should succeed with the correct params', async function () {
381 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png')
383 await makeUploadRequest({
385 path: path + '/me/avatar/pick',
386 token: server.accessToken,
389 statusCodeExpected: 200
394 describe('When getting a user', function () {
395 before(async function () {
396 const res = await getUsersList(server.url, server.accessToken)
398 userId = res.body.data[1].id
401 it('Should fail with an non authenticated user', async function () {
402 await makeGetRequest({ url: server.url, path: path + userId, token: 'super token', statusCodeExpected: 401 })
405 it('Should fail with a non admin user', async function () {
406 await makeGetRequest({ url: server.url, path, token: userAccessToken, statusCodeExpected: 403 })
409 it('Should succeed with the correct params', async function () {
410 await makeGetRequest({ url: server.url, path: path + userId, token: server.accessToken, statusCodeExpected: 200 })
414 describe('When updating a user', function () {
416 before(async function () {
417 const res = await getUsersList(server.url, server.accessToken)
419 userId = res.body.data[1].id
420 rootId = res.body.data[2].id
423 it('Should fail with an invalid email attribute', async function () {
428 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
431 it('Should fail with an invalid emailVerified attribute', async function () {
436 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
439 it('Should fail with an invalid videoQuota attribute', async function () {
444 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
447 it('Should fail with an invalid user role attribute', async function () {
452 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
455 it('Should fail with an non authenticated user', async function () {
460 await makePutBodyRequest({ url: server.url, path: path + userId, token: 'super token', fields, statusCodeExpected: 401 })
463 it('Should fail when updating root role', async function () {
465 role: UserRole.MODERATOR
468 await makePutBodyRequest({ url: server.url, path: path + rootId, token: server.accessToken, fields })
471 it('Should succeed with the correct params', async function () {
473 email: 'email@example.com',
476 role: UserRole.MODERATOR
479 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields, statusCodeExpected: 204 })
480 userAccessToken = await userLogin(server, user)
484 describe('When getting my information', function () {
485 it('Should fail with a non authenticated user', async function () {
486 await getMyUserInformation(server.url, 'fake_token', 401)
489 it('Should success with the correct parameters', async function () {
490 await getMyUserInformation(server.url, userAccessToken)
494 describe('When getting my video rating', function () {
495 it('Should fail with a non authenticated user', async function () {
496 await getMyUserVideoRating(server.url, 'fake_token', videoId, 401)
499 it('Should fail with an incorrect video uuid', async function () {
500 await getMyUserVideoRating(server.url, server.accessToken, 'blabla', 400)
503 it('Should fail with an unknown video', async function () {
504 await getMyUserVideoRating(server.url, server.accessToken, '4da6fde3-88f7-4d16-b119-108df5630b06', 404)
507 it('Should succeed with the correct parameters', async function () {
508 await getMyUserVideoRating(server.url, server.accessToken, videoId)
512 describe('When blocking/unblocking/removing user', function () {
513 it('Should fail with an incorrect id', async function () {
514 await removeUser(server.url, 'blabla', server.accessToken, 400)
515 await blockUser(server.url, 'blabla', server.accessToken, 400)
516 await unblockUser(server.url, 'blabla', server.accessToken, 400)
519 it('Should fail with the root user', async function () {
520 await removeUser(server.url, rootId, server.accessToken, 400)
521 await blockUser(server.url, rootId, server.accessToken, 400)
522 await unblockUser(server.url, rootId, server.accessToken, 400)
525 it('Should return 404 with a non existing id', async function () {
526 await removeUser(server.url, 4545454, server.accessToken, 404)
527 await blockUser(server.url, 4545454, server.accessToken, 404)
528 await unblockUser(server.url, 4545454, server.accessToken, 404)
531 it('Should fail with a non admin user', async function () {
532 await removeUser(server.url, userId, userAccessToken, 403)
533 await blockUser(server.url, userId, userAccessToken, 403)
534 await unblockUser(server.url, userId, userAccessToken, 403)
538 describe('When deleting our account', function () {
539 it('Should fail with with the root account', async function () {
540 await deleteMe(server.url, server.accessToken, 400)
544 describe('When register a new user', function () {
545 const registrationPath = path + '/register'
546 const baseCorrectParams = {
548 email: 'test3@example.com',
549 password: 'my super password'
552 it('Should fail with a too small username', async function () {
553 const fields = immutableAssign(baseCorrectParams, { username: '' })
555 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
558 it('Should fail with a too long username', async function () {
559 const fields = immutableAssign(baseCorrectParams, { username: 'super'.repeat(11) })
561 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
564 it('Should fail with an incorrect username', async function () {
565 const fields = immutableAssign(baseCorrectParams, { username: 'my username' })
567 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
570 it('Should fail with a missing email', async function () {
571 const fields = omit(baseCorrectParams, 'email')
573 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
576 it('Should fail with an invalid email', async function () {
577 const fields = immutableAssign(baseCorrectParams, { email: 'test_example.com' })
579 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
582 it('Should fail with a too small password', async function () {
583 const fields = immutableAssign(baseCorrectParams, { password: 'bla' })
585 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
588 it('Should fail with a too long password', async function () {
589 const fields = immutableAssign(baseCorrectParams, { password: 'super'.repeat(61) })
591 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
594 it('Should fail if we register a user with the same username', async function () {
595 const fields = immutableAssign(baseCorrectParams, { username: 'root' })
597 await makePostBodyRequest({
599 path: registrationPath,
600 token: server.accessToken,
602 statusCodeExpected: 409
606 it('Should fail with a "peertube" username', async function () {
607 const fields = immutableAssign(baseCorrectParams, { username: 'peertube' })
609 await makePostBodyRequest({
611 path: registrationPath,
612 token: server.accessToken,
614 statusCodeExpected: 409
618 it('Should fail if we register a user with the same email', async function () {
619 const fields = immutableAssign(baseCorrectParams, { email: 'admin1@example.com' })
621 await makePostBodyRequest({
623 path: registrationPath,
624 token: server.accessToken,
626 statusCodeExpected: 409
630 it('Should succeed with the correct params', async function () {
631 await makePostBodyRequest({
633 path: registrationPath,
634 token: server.accessToken,
635 fields: baseCorrectParams,
636 statusCodeExpected: 204
640 it('Should fail on a server with registration disabled', async function () {
643 email: 'test4@example.com',
644 password: 'my super password 4'
647 await makePostBodyRequest({
648 url: serverWithRegistrationDisabled.url,
649 path: registrationPath,
650 token: serverWithRegistrationDisabled.accessToken,
652 statusCodeExpected: 403
657 describe('When registering multiple users on a server with users limit', function () {
658 it('Should fail when after 3 registrations', async function () {
659 await registerUser(server.url, 'user42', 'super password', 403)
663 describe('When having a video quota', function () {
664 it('Should fail with a user having too many videos', async function () {
668 accessToken: server.accessToken,
672 await uploadVideo(server.url, server.accessToken, {}, 403)
675 it('Should fail with a registered user having too many videos', async function () {
680 password: 'my super password'
682 userAccessToken = await userLogin(server, user)
684 const videoAttributes = { fixture: 'video_short2.webm' }
685 await uploadVideo(server.url, userAccessToken, videoAttributes)
686 await uploadVideo(server.url, userAccessToken, videoAttributes)
687 await uploadVideo(server.url, userAccessToken, videoAttributes)
688 await uploadVideo(server.url, userAccessToken, videoAttributes)
689 await uploadVideo(server.url, userAccessToken, videoAttributes)
690 await uploadVideo(server.url, userAccessToken, videoAttributes, 403)
693 it('Should fail to import with HTTP/Torrent/magnet', async function () {
696 const baseAttributes = {
698 privacy: VideoPrivacy.PUBLIC
700 await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { targetUrl: getYoutubeVideoUrl() }))
701 await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { magnetUri: getMagnetURI() }))
702 await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { torrentfile: 'video-720p.torrent' }))
704 await waitJobs([ server ])
706 const res = await getMyVideoImports(server.url, server.accessToken)
708 expect(res.body.total).to.equal(3)
709 const videoImports: VideoImport[] = res.body.data
710 expect(videoImports).to.have.lengthOf(3)
712 for (const videoImport of videoImports) {
713 expect(videoImport.state.id).to.equal(VideoImportState.FAILED)
714 expect(videoImport.error).not.to.be.undefined
715 expect(videoImport.error).to.contain('user video quota is exceeded')
720 describe('When having a daily video quota', function () {
721 it('Should fail with a user having too many videos', async function () {
725 accessToken: server.accessToken,
729 await uploadVideo(server.url, server.accessToken, {}, 403)
733 describe('When having an absolute and daily video quota', function () {
734 it('Should fail if exceeding total quota', async function () {
738 accessToken: server.accessToken,
740 videoQuotaDaily: 1024 * 1024 * 1024
743 await uploadVideo(server.url, server.accessToken, {}, 403)
746 it('Should fail if exceeding daily quota', async function () {
750 accessToken: server.accessToken,
751 videoQuota: 1024 * 1024 * 1024,
755 await uploadVideo(server.url, server.accessToken, {}, 403)
759 describe('When asking a password reset', function () {
760 const path = '/api/v1/users/ask-reset-password'
762 it('Should fail with a missing email', async function () {
765 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
768 it('Should fail with an invalid email', async function () {
769 const fields = { email: 'hello' }
771 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
774 it('Should success with the correct params', async function () {
775 const fields = { email: 'admin@example.com' }
777 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 })
781 describe('When asking for an account verification email', function () {
782 const path = '/api/v1/users/ask-send-verify-email'
784 it('Should fail with a missing email', async function () {
787 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
790 it('Should fail with an invalid email', async function () {
791 const fields = { email: 'hello' }
793 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
796 it('Should succeed with the correct params', async function () {
797 const fields = { email: 'admin@example.com' }
799 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 })
803 after(async function () {
804 killallServers([ server, serverWithRegistrationDisabled ])
806 // Keep the logs if the test failed