aboutsummaryrefslogtreecommitdiffhomepage
path: root/packages/tests/src/api/server/follows.ts
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2023-07-31 14:34:36 +0200
committerChocobozzz <me@florianbigard.com>2023-08-11 15:02:33 +0200
commit3a4992633ee62d5edfbb484d9c6bcb3cf158489d (patch)
treee4510b39bdac9c318fdb4b47018d08f15368b8f0 /packages/tests/src/api/server/follows.ts
parent04d1da5621d25d59bd5fa1543b725c497bf5d9a8 (diff)
downloadPeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.tar.gz
PeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.tar.zst
PeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.zip
Migrate server to ESM
Sorry for the very big commit that may lead to git log issues and merge conflicts, but it's a major step forward: * Server can be faster at startup because imports() are async and we can easily lazy import big modules * Angular doesn't seem to support ES import (with .js extension), so we had to correctly organize peertube into a monorepo: * Use yarn workspace feature * Use typescript reference projects for dependencies * Shared projects have been moved into "packages", each one is now a node module (with a dedicated package.json/tsconfig.json) * server/tools have been moved into apps/ and is now a dedicated app bundled and published on NPM so users don't have to build peertube cli tools manually * server/tests have been moved into packages/ so we don't compile them every time we want to run the server * Use isolatedModule option: * Had to move from const enum to const (https://www.typescriptlang.org/docs/handbook/enums.html#objects-vs-enums) * Had to explictely specify "type" imports when used in decorators * Prefer tsx (that uses esbuild under the hood) instead of ts-node to load typescript files (tests with mocha or scripts): * To reduce test complexity as esbuild doesn't support decorator metadata, we only test server files that do not import server models * We still build tests files into js files for a faster CI * Remove unmaintained peertube CLI import script * Removed some barrels to speed up execution (less imports)
Diffstat (limited to 'packages/tests/src/api/server/follows.ts')
-rw-r--r--packages/tests/src/api/server/follows.ts644
1 files changed, 644 insertions, 0 deletions
diff --git a/packages/tests/src/api/server/follows.ts b/packages/tests/src/api/server/follows.ts
new file mode 100644
index 000000000..fbe2e87da
--- /dev/null
+++ b/packages/tests/src/api/server/follows.ts
@@ -0,0 +1,644 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import { expect } from 'chai'
4import { Video, VideoPrivacy } from '@peertube/peertube-models'
5import { cleanupTests, createMultipleServers, PeerTubeServer, setAccessTokensToServers, waitJobs } from '@peertube/peertube-server-commands'
6import { expectAccountFollows, expectChannelsFollows } from '@tests/shared/actors.js'
7import { testCaptionFile } from '@tests/shared/captions.js'
8import { dateIsValid } from '@tests/shared/checks.js'
9import { completeVideoCheck } from '@tests/shared/videos.js'
10
11describe('Test follows', function () {
12
13 describe('Complex follow', function () {
14 let servers: PeerTubeServer[] = []
15
16 before(async function () {
17 this.timeout(120000)
18
19 servers = await createMultipleServers(3)
20
21 // Get the access tokens
22 await setAccessTokensToServers(servers)
23 })
24
25 describe('Data propagation after follow', function () {
26
27 it('Should not have followers/followings', async function () {
28 for (const server of servers) {
29 const bodies = await Promise.all([
30 server.follows.getFollowers({ start: 0, count: 5, sort: 'createdAt' }),
31 server.follows.getFollowings({ start: 0, count: 5, sort: 'createdAt' })
32 ])
33
34 for (const body of bodies) {
35 expect(body.total).to.equal(0)
36
37 const follows = body.data
38 expect(follows).to.be.an('array')
39 expect(follows).to.have.lengthOf(0)
40 }
41 }
42 })
43
44 it('Should have server 1 following root account of server 2 and server 3', async function () {
45 this.timeout(30000)
46
47 await servers[0].follows.follow({
48 hosts: [ servers[2].url ],
49 handles: [ 'root@' + servers[1].host ]
50 })
51
52 await waitJobs(servers)
53 })
54
55 it('Should have 2 followings on server 1', async function () {
56 const body = await servers[0].follows.getFollowings({ start: 0, count: 1, sort: 'createdAt' })
57 expect(body.total).to.equal(2)
58
59 let follows = body.data
60 expect(follows).to.be.an('array')
61 expect(follows).to.have.lengthOf(1)
62
63 const body2 = await servers[0].follows.getFollowings({ start: 1, count: 1, sort: 'createdAt' })
64 follows = follows.concat(body2.data)
65
66 const server2Follow = follows.find(f => f.following.host === servers[1].host)
67 const server3Follow = follows.find(f => f.following.host === servers[2].host)
68
69 expect(server2Follow).to.not.be.undefined
70 expect(server2Follow.following.name).to.equal('root')
71 expect(server2Follow.state).to.equal('accepted')
72
73 expect(server3Follow).to.not.be.undefined
74 expect(server3Follow.following.name).to.equal('peertube')
75 expect(server3Follow.state).to.equal('accepted')
76 })
77
78 it('Should have 0 followings on server 2 and 3', async function () {
79 for (const server of [ servers[1], servers[2] ]) {
80 const body = await server.follows.getFollowings({ start: 0, count: 5, sort: 'createdAt' })
81 expect(body.total).to.equal(0)
82
83 const follows = body.data
84 expect(follows).to.be.an('array')
85 expect(follows).to.have.lengthOf(0)
86 }
87 })
88
89 it('Should have 1 followers on server 3', async function () {
90 const body = await servers[2].follows.getFollowers({ start: 0, count: 1, sort: 'createdAt' })
91 expect(body.total).to.equal(1)
92
93 const follows = body.data
94 expect(follows).to.be.an('array')
95 expect(follows).to.have.lengthOf(1)
96 expect(follows[0].follower.host).to.equal(servers[0].host)
97 })
98
99 it('Should have 0 followers on server 1 and 2', async function () {
100 for (const server of [ servers[0], servers[1] ]) {
101 const body = await server.follows.getFollowers({ start: 0, count: 5, sort: 'createdAt' })
102 expect(body.total).to.equal(0)
103
104 const follows = body.data
105 expect(follows).to.be.an('array')
106 expect(follows).to.have.lengthOf(0)
107 }
108 })
109
110 it('Should search/filter followings on server 1', async function () {
111 const sort = 'createdAt'
112 const start = 0
113 const count = 1
114
115 {
116 const search = ':' + servers[1].port
117
118 {
119 const body = await servers[0].follows.getFollowings({ start, count, sort, search })
120 expect(body.total).to.equal(1)
121
122 const follows = body.data
123 expect(follows).to.have.lengthOf(1)
124 expect(follows[0].following.host).to.equal(servers[1].host)
125 }
126
127 {
128 const body = await servers[0].follows.getFollowings({ start, count, sort, search, state: 'accepted' })
129 expect(body.total).to.equal(1)
130 expect(body.data).to.have.lengthOf(1)
131 }
132
133 {
134 const body = await servers[0].follows.getFollowings({ start, count, sort, search, state: 'accepted', actorType: 'Person' })
135 expect(body.total).to.equal(1)
136 expect(body.data).to.have.lengthOf(1)
137 }
138
139 {
140 const body = await servers[0].follows.getFollowings({
141 start,
142 count,
143 sort,
144 search,
145 state: 'accepted',
146 actorType: 'Application'
147 })
148 expect(body.total).to.equal(0)
149 expect(body.data).to.have.lengthOf(0)
150 }
151
152 {
153 const body = await servers[0].follows.getFollowings({ start, count, sort, search, state: 'pending' })
154 expect(body.total).to.equal(0)
155 expect(body.data).to.have.lengthOf(0)
156 }
157 }
158
159 {
160 const body = await servers[0].follows.getFollowings({ start, count, sort, search: 'root' })
161 expect(body.total).to.equal(1)
162 expect(body.data).to.have.lengthOf(1)
163 }
164
165 {
166 const body = await servers[0].follows.getFollowings({ start, count, sort, search: 'bla' })
167 expect(body.total).to.equal(0)
168
169 expect(body.data).to.have.lengthOf(0)
170 }
171 })
172
173 it('Should search/filter followers on server 2', async function () {
174 const start = 0
175 const count = 5
176 const sort = 'createdAt'
177
178 {
179 const search = servers[0].port + ''
180
181 {
182 const body = await servers[2].follows.getFollowers({ start, count, sort, search })
183 expect(body.total).to.equal(1)
184
185 const follows = body.data
186 expect(follows).to.have.lengthOf(1)
187 expect(follows[0].following.host).to.equal(servers[2].host)
188 }
189
190 {
191 const body = await servers[2].follows.getFollowers({ start, count, sort, search, state: 'accepted' })
192 expect(body.total).to.equal(1)
193 expect(body.data).to.have.lengthOf(1)
194 }
195
196 {
197 const body = await servers[2].follows.getFollowers({ start, count, sort, search, state: 'accepted', actorType: 'Person' })
198 expect(body.total).to.equal(0)
199 expect(body.data).to.have.lengthOf(0)
200 }
201
202 {
203 const body = await servers[2].follows.getFollowers({
204 start,
205 count,
206 sort,
207 search,
208 state: 'accepted',
209 actorType: 'Application'
210 })
211 expect(body.total).to.equal(1)
212 expect(body.data).to.have.lengthOf(1)
213 }
214
215 {
216 const body = await servers[2].follows.getFollowers({ start, count, sort, search, state: 'pending' })
217 expect(body.total).to.equal(0)
218 expect(body.data).to.have.lengthOf(0)
219 }
220 }
221
222 {
223 const body = await servers[2].follows.getFollowers({ start, count, sort, search: 'bla' })
224 expect(body.total).to.equal(0)
225
226 const follows = body.data
227 expect(follows).to.have.lengthOf(0)
228 }
229 })
230
231 it('Should have the correct follows counts', async function () {
232 await expectAccountFollows({ server: servers[0], handle: 'peertube@' + servers[0].host, followers: 0, following: 2 })
233 await expectAccountFollows({ server: servers[0], handle: 'root@' + servers[1].host, followers: 1, following: 0 })
234 await expectAccountFollows({ server: servers[0], handle: 'peertube@' + servers[2].host, followers: 1, following: 0 })
235
236 // Server 2 and 3 does not know server 1 follow another server (there was not a refresh)
237 await expectAccountFollows({ server: servers[1], handle: 'peertube@' + servers[0].host, followers: 0, following: 1 })
238 await expectAccountFollows({ server: servers[1], handle: 'root@' + servers[1].host, followers: 1, following: 0 })
239 await expectAccountFollows({ server: servers[1], handle: 'peertube@' + servers[1].host, followers: 0, following: 0 })
240
241 await expectAccountFollows({ server: servers[2], handle: 'peertube@' + servers[0].host, followers: 0, following: 1 })
242 await expectAccountFollows({ server: servers[2], handle: 'peertube@' + servers[2].host, followers: 1, following: 0 })
243 })
244
245 it('Should unfollow server 3 on server 1', async function () {
246 this.timeout(15000)
247
248 await servers[0].follows.unfollow({ target: servers[2] })
249
250 await waitJobs(servers)
251 })
252
253 it('Should not follow server 3 on server 1 anymore', async function () {
254 const body = await servers[0].follows.getFollowings({ start: 0, count: 2, sort: 'createdAt' })
255 expect(body.total).to.equal(1)
256
257 const follows = body.data
258 expect(follows).to.be.an('array')
259 expect(follows).to.have.lengthOf(1)
260
261 expect(follows[0].following.host).to.equal(servers[1].host)
262 })
263
264 it('Should not have server 1 as follower on server 3 anymore', async function () {
265 const body = await servers[2].follows.getFollowers({ start: 0, count: 1, sort: 'createdAt' })
266 expect(body.total).to.equal(0)
267
268 const follows = body.data
269 expect(follows).to.be.an('array')
270 expect(follows).to.have.lengthOf(0)
271 })
272
273 it('Should have the correct follows counts after the unfollow', async function () {
274 await expectAccountFollows({ server: servers[0], handle: 'peertube@' + servers[0].host, followers: 0, following: 1 })
275 await expectAccountFollows({ server: servers[0], handle: 'root@' + servers[1].host, followers: 1, following: 0 })
276 await expectAccountFollows({ server: servers[0], handle: 'peertube@' + servers[2].host, followers: 0, following: 0 })
277
278 await expectAccountFollows({ server: servers[1], handle: 'peertube@' + servers[0].host, followers: 0, following: 1 })
279 await expectAccountFollows({ server: servers[1], handle: 'root@' + servers[1].host, followers: 1, following: 0 })
280 await expectAccountFollows({ server: servers[1], handle: 'peertube@' + servers[1].host, followers: 0, following: 0 })
281
282 await expectAccountFollows({ server: servers[2], handle: 'peertube@' + servers[0].host, followers: 0, following: 0 })
283 await expectAccountFollows({ server: servers[2], handle: 'peertube@' + servers[2].host, followers: 0, following: 0 })
284 })
285
286 it('Should upload a video on server 2 and 3 and propagate only the video of server 2', async function () {
287 this.timeout(160000)
288
289 await servers[1].videos.upload({ attributes: { name: 'server2' } })
290 await servers[2].videos.upload({ attributes: { name: 'server3' } })
291
292 await waitJobs(servers)
293
294 {
295 const { total, data } = await servers[0].videos.list()
296 expect(total).to.equal(1)
297 expect(data[0].name).to.equal('server2')
298 }
299
300 {
301 const { total, data } = await servers[1].videos.list()
302 expect(total).to.equal(1)
303 expect(data[0].name).to.equal('server2')
304 }
305
306 {
307 const { total, data } = await servers[2].videos.list()
308 expect(total).to.equal(1)
309 expect(data[0].name).to.equal('server3')
310 }
311 })
312
313 it('Should remove account follow', async function () {
314 this.timeout(15000)
315
316 await servers[0].follows.unfollow({ target: 'root@' + servers[1].host })
317
318 await waitJobs(servers)
319 })
320
321 it('Should have removed the account follow', async function () {
322 await expectAccountFollows({ server: servers[0], handle: 'root@' + servers[1].host, followers: 0, following: 0 })
323 await expectAccountFollows({ server: servers[1], handle: 'root@' + servers[1].host, followers: 0, following: 0 })
324
325 {
326 const { total, data } = await servers[0].follows.getFollowings()
327 expect(total).to.equal(0)
328 expect(data).to.have.lengthOf(0)
329 }
330
331 {
332 const { total, data } = await servers[0].videos.list()
333 expect(total).to.equal(0)
334 expect(data).to.have.lengthOf(0)
335 }
336 })
337
338 it('Should follow a channel', async function () {
339 this.timeout(15000)
340
341 await servers[0].follows.follow({
342 handles: [ 'root_channel@' + servers[1].host ]
343 })
344
345 await waitJobs(servers)
346
347 await expectChannelsFollows({ server: servers[0], handle: 'root_channel@' + servers[1].host, followers: 1, following: 0 })
348 await expectChannelsFollows({ server: servers[1], handle: 'root_channel@' + servers[1].host, followers: 1, following: 0 })
349
350 {
351 const { total, data } = await servers[0].follows.getFollowings()
352 expect(total).to.equal(1)
353 expect(data).to.have.lengthOf(1)
354 }
355
356 {
357 const { total, data } = await servers[0].videos.list()
358 expect(total).to.equal(1)
359 expect(data).to.have.lengthOf(1)
360 }
361 })
362 })
363
364 describe('Should propagate data on a new server follow', function () {
365 let video4: Video
366
367 before(async function () {
368 this.timeout(240000)
369
370 const video4Attributes = {
371 name: 'server3-4',
372 category: 2,
373 nsfw: true,
374 licence: 6,
375 tags: [ 'tag1', 'tag2', 'tag3' ]
376 }
377
378 await servers[2].videos.upload({ attributes: { name: 'server3-2' } })
379 await servers[2].videos.upload({ attributes: { name: 'server3-3' } })
380
381 const video4CreateResult = await servers[2].videos.upload({ attributes: video4Attributes })
382
383 await servers[2].videos.upload({ attributes: { name: 'server3-5' } })
384 await servers[2].videos.upload({ attributes: { name: 'server3-6' } })
385
386 {
387 const userAccessToken = await servers[2].users.generateUserAndToken('captain')
388
389 await servers[2].videos.rate({ id: video4CreateResult.id, rating: 'like' })
390 await servers[2].videos.rate({ token: userAccessToken, id: video4CreateResult.id, rating: 'dislike' })
391 }
392
393 {
394 await servers[2].comments.createThread({ videoId: video4CreateResult.id, text: 'my super first comment' })
395
396 await servers[2].comments.addReplyToLastThread({ text: 'my super answer to thread 1' })
397 await servers[2].comments.addReplyToLastReply({ text: 'my super answer to answer of thread 1' })
398 await servers[2].comments.addReplyToLastThread({ text: 'my second answer to thread 1' })
399 }
400
401 {
402 const { id: threadId } = await servers[2].comments.createThread({ videoId: video4CreateResult.id, text: 'will be deleted' })
403 await servers[2].comments.addReplyToLastThread({ text: 'answer to deleted' })
404
405 const { id: replyId } = await servers[2].comments.addReplyToLastThread({ text: 'will also be deleted' })
406
407 await servers[2].comments.addReplyToLastReply({ text: 'my second answer to deleted' })
408
409 await servers[2].comments.delete({ videoId: video4CreateResult.id, commentId: threadId })
410 await servers[2].comments.delete({ videoId: video4CreateResult.id, commentId: replyId })
411 }
412
413 await servers[2].captions.add({
414 language: 'ar',
415 videoId: video4CreateResult.id,
416 fixture: 'subtitle-good2.vtt'
417 })
418
419 await waitJobs(servers)
420
421 // Server 1 follows server 3
422 await servers[0].follows.follow({ hosts: [ servers[2].url ] })
423
424 await waitJobs(servers)
425 })
426
427 it('Should have the correct follows counts', async function () {
428 await expectAccountFollows({ server: servers[0], handle: 'peertube@' + servers[0].host, followers: 0, following: 2 })
429 await expectAccountFollows({ server: servers[0], handle: 'root@' + servers[1].host, followers: 0, following: 0 })
430 await expectChannelsFollows({ server: servers[0], handle: 'root_channel@' + servers[1].host, followers: 1, following: 0 })
431 await expectAccountFollows({ server: servers[0], handle: 'peertube@' + servers[2].host, followers: 1, following: 0 })
432
433 await expectAccountFollows({ server: servers[1], handle: 'peertube@' + servers[0].host, followers: 0, following: 1 })
434 await expectAccountFollows({ server: servers[1], handle: 'peertube@' + servers[1].host, followers: 0, following: 0 })
435 await expectAccountFollows({ server: servers[1], handle: 'root@' + servers[1].host, followers: 0, following: 0 })
436 await expectChannelsFollows({ server: servers[1], handle: 'root_channel@' + servers[1].host, followers: 1, following: 0 })
437
438 await expectAccountFollows({ server: servers[2], handle: 'peertube@' + servers[0].host, followers: 0, following: 1 })
439 await expectAccountFollows({ server: servers[2], handle: 'peertube@' + servers[2].host, followers: 1, following: 0 })
440 })
441
442 it('Should have propagated videos', async function () {
443 const { total, data } = await servers[0].videos.list()
444 expect(total).to.equal(7)
445
446 const video2 = data.find(v => v.name === 'server3-2')
447 video4 = data.find(v => v.name === 'server3-4')
448 const video6 = data.find(v => v.name === 'server3-6')
449
450 expect(video2).to.not.be.undefined
451 expect(video4).to.not.be.undefined
452 expect(video6).to.not.be.undefined
453
454 const isLocal = false
455 const checkAttributes = {
456 name: 'server3-4',
457 category: 2,
458 licence: 6,
459 language: 'zh',
460 nsfw: true,
461 description: 'my super description',
462 support: 'my super support text',
463 account: {
464 name: 'root',
465 host: servers[2].host
466 },
467 isLocal,
468 commentsEnabled: true,
469 downloadEnabled: true,
470 duration: 5,
471 tags: [ 'tag1', 'tag2', 'tag3' ],
472 privacy: VideoPrivacy.PUBLIC,
473 likes: 1,
474 dislikes: 1,
475 channel: {
476 displayName: 'Main root channel',
477 name: 'root_channel',
478 description: '',
479 isLocal
480 },
481 fixture: 'video_short.webm',
482 files: [
483 {
484 resolution: 720,
485 size: 218910
486 }
487 ]
488 }
489 await completeVideoCheck({
490 server: servers[0],
491 originServer: servers[2],
492 videoUUID: video4.uuid,
493 attributes: checkAttributes
494 })
495 })
496
497 it('Should have propagated comments', async function () {
498 const { total, data } = await servers[0].comments.listThreads({ videoId: video4.id, sort: 'createdAt' })
499
500 expect(total).to.equal(2)
501 expect(data).to.be.an('array')
502 expect(data).to.have.lengthOf(2)
503
504 {
505 const comment = data[0]
506 expect(comment.inReplyToCommentId).to.be.null
507 expect(comment.text).equal('my super first comment')
508 expect(comment.videoId).to.equal(video4.id)
509 expect(comment.id).to.equal(comment.threadId)
510 expect(comment.account.name).to.equal('root')
511 expect(comment.account.host).to.equal(servers[2].host)
512 expect(comment.totalReplies).to.equal(3)
513 expect(dateIsValid(comment.createdAt as string)).to.be.true
514 expect(dateIsValid(comment.updatedAt as string)).to.be.true
515
516 const threadId = comment.threadId
517
518 const tree = await servers[0].comments.getThread({ videoId: video4.id, threadId })
519 expect(tree.comment.text).equal('my super first comment')
520 expect(tree.children).to.have.lengthOf(2)
521
522 const firstChild = tree.children[0]
523 expect(firstChild.comment.text).to.equal('my super answer to thread 1')
524 expect(firstChild.children).to.have.lengthOf(1)
525
526 const childOfFirstChild = firstChild.children[0]
527 expect(childOfFirstChild.comment.text).to.equal('my super answer to answer of thread 1')
528 expect(childOfFirstChild.children).to.have.lengthOf(0)
529
530 const secondChild = tree.children[1]
531 expect(secondChild.comment.text).to.equal('my second answer to thread 1')
532 expect(secondChild.children).to.have.lengthOf(0)
533 }
534
535 {
536 const deletedComment = data[1]
537 expect(deletedComment).to.not.be.undefined
538 expect(deletedComment.isDeleted).to.be.true
539 expect(deletedComment.deletedAt).to.not.be.null
540 expect(deletedComment.text).to.equal('')
541 expect(deletedComment.inReplyToCommentId).to.be.null
542 expect(deletedComment.account).to.be.null
543 expect(deletedComment.totalReplies).to.equal(2)
544 expect(dateIsValid(deletedComment.deletedAt as string)).to.be.true
545
546 const tree = await servers[0].comments.getThread({ videoId: video4.id, threadId: deletedComment.threadId })
547 const [ commentRoot, deletedChildRoot ] = tree.children
548
549 expect(deletedChildRoot).to.not.be.undefined
550 expect(deletedChildRoot.comment.isDeleted).to.be.true
551 expect(deletedChildRoot.comment.deletedAt).to.not.be.null
552 expect(deletedChildRoot.comment.text).to.equal('')
553 expect(deletedChildRoot.comment.inReplyToCommentId).to.equal(deletedComment.id)
554 expect(deletedChildRoot.comment.account).to.be.null
555 expect(deletedChildRoot.children).to.have.lengthOf(1)
556
557 const answerToDeletedChild = deletedChildRoot.children[0]
558 expect(answerToDeletedChild.comment).to.not.be.undefined
559 expect(answerToDeletedChild.comment.inReplyToCommentId).to.equal(deletedChildRoot.comment.id)
560 expect(answerToDeletedChild.comment.text).to.equal('my second answer to deleted')
561 expect(answerToDeletedChild.comment.account.name).to.equal('root')
562
563 expect(commentRoot.comment).to.not.be.undefined
564 expect(commentRoot.comment.inReplyToCommentId).to.equal(deletedComment.id)
565 expect(commentRoot.comment.text).to.equal('answer to deleted')
566 expect(commentRoot.comment.account.name).to.equal('root')
567 }
568 })
569
570 it('Should have propagated captions', async function () {
571 const body = await servers[0].captions.list({ videoId: video4.id })
572 expect(body.total).to.equal(1)
573 expect(body.data).to.have.lengthOf(1)
574
575 const caption1 = body.data[0]
576 expect(caption1.language.id).to.equal('ar')
577 expect(caption1.language.label).to.equal('Arabic')
578 expect(caption1.captionPath).to.match(new RegExp('^/lazy-static/video-captions/.+-ar.vtt$'))
579 await testCaptionFile(servers[0].url, caption1.captionPath, 'Subtitle good 2.')
580 })
581
582 it('Should unfollow server 3 on server 1 and does not list server 3 videos', async function () {
583 this.timeout(5000)
584
585 await servers[0].follows.unfollow({ target: servers[2] })
586
587 await waitJobs(servers)
588
589 const { total } = await servers[0].videos.list()
590 expect(total).to.equal(1)
591 })
592 })
593
594 after(async function () {
595 await cleanupTests(servers)
596 })
597 })
598
599 describe('Simple data propagation propagate data on a new channel follow', function () {
600 let servers: PeerTubeServer[] = []
601
602 before(async function () {
603 this.timeout(120000)
604
605 servers = await createMultipleServers(3)
606 await setAccessTokensToServers(servers)
607
608 await servers[0].videos.upload({ attributes: { name: 'video to add' } })
609
610 await waitJobs(servers)
611
612 for (const server of [ servers[1], servers[2] ]) {
613 const video = await server.videos.find({ name: 'video to add' })
614 expect(video).to.not.exist
615 }
616 })
617
618 it('Should have propagated video after new channel follow', async function () {
619 this.timeout(60000)
620
621 await servers[1].follows.follow({ handles: [ 'root_channel@' + servers[0].host ] })
622
623 await waitJobs(servers)
624
625 const video = await servers[1].videos.find({ name: 'video to add' })
626 expect(video).to.exist
627 })
628
629 it('Should have propagated video after new account follow', async function () {
630 this.timeout(60000)
631
632 await servers[2].follows.follow({ handles: [ 'root@' + servers[0].host ] })
633
634 await waitJobs(servers)
635
636 const video = await servers[2].videos.find({ name: 'video to add' })
637 expect(video).to.exist
638 })
639
640 after(async function () {
641 await cleanupTests(servers)
642 })
643 })
644})