]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/server/follows.ts
Bumped to version v5.2.1
[github/Chocobozzz/PeerTube.git] / server / tests / api / server / follows.ts
CommitLineData
a1587156 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
0f91ae62 2
86347717 3import { expect } from 'chai'
c55e3d72 4import { completeVideoCheck, dateIsValid, expectAccountFollows, expectChannelsFollows, testCaptionFile } from '@server/tests/shared'
d102de1b 5import { Video, VideoPrivacy } from '@shared/models'
c55e3d72 6import { cleanupTests, createMultipleServers, PeerTubeServer, setAccessTokensToServers, waitJobs } from '@shared/server-commands'
0f91ae62 7
0f91ae62 8describe('Test follows', function () {
254d3579 9 let servers: PeerTubeServer[] = []
0f91ae62
C
10
11 before(async function () {
81d02aac 12 this.timeout(120000)
0f91ae62 13
254d3579 14 servers = await createMultipleServers(3)
0f91ae62
C
15
16 // Get the access tokens
17 await setAccessTokensToServers(servers)
18 })
19
4d029ef8 20 describe('Data propagation after follow', function () {
0f91ae62 21
4d029ef8
C
22 it('Should not have followers/followings', async function () {
23 for (const server of servers) {
24 const bodies = await Promise.all([
25 server.follows.getFollowers({ start: 0, count: 5, sort: 'createdAt' }),
26 server.follows.getFollowings({ start: 0, count: 5, sort: 'createdAt' })
27 ])
0f91ae62 28
4d029ef8
C
29 for (const body of bodies) {
30 expect(body.total).to.equal(0)
0f91ae62 31
4d029ef8
C
32 const follows = body.data
33 expect(follows).to.be.an('array')
34 expect(follows).to.have.lengthOf(0)
35 }
36 }
37 })
0f91ae62 38
4d029ef8
C
39 it('Should have server 1 following root account of server 2 and server 3', async function () {
40 this.timeout(30000)
0f91ae62 41
4d029ef8
C
42 await servers[0].follows.follow({
43 hosts: [ servers[2].url ],
44 handles: [ 'root@' + servers[1].host ]
45 })
0f91ae62 46
4d029ef8
C
47 await waitJobs(servers)
48 })
0f91ae62 49
4d029ef8
C
50 it('Should have 2 followings on server 1', async function () {
51 const body = await servers[0].follows.getFollowings({ start: 0, count: 1, sort: 'createdAt' })
52 expect(body.total).to.equal(2)
0f91ae62 53
4d029ef8
C
54 let follows = body.data
55 expect(follows).to.be.an('array')
56 expect(follows).to.have.lengthOf(1)
0f91ae62 57
4d029ef8
C
58 const body2 = await servers[0].follows.getFollowings({ start: 1, count: 1, sort: 'createdAt' })
59 follows = follows.concat(body2.data)
0f91ae62 60
4d029ef8
C
61 const server2Follow = follows.find(f => f.following.host === servers[1].host)
62 const server3Follow = follows.find(f => f.following.host === servers[2].host)
0f91ae62 63
4d029ef8
C
64 expect(server2Follow).to.not.be.undefined
65 expect(server2Follow.following.name).to.equal('root')
66 expect(server2Follow.state).to.equal('accepted')
97ecddae 67
4d029ef8
C
68 expect(server3Follow).to.not.be.undefined
69 expect(server3Follow.following.name).to.equal('peertube')
70 expect(server3Follow.state).to.equal('accepted')
71 })
b8f4167f 72
4d029ef8
C
73 it('Should have 0 followings on server 2 and 3', async function () {
74 for (const server of [ servers[1], servers[2] ]) {
75 const body = await server.follows.getFollowings({ start: 0, count: 5, sort: 'createdAt' })
76 expect(body.total).to.equal(0)
97ecddae 77
c3d29f69 78 const follows = body.data
4d029ef8
C
79 expect(follows).to.be.an('array')
80 expect(follows).to.have.lengthOf(0)
97ecddae 81 }
4d029ef8 82 })
97ecddae 83
4d029ef8
C
84 it('Should have 1 followers on server 3', async function () {
85 const body = await servers[2].follows.getFollowers({ start: 0, count: 1, sort: 'createdAt' })
86 expect(body.total).to.equal(1)
87
88 const follows = body.data
89 expect(follows).to.be.an('array')
90 expect(follows).to.have.lengthOf(1)
2732eeff 91 expect(follows[0].follower.host).to.equal(servers[0].host)
4d029ef8
C
92 })
93
94 it('Should have 0 followers on server 1 and 2', async function () {
95 for (const server of [ servers[0], servers[1] ]) {
96 const body = await server.follows.getFollowers({ start: 0, count: 5, sort: 'createdAt' })
97 expect(body.total).to.equal(0)
98
99 const follows = body.data
100 expect(follows).to.be.an('array')
101 expect(follows).to.have.lengthOf(0)
97ecddae 102 }
4d029ef8
C
103 })
104
105 it('Should search/filter followings on server 1', async function () {
106 const sort = 'createdAt'
107 const start = 0
108 const count = 1
97ecddae
C
109
110 {
4d029ef8
C
111 const search = ':' + servers[1].port
112
113 {
114 const body = await servers[0].follows.getFollowings({ start, count, sort, search })
115 expect(body.total).to.equal(1)
116
117 const follows = body.data
118 expect(follows).to.have.lengthOf(1)
119 expect(follows[0].following.host).to.equal(servers[1].host)
120 }
121
122 {
123 const body = await servers[0].follows.getFollowings({ start, count, sort, search, state: 'accepted' })
124 expect(body.total).to.equal(1)
125 expect(body.data).to.have.lengthOf(1)
126 }
127
128 {
129 const body = await servers[0].follows.getFollowings({ start, count, sort, search, state: 'accepted', actorType: 'Person' })
130 expect(body.total).to.equal(1)
131 expect(body.data).to.have.lengthOf(1)
132 }
133
134 {
135 const body = await servers[0].follows.getFollowings({
136 start,
137 count,
138 sort,
139 search,
140 state: 'accepted',
141 actorType: 'Application'
142 })
143 expect(body.total).to.equal(0)
144 expect(body.data).to.have.lengthOf(0)
145 }
146
147 {
148 const body = await servers[0].follows.getFollowings({ start, count, sort, search, state: 'pending' })
149 expect(body.total).to.equal(0)
150 expect(body.data).to.have.lengthOf(0)
151 }
97ecddae
C
152 }
153
154 {
4d029ef8 155 const body = await servers[0].follows.getFollowings({ start, count, sort, search: 'root' })
c3d29f69
C
156 expect(body.total).to.equal(1)
157 expect(body.data).to.have.lengthOf(1)
97ecddae
C
158 }
159
160 {
4d029ef8 161 const body = await servers[0].follows.getFollowings({ start, count, sort, search: 'bla' })
c3d29f69 162 expect(body.total).to.equal(0)
4d029ef8 163
c3d29f69 164 expect(body.data).to.have.lengthOf(0)
97ecddae 165 }
4d029ef8 166 })
b014b6b9 167
4d029ef8
C
168 it('Should search/filter followers on server 2', async function () {
169 const start = 0
170 const count = 5
171 const sort = 'createdAt'
b014b6b9 172
4d029ef8
C
173 {
174 const search = servers[0].port + ''
b014b6b9 175
4d029ef8
C
176 {
177 const body = await servers[2].follows.getFollowers({ start, count, sort, search })
178 expect(body.total).to.equal(1)
0f91ae62 179
4d029ef8
C
180 const follows = body.data
181 expect(follows).to.have.lengthOf(1)
182 expect(follows[0].following.host).to.equal(servers[2].host)
183 }
0f91ae62 184
4d029ef8
C
185 {
186 const body = await servers[2].follows.getFollowers({ start, count, sort, search, state: 'accepted' })
187 expect(body.total).to.equal(1)
188 expect(body.data).to.have.lengthOf(1)
189 }
0f91ae62 190
4d029ef8
C
191 {
192 const body = await servers[2].follows.getFollowers({ start, count, sort, search, state: 'accepted', actorType: 'Person' })
193 expect(body.total).to.equal(0)
194 expect(body.data).to.have.lengthOf(0)
195 }
0f91ae62 196
4d029ef8
C
197 {
198 const body = await servers[2].follows.getFollowers({
199 start,
200 count,
201 sort,
202 search,
203 state: 'accepted',
204 actorType: 'Application'
205 })
206 expect(body.total).to.equal(1)
207 expect(body.data).to.have.lengthOf(1)
208 }
97ecddae 209
4d029ef8
C
210 {
211 const body = await servers[2].follows.getFollowers({ start, count, sort, search, state: 'pending' })
212 expect(body.total).to.equal(0)
213 expect(body.data).to.have.lengthOf(0)
214 }
215 }
b8f4167f 216
97ecddae 217 {
4d029ef8
C
218 const body = await servers[2].follows.getFollowers({ start, count, sort, search: 'bla' })
219 expect(body.total).to.equal(0)
97ecddae 220
c3d29f69 221 const follows = body.data
4d029ef8 222 expect(follows).to.have.lengthOf(0)
97ecddae 223 }
4d029ef8 224 })
97ecddae 225
4d029ef8
C
226 it('Should have the correct follows counts', async function () {
227 await expectAccountFollows({ server: servers[0], handle: 'peertube@' + servers[0].host, followers: 0, following: 2 })
228 await expectAccountFollows({ server: servers[0], handle: 'root@' + servers[1].host, followers: 1, following: 0 })
229 await expectAccountFollows({ server: servers[0], handle: 'peertube@' + servers[2].host, followers: 1, following: 0 })
97ecddae 230
4d029ef8
C
231 // Server 2 and 3 does not know server 1 follow another server (there was not a refresh)
232 await expectAccountFollows({ server: servers[1], handle: 'peertube@' + servers[0].host, followers: 0, following: 1 })
233 await expectAccountFollows({ server: servers[1], handle: 'root@' + servers[1].host, followers: 1, following: 0 })
234 await expectAccountFollows({ server: servers[1], handle: 'peertube@' + servers[1].host, followers: 0, following: 0 })
97ecddae 235
4d029ef8
C
236 await expectAccountFollows({ server: servers[2], handle: 'peertube@' + servers[0].host, followers: 0, following: 1 })
237 await expectAccountFollows({ server: servers[2], handle: 'peertube@' + servers[2].host, followers: 1, following: 0 })
238 })
97ecddae 239
4d029ef8
C
240 it('Should unfollow server 3 on server 1', async function () {
241 this.timeout(15000)
b014b6b9 242
4d029ef8
C
243 await servers[0].follows.unfollow({ target: servers[2] })
244
245 await waitJobs(servers)
246 })
247
248 it('Should not follow server 3 on server 1 anymore', async function () {
249 const body = await servers[0].follows.getFollowings({ start: 0, count: 2, sort: 'createdAt' })
250 expect(body.total).to.equal(1)
b014b6b9 251
c3d29f69 252 const follows = body.data
4d029ef8
C
253 expect(follows).to.be.an('array')
254 expect(follows).to.have.lengthOf(1)
b014b6b9 255
4d029ef8
C
256 expect(follows[0].following.host).to.equal(servers[1].host)
257 })
0f91ae62 258
4d029ef8
C
259 it('Should not have server 1 as follower on server 3 anymore', async function () {
260 const body = await servers[2].follows.getFollowers({ start: 0, count: 1, sort: 'createdAt' })
261 expect(body.total).to.equal(0)
0f91ae62 262
4d029ef8
C
263 const follows = body.data
264 expect(follows).to.be.an('array')
265 expect(follows).to.have.lengthOf(0)
266 })
32b2b43c 267
4d029ef8
C
268 it('Should have the correct follows counts after the unfollow', async function () {
269 await expectAccountFollows({ server: servers[0], handle: 'peertube@' + servers[0].host, followers: 0, following: 1 })
270 await expectAccountFollows({ server: servers[0], handle: 'root@' + servers[1].host, followers: 1, following: 0 })
271 await expectAccountFollows({ server: servers[0], handle: 'peertube@' + servers[2].host, followers: 0, following: 0 })
32b2b43c 272
4d029ef8
C
273 await expectAccountFollows({ server: servers[1], handle: 'peertube@' + servers[0].host, followers: 0, following: 1 })
274 await expectAccountFollows({ server: servers[1], handle: 'root@' + servers[1].host, followers: 1, following: 0 })
275 await expectAccountFollows({ server: servers[1], handle: 'peertube@' + servers[1].host, followers: 0, following: 0 })
32b2b43c 276
4d029ef8
C
277 await expectAccountFollows({ server: servers[2], handle: 'peertube@' + servers[0].host, followers: 0, following: 0 })
278 await expectAccountFollows({ server: servers[2], handle: 'peertube@' + servers[2].host, followers: 0, following: 0 })
279 })
0f91ae62 280
4d029ef8 281 it('Should upload a video on server 2 and 3 and propagate only the video of server 2', async function () {
f8918990 282 this.timeout(160000)
0f91ae62 283
4d029ef8
C
284 await servers[1].videos.upload({ attributes: { name: 'server2' } })
285 await servers[2].videos.upload({ attributes: { name: 'server3' } })
0f91ae62 286
4d029ef8 287 await waitJobs(servers)
0f91ae62 288
4d029ef8
C
289 {
290 const { total, data } = await servers[0].videos.list()
291 expect(total).to.equal(1)
292 expect(data[0].name).to.equal('server2')
293 }
0f91ae62 294
4d029ef8
C
295 {
296 const { total, data } = await servers[1].videos.list()
297 expect(total).to.equal(1)
298 expect(data[0].name).to.equal('server2')
299 }
0f91ae62 300
4d029ef8
C
301 {
302 const { total, data } = await servers[2].videos.list()
303 expect(total).to.equal(1)
304 expect(data[0].name).to.equal('server3')
305 }
306 })
0f91ae62 307
4d029ef8
C
308 it('Should remove account follow', async function () {
309 this.timeout(15000)
0f91ae62 310
4d029ef8 311 await servers[0].follows.unfollow({ target: 'root@' + servers[1].host })
32b2b43c 312
4d029ef8
C
313 await waitJobs(servers)
314 })
32b2b43c 315
4d029ef8
C
316 it('Should have removed the account follow', async function () {
317 await expectAccountFollows({ server: servers[0], handle: 'root@' + servers[1].host, followers: 0, following: 0 })
318 await expectAccountFollows({ server: servers[1], handle: 'root@' + servers[1].host, followers: 0, following: 0 })
32b2b43c 319
4d029ef8
C
320 {
321 const { total, data } = await servers[0].follows.getFollowings()
322 expect(total).to.equal(0)
323 expect(data).to.have.lengthOf(0)
324 }
0f91ae62 325
4d029ef8
C
326 {
327 const { total, data } = await servers[0].videos.list()
328 expect(total).to.equal(0)
329 expect(data).to.have.lengthOf(0)
330 }
331 })
0f91ae62 332
4d029ef8
C
333 it('Should follow a channel', async function () {
334 this.timeout(15000)
0f91ae62 335
4d029ef8
C
336 await servers[0].follows.follow({
337 handles: [ 'root_channel@' + servers[1].host ]
338 })
0f91ae62 339
4d029ef8 340 await waitJobs(servers)
0f91ae62 341
4d029ef8
C
342 await expectChannelsFollows({ server: servers[0], handle: 'root_channel@' + servers[1].host, followers: 1, following: 0 })
343 await expectChannelsFollows({ server: servers[1], handle: 'root_channel@' + servers[1].host, followers: 1, following: 0 })
344
345 {
346 const { total, data } = await servers[0].follows.getFollowings()
347 expect(total).to.equal(1)
348 expect(data).to.have.lengthOf(1)
349 }
350
351 {
352 const { total, data } = await servers[0].videos.list()
353 expect(total).to.equal(1)
354 expect(data).to.have.lengthOf(1)
355 }
356 })
0f91ae62
C
357 })
358
4d029ef8 359 describe('Should propagate data on a new server follow', function () {
d102de1b 360 let video4: Video
d8553faa 361
b1f5b93e 362 before(async function () {
5752683e 363 this.timeout(120000)
c46edbc2 364
b1f5b93e
C
365 const video4Attributes = {
366 name: 'server3-4',
367 category: 2,
368 nsfw: true,
369 licence: 6,
370 tags: [ 'tag1', 'tag2', 'tag3' ]
371 }
d8553faa 372
89d241a7
C
373 await servers[2].videos.upload({ attributes: { name: 'server3-2' } })
374 await servers[2].videos.upload({ attributes: { name: 'server3-3' } })
d102de1b 375 const video4CreateResult = await servers[2].videos.upload({ attributes: video4Attributes })
89d241a7
C
376 await servers[2].videos.upload({ attributes: { name: 'server3-5' } })
377 await servers[2].videos.upload({ attributes: { name: 'server3-6' } })
d8553faa 378
db799da3 379 {
89d241a7 380 const userAccessToken = await servers[2].users.generateUserAndToken('captain')
db799da3 381
d102de1b
C
382 await servers[2].videos.rate({ id: video4CreateResult.id, rating: 'like' })
383 await servers[2].videos.rate({ token: userAccessToken, id: video4CreateResult.id, rating: 'dislike' })
4d029ef8 384 }
c883db6d 385
4d029ef8 386 {
d102de1b 387 await servers[2].comments.createThread({ videoId: video4CreateResult.id, text: 'my super first comment' })
c883db6d 388
4d029ef8
C
389 await servers[2].comments.addReplyToLastThread({ text: 'my super answer to thread 1' })
390 await servers[2].comments.addReplyToLastReply({ text: 'my super answer to answer of thread 1' })
391 await servers[2].comments.addReplyToLastThread({ text: 'my second answer to thread 1' })
392 }
db799da3 393
4d029ef8 394 {
d102de1b 395 const { id: threadId } = await servers[2].comments.createThread({ videoId: video4CreateResult.id, text: 'will be deleted' })
4d029ef8 396 await servers[2].comments.addReplyToLastThread({ text: 'answer to deleted' })
d8553faa 397
4d029ef8 398 const { id: replyId } = await servers[2].comments.addReplyToLastThread({ text: 'will also be deleted' })
c46edbc2 399
4d029ef8 400 await servers[2].comments.addReplyToLastReply({ text: 'my second answer to deleted' })
40e87e9e 401
d102de1b
C
402 await servers[2].comments.delete({ videoId: video4CreateResult.id, commentId: threadId })
403 await servers[2].comments.delete({ videoId: video4CreateResult.id, commentId: replyId })
b1f5b93e 404 }
c46edbc2 405
c63830f1 406 await servers[2].captions.add({
4d029ef8 407 language: 'ar',
d102de1b 408 videoId: video4CreateResult.id,
4d029ef8
C
409 fixture: 'subtitle-good2.vtt'
410 })
411
3cd0734f 412 await waitJobs(servers)
b1f5b93e
C
413
414 // Server 1 follows server 3
4d029ef8 415 await servers[0].follows.follow({ hosts: [ servers[2].url ] })
b1f5b93e 416
3cd0734f 417 await waitJobs(servers)
b1f5b93e
C
418 })
419
4d029ef8
C
420 it('Should have the correct follows counts', async function () {
421 await expectAccountFollows({ server: servers[0], handle: 'peertube@' + servers[0].host, followers: 0, following: 2 })
422 await expectAccountFollows({ server: servers[0], handle: 'root@' + servers[1].host, followers: 0, following: 0 })
423 await expectChannelsFollows({ server: servers[0], handle: 'root_channel@' + servers[1].host, followers: 1, following: 0 })
424 await expectAccountFollows({ server: servers[0], handle: 'peertube@' + servers[2].host, followers: 1, following: 0 })
32b2b43c 425
4d029ef8
C
426 await expectAccountFollows({ server: servers[1], handle: 'peertube@' + servers[0].host, followers: 0, following: 1 })
427 await expectAccountFollows({ server: servers[1], handle: 'peertube@' + servers[1].host, followers: 0, following: 0 })
428 await expectAccountFollows({ server: servers[1], handle: 'root@' + servers[1].host, followers: 0, following: 0 })
429 await expectChannelsFollows({ server: servers[1], handle: 'root_channel@' + servers[1].host, followers: 1, following: 0 })
32b2b43c 430
4d029ef8
C
431 await expectAccountFollows({ server: servers[2], handle: 'peertube@' + servers[0].host, followers: 0, following: 1 })
432 await expectAccountFollows({ server: servers[2], handle: 'peertube@' + servers[2].host, followers: 1, following: 0 })
32b2b43c
C
433 })
434
40e87e9e 435 it('Should have propagated videos', async function () {
89d241a7 436 const { total, data } = await servers[0].videos.list()
d23dd9fb 437 expect(total).to.equal(7)
b1f5b93e 438
d23dd9fb
C
439 const video2 = data.find(v => v.name === 'server3-2')
440 video4 = data.find(v => v.name === 'server3-4')
441 const video6 = data.find(v => v.name === 'server3-6')
b1f5b93e
C
442
443 expect(video2).to.not.be.undefined
444 expect(video4).to.not.be.undefined
445 expect(video6).to.not.be.undefined
446
447 const isLocal = false
448 const checkAttributes = {
449 name: 'server3-4',
450 category: 2,
451 licence: 6,
9d3ef9fe 452 language: 'zh',
b1f5b93e
C
453 nsfw: true,
454 description: 'my super description',
2422c46b 455 support: 'my super support text',
b64c950a
C
456 account: {
457 name: 'root',
4d029ef8 458 host: servers[2].host
b64c950a 459 },
b1f5b93e 460 isLocal,
47564bbe 461 commentsEnabled: true,
7f2cfe3a 462 downloadEnabled: true,
b1f5b93e
C
463 duration: 5,
464 tags: [ 'tag1', 'tag2', 'tag3' ],
465 privacy: VideoPrivacy.PUBLIC,
466 likes: 1,
467 dislikes: 1,
468 channel: {
f6eebcb3
C
469 displayName: 'Main root channel',
470 name: 'root_channel',
b1f5b93e
C
471 description: '',
472 isLocal
473 },
474 fixture: 'video_short.webm',
475 files: [
476 {
477 resolution: 720,
478 size: 218910
479 }
480 ]
481 }
d102de1b
C
482 await completeVideoCheck({
483 server: servers[0],
484 originServer: servers[2],
485 videoUUID: video4.uuid,
486 attributes: checkAttributes
487 })
b1f5b93e 488 })
c46edbc2 489
40e87e9e 490 it('Should have propagated comments', async function () {
89d241a7 491 const { total, data } = await servers[0].comments.listThreads({ videoId: video4.id, sort: 'createdAt' })
db799da3 492
12edc149
C
493 expect(total).to.equal(2)
494 expect(data).to.be.an('array')
495 expect(data).to.have.lengthOf(2)
c883db6d
C
496
497 {
12edc149 498 const comment = data[0]
c883db6d
C
499 expect(comment.inReplyToCommentId).to.be.null
500 expect(comment.text).equal('my super first comment')
501 expect(comment.videoId).to.equal(video4.id)
502 expect(comment.id).to.equal(comment.threadId)
503 expect(comment.account.name).to.equal('root')
4d029ef8 504 expect(comment.account.host).to.equal(servers[2].host)
c883db6d
C
505 expect(comment.totalReplies).to.equal(3)
506 expect(dateIsValid(comment.createdAt as string)).to.be.true
507 expect(dateIsValid(comment.updatedAt as string)).to.be.true
508
509 const threadId = comment.threadId
510
89d241a7 511 const tree = await servers[0].comments.getThread({ videoId: video4.id, threadId })
c883db6d
C
512 expect(tree.comment.text).equal('my super first comment')
513 expect(tree.children).to.have.lengthOf(2)
514
a1587156 515 const firstChild = tree.children[0]
c883db6d
C
516 expect(firstChild.comment.text).to.equal('my super answer to thread 1')
517 expect(firstChild.children).to.have.lengthOf(1)
518
a1587156 519 const childOfFirstChild = firstChild.children[0]
c883db6d
C
520 expect(childOfFirstChild.comment.text).to.equal('my super answer to answer of thread 1')
521 expect(childOfFirstChild.children).to.have.lengthOf(0)
522
a1587156 523 const secondChild = tree.children[1]
c883db6d
C
524 expect(secondChild.comment.text).to.equal('my second answer to thread 1')
525 expect(secondChild.children).to.have.lengthOf(0)
526 }
527
528 {
12edc149 529 const deletedComment = data[1]
c883db6d
C
530 expect(deletedComment).to.not.be.undefined
531 expect(deletedComment.isDeleted).to.be.true
532 expect(deletedComment.deletedAt).to.not.be.null
533 expect(deletedComment.text).to.equal('')
534 expect(deletedComment.inReplyToCommentId).to.be.null
535 expect(deletedComment.account).to.be.null
9de33c6b 536 expect(deletedComment.totalReplies).to.equal(2)
c883db6d
C
537 expect(dateIsValid(deletedComment.deletedAt as string)).to.be.true
538
89d241a7 539 const tree = await servers[0].comments.getThread({ videoId: video4.id, threadId: deletedComment.threadId })
c883db6d
C
540 const [ commentRoot, deletedChildRoot ] = tree.children
541
542 expect(deletedChildRoot).to.not.be.undefined
543 expect(deletedChildRoot.comment.isDeleted).to.be.true
544 expect(deletedChildRoot.comment.deletedAt).to.not.be.null
545 expect(deletedChildRoot.comment.text).to.equal('')
546 expect(deletedChildRoot.comment.inReplyToCommentId).to.equal(deletedComment.id)
547 expect(deletedChildRoot.comment.account).to.be.null
548 expect(deletedChildRoot.children).to.have.lengthOf(1)
549
550 const answerToDeletedChild = deletedChildRoot.children[0]
551 expect(answerToDeletedChild.comment).to.not.be.undefined
552 expect(answerToDeletedChild.comment.inReplyToCommentId).to.equal(deletedChildRoot.comment.id)
553 expect(answerToDeletedChild.comment.text).to.equal('my second answer to deleted')
554 expect(answerToDeletedChild.comment.account.name).to.equal('root')
555
556 expect(commentRoot.comment).to.not.be.undefined
557 expect(commentRoot.comment.inReplyToCommentId).to.equal(deletedComment.id)
558 expect(commentRoot.comment.text).to.equal('answer to deleted')
559 expect(commentRoot.comment.account.name).to.equal('root')
560 }
b1f5b93e 561 })
f05a1c30 562
40e87e9e 563 it('Should have propagated captions', async function () {
c63830f1 564 const body = await servers[0].captions.list({ videoId: video4.id })
a2470c9f
C
565 expect(body.total).to.equal(1)
566 expect(body.data).to.have.lengthOf(1)
40e87e9e 567
a2470c9f 568 const caption1 = body.data[0]
40e87e9e
C
569 expect(caption1.language.id).to.equal('ar')
570 expect(caption1.language.label).to.equal('Arabic')
a35a2279 571 expect(caption1.captionPath).to.match(new RegExp('^/lazy-static/video-captions/.+-ar.vtt$'))
40e87e9e
C
572 await testCaptionFile(servers[0].url, caption1.captionPath, 'Subtitle good 2.')
573 })
574
f05a1c30
C
575 it('Should unfollow server 3 on server 1 and does not list server 3 videos', async function () {
576 this.timeout(5000)
577
4d029ef8 578 await servers[0].follows.unfollow({ target: servers[2] })
f05a1c30 579
3cd0734f 580 await waitJobs(servers)
f05a1c30 581
89d241a7 582 const { total } = await servers[0].videos.list()
d23dd9fb 583 expect(total).to.equal(1)
f05a1c30 584 })
4d029ef8
C
585 })
586
587 describe('Should propagate data on a new channel follow', function () {
588
589 before(async function () {
590 this.timeout(60000)
f05a1c30 591
4d029ef8
C
592 await servers[2].videos.upload({ attributes: { name: 'server3-7' } })
593
594 await waitJobs(servers)
595
596 const video = await servers[0].videos.find({ name: 'server3-7' })
597 expect(video).to.not.exist
598 })
599
600 it('Should have propagated channel video', async function () {
601 this.timeout(60000)
602
603 await servers[0].follows.follow({ handles: [ 'root_channel@' + servers[2].host ] })
604
605 await waitJobs(servers)
606
607 const video = await servers[0].videos.find({ name: 'server3-7' })
608
609 expect(video).to.exist
610 })
c46edbc2
C
611 })
612
7c3b7976
C
613 after(async function () {
614 await cleanupTests(servers)
0f91ae62
C
615 })
616})