]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/check-params/users.ts
Try to fix live test
[github/Chocobozzz/PeerTube.git] / server / tests / api / check-params / users.ts
CommitLineData
a1587156 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
0e1dc3e7 2
0e1dc3e7 3import 'mocha'
b488ba1e
C
4import { expect } from 'chai'
5import { omit } from 'lodash'
47564bbe 6import { join } from 'path'
a95a4cc8 7import { User, UserRole, VideoImport, VideoImportState } from '../../../../shared'
0e1dc3e7 8import {
e590b4a5 9 addVideoChannel,
42e1ec25 10 blockUser,
7c3b7976 11 cleanupTests,
42e1ec25
C
12 createUser,
13 deleteMe,
14 flushAndRunServer,
15 getMyUserInformation,
16 getMyUserVideoRating,
18490b07 17 getUserScopedTokens,
42e1ec25
C
18 getUsersList,
19 immutableAssign,
45f1bd72 20 killallServers,
42e1ec25
C
21 makeGetRequest,
22 makePostBodyRequest,
23 makePutBodyRequest,
24 makeUploadRequest,
25 registerUser,
26 removeUser,
18490b07 27 renewUserScopedTokens,
45f1bd72 28 reRunServer,
42e1ec25
C
29 ServerInfo,
30 setAccessTokensToServers,
31 unblockUser,
32 updateUser,
33 uploadVideo,
34 userLogin
94565d52 35} from '../../../../shared/extra-utils'
b488ba1e 36import { MockSmtpServer } from '../../../../shared/extra-utils/miscs/email'
9639bd17 37import {
38 checkBadCountPagination,
39 checkBadSortPagination,
40 checkBadStartPagination
94565d52 41} from '../../../../shared/extra-utils/requests/check-api-params'
94565d52 42import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
18490b07 43import { getGoodVideoUrl, getMagnetURI, getMyVideoImports, importVideo } from '../../../../shared/extra-utils/videos/video-imports'
1eddc9a7 44import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model'
b488ba1e 45import { VideoPrivacy } from '../../../../shared/models/videos'
0e1dc3e7
C
46
47describe('Test users API validators', function () {
48 const path = '/api/v1/users/'
49 let userId: number
50 let rootId: number
a95a4cc8 51 let moderatorId: number
0e1dc3e7
C
52 let videoId: number
53 let server: ServerInfo
54 let serverWithRegistrationDisabled: ServerInfo
55 let userAccessToken = ''
a95a4cc8 56 let moderatorAccessToken = ''
45f1bd72
JL
57 let emailPort: number
58 let overrideConfig: Object
0e1dc3e7
C
59
60 // ---------------------------------------------------------------
61
62 before(async function () {
e212f887 63 this.timeout(30000)
0e1dc3e7 64
45f1bd72
JL
65 const emails: object[] = []
66 emailPort = await MockSmtpServer.Instance.collectEmails(emails)
67
68 overrideConfig = { signup: { limit: 8 } }
69
a95a4cc8
C
70 {
71 const res = await Promise.all([
45f1bd72 72 flushAndRunServer(1, overrideConfig),
a95a4cc8
C
73 flushAndRunServer(2)
74 ])
0e1dc3e7 75
a95a4cc8
C
76 server = res[0]
77 serverWithRegistrationDisabled = res[1]
0e1dc3e7 78
a95a4cc8
C
79 await setAccessTokensToServers([ server ])
80 }
81
82 {
83 const user = {
84 username: 'user1',
85 password: 'my super password'
86 }
87
88 const videoQuota = 42000000
89 await createUser({
90 url: server.url,
91 accessToken: server.accessToken,
92 username: user.username,
93 password: user.password,
94 videoQuota: videoQuota
95 })
96 userAccessToken = await userLogin(server, user)
97 }
98
99 {
100 const moderator = {
101 username: 'moderator1',
102 password: 'super password'
103 }
104
105 await createUser({
106 url: server.url,
107 accessToken: server.accessToken,
108 username: moderator.username,
109 password: moderator.password,
110 role: UserRole.MODERATOR
111 })
112
113 moderatorAccessToken = await userLogin(server, moderator)
114 }
115
116 {
117 const moderator = {
118 username: 'moderator2',
119 password: 'super password'
120 }
121
122 await createUser({
123 url: server.url,
124 accessToken: server.accessToken,
125 username: moderator.username,
126 password: moderator.password,
127 role: UserRole.MODERATOR
128 })
129 }
26d21b78 130
187501f8
C
131 {
132 const res = await uploadVideo(server.url, server.accessToken, {})
133 videoId = res.body.video.id
134 }
a95a4cc8
C
135
136 {
137 const res = await getUsersList(server.url, server.accessToken)
138 const users: User[] = res.body.data
139
140 userId = users.find(u => u.username === 'user1').id
141 rootId = users.find(u => u.username === 'root').id
142 moderatorId = users.find(u => u.username === 'moderator2').id
143 }
0e1dc3e7
C
144 })
145
146 describe('When listing users', function () {
147 it('Should fail with a bad start pagination', async function () {
26d21b78 148 await checkBadStartPagination(server.url, path, server.accessToken)
0e1dc3e7
C
149 })
150
151 it('Should fail with a bad count pagination', async function () {
26d21b78 152 await checkBadCountPagination(server.url, path, server.accessToken)
0e1dc3e7
C
153 })
154
155 it('Should fail with an incorrect sort', async function () {
26d21b78 156 await checkBadSortPagination(server.url, path, server.accessToken)
0e1dc3e7 157 })
86d13ec2
C
158
159 it('Should fail with a non authenticated user', async function () {
26d21b78
C
160 await makeGetRequest({
161 url: server.url,
162 path,
163 statusCodeExpected: 401
164 })
86d13ec2
C
165 })
166
167 it('Should fail with a non admin user', async function () {
26d21b78
C
168 await makeGetRequest({
169 url: server.url,
170 path,
171 token: userAccessToken,
172 statusCodeExpected: 403
173 })
86d13ec2 174 })
0e1dc3e7
C
175 })
176
177 describe('When adding a new user', function () {
26d21b78
C
178 const baseCorrectParams = {
179 username: 'user2',
180 email: 'test@example.com',
181 password: 'my super password',
182 videoQuota: -1,
bee0abff 183 videoQuotaDaily: -1,
1eddc9a7 184 role: UserRole.USER,
3487330d 185 adminFlags: UserAdminFlag.BYPASS_VIDEO_AUTO_BLACKLIST
26d21b78
C
186 }
187
0e1dc3e7 188 it('Should fail with a too small username', async function () {
d0ce42c1 189 const fields = immutableAssign(baseCorrectParams, { username: '' })
0e1dc3e7
C
190
191 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
192 })
193
194 it('Should fail with a too long username', async function () {
9f7a1953 195 const fields = immutableAssign(baseCorrectParams, { username: 'super'.repeat(50) })
0e1dc3e7
C
196
197 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
198 })
199
563d032e 200 it('Should fail with a not lowercase username', async function () {
26d21b78 201 const fields = immutableAssign(baseCorrectParams, { username: 'Toto' })
563d032e
C
202
203 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
204 })
205
0e1dc3e7 206 it('Should fail with an incorrect username', async function () {
26d21b78 207 const fields = immutableAssign(baseCorrectParams, { username: 'my username' })
0e1dc3e7
C
208
209 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
210 })
211
212 it('Should fail with a missing email', async function () {
26d21b78 213 const fields = omit(baseCorrectParams, 'email')
0e1dc3e7
C
214
215 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
216 })
217
218 it('Should fail with an invalid email', async function () {
26d21b78 219 const fields = immutableAssign(baseCorrectParams, { email: 'test_example.com' })
0e1dc3e7
C
220
221 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
222 })
223
224 it('Should fail with a too small password', async function () {
26d21b78 225 const fields = immutableAssign(baseCorrectParams, { password: 'bla' })
0e1dc3e7
C
226
227 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
228 })
229
230 it('Should fail with a too long password', async function () {
26d21b78 231 const fields = immutableAssign(baseCorrectParams, { password: 'super'.repeat(61) })
0e1dc3e7
C
232
233 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
234 })
235
45f1bd72
JL
236 it('Should fail with empty password and no smtp configured', async function () {
237 const fields = immutableAssign(baseCorrectParams, { password: '' })
238
239 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
240 })
241
242 it('Should succeed with no password on a server with smtp enabled', async function () {
243 this.timeout(10000)
244
245 killallServers([ server ])
246
247 const config = immutableAssign(overrideConfig, {
248 smtp: {
249 hostname: 'localhost',
250 port: emailPort
251 }
252 })
253 await reRunServer(server, config)
254
255 const fields = immutableAssign(baseCorrectParams, {
256 password: '',
257 username: 'create_password',
258 email: 'create_password@example.com'
259 })
260
261 await makePostBodyRequest({
262 url: server.url,
263 path: path,
264 token: server.accessToken,
265 fields,
266 statusCodeExpected: 200
267 })
268 })
269
1eddc9a7
C
270 it('Should fail with invalid admin flags', async function () {
271 const fields = immutableAssign(baseCorrectParams, { adminFlags: 'toto' })
272
273 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
274 })
275
0e1dc3e7 276 it('Should fail with an non authenticated user', async function () {
26d21b78
C
277 await makePostBodyRequest({
278 url: server.url,
279 path,
280 token: 'super token',
281 fields: baseCorrectParams,
282 statusCodeExpected: 401
283 })
0e1dc3e7
C
284 })
285
286 it('Should fail if we add a user with the same username', async function () {
26d21b78 287 const fields = immutableAssign(baseCorrectParams, { username: 'user1' })
0e1dc3e7
C
288
289 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 409 })
290 })
291
292 it('Should fail if we add a user with the same email', async function () {
26d21b78 293 const fields = immutableAssign(baseCorrectParams, { email: 'user1@example.com' })
0e1dc3e7
C
294
295 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 409 })
296 })
297
77a5501f 298 it('Should fail without a videoQuota', async function () {
26d21b78 299 const fields = omit(baseCorrectParams, 'videoQuota')
77a5501f
C
300
301 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
302 })
303
bee0abff
FA
304 it('Should fail without a videoQuotaDaily', async function () {
305 const fields = omit(baseCorrectParams, 'videoQuotaDaily')
306
307 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
308 })
309
77a5501f 310 it('Should fail with an invalid videoQuota', async function () {
26d21b78 311 const fields = immutableAssign(baseCorrectParams, { videoQuota: -5 })
757f0da3
C
312
313 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
314 })
315
bee0abff
FA
316 it('Should fail with an invalid videoQuotaDaily', async function () {
317 const fields = immutableAssign(baseCorrectParams, { videoQuotaDaily: -7 })
318
319 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
320 })
321
757f0da3 322 it('Should fail without a user role', async function () {
26d21b78 323 const fields = omit(baseCorrectParams, 'role')
757f0da3
C
324
325 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
326 })
327
328 it('Should fail with an invalid user role', async function () {
26d21b78 329 const fields = immutableAssign(baseCorrectParams, { role: 88989 })
77a5501f
C
330
331 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
332 })
333
2ef6a063
C
334 it('Should fail with a "peertube" username', async function () {
335 const fields = immutableAssign(baseCorrectParams, { username: 'peertube' })
336
337 await makePostBodyRequest({
338 url: server.url,
339 path,
340 token: server.accessToken,
341 fields,
342 statusCodeExpected: 409
343 })
344 })
345
a95a4cc8
C
346 it('Should fail to create a moderator or an admin with a moderator', async function () {
347 for (const role of [ UserRole.MODERATOR, UserRole.ADMINISTRATOR ]) {
348 const fields = immutableAssign(baseCorrectParams, { role })
349
350 await makePostBodyRequest({
351 url: server.url,
352 path,
353 token: moderatorAccessToken,
354 fields,
355 statusCodeExpected: 403
356 })
357 }
358 })
359
360 it('Should succeed to create a user with a moderator', async function () {
361 const fields = immutableAssign(baseCorrectParams, { username: 'a4656', email: 'a4656@example.com', role: UserRole.USER })
362
363 await makePostBodyRequest({
364 url: server.url,
365 path,
366 token: moderatorAccessToken,
367 fields,
368 statusCodeExpected: 200
369 })
370 })
371
0e1dc3e7 372 it('Should succeed with the correct params', async function () {
26d21b78
C
373 await makePostBodyRequest({
374 url: server.url,
375 path,
376 token: server.accessToken,
377 fields: baseCorrectParams,
f05a1c30 378 statusCodeExpected: 200
26d21b78 379 })
0e1dc3e7
C
380 })
381
382 it('Should fail with a non admin user', async function () {
26d21b78 383 const user = {
0e1dc3e7 384 username: 'user1',
0e1dc3e7
C
385 password: 'my super password'
386 }
26d21b78 387 userAccessToken = await userLogin(server, user)
0e1dc3e7 388
0e1dc3e7
C
389 const fields = {
390 username: 'user3',
391 email: 'test@example.com',
77a5501f
C
392 password: 'my super password',
393 videoQuota: 42000000
0e1dc3e7
C
394 }
395 await makePostBodyRequest({ url: server.url, path, token: userAccessToken, fields, statusCodeExpected: 403 })
396 })
397 })
398
77a5501f
C
399 describe('When updating my account', function () {
400 it('Should fail with an invalid email attribute', async function () {
401 const fields = {
402 email: 'blabla'
403 }
0e1dc3e7 404
77a5501f 405 await makePutBodyRequest({ url: server.url, path: path + 'me', token: server.accessToken, fields })
0e1dc3e7
C
406 })
407
408 it('Should fail with a too small password', async function () {
409 const fields = {
a890d1e0 410 currentPassword: 'my super password',
0e1dc3e7
C
411 password: 'bla'
412 }
413
77a5501f 414 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
0e1dc3e7
C
415 })
416
417 it('Should fail with a too long password', async function () {
418 const fields = {
a890d1e0 419 currentPassword: 'my super password',
26d21b78 420 password: 'super'.repeat(61)
0e1dc3e7
C
421 }
422
77a5501f 423 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
0e1dc3e7
C
424 })
425
a890d1e0
C
426 it('Should fail without the current password', async function () {
427 const fields = {
428 currentPassword: 'my super password',
429 password: 'super'.repeat(61)
430 }
431
432 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
433 })
434
435 it('Should fail with an invalid current password', async function () {
436 const fields = {
437 currentPassword: 'my super password fail',
438 password: 'super'.repeat(61)
439 }
440
441 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields, statusCodeExpected: 401 })
442 })
443
0883b324 444 it('Should fail with an invalid NSFW policy attribute', async function () {
0e1dc3e7 445 const fields = {
0883b324 446 nsfwPolicy: 'hello'
0e1dc3e7
C
447 }
448
77a5501f 449 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
0e1dc3e7
C
450 })
451
7efe153b
AL
452 it('Should fail with an invalid autoPlayVideo attribute', async function () {
453 const fields = {
454 autoPlayVideo: -1
455 }
456
457 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
458 })
459
6aa54148
L
460 it('Should fail with an invalid autoPlayNextVideo attribute', async function () {
461 const fields = {
462 autoPlayNextVideo: -1
463 }
464
465 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
466 })
467
8b9a525a
C
468 it('Should fail with an invalid videosHistoryEnabled attribute', async function () {
469 const fields = {
470 videosHistoryEnabled: -1
471 }
472
473 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
474 })
475
0e1dc3e7
C
476 it('Should fail with an non authenticated user', async function () {
477 const fields = {
a890d1e0 478 currentPassword: 'my super password',
0e1dc3e7
C
479 password: 'my super password'
480 }
481
77a5501f 482 await makePutBodyRequest({ url: server.url, path: path + 'me', token: 'super token', fields, statusCodeExpected: 401 })
0e1dc3e7
C
483 })
484
2422c46b
C
485 it('Should fail with a too long description', async function () {
486 const fields = {
d23e6a1c 487 description: 'super'.repeat(201)
2422c46b
C
488 }
489
490 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
491 })
492
3caf77d3
C
493 it('Should fail with an invalid videoLanguages attribute', async function () {
494 {
495 const fields = {
496 videoLanguages: 'toto'
497 }
498
499 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
500 }
501
502 {
503 const languages = []
504 for (let i = 0; i < 1000; i++) {
505 languages.push('fr')
506 }
507
508 const fields = {
509 videoLanguages: languages
510 }
511
512 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
513 }
514 })
515
9b474844
C
516 it('Should fail with an invalid theme', async function () {
517 const fields = { theme: 'invalid' }
518 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
519 })
520
521 it('Should fail with an unknown theme', async function () {
522 const fields = { theme: 'peertube-theme-unknown' }
523 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
524 })
525
43d0ea7f
C
526 it('Should fail with an invalid noInstanceConfigWarningModal attribute', async function () {
527 const fields = {
528 noInstanceConfigWarningModal: -1
529 }
530
531 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
532 })
533
534 it('Should fail with an invalid noWelcomeModal attribute', async function () {
535 const fields = {
536 noWelcomeModal: -1
537 }
538
539 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
540 })
541
a890d1e0 542 it('Should succeed to change password with the correct params', async function () {
0e1dc3e7 543 const fields = {
a890d1e0 544 currentPassword: 'my super password',
0e1dc3e7 545 password: 'my super password',
0883b324 546 nsfwPolicy: 'blur',
7efe153b 547 autoPlayVideo: false,
9b474844 548 email: 'super_email@example.com',
43d0ea7f
C
549 theme: 'default',
550 noInstanceConfigWarningModal: true,
551 noWelcomeModal: true
0e1dc3e7
C
552 }
553
77a5501f
C
554 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields, statusCodeExpected: 204 })
555 })
a890d1e0
C
556
557 it('Should succeed without password change with the correct params', async function () {
558 const fields = {
559 nsfwPolicy: 'blur',
5efab546 560 autoPlayVideo: false
a890d1e0
C
561 }
562
563 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields, statusCodeExpected: 204 })
564 })
77a5501f
C
565 })
566
c5911fd3
C
567 describe('When updating my avatar', function () {
568 it('Should fail without an incorrect input file', async function () {
569 const fields = {}
570 const attaches = {
a1587156 571 avatarfile: join(__dirname, '..', '..', 'fixtures', 'video_short.mp4')
c5911fd3 572 }
ac81d1a0 573 await makeUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches })
c5911fd3
C
574 })
575
01de67b9
C
576 it('Should fail with a big file', async function () {
577 const fields = {}
578 const attaches = {
a1587156 579 avatarfile: join(__dirname, '..', '..', 'fixtures', 'avatar-big.png')
01de67b9 580 }
ac81d1a0 581 await makeUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches })
01de67b9
C
582 })
583
4bbfc6c6
C
584 it('Should fail with an unauthenticated user', async function () {
585 const fields = {}
586 const attaches = {
a1587156 587 avatarfile: join(__dirname, '..', '..', 'fixtures', 'avatar.png')
4bbfc6c6
C
588 }
589 await makeUploadRequest({
590 url: server.url,
591 path: path + '/me/avatar/pick',
592 fields,
593 attaches,
594 statusCodeExpected: 401
595 })
596 })
597
c5911fd3
C
598 it('Should succeed with the correct params', async function () {
599 const fields = {}
600 const attaches = {
a1587156 601 avatarfile: join(__dirname, '..', '..', 'fixtures', 'avatar.png')
c5911fd3 602 }
ac81d1a0 603 await makeUploadRequest({
47564bbe
C
604 url: server.url,
605 path: path + '/me/avatar/pick',
606 token: server.accessToken,
607 fields,
608 attaches,
609 statusCodeExpected: 200
610 })
c5911fd3
C
611 })
612 })
613
18490b07
C
614 describe('When managing my scoped tokens', function () {
615
616 it('Should fail to get my scoped tokens with an non authenticated user', async function () {
617 await getUserScopedTokens(server.url, null, 401)
618 })
619
620 it('Should fail to get my scoped tokens with a bad token', async function () {
621 await getUserScopedTokens(server.url, 'bad', 401)
622
623 })
624
625 it('Should succeed to get my scoped tokens', async function () {
626 await getUserScopedTokens(server.url, server.accessToken)
627 })
628
629 it('Should fail to renew my scoped tokens with an non authenticated user', async function () {
630 await renewUserScopedTokens(server.url, null, 401)
631 })
632
633 it('Should fail to renew my scoped tokens with a bad token', async function () {
634 await renewUserScopedTokens(server.url, 'bad', 401)
635 })
636
637 it('Should succeed to renew my scoped tokens', async function () {
638 await renewUserScopedTokens(server.url, server.accessToken)
639 })
640 })
641
94ff4c23 642 describe('When getting a user', function () {
94ff4c23
C
643
644 it('Should fail with an non authenticated user', async function () {
645 await makeGetRequest({ url: server.url, path: path + userId, token: 'super token', statusCodeExpected: 401 })
646 })
647
648 it('Should fail with a non admin user', async function () {
649 await makeGetRequest({ url: server.url, path, token: userAccessToken, statusCodeExpected: 403 })
650 })
651
652 it('Should succeed with the correct params', async function () {
653 await makeGetRequest({ url: server.url, path: path + userId, token: server.accessToken, statusCodeExpected: 200 })
654 })
655 })
656
77a5501f
C
657 describe('When updating a user', function () {
658
77a5501f
C
659 it('Should fail with an invalid email attribute', async function () {
660 const fields = {
661 email: 'blabla'
662 }
663
664 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
665 })
666
fc2ec87a
JM
667 it('Should fail with an invalid emailVerified attribute', async function () {
668 const fields = {
669 emailVerified: 'yes'
670 }
671
672 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
673 })
674
77a5501f
C
675 it('Should fail with an invalid videoQuota attribute', async function () {
676 const fields = {
677 videoQuota: -90
678 }
679
680 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
681 })
682
757f0da3
C
683 it('Should fail with an invalid user role attribute', async function () {
684 const fields = {
685 role: 54878
686 }
687
688 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
689 })
690
b426edd4
C
691 it('Should fail with a too small password', async function () {
692 const fields = {
693 currentPassword: 'my super password',
694 password: 'bla'
695 }
696
697 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
698 })
699
700 it('Should fail with a too long password', async function () {
701 const fields = {
702 currentPassword: 'my super password',
703 password: 'super'.repeat(61)
704 }
705
706 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
707 })
708
77a5501f
C
709 it('Should fail with an non authenticated user', async function () {
710 const fields = {
711 videoQuota: 42
712 }
713
714 await makePutBodyRequest({ url: server.url, path: path + userId, token: 'super token', fields, statusCodeExpected: 401 })
715 })
716
f8b8c36b
C
717 it('Should fail when updating root role', async function () {
718 const fields = {
719 role: UserRole.MODERATOR
720 }
721
722 await makePutBodyRequest({ url: server.url, path: path + rootId, token: server.accessToken, fields })
1eddc9a7
C
723 })
724
725 it('Should fail with invalid admin flags', async function () {
726 const fields = { adminFlags: 'toto' }
727
a95a4cc8
C
728 await makePutBodyRequest({ url: server.url, path, token: server.accessToken, fields })
729 })
730
731 it('Should fail to update an admin with a moderator', async function () {
732 const fields = {
733 videoQuota: 42
734 }
735
736 await makePutBodyRequest({
737 url: server.url,
738 path: path + moderatorId,
739 token: moderatorAccessToken,
740 fields,
741 statusCodeExpected: 403
742 })
743 })
744
745 it('Should succeed to update a user with a moderator', async function () {
746 const fields = {
747 videoQuota: 42
748 }
749
750 await makePutBodyRequest({
751 url: server.url,
752 path: path + userId,
753 token: moderatorAccessToken,
754 fields,
755 statusCodeExpected: 204
756 })
f8b8c36b
C
757 })
758
77a5501f
C
759 it('Should succeed with the correct params', async function () {
760 const fields = {
761 email: 'email@example.com',
fc2ec87a 762 emailVerified: true,
757f0da3 763 videoQuota: 42,
2f1548fd 764 role: UserRole.USER
77a5501f
C
765 }
766
767 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields, statusCodeExpected: 204 })
0e1dc3e7
C
768 })
769 })
770
771 describe('When getting my information', function () {
772 it('Should fail with a non authenticated user', async function () {
26d21b78 773 await getMyUserInformation(server.url, 'fake_token', 401)
0e1dc3e7
C
774 })
775
776 it('Should success with the correct parameters', async function () {
26d21b78 777 await getMyUserInformation(server.url, userAccessToken)
0e1dc3e7
C
778 })
779 })
780
781 describe('When getting my video rating', function () {
782 it('Should fail with a non authenticated user', async function () {
26d21b78 783 await getMyUserVideoRating(server.url, 'fake_token', videoId, 401)
0e1dc3e7
C
784 })
785
786 it('Should fail with an incorrect video uuid', async function () {
26d21b78 787 await getMyUserVideoRating(server.url, server.accessToken, 'blabla', 400)
0e1dc3e7
C
788 })
789
790 it('Should fail with an unknown video', async function () {
26d21b78 791 await getMyUserVideoRating(server.url, server.accessToken, '4da6fde3-88f7-4d16-b119-108df5630b06', 404)
0e1dc3e7
C
792 })
793
26d21b78
C
794 it('Should succeed with the correct parameters', async function () {
795 await getMyUserVideoRating(server.url, server.accessToken, videoId)
0e1dc3e7
C
796 })
797 })
798
22834691
C
799 describe('When retrieving my global ratings', function () {
800 const path = '/api/v1/accounts/user1/ratings'
801
802 it('Should fail with a bad start pagination', async function () {
803 await checkBadStartPagination(server.url, path, userAccessToken)
804 })
805
806 it('Should fail with a bad count pagination', async function () {
807 await checkBadCountPagination(server.url, path, userAccessToken)
808 })
809
810 it('Should fail with an incorrect sort', async function () {
811 await checkBadSortPagination(server.url, path, userAccessToken)
812 })
813
814 it('Should fail with a unauthenticated user', async function () {
815 await makeGetRequest({ url: server.url, path, statusCodeExpected: 401 })
816 })
817
818 it('Should fail with a another user', async function () {
819 await makeGetRequest({ url: server.url, path, token: server.accessToken, statusCodeExpected: 403 })
820 })
821
822 it('Should fail with a bad type', async function () {
823 await makeGetRequest({ url: server.url, path, token: userAccessToken, query: { rating: 'toto ' }, statusCodeExpected: 400 })
824 })
825
826 it('Should succeed with the correct params', async function () {
827 await makeGetRequest({ url: server.url, path, token: userAccessToken, statusCodeExpected: 200 })
828 })
829 })
830
e6921918 831 describe('When blocking/unblocking/removing user', function () {
0e1dc3e7 832 it('Should fail with an incorrect id', async function () {
26d21b78 833 await removeUser(server.url, 'blabla', server.accessToken, 400)
e6921918
C
834 await blockUser(server.url, 'blabla', server.accessToken, 400)
835 await unblockUser(server.url, 'blabla', server.accessToken, 400)
0e1dc3e7
C
836 })
837
838 it('Should fail with the root user', async function () {
26d21b78 839 await removeUser(server.url, rootId, server.accessToken, 400)
e6921918
C
840 await blockUser(server.url, rootId, server.accessToken, 400)
841 await unblockUser(server.url, rootId, server.accessToken, 400)
0e1dc3e7
C
842 })
843
844 it('Should return 404 with a non existing id', async function () {
26d21b78 845 await removeUser(server.url, 4545454, server.accessToken, 404)
e6921918
C
846 await blockUser(server.url, 4545454, server.accessToken, 404)
847 await unblockUser(server.url, 4545454, server.accessToken, 404)
848 })
849
850 it('Should fail with a non admin user', async function () {
851 await removeUser(server.url, userId, userAccessToken, 403)
852 await blockUser(server.url, userId, userAccessToken, 403)
853 await unblockUser(server.url, userId, userAccessToken, 403)
0e1dc3e7 854 })
a95a4cc8
C
855
856 it('Should fail on a moderator with a moderator', async function () {
857 await removeUser(server.url, moderatorId, moderatorAccessToken, 403)
858 await blockUser(server.url, moderatorId, moderatorAccessToken, 403)
859 await unblockUser(server.url, moderatorId, moderatorAccessToken, 403)
860 })
861
862 it('Should succeed on a user with a moderator', async function () {
863 await blockUser(server.url, userId, moderatorAccessToken)
864 await unblockUser(server.url, userId, moderatorAccessToken)
865 })
0e1dc3e7
C
866 })
867
92b9d60c
C
868 describe('When deleting our account', function () {
869 it('Should fail with with the root account', async function () {
870 await deleteMe(server.url, server.accessToken, 400)
871 })
872 })
873
e590b4a5 874 describe('When registering a new user', function () {
0e1dc3e7 875 const registrationPath = path + '/register'
26d21b78
C
876 const baseCorrectParams = {
877 username: 'user3',
1f20622f 878 displayName: 'super user',
26d21b78
C
879 email: 'test3@example.com',
880 password: 'my super password'
881 }
0e1dc3e7
C
882
883 it('Should fail with a too small username', async function () {
d0ce42c1 884 const fields = immutableAssign(baseCorrectParams, { username: '' })
0e1dc3e7
C
885
886 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
887 })
888
889 it('Should fail with a too long username', async function () {
9f7a1953 890 const fields = immutableAssign(baseCorrectParams, { username: 'super'.repeat(50) })
0e1dc3e7
C
891
892 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
893 })
894
895 it('Should fail with an incorrect username', async function () {
26d21b78 896 const fields = immutableAssign(baseCorrectParams, { username: 'my username' })
0e1dc3e7
C
897
898 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
899 })
900
901 it('Should fail with a missing email', async function () {
26d21b78 902 const fields = omit(baseCorrectParams, 'email')
0e1dc3e7
C
903
904 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
905 })
906
907 it('Should fail with an invalid email', async function () {
26d21b78 908 const fields = immutableAssign(baseCorrectParams, { email: 'test_example.com' })
0e1dc3e7
C
909
910 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
911 })
912
913 it('Should fail with a too small password', async function () {
26d21b78 914 const fields = immutableAssign(baseCorrectParams, { password: 'bla' })
0e1dc3e7
C
915
916 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
917 })
918
919 it('Should fail with a too long password', async function () {
26d21b78 920 const fields = immutableAssign(baseCorrectParams, { password: 'super'.repeat(61) })
0e1dc3e7
C
921
922 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
923 })
924
925 it('Should fail if we register a user with the same username', async function () {
26d21b78 926 const fields = immutableAssign(baseCorrectParams, { username: 'root' })
0e1dc3e7 927
26d21b78
C
928 await makePostBodyRequest({
929 url: server.url,
930 path: registrationPath,
931 token: server.accessToken,
932 fields,
933 statusCodeExpected: 409
934 })
0e1dc3e7
C
935 })
936
2ef6a063
C
937 it('Should fail with a "peertube" username', async function () {
938 const fields = immutableAssign(baseCorrectParams, { username: 'peertube' })
939
940 await makePostBodyRequest({
941 url: server.url,
942 path: registrationPath,
943 token: server.accessToken,
944 fields,
945 statusCodeExpected: 409
946 })
947 })
948
0e1dc3e7 949 it('Should fail if we register a user with the same email', async function () {
7c3b7976 950 const fields = immutableAssign(baseCorrectParams, { email: 'admin' + server.internalServerNumber + '@example.com' })
0e1dc3e7 951
26d21b78
C
952 await makePostBodyRequest({
953 url: server.url,
954 path: registrationPath,
955 token: server.accessToken,
956 fields,
957 statusCodeExpected: 409
958 })
0e1dc3e7
C
959 })
960
1f20622f
C
961 it('Should fail with a bad display name', async function () {
962 const fields = immutableAssign(baseCorrectParams, { displayName: 'a'.repeat(150) })
963
964 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
965 })
966
e590b4a5
C
967 it('Should fail with a bad channel name', async function () {
968 const fields = immutableAssign(baseCorrectParams, { channel: { name: '[]azf', displayName: 'toto' } })
969
970 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
971 })
972
973 it('Should fail with a bad channel display name', async function () {
974 const fields = immutableAssign(baseCorrectParams, { channel: { name: 'toto', displayName: '' } })
975
976 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
977 })
978
32d7f2b7 979 it('Should fail with a channel name that is the same as username', async function () {
1d5342ab
C
980 const source = { username: 'super_user', channel: { name: 'super_user', displayName: 'display name' } }
981 const fields = immutableAssign(baseCorrectParams, source)
982
983 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
984 })
985
e590b4a5
C
986 it('Should fail with an existing channel', async function () {
987 const videoChannelAttributesArg = { name: 'existing_channel', displayName: 'hello', description: 'super description' }
988 await addVideoChannel(server.url, server.accessToken, videoChannelAttributesArg)
989
990 const fields = immutableAssign(baseCorrectParams, { channel: { name: 'existing_channel', displayName: 'toto' } })
991
992 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields, statusCodeExpected: 409 })
993 })
994
0e1dc3e7 995 it('Should succeed with the correct params', async function () {
e590b4a5
C
996 const fields = immutableAssign(baseCorrectParams, { channel: { name: 'super_channel', displayName: 'toto' } })
997
26d21b78
C
998 await makePostBodyRequest({
999 url: server.url,
1000 path: registrationPath,
1001 token: server.accessToken,
e590b4a5 1002 fields: fields,
26d21b78
C
1003 statusCodeExpected: 204
1004 })
0e1dc3e7
C
1005 })
1006
1007 it('Should fail on a server with registration disabled', async function () {
1008 const fields = {
1009 username: 'user4',
1010 email: 'test4@example.com',
1011 password: 'my super password 4'
1012 }
1013
1014 await makePostBodyRequest({
1015 url: serverWithRegistrationDisabled.url,
1016 path: registrationPath,
1017 token: serverWithRegistrationDisabled.accessToken,
1018 fields,
1019 statusCodeExpected: 403
1020 })
1021 })
1022 })
1023
1024 describe('When registering multiple users on a server with users limit', function () {
1025 it('Should fail when after 3 registrations', async function () {
1026 await registerUser(server.url, 'user42', 'super password', 403)
1027 })
1028 })
1029
77a5501f 1030 describe('When having a video quota', function () {
bee0abff 1031 it('Should fail with a user having too many videos', async function () {
26d21b78
C
1032 await updateUser({
1033 url: server.url,
1034 userId: rootId,
1035 accessToken: server.accessToken,
77a5501f 1036 videoQuota: 42
26d21b78 1037 })
77a5501f 1038
26d21b78 1039 await uploadVideo(server.url, server.accessToken, {}, 403)
77a5501f
C
1040 })
1041
bee0abff 1042 it('Should fail with a registered user having too many videos', async function () {
adc236fe 1043 this.timeout(30000)
77a5501f 1044
26d21b78 1045 const user = {
77a5501f 1046 username: 'user3',
77a5501f
C
1047 password: 'my super password'
1048 }
26d21b78 1049 userAccessToken = await userLogin(server, user)
77a5501f
C
1050
1051 const videoAttributes = { fixture: 'video_short2.webm' }
1052 await uploadVideo(server.url, userAccessToken, videoAttributes)
1053 await uploadVideo(server.url, userAccessToken, videoAttributes)
1054 await uploadVideo(server.url, userAccessToken, videoAttributes)
1055 await uploadVideo(server.url, userAccessToken, videoAttributes)
1056 await uploadVideo(server.url, userAccessToken, videoAttributes)
1057 await uploadVideo(server.url, userAccessToken, videoAttributes, 403)
1058 })
187501f8
C
1059
1060 it('Should fail to import with HTTP/Torrent/magnet', async function () {
a031ab0b 1061 this.timeout(120000)
187501f8
C
1062
1063 const baseAttributes = {
1064 channelId: 1,
1065 privacy: VideoPrivacy.PUBLIC
1066 }
b488ba1e 1067 await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { targetUrl: getGoodVideoUrl() }))
187501f8 1068 await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { magnetUri: getMagnetURI() }))
9a7fd960 1069 await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { torrentfile: 'video-720p.torrent' as any }))
187501f8
C
1070
1071 await waitJobs([ server ])
1072
1073 const res = await getMyVideoImports(server.url, server.accessToken)
1074
1075 expect(res.body.total).to.equal(3)
1076 const videoImports: VideoImport[] = res.body.data
1077 expect(videoImports).to.have.lengthOf(3)
1078
1079 for (const videoImport of videoImports) {
1080 expect(videoImport.state.id).to.equal(VideoImportState.FAILED)
1081 expect(videoImport.error).not.to.be.undefined
1082 expect(videoImport.error).to.contain('user video quota is exceeded')
1083 }
1084 })
77a5501f
C
1085 })
1086
bee0abff
FA
1087 describe('When having a daily video quota', function () {
1088 it('Should fail with a user having too many videos', async function () {
1089 await updateUser({
1090 url: server.url,
1091 userId: rootId,
1092 accessToken: server.accessToken,
1093 videoQuotaDaily: 42
1094 })
1095
1096 await uploadVideo(server.url, server.accessToken, {}, 403)
1097 })
1098 })
1099
1100 describe('When having an absolute and daily video quota', function () {
1101 it('Should fail if exceeding total quota', async function () {
1102 await updateUser({
1103 url: server.url,
1104 userId: rootId,
1105 accessToken: server.accessToken,
1106 videoQuota: 42,
1107 videoQuotaDaily: 1024 * 1024 * 1024
1108 })
1109
1110 await uploadVideo(server.url, server.accessToken, {}, 403)
1111 })
1112
1113 it('Should fail if exceeding daily quota', async function () {
1114 await updateUser({
1115 url: server.url,
1116 userId: rootId,
1117 accessToken: server.accessToken,
1118 videoQuota: 1024 * 1024 * 1024,
1119 videoQuotaDaily: 42
1120 })
1121
1122 await uploadVideo(server.url, server.accessToken, {}, 403)
1123 })
1124 })
1125
f076daa7
C
1126 describe('When asking a password reset', function () {
1127 const path = '/api/v1/users/ask-reset-password'
1128
1129 it('Should fail with a missing email', async function () {
1130 const fields = {}
1131
1132 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
1133 })
1134
1135 it('Should fail with an invalid email', async function () {
1136 const fields = { email: 'hello' }
1137
1138 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
1139 })
1140
1141 it('Should success with the correct params', async function () {
1142 const fields = { email: 'admin@example.com' }
1143
1144 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 })
1145 })
1146 })
1147
d9eaee39
JM
1148 describe('When asking for an account verification email', function () {
1149 const path = '/api/v1/users/ask-send-verify-email'
1150
1151 it('Should fail with a missing email', async function () {
1152 const fields = {}
1153
1154 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
1155 })
1156
1157 it('Should fail with an invalid email', async function () {
1158 const fields = { email: 'hello' }
1159
1160 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
1161 })
1162
1163 it('Should succeed with the correct params', async function () {
1164 const fields = { email: 'admin@example.com' }
1165
1166 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 })
1167 })
1168 })
1169
7c3b7976 1170 after(async function () {
45f1bd72
JL
1171 MockSmtpServer.Instance.kill()
1172
7c3b7976 1173 await cleanupTests([ server, serverWithRegistrationDisabled ])
0e1dc3e7
C
1174 })
1175})