]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/tests/api/moderation/blocklist.ts
Merge branch 'release/4.2.0' into develop
[github/Chocobozzz/PeerTube.git] / server / tests / api / moderation / blocklist.ts
1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3 import 'mocha'
4 import * as chai from 'chai'
5 import { UserNotificationType } from '@shared/models'
6 import {
7 BlocklistCommand,
8 cleanupTests,
9 CommentsCommand,
10 createMultipleServers,
11 doubleFollow,
12 PeerTubeServer,
13 setAccessTokensToServers,
14 setDefaultAccountAvatar,
15 waitJobs
16 } from '@shared/server-commands'
17
18 const expect = chai.expect
19
20 async function checkAllVideos (server: PeerTubeServer, token: string) {
21 {
22 const { data } = await server.videos.listWithToken({ token })
23 expect(data).to.have.lengthOf(5)
24 }
25
26 {
27 const { data } = await server.videos.list()
28 expect(data).to.have.lengthOf(5)
29 }
30 }
31
32 async function checkAllComments (server: PeerTubeServer, token: string, videoUUID: string) {
33 const { data } = await server.comments.listThreads({ videoId: videoUUID, start: 0, count: 25, sort: '-createdAt', token })
34
35 const threads = data.filter(t => t.isDeleted === false)
36 expect(threads).to.have.lengthOf(2)
37
38 for (const thread of threads) {
39 const tree = await server.comments.getThread({ videoId: videoUUID, threadId: thread.id, token })
40 expect(tree.children).to.have.lengthOf(1)
41 }
42 }
43
44 async function checkCommentNotification (
45 mainServer: PeerTubeServer,
46 comment: { server: PeerTubeServer, token: string, videoUUID: string, text: string },
47 check: 'presence' | 'absence'
48 ) {
49 const command = comment.server.comments
50
51 const { threadId, createdAt } = await command.createThread({ token: comment.token, videoId: comment.videoUUID, text: comment.text })
52
53 await waitJobs([ mainServer, comment.server ])
54
55 const { data } = await mainServer.notifications.list({ start: 0, count: 30 })
56 const commentNotifications = data.filter(n => n.comment && n.comment.video.uuid === comment.videoUUID && n.createdAt >= createdAt)
57
58 if (check === 'presence') expect(commentNotifications).to.have.lengthOf(1)
59 else expect(commentNotifications).to.have.lengthOf(0)
60
61 await command.delete({ token: comment.token, videoId: comment.videoUUID, commentId: threadId })
62
63 await waitJobs([ mainServer, comment.server ])
64 }
65
66 describe('Test blocklist', function () {
67 let servers: PeerTubeServer[]
68 let videoUUID1: string
69 let videoUUID2: string
70 let videoUUID3: string
71 let userToken1: string
72 let userModeratorToken: string
73 let userToken2: string
74
75 let command: BlocklistCommand
76 let commentsCommand: CommentsCommand[]
77
78 before(async function () {
79 this.timeout(120000)
80
81 servers = await createMultipleServers(3)
82 await setAccessTokensToServers(servers)
83 await setDefaultAccountAvatar(servers)
84
85 command = servers[0].blocklist
86 commentsCommand = servers.map(s => s.comments)
87
88 {
89 const user = { username: 'user1', password: 'password' }
90 await servers[0].users.create({ username: user.username, password: user.password })
91
92 userToken1 = await servers[0].login.getAccessToken(user)
93 await servers[0].videos.upload({ token: userToken1, attributes: { name: 'video user 1' } })
94 }
95
96 {
97 const user = { username: 'moderator', password: 'password' }
98 await servers[0].users.create({ username: user.username, password: user.password })
99
100 userModeratorToken = await servers[0].login.getAccessToken(user)
101 }
102
103 {
104 const user = { username: 'user2', password: 'password' }
105 await servers[1].users.create({ username: user.username, password: user.password })
106
107 userToken2 = await servers[1].login.getAccessToken(user)
108 await servers[1].videos.upload({ token: userToken2, attributes: { name: 'video user 2' } })
109 }
110
111 {
112 const { uuid } = await servers[0].videos.upload({ attributes: { name: 'video server 1' } })
113 videoUUID1 = uuid
114 }
115
116 {
117 const { uuid } = await servers[1].videos.upload({ attributes: { name: 'video server 2' } })
118 videoUUID2 = uuid
119 }
120
121 {
122 const { uuid } = await servers[0].videos.upload({ attributes: { name: 'video 2 server 1' } })
123 videoUUID3 = uuid
124 }
125
126 await doubleFollow(servers[0], servers[1])
127 await doubleFollow(servers[0], servers[2])
128
129 {
130 const created = await commentsCommand[0].createThread({ videoId: videoUUID1, text: 'comment root 1' })
131 const reply = await commentsCommand[0].addReply({
132 token: userToken1,
133 videoId: videoUUID1,
134 toCommentId: created.id,
135 text: 'comment user 1'
136 })
137 await commentsCommand[0].addReply({ videoId: videoUUID1, toCommentId: reply.id, text: 'comment root 1' })
138 }
139
140 {
141 const created = await commentsCommand[0].createThread({ token: userToken1, videoId: videoUUID1, text: 'comment user 1' })
142 await commentsCommand[0].addReply({ videoId: videoUUID1, toCommentId: created.id, text: 'comment root 1' })
143 }
144
145 await waitJobs(servers)
146 })
147
148 describe('User blocklist', function () {
149
150 describe('When managing account blocklist', function () {
151 it('Should list all videos', function () {
152 return checkAllVideos(servers[0], servers[0].accessToken)
153 })
154
155 it('Should list the comments', function () {
156 return checkAllComments(servers[0], servers[0].accessToken, videoUUID1)
157 })
158
159 it('Should block a remote account', async function () {
160 await command.addToMyBlocklist({ account: 'user2@localhost:' + servers[1].port })
161 })
162
163 it('Should hide its videos', async function () {
164 const { data } = await servers[0].videos.listWithToken()
165
166 expect(data).to.have.lengthOf(4)
167
168 const v = data.find(v => v.name === 'video user 2')
169 expect(v).to.be.undefined
170 })
171
172 it('Should block a local account', async function () {
173 await command.addToMyBlocklist({ account: 'user1' })
174 })
175
176 it('Should hide its videos', async function () {
177 const { data } = await servers[0].videos.listWithToken()
178
179 expect(data).to.have.lengthOf(3)
180
181 const v = data.find(v => v.name === 'video user 1')
182 expect(v).to.be.undefined
183 })
184
185 it('Should hide its comments', async function () {
186 const { data } = await commentsCommand[0].listThreads({
187 token: servers[0].accessToken,
188 videoId: videoUUID1,
189 start: 0,
190 count: 25,
191 sort: '-createdAt'
192 })
193
194 expect(data).to.have.lengthOf(1)
195 expect(data[0].totalReplies).to.equal(1)
196
197 const t = data.find(t => t.text === 'comment user 1')
198 expect(t).to.be.undefined
199
200 for (const thread of data) {
201 const tree = await commentsCommand[0].getThread({
202 videoId: videoUUID1,
203 threadId: thread.id,
204 token: servers[0].accessToken
205 })
206 expect(tree.children).to.have.lengthOf(0)
207 }
208 })
209
210 it('Should not have notifications from blocked accounts', async function () {
211 this.timeout(20000)
212
213 {
214 const comment = { server: servers[0], token: userToken1, videoUUID: videoUUID1, text: 'hidden comment' }
215 await checkCommentNotification(servers[0], comment, 'absence')
216 }
217
218 {
219 const comment = {
220 server: servers[0],
221 token: userToken1,
222 videoUUID: videoUUID2,
223 text: 'hello @root@localhost:' + servers[0].port
224 }
225 await checkCommentNotification(servers[0], comment, 'absence')
226 }
227 })
228
229 it('Should list all the videos with another user', async function () {
230 return checkAllVideos(servers[0], userToken1)
231 })
232
233 it('Should list blocked accounts', async function () {
234 {
235 const body = await command.listMyAccountBlocklist({ start: 0, count: 1, sort: 'createdAt' })
236 expect(body.total).to.equal(2)
237
238 const block = body.data[0]
239 expect(block.byAccount.displayName).to.equal('root')
240 expect(block.byAccount.name).to.equal('root')
241 expect(block.blockedAccount.displayName).to.equal('user2')
242 expect(block.blockedAccount.name).to.equal('user2')
243 expect(block.blockedAccount.host).to.equal('localhost:' + servers[1].port)
244 }
245
246 {
247 const body = await command.listMyAccountBlocklist({ start: 1, count: 2, sort: 'createdAt' })
248 expect(body.total).to.equal(2)
249
250 const block = body.data[0]
251 expect(block.byAccount.displayName).to.equal('root')
252 expect(block.byAccount.name).to.equal('root')
253 expect(block.blockedAccount.displayName).to.equal('user1')
254 expect(block.blockedAccount.name).to.equal('user1')
255 expect(block.blockedAccount.host).to.equal('localhost:' + servers[0].port)
256 }
257 })
258
259 it('Should search blocked accounts', async function () {
260 const body = await command.listMyAccountBlocklist({ start: 0, count: 10, search: 'user2' })
261 expect(body.total).to.equal(1)
262
263 expect(body.data[0].blockedAccount.name).to.equal('user2')
264 })
265
266 it('Should get blocked status', async function () {
267 const remoteHandle = 'user2@' + servers[1].host
268 const localHandle = 'user1@' + servers[0].host
269 const unknownHandle = 'user5@' + servers[0].host
270
271 {
272 const status = await command.getStatus({ accounts: [ remoteHandle ] })
273 expect(Object.keys(status.accounts)).to.have.lengthOf(1)
274 expect(status.accounts[remoteHandle].blockedByUser).to.be.false
275 expect(status.accounts[remoteHandle].blockedByServer).to.be.false
276
277 expect(Object.keys(status.hosts)).to.have.lengthOf(0)
278 }
279
280 {
281 const status = await command.getStatus({ token: servers[0].accessToken, accounts: [ remoteHandle ] })
282 expect(Object.keys(status.accounts)).to.have.lengthOf(1)
283 expect(status.accounts[remoteHandle].blockedByUser).to.be.true
284 expect(status.accounts[remoteHandle].blockedByServer).to.be.false
285
286 expect(Object.keys(status.hosts)).to.have.lengthOf(0)
287 }
288
289 {
290 const status = await command.getStatus({ token: servers[0].accessToken, accounts: [ localHandle, remoteHandle, unknownHandle ] })
291 expect(Object.keys(status.accounts)).to.have.lengthOf(3)
292
293 for (const handle of [ localHandle, remoteHandle ]) {
294 expect(status.accounts[handle].blockedByUser).to.be.true
295 expect(status.accounts[handle].blockedByServer).to.be.false
296 }
297
298 expect(status.accounts[unknownHandle].blockedByUser).to.be.false
299 expect(status.accounts[unknownHandle].blockedByServer).to.be.false
300
301 expect(Object.keys(status.hosts)).to.have.lengthOf(0)
302 }
303 })
304
305 it('Should not allow a remote blocked user to comment my videos', async function () {
306 this.timeout(60000)
307
308 {
309 await commentsCommand[1].createThread({ token: userToken2, videoId: videoUUID3, text: 'comment user 2' })
310 await waitJobs(servers)
311
312 await commentsCommand[0].createThread({ token: servers[0].accessToken, videoId: videoUUID3, text: 'uploader' })
313 await waitJobs(servers)
314
315 const commentId = await commentsCommand[1].findCommentId({ videoId: videoUUID3, text: 'uploader' })
316 const message = 'reply by user 2'
317 const reply = await commentsCommand[1].addReply({ token: userToken2, videoId: videoUUID3, toCommentId: commentId, text: message })
318 await commentsCommand[1].addReply({ videoId: videoUUID3, toCommentId: reply.id, text: 'another reply' })
319
320 await waitJobs(servers)
321 }
322
323 // Server 2 has all the comments
324 {
325 const { data } = await commentsCommand[1].listThreads({ videoId: videoUUID3, count: 25, sort: '-createdAt' })
326
327 expect(data).to.have.lengthOf(2)
328 expect(data[0].text).to.equal('uploader')
329 expect(data[1].text).to.equal('comment user 2')
330
331 const tree = await commentsCommand[1].getThread({ videoId: videoUUID3, threadId: data[0].id })
332 expect(tree.children).to.have.lengthOf(1)
333 expect(tree.children[0].comment.text).to.equal('reply by user 2')
334 expect(tree.children[0].children).to.have.lengthOf(1)
335 expect(tree.children[0].children[0].comment.text).to.equal('another reply')
336 }
337
338 // Server 1 and 3 should only have uploader comments
339 for (const server of [ servers[0], servers[2] ]) {
340 const { data } = await server.comments.listThreads({ videoId: videoUUID3, count: 25, sort: '-createdAt' })
341
342 expect(data).to.have.lengthOf(1)
343 expect(data[0].text).to.equal('uploader')
344
345 const tree = await server.comments.getThread({ videoId: videoUUID3, threadId: data[0].id })
346
347 if (server.serverNumber === 1) expect(tree.children).to.have.lengthOf(0)
348 else expect(tree.children).to.have.lengthOf(1)
349 }
350 })
351
352 it('Should unblock the remote account', async function () {
353 await command.removeFromMyBlocklist({ account: 'user2@localhost:' + servers[1].port })
354 })
355
356 it('Should display its videos', async function () {
357 const { data } = await servers[0].videos.listWithToken()
358 expect(data).to.have.lengthOf(4)
359
360 const v = data.find(v => v.name === 'video user 2')
361 expect(v).not.to.be.undefined
362 })
363
364 it('Should display its comments on my video', async function () {
365 for (const server of servers) {
366 const { data } = await server.comments.listThreads({ videoId: videoUUID3, count: 25, sort: '-createdAt' })
367
368 // Server 3 should not have 2 comment threads, because server 1 did not forward the server 2 comment
369 if (server.serverNumber === 3) {
370 expect(data).to.have.lengthOf(1)
371 continue
372 }
373
374 expect(data).to.have.lengthOf(2)
375 expect(data[0].text).to.equal('uploader')
376 expect(data[1].text).to.equal('comment user 2')
377
378 const tree = await server.comments.getThread({ videoId: videoUUID3, threadId: data[0].id })
379 expect(tree.children).to.have.lengthOf(1)
380 expect(tree.children[0].comment.text).to.equal('reply by user 2')
381 expect(tree.children[0].children).to.have.lengthOf(1)
382 expect(tree.children[0].children[0].comment.text).to.equal('another reply')
383 }
384 })
385
386 it('Should unblock the local account', async function () {
387 await command.removeFromMyBlocklist({ account: 'user1' })
388 })
389
390 it('Should display its comments', function () {
391 return checkAllComments(servers[0], servers[0].accessToken, videoUUID1)
392 })
393
394 it('Should have a notification from a non blocked account', async function () {
395 this.timeout(20000)
396
397 {
398 const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'displayed comment' }
399 await checkCommentNotification(servers[0], comment, 'presence')
400 }
401
402 {
403 const comment = {
404 server: servers[0],
405 token: userToken1,
406 videoUUID: videoUUID2,
407 text: 'hello @root@localhost:' + servers[0].port
408 }
409 await checkCommentNotification(servers[0], comment, 'presence')
410 }
411 })
412 })
413
414 describe('When managing server blocklist', function () {
415
416 it('Should list all videos', function () {
417 return checkAllVideos(servers[0], servers[0].accessToken)
418 })
419
420 it('Should list the comments', function () {
421 return checkAllComments(servers[0], servers[0].accessToken, videoUUID1)
422 })
423
424 it('Should block a remote server', async function () {
425 await command.addToMyBlocklist({ server: 'localhost:' + servers[1].port })
426 })
427
428 it('Should hide its videos', async function () {
429 const { data } = await servers[0].videos.listWithToken()
430
431 expect(data).to.have.lengthOf(3)
432
433 const v1 = data.find(v => v.name === 'video user 2')
434 const v2 = data.find(v => v.name === 'video server 2')
435
436 expect(v1).to.be.undefined
437 expect(v2).to.be.undefined
438 })
439
440 it('Should list all the videos with another user', async function () {
441 return checkAllVideos(servers[0], userToken1)
442 })
443
444 it('Should hide its comments', async function () {
445 this.timeout(10000)
446
447 const { id } = await commentsCommand[1].createThread({ token: userToken2, videoId: videoUUID1, text: 'hidden comment 2' })
448
449 await waitJobs(servers)
450
451 await checkAllComments(servers[0], servers[0].accessToken, videoUUID1)
452
453 await commentsCommand[1].delete({ token: userToken2, videoId: videoUUID1, commentId: id })
454 })
455
456 it('Should not have notifications from blocked server', async function () {
457 this.timeout(20000)
458
459 {
460 const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'hidden comment' }
461 await checkCommentNotification(servers[0], comment, 'absence')
462 }
463
464 {
465 const comment = {
466 server: servers[1],
467 token: userToken2,
468 videoUUID: videoUUID1,
469 text: 'hello @root@localhost:' + servers[0].port
470 }
471 await checkCommentNotification(servers[0], comment, 'absence')
472 }
473 })
474
475 it('Should list blocked servers', async function () {
476 const body = await command.listMyServerBlocklist({ start: 0, count: 1, sort: 'createdAt' })
477 expect(body.total).to.equal(1)
478
479 const block = body.data[0]
480 expect(block.byAccount.displayName).to.equal('root')
481 expect(block.byAccount.name).to.equal('root')
482 expect(block.blockedServer.host).to.equal('localhost:' + servers[1].port)
483 })
484
485 it('Should search blocked servers', async function () {
486 const body = await command.listMyServerBlocklist({ start: 0, count: 10, search: servers[1].host })
487 expect(body.total).to.equal(1)
488
489 expect(body.data[0].blockedServer.host).to.equal(servers[1].host)
490 })
491
492 it('Should get blocklist status', async function () {
493 const blockedServer = servers[1].host
494 const notBlockedServer = 'example.com'
495
496 {
497 const status = await command.getStatus({ hosts: [ blockedServer, notBlockedServer ] })
498 expect(Object.keys(status.accounts)).to.have.lengthOf(0)
499
500 expect(Object.keys(status.hosts)).to.have.lengthOf(2)
501 expect(status.hosts[blockedServer].blockedByUser).to.be.false
502 expect(status.hosts[blockedServer].blockedByServer).to.be.false
503
504 expect(status.hosts[notBlockedServer].blockedByUser).to.be.false
505 expect(status.hosts[notBlockedServer].blockedByServer).to.be.false
506 }
507
508 {
509 const status = await command.getStatus({ token: servers[0].accessToken, hosts: [ blockedServer, notBlockedServer ] })
510 expect(Object.keys(status.accounts)).to.have.lengthOf(0)
511
512 expect(Object.keys(status.hosts)).to.have.lengthOf(2)
513 expect(status.hosts[blockedServer].blockedByUser).to.be.true
514 expect(status.hosts[blockedServer].blockedByServer).to.be.false
515
516 expect(status.hosts[notBlockedServer].blockedByUser).to.be.false
517 expect(status.hosts[notBlockedServer].blockedByServer).to.be.false
518 }
519 })
520
521 it('Should unblock the remote server', async function () {
522 await command.removeFromMyBlocklist({ server: 'localhost:' + servers[1].port })
523 })
524
525 it('Should display its videos', function () {
526 return checkAllVideos(servers[0], servers[0].accessToken)
527 })
528
529 it('Should display its comments', function () {
530 return checkAllComments(servers[0], servers[0].accessToken, videoUUID1)
531 })
532
533 it('Should have notification from unblocked server', async function () {
534 this.timeout(20000)
535
536 {
537 const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'displayed comment' }
538 await checkCommentNotification(servers[0], comment, 'presence')
539 }
540
541 {
542 const comment = {
543 server: servers[1],
544 token: userToken2,
545 videoUUID: videoUUID1,
546 text: 'hello @root@localhost:' + servers[0].port
547 }
548 await checkCommentNotification(servers[0], comment, 'presence')
549 }
550 })
551 })
552 })
553
554 describe('Server blocklist', function () {
555
556 describe('When managing account blocklist', function () {
557 it('Should list all videos', async function () {
558 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
559 await checkAllVideos(servers[0], token)
560 }
561 })
562
563 it('Should list the comments', async function () {
564 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
565 await checkAllComments(servers[0], token, videoUUID1)
566 }
567 })
568
569 it('Should block a remote account', async function () {
570 await command.addToServerBlocklist({ account: 'user2@localhost:' + servers[1].port })
571 })
572
573 it('Should hide its videos', async function () {
574 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
575 const { data } = await servers[0].videos.listWithToken({ token })
576
577 expect(data).to.have.lengthOf(4)
578
579 const v = data.find(v => v.name === 'video user 2')
580 expect(v).to.be.undefined
581 }
582 })
583
584 it('Should block a local account', async function () {
585 await command.addToServerBlocklist({ account: 'user1' })
586 })
587
588 it('Should hide its videos', async function () {
589 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
590 const { data } = await servers[0].videos.listWithToken({ token })
591
592 expect(data).to.have.lengthOf(3)
593
594 const v = data.find(v => v.name === 'video user 1')
595 expect(v).to.be.undefined
596 }
597 })
598
599 it('Should hide its comments', async function () {
600 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
601 const { data } = await commentsCommand[0].listThreads({ videoId: videoUUID1, count: 20, sort: '-createdAt', token })
602 const threads = data.filter(t => t.isDeleted === false)
603
604 expect(threads).to.have.lengthOf(1)
605 expect(threads[0].totalReplies).to.equal(1)
606
607 const t = threads.find(t => t.text === 'comment user 1')
608 expect(t).to.be.undefined
609
610 for (const thread of threads) {
611 const tree = await commentsCommand[0].getThread({ videoId: videoUUID1, threadId: thread.id, token })
612 expect(tree.children).to.have.lengthOf(0)
613 }
614 }
615 })
616
617 it('Should not have notification from blocked accounts by instance', async function () {
618 this.timeout(20000)
619
620 {
621 const comment = { server: servers[0], token: userToken1, videoUUID: videoUUID1, text: 'hidden comment' }
622 await checkCommentNotification(servers[0], comment, 'absence')
623 }
624
625 {
626 const comment = {
627 server: servers[1],
628 token: userToken2,
629 videoUUID: videoUUID1,
630 text: 'hello @root@localhost:' + servers[0].port
631 }
632 await checkCommentNotification(servers[0], comment, 'absence')
633 }
634 })
635
636 it('Should list blocked accounts', async function () {
637 {
638 const body = await command.listServerAccountBlocklist({ start: 0, count: 1, sort: 'createdAt' })
639 expect(body.total).to.equal(2)
640
641 const block = body.data[0]
642 expect(block.byAccount.displayName).to.equal('peertube')
643 expect(block.byAccount.name).to.equal('peertube')
644 expect(block.blockedAccount.displayName).to.equal('user2')
645 expect(block.blockedAccount.name).to.equal('user2')
646 expect(block.blockedAccount.host).to.equal('localhost:' + servers[1].port)
647 }
648
649 {
650 const body = await command.listServerAccountBlocklist({ start: 1, count: 2, sort: 'createdAt' })
651 expect(body.total).to.equal(2)
652
653 const block = body.data[0]
654 expect(block.byAccount.displayName).to.equal('peertube')
655 expect(block.byAccount.name).to.equal('peertube')
656 expect(block.blockedAccount.displayName).to.equal('user1')
657 expect(block.blockedAccount.name).to.equal('user1')
658 expect(block.blockedAccount.host).to.equal('localhost:' + servers[0].port)
659 }
660 })
661
662 it('Should search blocked accounts', async function () {
663 const body = await command.listServerAccountBlocklist({ start: 0, count: 10, search: 'user2' })
664 expect(body.total).to.equal(1)
665
666 expect(body.data[0].blockedAccount.name).to.equal('user2')
667 })
668
669 it('Should get blocked status', async function () {
670 const remoteHandle = 'user2@' + servers[1].host
671 const localHandle = 'user1@' + servers[0].host
672 const unknownHandle = 'user5@' + servers[0].host
673
674 for (const token of [ undefined, servers[0].accessToken ]) {
675 const status = await command.getStatus({ token, accounts: [ localHandle, remoteHandle, unknownHandle ] })
676 expect(Object.keys(status.accounts)).to.have.lengthOf(3)
677
678 for (const handle of [ localHandle, remoteHandle ]) {
679 expect(status.accounts[handle].blockedByUser).to.be.false
680 expect(status.accounts[handle].blockedByServer).to.be.true
681 }
682
683 expect(status.accounts[unknownHandle].blockedByUser).to.be.false
684 expect(status.accounts[unknownHandle].blockedByServer).to.be.false
685
686 expect(Object.keys(status.hosts)).to.have.lengthOf(0)
687 }
688 })
689
690 it('Should unblock the remote account', async function () {
691 await command.removeFromServerBlocklist({ account: 'user2@localhost:' + servers[1].port })
692 })
693
694 it('Should display its videos', async function () {
695 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
696 const { data } = await servers[0].videos.listWithToken({ token })
697 expect(data).to.have.lengthOf(4)
698
699 const v = data.find(v => v.name === 'video user 2')
700 expect(v).not.to.be.undefined
701 }
702 })
703
704 it('Should unblock the local account', async function () {
705 await command.removeFromServerBlocklist({ account: 'user1' })
706 })
707
708 it('Should display its comments', async function () {
709 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
710 await checkAllComments(servers[0], token, videoUUID1)
711 }
712 })
713
714 it('Should have notifications from unblocked accounts', async function () {
715 this.timeout(20000)
716
717 {
718 const comment = { server: servers[0], token: userToken1, videoUUID: videoUUID1, text: 'displayed comment' }
719 await checkCommentNotification(servers[0], comment, 'presence')
720 }
721
722 {
723 const comment = {
724 server: servers[1],
725 token: userToken2,
726 videoUUID: videoUUID1,
727 text: 'hello @root@localhost:' + servers[0].port
728 }
729 await checkCommentNotification(servers[0], comment, 'presence')
730 }
731 })
732 })
733
734 describe('When managing server blocklist', function () {
735
736 it('Should list all videos', async function () {
737 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
738 await checkAllVideos(servers[0], token)
739 }
740 })
741
742 it('Should list the comments', async function () {
743 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
744 await checkAllComments(servers[0], token, videoUUID1)
745 }
746 })
747
748 it('Should block a remote server', async function () {
749 await command.addToServerBlocklist({ server: 'localhost:' + servers[1].port })
750 })
751
752 it('Should hide its videos', async function () {
753 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
754 const requests = [
755 servers[0].videos.list(),
756 servers[0].videos.listWithToken({ token })
757 ]
758
759 for (const req of requests) {
760 const { data } = await req
761 expect(data).to.have.lengthOf(3)
762
763 const v1 = data.find(v => v.name === 'video user 2')
764 const v2 = data.find(v => v.name === 'video server 2')
765
766 expect(v1).to.be.undefined
767 expect(v2).to.be.undefined
768 }
769 }
770 })
771
772 it('Should hide its comments', async function () {
773 this.timeout(10000)
774
775 const { id } = await commentsCommand[1].createThread({ token: userToken2, videoId: videoUUID1, text: 'hidden comment 2' })
776
777 await waitJobs(servers)
778
779 await checkAllComments(servers[0], servers[0].accessToken, videoUUID1)
780
781 await commentsCommand[1].delete({ token: userToken2, videoId: videoUUID1, commentId: id })
782 })
783
784 it('Should not have notification from blocked instances by instance', async function () {
785 this.timeout(50000)
786
787 {
788 const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'hidden comment' }
789 await checkCommentNotification(servers[0], comment, 'absence')
790 }
791
792 {
793 const comment = {
794 server: servers[1],
795 token: userToken2,
796 videoUUID: videoUUID1,
797 text: 'hello @root@localhost:' + servers[0].port
798 }
799 await checkCommentNotification(servers[0], comment, 'absence')
800 }
801
802 {
803 const now = new Date()
804 await servers[1].follows.unfollow({ target: servers[0] })
805 await waitJobs(servers)
806 await servers[1].follows.follow({ hosts: [ servers[0].host ] })
807
808 await waitJobs(servers)
809
810 const { data } = await servers[0].notifications.list({ start: 0, count: 30 })
811 const commentNotifications = data.filter(n => {
812 return n.type === UserNotificationType.NEW_INSTANCE_FOLLOWER && n.createdAt >= now.toISOString()
813 })
814
815 expect(commentNotifications).to.have.lengthOf(0)
816 }
817 })
818
819 it('Should list blocked servers', async function () {
820 const body = await command.listServerServerBlocklist({ start: 0, count: 1, sort: 'createdAt' })
821 expect(body.total).to.equal(1)
822
823 const block = body.data[0]
824 expect(block.byAccount.displayName).to.equal('peertube')
825 expect(block.byAccount.name).to.equal('peertube')
826 expect(block.blockedServer.host).to.equal('localhost:' + servers[1].port)
827 })
828
829 it('Should search blocked servers', async function () {
830 const body = await command.listServerServerBlocklist({ start: 0, count: 10, search: servers[1].host })
831 expect(body.total).to.equal(1)
832
833 expect(body.data[0].blockedServer.host).to.equal(servers[1].host)
834 })
835
836 it('Should get blocklist status', async function () {
837 const blockedServer = servers[1].host
838 const notBlockedServer = 'example.com'
839
840 for (const token of [ undefined, servers[0].accessToken ]) {
841 const status = await command.getStatus({ token, hosts: [ blockedServer, notBlockedServer ] })
842 expect(Object.keys(status.accounts)).to.have.lengthOf(0)
843
844 expect(Object.keys(status.hosts)).to.have.lengthOf(2)
845 expect(status.hosts[blockedServer].blockedByUser).to.be.false
846 expect(status.hosts[blockedServer].blockedByServer).to.be.true
847
848 expect(status.hosts[notBlockedServer].blockedByUser).to.be.false
849 expect(status.hosts[notBlockedServer].blockedByServer).to.be.false
850 }
851 })
852
853 it('Should unblock the remote server', async function () {
854 await command.removeFromServerBlocklist({ server: 'localhost:' + servers[1].port })
855 })
856
857 it('Should list all videos', async function () {
858 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
859 await checkAllVideos(servers[0], token)
860 }
861 })
862
863 it('Should list the comments', async function () {
864 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
865 await checkAllComments(servers[0], token, videoUUID1)
866 }
867 })
868
869 it('Should have notification from unblocked instances', async function () {
870 this.timeout(50000)
871
872 {
873 const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'displayed comment' }
874 await checkCommentNotification(servers[0], comment, 'presence')
875 }
876
877 {
878 const comment = {
879 server: servers[1],
880 token: userToken2,
881 videoUUID: videoUUID1,
882 text: 'hello @root@localhost:' + servers[0].port
883 }
884 await checkCommentNotification(servers[0], comment, 'presence')
885 }
886
887 {
888 const now = new Date()
889 await servers[1].follows.unfollow({ target: servers[0] })
890 await waitJobs(servers)
891 await servers[1].follows.follow({ hosts: [ servers[0].host ] })
892
893 await waitJobs(servers)
894
895 const { data } = await servers[0].notifications.list({ start: 0, count: 30 })
896 const commentNotifications = data.filter(n => {
897 return n.type === UserNotificationType.NEW_INSTANCE_FOLLOWER && n.createdAt >= now.toISOString()
898 })
899
900 expect(commentNotifications).to.have.lengthOf(1)
901 }
902 })
903 })
904 })
905
906 after(async function () {
907 await cleanupTests(servers)
908 })
909 })