Add tests for video-abuse persistence after video deletion
[oweals/peertube.git] / server / tests / api / videos / video-abuse.ts
1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3 import * as chai from 'chai'
4 import 'mocha'
5 import { VideoAbuse, VideoAbuseState } from '../../../../shared/models/videos'
6 import {
7   cleanupTests,
8   deleteVideoAbuse,
9   flushAndRunMultipleServers,
10   getVideoAbusesList,
11   getVideosList,
12   reportVideoAbuse,
13   ServerInfo,
14   setAccessTokensToServers,
15   updateVideoAbuse,
16   uploadVideo,
17   removeVideo
18 } from '../../../../shared/extra-utils/index'
19 import { doubleFollow } from '../../../../shared/extra-utils/server/follows'
20 import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
21 import {
22   addAccountToServerBlocklist,
23   addServerToServerBlocklist,
24   removeAccountFromServerBlocklist,
25   removeServerFromServerBlocklist
26 } from '../../../../shared/extra-utils/users/blocklist'
27
28 const expect = chai.expect
29
30 describe('Test video abuses', function () {
31   let servers: ServerInfo[] = []
32   let abuseServer2: VideoAbuse
33
34   before(async function () {
35     this.timeout(50000)
36
37     // Run servers
38     servers = await flushAndRunMultipleServers(2)
39
40     // Get the access tokens
41     await setAccessTokensToServers(servers)
42
43     // Server 1 and server 2 follow each other
44     await doubleFollow(servers[0], servers[1])
45
46     // Upload some videos on each servers
47     const video1Attributes = {
48       name: 'my super name for server 1',
49       description: 'my super description for server 1'
50     }
51     await uploadVideo(servers[0].url, servers[0].accessToken, video1Attributes)
52
53     const video2Attributes = {
54       name: 'my super name for server 2',
55       description: 'my super description for server 2'
56     }
57     await uploadVideo(servers[1].url, servers[1].accessToken, video2Attributes)
58
59     // Wait videos propagation, server 2 has transcoding enabled
60     await waitJobs(servers)
61
62     const res = await getVideosList(servers[0].url)
63     const videos = res.body.data
64
65     expect(videos.length).to.equal(2)
66
67     servers[0].video = videos.find(video => video.name === 'my super name for server 1')
68     servers[1].video = videos.find(video => video.name === 'my super name for server 2')
69   })
70
71   it('Should not have video abuses', async function () {
72     const res = await getVideoAbusesList(servers[0].url, servers[0].accessToken)
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   it('Should report abuse on a local video', async function () {
80     this.timeout(15000)
81
82     const reason = 'my super bad reason'
83     await reportVideoAbuse(servers[0].url, servers[0].accessToken, servers[0].video.id, reason)
84
85     // We wait requests propagation, even if the server 1 is not supposed to make a request to server 2
86     await waitJobs(servers)
87   })
88
89   it('Should have 1 video abuses on server 1 and 0 on server 2', async function () {
90     const res1 = await getVideoAbusesList(servers[0].url, servers[0].accessToken)
91
92     expect(res1.body.total).to.equal(1)
93     expect(res1.body.data).to.be.an('array')
94     expect(res1.body.data.length).to.equal(1)
95
96     const abuse: VideoAbuse = res1.body.data[0]
97     expect(abuse.reason).to.equal('my super bad reason')
98     expect(abuse.reporterAccount.name).to.equal('root')
99     expect(abuse.reporterAccount.host).to.equal('localhost:' + servers[0].port)
100     expect(abuse.video.id).to.equal(servers[0].video.id)
101     expect(abuse.video.channel).to.exist
102     expect(abuse.count).to.equal(1)
103     expect(abuse.nth).to.equal(1)
104     expect(abuse.countReportsForReporter).to.equal(1)
105     expect(abuse.countReportsForReportee).to.equal(1)
106
107     const res2 = await getVideoAbusesList(servers[1].url, servers[1].accessToken)
108     expect(res2.body.total).to.equal(0)
109     expect(res2.body.data).to.be.an('array')
110     expect(res2.body.data.length).to.equal(0)
111   })
112
113   it('Should report abuse on a remote video', async function () {
114     this.timeout(10000)
115
116     const reason = 'my super bad reason 2'
117     await reportVideoAbuse(servers[0].url, servers[0].accessToken, servers[1].video.id, reason)
118
119     // We wait requests propagation
120     await waitJobs(servers)
121   })
122
123   it('Should have 2 video abuses on server 1 and 1 on server 2', async function () {
124     const res1 = await getVideoAbusesList(servers[0].url, servers[0].accessToken)
125     expect(res1.body.total).to.equal(2)
126     expect(res1.body.data).to.be.an('array')
127     expect(res1.body.data.length).to.equal(2)
128
129     const abuse1: VideoAbuse = res1.body.data[0]
130     expect(abuse1.reason).to.equal('my super bad reason')
131     expect(abuse1.reporterAccount.name).to.equal('root')
132     expect(abuse1.reporterAccount.host).to.equal('localhost:' + servers[0].port)
133     expect(abuse1.video.id).to.equal(servers[0].video.id)
134     expect(abuse1.state.id).to.equal(VideoAbuseState.PENDING)
135     expect(abuse1.state.label).to.equal('Pending')
136     expect(abuse1.moderationComment).to.be.null
137     expect(abuse1.count).to.equal(1)
138     expect(abuse1.nth).to.equal(1)
139
140     const abuse2: VideoAbuse = res1.body.data[1]
141     expect(abuse2.reason).to.equal('my super bad reason 2')
142     expect(abuse2.reporterAccount.name).to.equal('root')
143     expect(abuse2.reporterAccount.host).to.equal('localhost:' + servers[0].port)
144     expect(abuse2.video.id).to.equal(servers[1].video.id)
145     expect(abuse2.state.id).to.equal(VideoAbuseState.PENDING)
146     expect(abuse2.state.label).to.equal('Pending')
147     expect(abuse2.moderationComment).to.be.null
148
149     const res2 = await getVideoAbusesList(servers[1].url, servers[1].accessToken)
150     expect(res2.body.total).to.equal(1)
151     expect(res2.body.data).to.be.an('array')
152     expect(res2.body.data.length).to.equal(1)
153
154     abuseServer2 = res2.body.data[0]
155     expect(abuseServer2.reason).to.equal('my super bad reason 2')
156     expect(abuseServer2.reporterAccount.name).to.equal('root')
157     expect(abuseServer2.reporterAccount.host).to.equal('localhost:' + servers[0].port)
158     expect(abuseServer2.state.id).to.equal(VideoAbuseState.PENDING)
159     expect(abuseServer2.state.label).to.equal('Pending')
160     expect(abuseServer2.moderationComment).to.be.null
161   })
162
163   it('Should update the state of a video abuse', async function () {
164     const body = { state: VideoAbuseState.REJECTED }
165     await updateVideoAbuse(servers[1].url, servers[1].accessToken, abuseServer2.video.uuid, abuseServer2.id, body)
166
167     const res = await getVideoAbusesList(servers[1].url, servers[1].accessToken)
168     expect(res.body.data[0].state.id).to.equal(VideoAbuseState.REJECTED)
169   })
170
171   it('Should add a moderation comment', async function () {
172     const body = { state: VideoAbuseState.ACCEPTED, moderationComment: 'It is valid' }
173     await updateVideoAbuse(servers[1].url, servers[1].accessToken, abuseServer2.video.uuid, abuseServer2.id, body)
174
175     const res = await getVideoAbusesList(servers[1].url, servers[1].accessToken)
176     expect(res.body.data[0].state.id).to.equal(VideoAbuseState.ACCEPTED)
177     expect(res.body.data[0].moderationComment).to.equal('It is valid')
178   })
179
180   it('Should hide video abuses from blocked accounts', async function () {
181     this.timeout(10000)
182
183     {
184       await reportVideoAbuse(servers[1].url, servers[1].accessToken, servers[0].video.uuid, 'will mute this')
185       await waitJobs(servers)
186
187       const res = await getVideoAbusesList(servers[0].url, servers[0].accessToken)
188       expect(res.body.total).to.equal(3)
189     }
190
191     const accountToBlock = 'root@localhost:' + servers[1].port
192
193     {
194       await addAccountToServerBlocklist(servers[0].url, servers[0].accessToken, accountToBlock)
195
196       const res = await getVideoAbusesList(servers[0].url, servers[0].accessToken)
197       expect(res.body.total).to.equal(2)
198
199       const abuse = res.body.data.find(a => a.reason === 'will mute this')
200       expect(abuse).to.be.undefined
201     }
202
203     {
204       await removeAccountFromServerBlocklist(servers[0].url, servers[0].accessToken, accountToBlock)
205
206       const res = await getVideoAbusesList(servers[0].url, servers[0].accessToken)
207       expect(res.body.total).to.equal(3)
208     }
209   })
210
211   it('Should hide video abuses from blocked servers', async function () {
212     const serverToBlock = servers[1].host
213
214     {
215       await addServerToServerBlocklist(servers[0].url, servers[0].accessToken, servers[1].host)
216
217       const res = await getVideoAbusesList(servers[0].url, servers[0].accessToken)
218       expect(res.body.total).to.equal(2)
219
220       const abuse = res.body.data.find(a => a.reason === 'will mute this')
221       expect(abuse).to.be.undefined
222     }
223
224     {
225       await removeServerFromServerBlocklist(servers[0].url, servers[0].accessToken, serverToBlock)
226
227       const res = await getVideoAbusesList(servers[0].url, servers[0].accessToken)
228       expect(res.body.total).to.equal(3)
229     }
230   })
231
232   it('Should keep the video abuse when deleting the video', async function () {
233     this.timeout(10000)
234
235     await removeVideo(servers[1].url, servers[1].accessToken, abuseServer2.video.uuid)
236
237     await waitJobs(servers)
238
239     {
240       const res = await getVideoAbusesList(servers[1].url, servers[1].accessToken)
241       expect(res.body.total).to.equal(2)
242       expect(res.body.data.length).to.equal(2)
243       expect(res.body.data[0].id).to.equal(abuseServer2.id)
244
245       const abuse: VideoAbuse = res.body.data[1]
246       expect(abuse.video.deleted).to.be.true
247       expect(abuse.video.id).to.equal(abuseServer2.video.id)
248       expect(abuse.video.channel).to.exist
249     }
250   })
251
252   it('Should delete the video abuse', async function () {
253     this.timeout(10000)
254
255     await deleteVideoAbuse(servers[1].url, servers[1].accessToken, abuseServer2.video.uuid, abuseServer2.id)
256
257     await waitJobs(servers)
258
259     {
260       const res = await getVideoAbusesList(servers[1].url, servers[1].accessToken)
261       expect(res.body.total).to.equal(1)
262       expect(res.body.data.length).to.equal(1)
263       expect(res.body.data[0].id).to.not.equal(abuseServer2.id)
264     }
265
266     {
267       const res = await getVideoAbusesList(servers[0].url, servers[0].accessToken)
268       expect(res.body.total).to.equal(3)
269     }
270   })
271
272   after(async function () {
273     await cleanupTests(servers)
274   })
275 })