diff options
Diffstat (limited to 'server/tests/api/moderation')
-rw-r--r-- | server/tests/api/moderation/abuses.ts | 384 | ||||
-rw-r--r-- | server/tests/api/moderation/blocklist.ts | 828 | ||||
-rw-r--r-- | server/tests/api/moderation/index.ts | 2 |
3 files changed, 1214 insertions, 0 deletions
diff --git a/server/tests/api/moderation/abuses.ts b/server/tests/api/moderation/abuses.ts new file mode 100644 index 000000000..28c5a5531 --- /dev/null +++ b/server/tests/api/moderation/abuses.ts | |||
@@ -0,0 +1,384 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | ||
2 | |||
3 | import 'mocha' | ||
4 | import * as chai from 'chai' | ||
5 | import { Abuse, AbusePredefinedReasonsString, AbuseState } from '@shared/models' | ||
6 | import { | ||
7 | cleanupTests, | ||
8 | createUser, | ||
9 | deleteVideoAbuse, | ||
10 | flushAndRunMultipleServers, | ||
11 | getVideoAbusesList, | ||
12 | getVideosList, | ||
13 | removeVideo, | ||
14 | reportVideoAbuse, | ||
15 | ServerInfo, | ||
16 | setAccessTokensToServers, | ||
17 | updateVideoAbuse, | ||
18 | uploadVideo, | ||
19 | userLogin | ||
20 | } from '../../../../shared/extra-utils/index' | ||
21 | import { doubleFollow } from '../../../../shared/extra-utils/server/follows' | ||
22 | import { waitJobs } from '../../../../shared/extra-utils/server/jobs' | ||
23 | import { | ||
24 | addAccountToServerBlocklist, | ||
25 | addServerToServerBlocklist, | ||
26 | removeAccountFromServerBlocklist, | ||
27 | removeServerFromServerBlocklist | ||
28 | } from '../../../../shared/extra-utils/users/blocklist' | ||
29 | |||
30 | const expect = chai.expect | ||
31 | |||
32 | describe('Test abuses', function () { | ||
33 | let servers: ServerInfo[] = [] | ||
34 | let abuseServer2: Abuse | ||
35 | |||
36 | before(async function () { | ||
37 | this.timeout(50000) | ||
38 | |||
39 | // Run servers | ||
40 | servers = await flushAndRunMultipleServers(2) | ||
41 | |||
42 | // Get the access tokens | ||
43 | await setAccessTokensToServers(servers) | ||
44 | |||
45 | // Server 1 and server 2 follow each other | ||
46 | await doubleFollow(servers[0], servers[1]) | ||
47 | |||
48 | // Upload some videos on each servers | ||
49 | const video1Attributes = { | ||
50 | name: 'my super name for server 1', | ||
51 | description: 'my super description for server 1' | ||
52 | } | ||
53 | await uploadVideo(servers[0].url, servers[0].accessToken, video1Attributes) | ||
54 | |||
55 | const video2Attributes = { | ||
56 | name: 'my super name for server 2', | ||
57 | description: 'my super description for server 2' | ||
58 | } | ||
59 | await uploadVideo(servers[1].url, servers[1].accessToken, video2Attributes) | ||
60 | |||
61 | // Wait videos propagation, server 2 has transcoding enabled | ||
62 | await waitJobs(servers) | ||
63 | |||
64 | const res = await getVideosList(servers[0].url) | ||
65 | const videos = res.body.data | ||
66 | |||
67 | expect(videos.length).to.equal(2) | ||
68 | |||
69 | servers[0].video = videos.find(video => video.name === 'my super name for server 1') | ||
70 | servers[1].video = videos.find(video => video.name === 'my super name for server 2') | ||
71 | }) | ||
72 | |||
73 | it('Should not have video abuses', async function () { | ||
74 | const res = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken }) | ||
75 | |||
76 | expect(res.body.total).to.equal(0) | ||
77 | expect(res.body.data).to.be.an('array') | ||
78 | expect(res.body.data.length).to.equal(0) | ||
79 | }) | ||
80 | |||
81 | it('Should report abuse on a local video', async function () { | ||
82 | this.timeout(15000) | ||
83 | |||
84 | const reason = 'my super bad reason' | ||
85 | await reportVideoAbuse(servers[0].url, servers[0].accessToken, servers[0].video.id, reason) | ||
86 | |||
87 | // We wait requests propagation, even if the server 1 is not supposed to make a request to server 2 | ||
88 | await waitJobs(servers) | ||
89 | }) | ||
90 | |||
91 | it('Should have 1 video abuses on server 1 and 0 on server 2', async function () { | ||
92 | const res1 = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken }) | ||
93 | |||
94 | expect(res1.body.total).to.equal(1) | ||
95 | expect(res1.body.data).to.be.an('array') | ||
96 | expect(res1.body.data.length).to.equal(1) | ||
97 | |||
98 | const abuse: Abuse = res1.body.data[0] | ||
99 | expect(abuse.reason).to.equal('my super bad reason') | ||
100 | expect(abuse.reporterAccount.name).to.equal('root') | ||
101 | expect(abuse.reporterAccount.host).to.equal('localhost:' + servers[0].port) | ||
102 | expect(abuse.video.id).to.equal(servers[0].video.id) | ||
103 | expect(abuse.video.channel).to.exist | ||
104 | expect(abuse.count).to.equal(1) | ||
105 | expect(abuse.nth).to.equal(1) | ||
106 | expect(abuse.countReportsForReporter).to.equal(1) | ||
107 | expect(abuse.countReportsForReportee).to.equal(1) | ||
108 | |||
109 | const res2 = await getVideoAbusesList({ url: servers[1].url, token: servers[1].accessToken }) | ||
110 | expect(res2.body.total).to.equal(0) | ||
111 | expect(res2.body.data).to.be.an('array') | ||
112 | expect(res2.body.data.length).to.equal(0) | ||
113 | }) | ||
114 | |||
115 | it('Should report abuse on a remote video', async function () { | ||
116 | this.timeout(10000) | ||
117 | |||
118 | const reason = 'my super bad reason 2' | ||
119 | await reportVideoAbuse(servers[0].url, servers[0].accessToken, servers[1].video.id, reason) | ||
120 | |||
121 | // We wait requests propagation | ||
122 | await waitJobs(servers) | ||
123 | }) | ||
124 | |||
125 | it('Should have 2 video abuses on server 1 and 1 on server 2', async function () { | ||
126 | const res1 = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken }) | ||
127 | expect(res1.body.total).to.equal(2) | ||
128 | expect(res1.body.data).to.be.an('array') | ||
129 | expect(res1.body.data.length).to.equal(2) | ||
130 | |||
131 | const abuse1: Abuse = res1.body.data[0] | ||
132 | expect(abuse1.reason).to.equal('my super bad reason') | ||
133 | expect(abuse1.reporterAccount.name).to.equal('root') | ||
134 | expect(abuse1.reporterAccount.host).to.equal('localhost:' + servers[0].port) | ||
135 | expect(abuse1.video.id).to.equal(servers[0].video.id) | ||
136 | expect(abuse1.state.id).to.equal(AbuseState.PENDING) | ||
137 | expect(abuse1.state.label).to.equal('Pending') | ||
138 | expect(abuse1.moderationComment).to.be.null | ||
139 | expect(abuse1.count).to.equal(1) | ||
140 | expect(abuse1.nth).to.equal(1) | ||
141 | |||
142 | const abuse2: Abuse = res1.body.data[1] | ||
143 | expect(abuse2.reason).to.equal('my super bad reason 2') | ||
144 | expect(abuse2.reporterAccount.name).to.equal('root') | ||
145 | expect(abuse2.reporterAccount.host).to.equal('localhost:' + servers[0].port) | ||
146 | expect(abuse2.video.id).to.equal(servers[1].video.id) | ||
147 | expect(abuse2.state.id).to.equal(AbuseState.PENDING) | ||
148 | expect(abuse2.state.label).to.equal('Pending') | ||
149 | expect(abuse2.moderationComment).to.be.null | ||
150 | |||
151 | const res2 = await getVideoAbusesList({ url: servers[1].url, token: servers[1].accessToken }) | ||
152 | expect(res2.body.total).to.equal(1) | ||
153 | expect(res2.body.data).to.be.an('array') | ||
154 | expect(res2.body.data.length).to.equal(1) | ||
155 | |||
156 | abuseServer2 = res2.body.data[0] | ||
157 | expect(abuseServer2.reason).to.equal('my super bad reason 2') | ||
158 | expect(abuseServer2.reporterAccount.name).to.equal('root') | ||
159 | expect(abuseServer2.reporterAccount.host).to.equal('localhost:' + servers[0].port) | ||
160 | expect(abuseServer2.state.id).to.equal(AbuseState.PENDING) | ||
161 | expect(abuseServer2.state.label).to.equal('Pending') | ||
162 | expect(abuseServer2.moderationComment).to.be.null | ||
163 | }) | ||
164 | |||
165 | it('Should update the state of a video abuse', async function () { | ||
166 | const body = { state: AbuseState.REJECTED } | ||
167 | await updateVideoAbuse(servers[1].url, servers[1].accessToken, abuseServer2.video.uuid, abuseServer2.id, body) | ||
168 | |||
169 | const res = await getVideoAbusesList({ url: servers[1].url, token: servers[1].accessToken }) | ||
170 | expect(res.body.data[0].state.id).to.equal(AbuseState.REJECTED) | ||
171 | }) | ||
172 | |||
173 | it('Should add a moderation comment', async function () { | ||
174 | const body = { state: AbuseState.ACCEPTED, moderationComment: 'It is valid' } | ||
175 | await updateVideoAbuse(servers[1].url, servers[1].accessToken, abuseServer2.video.uuid, abuseServer2.id, body) | ||
176 | |||
177 | const res = await getVideoAbusesList({ url: servers[1].url, token: servers[1].accessToken }) | ||
178 | expect(res.body.data[0].state.id).to.equal(AbuseState.ACCEPTED) | ||
179 | expect(res.body.data[0].moderationComment).to.equal('It is valid') | ||
180 | }) | ||
181 | |||
182 | it('Should hide video abuses from blocked accounts', async function () { | ||
183 | this.timeout(10000) | ||
184 | |||
185 | { | ||
186 | await reportVideoAbuse(servers[1].url, servers[1].accessToken, servers[0].video.uuid, 'will mute this') | ||
187 | await waitJobs(servers) | ||
188 | |||
189 | const res = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken }) | ||
190 | expect(res.body.total).to.equal(3) | ||
191 | } | ||
192 | |||
193 | const accountToBlock = 'root@localhost:' + servers[1].port | ||
194 | |||
195 | { | ||
196 | await addAccountToServerBlocklist(servers[0].url, servers[0].accessToken, accountToBlock) | ||
197 | |||
198 | const res = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken }) | ||
199 | expect(res.body.total).to.equal(2) | ||
200 | |||
201 | const abuse = res.body.data.find(a => a.reason === 'will mute this') | ||
202 | expect(abuse).to.be.undefined | ||
203 | } | ||
204 | |||
205 | { | ||
206 | await removeAccountFromServerBlocklist(servers[0].url, servers[0].accessToken, accountToBlock) | ||
207 | |||
208 | const res = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken }) | ||
209 | expect(res.body.total).to.equal(3) | ||
210 | } | ||
211 | }) | ||
212 | |||
213 | it('Should hide video abuses from blocked servers', async function () { | ||
214 | const serverToBlock = servers[1].host | ||
215 | |||
216 | { | ||
217 | await addServerToServerBlocklist(servers[0].url, servers[0].accessToken, servers[1].host) | ||
218 | |||
219 | const res = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken }) | ||
220 | expect(res.body.total).to.equal(2) | ||
221 | |||
222 | const abuse = res.body.data.find(a => a.reason === 'will mute this') | ||
223 | expect(abuse).to.be.undefined | ||
224 | } | ||
225 | |||
226 | { | ||
227 | await removeServerFromServerBlocklist(servers[0].url, servers[0].accessToken, serverToBlock) | ||
228 | |||
229 | const res = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken }) | ||
230 | expect(res.body.total).to.equal(3) | ||
231 | } | ||
232 | }) | ||
233 | |||
234 | it('Should keep the video abuse when deleting the video', async function () { | ||
235 | this.timeout(10000) | ||
236 | |||
237 | await removeVideo(servers[1].url, servers[1].accessToken, abuseServer2.video.uuid) | ||
238 | |||
239 | await waitJobs(servers) | ||
240 | |||
241 | const res = await getVideoAbusesList({ url: servers[1].url, token: servers[1].accessToken }) | ||
242 | expect(res.body.total).to.equal(2, "wrong number of videos returned") | ||
243 | expect(res.body.data.length).to.equal(2, "wrong number of videos returned") | ||
244 | expect(res.body.data[0].id).to.equal(abuseServer2.id, "wrong origin server id for first video") | ||
245 | |||
246 | const abuse: Abuse = res.body.data[0] | ||
247 | expect(abuse.video.id).to.equal(abuseServer2.video.id, "wrong video id") | ||
248 | expect(abuse.video.channel).to.exist | ||
249 | expect(abuse.video.deleted).to.be.true | ||
250 | }) | ||
251 | |||
252 | it('Should include counts of reports from reporter and reportee', async function () { | ||
253 | this.timeout(10000) | ||
254 | |||
255 | // register a second user to have two reporters/reportees | ||
256 | const user = { username: 'user2', password: 'password' } | ||
257 | await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, ...user }) | ||
258 | const userAccessToken = await userLogin(servers[0], user) | ||
259 | |||
260 | // upload a third video via this user | ||
261 | const video3Attributes = { | ||
262 | name: 'my second super name for server 1', | ||
263 | description: 'my second super description for server 1' | ||
264 | } | ||
265 | await uploadVideo(servers[0].url, userAccessToken, video3Attributes) | ||
266 | |||
267 | const res1 = await getVideosList(servers[0].url) | ||
268 | const videos = res1.body.data | ||
269 | const video3 = videos.find(video => video.name === 'my second super name for server 1') | ||
270 | |||
271 | // resume with the test | ||
272 | const reason3 = 'my super bad reason 3' | ||
273 | await reportVideoAbuse(servers[0].url, servers[0].accessToken, video3.id, reason3) | ||
274 | const reason4 = 'my super bad reason 4' | ||
275 | await reportVideoAbuse(servers[0].url, userAccessToken, servers[0].video.id, reason4) | ||
276 | |||
277 | const res2 = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken }) | ||
278 | |||
279 | { | ||
280 | for (const abuse of res2.body.data as Abuse[]) { | ||
281 | if (abuse.video.id === video3.id) { | ||
282 | expect(abuse.count).to.equal(1, "wrong reports count for video 3") | ||
283 | expect(abuse.nth).to.equal(1, "wrong report position in report list for video 3") | ||
284 | expect(abuse.countReportsForReportee).to.equal(1, "wrong reports count for reporter on video 3 abuse") | ||
285 | expect(abuse.countReportsForReporter).to.equal(3, "wrong reports count for reportee on video 3 abuse") | ||
286 | } | ||
287 | if (abuse.video.id === servers[0].video.id) { | ||
288 | expect(abuse.countReportsForReportee).to.equal(3, "wrong reports count for reporter on video 1 abuse") | ||
289 | } | ||
290 | } | ||
291 | } | ||
292 | }) | ||
293 | |||
294 | it('Should list predefined reasons as well as timestamps for the reported video', async function () { | ||
295 | this.timeout(10000) | ||
296 | |||
297 | const reason5 = 'my super bad reason 5' | ||
298 | const predefinedReasons5: AbusePredefinedReasonsString[] = [ 'violentOrRepulsive', 'captions' ] | ||
299 | const createdAbuse = (await reportVideoAbuse( | ||
300 | servers[0].url, | ||
301 | servers[0].accessToken, | ||
302 | servers[0].video.id, | ||
303 | reason5, | ||
304 | predefinedReasons5, | ||
305 | 1, | ||
306 | 5 | ||
307 | )).body.abuse | ||
308 | |||
309 | const res = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken }) | ||
310 | |||
311 | { | ||
312 | const abuse = (res.body.data as Abuse[]).find(a => a.id === createdAbuse.id) | ||
313 | expect(abuse.reason).to.equals(reason5) | ||
314 | expect(abuse.predefinedReasons).to.deep.equals(predefinedReasons5, "predefined reasons do not match the one reported") | ||
315 | expect(abuse.video.startAt).to.equal(1, "starting timestamp doesn't match the one reported") | ||
316 | expect(abuse.video.endAt).to.equal(5, "ending timestamp doesn't match the one reported") | ||
317 | } | ||
318 | }) | ||
319 | |||
320 | it('Should delete the video abuse', async function () { | ||
321 | this.timeout(10000) | ||
322 | |||
323 | await deleteVideoAbuse(servers[1].url, servers[1].accessToken, abuseServer2.video.uuid, abuseServer2.id) | ||
324 | |||
325 | await waitJobs(servers) | ||
326 | |||
327 | { | ||
328 | const res = await getVideoAbusesList({ url: servers[1].url, token: servers[1].accessToken }) | ||
329 | expect(res.body.total).to.equal(1) | ||
330 | expect(res.body.data.length).to.equal(1) | ||
331 | expect(res.body.data[0].id).to.not.equal(abuseServer2.id) | ||
332 | } | ||
333 | |||
334 | { | ||
335 | const res = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken }) | ||
336 | expect(res.body.total).to.equal(6) | ||
337 | } | ||
338 | }) | ||
339 | |||
340 | it('Should list and filter video abuses', async function () { | ||
341 | async function list (query: Omit<Parameters<typeof getVideoAbusesList>[0], 'url' | 'token'>) { | ||
342 | const options = { | ||
343 | url: servers[0].url, | ||
344 | token: servers[0].accessToken | ||
345 | } | ||
346 | |||
347 | Object.assign(options, query) | ||
348 | |||
349 | const res = await getVideoAbusesList(options) | ||
350 | |||
351 | return res.body.data as Abuse[] | ||
352 | } | ||
353 | |||
354 | expect(await list({ id: 56 })).to.have.lengthOf(0) | ||
355 | expect(await list({ id: 1 })).to.have.lengthOf(1) | ||
356 | |||
357 | expect(await list({ search: 'my super name for server 1' })).to.have.lengthOf(4) | ||
358 | expect(await list({ search: 'aaaaaaaaaaaaaaaaaaaaaaaaaa' })).to.have.lengthOf(0) | ||
359 | |||
360 | expect(await list({ searchVideo: 'my second super name for server 1' })).to.have.lengthOf(1) | ||
361 | |||
362 | expect(await list({ searchVideoChannel: 'root' })).to.have.lengthOf(4) | ||
363 | expect(await list({ searchVideoChannel: 'aaaa' })).to.have.lengthOf(0) | ||
364 | |||
365 | expect(await list({ searchReporter: 'user2' })).to.have.lengthOf(1) | ||
366 | expect(await list({ searchReporter: 'root' })).to.have.lengthOf(5) | ||
367 | |||
368 | expect(await list({ searchReportee: 'root' })).to.have.lengthOf(5) | ||
369 | expect(await list({ searchReportee: 'aaaa' })).to.have.lengthOf(0) | ||
370 | |||
371 | expect(await list({ videoIs: 'deleted' })).to.have.lengthOf(1) | ||
372 | expect(await list({ videoIs: 'blacklisted' })).to.have.lengthOf(0) | ||
373 | |||
374 | expect(await list({ state: AbuseState.ACCEPTED })).to.have.lengthOf(0) | ||
375 | expect(await list({ state: AbuseState.PENDING })).to.have.lengthOf(6) | ||
376 | |||
377 | expect(await list({ predefinedReason: 'violentOrRepulsive' })).to.have.lengthOf(1) | ||
378 | expect(await list({ predefinedReason: 'serverRules' })).to.have.lengthOf(0) | ||
379 | }) | ||
380 | |||
381 | after(async function () { | ||
382 | await cleanupTests(servers) | ||
383 | }) | ||
384 | }) | ||
diff --git a/server/tests/api/moderation/blocklist.ts b/server/tests/api/moderation/blocklist.ts new file mode 100644 index 000000000..8c9107a50 --- /dev/null +++ b/server/tests/api/moderation/blocklist.ts | |||
@@ -0,0 +1,828 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | ||
2 | |||
3 | import * as chai from 'chai' | ||
4 | import 'mocha' | ||
5 | import { AccountBlock, ServerBlock, Video, UserNotification, UserNotificationType } from '../../../../shared/index' | ||
6 | import { | ||
7 | cleanupTests, | ||
8 | createUser, | ||
9 | deleteVideoComment, | ||
10 | doubleFollow, | ||
11 | flushAndRunMultipleServers, | ||
12 | ServerInfo, | ||
13 | uploadVideo, | ||
14 | userLogin, | ||
15 | follow, | ||
16 | unfollow | ||
17 | } from '../../../../shared/extra-utils/index' | ||
18 | import { setAccessTokensToServers } from '../../../../shared/extra-utils/users/login' | ||
19 | import { getVideosList, getVideosListWithToken } from '../../../../shared/extra-utils/videos/videos' | ||
20 | import { | ||
21 | addVideoCommentReply, | ||
22 | addVideoCommentThread, | ||
23 | getVideoCommentThreads, | ||
24 | getVideoThreadComments, | ||
25 | findCommentId | ||
26 | } from '../../../../shared/extra-utils/videos/video-comments' | ||
27 | import { waitJobs } from '../../../../shared/extra-utils/server/jobs' | ||
28 | import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' | ||
29 | import { | ||
30 | addAccountToAccountBlocklist, | ||
31 | addAccountToServerBlocklist, | ||
32 | addServerToAccountBlocklist, | ||
33 | addServerToServerBlocklist, | ||
34 | getAccountBlocklistByAccount, | ||
35 | getAccountBlocklistByServer, | ||
36 | getServerBlocklistByAccount, | ||
37 | getServerBlocklistByServer, | ||
38 | removeAccountFromAccountBlocklist, | ||
39 | removeAccountFromServerBlocklist, | ||
40 | removeServerFromAccountBlocklist, | ||
41 | removeServerFromServerBlocklist | ||
42 | } from '../../../../shared/extra-utils/users/blocklist' | ||
43 | import { getUserNotifications } from '../../../../shared/extra-utils/users/user-notifications' | ||
44 | |||
45 | const expect = chai.expect | ||
46 | |||
47 | async function checkAllVideos (url: string, token: string) { | ||
48 | { | ||
49 | const res = await getVideosListWithToken(url, token) | ||
50 | |||
51 | expect(res.body.data).to.have.lengthOf(5) | ||
52 | } | ||
53 | |||
54 | { | ||
55 | const res = await getVideosList(url) | ||
56 | |||
57 | expect(res.body.data).to.have.lengthOf(5) | ||
58 | } | ||
59 | } | ||
60 | |||
61 | async function checkAllComments (url: string, token: string, videoUUID: string) { | ||
62 | const resThreads = await getVideoCommentThreads(url, videoUUID, 0, 25, '-createdAt', token) | ||
63 | |||
64 | const allThreads: VideoComment[] = resThreads.body.data | ||
65 | const threads = allThreads.filter(t => t.isDeleted === false) | ||
66 | expect(threads).to.have.lengthOf(2) | ||
67 | |||
68 | for (const thread of threads) { | ||
69 | const res = await getVideoThreadComments(url, videoUUID, thread.id, token) | ||
70 | |||
71 | const tree: VideoCommentThreadTree = res.body | ||
72 | expect(tree.children).to.have.lengthOf(1) | ||
73 | } | ||
74 | } | ||
75 | |||
76 | async function checkCommentNotification ( | ||
77 | mainServer: ServerInfo, | ||
78 | comment: { server: ServerInfo, token: string, videoUUID: string, text: string }, | ||
79 | check: 'presence' | 'absence' | ||
80 | ) { | ||
81 | const resComment = await addVideoCommentThread(comment.server.url, comment.token, comment.videoUUID, comment.text) | ||
82 | const created = resComment.body.comment as VideoComment | ||
83 | const threadId = created.id | ||
84 | const createdAt = created.createdAt | ||
85 | |||
86 | await waitJobs([ mainServer, comment.server ]) | ||
87 | |||
88 | const res = await getUserNotifications(mainServer.url, mainServer.accessToken, 0, 30) | ||
89 | const commentNotifications = (res.body.data as UserNotification[]) | ||
90 | .filter(n => n.comment && n.comment.video.uuid === comment.videoUUID && n.createdAt >= createdAt) | ||
91 | |||
92 | if (check === 'presence') expect(commentNotifications).to.have.lengthOf(1) | ||
93 | else expect(commentNotifications).to.have.lengthOf(0) | ||
94 | |||
95 | await deleteVideoComment(comment.server.url, comment.token, comment.videoUUID, threadId) | ||
96 | |||
97 | await waitJobs([ mainServer, comment.server ]) | ||
98 | } | ||
99 | |||
100 | describe('Test blocklist', function () { | ||
101 | let servers: ServerInfo[] | ||
102 | let videoUUID1: string | ||
103 | let videoUUID2: string | ||
104 | let videoUUID3: string | ||
105 | let userToken1: string | ||
106 | let userModeratorToken: string | ||
107 | let userToken2: string | ||
108 | |||
109 | before(async function () { | ||
110 | this.timeout(60000) | ||
111 | |||
112 | servers = await flushAndRunMultipleServers(3) | ||
113 | await setAccessTokensToServers(servers) | ||
114 | |||
115 | { | ||
116 | const user = { username: 'user1', password: 'password' } | ||
117 | await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: user.username, password: user.password }) | ||
118 | |||
119 | userToken1 = await userLogin(servers[0], user) | ||
120 | await uploadVideo(servers[0].url, userToken1, { name: 'video user 1' }) | ||
121 | } | ||
122 | |||
123 | { | ||
124 | const user = { username: 'moderator', password: 'password' } | ||
125 | await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: user.username, password: user.password }) | ||
126 | |||
127 | userModeratorToken = await userLogin(servers[0], user) | ||
128 | } | ||
129 | |||
130 | { | ||
131 | const user = { username: 'user2', password: 'password' } | ||
132 | await createUser({ url: servers[1].url, accessToken: servers[1].accessToken, username: user.username, password: user.password }) | ||
133 | |||
134 | userToken2 = await userLogin(servers[1], user) | ||
135 | await uploadVideo(servers[1].url, userToken2, { name: 'video user 2' }) | ||
136 | } | ||
137 | |||
138 | { | ||
139 | const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video server 1' }) | ||
140 | videoUUID1 = res.body.video.uuid | ||
141 | } | ||
142 | |||
143 | { | ||
144 | const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video server 2' }) | ||
145 | videoUUID2 = res.body.video.uuid | ||
146 | } | ||
147 | |||
148 | { | ||
149 | const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video 2 server 1' }) | ||
150 | videoUUID3 = res.body.video.uuid | ||
151 | } | ||
152 | |||
153 | await doubleFollow(servers[0], servers[1]) | ||
154 | await doubleFollow(servers[0], servers[2]) | ||
155 | |||
156 | { | ||
157 | const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID1, 'comment root 1') | ||
158 | const resReply = await addVideoCommentReply(servers[0].url, userToken1, videoUUID1, resComment.body.comment.id, 'comment user 1') | ||
159 | await addVideoCommentReply(servers[0].url, servers[0].accessToken, videoUUID1, resReply.body.comment.id, 'comment root 1') | ||
160 | } | ||
161 | |||
162 | { | ||
163 | const resComment = await addVideoCommentThread(servers[0].url, userToken1, videoUUID1, 'comment user 1') | ||
164 | await addVideoCommentReply(servers[0].url, servers[0].accessToken, videoUUID1, resComment.body.comment.id, 'comment root 1') | ||
165 | } | ||
166 | |||
167 | await waitJobs(servers) | ||
168 | }) | ||
169 | |||
170 | describe('User blocklist', function () { | ||
171 | |||
172 | describe('When managing account blocklist', function () { | ||
173 | it('Should list all videos', function () { | ||
174 | return checkAllVideos(servers[0].url, servers[0].accessToken) | ||
175 | }) | ||
176 | |||
177 | it('Should list the comments', function () { | ||
178 | return checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1) | ||
179 | }) | ||
180 | |||
181 | it('Should block a remote account', async function () { | ||
182 | await addAccountToAccountBlocklist(servers[0].url, servers[0].accessToken, 'user2@localhost:' + servers[1].port) | ||
183 | }) | ||
184 | |||
185 | it('Should hide its videos', async function () { | ||
186 | const res = await getVideosListWithToken(servers[0].url, servers[0].accessToken) | ||
187 | |||
188 | const videos: Video[] = res.body.data | ||
189 | expect(videos).to.have.lengthOf(4) | ||
190 | |||
191 | const v = videos.find(v => v.name === 'video user 2') | ||
192 | expect(v).to.be.undefined | ||
193 | }) | ||
194 | |||
195 | it('Should block a local account', async function () { | ||
196 | await addAccountToAccountBlocklist(servers[0].url, servers[0].accessToken, 'user1') | ||
197 | }) | ||
198 | |||
199 | it('Should hide its videos', async function () { | ||
200 | const res = await getVideosListWithToken(servers[0].url, servers[0].accessToken) | ||
201 | |||
202 | const videos: Video[] = res.body.data | ||
203 | expect(videos).to.have.lengthOf(3) | ||
204 | |||
205 | const v = videos.find(v => v.name === 'video user 1') | ||
206 | expect(v).to.be.undefined | ||
207 | }) | ||
208 | |||
209 | it('Should hide its comments', async function () { | ||
210 | const resThreads = await getVideoCommentThreads(servers[0].url, videoUUID1, 0, 25, '-createdAt', servers[0].accessToken) | ||
211 | |||
212 | const threads: VideoComment[] = resThreads.body.data | ||
213 | expect(threads).to.have.lengthOf(1) | ||
214 | expect(threads[0].totalReplies).to.equal(0) | ||
215 | |||
216 | const t = threads.find(t => t.text === 'comment user 1') | ||
217 | expect(t).to.be.undefined | ||
218 | |||
219 | for (const thread of threads) { | ||
220 | const res = await getVideoThreadComments(servers[0].url, videoUUID1, thread.id, servers[0].accessToken) | ||
221 | |||
222 | const tree: VideoCommentThreadTree = res.body | ||
223 | expect(tree.children).to.have.lengthOf(0) | ||
224 | } | ||
225 | }) | ||
226 | |||
227 | it('Should not have notifications from blocked accounts', async function () { | ||
228 | this.timeout(20000) | ||
229 | |||
230 | { | ||
231 | const comment = { server: servers[0], token: userToken1, videoUUID: videoUUID1, text: 'hidden comment' } | ||
232 | await checkCommentNotification(servers[0], comment, 'absence') | ||
233 | } | ||
234 | |||
235 | { | ||
236 | const comment = { | ||
237 | server: servers[0], | ||
238 | token: userToken1, | ||
239 | videoUUID: videoUUID2, | ||
240 | text: 'hello @root@localhost:' + servers[0].port | ||
241 | } | ||
242 | await checkCommentNotification(servers[0], comment, 'absence') | ||
243 | } | ||
244 | }) | ||
245 | |||
246 | it('Should list all the videos with another user', async function () { | ||
247 | return checkAllVideos(servers[0].url, userToken1) | ||
248 | }) | ||
249 | |||
250 | it('Should list blocked accounts', async function () { | ||
251 | { | ||
252 | const res = await getAccountBlocklistByAccount(servers[0].url, servers[0].accessToken, 0, 1, 'createdAt') | ||
253 | const blocks: AccountBlock[] = res.body.data | ||
254 | |||
255 | expect(res.body.total).to.equal(2) | ||
256 | |||
257 | const block = blocks[0] | ||
258 | expect(block.byAccount.displayName).to.equal('root') | ||
259 | expect(block.byAccount.name).to.equal('root') | ||
260 | expect(block.blockedAccount.displayName).to.equal('user2') | ||
261 | expect(block.blockedAccount.name).to.equal('user2') | ||
262 | expect(block.blockedAccount.host).to.equal('localhost:' + servers[1].port) | ||
263 | } | ||
264 | |||
265 | { | ||
266 | const res = await getAccountBlocklistByAccount(servers[0].url, servers[0].accessToken, 1, 2, 'createdAt') | ||
267 | const blocks: AccountBlock[] = res.body.data | ||
268 | |||
269 | expect(res.body.total).to.equal(2) | ||
270 | |||
271 | const block = blocks[0] | ||
272 | expect(block.byAccount.displayName).to.equal('root') | ||
273 | expect(block.byAccount.name).to.equal('root') | ||
274 | expect(block.blockedAccount.displayName).to.equal('user1') | ||
275 | expect(block.blockedAccount.name).to.equal('user1') | ||
276 | expect(block.blockedAccount.host).to.equal('localhost:' + servers[0].port) | ||
277 | } | ||
278 | }) | ||
279 | |||
280 | it('Should not allow a remote blocked user to comment my videos', async function () { | ||
281 | this.timeout(60000) | ||
282 | |||
283 | { | ||
284 | await addVideoCommentThread(servers[1].url, userToken2, videoUUID3, 'comment user 2') | ||
285 | await waitJobs(servers) | ||
286 | |||
287 | await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID3, 'uploader') | ||
288 | await waitJobs(servers) | ||
289 | |||
290 | const commentId = await findCommentId(servers[1].url, videoUUID3, 'uploader') | ||
291 | const message = 'reply by user 2' | ||
292 | const resReply = await addVideoCommentReply(servers[1].url, userToken2, videoUUID3, commentId, message) | ||
293 | await addVideoCommentReply(servers[1].url, servers[1].accessToken, videoUUID3, resReply.body.comment.id, 'another reply') | ||
294 | |||
295 | await waitJobs(servers) | ||
296 | } | ||
297 | |||
298 | // Server 2 has all the comments | ||
299 | { | ||
300 | const resThreads = await getVideoCommentThreads(servers[1].url, videoUUID3, 0, 25, '-createdAt') | ||
301 | const threads: VideoComment[] = resThreads.body.data | ||
302 | |||
303 | expect(threads).to.have.lengthOf(2) | ||
304 | expect(threads[0].text).to.equal('uploader') | ||
305 | expect(threads[1].text).to.equal('comment user 2') | ||
306 | |||
307 | const resReplies = await getVideoThreadComments(servers[1].url, videoUUID3, threads[0].id) | ||
308 | |||
309 | const tree: VideoCommentThreadTree = resReplies.body | ||
310 | expect(tree.children).to.have.lengthOf(1) | ||
311 | expect(tree.children[0].comment.text).to.equal('reply by user 2') | ||
312 | expect(tree.children[0].children).to.have.lengthOf(1) | ||
313 | expect(tree.children[0].children[0].comment.text).to.equal('another reply') | ||
314 | } | ||
315 | |||
316 | // Server 1 and 3 should only have uploader comments | ||
317 | for (const server of [ servers[0], servers[2] ]) { | ||
318 | const resThreads = await getVideoCommentThreads(server.url, videoUUID3, 0, 25, '-createdAt') | ||
319 | const threads: VideoComment[] = resThreads.body.data | ||
320 | |||
321 | expect(threads).to.have.lengthOf(1) | ||
322 | expect(threads[0].text).to.equal('uploader') | ||
323 | |||
324 | const resReplies = await getVideoThreadComments(server.url, videoUUID3, threads[0].id) | ||
325 | |||
326 | const tree: VideoCommentThreadTree = resReplies.body | ||
327 | if (server.serverNumber === 1) { | ||
328 | expect(tree.children).to.have.lengthOf(0) | ||
329 | } else { | ||
330 | expect(tree.children).to.have.lengthOf(1) | ||
331 | } | ||
332 | } | ||
333 | }) | ||
334 | |||
335 | it('Should unblock the remote account', async function () { | ||
336 | await removeAccountFromAccountBlocklist(servers[0].url, servers[0].accessToken, 'user2@localhost:' + servers[1].port) | ||
337 | }) | ||
338 | |||
339 | it('Should display its videos', async function () { | ||
340 | const res = await getVideosListWithToken(servers[0].url, servers[0].accessToken) | ||
341 | |||
342 | const videos: Video[] = res.body.data | ||
343 | expect(videos).to.have.lengthOf(4) | ||
344 | |||
345 | const v = videos.find(v => v.name === 'video user 2') | ||
346 | expect(v).not.to.be.undefined | ||
347 | }) | ||
348 | |||
349 | it('Should display its comments on my video', async function () { | ||
350 | for (const server of servers) { | ||
351 | const resThreads = await getVideoCommentThreads(server.url, videoUUID3, 0, 25, '-createdAt') | ||
352 | const threads: VideoComment[] = resThreads.body.data | ||
353 | |||
354 | // Server 3 should not have 2 comment threads, because server 1 did not forward the server 2 comment | ||
355 | if (server.serverNumber === 3) { | ||
356 | expect(threads).to.have.lengthOf(1) | ||
357 | continue | ||
358 | } | ||
359 | |||
360 | expect(threads).to.have.lengthOf(2) | ||
361 | expect(threads[0].text).to.equal('uploader') | ||
362 | expect(threads[1].text).to.equal('comment user 2') | ||
363 | |||
364 | const resReplies = await getVideoThreadComments(server.url, videoUUID3, threads[0].id) | ||
365 | |||
366 | const tree: VideoCommentThreadTree = resReplies.body | ||
367 | expect(tree.children).to.have.lengthOf(1) | ||
368 | expect(tree.children[0].comment.text).to.equal('reply by user 2') | ||
369 | expect(tree.children[0].children).to.have.lengthOf(1) | ||
370 | expect(tree.children[0].children[0].comment.text).to.equal('another reply') | ||
371 | } | ||
372 | }) | ||
373 | |||
374 | it('Should unblock the local account', async function () { | ||
375 | await removeAccountFromAccountBlocklist(servers[0].url, servers[0].accessToken, 'user1') | ||
376 | }) | ||
377 | |||
378 | it('Should display its comments', function () { | ||
379 | return checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1) | ||
380 | }) | ||
381 | |||
382 | it('Should have a notification from a non blocked account', async function () { | ||
383 | this.timeout(20000) | ||
384 | |||
385 | { | ||
386 | const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'displayed comment' } | ||
387 | await checkCommentNotification(servers[0], comment, 'presence') | ||
388 | } | ||
389 | |||
390 | { | ||
391 | const comment = { | ||
392 | server: servers[0], | ||
393 | token: userToken1, | ||
394 | videoUUID: videoUUID2, | ||
395 | text: 'hello @root@localhost:' + servers[0].port | ||
396 | } | ||
397 | await checkCommentNotification(servers[0], comment, 'presence') | ||
398 | } | ||
399 | }) | ||
400 | }) | ||
401 | |||
402 | describe('When managing server blocklist', function () { | ||
403 | it('Should list all videos', function () { | ||
404 | return checkAllVideos(servers[0].url, servers[0].accessToken) | ||
405 | }) | ||
406 | |||
407 | it('Should list the comments', function () { | ||
408 | return checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1) | ||
409 | }) | ||
410 | |||
411 | it('Should block a remote server', async function () { | ||
412 | await addServerToAccountBlocklist(servers[0].url, servers[0].accessToken, 'localhost:' + servers[1].port) | ||
413 | }) | ||
414 | |||
415 | it('Should hide its videos', async function () { | ||
416 | const res = await getVideosListWithToken(servers[0].url, servers[0].accessToken) | ||
417 | |||
418 | const videos: Video[] = res.body.data | ||
419 | expect(videos).to.have.lengthOf(3) | ||
420 | |||
421 | const v1 = videos.find(v => v.name === 'video user 2') | ||
422 | const v2 = videos.find(v => v.name === 'video server 2') | ||
423 | |||
424 | expect(v1).to.be.undefined | ||
425 | expect(v2).to.be.undefined | ||
426 | }) | ||
427 | |||
428 | it('Should list all the videos with another user', async function () { | ||
429 | return checkAllVideos(servers[0].url, userToken1) | ||
430 | }) | ||
431 | |||
432 | it('Should hide its comments', async function () { | ||
433 | this.timeout(10000) | ||
434 | |||
435 | const resThreads = await addVideoCommentThread(servers[1].url, userToken2, videoUUID1, 'hidden comment 2') | ||
436 | const threadId = resThreads.body.comment.id | ||
437 | |||
438 | await waitJobs(servers) | ||
439 | |||
440 | await checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1) | ||
441 | |||
442 | await deleteVideoComment(servers[1].url, userToken2, videoUUID1, threadId) | ||
443 | }) | ||
444 | |||
445 | it('Should not have notifications from blocked server', async function () { | ||
446 | this.timeout(20000) | ||
447 | |||
448 | { | ||
449 | const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'hidden comment' } | ||
450 | await checkCommentNotification(servers[0], comment, 'absence') | ||
451 | } | ||
452 | |||
453 | { | ||
454 | const comment = { | ||
455 | server: servers[1], | ||
456 | token: userToken2, | ||
457 | videoUUID: videoUUID1, | ||
458 | text: 'hello @root@localhost:' + servers[0].port | ||
459 | } | ||
460 | await checkCommentNotification(servers[0], comment, 'absence') | ||
461 | } | ||
462 | }) | ||
463 | |||
464 | it('Should list blocked servers', async function () { | ||
465 | const res = await getServerBlocklistByAccount(servers[0].url, servers[0].accessToken, 0, 1, 'createdAt') | ||
466 | const blocks: ServerBlock[] = res.body.data | ||
467 | |||
468 | expect(res.body.total).to.equal(1) | ||
469 | |||
470 | const block = blocks[0] | ||
471 | expect(block.byAccount.displayName).to.equal('root') | ||
472 | expect(block.byAccount.name).to.equal('root') | ||
473 | expect(block.blockedServer.host).to.equal('localhost:' + servers[1].port) | ||
474 | }) | ||
475 | |||
476 | it('Should unblock the remote server', async function () { | ||
477 | await removeServerFromAccountBlocklist(servers[0].url, servers[0].accessToken, 'localhost:' + servers[1].port) | ||
478 | }) | ||
479 | |||
480 | it('Should display its videos', function () { | ||
481 | return checkAllVideos(servers[0].url, servers[0].accessToken) | ||
482 | }) | ||
483 | |||
484 | it('Should display its comments', function () { | ||
485 | return checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1) | ||
486 | }) | ||
487 | |||
488 | it('Should have notification from unblocked server', async function () { | ||
489 | this.timeout(20000) | ||
490 | |||
491 | { | ||
492 | const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'displayed comment' } | ||
493 | await checkCommentNotification(servers[0], comment, 'presence') | ||
494 | } | ||
495 | |||
496 | { | ||
497 | const comment = { | ||
498 | server: servers[1], | ||
499 | token: userToken2, | ||
500 | videoUUID: videoUUID1, | ||
501 | text: 'hello @root@localhost:' + servers[0].port | ||
502 | } | ||
503 | await checkCommentNotification(servers[0], comment, 'presence') | ||
504 | } | ||
505 | }) | ||
506 | }) | ||
507 | }) | ||
508 | |||
509 | describe('Server blocklist', function () { | ||
510 | |||
511 | describe('When managing account blocklist', function () { | ||
512 | it('Should list all videos', async function () { | ||
513 | for (const token of [ userModeratorToken, servers[0].accessToken ]) { | ||
514 | await checkAllVideos(servers[0].url, token) | ||
515 | } | ||
516 | }) | ||
517 | |||
518 | it('Should list the comments', async function () { | ||
519 | for (const token of [ userModeratorToken, servers[0].accessToken ]) { | ||
520 | await checkAllComments(servers[0].url, token, videoUUID1) | ||
521 | } | ||
522 | }) | ||
523 | |||
524 | it('Should block a remote account', async function () { | ||
525 | await addAccountToServerBlocklist(servers[0].url, servers[0].accessToken, 'user2@localhost:' + servers[1].port) | ||
526 | }) | ||
527 | |||
528 | it('Should hide its videos', async function () { | ||
529 | for (const token of [ userModeratorToken, servers[0].accessToken ]) { | ||
530 | const res = await getVideosListWithToken(servers[0].url, token) | ||
531 | |||
532 | const videos: Video[] = res.body.data | ||
533 | expect(videos).to.have.lengthOf(4) | ||
534 | |||
535 | const v = videos.find(v => v.name === 'video user 2') | ||
536 | expect(v).to.be.undefined | ||
537 | } | ||
538 | }) | ||
539 | |||
540 | it('Should block a local account', async function () { | ||
541 | await addAccountToServerBlocklist(servers[0].url, servers[0].accessToken, 'user1') | ||
542 | }) | ||
543 | |||
544 | it('Should hide its videos', async function () { | ||
545 | for (const token of [ userModeratorToken, servers[0].accessToken ]) { | ||
546 | const res = await getVideosListWithToken(servers[0].url, token) | ||
547 | |||
548 | const videos: Video[] = res.body.data | ||
549 | expect(videos).to.have.lengthOf(3) | ||
550 | |||
551 | const v = videos.find(v => v.name === 'video user 1') | ||
552 | expect(v).to.be.undefined | ||
553 | } | ||
554 | }) | ||
555 | |||
556 | it('Should hide its comments', async function () { | ||
557 | for (const token of [ userModeratorToken, servers[0].accessToken ]) { | ||
558 | const resThreads = await getVideoCommentThreads(servers[0].url, videoUUID1, 0, 20, '-createdAt', token) | ||
559 | |||
560 | let threads: VideoComment[] = resThreads.body.data | ||
561 | threads = threads.filter(t => t.isDeleted === false) | ||
562 | |||
563 | expect(threads).to.have.lengthOf(1) | ||
564 | expect(threads[0].totalReplies).to.equal(0) | ||
565 | |||
566 | const t = threads.find(t => t.text === 'comment user 1') | ||
567 | expect(t).to.be.undefined | ||
568 | |||
569 | for (const thread of threads) { | ||
570 | const res = await getVideoThreadComments(servers[0].url, videoUUID1, thread.id, token) | ||
571 | |||
572 | const tree: VideoCommentThreadTree = res.body | ||
573 | expect(tree.children).to.have.lengthOf(0) | ||
574 | } | ||
575 | } | ||
576 | }) | ||
577 | |||
578 | it('Should not have notification from blocked accounts by instance', async function () { | ||
579 | this.timeout(20000) | ||
580 | |||
581 | { | ||
582 | const comment = { server: servers[0], token: userToken1, videoUUID: videoUUID1, text: 'hidden comment' } | ||
583 | await checkCommentNotification(servers[0], comment, 'absence') | ||
584 | } | ||
585 | |||
586 | { | ||
587 | const comment = { | ||
588 | server: servers[1], | ||
589 | token: userToken2, | ||
590 | videoUUID: videoUUID1, | ||
591 | text: 'hello @root@localhost:' + servers[0].port | ||
592 | } | ||
593 | await checkCommentNotification(servers[0], comment, 'absence') | ||
594 | } | ||
595 | }) | ||
596 | |||
597 | it('Should list blocked accounts', async function () { | ||
598 | { | ||
599 | const res = await getAccountBlocklistByServer(servers[0].url, servers[0].accessToken, 0, 1, 'createdAt') | ||
600 | const blocks: AccountBlock[] = res.body.data | ||
601 | |||
602 | expect(res.body.total).to.equal(2) | ||
603 | |||
604 | const block = blocks[0] | ||
605 | expect(block.byAccount.displayName).to.equal('peertube') | ||
606 | expect(block.byAccount.name).to.equal('peertube') | ||
607 | expect(block.blockedAccount.displayName).to.equal('user2') | ||
608 | expect(block.blockedAccount.name).to.equal('user2') | ||
609 | expect(block.blockedAccount.host).to.equal('localhost:' + servers[1].port) | ||
610 | } | ||
611 | |||
612 | { | ||
613 | const res = await getAccountBlocklistByServer(servers[0].url, servers[0].accessToken, 1, 2, 'createdAt') | ||
614 | const blocks: AccountBlock[] = res.body.data | ||
615 | |||
616 | expect(res.body.total).to.equal(2) | ||
617 | |||
618 | const block = blocks[0] | ||
619 | expect(block.byAccount.displayName).to.equal('peertube') | ||
620 | expect(block.byAccount.name).to.equal('peertube') | ||
621 | expect(block.blockedAccount.displayName).to.equal('user1') | ||
622 | expect(block.blockedAccount.name).to.equal('user1') | ||
623 | expect(block.blockedAccount.host).to.equal('localhost:' + servers[0].port) | ||
624 | } | ||
625 | }) | ||
626 | |||
627 | it('Should unblock the remote account', async function () { | ||
628 | await removeAccountFromServerBlocklist(servers[0].url, servers[0].accessToken, 'user2@localhost:' + servers[1].port) | ||
629 | }) | ||
630 | |||
631 | it('Should display its videos', async function () { | ||
632 | for (const token of [ userModeratorToken, servers[0].accessToken ]) { | ||
633 | const res = await getVideosListWithToken(servers[0].url, token) | ||
634 | |||
635 | const videos: Video[] = res.body.data | ||
636 | expect(videos).to.have.lengthOf(4) | ||
637 | |||
638 | const v = videos.find(v => v.name === 'video user 2') | ||
639 | expect(v).not.to.be.undefined | ||
640 | } | ||
641 | }) | ||
642 | |||
643 | it('Should unblock the local account', async function () { | ||
644 | await removeAccountFromServerBlocklist(servers[0].url, servers[0].accessToken, 'user1') | ||
645 | }) | ||
646 | |||
647 | it('Should display its comments', async function () { | ||
648 | for (const token of [ userModeratorToken, servers[0].accessToken ]) { | ||
649 | await checkAllComments(servers[0].url, token, videoUUID1) | ||
650 | } | ||
651 | }) | ||
652 | |||
653 | it('Should have notifications from unblocked accounts', async function () { | ||
654 | this.timeout(20000) | ||
655 | |||
656 | { | ||
657 | const comment = { server: servers[0], token: userToken1, videoUUID: videoUUID1, text: 'displayed comment' } | ||
658 | await checkCommentNotification(servers[0], comment, 'presence') | ||
659 | } | ||
660 | |||
661 | { | ||
662 | const comment = { | ||
663 | server: servers[1], | ||
664 | token: userToken2, | ||
665 | videoUUID: videoUUID1, | ||
666 | text: 'hello @root@localhost:' + servers[0].port | ||
667 | } | ||
668 | await checkCommentNotification(servers[0], comment, 'presence') | ||
669 | } | ||
670 | }) | ||
671 | }) | ||
672 | |||
673 | describe('When managing server blocklist', function () { | ||
674 | it('Should list all videos', async function () { | ||
675 | for (const token of [ userModeratorToken, servers[0].accessToken ]) { | ||
676 | await checkAllVideos(servers[0].url, token) | ||
677 | } | ||
678 | }) | ||
679 | |||
680 | it('Should list the comments', async function () { | ||
681 | for (const token of [ userModeratorToken, servers[0].accessToken ]) { | ||
682 | await checkAllComments(servers[0].url, token, videoUUID1) | ||
683 | } | ||
684 | }) | ||
685 | |||
686 | it('Should block a remote server', async function () { | ||
687 | await addServerToServerBlocklist(servers[0].url, servers[0].accessToken, 'localhost:' + servers[1].port) | ||
688 | }) | ||
689 | |||
690 | it('Should hide its videos', async function () { | ||
691 | for (const token of [ userModeratorToken, servers[0].accessToken ]) { | ||
692 | const res1 = await getVideosList(servers[0].url) | ||
693 | const res2 = await getVideosListWithToken(servers[0].url, token) | ||
694 | |||
695 | for (const res of [ res1, res2 ]) { | ||
696 | const videos: Video[] = res.body.data | ||
697 | expect(videos).to.have.lengthOf(3) | ||
698 | |||
699 | const v1 = videos.find(v => v.name === 'video user 2') | ||
700 | const v2 = videos.find(v => v.name === 'video server 2') | ||
701 | |||
702 | expect(v1).to.be.undefined | ||
703 | expect(v2).to.be.undefined | ||
704 | } | ||
705 | } | ||
706 | }) | ||
707 | |||
708 | it('Should hide its comments', async function () { | ||
709 | this.timeout(10000) | ||
710 | |||
711 | const resThreads = await addVideoCommentThread(servers[1].url, userToken2, videoUUID1, 'hidden comment 2') | ||
712 | const threadId = resThreads.body.comment.id | ||
713 | |||
714 | await waitJobs(servers) | ||
715 | |||
716 | await checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1) | ||
717 | |||
718 | await deleteVideoComment(servers[1].url, userToken2, videoUUID1, threadId) | ||
719 | }) | ||
720 | |||
721 | it('Should not have notification from blocked instances by instance', async function () { | ||
722 | this.timeout(50000) | ||
723 | |||
724 | { | ||
725 | const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'hidden comment' } | ||
726 | await checkCommentNotification(servers[0], comment, 'absence') | ||
727 | } | ||
728 | |||
729 | { | ||
730 | const comment = { | ||
731 | server: servers[1], | ||
732 | token: userToken2, | ||
733 | videoUUID: videoUUID1, | ||
734 | text: 'hello @root@localhost:' + servers[0].port | ||
735 | } | ||
736 | await checkCommentNotification(servers[0], comment, 'absence') | ||
737 | } | ||
738 | |||
739 | { | ||
740 | const now = new Date() | ||
741 | await unfollow(servers[1].url, servers[1].accessToken, servers[0]) | ||
742 | await waitJobs(servers) | ||
743 | await follow(servers[1].url, [ servers[0].host ], servers[1].accessToken) | ||
744 | |||
745 | await waitJobs(servers) | ||
746 | |||
747 | const res = await getUserNotifications(servers[0].url, servers[0].accessToken, 0, 30) | ||
748 | const commentNotifications = (res.body.data as UserNotification[]) | ||
749 | .filter(n => { | ||
750 | return n.type === UserNotificationType.NEW_INSTANCE_FOLLOWER && | ||
751 | n.createdAt >= now.toISOString() | ||
752 | }) | ||
753 | |||
754 | expect(commentNotifications).to.have.lengthOf(0) | ||
755 | } | ||
756 | }) | ||
757 | |||
758 | it('Should list blocked servers', async function () { | ||
759 | const res = await getServerBlocklistByServer(servers[0].url, servers[0].accessToken, 0, 1, 'createdAt') | ||
760 | const blocks: ServerBlock[] = res.body.data | ||
761 | |||
762 | expect(res.body.total).to.equal(1) | ||
763 | |||
764 | const block = blocks[0] | ||
765 | expect(block.byAccount.displayName).to.equal('peertube') | ||
766 | expect(block.byAccount.name).to.equal('peertube') | ||
767 | expect(block.blockedServer.host).to.equal('localhost:' + servers[1].port) | ||
768 | }) | ||
769 | |||
770 | it('Should unblock the remote server', async function () { | ||
771 | await removeServerFromServerBlocklist(servers[0].url, servers[0].accessToken, 'localhost:' + servers[1].port) | ||
772 | }) | ||
773 | |||
774 | it('Should list all videos', async function () { | ||
775 | for (const token of [ userModeratorToken, servers[0].accessToken ]) { | ||
776 | await checkAllVideos(servers[0].url, token) | ||
777 | } | ||
778 | }) | ||
779 | |||
780 | it('Should list the comments', async function () { | ||
781 | for (const token of [ userModeratorToken, servers[0].accessToken ]) { | ||
782 | await checkAllComments(servers[0].url, token, videoUUID1) | ||
783 | } | ||
784 | }) | ||
785 | |||
786 | it('Should have notification from unblocked instances', async function () { | ||
787 | this.timeout(50000) | ||
788 | |||
789 | { | ||
790 | const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'displayed comment' } | ||
791 | await checkCommentNotification(servers[0], comment, 'presence') | ||
792 | } | ||
793 | |||
794 | { | ||
795 | const comment = { | ||
796 | server: servers[1], | ||
797 | token: userToken2, | ||
798 | videoUUID: videoUUID1, | ||
799 | text: 'hello @root@localhost:' + servers[0].port | ||
800 | } | ||
801 | await checkCommentNotification(servers[0], comment, 'presence') | ||
802 | } | ||
803 | |||
804 | { | ||
805 | const now = new Date() | ||
806 | await unfollow(servers[1].url, servers[1].accessToken, servers[0]) | ||
807 | await waitJobs(servers) | ||
808 | await follow(servers[1].url, [ servers[0].host ], servers[1].accessToken) | ||
809 | |||
810 | await waitJobs(servers) | ||
811 | |||
812 | const res = await getUserNotifications(servers[0].url, servers[0].accessToken, 0, 30) | ||
813 | const commentNotifications = (res.body.data as UserNotification[]) | ||
814 | .filter(n => { | ||
815 | return n.type === UserNotificationType.NEW_INSTANCE_FOLLOWER && | ||
816 | n.createdAt >= now.toISOString() | ||
817 | }) | ||
818 | |||
819 | expect(commentNotifications).to.have.lengthOf(1) | ||
820 | } | ||
821 | }) | ||
822 | }) | ||
823 | }) | ||
824 | |||
825 | after(async function () { | ||
826 | await cleanupTests(servers) | ||
827 | }) | ||
828 | }) | ||
diff --git a/server/tests/api/moderation/index.ts b/server/tests/api/moderation/index.ts new file mode 100644 index 000000000..cb018d88e --- /dev/null +++ b/server/tests/api/moderation/index.ts | |||
@@ -0,0 +1,2 @@ | |||
1 | export * from './abuses' | ||
2 | export * from './blocklist' | ||