]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/users/user-subscriptions.ts
Fix lint
[github/Chocobozzz/PeerTube.git] / server / tests / api / users / user-subscriptions.ts
CommitLineData
a1587156 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
06a05d5f 2
06a05d5f 3import 'mocha'
c3d29f69 4import * as chai from 'chai'
6def7d34 5import { VideoPrivacy } from '@shared/models'
9639bd17 6import {
7c3b7976 7 cleanupTests,
254d3579 8 createMultipleServers,
4c7e60bc 9 doubleFollow,
254d3579 10 PeerTubeServer,
c3d29f69 11 setAccessTokensToServers,
d0800f76 12 setDefaultAccountAvatar,
13 setDefaultChannelAvatar,
2c27e704 14 SubscriptionsCommand,
c3d29f69 15 waitJobs
bf54587a 16} from '@shared/server-commands'
06a05d5f
C
17
18const expect = chai.expect
19
20describe('Test users subscriptions', function () {
254d3579 21 let servers: PeerTubeServer[] = []
8a19bee1 22 const users: { accessToken: string }[] = []
f6eebcb3 23 let video3UUID: string
06a05d5f 24
2c27e704
C
25 let command: SubscriptionsCommand
26
06a05d5f 27 before(async function () {
87c0f718 28 this.timeout(240000)
06a05d5f 29
254d3579 30 servers = await createMultipleServers(3)
06a05d5f
C
31
32 // Get the access tokens
33 await setAccessTokensToServers(servers)
d0800f76 34 await setDefaultChannelAvatar(servers)
35 await setDefaultAccountAvatar(servers)
06a05d5f
C
36
37 // Server 1 and server 2 follow each other
38 await doubleFollow(servers[0], servers[1])
39
6def7d34
C
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 })
06a05d5f 43
6def7d34
C
44 const accessToken = await server.login.getAccessToken(user)
45 users.push({ accessToken })
06a05d5f 46
6def7d34
C
47 const videoName1 = 'video 1-' + server.serverNumber
48 await server.videos.upload({ token: accessToken, attributes: { name: videoName1 } })
06a05d5f 49
6def7d34
C
50 const videoName2 = 'video 2-' + server.serverNumber
51 await server.videos.upload({ token: accessToken, attributes: { name: videoName2 } })
06a05d5f
C
52 }
53
54 await waitJobs(servers)
2c27e704 55
89d241a7 56 command = servers[0].subscriptions
06a05d5f
C
57 })
58
59 it('Should display videos of server 2 on server 1', async function () {
89d241a7 60 const { total } = await servers[0].videos.list()
06a05d5f 61
d23dd9fb 62 expect(total).to.equal(4)
06a05d5f
C
63 })
64
65 it('User of server 1 should follow user of server 3 and root of server 1', async function () {
8a19bee1 66 this.timeout(60000)
06a05d5f 67
2c27e704
C
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 })
06a05d5f
C
70
71 await waitJobs(servers)
72
4c7e60bc
C
73 const attributes = { name: 'video server 3 added after follow' }
74 const { uuid } = await servers[2].videos.upload({ token: users[2].accessToken, attributes })
d23dd9fb 75 video3UUID = uuid
06a05d5f
C
76
77 await waitJobs(servers)
78 })
79
80 it('Should not display videos of server 3 on server 1', async function () {
89d241a7 81 const { total, data } = await servers[0].videos.list()
d23dd9fb 82 expect(total).to.equal(4)
06a05d5f 83
d23dd9fb 84 for (const video of data) {
06a05d5f
C
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')
88 }
89 })
90
91 it('Should list subscriptions', async function () {
92 {
2c27e704
C
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)
06a05d5f
C
97 }
98
99 {
2c27e704
C
100 const body = await command.list({ token: users[0].accessToken, sort: 'createdAt' })
101 expect(body.total).to.equal(2)
06a05d5f 102
2c27e704 103 const subscriptions = body.data
06a05d5f
C
104 expect(subscriptions).to.be.an('array')
105 expect(subscriptions).to.have.lengthOf(2)
106
8a19bee1
C
107 expect(subscriptions[0].name).to.equal('user3_channel')
108 expect(subscriptions[1].name).to.equal('root_channel')
06a05d5f
C
109 }
110 })
111
99492dbc
C
112 it('Should get subscription', async function () {
113 {
2c27e704 114 const videoChannel = await command.get({ token: users[0].accessToken, uri: 'user3_channel@localhost:' + servers[2].port })
99492dbc
C
115
116 expect(videoChannel.name).to.equal('user3_channel')
48f07b4a 117 expect(videoChannel.host).to.equal('localhost:' + servers[2].port)
99492dbc
C
118 expect(videoChannel.displayName).to.equal('Main user3 channel')
119 expect(videoChannel.followingCount).to.equal(0)
120 expect(videoChannel.followersCount).to.equal(1)
121 }
122
123 {
2c27e704 124 const videoChannel = await command.get({ token: users[0].accessToken, uri: 'root_channel@localhost:' + servers[0].port })
99492dbc
C
125
126 expect(videoChannel.name).to.equal('root_channel')
48f07b4a 127 expect(videoChannel.host).to.equal('localhost:' + servers[0].port)
99492dbc
C
128 expect(videoChannel.displayName).to.equal('Main root channel')
129 expect(videoChannel.followingCount).to.equal(0)
130 expect(videoChannel.followersCount).to.equal(1)
131 }
132 })
133
f37dc0dd
C
134 it('Should return the existing subscriptions', async function () {
135 const uris = [
48f07b4a
C
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
f37dc0dd
C
140 ]
141
2c27e704 142 const body = await command.exist({ token: users[0].accessToken, uris })
f37dc0dd 143
48f07b4a
C
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
f37dc0dd
C
148 })
149
7b390964
RK
150 it('Should search among subscriptions', async function () {
151 {
2c27e704
C
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)
7b390964
RK
155 }
156
157 {
2c27e704
C
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)
7b390964
RK
161 }
162 })
163
06a05d5f
C
164 it('Should list subscription videos', async function () {
165 {
2c27e704
C
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)
06a05d5f
C
170 }
171
172 {
2c27e704
C
173 const body = await command.listVideos({ token: users[0].accessToken, sort: 'createdAt' })
174 expect(body.total).to.equal(3)
06a05d5f 175
2c27e704 176 const videos = body.data
06a05d5f
C
177 expect(videos).to.be.an('array')
178 expect(videos).to.have.lengthOf(3)
179
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')
183 }
184 })
185
186 it('Should upload a video by root on server 1 and see it in the subscription videos', async function () {
8a19bee1 187 this.timeout(60000)
06a05d5f
C
188
189 const videoName = 'video server 1 added after follow'
89d241a7 190 await servers[0].videos.upload({ attributes: { name: videoName } })
06a05d5f
C
191
192 await waitJobs(servers)
193
194 {
2c27e704
C
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)
06a05d5f
C
199 }
200
201 {
2c27e704
C
202 const body = await command.listVideos({ token: users[0].accessToken, sort: 'createdAt' })
203 expect(body.total).to.equal(4)
06a05d5f 204
2c27e704 205 const videos = body.data
06a05d5f
C
206 expect(videos).to.be.an('array')
207 expect(videos).to.have.lengthOf(4)
208
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')
213 }
214
215 {
89d241a7 216 const { data, total } = await servers[0].videos.list()
d23dd9fb 217 expect(total).to.equal(5)
06a05d5f 218
d23dd9fb 219 for (const video of data) {
06a05d5f
C
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')
223 }
224 }
225 })
226
227 it('Should have server 1 follow server 3 and display server 3 videos', async function () {
8a19bee1 228 this.timeout(60000)
06a05d5f 229
4d029ef8 230 await servers[0].follows.follow({ hosts: [ servers[2].url ] })
06a05d5f
C
231
232 await waitJobs(servers)
233
89d241a7 234 const { data, total } = await servers[0].videos.list()
d23dd9fb 235 expect(total).to.equal(8)
06a05d5f
C
236
237 const names = [ '1-3', '2-3', 'video server 3 added after follow' ]
238 for (const name of names) {
d23dd9fb 239 const video = data.find(v => v.name.includes(name))
06a05d5f
C
240 expect(video).to.not.be.undefined
241 }
242 })
243
244 it('Should remove follow server 1 -> server 3 and hide server 3 videos', async function () {
8a19bee1 245 this.timeout(60000)
06a05d5f 246
89d241a7 247 await servers[0].follows.unfollow({ target: servers[2] })
06a05d5f
C
248
249 await waitJobs(servers)
250
89d241a7 251 const { total, data } = await servers[0].videos.list()
d23dd9fb 252 expect(total).to.equal(5)
06a05d5f 253
d23dd9fb 254 for (const video of data) {
06a05d5f
C
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')
258 }
259 })
260
261 it('Should still list subscription videos', async function () {
262 {
2c27e704
C
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)
06a05d5f
C
267 }
268
269 {
2c27e704
C
270 const body = await command.listVideos({ token: users[0].accessToken, sort: 'createdAt' })
271 expect(body.total).to.equal(4)
06a05d5f 272
2c27e704 273 const videos = body.data
06a05d5f
C
274 expect(videos).to.be.an('array')
275 expect(videos).to.have.lengthOf(4)
276
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')
281 }
282 })
283
f6eebcb3
C
284 it('Should update a video of server 3 and see the updated video on server 1', async function () {
285 this.timeout(30000)
286
89d241a7 287 await servers[2].videos.update({ id: video3UUID, attributes: { name: 'video server 3 added after follow updated' } })
f6eebcb3
C
288
289 await waitJobs(servers)
290
2c27e704
C
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')
f6eebcb3
C
293 })
294
06a05d5f 295 it('Should remove user of server 3 subscription', async function () {
f6eebcb3
C
296 this.timeout(30000)
297
2c27e704 298 await command.remove({ token: users[0].accessToken, uri: 'user3_channel@localhost:' + servers[2].port })
06a05d5f
C
299
300 await waitJobs(servers)
301 })
302
303 it('Should not display its videos anymore', async function () {
2c27e704
C
304 const body = await command.listVideos({ token: users[0].accessToken, sort: 'createdAt' })
305 expect(body.total).to.equal(1)
06a05d5f 306
2c27e704
C
307 const videos = body.data
308 expect(videos).to.be.an('array')
309 expect(videos).to.have.lengthOf(1)
06a05d5f 310
2c27e704 311 expect(videos[0].name).to.equal('video server 1 added after follow')
06a05d5f
C
312 })
313
314 it('Should remove the root subscription and not display the videos anymore', async function () {
f6eebcb3
C
315 this.timeout(30000)
316
2c27e704 317 await command.remove({ token: users[0].accessToken, uri: 'root_channel@localhost:' + servers[0].port })
06a05d5f
C
318
319 await waitJobs(servers)
320
321 {
2c27e704
C
322 const body = await command.list({ token: users[0].accessToken, sort: 'createdAt' })
323 expect(body.total).to.equal(0)
06a05d5f 324
2c27e704 325 const videos = body.data
06a05d5f
C
326 expect(videos).to.be.an('array')
327 expect(videos).to.have.lengthOf(0)
328 }
329 })
330
331 it('Should correctly display public videos on server 1', async function () {
89d241a7 332 const { total, data } = await servers[0].videos.list()
d23dd9fb 333 expect(total).to.equal(5)
06a05d5f 334
d23dd9fb 335 for (const video of data) {
06a05d5f
C
336 expect(video.name).to.not.contain('1-3')
337 expect(video.name).to.not.contain('2-3')
f6eebcb3 338 expect(video.name).to.not.contain('video server 3 added after follow updated')
06a05d5f
C
339 }
340 })
341
342 it('Should follow user of server 3 again', async function () {
8a19bee1 343 this.timeout(60000)
06a05d5f 344
2c27e704 345 await command.add({ token: users[0].accessToken, targetUri: 'user3_channel@localhost:' + servers[2].port })
06a05d5f
C
346
347 await waitJobs(servers)
348
349 {
2c27e704
C
350 const body = await command.listVideos({ token: users[0].accessToken, sort: 'createdAt' })
351 expect(body.total).to.equal(3)
06a05d5f 352
2c27e704 353 const videos = body.data
06a05d5f
C
354 expect(videos).to.be.an('array')
355 expect(videos).to.have.lengthOf(3)
356
357 expect(videos[0].name).to.equal('video 1-3')
358 expect(videos[1].name).to.equal('video 2-3')
f6eebcb3 359 expect(videos[2].name).to.equal('video server 3 added after follow updated')
06a05d5f
C
360 }
361
362 {
89d241a7 363 const { total, data } = await servers[0].videos.list()
d23dd9fb 364 expect(total).to.equal(5)
06a05d5f 365
d23dd9fb 366 for (const video of data) {
06a05d5f
C
367 expect(video.name).to.not.contain('1-3')
368 expect(video.name).to.not.contain('2-3')
f6eebcb3 369 expect(video.name).to.not.contain('video server 3 added after follow updated')
06a05d5f
C
370 }
371 }
372 })
373
4beda9e1
C
374 it('Should follow user channels of server 3 by root of server 3', async function () {
375 this.timeout(60000)
376
377 await servers[2].channels.create({ token: users[2].accessToken, attributes: { name: 'user3_channel2' } })
378
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 })
381
382 await waitJobs(servers)
383 })
384
385 it('Should list user 3 followers', async function () {
386 {
387 const { total, data } = await servers[2].accounts.listFollowers({
388 token: users[2].accessToken,
389 accountName: 'user3',
390 start: 0,
391 count: 5,
392 sort: 'createdAt'
393 })
394
395 expect(total).to.equal(3)
906f46d0
C
396 expect(data).to.have.lengthOf(3)
397
4beda9e1
C
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')
402
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')
407
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')
412 }
413
414 {
415 const { total, data } = await servers[2].accounts.listFollowers({
416 token: users[2].accessToken,
417 accountName: 'user3',
418 start: 0,
419 count: 1,
420 sort: '-createdAt'
421 })
422
423 expect(total).to.equal(3)
906f46d0
C
424 expect(data).to.have.lengthOf(1)
425
4beda9e1
C
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')
430 }
431
432 {
433 const { total, data } = await servers[2].accounts.listFollowers({
434 token: users[2].accessToken,
435 accountName: 'user3',
436 start: 1,
437 count: 1,
438 sort: '-createdAt'
439 })
440
441 expect(total).to.equal(3)
906f46d0
C
442 expect(data).to.have.lengthOf(1)
443
4beda9e1
C
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')
448 }
449
450 {
451 const { total, data } = await servers[2].accounts.listFollowers({
452 token: users[2].accessToken,
453 accountName: 'user3',
454 search: 'user1',
455 sort: '-createdAt'
456 })
457
458 expect(total).to.equal(1)
906f46d0
C
459 expect(data).to.have.lengthOf(1)
460
4beda9e1
C
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')
465 }
466 })
467
468 it('Should list user3_channel followers', async function () {
469 {
470 const { total, data } = await servers[2].channels.listFollowers({
471 token: users[2].accessToken,
472 channelName: 'user3_channel',
473 start: 0,
474 count: 5,
475 sort: 'createdAt'
476 })
477
478 expect(total).to.equal(2)
906f46d0
C
479 expect(data).to.have.lengthOf(2)
480
4beda9e1
C
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')
485
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')
490 }
491
492 {
493 const { total, data } = await servers[2].channels.listFollowers({
494 token: users[2].accessToken,
495 channelName: 'user3_channel',
496 start: 0,
497 count: 1,
498 sort: '-createdAt'
499 })
500
501 expect(total).to.equal(2)
906f46d0
C
502 expect(data).to.have.lengthOf(1)
503
4beda9e1
C
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')
508 }
509
510 {
511 const { total, data } = await servers[2].channels.listFollowers({
512 token: users[2].accessToken,
513 channelName: 'user3_channel',
514 start: 1,
515 count: 1,
516 sort: '-createdAt'
517 })
518
519 expect(total).to.equal(2)
906f46d0
C
520 expect(data).to.have.lengthOf(1)
521
4beda9e1
C
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)
906f46d0 525 expect(data[0].follower.name).to.equal('user1')
4beda9e1
C
526 }
527
528 {
529 const { total, data } = await servers[2].channels.listFollowers({
530 token: users[2].accessToken,
531 channelName: 'user3_channel',
532 search: 'user1',
533 sort: '-createdAt'
534 })
535
536 expect(total).to.equal(1)
906f46d0
C
537 expect(data).to.have.lengthOf(1)
538
4beda9e1
C
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')
543 }
544 })
545
6def7d34
C
546 it('Should update video as internal and not see from remote server', async function () {
547 this.timeout(30000)
548
549 await servers[2].videos.update({ id: video3UUID, attributes: { name: 'internal', privacy: VideoPrivacy.INTERNAL } })
550 await waitJobs(servers)
551
552 {
553 const { data } = await command.listVideos({ token: users[0].accessToken })
554 expect(data.find(v => v.name === 'internal')).to.not.exist
555 }
556 })
557
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
561 })
562
563 it('Should update video as private and not see from anyone server', async function () {
564 this.timeout(30000)
565
566 await servers[2].videos.update({ id: video3UUID, attributes: { name: 'private', privacy: VideoPrivacy.PRIVATE } })
567 await waitJobs(servers)
568
569 {
570 const { data } = await command.listVideos({ token: users[0].accessToken })
571 expect(data.find(v => v.name === 'private')).to.not.exist
572 }
573
574 {
575 const { data } = await servers[2].subscriptions.listVideos({ token: servers[2].accessToken })
576 expect(data.find(v => v.name === 'private')).to.not.exist
577 }
578 })
579
7c3b7976
C
580 after(async function () {
581 await cleanupTests(servers)
06a05d5f
C
582 })
583})