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