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: 'fi' })
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: 'my_super_username_which_is_very_long' })
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 videoQuota attribute', async function () {
440 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
443 it('Should fail with an invalid user role attribute', async function () {
448 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
451 it('Should fail with an non authenticated user', async function () {
456 await makePutBodyRequest({ url: server.url, path: path + userId, token: 'super token', fields, statusCodeExpected: 401 })
459 it('Should fail when updating root role', async function () {
461 role: UserRole.MODERATOR
464 await makePutBodyRequest({ url: server.url, path: path + rootId, token: server.accessToken, fields })
467 it('Should succeed with the correct params', async function () {
469 email: 'email@example.com',
471 role: UserRole.MODERATOR
474 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields, statusCodeExpected: 204 })
475 userAccessToken = await userLogin(server, user)
479 describe('When getting my information', function () {
480 it('Should fail with a non authenticated user', async function () {
481 await getMyUserInformation(server.url, 'fake_token', 401)
484 it('Should success with the correct parameters', async function () {
485 await getMyUserInformation(server.url, userAccessToken)
489 describe('When getting my video rating', function () {
490 it('Should fail with a non authenticated user', async function () {
491 await getMyUserVideoRating(server.url, 'fake_token', videoId, 401)
494 it('Should fail with an incorrect video uuid', async function () {
495 await getMyUserVideoRating(server.url, server.accessToken, 'blabla', 400)
498 it('Should fail with an unknown video', async function () {
499 await getMyUserVideoRating(server.url, server.accessToken, '4da6fde3-88f7-4d16-b119-108df5630b06', 404)
502 it('Should succeed with the correct parameters', async function () {
503 await getMyUserVideoRating(server.url, server.accessToken, videoId)
507 describe('When blocking/unblocking/removing user', function () {
508 it('Should fail with an incorrect id', async function () {
509 await removeUser(server.url, 'blabla', server.accessToken, 400)
510 await blockUser(server.url, 'blabla', server.accessToken, 400)
511 await unblockUser(server.url, 'blabla', server.accessToken, 400)
514 it('Should fail with the root user', async function () {
515 await removeUser(server.url, rootId, server.accessToken, 400)
516 await blockUser(server.url, rootId, server.accessToken, 400)
517 await unblockUser(server.url, rootId, server.accessToken, 400)
520 it('Should return 404 with a non existing id', async function () {
521 await removeUser(server.url, 4545454, server.accessToken, 404)
522 await blockUser(server.url, 4545454, server.accessToken, 404)
523 await unblockUser(server.url, 4545454, server.accessToken, 404)
526 it('Should fail with a non admin user', async function () {
527 await removeUser(server.url, userId, userAccessToken, 403)
528 await blockUser(server.url, userId, userAccessToken, 403)
529 await unblockUser(server.url, userId, userAccessToken, 403)
533 describe('When deleting our account', function () {
534 it('Should fail with with the root account', async function () {
535 await deleteMe(server.url, server.accessToken, 400)
539 describe('When register a new user', function () {
540 const registrationPath = path + '/register'
541 const baseCorrectParams = {
543 email: 'test3@example.com',
544 password: 'my super password'
547 it('Should fail with a too small username', async function () {
548 const fields = immutableAssign(baseCorrectParams, { username: 'ji' })
550 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
553 it('Should fail with a too long username', async function () {
554 const fields = immutableAssign(baseCorrectParams, { username: 'my_super_username_which_is_very_long' })
556 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
559 it('Should fail with an incorrect username', async function () {
560 const fields = immutableAssign(baseCorrectParams, { username: 'my username' })
562 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
565 it('Should fail with a missing email', async function () {
566 const fields = omit(baseCorrectParams, 'email')
568 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
571 it('Should fail with an invalid email', async function () {
572 const fields = immutableAssign(baseCorrectParams, { email: 'test_example.com' })
574 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
577 it('Should fail with a too small password', async function () {
578 const fields = immutableAssign(baseCorrectParams, { password: 'bla' })
580 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
583 it('Should fail with a too long password', async function () {
584 const fields = immutableAssign(baseCorrectParams, { password: 'super'.repeat(61) })
586 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
589 it('Should fail if we register a user with the same username', async function () {
590 const fields = immutableAssign(baseCorrectParams, { username: 'root' })
592 await makePostBodyRequest({
594 path: registrationPath,
595 token: server.accessToken,
597 statusCodeExpected: 409
601 it('Should fail with a "peertube" username', async function () {
602 const fields = immutableAssign(baseCorrectParams, { username: 'peertube' })
604 await makePostBodyRequest({
606 path: registrationPath,
607 token: server.accessToken,
609 statusCodeExpected: 409
613 it('Should fail if we register a user with the same email', async function () {
614 const fields = immutableAssign(baseCorrectParams, { email: 'admin1@example.com' })
616 await makePostBodyRequest({
618 path: registrationPath,
619 token: server.accessToken,
621 statusCodeExpected: 409
625 it('Should succeed with the correct params', async function () {
626 await makePostBodyRequest({
628 path: registrationPath,
629 token: server.accessToken,
630 fields: baseCorrectParams,
631 statusCodeExpected: 204
635 it('Should fail on a server with registration disabled', async function () {
638 email: 'test4@example.com',
639 password: 'my super password 4'
642 await makePostBodyRequest({
643 url: serverWithRegistrationDisabled.url,
644 path: registrationPath,
645 token: serverWithRegistrationDisabled.accessToken,
647 statusCodeExpected: 403
652 describe('When registering multiple users on a server with users limit', function () {
653 it('Should fail when after 3 registrations', async function () {
654 await registerUser(server.url, 'user42', 'super password', 403)
658 describe('When having a video quota', function () {
659 it('Should fail with a user having too many videos', async function () {
663 accessToken: server.accessToken,
667 await uploadVideo(server.url, server.accessToken, {}, 403)
670 it('Should fail with a registered user having too many videos', async function () {
675 password: 'my super password'
677 userAccessToken = await userLogin(server, user)
679 const videoAttributes = { fixture: 'video_short2.webm' }
680 await uploadVideo(server.url, userAccessToken, videoAttributes)
681 await uploadVideo(server.url, userAccessToken, videoAttributes)
682 await uploadVideo(server.url, userAccessToken, videoAttributes)
683 await uploadVideo(server.url, userAccessToken, videoAttributes)
684 await uploadVideo(server.url, userAccessToken, videoAttributes)
685 await uploadVideo(server.url, userAccessToken, videoAttributes, 403)
688 it('Should fail to import with HTTP/Torrent/magnet', async function () {
691 const baseAttributes = {
693 privacy: VideoPrivacy.PUBLIC
695 await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { targetUrl: getYoutubeVideoUrl() }))
696 await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { magnetUri: getMagnetURI() }))
697 await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { torrentfile: 'video-720p.torrent' }))
699 await waitJobs([ server ])
701 const res = await getMyVideoImports(server.url, server.accessToken)
703 expect(res.body.total).to.equal(3)
704 const videoImports: VideoImport[] = res.body.data
705 expect(videoImports).to.have.lengthOf(3)
707 for (const videoImport of videoImports) {
708 expect(videoImport.state.id).to.equal(VideoImportState.FAILED)
709 expect(videoImport.error).not.to.be.undefined
710 expect(videoImport.error).to.contain('user video quota is exceeded')
715 describe('When having a daily video quota', function () {
716 it('Should fail with a user having too many videos', async function () {
720 accessToken: server.accessToken,
724 await uploadVideo(server.url, server.accessToken, {}, 403)
728 describe('When having an absolute and daily video quota', function () {
729 it('Should fail if exceeding total quota', async function () {
733 accessToken: server.accessToken,
735 videoQuotaDaily: 1024 * 1024 * 1024
738 await uploadVideo(server.url, server.accessToken, {}, 403)
741 it('Should fail if exceeding daily quota', async function () {
745 accessToken: server.accessToken,
746 videoQuota: 1024 * 1024 * 1024,
750 await uploadVideo(server.url, server.accessToken, {}, 403)
754 describe('When asking a password reset', function () {
755 const path = '/api/v1/users/ask-reset-password'
757 it('Should fail with a missing email', async function () {
760 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
763 it('Should fail with an invalid email', async function () {
764 const fields = { email: 'hello' }
766 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
769 it('Should success with the correct params', async function () {
770 const fields = { email: 'admin@example.com' }
772 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 })
776 describe('When asking for an account verification email', function () {
777 const path = '/api/v1/users/ask-send-verify-email'
779 it('Should fail with a missing email', async function () {
782 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
785 it('Should fail with an invalid email', async function () {
786 const fields = { email: 'hello' }
788 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
791 it('Should succeed with the correct params', async function () {
792 const fields = { email: 'admin@example.com' }
794 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 })
798 after(async function () {
799 killallServers([ server, serverWithRegistrationDisabled ])
801 // Keep the logs if the test failed