Redundancy and search tests in parallel too
[oweals/peertube.git] / server / tests / api / users / users.ts
1 /* tslint:disable:no-unused-expression */
2
3 import * as chai from 'chai'
4 import 'mocha'
5 import { User, UserRole, Video } from '../../../../shared/index'
6 import {
7   blockUser,
8   cleanupTests,
9   createUser,
10   deleteMe,
11   flushAndRunServer,
12   getAccountRatings,
13   getBlacklistedVideosList,
14   getMyUserInformation,
15   getMyUserVideoQuotaUsed,
16   getMyUserVideoRating,
17   getUserInformation,
18   getUsersList,
19   getUsersListPaginationAndSort,
20   getVideosList,
21   login,
22   makePutBodyRequest,
23   rateVideo,
24   registerUser,
25   removeUser,
26   removeVideo,
27   ServerInfo,
28   testImage,
29   unblockUser,
30   updateMyAvatar,
31   updateMyUser,
32   updateUser,
33   uploadVideo,
34   userLogin
35 } from '../../../../shared/extra-utils'
36 import { follow } from '../../../../shared/extra-utils/server/follows'
37 import { setAccessTokensToServers } from '../../../../shared/extra-utils/users/login'
38 import { getMyVideos } from '../../../../shared/extra-utils/videos/videos'
39 import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model'
40
41 const expect = chai.expect
42
43 describe('Test users', function () {
44   let server: ServerInfo
45   let accessToken: string
46   let accessTokenUser: string
47   let videoId: number
48   let userId: number
49   const user = {
50     username: 'user_1',
51     password: 'super password'
52   }
53
54   before(async function () {
55     this.timeout(30000)
56     server = await flushAndRunServer(1)
57
58     await setAccessTokensToServers([ server ])
59   })
60
61   describe('OAuth client', function () {
62     it('Should create a new client')
63
64     it('Should return the first client')
65
66     it('Should remove the last client')
67
68     it('Should not login with an invalid client id', async function () {
69       const client = { id: 'client', secret: server.client.secret }
70       const res = await login(server.url, client, server.user, 400)
71
72       expect(res.body.error).to.contain('client is invalid')
73     })
74
75     it('Should not login with an invalid client secret', async function () {
76       const client = { id: server.client.id, secret: 'coucou' }
77       const res = await login(server.url, client, server.user, 400)
78
79       expect(res.body.error).to.contain('client is invalid')
80     })
81   })
82
83   describe('Login', function () {
84
85     it('Should not login with an invalid username', async function () {
86       const user = { username: 'captain crochet', password: server.user.password }
87       const res = await login(server.url, server.client, user, 400)
88
89       expect(res.body.error).to.contain('credentials are invalid')
90     })
91
92     it('Should not login with an invalid password', async function () {
93       const user = { username: server.user.username, password: 'mew_three' }
94       const res = await login(server.url, server.client, user, 400)
95
96       expect(res.body.error).to.contain('credentials are invalid')
97     })
98
99     it('Should not be able to upload a video', async function () {
100       accessToken = 'my_super_token'
101
102       const videoAttributes = {}
103       await uploadVideo(server.url, accessToken, videoAttributes, 401)
104     })
105
106     it('Should not be able to follow', async function () {
107       accessToken = 'my_super_token'
108       await follow(server.url, [ 'http://example.com' ], accessToken, 401)
109     })
110
111     it('Should not be able to unfollow')
112
113     it('Should be able to login', async function () {
114       const res = await login(server.url, server.client, server.user, 200)
115
116       accessToken = res.body.access_token
117     })
118   })
119
120   describe('Upload', function () {
121
122     it('Should upload the video with the correct token', async function () {
123       const videoAttributes = {}
124       await uploadVideo(server.url, accessToken, videoAttributes)
125       const res = await getVideosList(server.url)
126       const video = res.body.data[ 0 ]
127
128       expect(video.account.name).to.equal('root')
129       videoId = video.id
130     })
131
132     it('Should upload the video again with the correct token', async function () {
133       const videoAttributes = {}
134       await uploadVideo(server.url, accessToken, videoAttributes)
135     })
136   })
137
138   describe('Ratings', function () {
139
140     it('Should retrieve a video rating', async function () {
141       await rateVideo(server.url, accessToken, videoId, 'like')
142       const res = await getMyUserVideoRating(server.url, accessToken, videoId)
143       const rating = res.body
144
145       expect(rating.videoId).to.equal(videoId)
146       expect(rating.rating).to.equal('like')
147     })
148
149     it('Should retrieve ratings list', async function () {
150       await rateVideo(server.url, accessToken, videoId, 'like')
151
152       const res = await getAccountRatings(server.url, server.user.username, server.accessToken, null, 200)
153       const ratings = res.body
154
155       expect(ratings.total).to.equal(1)
156       expect(ratings.data[ 0 ].video.id).to.equal(videoId)
157       expect(ratings.data[ 0 ].rating).to.equal('like')
158     })
159
160     it('Should retrieve ratings list by rating type', async function () {
161       {
162         const res = await getAccountRatings(server.url, server.user.username, server.accessToken, 'like')
163         const ratings = res.body
164         expect(ratings.data.length).to.equal(1)
165       }
166
167       {
168         const res = await getAccountRatings(server.url, server.user.username, server.accessToken, 'dislike')
169         const ratings = res.body
170         expect(ratings.data.length).to.equal(0)
171       }
172     })
173   })
174
175   describe('Remove video', function () {
176     it('Should not be able to remove the video with an incorrect token', async function () {
177       await removeVideo(server.url, 'bad_token', videoId, 401)
178     })
179
180     it('Should not be able to remove the video with the token of another account')
181
182     it('Should be able to remove the video with the correct token', async function () {
183       await removeVideo(server.url, accessToken, videoId)
184     })
185   })
186
187   describe('Logout', function () {
188     it('Should logout (revoke token)')
189
190     it('Should not be able to get the user information')
191
192     it('Should not be able to upload a video')
193
194     it('Should not be able to remove a video')
195
196     it('Should not be able to rate a video', async function () {
197       const path = '/api/v1/videos/'
198       const data = {
199         rating: 'likes'
200       }
201
202       const options = {
203         url: server.url,
204         path: path + videoId,
205         token: 'wrong token',
206         fields: data,
207         statusCodeExpected: 401
208       }
209       await makePutBodyRequest(options)
210     })
211
212     it('Should be able to login again')
213
214     it('Should have an expired access token')
215
216     it('Should refresh the token')
217
218     it('Should be able to upload a video again')
219   })
220
221   describe('Creating a user', function () {
222
223     it('Should be able to create a new user', async function () {
224       await createUser({
225         url: server.url,
226         accessToken: accessToken,
227         username: user.username,
228         password: user.password,
229         videoQuota: 2 * 1024 * 1024,
230         adminFlags: UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST
231       })
232     })
233
234     it('Should be able to login with this user', async function () {
235       accessTokenUser = await userLogin(server, user)
236     })
237
238     it('Should be able to get user information', async function () {
239       const res1 = await getMyUserInformation(server.url, accessTokenUser)
240       const userMe: User = res1.body
241
242       const res2 = await getUserInformation(server.url, server.accessToken, userMe.id)
243       const userGet: User = res2.body
244
245       for (const user of [ userMe, userGet ]) {
246         expect(user.username).to.equal('user_1')
247         expect(user.email).to.equal('user_1@example.com')
248         expect(user.nsfwPolicy).to.equal('display')
249         expect(user.videoQuota).to.equal(2 * 1024 * 1024)
250         expect(user.roleLabel).to.equal('User')
251         expect(user.id).to.be.a('number')
252         expect(user.account.displayName).to.equal('user_1')
253         expect(user.account.description).to.be.null
254       }
255
256       expect(userMe.adminFlags).to.be.undefined
257       expect(userGet.adminFlags).to.equal(UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST)
258     })
259   })
260
261   describe('My videos & quotas', function () {
262
263     it('Should be able to upload a video with this user', async function () {
264       this.timeout(5000)
265
266       const videoAttributes = {
267         name: 'super user video',
268         fixture: 'video_short.webm'
269       }
270       await uploadVideo(server.url, accessTokenUser, videoAttributes)
271     })
272
273     it('Should have video quota updated', async function () {
274       const res = await getMyUserVideoQuotaUsed(server.url, accessTokenUser)
275       const data = res.body
276
277       expect(data.videoQuotaUsed).to.equal(218910)
278
279       const resUsers = await getUsersList(server.url, server.accessToken)
280
281       const users: User[] = resUsers.body.data
282       const tmpUser = users.find(u => u.username === user.username)
283       expect(tmpUser.videoQuotaUsed).to.equal(218910)
284     })
285
286     it('Should be able to list my videos', async function () {
287       const res = await getMyVideos(server.url, accessTokenUser, 0, 5)
288       expect(res.body.total).to.equal(1)
289
290       const videos = res.body.data
291       expect(videos).to.have.lengthOf(1)
292
293       const video: Video = videos[ 0 ]
294       expect(video.name).to.equal('super user video')
295       expect(video.thumbnailPath).to.not.be.null
296       expect(video.previewPath).to.not.be.null
297     })
298   })
299
300   describe('Users listing', function () {
301
302     it('Should list all the users', async function () {
303       const res = await getUsersList(server.url, server.accessToken)
304       const result = res.body
305       const total = result.total
306       const users = result.data
307
308       expect(total).to.equal(2)
309       expect(users).to.be.an('array')
310       expect(users.length).to.equal(2)
311
312       const user = users[ 0 ]
313       expect(user.username).to.equal('user_1')
314       expect(user.email).to.equal('user_1@example.com')
315       expect(user.nsfwPolicy).to.equal('display')
316
317       const rootUser = users[ 1 ]
318       expect(rootUser.username).to.equal('root')
319       expect(rootUser.email).to.equal('admin1@example.com')
320       expect(user.nsfwPolicy).to.equal('display')
321
322       userId = user.id
323     })
324
325     it('Should list only the first user by username asc', async function () {
326       const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 1, 'username')
327
328       const result = res.body
329       const total = result.total
330       const users = result.data
331
332       expect(total).to.equal(2)
333       expect(users.length).to.equal(1)
334
335       const user = users[ 0 ]
336       expect(user.username).to.equal('root')
337       expect(user.email).to.equal('admin1@example.com')
338       expect(user.roleLabel).to.equal('Administrator')
339       expect(user.nsfwPolicy).to.equal('display')
340     })
341
342     it('Should list only the first user by username desc', async function () {
343       const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 1, '-username')
344       const result = res.body
345       const total = result.total
346       const users = result.data
347
348       expect(total).to.equal(2)
349       expect(users.length).to.equal(1)
350
351       const user = users[ 0 ]
352       expect(user.username).to.equal('user_1')
353       expect(user.email).to.equal('user_1@example.com')
354       expect(user.nsfwPolicy).to.equal('display')
355     })
356
357     it('Should list only the second user by createdAt desc', async function () {
358       const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 1, '-createdAt')
359       const result = res.body
360       const total = result.total
361       const users = result.data
362
363       expect(total).to.equal(2)
364       expect(users.length).to.equal(1)
365
366       const user = users[ 0 ]
367       expect(user.username).to.equal('user_1')
368       expect(user.email).to.equal('user_1@example.com')
369       expect(user.nsfwPolicy).to.equal('display')
370     })
371
372     it('Should list all the users by createdAt asc', async function () {
373       const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 2, 'createdAt')
374       const result = res.body
375       const total = result.total
376       const users = result.data
377
378       expect(total).to.equal(2)
379       expect(users.length).to.equal(2)
380
381       expect(users[ 0 ].username).to.equal('root')
382       expect(users[ 0 ].email).to.equal('admin1@example.com')
383       expect(users[ 0 ].nsfwPolicy).to.equal('display')
384
385       expect(users[ 1 ].username).to.equal('user_1')
386       expect(users[ 1 ].email).to.equal('user_1@example.com')
387       expect(users[ 1 ].nsfwPolicy).to.equal('display')
388     })
389
390     it('Should search user by username', async function () {
391       const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 2, 'createdAt', 'oot')
392       const users = res.body.data as User[]
393
394       expect(res.body.total).to.equal(1)
395       expect(users.length).to.equal(1)
396
397       expect(users[ 0 ].username).to.equal('root')
398     })
399
400     it('Should search user by email', async function () {
401       {
402         const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 2, 'createdAt', 'r_1@exam')
403         const users = res.body.data as User[]
404
405         expect(res.body.total).to.equal(1)
406         expect(users.length).to.equal(1)
407
408         expect(users[ 0 ].username).to.equal('user_1')
409         expect(users[ 0 ].email).to.equal('user_1@example.com')
410       }
411
412       {
413         const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 2, 'createdAt', 'example')
414         const users = res.body.data as User[]
415
416         expect(res.body.total).to.equal(2)
417         expect(users.length).to.equal(2)
418
419         expect(users[ 0 ].username).to.equal('root')
420         expect(users[ 1 ].username).to.equal('user_1')
421       }
422     })
423   })
424
425   describe('Update my account', function () {
426     it('Should update my password', async function () {
427       await updateMyUser({
428         url: server.url,
429         accessToken: accessTokenUser,
430         currentPassword: 'super password',
431         newPassword: 'new password'
432       })
433       user.password = 'new password'
434
435       await userLogin(server, user, 200)
436     })
437
438     it('Should be able to change the NSFW display attribute', async function () {
439       await updateMyUser({
440         url: server.url,
441         accessToken: accessTokenUser,
442         nsfwPolicy: 'do_not_list'
443       })
444
445       const res = await getMyUserInformation(server.url, accessTokenUser)
446       const user = res.body
447
448       expect(user.username).to.equal('user_1')
449       expect(user.email).to.equal('user_1@example.com')
450       expect(user.nsfwPolicy).to.equal('do_not_list')
451       expect(user.videoQuota).to.equal(2 * 1024 * 1024)
452       expect(user.id).to.be.a('number')
453       expect(user.account.displayName).to.equal('user_1')
454       expect(user.account.description).to.be.null
455     })
456
457     it('Should be able to change the autoPlayVideo attribute', async function () {
458       await updateMyUser({
459         url: server.url,
460         accessToken: accessTokenUser,
461         autoPlayVideo: false
462       })
463
464       const res = await getMyUserInformation(server.url, accessTokenUser)
465       const user = res.body
466
467       expect(user.autoPlayVideo).to.be.false
468     })
469
470     it('Should be able to change the email display attribute', async function () {
471       await updateMyUser({
472         url: server.url,
473         accessToken: accessTokenUser,
474         email: 'updated@example.com'
475       })
476
477       const res = await getMyUserInformation(server.url, accessTokenUser)
478       const user = res.body
479
480       expect(user.username).to.equal('user_1')
481       expect(user.email).to.equal('updated@example.com')
482       expect(user.nsfwPolicy).to.equal('do_not_list')
483       expect(user.videoQuota).to.equal(2 * 1024 * 1024)
484       expect(user.id).to.be.a('number')
485       expect(user.account.displayName).to.equal('user_1')
486       expect(user.account.description).to.be.null
487     })
488
489     it('Should be able to update my avatar', async function () {
490       const fixture = 'avatar.png'
491
492       await updateMyAvatar({
493         url: server.url,
494         accessToken: accessTokenUser,
495         fixture
496       })
497
498       const res = await getMyUserInformation(server.url, accessTokenUser)
499       const user = res.body
500
501       await testImage(server.url, 'avatar-resized', user.account.avatar.path, '.png')
502     })
503
504     it('Should be able to update my display name', async function () {
505       await updateMyUser({
506         url: server.url,
507         accessToken: accessTokenUser,
508         displayName: 'new display name'
509       })
510
511       const res = await getMyUserInformation(server.url, accessTokenUser)
512       const user = res.body
513
514       expect(user.username).to.equal('user_1')
515       expect(user.email).to.equal('updated@example.com')
516       expect(user.nsfwPolicy).to.equal('do_not_list')
517       expect(user.videoQuota).to.equal(2 * 1024 * 1024)
518       expect(user.id).to.be.a('number')
519       expect(user.account.displayName).to.equal('new display name')
520       expect(user.account.description).to.be.null
521     })
522
523     it('Should be able to update my description', async function () {
524       await updateMyUser({
525         url: server.url,
526         accessToken: accessTokenUser,
527         description: 'my super description updated'
528       })
529
530       const res = await getMyUserInformation(server.url, accessTokenUser)
531       const user = res.body
532
533       expect(user.username).to.equal('user_1')
534       expect(user.email).to.equal('updated@example.com')
535       expect(user.nsfwPolicy).to.equal('do_not_list')
536       expect(user.videoQuota).to.equal(2 * 1024 * 1024)
537       expect(user.id).to.be.a('number')
538       expect(user.account.displayName).to.equal('new display name')
539       expect(user.account.description).to.equal('my super description updated')
540     })
541   })
542
543   describe('Updating another user', function () {
544
545     it('Should be able to update another user', async function () {
546       await updateUser({
547         url: server.url,
548         userId,
549         accessToken,
550         email: 'updated2@example.com',
551         emailVerified: true,
552         videoQuota: 42,
553         role: UserRole.MODERATOR,
554         adminFlags: UserAdminFlag.NONE
555       })
556
557       const res = await getUserInformation(server.url, accessToken, userId)
558       const user = res.body
559
560       expect(user.username).to.equal('user_1')
561       expect(user.email).to.equal('updated2@example.com')
562       expect(user.emailVerified).to.be.true
563       expect(user.nsfwPolicy).to.equal('do_not_list')
564       expect(user.videoQuota).to.equal(42)
565       expect(user.roleLabel).to.equal('Moderator')
566       expect(user.id).to.be.a('number')
567       expect(user.adminFlags).to.equal(UserAdminFlag.NONE)
568     })
569
570     it('Should have removed the user token', async function () {
571       await getMyUserVideoQuotaUsed(server.url, accessTokenUser, 401)
572
573       accessTokenUser = await userLogin(server, user)
574     })
575
576     it('Should be able to update another user password', async function () {
577       await updateUser({
578         url: server.url,
579         userId,
580         accessToken,
581         password: 'password updated'
582       })
583
584       await getMyUserVideoQuotaUsed(server.url, accessTokenUser, 401)
585
586       await userLogin(server, user, 400)
587
588       user.password = 'password updated'
589       accessTokenUser = await userLogin(server, user)
590     })
591   })
592
593   describe('Video blacklists', function () {
594     it('Should be able to list video blacklist by a moderator', async function () {
595       await getBlacklistedVideosList({ url: server.url, token: accessTokenUser })
596     })
597   })
598
599   describe('Remove a user', function () {
600     it('Should be able to remove this user', async function () {
601       await removeUser(server.url, userId, accessToken)
602     })
603
604     it('Should not be able to login with this user', async function () {
605       await userLogin(server, user, 400)
606     })
607
608     it('Should not have videos of this user', async function () {
609       const res = await getVideosList(server.url)
610
611       expect(res.body.total).to.equal(1)
612
613       const video = res.body.data[ 0 ]
614       expect(video.account.name).to.equal('root')
615     })
616   })
617
618   describe('Registering a new user', function () {
619     it('Should register a new user', async function () {
620       await registerUser(server.url, 'user_15', 'my super password')
621     })
622
623     it('Should be able to login with this registered user', async function () {
624       const user15 = {
625         username: 'user_15',
626         password: 'my super password'
627       }
628
629       accessToken = await userLogin(server, user15)
630     })
631
632     it('Should have the correct video quota', async function () {
633       const res = await getMyUserInformation(server.url, accessToken)
634       const user = res.body
635
636       expect(user.videoQuota).to.equal(5 * 1024 * 1024)
637     })
638
639     it('Should remove me', async function () {
640       {
641         const res = await getUsersList(server.url, server.accessToken)
642         expect(res.body.data.find(u => u.username === 'user_15')).to.not.be.undefined
643       }
644
645       await deleteMe(server.url, accessToken)
646
647       {
648         const res = await getUsersList(server.url, server.accessToken)
649         expect(res.body.data.find(u => u.username === 'user_15')).to.be.undefined
650       }
651     })
652   })
653
654   describe('User blocking', function () {
655     it('Should block and unblock a user', async function () {
656       const user16 = {
657         username: 'user_16',
658         password: 'my super password'
659       }
660       const resUser = await createUser({
661         url: server.url,
662         accessToken: server.accessToken,
663         username: user16.username,
664         password: user16.password
665       })
666       const user16Id = resUser.body.user.id
667
668       accessToken = await userLogin(server, user16)
669
670       await getMyUserInformation(server.url, accessToken, 200)
671       await blockUser(server.url, user16Id, server.accessToken)
672
673       await getMyUserInformation(server.url, accessToken, 401)
674       await userLogin(server, user16, 400)
675
676       await unblockUser(server.url, user16Id, server.accessToken)
677       accessToken = await userLogin(server, user16)
678       await getMyUserInformation(server.url, accessToken, 200)
679     })
680   })
681
682   after(async function () {
683     await cleanupTests([ server ])
684   })
685 })