]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/moderation/blocklist.ts
Merge branch 'release/4.2.0' into develop
[github/Chocobozzz/PeerTube.git] / server / tests / api / moderation / blocklist.ts
CommitLineData
a1587156 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
b44164bb 2
b44164bb 3import 'mocha'
2b02c520 4import * as chai from 'chai'
d0800f76 5import { UserNotificationType } from '@shared/models'
b44164bb 6import {
5f8bd4cb 7 BlocklistCommand,
7c3b7976 8 cleanupTests,
12edc149 9 CommentsCommand,
254d3579 10 createMultipleServers,
4c7e60bc 11 doubleFollow,
254d3579 12 PeerTubeServer,
2b02c520 13 setAccessTokensToServers,
d0800f76 14 setDefaultAccountAvatar,
2b02c520 15 waitJobs
bf54587a 16} from '@shared/server-commands'
b44164bb
C
17
18const expect = chai.expect
19
254d3579 20async function checkAllVideos (server: PeerTubeServer, token: string) {
65b21c96 21 {
89d241a7 22 const { data } = await server.videos.listWithToken({ token })
d23dd9fb 23 expect(data).to.have.lengthOf(5)
65b21c96
C
24 }
25
26 {
89d241a7 27 const { data } = await server.videos.list()
d23dd9fb 28 expect(data).to.have.lengthOf(5)
65b21c96 29 }
b44164bb
C
30}
31
254d3579 32async function checkAllComments (server: PeerTubeServer, token: string, videoUUID: string) {
89d241a7 33 const { data } = await server.comments.listThreads({ videoId: videoUUID, start: 0, count: 25, sort: '-createdAt', token })
b44164bb 34
12edc149 35 const threads = data.filter(t => t.isDeleted === false)
b44164bb
C
36 expect(threads).to.have.lengthOf(2)
37
38 for (const thread of threads) {
89d241a7 39 const tree = await server.comments.getThread({ videoId: videoUUID, threadId: thread.id, token })
b44164bb
C
40 expect(tree.children).to.have.lengthOf(1)
41 }
42}
43
dddc8b1f 44async function checkCommentNotification (
254d3579
C
45 mainServer: PeerTubeServer,
46 comment: { server: PeerTubeServer, token: string, videoUUID: string, text: string },
dddc8b1f
C
47 check: 'presence' | 'absence'
48) {
89d241a7 49 const command = comment.server.comments
12edc149
C
50
51 const { threadId, createdAt } = await command.createThread({ token: comment.token, videoId: comment.videoUUID, text: comment.text })
dddc8b1f 52
a1587156 53 await waitJobs([ mainServer, comment.server ])
dddc8b1f 54
89d241a7 55 const { data } = await mainServer.notifications.list({ start: 0, count: 30 })
dd0ebb71 56 const commentNotifications = data.filter(n => n.comment && n.comment.video.uuid === comment.videoUUID && n.createdAt >= createdAt)
dddc8b1f
C
57
58 if (check === 'presence') expect(commentNotifications).to.have.lengthOf(1)
59 else expect(commentNotifications).to.have.lengthOf(0)
60
12edc149 61 await command.delete({ token: comment.token, videoId: comment.videoUUID, commentId: threadId })
dddc8b1f 62
a1587156 63 await waitJobs([ mainServer, comment.server ])
dddc8b1f
C
64}
65
b44164bb 66describe('Test blocklist', function () {
254d3579 67 let servers: PeerTubeServer[]
b44164bb
C
68 let videoUUID1: string
69 let videoUUID2: string
696d83fd 70 let videoUUID3: string
b44164bb
C
71 let userToken1: string
72 let userModeratorToken: string
73 let userToken2: string
74
5f8bd4cb 75 let command: BlocklistCommand
12edc149 76 let commentsCommand: CommentsCommand[]
5f8bd4cb 77
b44164bb 78 before(async function () {
61fd9834 79 this.timeout(120000)
b44164bb 80
254d3579 81 servers = await createMultipleServers(3)
b44164bb 82 await setAccessTokensToServers(servers)
d0800f76 83 await setDefaultAccountAvatar(servers)
b44164bb 84
89d241a7
C
85 command = servers[0].blocklist
86 commentsCommand = servers.map(s => s.comments)
12edc149 87
b44164bb
C
88 {
89 const user = { username: 'user1', password: 'password' }
89d241a7 90 await servers[0].users.create({ username: user.username, password: user.password })
b44164bb 91
89d241a7
C
92 userToken1 = await servers[0].login.getAccessToken(user)
93 await servers[0].videos.upload({ token: userToken1, attributes: { name: 'video user 1' } })
b44164bb
C
94 }
95
96 {
97 const user = { username: 'moderator', password: 'password' }
89d241a7 98 await servers[0].users.create({ username: user.username, password: user.password })
b44164bb 99
89d241a7 100 userModeratorToken = await servers[0].login.getAccessToken(user)
b44164bb
C
101 }
102
103 {
104 const user = { username: 'user2', password: 'password' }
89d241a7 105 await servers[1].users.create({ username: user.username, password: user.password })
b44164bb 106
89d241a7
C
107 userToken2 = await servers[1].login.getAccessToken(user)
108 await servers[1].videos.upload({ token: userToken2, attributes: { name: 'video user 2' } })
b44164bb
C
109 }
110
111 {
89d241a7 112 const { uuid } = await servers[0].videos.upload({ attributes: { name: 'video server 1' } })
d23dd9fb 113 videoUUID1 = uuid
b44164bb
C
114 }
115
116 {
89d241a7 117 const { uuid } = await servers[1].videos.upload({ attributes: { name: 'video server 2' } })
d23dd9fb 118 videoUUID2 = uuid
b44164bb
C
119 }
120
696d83fd 121 {
89d241a7 122 const { uuid } = await servers[0].videos.upload({ attributes: { name: 'video 2 server 1' } })
d23dd9fb 123 videoUUID3 = uuid
696d83fd
C
124 }
125
b44164bb 126 await doubleFollow(servers[0], servers[1])
696d83fd 127 await doubleFollow(servers[0], servers[2])
b44164bb
C
128
129 {
12edc149
C
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' })
b44164bb
C
138 }
139
140 {
12edc149
C
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' })
b44164bb
C
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 () {
12edc149 152 return checkAllVideos(servers[0], servers[0].accessToken)
b44164bb
C
153 })
154
155 it('Should list the comments', function () {
12edc149 156 return checkAllComments(servers[0], servers[0].accessToken, videoUUID1)
b44164bb
C
157 })
158
159 it('Should block a remote account', async function () {
5f8bd4cb 160 await command.addToMyBlocklist({ account: 'user2@localhost:' + servers[1].port })
b44164bb
C
161 })
162
163 it('Should hide its videos', async function () {
89d241a7 164 const { data } = await servers[0].videos.listWithToken()
b44164bb 165
d23dd9fb 166 expect(data).to.have.lengthOf(4)
b44164bb 167
d23dd9fb 168 const v = data.find(v => v.name === 'video user 2')
b44164bb
C
169 expect(v).to.be.undefined
170 })
171
172 it('Should block a local account', async function () {
5f8bd4cb 173 await command.addToMyBlocklist({ account: 'user1' })
b44164bb
C
174 })
175
176 it('Should hide its videos', async function () {
89d241a7 177 const { data } = await servers[0].videos.listWithToken()
b44164bb 178
d23dd9fb 179 expect(data).to.have.lengthOf(3)
b44164bb 180
d23dd9fb 181 const v = data.find(v => v.name === 'video user 1')
b44164bb
C
182 expect(v).to.be.undefined
183 })
184
185 it('Should hide its comments', async function () {
12edc149
C
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')
b44164bb
C
198 expect(t).to.be.undefined
199
12edc149
C
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 })
b44164bb
C
206 expect(tree.children).to.have.lengthOf(0)
207 }
208 })
209
dddc8b1f
C
210 it('Should not have notifications from blocked accounts', async function () {
211 this.timeout(20000)
212
213 {
a1587156
C
214 const comment = { server: servers[0], token: userToken1, videoUUID: videoUUID1, text: 'hidden comment' }
215 await checkCommentNotification(servers[0], comment, 'absence')
dddc8b1f
C
216 }
217
218 {
219 const comment = {
a1587156 220 server: servers[0],
dddc8b1f
C
221 token: userToken1,
222 videoUUID: videoUUID2,
a1587156 223 text: 'hello @root@localhost:' + servers[0].port
dddc8b1f 224 }
a1587156 225 await checkCommentNotification(servers[0], comment, 'absence')
dddc8b1f
C
226 }
227 })
228
b44164bb 229 it('Should list all the videos with another user', async function () {
12edc149 230 return checkAllVideos(servers[0], userToken1)
b44164bb
C
231 })
232
b44164bb
C
233 it('Should list blocked accounts', async function () {
234 {
5f8bd4cb
C
235 const body = await command.listMyAccountBlocklist({ start: 0, count: 1, sort: 'createdAt' })
236 expect(body.total).to.equal(2)
b44164bb 237
5f8bd4cb 238 const block = body.data[0]
b44164bb
C
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')
7243f84d 243 expect(block.blockedAccount.host).to.equal('localhost:' + servers[1].port)
b44164bb
C
244 }
245
246 {
5f8bd4cb
C
247 const body = await command.listMyAccountBlocklist({ start: 1, count: 2, sort: 'createdAt' })
248 expect(body.total).to.equal(2)
b44164bb 249
5f8bd4cb 250 const block = body.data[0]
b44164bb
C
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')
7243f84d 255 expect(block.blockedAccount.host).to.equal('localhost:' + servers[0].port)
b44164bb
C
256 }
257 })
258
d3976db2
C
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
80badf49
C
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
696d83fd
C
305 it('Should not allow a remote blocked user to comment my videos', async function () {
306 this.timeout(60000)
307
308 {
12edc149 309 await commentsCommand[1].createThread({ token: userToken2, videoId: videoUUID3, text: 'comment user 2' })
696d83fd
C
310 await waitJobs(servers)
311
12edc149 312 await commentsCommand[0].createThread({ token: servers[0].accessToken, videoId: videoUUID3, text: 'uploader' })
696d83fd
C
313 await waitJobs(servers)
314
12edc149 315 const commentId = await commentsCommand[1].findCommentId({ videoId: videoUUID3, text: 'uploader' })
696d83fd 316 const message = 'reply by user 2'
12edc149
C
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' })
696d83fd
C
319
320 await waitJobs(servers)
321 }
322
323 // Server 2 has all the comments
324 {
12edc149 325 const { data } = await commentsCommand[1].listThreads({ videoId: videoUUID3, count: 25, sort: '-createdAt' })
696d83fd 326
12edc149
C
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')
696d83fd 330
12edc149 331 const tree = await commentsCommand[1].getThread({ videoId: videoUUID3, threadId: data[0].id })
696d83fd
C
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] ]) {
89d241a7 340 const { data } = await server.comments.listThreads({ videoId: videoUUID3, count: 25, sort: '-createdAt' })
696d83fd 341
12edc149
C
342 expect(data).to.have.lengthOf(1)
343 expect(data[0].text).to.equal('uploader')
696d83fd 344
89d241a7 345 const tree = await server.comments.getThread({ videoId: videoUUID3, threadId: data[0].id })
696d83fd 346
12edc149
C
347 if (server.serverNumber === 1) expect(tree.children).to.have.lengthOf(0)
348 else expect(tree.children).to.have.lengthOf(1)
696d83fd
C
349 }
350 })
351
b44164bb 352 it('Should unblock the remote account', async function () {
5f8bd4cb 353 await command.removeFromMyBlocklist({ account: 'user2@localhost:' + servers[1].port })
b44164bb
C
354 })
355
356 it('Should display its videos', async function () {
89d241a7 357 const { data } = await servers[0].videos.listWithToken()
d23dd9fb 358 expect(data).to.have.lengthOf(4)
b44164bb 359
d23dd9fb 360 const v = data.find(v => v.name === 'video user 2')
b44164bb
C
361 expect(v).not.to.be.undefined
362 })
363
696d83fd
C
364 it('Should display its comments on my video', async function () {
365 for (const server of servers) {
89d241a7 366 const { data } = await server.comments.listThreads({ videoId: videoUUID3, count: 25, sort: '-createdAt' })
696d83fd
C
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) {
12edc149 370 expect(data).to.have.lengthOf(1)
696d83fd
C
371 continue
372 }
373
12edc149
C
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')
696d83fd 377
89d241a7 378 const tree = await server.comments.getThread({ videoId: videoUUID3, threadId: data[0].id })
696d83fd
C
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
b44164bb 386 it('Should unblock the local account', async function () {
5f8bd4cb 387 await command.removeFromMyBlocklist({ account: 'user1' })
b44164bb
C
388 })
389
390 it('Should display its comments', function () {
12edc149 391 return checkAllComments(servers[0], servers[0].accessToken, videoUUID1)
b44164bb 392 })
dddc8b1f
C
393
394 it('Should have a notification from a non blocked account', async function () {
395 this.timeout(20000)
396
397 {
a1587156
C
398 const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'displayed comment' }
399 await checkCommentNotification(servers[0], comment, 'presence')
dddc8b1f
C
400 }
401
402 {
403 const comment = {
a1587156 404 server: servers[0],
dddc8b1f
C
405 token: userToken1,
406 videoUUID: videoUUID2,
a1587156 407 text: 'hello @root@localhost:' + servers[0].port
dddc8b1f 408 }
a1587156 409 await checkCommentNotification(servers[0], comment, 'presence')
dddc8b1f
C
410 }
411 })
b44164bb
C
412 })
413
414 describe('When managing server blocklist', function () {
5f8bd4cb 415
b44164bb 416 it('Should list all videos', function () {
12edc149 417 return checkAllVideos(servers[0], servers[0].accessToken)
b44164bb
C
418 })
419
420 it('Should list the comments', function () {
12edc149 421 return checkAllComments(servers[0], servers[0].accessToken, videoUUID1)
b44164bb
C
422 })
423
424 it('Should block a remote server', async function () {
5f8bd4cb 425 await command.addToMyBlocklist({ server: 'localhost:' + servers[1].port })
b44164bb
C
426 })
427
428 it('Should hide its videos', async function () {
89d241a7 429 const { data } = await servers[0].videos.listWithToken()
b44164bb 430
d23dd9fb 431 expect(data).to.have.lengthOf(3)
b44164bb 432
d23dd9fb
C
433 const v1 = data.find(v => v.name === 'video user 2')
434 const v2 = data.find(v => v.name === 'video server 2')
b44164bb
C
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 () {
12edc149 441 return checkAllVideos(servers[0], userToken1)
b44164bb
C
442 })
443
dddc8b1f
C
444 it('Should hide its comments', async function () {
445 this.timeout(10000)
446
12edc149 447 const { id } = await commentsCommand[1].createThread({ token: userToken2, videoId: videoUUID1, text: 'hidden comment 2' })
dddc8b1f
C
448
449 await waitJobs(servers)
450
12edc149 451 await checkAllComments(servers[0], servers[0].accessToken, videoUUID1)
dddc8b1f 452
12edc149 453 await commentsCommand[1].delete({ token: userToken2, videoId: videoUUID1, commentId: id })
dddc8b1f
C
454 })
455
456 it('Should not have notifications from blocked server', async function () {
457 this.timeout(20000)
458
459 {
a1587156
C
460 const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'hidden comment' }
461 await checkCommentNotification(servers[0], comment, 'absence')
dddc8b1f
C
462 }
463
464 {
465 const comment = {
a1587156 466 server: servers[1],
dddc8b1f
C
467 token: userToken2,
468 videoUUID: videoUUID1,
a1587156 469 text: 'hello @root@localhost:' + servers[0].port
dddc8b1f 470 }
a1587156 471 await checkCommentNotification(servers[0], comment, 'absence')
dddc8b1f
C
472 }
473 })
b44164bb
C
474
475 it('Should list blocked servers', async function () {
5f8bd4cb
C
476 const body = await command.listMyServerBlocklist({ start: 0, count: 1, sort: 'createdAt' })
477 expect(body.total).to.equal(1)
b44164bb 478
5f8bd4cb 479 const block = body.data[0]
b44164bb
C
480 expect(block.byAccount.displayName).to.equal('root')
481 expect(block.byAccount.name).to.equal('root')
7243f84d 482 expect(block.blockedServer.host).to.equal('localhost:' + servers[1].port)
b44164bb
C
483 })
484
d3976db2
C
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
80badf49
C
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
b44164bb 521 it('Should unblock the remote server', async function () {
5f8bd4cb 522 await command.removeFromMyBlocklist({ server: 'localhost:' + servers[1].port })
b44164bb
C
523 })
524
525 it('Should display its videos', function () {
12edc149 526 return checkAllVideos(servers[0], servers[0].accessToken)
b44164bb
C
527 })
528
529 it('Should display its comments', function () {
12edc149 530 return checkAllComments(servers[0], servers[0].accessToken, videoUUID1)
b44164bb 531 })
dddc8b1f
C
532
533 it('Should have notification from unblocked server', async function () {
534 this.timeout(20000)
535
536 {
a1587156
C
537 const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'displayed comment' }
538 await checkCommentNotification(servers[0], comment, 'presence')
dddc8b1f
C
539 }
540
541 {
542 const comment = {
a1587156 543 server: servers[1],
dddc8b1f
C
544 token: userToken2,
545 videoUUID: videoUUID1,
a1587156 546 text: 'hello @root@localhost:' + servers[0].port
dddc8b1f 547 }
a1587156 548 await checkCommentNotification(servers[0], comment, 'presence')
dddc8b1f
C
549 }
550 })
b44164bb
C
551 })
552 })
553
554 describe('Server blocklist', function () {
555
556 describe('When managing account blocklist', function () {
557 it('Should list all videos', async function () {
a1587156 558 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
12edc149 559 await checkAllVideos(servers[0], token)
b44164bb
C
560 }
561 })
562
563 it('Should list the comments', async function () {
a1587156 564 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
12edc149 565 await checkAllComments(servers[0], token, videoUUID1)
b44164bb
C
566 }
567 })
568
569 it('Should block a remote account', async function () {
5f8bd4cb 570 await command.addToServerBlocklist({ account: 'user2@localhost:' + servers[1].port })
b44164bb
C
571 })
572
573 it('Should hide its videos', async function () {
a1587156 574 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
89d241a7 575 const { data } = await servers[0].videos.listWithToken({ token })
b44164bb 576
d23dd9fb 577 expect(data).to.have.lengthOf(4)
b44164bb 578
d23dd9fb 579 const v = data.find(v => v.name === 'video user 2')
b44164bb
C
580 expect(v).to.be.undefined
581 }
582 })
583
584 it('Should block a local account', async function () {
5f8bd4cb 585 await command.addToServerBlocklist({ account: 'user1' })
b44164bb
C
586 })
587
588 it('Should hide its videos', async function () {
a1587156 589 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
89d241a7 590 const { data } = await servers[0].videos.listWithToken({ token })
b44164bb 591
d23dd9fb 592 expect(data).to.have.lengthOf(3)
b44164bb 593
d23dd9fb 594 const v = data.find(v => v.name === 'video user 1')
b44164bb
C
595 expect(v).to.be.undefined
596 }
597 })
598
599 it('Should hide its comments', async function () {
a1587156 600 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
12edc149
C
601 const { data } = await commentsCommand[0].listThreads({ videoId: videoUUID1, count: 20, sort: '-createdAt', token })
602 const threads = data.filter(t => t.isDeleted === false)
b44164bb 603
b44164bb 604 expect(threads).to.have.lengthOf(1)
9de33c6b 605 expect(threads[0].totalReplies).to.equal(1)
b44164bb
C
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) {
12edc149 611 const tree = await commentsCommand[0].getThread({ videoId: videoUUID1, threadId: thread.id, token })
b44164bb
C
612 expect(tree.children).to.have.lengthOf(0)
613 }
614 }
615 })
616
dddc8b1f
C
617 it('Should not have notification from blocked accounts by instance', async function () {
618 this.timeout(20000)
619
620 {
a1587156
C
621 const comment = { server: servers[0], token: userToken1, videoUUID: videoUUID1, text: 'hidden comment' }
622 await checkCommentNotification(servers[0], comment, 'absence')
dddc8b1f
C
623 }
624
625 {
626 const comment = {
a1587156 627 server: servers[1],
dddc8b1f
C
628 token: userToken2,
629 videoUUID: videoUUID1,
a1587156 630 text: 'hello @root@localhost:' + servers[0].port
dddc8b1f 631 }
a1587156 632 await checkCommentNotification(servers[0], comment, 'absence')
dddc8b1f
C
633 }
634 })
635
b44164bb
C
636 it('Should list blocked accounts', async function () {
637 {
5f8bd4cb
C
638 const body = await command.listServerAccountBlocklist({ start: 0, count: 1, sort: 'createdAt' })
639 expect(body.total).to.equal(2)
b44164bb 640
5f8bd4cb 641 const block = body.data[0]
b44164bb
C
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')
7243f84d 646 expect(block.blockedAccount.host).to.equal('localhost:' + servers[1].port)
b44164bb
C
647 }
648
649 {
5f8bd4cb
C
650 const body = await command.listServerAccountBlocklist({ start: 1, count: 2, sort: 'createdAt' })
651 expect(body.total).to.equal(2)
b44164bb 652
5f8bd4cb 653 const block = body.data[0]
b44164bb
C
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')
7243f84d 658 expect(block.blockedAccount.host).to.equal('localhost:' + servers[0].port)
b44164bb
C
659 }
660 })
661
d3976db2
C
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
80badf49
C
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
b44164bb 690 it('Should unblock the remote account', async function () {
5f8bd4cb 691 await command.removeFromServerBlocklist({ account: 'user2@localhost:' + servers[1].port })
b44164bb
C
692 })
693
694 it('Should display its videos', async function () {
a1587156 695 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
89d241a7 696 const { data } = await servers[0].videos.listWithToken({ token })
d23dd9fb 697 expect(data).to.have.lengthOf(4)
b44164bb 698
d23dd9fb 699 const v = data.find(v => v.name === 'video user 2')
b44164bb
C
700 expect(v).not.to.be.undefined
701 }
702 })
703
704 it('Should unblock the local account', async function () {
5f8bd4cb 705 await command.removeFromServerBlocklist({ account: 'user1' })
b44164bb
C
706 })
707
708 it('Should display its comments', async function () {
a1587156 709 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
12edc149 710 await checkAllComments(servers[0], token, videoUUID1)
b44164bb
C
711 }
712 })
dddc8b1f
C
713
714 it('Should have notifications from unblocked accounts', async function () {
715 this.timeout(20000)
716
717 {
a1587156
C
718 const comment = { server: servers[0], token: userToken1, videoUUID: videoUUID1, text: 'displayed comment' }
719 await checkCommentNotification(servers[0], comment, 'presence')
dddc8b1f
C
720 }
721
722 {
723 const comment = {
a1587156 724 server: servers[1],
dddc8b1f
C
725 token: userToken2,
726 videoUUID: videoUUID1,
a1587156 727 text: 'hello @root@localhost:' + servers[0].port
dddc8b1f 728 }
a1587156 729 await checkCommentNotification(servers[0], comment, 'presence')
dddc8b1f
C
730 }
731 })
b44164bb
C
732 })
733
734 describe('When managing server blocklist', function () {
80badf49 735
b44164bb 736 it('Should list all videos', async function () {
a1587156 737 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
12edc149 738 await checkAllVideos(servers[0], token)
b44164bb
C
739 }
740 })
741
742 it('Should list the comments', async function () {
a1587156 743 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
12edc149 744 await checkAllComments(servers[0], token, videoUUID1)
b44164bb
C
745 }
746 })
747
748 it('Should block a remote server', async function () {
5f8bd4cb 749 await command.addToServerBlocklist({ server: 'localhost:' + servers[1].port })
b44164bb
C
750 })
751
752 it('Should hide its videos', async function () {
a1587156 753 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
d23dd9fb 754 const requests = [
89d241a7
C
755 servers[0].videos.list(),
756 servers[0].videos.listWithToken({ token })
d23dd9fb 757 ]
b44164bb 758
d23dd9fb
C
759 for (const req of requests) {
760 const { data } = await req
761 expect(data).to.have.lengthOf(3)
b44164bb 762
d23dd9fb
C
763 const v1 = data.find(v => v.name === 'video user 2')
764 const v2 = data.find(v => v.name === 'video server 2')
b44164bb 765
65b21c96
C
766 expect(v1).to.be.undefined
767 expect(v2).to.be.undefined
768 }
b44164bb
C
769 }
770 })
771
dddc8b1f
C
772 it('Should hide its comments', async function () {
773 this.timeout(10000)
774
12edc149 775 const { id } = await commentsCommand[1].createThread({ token: userToken2, videoId: videoUUID1, text: 'hidden comment 2' })
dddc8b1f
C
776
777 await waitJobs(servers)
778
12edc149 779 await checkAllComments(servers[0], servers[0].accessToken, videoUUID1)
dddc8b1f 780
12edc149 781 await commentsCommand[1].delete({ token: userToken2, videoId: videoUUID1, commentId: id })
dddc8b1f
C
782 })
783
784 it('Should not have notification from blocked instances by instance', async function () {
696d83fd 785 this.timeout(50000)
dddc8b1f
C
786
787 {
a1587156
C
788 const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'hidden comment' }
789 await checkCommentNotification(servers[0], comment, 'absence')
dddc8b1f
C
790 }
791
792 {
793 const comment = {
a1587156 794 server: servers[1],
dddc8b1f
C
795 token: userToken2,
796 videoUUID: videoUUID1,
a1587156 797 text: 'hello @root@localhost:' + servers[0].port
dddc8b1f 798 }
a1587156 799 await checkCommentNotification(servers[0], comment, 'absence')
dddc8b1f 800 }
696d83fd
C
801
802 {
803 const now = new Date()
89d241a7 804 await servers[1].follows.unfollow({ target: servers[0] })
696d83fd 805 await waitJobs(servers)
4d029ef8 806 await servers[1].follows.follow({ hosts: [ servers[0].host ] })
696d83fd
C
807
808 await waitJobs(servers)
809
89d241a7 810 const { data } = await servers[0].notifications.list({ start: 0, count: 30 })
dd0ebb71
C
811 const commentNotifications = data.filter(n => {
812 return n.type === UserNotificationType.NEW_INSTANCE_FOLLOWER && n.createdAt >= now.toISOString()
813 })
696d83fd
C
814
815 expect(commentNotifications).to.have.lengthOf(0)
816 }
dddc8b1f 817 })
b44164bb
C
818
819 it('Should list blocked servers', async function () {
5f8bd4cb
C
820 const body = await command.listServerServerBlocklist({ start: 0, count: 1, sort: 'createdAt' })
821 expect(body.total).to.equal(1)
b44164bb 822
5f8bd4cb 823 const block = body.data[0]
b44164bb
C
824 expect(block.byAccount.displayName).to.equal('peertube')
825 expect(block.byAccount.name).to.equal('peertube')
7243f84d 826 expect(block.blockedServer.host).to.equal('localhost:' + servers[1].port)
b44164bb
C
827 })
828
d3976db2
C
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
80badf49
C
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
b44164bb 853 it('Should unblock the remote server', async function () {
5f8bd4cb 854 await command.removeFromServerBlocklist({ server: 'localhost:' + servers[1].port })
b44164bb
C
855 })
856
857 it('Should list all videos', async function () {
a1587156 858 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
12edc149 859 await checkAllVideos(servers[0], token)
b44164bb
C
860 }
861 })
862
863 it('Should list the comments', async function () {
a1587156 864 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
12edc149 865 await checkAllComments(servers[0], token, videoUUID1)
b44164bb
C
866 }
867 })
dddc8b1f
C
868
869 it('Should have notification from unblocked instances', async function () {
696d83fd 870 this.timeout(50000)
dddc8b1f
C
871
872 {
a1587156
C
873 const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'displayed comment' }
874 await checkCommentNotification(servers[0], comment, 'presence')
dddc8b1f
C
875 }
876
877 {
878 const comment = {
a1587156 879 server: servers[1],
dddc8b1f
C
880 token: userToken2,
881 videoUUID: videoUUID1,
a1587156 882 text: 'hello @root@localhost:' + servers[0].port
dddc8b1f 883 }
a1587156 884 await checkCommentNotification(servers[0], comment, 'presence')
dddc8b1f 885 }
696d83fd
C
886
887 {
888 const now = new Date()
89d241a7 889 await servers[1].follows.unfollow({ target: servers[0] })
696d83fd 890 await waitJobs(servers)
4d029ef8 891 await servers[1].follows.follow({ hosts: [ servers[0].host ] })
696d83fd
C
892
893 await waitJobs(servers)
894
89d241a7 895 const { data } = await servers[0].notifications.list({ start: 0, count: 30 })
dd0ebb71
C
896 const commentNotifications = data.filter(n => {
897 return n.type === UserNotificationType.NEW_INSTANCE_FOLLOWER && n.createdAt >= now.toISOString()
898 })
696d83fd
C
899
900 expect(commentNotifications).to.have.lengthOf(1)
901 }
dddc8b1f 902 })
b44164bb
C
903 })
904 })
905
7c3b7976
C
906 after(async function () {
907 await cleanupTests(servers)
b44164bb
C
908 })
909})