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 () {
260 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
263 it('Should fail with a too long password', async function () {
265 password: 'super'.repeat(61)
268 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
271 it('Should fail with an invalid NSFW policy attribute', async function () {
276 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
279 it('Should fail with an invalid autoPlayVideo attribute', async function () {
284 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
287 it('Should fail with an non authenticated user', async function () {
289 password: 'my super password'
292 await makePutBodyRequest({ url: server.url, path: path + 'me', token: 'super token', fields, statusCodeExpected: 401 })
295 it('Should fail with a too long description', async function () {
297 description: 'super'.repeat(60)
300 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
303 it('Should succeed with the correct params', async function () {
305 password: 'my super password',
307 autoPlayVideo: false,
308 email: 'super_email@example.com'
311 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields, statusCodeExpected: 204 })
315 describe('When updating my avatar', function () {
316 it('Should fail without an incorrect input file', async function () {
319 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'video_short.mp4')
321 await makeUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches })
324 it('Should fail with a big file', async function () {
327 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar-big.png')
329 await makeUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches })
332 it('Should fail with an unauthenticated user', async function () {
335 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png')
337 await makeUploadRequest({
339 path: path + '/me/avatar/pick',
342 statusCodeExpected: 401
346 it('Should succeed with the correct params', async function () {
349 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png')
351 await makeUploadRequest({
353 path: path + '/me/avatar/pick',
354 token: server.accessToken,
357 statusCodeExpected: 200
362 describe('When getting a user', function () {
363 before(async function () {
364 const res = await getUsersList(server.url, server.accessToken)
366 userId = res.body.data[1].id
369 it('Should fail with an non authenticated user', async function () {
370 await makeGetRequest({ url: server.url, path: path + userId, token: 'super token', statusCodeExpected: 401 })
373 it('Should fail with a non admin user', async function () {
374 await makeGetRequest({ url: server.url, path, token: userAccessToken, statusCodeExpected: 403 })
377 it('Should succeed with the correct params', async function () {
378 await makeGetRequest({ url: server.url, path: path + userId, token: server.accessToken, statusCodeExpected: 200 })
382 describe('When updating a user', function () {
384 before(async function () {
385 const res = await getUsersList(server.url, server.accessToken)
387 userId = res.body.data[1].id
388 rootId = res.body.data[2].id
391 it('Should fail with an invalid email attribute', async function () {
396 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
399 it('Should fail with an invalid videoQuota attribute', async function () {
404 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
407 it('Should fail with an invalid user role attribute', async function () {
412 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
415 it('Should fail with an non authenticated user', async function () {
420 await makePutBodyRequest({ url: server.url, path: path + userId, token: 'super token', fields, statusCodeExpected: 401 })
423 it('Should fail when updating root role', async function () {
425 role: UserRole.MODERATOR
428 await makePutBodyRequest({ url: server.url, path: path + rootId, token: server.accessToken, fields })
431 it('Should succeed with the correct params', async function () {
433 email: 'email@example.com',
435 role: UserRole.MODERATOR
438 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields, statusCodeExpected: 204 })
439 userAccessToken = await userLogin(server, user)
443 describe('When getting my information', function () {
444 it('Should fail with a non authenticated user', async function () {
445 await getMyUserInformation(server.url, 'fake_token', 401)
448 it('Should success with the correct parameters', async function () {
449 await getMyUserInformation(server.url, userAccessToken)
453 describe('When getting my video rating', function () {
454 it('Should fail with a non authenticated user', async function () {
455 await getMyUserVideoRating(server.url, 'fake_token', videoId, 401)
458 it('Should fail with an incorrect video uuid', async function () {
459 await getMyUserVideoRating(server.url, server.accessToken, 'blabla', 400)
462 it('Should fail with an unknown video', async function () {
463 await getMyUserVideoRating(server.url, server.accessToken, '4da6fde3-88f7-4d16-b119-108df5630b06', 404)
466 it('Should succeed with the correct parameters', async function () {
467 await getMyUserVideoRating(server.url, server.accessToken, videoId)
471 describe('When blocking/unblocking/removing user', function () {
472 it('Should fail with an incorrect id', async function () {
473 await removeUser(server.url, 'blabla', server.accessToken, 400)
474 await blockUser(server.url, 'blabla', server.accessToken, 400)
475 await unblockUser(server.url, 'blabla', server.accessToken, 400)
478 it('Should fail with the root user', async function () {
479 await removeUser(server.url, rootId, server.accessToken, 400)
480 await blockUser(server.url, rootId, server.accessToken, 400)
481 await unblockUser(server.url, rootId, server.accessToken, 400)
484 it('Should return 404 with a non existing id', async function () {
485 await removeUser(server.url, 4545454, server.accessToken, 404)
486 await blockUser(server.url, 4545454, server.accessToken, 404)
487 await unblockUser(server.url, 4545454, server.accessToken, 404)
490 it('Should fail with a non admin user', async function () {
491 await removeUser(server.url, userId, userAccessToken, 403)
492 await blockUser(server.url, userId, userAccessToken, 403)
493 await unblockUser(server.url, userId, userAccessToken, 403)
497 describe('When deleting our account', function () {
498 it('Should fail with with the root account', async function () {
499 await deleteMe(server.url, server.accessToken, 400)
503 describe('When register a new user', function () {
504 const registrationPath = path + '/register'
505 const baseCorrectParams = {
507 email: 'test3@example.com',
508 password: 'my super password'
511 it('Should fail with a too small username', async function () {
512 const fields = immutableAssign(baseCorrectParams, { username: 'ji' })
514 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
517 it('Should fail with a too long username', async function () {
518 const fields = immutableAssign(baseCorrectParams, { username: 'my_super_username_which_is_very_long' })
520 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
523 it('Should fail with an incorrect username', async function () {
524 const fields = immutableAssign(baseCorrectParams, { username: 'my username' })
526 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
529 it('Should fail with a missing email', async function () {
530 const fields = omit(baseCorrectParams, 'email')
532 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
535 it('Should fail with an invalid email', async function () {
536 const fields = immutableAssign(baseCorrectParams, { email: 'test_example.com' })
538 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
541 it('Should fail with a too small password', async function () {
542 const fields = immutableAssign(baseCorrectParams, { password: 'bla' })
544 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
547 it('Should fail with a too long password', async function () {
548 const fields = immutableAssign(baseCorrectParams, { password: 'super'.repeat(61) })
550 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
553 it('Should fail if we register a user with the same username', async function () {
554 const fields = immutableAssign(baseCorrectParams, { username: 'root' })
556 await makePostBodyRequest({
558 path: registrationPath,
559 token: server.accessToken,
561 statusCodeExpected: 409
565 it('Should fail with a "peertube" username', async function () {
566 const fields = immutableAssign(baseCorrectParams, { username: 'peertube' })
568 await makePostBodyRequest({
570 path: registrationPath,
571 token: server.accessToken,
573 statusCodeExpected: 409
577 it('Should fail if we register a user with the same email', async function () {
578 const fields = immutableAssign(baseCorrectParams, { email: 'admin1@example.com' })
580 await makePostBodyRequest({
582 path: registrationPath,
583 token: server.accessToken,
585 statusCodeExpected: 409
589 it('Should succeed with the correct params', async function () {
590 await makePostBodyRequest({
592 path: registrationPath,
593 token: server.accessToken,
594 fields: baseCorrectParams,
595 statusCodeExpected: 204
599 it('Should fail on a server with registration disabled', async function () {
602 email: 'test4@example.com',
603 password: 'my super password 4'
606 await makePostBodyRequest({
607 url: serverWithRegistrationDisabled.url,
608 path: registrationPath,
609 token: serverWithRegistrationDisabled.accessToken,
611 statusCodeExpected: 403
616 describe('When registering multiple users on a server with users limit', function () {
617 it('Should fail when after 3 registrations', async function () {
618 await registerUser(server.url, 'user42', 'super password', 403)
622 describe('When having a video quota', function () {
623 it('Should fail with a user having too many videos', async function () {
627 accessToken: server.accessToken,
631 await uploadVideo(server.url, server.accessToken, {}, 403)
634 it('Should fail with a registered user having too many videos', async function () {
639 password: 'my super password'
641 userAccessToken = await userLogin(server, user)
643 const videoAttributes = { fixture: 'video_short2.webm' }
644 await uploadVideo(server.url, userAccessToken, videoAttributes)
645 await uploadVideo(server.url, userAccessToken, videoAttributes)
646 await uploadVideo(server.url, userAccessToken, videoAttributes)
647 await uploadVideo(server.url, userAccessToken, videoAttributes)
648 await uploadVideo(server.url, userAccessToken, videoAttributes)
649 await uploadVideo(server.url, userAccessToken, videoAttributes, 403)
652 it('Should fail to import with HTTP/Torrent/magnet', async function () {
655 const baseAttributes = {
657 privacy: VideoPrivacy.PUBLIC
659 await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { targetUrl: getYoutubeVideoUrl() }))
660 await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { magnetUri: getMagnetURI() }))
661 await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { torrentfile: 'video-720p.torrent' }))
663 await waitJobs([ server ])
665 const res = await getMyVideoImports(server.url, server.accessToken)
667 expect(res.body.total).to.equal(3)
668 const videoImports: VideoImport[] = res.body.data
669 expect(videoImports).to.have.lengthOf(3)
671 for (const videoImport of videoImports) {
672 expect(videoImport.state.id).to.equal(VideoImportState.FAILED)
673 expect(videoImport.error).not.to.be.undefined
674 expect(videoImport.error).to.contain('user video quota is exceeded')
679 describe('When having a daily video quota', function () {
680 it('Should fail with a user having too many videos', async function () {
684 accessToken: server.accessToken,
688 await uploadVideo(server.url, server.accessToken, {}, 403)
692 describe('When having an absolute and daily video quota', function () {
693 it('Should fail if exceeding total quota', async function () {
697 accessToken: server.accessToken,
699 videoQuotaDaily: 1024 * 1024 * 1024
702 await uploadVideo(server.url, server.accessToken, {}, 403)
705 it('Should fail if exceeding daily quota', async function () {
709 accessToken: server.accessToken,
710 videoQuota: 1024 * 1024 * 1024,
714 await uploadVideo(server.url, server.accessToken, {}, 403)
718 describe('When asking a password reset', function () {
719 const path = '/api/v1/users/ask-reset-password'
721 it('Should fail with a missing email', async function () {
724 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
727 it('Should fail with an invalid email', async function () {
728 const fields = { email: 'hello' }
730 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
733 it('Should success with the correct params', async function () {
734 const fields = { email: 'admin@example.com' }
736 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 })
740 describe('When asking for an account verification email', function () {
741 const path = '/api/v1/users/ask-send-verify-email'
743 it('Should fail with a missing email', async function () {
746 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
749 it('Should fail with an invalid email', async function () {
750 const fields = { email: 'hello' }
752 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
755 it('Should succeed with the correct params', async function () {
756 const fields = { email: 'admin@example.com' }
758 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 })
762 after(async function () {
763 killallServers([ server, serverWithRegistrationDisabled ])
765 // Keep the logs if the test failed