1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
3 import * as chai from 'chai'
5 import { AccountBlock, ServerBlock, Video } from '../../../../shared/index'
11 flushAndRunMultipleServers,
15 } from '../../../../shared/extra-utils/index'
16 import { setAccessTokensToServers } from '../../../../shared/extra-utils/users/login'
17 import { getVideosList, getVideosListWithToken } from '../../../../shared/extra-utils/videos/videos'
20 addVideoCommentThread,
21 getVideoCommentThreads,
22 getVideoThreadComments
23 } from '../../../../shared/extra-utils/videos/video-comments'
24 import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
25 import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
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 '../../../../shared/extra-utils/users/blocklist'
40 import { getUserNotifications } from '../../../../shared/extra-utils/users/user-notifications'
42 const expect = chai.expect
44 async function checkAllVideos (url: string, token: string) {
46 const res = await getVideosListWithToken(url, token)
48 expect(res.body.data).to.have.lengthOf(4)
52 const res = await getVideosList(url)
54 expect(res.body.data).to.have.lengthOf(4)
58 async function checkAllComments (url: string, token: string, videoUUID: string) {
59 const resThreads = await getVideoCommentThreads(url, videoUUID, 0, 25, '-createdAt', token)
61 const allThreads: VideoComment[] = resThreads.body.data
62 const threads = allThreads.filter(t => t.isDeleted === false)
63 expect(threads).to.have.lengthOf(2)
65 for (const thread of threads) {
66 const res = await getVideoThreadComments(url, videoUUID, thread.id, token)
68 const tree: VideoCommentThreadTree = res.body
69 expect(tree.children).to.have.lengthOf(1)
73 async function checkCommentNotification (
74 mainServer: ServerInfo,
75 comment: { server: ServerInfo, token: string, videoUUID: string, text: string },
76 check: 'presence' | 'absence'
78 const resComment = await addVideoCommentThread(comment.server.url, comment.token, comment.videoUUID, comment.text)
79 const threadId = resComment.body.comment.id
81 await waitJobs([ mainServer, comment.server ])
83 const res = await getUserNotifications(mainServer.url, mainServer.accessToken, 0, 30)
84 const commentNotifications = res.body.data
85 .filter(n => n.comment && n.comment.id === threadId)
87 if (check === 'presence') expect(commentNotifications).to.have.lengthOf(1)
88 else expect(commentNotifications).to.have.lengthOf(0)
90 await deleteVideoComment(comment.server.url, comment.token, comment.videoUUID, threadId)
92 await waitJobs([ mainServer, comment.server ])
95 describe('Test blocklist', function () {
96 let servers: ServerInfo[]
97 let videoUUID1: string
98 let videoUUID2: string
99 let userToken1: string
100 let userModeratorToken: string
101 let userToken2: string
103 before(async function () {
106 servers = await flushAndRunMultipleServers(2)
107 await setAccessTokensToServers(servers)
110 const user = { username: 'user1', password: 'password' }
111 await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: user.username, password: user.password })
113 userToken1 = await userLogin(servers[0], user)
114 await uploadVideo(servers[0].url, userToken1, { name: 'video user 1' })
118 const user = { username: 'moderator', password: 'password' }
119 await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: user.username, password: user.password })
121 userModeratorToken = await userLogin(servers[0], user)
125 const user = { username: 'user2', password: 'password' }
126 await createUser({ url: servers[1].url, accessToken: servers[1].accessToken, username: user.username, password: user.password })
128 userToken2 = await userLogin(servers[1], user)
129 await uploadVideo(servers[1].url, userToken2, { name: 'video user 2' })
133 const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video server 1' })
134 videoUUID1 = res.body.video.uuid
138 const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video server 2' })
139 videoUUID2 = res.body.video.uuid
142 await doubleFollow(servers[0], servers[1])
145 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID1, 'comment root 1')
146 const resReply = await addVideoCommentReply(servers[0].url, userToken1, videoUUID1, resComment.body.comment.id, 'comment user 1')
147 await addVideoCommentReply(servers[0].url, servers[0].accessToken, videoUUID1, resReply.body.comment.id, 'comment root 1')
151 const resComment = await addVideoCommentThread(servers[0].url, userToken1, videoUUID1, 'comment user 1')
152 await addVideoCommentReply(servers[0].url, servers[0].accessToken, videoUUID1, resComment.body.comment.id, 'comment root 1')
155 await waitJobs(servers)
158 describe('User blocklist', function () {
160 describe('When managing account blocklist', function () {
161 it('Should list all videos', function () {
162 return checkAllVideos(servers[0].url, servers[0].accessToken)
165 it('Should list the comments', function () {
166 return checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1)
169 it('Should block a remote account', async function () {
170 await addAccountToAccountBlocklist(servers[0].url, servers[0].accessToken, 'user2@localhost:' + servers[1].port)
173 it('Should hide its videos', async function () {
174 const res = await getVideosListWithToken(servers[0].url, servers[0].accessToken)
176 const videos: Video[] = res.body.data
177 expect(videos).to.have.lengthOf(3)
179 const v = videos.find(v => v.name === 'video user 2')
180 expect(v).to.be.undefined
183 it('Should block a local account', async function () {
184 await addAccountToAccountBlocklist(servers[0].url, servers[0].accessToken, 'user1')
187 it('Should hide its videos', async function () {
188 const res = await getVideosListWithToken(servers[0].url, servers[0].accessToken)
190 const videos: Video[] = res.body.data
191 expect(videos).to.have.lengthOf(2)
193 const v = videos.find(v => v.name === 'video user 1')
194 expect(v).to.be.undefined
197 it('Should hide its comments', async function () {
198 const resThreads = await getVideoCommentThreads(servers[0].url, videoUUID1, 0, 25, '-createdAt', servers[0].accessToken)
200 const threads: VideoComment[] = resThreads.body.data
201 expect(threads).to.have.lengthOf(1)
202 expect(threads[0].totalReplies).to.equal(0)
204 const t = threads.find(t => t.text === 'comment user 1')
205 expect(t).to.be.undefined
207 for (const thread of threads) {
208 const res = await getVideoThreadComments(servers[0].url, videoUUID1, thread.id, servers[0].accessToken)
210 const tree: VideoCommentThreadTree = res.body
211 expect(tree.children).to.have.lengthOf(0)
215 it('Should not have notifications from blocked accounts', async function () {
219 const comment = { server: servers[0], token: userToken1, videoUUID: videoUUID1, text: 'hidden comment' }
220 await checkCommentNotification(servers[0], comment, 'absence')
227 videoUUID: videoUUID2,
228 text: 'hello @root@localhost:' + servers[0].port
230 await checkCommentNotification(servers[0], comment, 'absence')
234 it('Should list all the videos with another user', async function () {
235 return checkAllVideos(servers[0].url, userToken1)
238 it('Should list all the comments with another user', async function () {
239 return checkAllComments(servers[0].url, userToken1, videoUUID1)
242 it('Should list blocked accounts', async function () {
244 const res = await getAccountBlocklistByAccount(servers[0].url, servers[0].accessToken, 0, 1, 'createdAt')
245 const blocks: AccountBlock[] = res.body.data
247 expect(res.body.total).to.equal(2)
249 const block = blocks[0]
250 expect(block.byAccount.displayName).to.equal('root')
251 expect(block.byAccount.name).to.equal('root')
252 expect(block.blockedAccount.displayName).to.equal('user2')
253 expect(block.blockedAccount.name).to.equal('user2')
254 expect(block.blockedAccount.host).to.equal('localhost:' + servers[1].port)
258 const res = await getAccountBlocklistByAccount(servers[0].url, servers[0].accessToken, 1, 2, 'createdAt')
259 const blocks: AccountBlock[] = res.body.data
261 expect(res.body.total).to.equal(2)
263 const block = blocks[0]
264 expect(block.byAccount.displayName).to.equal('root')
265 expect(block.byAccount.name).to.equal('root')
266 expect(block.blockedAccount.displayName).to.equal('user1')
267 expect(block.blockedAccount.name).to.equal('user1')
268 expect(block.blockedAccount.host).to.equal('localhost:' + servers[0].port)
272 it('Should unblock the remote account', async function () {
273 await removeAccountFromAccountBlocklist(servers[0].url, servers[0].accessToken, 'user2@localhost:' + servers[1].port)
276 it('Should display its videos', async function () {
277 const res = await getVideosListWithToken(servers[0].url, servers[0].accessToken)
279 const videos: Video[] = res.body.data
280 expect(videos).to.have.lengthOf(3)
282 const v = videos.find(v => v.name === 'video user 2')
283 expect(v).not.to.be.undefined
286 it('Should unblock the local account', async function () {
287 await removeAccountFromAccountBlocklist(servers[0].url, servers[0].accessToken, 'user1')
290 it('Should display its comments', function () {
291 return checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1)
294 it('Should have a notification from a non blocked account', async function () {
298 const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'displayed comment' }
299 await checkCommentNotification(servers[0], comment, 'presence')
306 videoUUID: videoUUID2,
307 text: 'hello @root@localhost:' + servers[0].port
309 await checkCommentNotification(servers[0], comment, 'presence')
314 describe('When managing server blocklist', function () {
315 it('Should list all videos', function () {
316 return checkAllVideos(servers[0].url, servers[0].accessToken)
319 it('Should list the comments', function () {
320 return checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1)
323 it('Should block a remote server', async function () {
324 await addServerToAccountBlocklist(servers[0].url, servers[0].accessToken, 'localhost:' + servers[1].port)
327 it('Should hide its videos', async function () {
328 const res = await getVideosListWithToken(servers[0].url, servers[0].accessToken)
330 const videos: Video[] = res.body.data
331 expect(videos).to.have.lengthOf(2)
333 const v1 = videos.find(v => v.name === 'video user 2')
334 const v2 = videos.find(v => v.name === 'video server 2')
336 expect(v1).to.be.undefined
337 expect(v2).to.be.undefined
340 it('Should list all the videos with another user', async function () {
341 return checkAllVideos(servers[0].url, userToken1)
344 it('Should hide its comments', async function () {
347 const resThreads = await addVideoCommentThread(servers[1].url, userToken2, videoUUID1, 'hidden comment 2')
348 const threadId = resThreads.body.comment.id
350 await waitJobs(servers)
352 await checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1)
354 await deleteVideoComment(servers[1].url, userToken2, videoUUID1, threadId)
357 it('Should not have notifications from blocked server', async function () {
361 const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'hidden comment' }
362 await checkCommentNotification(servers[0], comment, 'absence')
369 videoUUID: videoUUID1,
370 text: 'hello @root@localhost:' + servers[0].port
372 await checkCommentNotification(servers[0], comment, 'absence')
376 it('Should list blocked servers', async function () {
377 const res = await getServerBlocklistByAccount(servers[0].url, servers[0].accessToken, 0, 1, 'createdAt')
378 const blocks: ServerBlock[] = res.body.data
380 expect(res.body.total).to.equal(1)
382 const block = blocks[0]
383 expect(block.byAccount.displayName).to.equal('root')
384 expect(block.byAccount.name).to.equal('root')
385 expect(block.blockedServer.host).to.equal('localhost:' + servers[1].port)
388 it('Should unblock the remote server', async function () {
389 await removeServerFromAccountBlocklist(servers[0].url, servers[0].accessToken, 'localhost:' + servers[1].port)
392 it('Should display its videos', function () {
393 return checkAllVideos(servers[0].url, servers[0].accessToken)
396 it('Should display its comments', function () {
397 return checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1)
400 it('Should have notification from unblocked server', async function () {
404 const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'displayed comment' }
405 await checkCommentNotification(servers[0], comment, 'presence')
412 videoUUID: videoUUID1,
413 text: 'hello @root@localhost:' + servers[0].port
415 await checkCommentNotification(servers[0], comment, 'presence')
421 describe('Server blocklist', function () {
423 describe('When managing account blocklist', function () {
424 it('Should list all videos', async function () {
425 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
426 await checkAllVideos(servers[0].url, token)
430 it('Should list the comments', async function () {
431 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
432 await checkAllComments(servers[0].url, token, videoUUID1)
436 it('Should block a remote account', async function () {
437 await addAccountToServerBlocklist(servers[0].url, servers[0].accessToken, 'user2@localhost:' + servers[1].port)
440 it('Should hide its videos', async function () {
441 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
442 const res = await getVideosListWithToken(servers[0].url, token)
444 const videos: Video[] = res.body.data
445 expect(videos).to.have.lengthOf(3)
447 const v = videos.find(v => v.name === 'video user 2')
448 expect(v).to.be.undefined
452 it('Should block a local account', async function () {
453 await addAccountToServerBlocklist(servers[0].url, servers[0].accessToken, 'user1')
456 it('Should hide its videos', async function () {
457 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
458 const res = await getVideosListWithToken(servers[0].url, token)
460 const videos: Video[] = res.body.data
461 expect(videos).to.have.lengthOf(2)
463 const v = videos.find(v => v.name === 'video user 1')
464 expect(v).to.be.undefined
468 it('Should hide its comments', async function () {
469 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
470 const resThreads = await getVideoCommentThreads(servers[0].url, videoUUID1, 0, 20, '-createdAt', token)
472 let threads: VideoComment[] = resThreads.body.data
473 threads = threads.filter(t => t.isDeleted === false)
475 expect(threads).to.have.lengthOf(1)
476 expect(threads[0].totalReplies).to.equal(0)
478 const t = threads.find(t => t.text === 'comment user 1')
479 expect(t).to.be.undefined
481 for (const thread of threads) {
482 const res = await getVideoThreadComments(servers[0].url, videoUUID1, thread.id, token)
484 const tree: VideoCommentThreadTree = res.body
485 expect(tree.children).to.have.lengthOf(0)
490 it('Should not have notification from blocked accounts by instance', async function () {
494 const comment = { server: servers[0], token: userToken1, videoUUID: videoUUID1, text: 'hidden comment' }
495 await checkCommentNotification(servers[0], comment, 'absence')
502 videoUUID: videoUUID1,
503 text: 'hello @root@localhost:' + servers[0].port
505 await checkCommentNotification(servers[0], comment, 'absence')
509 it('Should list blocked accounts', async function () {
511 const res = await getAccountBlocklistByServer(servers[0].url, servers[0].accessToken, 0, 1, 'createdAt')
512 const blocks: AccountBlock[] = res.body.data
514 expect(res.body.total).to.equal(2)
516 const block = blocks[0]
517 expect(block.byAccount.displayName).to.equal('peertube')
518 expect(block.byAccount.name).to.equal('peertube')
519 expect(block.blockedAccount.displayName).to.equal('user2')
520 expect(block.blockedAccount.name).to.equal('user2')
521 expect(block.blockedAccount.host).to.equal('localhost:' + servers[1].port)
525 const res = await getAccountBlocklistByServer(servers[0].url, servers[0].accessToken, 1, 2, 'createdAt')
526 const blocks: AccountBlock[] = res.body.data
528 expect(res.body.total).to.equal(2)
530 const block = blocks[0]
531 expect(block.byAccount.displayName).to.equal('peertube')
532 expect(block.byAccount.name).to.equal('peertube')
533 expect(block.blockedAccount.displayName).to.equal('user1')
534 expect(block.blockedAccount.name).to.equal('user1')
535 expect(block.blockedAccount.host).to.equal('localhost:' + servers[0].port)
539 it('Should unblock the remote account', async function () {
540 await removeAccountFromServerBlocklist(servers[0].url, servers[0].accessToken, 'user2@localhost:' + servers[1].port)
543 it('Should display its videos', async function () {
544 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
545 const res = await getVideosListWithToken(servers[0].url, token)
547 const videos: Video[] = res.body.data
548 expect(videos).to.have.lengthOf(3)
550 const v = videos.find(v => v.name === 'video user 2')
551 expect(v).not.to.be.undefined
555 it('Should unblock the local account', async function () {
556 await removeAccountFromServerBlocklist(servers[0].url, servers[0].accessToken, 'user1')
559 it('Should display its comments', async function () {
560 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
561 await checkAllComments(servers[0].url, token, videoUUID1)
565 it('Should have notifications from unblocked accounts', async function () {
569 const comment = { server: servers[0], token: userToken1, videoUUID: videoUUID1, text: 'displayed comment' }
570 await checkCommentNotification(servers[0], comment, 'presence')
577 videoUUID: videoUUID1,
578 text: 'hello @root@localhost:' + servers[0].port
580 await checkCommentNotification(servers[0], comment, 'presence')
585 describe('When managing server blocklist', function () {
586 it('Should list all videos', async function () {
587 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
588 await checkAllVideos(servers[0].url, token)
592 it('Should list the comments', async function () {
593 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
594 await checkAllComments(servers[0].url, token, videoUUID1)
598 it('Should block a remote server', async function () {
599 await addServerToServerBlocklist(servers[0].url, servers[0].accessToken, 'localhost:' + servers[1].port)
602 it('Should hide its videos', async function () {
603 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
604 const res1 = await getVideosList(servers[0].url)
605 const res2 = await getVideosListWithToken(servers[0].url, token)
607 for (const res of [ res1, res2 ]) {
608 const videos: Video[] = res.body.data
609 expect(videos).to.have.lengthOf(2)
611 const v1 = videos.find(v => v.name === 'video user 2')
612 const v2 = videos.find(v => v.name === 'video server 2')
614 expect(v1).to.be.undefined
615 expect(v2).to.be.undefined
620 it('Should hide its comments', async function () {
623 const resThreads = await addVideoCommentThread(servers[1].url, userToken2, videoUUID1, 'hidden comment 2')
624 const threadId = resThreads.body.comment.id
626 await waitJobs(servers)
628 await checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1)
630 await deleteVideoComment(servers[1].url, userToken2, videoUUID1, threadId)
633 it('Should not have notification from blocked instances by instance', async function () {
637 const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'hidden comment' }
638 await checkCommentNotification(servers[0], comment, 'absence')
645 videoUUID: videoUUID1,
646 text: 'hello @root@localhost:' + servers[0].port
648 await checkCommentNotification(servers[0], comment, 'absence')
652 it('Should list blocked servers', async function () {
653 const res = await getServerBlocklistByServer(servers[0].url, servers[0].accessToken, 0, 1, 'createdAt')
654 const blocks: ServerBlock[] = res.body.data
656 expect(res.body.total).to.equal(1)
658 const block = blocks[0]
659 expect(block.byAccount.displayName).to.equal('peertube')
660 expect(block.byAccount.name).to.equal('peertube')
661 expect(block.blockedServer.host).to.equal('localhost:' + servers[1].port)
664 it('Should unblock the remote server', async function () {
665 await removeServerFromServerBlocklist(servers[0].url, servers[0].accessToken, 'localhost:' + servers[1].port)
668 it('Should list all videos', async function () {
669 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
670 await checkAllVideos(servers[0].url, token)
674 it('Should list the comments', async function () {
675 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
676 await checkAllComments(servers[0].url, token, videoUUID1)
680 it('Should have notification from unblocked instances', async function () {
684 const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'displayed comment' }
685 await checkCommentNotification(servers[0], comment, 'presence')
692 videoUUID: videoUUID1,
693 text: 'hello @root@localhost:' + servers[0].port
695 await checkCommentNotification(servers[0], comment, 'presence')
701 after(async function () {
702 await cleanupTests(servers)