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: 'fi' })
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: 'my_super_username_which_is_very_long' })
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(60)
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 videoQuota attribute', async function () {
436 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
439 it('Should fail with an invalid user role attribute', async function () {
444 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
447 it('Should fail with an non authenticated user', async function () {
452 await makePutBodyRequest({ url: server.url, path: path + userId, token: 'super token', fields, statusCodeExpected: 401 })
455 it('Should fail when updating root role', async function () {
457 role: UserRole.MODERATOR
460 await makePutBodyRequest({ url: server.url, path: path + rootId, token: server.accessToken, fields })
463 it('Should succeed with the correct params', async function () {
465 email: 'email@example.com',
467 role: UserRole.MODERATOR
470 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields, statusCodeExpected: 204 })
471 userAccessToken = await userLogin(server, user)
475 describe('When getting my information', function () {
476 it('Should fail with a non authenticated user', async function () {
477 await getMyUserInformation(server.url, 'fake_token', 401)
480 it('Should success with the correct parameters', async function () {
481 await getMyUserInformation(server.url, userAccessToken)
485 describe('When getting my video rating', function () {
486 it('Should fail with a non authenticated user', async function () {
487 await getMyUserVideoRating(server.url, 'fake_token', videoId, 401)
490 it('Should fail with an incorrect video uuid', async function () {
491 await getMyUserVideoRating(server.url, server.accessToken, 'blabla', 400)
494 it('Should fail with an unknown video', async function () {
495 await getMyUserVideoRating(server.url, server.accessToken, '4da6fde3-88f7-4d16-b119-108df5630b06', 404)
498 it('Should succeed with the correct parameters', async function () {
499 await getMyUserVideoRating(server.url, server.accessToken, videoId)
503 describe('When blocking/unblocking/removing user', function () {
504 it('Should fail with an incorrect id', async function () {
505 await removeUser(server.url, 'blabla', server.accessToken, 400)
506 await blockUser(server.url, 'blabla', server.accessToken, 400)
507 await unblockUser(server.url, 'blabla', server.accessToken, 400)
510 it('Should fail with the root user', async function () {
511 await removeUser(server.url, rootId, server.accessToken, 400)
512 await blockUser(server.url, rootId, server.accessToken, 400)
513 await unblockUser(server.url, rootId, server.accessToken, 400)
516 it('Should return 404 with a non existing id', async function () {
517 await removeUser(server.url, 4545454, server.accessToken, 404)
518 await blockUser(server.url, 4545454, server.accessToken, 404)
519 await unblockUser(server.url, 4545454, server.accessToken, 404)
522 it('Should fail with a non admin user', async function () {
523 await removeUser(server.url, userId, userAccessToken, 403)
524 await blockUser(server.url, userId, userAccessToken, 403)
525 await unblockUser(server.url, userId, userAccessToken, 403)
529 describe('When deleting our account', function () {
530 it('Should fail with with the root account', async function () {
531 await deleteMe(server.url, server.accessToken, 400)
535 describe('When register a new user', function () {
536 const registrationPath = path + '/register'
537 const baseCorrectParams = {
539 email: 'test3@example.com',
540 password: 'my super password'
543 it('Should fail with a too small username', async function () {
544 const fields = immutableAssign(baseCorrectParams, { username: 'ji' })
546 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
549 it('Should fail with a too long username', async function () {
550 const fields = immutableAssign(baseCorrectParams, { username: 'my_super_username_which_is_very_long' })
552 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
555 it('Should fail with an incorrect username', async function () {
556 const fields = immutableAssign(baseCorrectParams, { username: 'my username' })
558 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
561 it('Should fail with a missing email', async function () {
562 const fields = omit(baseCorrectParams, 'email')
564 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
567 it('Should fail with an invalid email', async function () {
568 const fields = immutableAssign(baseCorrectParams, { email: 'test_example.com' })
570 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
573 it('Should fail with a too small password', async function () {
574 const fields = immutableAssign(baseCorrectParams, { password: 'bla' })
576 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
579 it('Should fail with a too long password', async function () {
580 const fields = immutableAssign(baseCorrectParams, { password: 'super'.repeat(61) })
582 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
585 it('Should fail if we register a user with the same username', async function () {
586 const fields = immutableAssign(baseCorrectParams, { username: 'root' })
588 await makePostBodyRequest({
590 path: registrationPath,
591 token: server.accessToken,
593 statusCodeExpected: 409
597 it('Should fail with a "peertube" username', async function () {
598 const fields = immutableAssign(baseCorrectParams, { username: 'peertube' })
600 await makePostBodyRequest({
602 path: registrationPath,
603 token: server.accessToken,
605 statusCodeExpected: 409
609 it('Should fail if we register a user with the same email', async function () {
610 const fields = immutableAssign(baseCorrectParams, { email: 'admin1@example.com' })
612 await makePostBodyRequest({
614 path: registrationPath,
615 token: server.accessToken,
617 statusCodeExpected: 409
621 it('Should succeed with the correct params', async function () {
622 await makePostBodyRequest({
624 path: registrationPath,
625 token: server.accessToken,
626 fields: baseCorrectParams,
627 statusCodeExpected: 204
631 it('Should fail on a server with registration disabled', async function () {
634 email: 'test4@example.com',
635 password: 'my super password 4'
638 await makePostBodyRequest({
639 url: serverWithRegistrationDisabled.url,
640 path: registrationPath,
641 token: serverWithRegistrationDisabled.accessToken,
643 statusCodeExpected: 403
648 describe('When registering multiple users on a server with users limit', function () {
649 it('Should fail when after 3 registrations', async function () {
650 await registerUser(server.url, 'user42', 'super password', 403)
654 describe('When having a video quota', function () {
655 it('Should fail with a user having too many videos', async function () {
659 accessToken: server.accessToken,
663 await uploadVideo(server.url, server.accessToken, {}, 403)
666 it('Should fail with a registered user having too many videos', async function () {
671 password: 'my super password'
673 userAccessToken = await userLogin(server, user)
675 const videoAttributes = { fixture: 'video_short2.webm' }
676 await uploadVideo(server.url, userAccessToken, videoAttributes)
677 await uploadVideo(server.url, userAccessToken, videoAttributes)
678 await uploadVideo(server.url, userAccessToken, videoAttributes)
679 await uploadVideo(server.url, userAccessToken, videoAttributes)
680 await uploadVideo(server.url, userAccessToken, videoAttributes)
681 await uploadVideo(server.url, userAccessToken, videoAttributes, 403)
684 it('Should fail to import with HTTP/Torrent/magnet', async function () {
687 const baseAttributes = {
689 privacy: VideoPrivacy.PUBLIC
691 await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { targetUrl: getYoutubeVideoUrl() }))
692 await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { magnetUri: getMagnetURI() }))
693 await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { torrentfile: 'video-720p.torrent' }))
695 await waitJobs([ server ])
697 const res = await getMyVideoImports(server.url, server.accessToken)
699 expect(res.body.total).to.equal(3)
700 const videoImports: VideoImport[] = res.body.data
701 expect(videoImports).to.have.lengthOf(3)
703 for (const videoImport of videoImports) {
704 expect(videoImport.state.id).to.equal(VideoImportState.FAILED)
705 expect(videoImport.error).not.to.be.undefined
706 expect(videoImport.error).to.contain('user video quota is exceeded')
711 describe('When having a daily video quota', function () {
712 it('Should fail with a user having too many videos', async function () {
716 accessToken: server.accessToken,
720 await uploadVideo(server.url, server.accessToken, {}, 403)
724 describe('When having an absolute and daily video quota', function () {
725 it('Should fail if exceeding total quota', async function () {
729 accessToken: server.accessToken,
731 videoQuotaDaily: 1024 * 1024 * 1024
734 await uploadVideo(server.url, server.accessToken, {}, 403)
737 it('Should fail if exceeding daily quota', async function () {
741 accessToken: server.accessToken,
742 videoQuota: 1024 * 1024 * 1024,
746 await uploadVideo(server.url, server.accessToken, {}, 403)
750 describe('When asking a password reset', function () {
751 const path = '/api/v1/users/ask-reset-password'
753 it('Should fail with a missing email', async function () {
756 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
759 it('Should fail with an invalid email', async function () {
760 const fields = { email: 'hello' }
762 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
765 it('Should success with the correct params', async function () {
766 const fields = { email: 'admin@example.com' }
768 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 })
772 describe('When asking for an account verification email', function () {
773 const path = '/api/v1/users/ask-send-verify-email'
775 it('Should fail with a missing email', async function () {
778 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
781 it('Should fail with an invalid email', async function () {
782 const fields = { email: 'hello' }
784 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
787 it('Should succeed with the correct params', async function () {
788 const fields = { email: 'admin@example.com' }
790 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 })
794 after(async function () {
795 killallServers([ server, serverWithRegistrationDisabled ])
797 // Keep the logs if the test failed