1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
3 import { expect } from 'chai'
4 import { VideoPrivacy } from '@shared/models'
10 setAccessTokensToServers,
11 setDefaultAccountAvatar,
12 setDefaultChannelAvatar,
15 } from '@shared/server-commands'
17 describe('Test users subscriptions', function () {
18 let servers: PeerTubeServer[] = []
19 const users: { accessToken: string }[] = []
20 let video3UUID: string
22 let command: SubscriptionsCommand
24 before(async function () {
27 servers = await createMultipleServers(3)
29 // Get the access tokens
30 await setAccessTokensToServers(servers)
31 await setDefaultChannelAvatar(servers)
32 await setDefaultAccountAvatar(servers)
34 // Server 1 and server 2 follow each other
35 await doubleFollow(servers[0], servers[1])
37 for (const server of servers) {
38 const user = { username: 'user' + server.serverNumber, password: 'password' }
39 await server.users.create({ username: user.username, password: user.password })
41 const accessToken = await server.login.getAccessToken(user)
42 users.push({ accessToken })
44 const videoName1 = 'video 1-' + server.serverNumber
45 await server.videos.upload({ token: accessToken, attributes: { name: videoName1 } })
47 const videoName2 = 'video 2-' + server.serverNumber
48 await server.videos.upload({ token: accessToken, attributes: { name: videoName2 } })
51 await waitJobs(servers)
53 command = servers[0].subscriptions
56 describe('Destinction between server videos and user videos', function () {
57 it('Should display videos of server 2 on server 1', async function () {
58 const { total } = await servers[0].videos.list()
60 expect(total).to.equal(4)
63 it('User of server 1 should follow user of server 3 and root of server 1', async function () {
66 await command.add({ token: users[0].accessToken, targetUri: 'user3_channel@' + servers[2].host })
67 await command.add({ token: users[0].accessToken, targetUri: 'root_channel@' + servers[0].host })
69 await waitJobs(servers)
71 const attributes = { name: 'video server 3 added after follow' }
72 const { uuid } = await servers[2].videos.upload({ token: users[2].accessToken, attributes })
75 await waitJobs(servers)
78 it('Should not display videos of server 3 on server 1', async function () {
79 const { total, data } = await servers[0].videos.list()
80 expect(total).to.equal(4)
82 for (const video of data) {
83 expect(video.name).to.not.contain('1-3')
84 expect(video.name).to.not.contain('2-3')
85 expect(video.name).to.not.contain('video server 3 added after follow')
90 describe('Subscription endpoints', function () {
92 it('Should list subscriptions', async function () {
94 const body = await command.list()
95 expect(body.total).to.equal(0)
96 expect(body.data).to.be.an('array')
97 expect(body.data).to.have.lengthOf(0)
101 const body = await command.list({ token: users[0].accessToken, sort: 'createdAt' })
102 expect(body.total).to.equal(2)
104 const subscriptions = body.data
105 expect(subscriptions).to.be.an('array')
106 expect(subscriptions).to.have.lengthOf(2)
108 expect(subscriptions[0].name).to.equal('user3_channel')
109 expect(subscriptions[1].name).to.equal('root_channel')
113 it('Should get subscription', async function () {
115 const videoChannel = await command.get({ token: users[0].accessToken, uri: 'user3_channel@' + servers[2].host })
117 expect(videoChannel.name).to.equal('user3_channel')
118 expect(videoChannel.host).to.equal(servers[2].host)
119 expect(videoChannel.displayName).to.equal('Main user3 channel')
120 expect(videoChannel.followingCount).to.equal(0)
121 expect(videoChannel.followersCount).to.equal(1)
125 const videoChannel = await command.get({ token: users[0].accessToken, uri: 'root_channel@' + servers[0].host })
127 expect(videoChannel.name).to.equal('root_channel')
128 expect(videoChannel.host).to.equal(servers[0].host)
129 expect(videoChannel.displayName).to.equal('Main root channel')
130 expect(videoChannel.followingCount).to.equal(0)
131 expect(videoChannel.followersCount).to.equal(1)
135 it('Should return the existing subscriptions', async function () {
137 'user3_channel@' + servers[2].host,
138 'root2_channel@' + servers[0].host,
139 'root_channel@' + servers[0].host,
140 'user3_channel@' + servers[0].host
143 const body = await command.exist({ token: users[0].accessToken, uris })
145 expect(body['user3_channel@' + servers[2].host]).to.be.true
146 expect(body['root2_channel@' + servers[0].host]).to.be.false
147 expect(body['root_channel@' + servers[0].host]).to.be.true
148 expect(body['user3_channel@' + servers[0].host]).to.be.false
151 it('Should search among subscriptions', async function () {
153 const body = await command.list({ token: users[0].accessToken, sort: '-createdAt', search: 'user3_channel' })
154 expect(body.total).to.equal(1)
155 expect(body.data).to.have.lengthOf(1)
159 const body = await command.list({ token: users[0].accessToken, sort: '-createdAt', search: 'toto' })
160 expect(body.total).to.equal(0)
161 expect(body.data).to.have.lengthOf(0)
166 describe('Subscription videos', function () {
168 it('Should list subscription videos', async function () {
170 const body = await servers[0].videos.listMySubscriptionVideos()
171 expect(body.total).to.equal(0)
172 expect(body.data).to.be.an('array')
173 expect(body.data).to.have.lengthOf(0)
177 const body = await servers[0].videos.listMySubscriptionVideos({ token: users[0].accessToken, sort: 'createdAt' })
178 expect(body.total).to.equal(3)
180 const videos = body.data
181 expect(videos).to.be.an('array')
182 expect(videos).to.have.lengthOf(3)
184 expect(videos[0].name).to.equal('video 1-3')
185 expect(videos[1].name).to.equal('video 2-3')
186 expect(videos[2].name).to.equal('video server 3 added after follow')
190 const body = await servers[0].videos.listMySubscriptionVideos({ token: users[0].accessToken, count: 1, start: 1 })
191 expect(body.total).to.equal(3)
193 const videos = body.data
194 expect(videos).to.be.an('array')
195 expect(videos).to.have.lengthOf(1)
197 expect(videos[0].name).to.equal('video 2-3')
201 it('Should upload a video by root on server 1 and see it in the subscription videos', async function () {
204 const videoName = 'video server 1 added after follow'
205 await servers[0].videos.upload({ attributes: { name: videoName } })
207 await waitJobs(servers)
210 const body = await servers[0].videos.listMySubscriptionVideos()
211 expect(body.total).to.equal(0)
212 expect(body.data).to.be.an('array')
213 expect(body.data).to.have.lengthOf(0)
217 const body = await servers[0].videos.listMySubscriptionVideos({ token: users[0].accessToken, sort: 'createdAt' })
218 expect(body.total).to.equal(4)
220 const videos = body.data
221 expect(videos).to.be.an('array')
222 expect(videos).to.have.lengthOf(4)
224 expect(videos[0].name).to.equal('video 1-3')
225 expect(videos[1].name).to.equal('video 2-3')
226 expect(videos[2].name).to.equal('video server 3 added after follow')
227 expect(videos[3].name).to.equal('video server 1 added after follow')
231 const { data, total } = await servers[0].videos.list()
232 expect(total).to.equal(5)
234 for (const video of data) {
235 expect(video.name).to.not.contain('1-3')
236 expect(video.name).to.not.contain('2-3')
237 expect(video.name).to.not.contain('video server 3 added after follow')
242 it('Should have server 1 following server 3 and display server 3 videos', async function () {
245 await servers[0].follows.follow({ hosts: [ servers[2].url ] })
247 await waitJobs(servers)
249 const { data, total } = await servers[0].videos.list()
250 expect(total).to.equal(8)
252 const names = [ '1-3', '2-3', 'video server 3 added after follow' ]
253 for (const name of names) {
254 const video = data.find(v => v.name.includes(name))
255 expect(video).to.not.be.undefined
259 it('Should remove follow server 1 -> server 3 and hide server 3 videos', async function () {
262 await servers[0].follows.unfollow({ target: servers[2] })
264 await waitJobs(servers)
266 const { total, data } = await servers[0].videos.list()
267 expect(total).to.equal(5)
269 for (const video of data) {
270 expect(video.name).to.not.contain('1-3')
271 expect(video.name).to.not.contain('2-3')
272 expect(video.name).to.not.contain('video server 3 added after follow')
276 it('Should still list subscription videos', async function () {
278 const body = await servers[0].videos.listMySubscriptionVideos()
279 expect(body.total).to.equal(0)
280 expect(body.data).to.be.an('array')
281 expect(body.data).to.have.lengthOf(0)
285 const body = await servers[0].videos.listMySubscriptionVideos({ token: users[0].accessToken, sort: 'createdAt' })
286 expect(body.total).to.equal(4)
288 const videos = body.data
289 expect(videos).to.be.an('array')
290 expect(videos).to.have.lengthOf(4)
292 expect(videos[0].name).to.equal('video 1-3')
293 expect(videos[1].name).to.equal('video 2-3')
294 expect(videos[2].name).to.equal('video server 3 added after follow')
295 expect(videos[3].name).to.equal('video server 1 added after follow')
300 describe('Existing subscription video update', function () {
302 it('Should update a video of server 3 and see the updated video on server 1', async function () {
305 await servers[2].videos.update({ id: video3UUID, attributes: { name: 'video server 3 added after follow updated' } })
307 await waitJobs(servers)
309 const body = await servers[0].videos.listMySubscriptionVideos({ token: users[0].accessToken, sort: 'createdAt' })
310 expect(body.data[2].name).to.equal('video server 3 added after follow updated')
314 describe('Subscription removal', function () {
316 it('Should remove user of server 3 subscription', async function () {
319 await command.remove({ token: users[0].accessToken, uri: 'user3_channel@' + servers[2].host })
321 await waitJobs(servers)
324 it('Should not display its videos anymore', async function () {
325 const body = await servers[0].videos.listMySubscriptionVideos({ token: users[0].accessToken, sort: 'createdAt' })
326 expect(body.total).to.equal(1)
328 const videos = body.data
329 expect(videos).to.be.an('array')
330 expect(videos).to.have.lengthOf(1)
332 expect(videos[0].name).to.equal('video server 1 added after follow')
335 it('Should remove the root subscription and not display the videos anymore', async function () {
338 await command.remove({ token: users[0].accessToken, uri: 'root_channel@' + servers[0].host })
340 await waitJobs(servers)
343 const body = await command.list({ token: users[0].accessToken, sort: 'createdAt' })
344 expect(body.total).to.equal(0)
346 const videos = body.data
347 expect(videos).to.be.an('array')
348 expect(videos).to.have.lengthOf(0)
352 it('Should correctly display public videos on server 1', async function () {
353 const { total, data } = await servers[0].videos.list()
354 expect(total).to.equal(5)
356 for (const video of data) {
357 expect(video.name).to.not.contain('1-3')
358 expect(video.name).to.not.contain('2-3')
359 expect(video.name).to.not.contain('video server 3 added after follow updated')
364 describe('Re-follow', function () {
366 it('Should follow user of server 3 again', async function () {
369 await command.add({ token: users[0].accessToken, targetUri: 'user3_channel@' + servers[2].host })
371 await waitJobs(servers)
374 const body = await servers[0].videos.listMySubscriptionVideos({ token: users[0].accessToken, sort: 'createdAt' })
375 expect(body.total).to.equal(3)
377 const videos = body.data
378 expect(videos).to.be.an('array')
379 expect(videos).to.have.lengthOf(3)
381 expect(videos[0].name).to.equal('video 1-3')
382 expect(videos[1].name).to.equal('video 2-3')
383 expect(videos[2].name).to.equal('video server 3 added after follow updated')
387 const { total, data } = await servers[0].videos.list()
388 expect(total).to.equal(5)
390 for (const video of data) {
391 expect(video.name).to.not.contain('1-3')
392 expect(video.name).to.not.contain('2-3')
393 expect(video.name).to.not.contain('video server 3 added after follow updated')
398 it('Should follow user channels of server 3 by root of server 3', async function () {
401 await servers[2].channels.create({ token: users[2].accessToken, attributes: { name: 'user3_channel2' } })
403 await servers[2].subscriptions.add({ token: servers[2].accessToken, targetUri: 'user3_channel@' + servers[2].host })
404 await servers[2].subscriptions.add({ token: servers[2].accessToken, targetUri: 'user3_channel2@' + servers[2].host })
406 await waitJobs(servers)
410 describe('Followers listing', function () {
412 it('Should list user 3 followers', async function () {
414 const { total, data } = await servers[2].accounts.listFollowers({
415 token: users[2].accessToken,
416 accountName: 'user3',
422 expect(total).to.equal(3)
423 expect(data).to.have.lengthOf(3)
425 expect(data[0].following.host).to.equal(servers[2].host)
426 expect(data[0].following.name).to.equal('user3_channel')
427 expect(data[0].follower.host).to.equal(servers[0].host)
428 expect(data[0].follower.name).to.equal('user1')
430 expect(data[1].following.host).to.equal(servers[2].host)
431 expect(data[1].following.name).to.equal('user3_channel')
432 expect(data[1].follower.host).to.equal(servers[2].host)
433 expect(data[1].follower.name).to.equal('root')
435 expect(data[2].following.host).to.equal(servers[2].host)
436 expect(data[2].following.name).to.equal('user3_channel2')
437 expect(data[2].follower.host).to.equal(servers[2].host)
438 expect(data[2].follower.name).to.equal('root')
442 const { total, data } = await servers[2].accounts.listFollowers({
443 token: users[2].accessToken,
444 accountName: 'user3',
450 expect(total).to.equal(3)
451 expect(data).to.have.lengthOf(1)
453 expect(data[0].following.host).to.equal(servers[2].host)
454 expect(data[0].following.name).to.equal('user3_channel2')
455 expect(data[0].follower.host).to.equal(servers[2].host)
456 expect(data[0].follower.name).to.equal('root')
460 const { total, data } = await servers[2].accounts.listFollowers({
461 token: users[2].accessToken,
462 accountName: 'user3',
468 expect(total).to.equal(3)
469 expect(data).to.have.lengthOf(1)
471 expect(data[0].following.host).to.equal(servers[2].host)
472 expect(data[0].following.name).to.equal('user3_channel')
473 expect(data[0].follower.host).to.equal(servers[2].host)
474 expect(data[0].follower.name).to.equal('root')
478 const { total, data } = await servers[2].accounts.listFollowers({
479 token: users[2].accessToken,
480 accountName: 'user3',
485 expect(total).to.equal(1)
486 expect(data).to.have.lengthOf(1)
488 expect(data[0].following.host).to.equal(servers[2].host)
489 expect(data[0].following.name).to.equal('user3_channel')
490 expect(data[0].follower.host).to.equal(servers[0].host)
491 expect(data[0].follower.name).to.equal('user1')
495 it('Should list user3_channel followers', async function () {
497 const { total, data } = await servers[2].channels.listFollowers({
498 token: users[2].accessToken,
499 channelName: 'user3_channel',
505 expect(total).to.equal(2)
506 expect(data).to.have.lengthOf(2)
508 expect(data[0].following.host).to.equal(servers[2].host)
509 expect(data[0].following.name).to.equal('user3_channel')
510 expect(data[0].follower.host).to.equal(servers[0].host)
511 expect(data[0].follower.name).to.equal('user1')
513 expect(data[1].following.host).to.equal(servers[2].host)
514 expect(data[1].following.name).to.equal('user3_channel')
515 expect(data[1].follower.host).to.equal(servers[2].host)
516 expect(data[1].follower.name).to.equal('root')
520 const { total, data } = await servers[2].channels.listFollowers({
521 token: users[2].accessToken,
522 channelName: 'user3_channel',
528 expect(total).to.equal(2)
529 expect(data).to.have.lengthOf(1)
531 expect(data[0].following.host).to.equal(servers[2].host)
532 expect(data[0].following.name).to.equal('user3_channel')
533 expect(data[0].follower.host).to.equal(servers[2].host)
534 expect(data[0].follower.name).to.equal('root')
538 const { total, data } = await servers[2].channels.listFollowers({
539 token: users[2].accessToken,
540 channelName: 'user3_channel',
546 expect(total).to.equal(2)
547 expect(data).to.have.lengthOf(1)
549 expect(data[0].following.host).to.equal(servers[2].host)
550 expect(data[0].following.name).to.equal('user3_channel')
551 expect(data[0].follower.host).to.equal(servers[0].host)
552 expect(data[0].follower.name).to.equal('user1')
556 const { total, data } = await servers[2].channels.listFollowers({
557 token: users[2].accessToken,
558 channelName: 'user3_channel',
563 expect(total).to.equal(1)
564 expect(data).to.have.lengthOf(1)
566 expect(data[0].following.host).to.equal(servers[2].host)
567 expect(data[0].following.name).to.equal('user3_channel')
568 expect(data[0].follower.host).to.equal(servers[0].host)
569 expect(data[0].follower.name).to.equal('user1')
574 describe('Subscription videos privacy', function () {
576 it('Should update video as internal and not see from remote server', async function () {
579 await servers[2].videos.update({ id: video3UUID, attributes: { name: 'internal', privacy: VideoPrivacy.INTERNAL } })
580 await waitJobs(servers)
583 const { data } = await servers[0].videos.listMySubscriptionVideos({ token: users[0].accessToken })
584 expect(data.find(v => v.name === 'internal')).to.not.exist
588 it('Should see internal from local user', async function () {
589 const { data } = await servers[2].videos.listMySubscriptionVideos({ token: servers[2].accessToken })
590 expect(data.find(v => v.name === 'internal')).to.exist
593 it('Should update video as private and not see from anyone server', async function () {
596 await servers[2].videos.update({ id: video3UUID, attributes: { name: 'private', privacy: VideoPrivacy.PRIVATE } })
597 await waitJobs(servers)
600 const { data } = await servers[0].videos.listMySubscriptionVideos({ token: users[0].accessToken })
601 expect(data.find(v => v.name === 'private')).to.not.exist
605 const { data } = await servers[2].videos.listMySubscriptionVideos({ token: servers[2].accessToken })
606 expect(data.find(v => v.name === 'private')).to.not.exist
611 after(async function () {
612 await cleanupTests(servers)