Add ability to mute a user/instance by server in client
[oweals/peertube.git] / server / tests / api / users / blocklist.ts
1 /* tslint:disable:no-unused-expression */
2
3 import * as chai from 'chai'
4 import 'mocha'
5 import { AccountBlock, ServerBlock, Video } from '../../../../shared/index'
6 import {
7   createUser,
8   doubleFollow,
9   flushAndRunMultipleServers,
10   flushTests,
11   killallServers,
12   ServerInfo,
13   uploadVideo,
14   userLogin
15 } from '../../utils/index'
16 import { setAccessTokensToServers } from '../../utils/users/login'
17 import { getVideosListWithToken, getVideosList } from '../../utils/videos/videos'
18 import {
19   addVideoCommentReply,
20   addVideoCommentThread,
21   getVideoCommentThreads,
22   getVideoThreadComments
23 } from '../../utils/videos/video-comments'
24 import { waitJobs } from '../../utils/server/jobs'
25 import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
26 import {
27   addAccountToAccountBlocklist,
28   addAccountToServerBlocklist,
29   addServerToAccountBlocklist,
30   addServerToServerBlocklist,
31   getAccountBlocklistByAccount,
32   getAccountBlocklistByServer,
33   getServerBlocklistByAccount,
34   getServerBlocklistByServer,
35   removeAccountFromAccountBlocklist,
36   removeAccountFromServerBlocklist,
37   removeServerFromAccountBlocklist,
38   removeServerFromServerBlocklist
39 } from '../../utils/users/blocklist'
40
41 const expect = chai.expect
42
43 async function checkAllVideos (url: string, token: string) {
44   {
45     const res = await getVideosListWithToken(url, token)
46
47     expect(res.body.data).to.have.lengthOf(4)
48   }
49
50   {
51     const res = await getVideosList(url)
52
53     expect(res.body.data).to.have.lengthOf(4)
54   }
55 }
56
57 async function checkAllComments (url: string, token: string, videoUUID: string) {
58   const resThreads = await getVideoCommentThreads(url, videoUUID, 0, 5, '-createdAt', token)
59
60   const threads: VideoComment[] = resThreads.body.data
61   expect(threads).to.have.lengthOf(2)
62
63   for (const thread of threads) {
64     const res = await getVideoThreadComments(url, videoUUID, thread.id, token)
65
66     const tree: VideoCommentThreadTree = res.body
67     expect(tree.children).to.have.lengthOf(1)
68   }
69 }
70
71 describe('Test blocklist', function () {
72   let servers: ServerInfo[]
73   let videoUUID1: string
74   let videoUUID2: string
75   let userToken1: string
76   let userModeratorToken: string
77   let userToken2: string
78
79   before(async function () {
80     this.timeout(60000)
81
82     await flushTests()
83
84     servers = await flushAndRunMultipleServers(2)
85     await setAccessTokensToServers(servers)
86
87     {
88       const user = { username: 'user1', password: 'password' }
89       await createUser(servers[0].url, servers[0].accessToken, user.username, user.password)
90
91       userToken1 = await userLogin(servers[0], user)
92       await uploadVideo(servers[0].url, userToken1, { name: 'video user 1' })
93     }
94
95     {
96       const user = { username: 'moderator', password: 'password' }
97       await createUser(servers[0].url, servers[0].accessToken, user.username, user.password)
98
99       userModeratorToken = await userLogin(servers[0], user)
100     }
101
102     {
103       const user = { username: 'user2', password: 'password' }
104       await createUser(servers[1].url, servers[1].accessToken, user.username, user.password)
105
106       userToken2 = await userLogin(servers[1], user)
107       await uploadVideo(servers[1].url, userToken2, { name: 'video user 2' })
108     }
109
110     {
111       const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video server 1' })
112       videoUUID1 = res.body.video.uuid
113     }
114
115     {
116       const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video server 2' })
117       videoUUID2 = res.body.video.uuid
118     }
119
120     await doubleFollow(servers[0], servers[1])
121
122     {
123       const resComment = await addVideoCommentThread(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID1, 'comment root 1')
124       const resReply = await addVideoCommentReply(servers[ 0 ].url, userToken1, videoUUID1, resComment.body.comment.id, 'comment user 1')
125       await addVideoCommentReply(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID1, resReply.body.comment.id, 'comment root 1')
126     }
127
128     {
129       const resComment = await addVideoCommentThread(servers[ 0 ].url, userToken1, videoUUID1, 'comment user 1')
130       await addVideoCommentReply(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID1, resComment.body.comment.id, 'comment root 1')
131     }
132
133     await waitJobs(servers)
134   })
135
136   describe('User blocklist', function () {
137
138     describe('When managing account blocklist', function () {
139       it('Should list all videos', function () {
140         return checkAllVideos(servers[ 0 ].url, servers[ 0 ].accessToken)
141       })
142
143       it('Should list the comments', function () {
144         return checkAllComments(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID1)
145       })
146
147       it('Should block a remote account', async function () {
148         await addAccountToAccountBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'user2@localhost:9002')
149       })
150
151       it('Should hide its videos', async function () {
152         const res = await getVideosListWithToken(servers[ 0 ].url, servers[ 0 ].accessToken)
153
154         const videos: Video[] = res.body.data
155         expect(videos).to.have.lengthOf(3)
156
157         const v = videos.find(v => v.name === 'video user 2')
158         expect(v).to.be.undefined
159       })
160
161       it('Should block a local account', async function () {
162         await addAccountToAccountBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'user1')
163       })
164
165       it('Should hide its videos', async function () {
166         const res = await getVideosListWithToken(servers[ 0 ].url, servers[ 0 ].accessToken)
167
168         const videos: Video[] = res.body.data
169         expect(videos).to.have.lengthOf(2)
170
171         const v = videos.find(v => v.name === 'video user 1')
172         expect(v).to.be.undefined
173       })
174
175       it('Should hide its comments', async function () {
176         const resThreads = await getVideoCommentThreads(servers[ 0 ].url, videoUUID1, 0, 5, '-createdAt', servers[ 0 ].accessToken)
177
178         const threads: VideoComment[] = resThreads.body.data
179         expect(threads).to.have.lengthOf(1)
180         expect(threads[ 0 ].totalReplies).to.equal(0)
181
182         const t = threads.find(t => t.text === 'comment user 1')
183         expect(t).to.be.undefined
184
185         for (const thread of threads) {
186           const res = await getVideoThreadComments(servers[ 0 ].url, videoUUID1, thread.id, servers[ 0 ].accessToken)
187
188           const tree: VideoCommentThreadTree = res.body
189           expect(tree.children).to.have.lengthOf(0)
190         }
191       })
192
193       it('Should list all the videos with another user', async function () {
194         return checkAllVideos(servers[ 0 ].url, userToken1)
195       })
196
197       it('Should list all the comments with another user', async function () {
198         return checkAllComments(servers[ 0 ].url, userToken1, videoUUID1)
199       })
200
201       it('Should list blocked accounts', async function () {
202         {
203           const res = await getAccountBlocklistByAccount(servers[ 0 ].url, servers[ 0 ].accessToken, 0, 1, 'createdAt')
204           const blocks: AccountBlock[] = res.body.data
205
206           expect(res.body.total).to.equal(2)
207
208           const block = blocks[ 0 ]
209           expect(block.byAccount.displayName).to.equal('root')
210           expect(block.byAccount.name).to.equal('root')
211           expect(block.blockedAccount.displayName).to.equal('user2')
212           expect(block.blockedAccount.name).to.equal('user2')
213           expect(block.blockedAccount.host).to.equal('localhost:9002')
214         }
215
216         {
217           const res = await getAccountBlocklistByAccount(servers[ 0 ].url, servers[ 0 ].accessToken, 1, 2, 'createdAt')
218           const blocks: AccountBlock[] = res.body.data
219
220           expect(res.body.total).to.equal(2)
221
222           const block = blocks[ 0 ]
223           expect(block.byAccount.displayName).to.equal('root')
224           expect(block.byAccount.name).to.equal('root')
225           expect(block.blockedAccount.displayName).to.equal('user1')
226           expect(block.blockedAccount.name).to.equal('user1')
227           expect(block.blockedAccount.host).to.equal('localhost:9001')
228         }
229       })
230
231       it('Should unblock the remote account', async function () {
232         await removeAccountFromAccountBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'user2@localhost:9002')
233       })
234
235       it('Should display its videos', async function () {
236         const res = await getVideosListWithToken(servers[ 0 ].url, servers[ 0 ].accessToken)
237
238         const videos: Video[] = res.body.data
239         expect(videos).to.have.lengthOf(3)
240
241         const v = videos.find(v => v.name === 'video user 2')
242         expect(v).not.to.be.undefined
243       })
244
245       it('Should unblock the local account', async function () {
246         await removeAccountFromAccountBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'user1')
247       })
248
249       it('Should display its comments', function () {
250         return checkAllComments(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID1)
251       })
252     })
253
254     describe('When managing server blocklist', function () {
255       it('Should list all videos', function () {
256         return checkAllVideos(servers[ 0 ].url, servers[ 0 ].accessToken)
257       })
258
259       it('Should list the comments', function () {
260         return checkAllComments(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID1)
261       })
262
263       it('Should block a remote server', async function () {
264         await addServerToAccountBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'localhost:9002')
265       })
266
267       it('Should hide its videos', async function () {
268         const res = await getVideosListWithToken(servers[ 0 ].url, servers[ 0 ].accessToken)
269
270         const videos: Video[] = res.body.data
271         expect(videos).to.have.lengthOf(2)
272
273         const v1 = videos.find(v => v.name === 'video user 2')
274         const v2 = videos.find(v => v.name === 'video server 2')
275
276         expect(v1).to.be.undefined
277         expect(v2).to.be.undefined
278       })
279
280       it('Should list all the videos with another user', async function () {
281         return checkAllVideos(servers[ 0 ].url, userToken1)
282       })
283
284       it('Should hide its comments')
285
286       it('Should list blocked servers', async function () {
287         const res = await getServerBlocklistByAccount(servers[ 0 ].url, servers[ 0 ].accessToken, 0, 1, 'createdAt')
288         const blocks: ServerBlock[] = res.body.data
289
290         expect(res.body.total).to.equal(1)
291
292         const block = blocks[ 0 ]
293         expect(block.byAccount.displayName).to.equal('root')
294         expect(block.byAccount.name).to.equal('root')
295         expect(block.blockedServer.host).to.equal('localhost:9002')
296       })
297
298       it('Should unblock the remote server', async function () {
299         await removeServerFromAccountBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'localhost:9002')
300       })
301
302       it('Should display its videos', function () {
303         return checkAllVideos(servers[ 0 ].url, servers[ 0 ].accessToken)
304       })
305
306       it('Should display its comments', function () {
307         return checkAllComments(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID1)
308       })
309     })
310   })
311
312   describe('Server blocklist', function () {
313
314     describe('When managing account blocklist', function () {
315       it('Should list all videos', async function () {
316         for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) {
317           await checkAllVideos(servers[ 0 ].url, token)
318         }
319       })
320
321       it('Should list the comments', async function () {
322         for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) {
323           await checkAllComments(servers[ 0 ].url, token, videoUUID1)
324         }
325       })
326
327       it('Should block a remote account', async function () {
328         await addAccountToServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'user2@localhost:9002')
329       })
330
331       it('Should hide its videos', async function () {
332         for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) {
333           const res = await getVideosListWithToken(servers[ 0 ].url, token)
334
335           const videos: Video[] = res.body.data
336           expect(videos).to.have.lengthOf(3)
337
338           const v = videos.find(v => v.name === 'video user 2')
339           expect(v).to.be.undefined
340         }
341       })
342
343       it('Should block a local account', async function () {
344         await addAccountToServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'user1')
345       })
346
347       it('Should hide its videos', async function () {
348         for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) {
349           const res = await getVideosListWithToken(servers[ 0 ].url, token)
350
351           const videos: Video[] = res.body.data
352           expect(videos).to.have.lengthOf(2)
353
354           const v = videos.find(v => v.name === 'video user 1')
355           expect(v).to.be.undefined
356         }
357       })
358
359       it('Should hide its comments', async function () {
360         for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) {
361           const resThreads = await getVideoCommentThreads(servers[ 0 ].url, videoUUID1, 0, 5, '-createdAt', token)
362
363           const threads: VideoComment[] = resThreads.body.data
364           expect(threads).to.have.lengthOf(1)
365           expect(threads[ 0 ].totalReplies).to.equal(0)
366
367           const t = threads.find(t => t.text === 'comment user 1')
368           expect(t).to.be.undefined
369
370           for (const thread of threads) {
371             const res = await getVideoThreadComments(servers[ 0 ].url, videoUUID1, thread.id, token)
372
373             const tree: VideoCommentThreadTree = res.body
374             expect(tree.children).to.have.lengthOf(0)
375           }
376         }
377       })
378
379       it('Should list blocked accounts', async function () {
380         {
381           const res = await getAccountBlocklistByServer(servers[ 0 ].url, servers[ 0 ].accessToken, 0, 1, 'createdAt')
382           const blocks: AccountBlock[] = res.body.data
383
384           expect(res.body.total).to.equal(2)
385
386           const block = blocks[ 0 ]
387           expect(block.byAccount.displayName).to.equal('peertube')
388           expect(block.byAccount.name).to.equal('peertube')
389           expect(block.blockedAccount.displayName).to.equal('user2')
390           expect(block.blockedAccount.name).to.equal('user2')
391           expect(block.blockedAccount.host).to.equal('localhost:9002')
392         }
393
394         {
395           const res = await getAccountBlocklistByServer(servers[ 0 ].url, servers[ 0 ].accessToken, 1, 2, 'createdAt')
396           const blocks: AccountBlock[] = res.body.data
397
398           expect(res.body.total).to.equal(2)
399
400           const block = blocks[ 0 ]
401           expect(block.byAccount.displayName).to.equal('peertube')
402           expect(block.byAccount.name).to.equal('peertube')
403           expect(block.blockedAccount.displayName).to.equal('user1')
404           expect(block.blockedAccount.name).to.equal('user1')
405           expect(block.blockedAccount.host).to.equal('localhost:9001')
406         }
407       })
408
409       it('Should unblock the remote account', async function () {
410         await removeAccountFromServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'user2@localhost:9002')
411       })
412
413       it('Should display its videos', async function () {
414         for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) {
415           const res = await getVideosListWithToken(servers[ 0 ].url, token)
416
417           const videos: Video[] = res.body.data
418           expect(videos).to.have.lengthOf(3)
419
420           const v = videos.find(v => v.name === 'video user 2')
421           expect(v).not.to.be.undefined
422         }
423       })
424
425       it('Should unblock the local account', async function () {
426         await removeAccountFromServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'user1')
427       })
428
429       it('Should display its comments', async function () {
430         for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) {
431           await checkAllComments(servers[ 0 ].url, token, videoUUID1)
432         }
433       })
434     })
435
436     describe('When managing server blocklist', function () {
437       it('Should list all videos', async function () {
438         for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) {
439           await checkAllVideos(servers[ 0 ].url, token)
440         }
441       })
442
443       it('Should list the comments', async function () {
444         for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) {
445           await checkAllComments(servers[ 0 ].url, token, videoUUID1)
446         }
447       })
448
449       it('Should block a remote server', async function () {
450         await addServerToServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'localhost:9002')
451       })
452
453       it('Should hide its videos', async function () {
454         for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) {
455           const res1 = await getVideosList(servers[ 0 ].url)
456           const res2 = await getVideosListWithToken(servers[ 0 ].url, token)
457
458           for (const res of [ res1, res2 ]) {
459             const videos: Video[] = res.body.data
460             expect(videos).to.have.lengthOf(2)
461
462             const v1 = videos.find(v => v.name === 'video user 2')
463             const v2 = videos.find(v => v.name === 'video server 2')
464
465             expect(v1).to.be.undefined
466             expect(v2).to.be.undefined
467           }
468         }
469       })
470
471       it('Should hide its comments')
472
473       it('Should list blocked servers', async function () {
474         const res = await getServerBlocklistByServer(servers[ 0 ].url, servers[ 0 ].accessToken, 0, 1, 'createdAt')
475         const blocks: ServerBlock[] = res.body.data
476
477         expect(res.body.total).to.equal(1)
478
479         const block = blocks[ 0 ]
480         expect(block.byAccount.displayName).to.equal('peertube')
481         expect(block.byAccount.name).to.equal('peertube')
482         expect(block.blockedServer.host).to.equal('localhost:9002')
483       })
484
485       it('Should unblock the remote server', async function () {
486         await removeServerFromServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'localhost:9002')
487       })
488
489       it('Should list all videos', async function () {
490         for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) {
491           await checkAllVideos(servers[ 0 ].url, token)
492         }
493       })
494
495       it('Should list the comments', async function () {
496         for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) {
497           await checkAllComments(servers[ 0 ].url, token, videoUUID1)
498         }
499       })
500     })
501   })
502
503   after(async function () {
504     killallServers(servers)
505
506     // Keep the logs if the test failed
507     if (this[ 'ok' ]) {
508       await flushTests()
509     }
510   })
511 })