1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
4 import * as chai from 'chai'
5 import { VideoPrivacy } from '@shared/models'
11 setAccessTokensToServers,
12 setDefaultAccountAvatar,
13 setDefaultChannelAvatar,
16 } from '@shared/server-commands'
18 const expect = chai.expect
20 describe('Test users subscriptions', function () {
21 let servers: PeerTubeServer[] = []
22 const users: { accessToken: string }[] = []
23 let video3UUID: string
25 let command: SubscriptionsCommand
27 before(async function () {
30 servers = await createMultipleServers(3)
32 // Get the access tokens
33 await setAccessTokensToServers(servers)
34 await setDefaultChannelAvatar(servers)
35 await setDefaultAccountAvatar(servers)
37 // Server 1 and server 2 follow each other
38 await doubleFollow(servers[0], servers[1])
40 for (const server of servers) {
41 const user = { username: 'user' + server.serverNumber, password: 'password' }
42 await server.users.create({ username: user.username, password: user.password })
44 const accessToken = await server.login.getAccessToken(user)
45 users.push({ accessToken })
47 const videoName1 = 'video 1-' + server.serverNumber
48 await server.videos.upload({ token: accessToken, attributes: { name: videoName1 } })
50 const videoName2 = 'video 2-' + server.serverNumber
51 await server.videos.upload({ token: accessToken, attributes: { name: videoName2 } })
54 await waitJobs(servers)
56 command = servers[0].subscriptions
59 it('Should display videos of server 2 on server 1', async function () {
60 const { total } = await servers[0].videos.list()
62 expect(total).to.equal(4)
65 it('User of server 1 should follow user of server 3 and root of server 1', async function () {
68 await command.add({ token: users[0].accessToken, targetUri: 'user3_channel@localhost:' + servers[2].port })
69 await command.add({ token: users[0].accessToken, targetUri: 'root_channel@localhost:' + servers[0].port })
71 await waitJobs(servers)
73 const attributes = { name: 'video server 3 added after follow' }
74 const { uuid } = await servers[2].videos.upload({ token: users[2].accessToken, attributes })
77 await waitJobs(servers)
80 it('Should not display videos of server 3 on server 1', async function () {
81 const { total, data } = await servers[0].videos.list()
82 expect(total).to.equal(4)
84 for (const video of data) {
85 expect(video.name).to.not.contain('1-3')
86 expect(video.name).to.not.contain('2-3')
87 expect(video.name).to.not.contain('video server 3 added after follow')
91 it('Should list subscriptions', async function () {
93 const body = await command.list()
94 expect(body.total).to.equal(0)
95 expect(body.data).to.be.an('array')
96 expect(body.data).to.have.lengthOf(0)
100 const body = await command.list({ token: users[0].accessToken, sort: 'createdAt' })
101 expect(body.total).to.equal(2)
103 const subscriptions = body.data
104 expect(subscriptions).to.be.an('array')
105 expect(subscriptions).to.have.lengthOf(2)
107 expect(subscriptions[0].name).to.equal('user3_channel')
108 expect(subscriptions[1].name).to.equal('root_channel')
112 it('Should get subscription', async function () {
114 const videoChannel = await command.get({ token: users[0].accessToken, uri: 'user3_channel@localhost:' + servers[2].port })
116 expect(videoChannel.name).to.equal('user3_channel')
117 expect(videoChannel.host).to.equal('localhost:' + servers[2].port)
118 expect(videoChannel.displayName).to.equal('Main user3 channel')
119 expect(videoChannel.followingCount).to.equal(0)
120 expect(videoChannel.followersCount).to.equal(1)
124 const videoChannel = await command.get({ token: users[0].accessToken, uri: 'root_channel@localhost:' + servers[0].port })
126 expect(videoChannel.name).to.equal('root_channel')
127 expect(videoChannel.host).to.equal('localhost:' + servers[0].port)
128 expect(videoChannel.displayName).to.equal('Main root channel')
129 expect(videoChannel.followingCount).to.equal(0)
130 expect(videoChannel.followersCount).to.equal(1)
134 it('Should return the existing subscriptions', async function () {
136 'user3_channel@localhost:' + servers[2].port,
137 'root2_channel@localhost:' + servers[0].port,
138 'root_channel@localhost:' + servers[0].port,
139 'user3_channel@localhost:' + servers[0].port
142 const body = await command.exist({ token: users[0].accessToken, uris })
144 expect(body['user3_channel@localhost:' + servers[2].port]).to.be.true
145 expect(body['root2_channel@localhost:' + servers[0].port]).to.be.false
146 expect(body['root_channel@localhost:' + servers[0].port]).to.be.true
147 expect(body['user3_channel@localhost:' + servers[0].port]).to.be.false
150 it('Should search among subscriptions', async function () {
152 const body = await command.list({ token: users[0].accessToken, sort: '-createdAt', search: 'user3_channel' })
153 expect(body.total).to.equal(1)
154 expect(body.data).to.have.lengthOf(1)
158 const body = await command.list({ token: users[0].accessToken, sort: '-createdAt', search: 'toto' })
159 expect(body.total).to.equal(0)
160 expect(body.data).to.have.lengthOf(0)
164 it('Should list subscription videos', async function () {
166 const body = await command.listVideos()
167 expect(body.total).to.equal(0)
168 expect(body.data).to.be.an('array')
169 expect(body.data).to.have.lengthOf(0)
173 const body = await command.listVideos({ token: users[0].accessToken, sort: 'createdAt' })
174 expect(body.total).to.equal(3)
176 const videos = body.data
177 expect(videos).to.be.an('array')
178 expect(videos).to.have.lengthOf(3)
180 expect(videos[0].name).to.equal('video 1-3')
181 expect(videos[1].name).to.equal('video 2-3')
182 expect(videos[2].name).to.equal('video server 3 added after follow')
186 it('Should upload a video by root on server 1 and see it in the subscription videos', async function () {
189 const videoName = 'video server 1 added after follow'
190 await servers[0].videos.upload({ attributes: { name: videoName } })
192 await waitJobs(servers)
195 const body = await command.listVideos()
196 expect(body.total).to.equal(0)
197 expect(body.data).to.be.an('array')
198 expect(body.data).to.have.lengthOf(0)
202 const body = await command.listVideos({ token: users[0].accessToken, sort: 'createdAt' })
203 expect(body.total).to.equal(4)
205 const videos = body.data
206 expect(videos).to.be.an('array')
207 expect(videos).to.have.lengthOf(4)
209 expect(videos[0].name).to.equal('video 1-3')
210 expect(videos[1].name).to.equal('video 2-3')
211 expect(videos[2].name).to.equal('video server 3 added after follow')
212 expect(videos[3].name).to.equal('video server 1 added after follow')
216 const { data, total } = await servers[0].videos.list()
217 expect(total).to.equal(5)
219 for (const video of data) {
220 expect(video.name).to.not.contain('1-3')
221 expect(video.name).to.not.contain('2-3')
222 expect(video.name).to.not.contain('video server 3 added after follow')
227 it('Should have server 1 follow server 3 and display server 3 videos', async function () {
230 await servers[0].follows.follow({ hosts: [ servers[2].url ] })
232 await waitJobs(servers)
234 const { data, total } = await servers[0].videos.list()
235 expect(total).to.equal(8)
237 const names = [ '1-3', '2-3', 'video server 3 added after follow' ]
238 for (const name of names) {
239 const video = data.find(v => v.name.includes(name))
240 expect(video).to.not.be.undefined
244 it('Should remove follow server 1 -> server 3 and hide server 3 videos', async function () {
247 await servers[0].follows.unfollow({ target: servers[2] })
249 await waitJobs(servers)
251 const { total, data } = await servers[0].videos.list()
252 expect(total).to.equal(5)
254 for (const video of data) {
255 expect(video.name).to.not.contain('1-3')
256 expect(video.name).to.not.contain('2-3')
257 expect(video.name).to.not.contain('video server 3 added after follow')
261 it('Should still list subscription videos', async function () {
263 const body = await command.listVideos()
264 expect(body.total).to.equal(0)
265 expect(body.data).to.be.an('array')
266 expect(body.data).to.have.lengthOf(0)
270 const body = await command.listVideos({ token: users[0].accessToken, sort: 'createdAt' })
271 expect(body.total).to.equal(4)
273 const videos = body.data
274 expect(videos).to.be.an('array')
275 expect(videos).to.have.lengthOf(4)
277 expect(videos[0].name).to.equal('video 1-3')
278 expect(videos[1].name).to.equal('video 2-3')
279 expect(videos[2].name).to.equal('video server 3 added after follow')
280 expect(videos[3].name).to.equal('video server 1 added after follow')
284 it('Should update a video of server 3 and see the updated video on server 1', async function () {
287 await servers[2].videos.update({ id: video3UUID, attributes: { name: 'video server 3 added after follow updated' } })
289 await waitJobs(servers)
291 const body = await command.listVideos({ token: users[0].accessToken, sort: 'createdAt' })
292 expect(body.data[2].name).to.equal('video server 3 added after follow updated')
295 it('Should remove user of server 3 subscription', async function () {
298 await command.remove({ token: users[0].accessToken, uri: 'user3_channel@localhost:' + servers[2].port })
300 await waitJobs(servers)
303 it('Should not display its videos anymore', async function () {
304 const body = await command.listVideos({ token: users[0].accessToken, sort: 'createdAt' })
305 expect(body.total).to.equal(1)
307 const videos = body.data
308 expect(videos).to.be.an('array')
309 expect(videos).to.have.lengthOf(1)
311 expect(videos[0].name).to.equal('video server 1 added after follow')
314 it('Should remove the root subscription and not display the videos anymore', async function () {
317 await command.remove({ token: users[0].accessToken, uri: 'root_channel@localhost:' + servers[0].port })
319 await waitJobs(servers)
322 const body = await command.list({ token: users[0].accessToken, sort: 'createdAt' })
323 expect(body.total).to.equal(0)
325 const videos = body.data
326 expect(videos).to.be.an('array')
327 expect(videos).to.have.lengthOf(0)
331 it('Should correctly display public videos on server 1', async function () {
332 const { total, data } = await servers[0].videos.list()
333 expect(total).to.equal(5)
335 for (const video of data) {
336 expect(video.name).to.not.contain('1-3')
337 expect(video.name).to.not.contain('2-3')
338 expect(video.name).to.not.contain('video server 3 added after follow updated')
342 it('Should follow user of server 3 again', async function () {
345 await command.add({ token: users[0].accessToken, targetUri: 'user3_channel@localhost:' + servers[2].port })
347 await waitJobs(servers)
350 const body = await command.listVideos({ token: users[0].accessToken, sort: 'createdAt' })
351 expect(body.total).to.equal(3)
353 const videos = body.data
354 expect(videos).to.be.an('array')
355 expect(videos).to.have.lengthOf(3)
357 expect(videos[0].name).to.equal('video 1-3')
358 expect(videos[1].name).to.equal('video 2-3')
359 expect(videos[2].name).to.equal('video server 3 added after follow updated')
363 const { total, data } = await servers[0].videos.list()
364 expect(total).to.equal(5)
366 for (const video of data) {
367 expect(video.name).to.not.contain('1-3')
368 expect(video.name).to.not.contain('2-3')
369 expect(video.name).to.not.contain('video server 3 added after follow updated')
374 it('Should follow user channels of server 3 by root of server 3', async function () {
377 await servers[2].channels.create({ token: users[2].accessToken, attributes: { name: 'user3_channel2' } })
379 await servers[2].subscriptions.add({ token: servers[2].accessToken, targetUri: 'user3_channel@localhost:' + servers[2].port })
380 await servers[2].subscriptions.add({ token: servers[2].accessToken, targetUri: 'user3_channel2@localhost:' + servers[2].port })
382 await waitJobs(servers)
385 it('Should list user 3 followers', async function () {
387 const { total, data } = await servers[2].accounts.listFollowers({
388 token: users[2].accessToken,
389 accountName: 'user3',
395 expect(total).to.equal(3)
396 expect(data).to.have.lengthOf(3)
398 expect(data[0].following.host).to.equal(servers[2].host)
399 expect(data[0].following.name).to.equal('user3_channel')
400 expect(data[0].follower.host).to.equal(servers[0].host)
401 expect(data[0].follower.name).to.equal('user1')
403 expect(data[1].following.host).to.equal(servers[2].host)
404 expect(data[1].following.name).to.equal('user3_channel')
405 expect(data[1].follower.host).to.equal(servers[2].host)
406 expect(data[1].follower.name).to.equal('root')
408 expect(data[2].following.host).to.equal(servers[2].host)
409 expect(data[2].following.name).to.equal('user3_channel2')
410 expect(data[2].follower.host).to.equal(servers[2].host)
411 expect(data[2].follower.name).to.equal('root')
415 const { total, data } = await servers[2].accounts.listFollowers({
416 token: users[2].accessToken,
417 accountName: 'user3',
423 expect(total).to.equal(3)
424 expect(data).to.have.lengthOf(1)
426 expect(data[0].following.host).to.equal(servers[2].host)
427 expect(data[0].following.name).to.equal('user3_channel2')
428 expect(data[0].follower.host).to.equal(servers[2].host)
429 expect(data[0].follower.name).to.equal('root')
433 const { total, data } = await servers[2].accounts.listFollowers({
434 token: users[2].accessToken,
435 accountName: 'user3',
441 expect(total).to.equal(3)
442 expect(data).to.have.lengthOf(1)
444 expect(data[0].following.host).to.equal(servers[2].host)
445 expect(data[0].following.name).to.equal('user3_channel')
446 expect(data[0].follower.host).to.equal(servers[2].host)
447 expect(data[0].follower.name).to.equal('root')
451 const { total, data } = await servers[2].accounts.listFollowers({
452 token: users[2].accessToken,
453 accountName: 'user3',
458 expect(total).to.equal(1)
459 expect(data).to.have.lengthOf(1)
461 expect(data[0].following.host).to.equal(servers[2].host)
462 expect(data[0].following.name).to.equal('user3_channel')
463 expect(data[0].follower.host).to.equal(servers[0].host)
464 expect(data[0].follower.name).to.equal('user1')
468 it('Should list user3_channel followers', async function () {
470 const { total, data } = await servers[2].channels.listFollowers({
471 token: users[2].accessToken,
472 channelName: 'user3_channel',
478 expect(total).to.equal(2)
479 expect(data).to.have.lengthOf(2)
481 expect(data[0].following.host).to.equal(servers[2].host)
482 expect(data[0].following.name).to.equal('user3_channel')
483 expect(data[0].follower.host).to.equal(servers[0].host)
484 expect(data[0].follower.name).to.equal('user1')
486 expect(data[1].following.host).to.equal(servers[2].host)
487 expect(data[1].following.name).to.equal('user3_channel')
488 expect(data[1].follower.host).to.equal(servers[2].host)
489 expect(data[1].follower.name).to.equal('root')
493 const { total, data } = await servers[2].channels.listFollowers({
494 token: users[2].accessToken,
495 channelName: 'user3_channel',
501 expect(total).to.equal(2)
502 expect(data).to.have.lengthOf(1)
504 expect(data[0].following.host).to.equal(servers[2].host)
505 expect(data[0].following.name).to.equal('user3_channel')
506 expect(data[0].follower.host).to.equal(servers[2].host)
507 expect(data[0].follower.name).to.equal('root')
511 const { total, data } = await servers[2].channels.listFollowers({
512 token: users[2].accessToken,
513 channelName: 'user3_channel',
519 expect(total).to.equal(2)
520 expect(data).to.have.lengthOf(1)
522 expect(data[0].following.host).to.equal(servers[2].host)
523 expect(data[0].following.name).to.equal('user3_channel')
524 expect(data[0].follower.host).to.equal(servers[0].host)
525 expect(data[0].follower.name).to.equal('user1')
529 const { total, data } = await servers[2].channels.listFollowers({
530 token: users[2].accessToken,
531 channelName: 'user3_channel',
536 expect(total).to.equal(1)
537 expect(data).to.have.lengthOf(1)
539 expect(data[0].following.host).to.equal(servers[2].host)
540 expect(data[0].following.name).to.equal('user3_channel')
541 expect(data[0].follower.host).to.equal(servers[0].host)
542 expect(data[0].follower.name).to.equal('user1')
546 it('Should update video as internal and not see from remote server', async function () {
549 await servers[2].videos.update({ id: video3UUID, attributes: { name: 'internal', privacy: VideoPrivacy.INTERNAL } })
550 await waitJobs(servers)
553 const { data } = await command.listVideos({ token: users[0].accessToken })
554 expect(data.find(v => v.name === 'internal')).to.not.exist
558 it('Should see internal from local user', async function () {
559 const { data } = await servers[2].subscriptions.listVideos({ token: servers[2].accessToken })
560 expect(data.find(v => v.name === 'internal')).to.exist
563 it('Should update video as private and not see from anyone server', async function () {
566 await servers[2].videos.update({ id: video3UUID, attributes: { name: 'private', privacy: VideoPrivacy.PRIVATE } })
567 await waitJobs(servers)
570 const { data } = await command.listVideos({ token: users[0].accessToken })
571 expect(data.find(v => v.name === 'private')).to.not.exist
575 const { data } = await servers[2].subscriptions.listVideos({ token: servers[2].accessToken })
576 expect(data.find(v => v.name === 'private')).to.not.exist
580 after(async function () {
581 await cleanupTests(servers)