add quarantine videos feature (#1637)
[oweals/peertube.git] / server / tests / api / users / user-subscriptions.ts
1 /* tslint:disable:no-unused-expression */
2
3 import * as chai from 'chai'
4 import 'mocha'
5 import {
6   createUser,
7   doubleFollow,
8   flushAndRunMultipleServers,
9   follow,
10   getVideosList,
11   unfollow,
12   updateVideo,
13   userLogin
14 } from '../../../../shared/utils'
15 import { killallServers, ServerInfo, uploadVideo } from '../../../../shared/utils/index'
16 import { setAccessTokensToServers } from '../../../../shared/utils/users/login'
17 import { Video, VideoChannel } from '../../../../shared/models/videos'
18 import { waitJobs } from '../../../../shared/utils/server/jobs'
19 import {
20   addUserSubscription,
21   listUserSubscriptions,
22   listUserSubscriptionVideos,
23   removeUserSubscription,
24   getUserSubscription, areSubscriptionsExist
25 } from '../../../../shared/utils/users/user-subscriptions'
26
27 const expect = chai.expect
28
29 describe('Test users subscriptions', function () {
30   let servers: ServerInfo[] = []
31   const users: { accessToken: string }[] = []
32   let video3UUID: string
33
34   before(async function () {
35     this.timeout(120000)
36
37     servers = await flushAndRunMultipleServers(3)
38
39     // Get the access tokens
40     await setAccessTokensToServers(servers)
41
42     // Server 1 and server 2 follow each other
43     await doubleFollow(servers[0], servers[1])
44
45     {
46       for (const server of servers) {
47         const user = { username: 'user' + server.serverNumber, password: 'password' }
48         await createUser(server.url, server.accessToken, user.username, user.password)
49
50         const accessToken = await userLogin(server, user)
51         users.push({ accessToken })
52
53         const videoName1 = 'video 1-' + server.serverNumber
54         await uploadVideo(server.url, accessToken, { name: videoName1 })
55
56         const videoName2 = 'video 2-' + server.serverNumber
57         await uploadVideo(server.url, accessToken, { name: videoName2 })
58       }
59     }
60
61     await waitJobs(servers)
62   })
63
64   it('Should display videos of server 2 on server 1', async function () {
65     const res = await getVideosList(servers[0].url)
66
67     expect(res.body.total).to.equal(4)
68   })
69
70   it('User of server 1 should follow user of server 3 and root of server 1', async function () {
71     this.timeout(60000)
72
73     await addUserSubscription(servers[0].url, users[0].accessToken, 'user3_channel@localhost:9003')
74     await addUserSubscription(servers[0].url, users[0].accessToken, 'root_channel@localhost:9001')
75
76     await waitJobs(servers)
77
78     const res = await uploadVideo(servers[2].url, users[2].accessToken, { name: 'video server 3 added after follow' })
79     video3UUID = res.body.video.uuid
80
81     await waitJobs(servers)
82   })
83
84   it('Should not display videos of server 3 on server 1', async function () {
85     const res = await getVideosList(servers[0].url)
86
87     expect(res.body.total).to.equal(4)
88     for (const video of res.body.data) {
89       expect(video.name).to.not.contain('1-3')
90       expect(video.name).to.not.contain('2-3')
91       expect(video.name).to.not.contain('video server 3 added after follow')
92     }
93   })
94
95   it('Should list subscriptions', async function () {
96     {
97       const res = await listUserSubscriptions(servers[0].url, servers[0].accessToken)
98       expect(res.body.total).to.equal(0)
99       expect(res.body.data).to.be.an('array')
100       expect(res.body.data).to.have.lengthOf(0)
101     }
102
103     {
104       const res = await listUserSubscriptions(servers[0].url, users[0].accessToken)
105       expect(res.body.total).to.equal(2)
106
107       const subscriptions: VideoChannel[] = res.body.data
108       expect(subscriptions).to.be.an('array')
109       expect(subscriptions).to.have.lengthOf(2)
110
111       expect(subscriptions[0].name).to.equal('user3_channel')
112       expect(subscriptions[1].name).to.equal('root_channel')
113     }
114   })
115
116   it('Should get subscription', async function () {
117     {
118       const res = await getUserSubscription(servers[ 0 ].url, users[ 0 ].accessToken, 'user3_channel@localhost:9003')
119       const videoChannel: VideoChannel = res.body
120
121       expect(videoChannel.name).to.equal('user3_channel')
122       expect(videoChannel.host).to.equal('localhost:9003')
123       expect(videoChannel.displayName).to.equal('Main user3 channel')
124       expect(videoChannel.followingCount).to.equal(0)
125       expect(videoChannel.followersCount).to.equal(1)
126     }
127
128     {
129       const res = await getUserSubscription(servers[ 0 ].url, users[ 0 ].accessToken, 'root_channel@localhost:9001')
130       const videoChannel: VideoChannel = res.body
131
132       expect(videoChannel.name).to.equal('root_channel')
133       expect(videoChannel.host).to.equal('localhost:9001')
134       expect(videoChannel.displayName).to.equal('Main root channel')
135       expect(videoChannel.followingCount).to.equal(0)
136       expect(videoChannel.followersCount).to.equal(1)
137     }
138   })
139
140   it('Should return the existing subscriptions', async function () {
141     const uris = [
142       'user3_channel@localhost:9003',
143       'root2_channel@localhost:9001',
144       'root_channel@localhost:9001',
145       'user3_channel@localhost:9001'
146     ]
147
148     const res = await areSubscriptionsExist(servers[ 0 ].url, users[ 0 ].accessToken, uris)
149     const body = res.body
150
151     expect(body['user3_channel@localhost:9003']).to.be.true
152     expect(body['root2_channel@localhost:9001']).to.be.false
153     expect(body['root_channel@localhost:9001']).to.be.true
154     expect(body['user3_channel@localhost:9001']).to.be.false
155   })
156
157   it('Should list subscription videos', async function () {
158     {
159       const res = await listUserSubscriptionVideos(servers[0].url, servers[0].accessToken)
160       expect(res.body.total).to.equal(0)
161       expect(res.body.data).to.be.an('array')
162       expect(res.body.data).to.have.lengthOf(0)
163     }
164
165     {
166       const res = await listUserSubscriptionVideos(servers[0].url, users[0].accessToken, 'createdAt')
167       expect(res.body.total).to.equal(3)
168
169       const videos: Video[] = res.body.data
170       expect(videos).to.be.an('array')
171       expect(videos).to.have.lengthOf(3)
172
173       expect(videos[0].name).to.equal('video 1-3')
174       expect(videos[1].name).to.equal('video 2-3')
175       expect(videos[2].name).to.equal('video server 3 added after follow')
176     }
177   })
178
179   it('Should upload a video by root on server 1 and see it in the subscription videos', async function () {
180     this.timeout(60000)
181
182     const videoName = 'video server 1 added after follow'
183     await uploadVideo(servers[0].url, servers[0].accessToken, { name: videoName })
184
185     await waitJobs(servers)
186
187     {
188       const res = await listUserSubscriptionVideos(servers[0].url, servers[0].accessToken)
189       expect(res.body.total).to.equal(0)
190       expect(res.body.data).to.be.an('array')
191       expect(res.body.data).to.have.lengthOf(0)
192     }
193
194     {
195       const res = await listUserSubscriptionVideos(servers[0].url, users[0].accessToken, 'createdAt')
196       expect(res.body.total).to.equal(4)
197
198       const videos: Video[] = res.body.data
199       expect(videos).to.be.an('array')
200       expect(videos).to.have.lengthOf(4)
201
202       expect(videos[0].name).to.equal('video 1-3')
203       expect(videos[1].name).to.equal('video 2-3')
204       expect(videos[2].name).to.equal('video server 3 added after follow')
205       expect(videos[3].name).to.equal('video server 1 added after follow')
206     }
207
208     {
209       const res = await getVideosList(servers[0].url)
210
211       expect(res.body.total).to.equal(5)
212       for (const video of res.body.data) {
213         expect(video.name).to.not.contain('1-3')
214         expect(video.name).to.not.contain('2-3')
215         expect(video.name).to.not.contain('video server 3 added after follow')
216       }
217     }
218   })
219
220   it('Should have server 1 follow server 3 and display server 3 videos', async function () {
221     this.timeout(60000)
222
223     await follow(servers[0].url, [ servers[2].url ], servers[0].accessToken)
224
225     await waitJobs(servers)
226
227     const res = await getVideosList(servers[0].url)
228
229     expect(res.body.total).to.equal(8)
230
231     const names = [ '1-3', '2-3', 'video server 3 added after follow' ]
232     for (const name of names) {
233       const video = res.body.data.find(v => v.name.indexOf(name) === -1)
234       expect(video).to.not.be.undefined
235     }
236   })
237
238   it('Should remove follow server 1 -> server 3 and hide server 3 videos', async function () {
239     this.timeout(60000)
240
241     await unfollow(servers[0].url, servers[0].accessToken, servers[2])
242
243     await waitJobs(servers)
244
245     const res = await getVideosList(servers[0].url)
246
247     expect(res.body.total).to.equal(5)
248     for (const video of res.body.data) {
249       expect(video.name).to.not.contain('1-3')
250       expect(video.name).to.not.contain('2-3')
251       expect(video.name).to.not.contain('video server 3 added after follow')
252     }
253   })
254
255   it('Should still list subscription videos', async function () {
256     {
257       const res = await listUserSubscriptionVideos(servers[0].url, servers[0].accessToken)
258       expect(res.body.total).to.equal(0)
259       expect(res.body.data).to.be.an('array')
260       expect(res.body.data).to.have.lengthOf(0)
261     }
262
263     {
264       const res = await listUserSubscriptionVideos(servers[0].url, users[0].accessToken, 'createdAt')
265       expect(res.body.total).to.equal(4)
266
267       const videos: Video[] = res.body.data
268       expect(videos).to.be.an('array')
269       expect(videos).to.have.lengthOf(4)
270
271       expect(videos[0].name).to.equal('video 1-3')
272       expect(videos[1].name).to.equal('video 2-3')
273       expect(videos[2].name).to.equal('video server 3 added after follow')
274       expect(videos[3].name).to.equal('video server 1 added after follow')
275     }
276   })
277
278   it('Should update a video of server 3 and see the updated video on server 1', async function () {
279     this.timeout(30000)
280
281     await updateVideo(servers[2].url, users[2].accessToken, video3UUID, { name: 'video server 3 added after follow updated' })
282
283     await waitJobs(servers)
284
285     const res = await listUserSubscriptionVideos(servers[0].url, users[0].accessToken, 'createdAt')
286     const videos: Video[] = res.body.data
287     expect(videos[2].name).to.equal('video server 3 added after follow updated')
288   })
289
290   it('Should remove user of server 3 subscription', async function () {
291     this.timeout(30000)
292
293     await removeUserSubscription(servers[0].url, users[0].accessToken, 'user3_channel@localhost:9003')
294
295     await waitJobs(servers)
296   })
297
298   it('Should not display its videos anymore', async function () {
299     {
300       const res = await listUserSubscriptionVideos(servers[0].url, users[0].accessToken, 'createdAt')
301       expect(res.body.total).to.equal(1)
302
303       const videos: Video[] = res.body.data
304       expect(videos).to.be.an('array')
305       expect(videos).to.have.lengthOf(1)
306
307       expect(videos[0].name).to.equal('video server 1 added after follow')
308     }
309   })
310
311   it('Should remove the root subscription and not display the videos anymore', async function () {
312     this.timeout(30000)
313
314     await removeUserSubscription(servers[0].url, users[0].accessToken, 'root_channel@localhost:9001')
315
316     await waitJobs(servers)
317
318     {
319       const res = await listUserSubscriptionVideos(servers[0].url, users[0].accessToken, 'createdAt')
320       expect(res.body.total).to.equal(0)
321
322       const videos: Video[] = res.body.data
323       expect(videos).to.be.an('array')
324       expect(videos).to.have.lengthOf(0)
325     }
326   })
327
328   it('Should correctly display public videos on server 1', async function () {
329     const res = await getVideosList(servers[0].url)
330
331     expect(res.body.total).to.equal(5)
332     for (const video of res.body.data) {
333       expect(video.name).to.not.contain('1-3')
334       expect(video.name).to.not.contain('2-3')
335       expect(video.name).to.not.contain('video server 3 added after follow updated')
336     }
337   })
338
339   it('Should follow user of server 3 again', async function () {
340     this.timeout(60000)
341
342     await addUserSubscription(servers[0].url, users[0].accessToken, 'user3_channel@localhost:9003')
343
344     await waitJobs(servers)
345
346     {
347       const res = await listUserSubscriptionVideos(servers[0].url, users[0].accessToken, 'createdAt')
348       expect(res.body.total).to.equal(3)
349
350       const videos: Video[] = res.body.data
351       expect(videos).to.be.an('array')
352       expect(videos).to.have.lengthOf(3)
353
354       expect(videos[0].name).to.equal('video 1-3')
355       expect(videos[1].name).to.equal('video 2-3')
356       expect(videos[2].name).to.equal('video server 3 added after follow updated')
357     }
358
359     {
360       const res = await getVideosList(servers[0].url)
361
362       expect(res.body.total).to.equal(5)
363       for (const video of res.body.data) {
364         expect(video.name).to.not.contain('1-3')
365         expect(video.name).to.not.contain('2-3')
366         expect(video.name).to.not.contain('video server 3 added after follow updated')
367       }
368     }
369   })
370
371   after(async function () {
372     killallServers(servers)
373   })
374 })