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