Shared utils -> extra-utils
[oweals/peertube.git] / server / tests / api / videos / video-blacklist.ts
1 /* tslint:disable:no-unused-expression */
2
3 import * as chai from 'chai'
4 import { orderBy } from 'lodash'
5 import 'mocha'
6 import {
7   addVideoToBlacklist,
8   createUser,
9   flushAndRunMultipleServers,
10   getBlacklistedVideosList,
11   getMyVideos,
12   getVideosList,
13   killallServers,
14   removeVideoFromBlacklist,
15   reRunServer,
16   searchVideo,
17   ServerInfo,
18   setAccessTokensToServers,
19   updateVideo,
20   updateVideoBlacklist,
21   uploadVideo,
22   userLogin
23 } from '../../../../shared/extra-utils/index'
24 import { doubleFollow } from '../../../../shared/extra-utils/server/follows'
25 import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
26 import { VideoBlacklist, VideoBlacklistType } from '../../../../shared/models/videos'
27 import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model'
28 import { UserRole } from '../../../../shared/models/users'
29
30 const expect = chai.expect
31
32 describe('Test video blacklist', function () {
33   let servers: ServerInfo[] = []
34   let videoId: number
35
36   async function blacklistVideosOnServer (server: ServerInfo) {
37     const res = await getVideosList(server.url)
38
39     const videos = res.body.data
40     for (let video of videos) {
41       await addVideoToBlacklist(server.url, server.accessToken, video.id, 'super reason')
42     }
43   }
44
45   before(async function () {
46     this.timeout(50000)
47
48     // Run servers
49     servers = await flushAndRunMultipleServers(2)
50
51     // Get the access tokens
52     await setAccessTokensToServers(servers)
53
54     // Server 1 and server 2 follow each other
55     await doubleFollow(servers[0], servers[1])
56
57     // Upload 2 videos on server 2
58     await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'My 1st video', description: 'A video on server 2' })
59     await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'My 2nd video', description: 'A video on server 2' })
60
61     // Wait videos propagation, server 2 has transcoding enabled
62     await waitJobs(servers)
63
64     // Blacklist the two videos on server 1
65     await blacklistVideosOnServer(servers[0])
66   })
67
68   describe('When listing/searching videos', function () {
69
70     it('Should not have the video blacklisted in videos list/search on server 1', async function () {
71       {
72         const res = await getVideosList(servers[ 0 ].url)
73
74         expect(res.body.total).to.equal(0)
75         expect(res.body.data).to.be.an('array')
76         expect(res.body.data.length).to.equal(0)
77       }
78
79       {
80         const res = await searchVideo(servers[ 0 ].url, 'name')
81
82         expect(res.body.total).to.equal(0)
83         expect(res.body.data).to.be.an('array')
84         expect(res.body.data.length).to.equal(0)
85       }
86     })
87
88     it('Should have the blacklisted video in videos list/search on server 2', async function () {
89       {
90         const res = await getVideosList(servers[ 1 ].url)
91
92         expect(res.body.total).to.equal(2)
93         expect(res.body.data).to.be.an('array')
94         expect(res.body.data.length).to.equal(2)
95       }
96
97       {
98         const res = await searchVideo(servers[ 1 ].url, 'video')
99
100         expect(res.body.total).to.equal(2)
101         expect(res.body.data).to.be.an('array')
102         expect(res.body.data.length).to.equal(2)
103       }
104     })
105   })
106
107   describe('When listing manually blacklisted videos', function () {
108     it('Should display all the blacklisted videos', async function () {
109       const res = await getBlacklistedVideosList({ url: servers[0].url, token: servers[0].accessToken })
110
111       expect(res.body.total).to.equal(2)
112
113       const blacklistedVideos = res.body.data
114       expect(blacklistedVideos).to.be.an('array')
115       expect(blacklistedVideos.length).to.equal(2)
116
117       for (const blacklistedVideo of blacklistedVideos) {
118         expect(blacklistedVideo.reason).to.equal('super reason')
119         videoId = blacklistedVideo.video.id
120       }
121     })
122
123     it('Should display all the blacklisted videos when applying manual type filter', async function () {
124       const res = await getBlacklistedVideosList({
125         url: servers[ 0 ].url,
126         token: servers[ 0 ].accessToken,
127         type: VideoBlacklistType.MANUAL
128       })
129
130       expect(res.body.total).to.equal(2)
131
132       const blacklistedVideos = res.body.data
133       expect(blacklistedVideos).to.be.an('array')
134       expect(blacklistedVideos.length).to.equal(2)
135     })
136
137     it('Should display nothing when applying automatic type filter', async function () {
138       const res = await getBlacklistedVideosList({
139         url: servers[ 0 ].url,
140         token: servers[ 0 ].accessToken,
141         type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED
142       })
143
144       expect(res.body.total).to.equal(0)
145
146       const blacklistedVideos = res.body.data
147       expect(blacklistedVideos).to.be.an('array')
148       expect(blacklistedVideos.length).to.equal(0)
149     })
150
151     it('Should get the correct sort when sorting by descending id', async function () {
152       const res = await getBlacklistedVideosList({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, sort: '-id' })
153       expect(res.body.total).to.equal(2)
154
155       const blacklistedVideos = res.body.data
156       expect(blacklistedVideos).to.be.an('array')
157       expect(blacklistedVideos.length).to.equal(2)
158
159       const result = orderBy(res.body.data, [ 'id' ], [ 'desc' ])
160
161       expect(blacklistedVideos).to.deep.equal(result)
162     })
163
164     it('Should get the correct sort when sorting by descending video name', async function () {
165       const res = await getBlacklistedVideosList({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, sort: '-name' })
166       expect(res.body.total).to.equal(2)
167
168       const blacklistedVideos = res.body.data
169       expect(blacklistedVideos).to.be.an('array')
170       expect(blacklistedVideos.length).to.equal(2)
171
172       const result = orderBy(res.body.data, [ 'name' ], [ 'desc' ])
173
174       expect(blacklistedVideos).to.deep.equal(result)
175     })
176
177     it('Should get the correct sort when sorting by ascending creation date', async function () {
178       const res = await getBlacklistedVideosList({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, sort: 'createdAt' })
179       expect(res.body.total).to.equal(2)
180
181       const blacklistedVideos = res.body.data
182       expect(blacklistedVideos).to.be.an('array')
183       expect(blacklistedVideos.length).to.equal(2)
184
185       const result = orderBy(res.body.data, [ 'createdAt' ])
186
187       expect(blacklistedVideos).to.deep.equal(result)
188     })
189   })
190
191   describe('When updating blacklisted videos', function () {
192     it('Should change the reason', async function () {
193       await updateVideoBlacklist(servers[0].url, servers[0].accessToken, videoId, 'my super reason updated')
194
195       const res = await getBlacklistedVideosList({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, sort: '-name' })
196       const video = res.body.data.find(b => b.video.id === videoId)
197
198       expect(video.reason).to.equal('my super reason updated')
199     })
200   })
201
202   describe('When listing my videos', function () {
203     it('Should display blacklisted videos', async function () {
204       await blacklistVideosOnServer(servers[1])
205
206       const res = await getMyVideos(servers[1].url, servers[1].accessToken, 0, 5)
207
208       expect(res.body.total).to.equal(2)
209       expect(res.body.data).to.have.lengthOf(2)
210
211       for (const video of res.body.data) {
212         expect(video.blacklisted).to.be.true
213         expect(video.blacklistedReason).to.equal('super reason')
214       }
215     })
216   })
217
218   describe('When removing a blacklisted video', function () {
219     let videoToRemove: VideoBlacklist
220     let blacklist = []
221
222     it('Should not have any video in videos list on server 1', async function () {
223       const res = await getVideosList(servers[0].url)
224       expect(res.body.total).to.equal(0)
225       expect(res.body.data).to.be.an('array')
226       expect(res.body.data.length).to.equal(0)
227     })
228
229     it('Should remove a video from the blacklist on server 1', async function () {
230       // Get one video in the blacklist
231       const res = await getBlacklistedVideosList({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, sort: '-name' })
232       videoToRemove = res.body.data[0]
233       blacklist = res.body.data.slice(1)
234
235       // Remove it
236       await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, videoToRemove.video.id)
237     })
238
239     it('Should have the ex-blacklisted video in videos list on server 1', async function () {
240       const res = await getVideosList(servers[0].url)
241       expect(res.body.total).to.equal(1)
242
243       const videos = res.body.data
244       expect(videos).to.be.an('array')
245       expect(videos.length).to.equal(1)
246
247       expect(videos[0].name).to.equal(videoToRemove.video.name)
248       expect(videos[0].id).to.equal(videoToRemove.video.id)
249     })
250
251     it('Should not have the ex-blacklisted video in videos blacklist list on server 1', async function () {
252       const res = await getBlacklistedVideosList({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, sort: '-name' })
253       expect(res.body.total).to.equal(1)
254
255       const videos = res.body.data
256       expect(videos).to.be.an('array')
257       expect(videos.length).to.equal(1)
258       expect(videos).to.deep.equal(blacklist)
259     })
260   })
261
262   describe('When blacklisting local videos', function () {
263     let video3UUID: string
264     let video4UUID: string
265
266     before(async function () {
267       this.timeout(10000)
268
269       {
270         const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'Video 3' })
271         video3UUID = res.body.video.uuid
272       }
273       {
274         const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, { name: 'Video 4' })
275         video4UUID = res.body.video.uuid
276       }
277
278       await waitJobs(servers)
279     })
280
281     it('Should blacklist video 3 and keep it federated', async function () {
282       this.timeout(10000)
283
284       await addVideoToBlacklist(servers[ 0 ].url, servers[ 0 ].accessToken, video3UUID, 'super reason', false)
285
286       await waitJobs(servers)
287
288       {
289         const res = await getVideosList(servers[ 0 ].url)
290         expect(res.body.data.find(v => v.uuid === video3UUID)).to.be.undefined
291       }
292
293       {
294         const res = await getVideosList(servers[ 1 ].url)
295         expect(res.body.data.find(v => v.uuid === video3UUID)).to.not.be.undefined
296       }
297     })
298
299     it('Should unfederate the video', async function () {
300       this.timeout(10000)
301
302       await addVideoToBlacklist(servers[ 0 ].url, servers[ 0 ].accessToken, video4UUID, 'super reason', true)
303
304       await waitJobs(servers)
305
306       for (const server of servers) {
307         const res = await getVideosList(server.url)
308         expect(res.body.data.find(v => v.uuid === video4UUID)).to.be.undefined
309       }
310     })
311
312     it('Should have the video unfederated even after an Update AP message', async function () {
313       this.timeout(10000)
314
315       await updateVideo(servers[ 0 ].url, servers[ 0 ].accessToken, video4UUID, { description: 'super description' })
316
317       await waitJobs(servers)
318
319       for (const server of servers) {
320         const res = await getVideosList(server.url)
321         expect(res.body.data.find(v => v.uuid === video4UUID)).to.be.undefined
322       }
323     })
324
325     it('Should have the correct video blacklist unfederate attribute', async function () {
326       const res = await getBlacklistedVideosList({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, sort: 'createdAt' })
327
328       const blacklistedVideos: VideoBlacklist[] = res.body.data
329       const video3Blacklisted = blacklistedVideos.find(b => b.video.uuid === video3UUID)
330       const video4Blacklisted = blacklistedVideos.find(b => b.video.uuid === video4UUID)
331
332       expect(video3Blacklisted.unfederated).to.be.false
333       expect(video4Blacklisted.unfederated).to.be.true
334     })
335
336     it('Should remove the video from blacklist and refederate the video', async function () {
337       this.timeout(10000)
338
339       await removeVideoFromBlacklist(servers[ 0 ].url, servers[ 0 ].accessToken, video4UUID)
340
341       await waitJobs(servers)
342
343       for (const server of servers) {
344         const res = await getVideosList(server.url)
345         expect(res.body.data.find(v => v.uuid === video4UUID)).to.not.be.undefined
346       }
347     })
348
349   })
350
351   describe('When auto blacklist videos', function () {
352     let userWithoutFlag: string
353     let userWithFlag: string
354
355     before(async function () {
356       this.timeout(20000)
357
358       killallServers([ servers[0] ])
359
360       const config = {
361         'auto_blacklist': {
362           videos: {
363             'of_users': {
364               enabled: true
365             }
366           }
367         }
368       }
369       await reRunServer(servers[0], config)
370
371       {
372         const user = { username: 'user_without_flag', password: 'password' }
373         await createUser({
374           url: servers[ 0 ].url,
375           accessToken: servers[ 0 ].accessToken,
376           username: user.username,
377           adminFlags: UserAdminFlag.NONE,
378           password: user.password,
379           role: UserRole.USER
380         })
381
382         userWithoutFlag = await userLogin(servers[0], user)
383       }
384
385       {
386         const user = { username: 'user_with_flag', password: 'password' }
387         await createUser({
388           url: servers[ 0 ].url,
389           accessToken: servers[ 0 ].accessToken,
390           username: user.username,
391           adminFlags: UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST,
392           password: user.password,
393           role: UserRole.USER
394         })
395
396         userWithFlag = await userLogin(servers[0], user)
397       }
398
399       await waitJobs(servers)
400     })
401
402     it('Should auto blacklist a video', async function () {
403       await uploadVideo(servers[0].url, userWithoutFlag, { name: 'blacklisted' })
404
405       const res = await getBlacklistedVideosList({
406         url: servers[ 0 ].url,
407         token: servers[ 0 ].accessToken,
408         type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED
409       })
410
411       expect(res.body.total).to.equal(1)
412       expect(res.body.data[0].video.name).to.equal('blacklisted')
413     })
414
415     it('Should not auto blacklist a video', async function () {
416       await uploadVideo(servers[0].url, userWithFlag, { name: 'not blacklisted' })
417
418       const res = await getBlacklistedVideosList({
419         url: servers[ 0 ].url,
420         token: servers[ 0 ].accessToken,
421         type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED
422       })
423
424       expect(res.body.total).to.equal(1)
425     })
426   })
427
428   after(async function () {
429     killallServers(servers)
430   })
431 })