]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/tests/plugins/filter-hooks.ts
b5e29d298580673f6e27d7983ff0f51d0563ac49
[github/Chocobozzz/PeerTube.git] / server / tests / plugins / filter-hooks.ts
1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3 import 'mocha'
4 import * as chai from 'chai'
5 import { HttpStatusCode } from '@shared/core-utils'
6 import {
7 cleanupTests,
8 doubleFollow,
9 flushAndRunMultipleServers,
10 getAccountVideos,
11 getMyVideos,
12 getVideo,
13 getVideoChannelVideos,
14 getVideosList,
15 getVideosListPagination,
16 getVideoWithToken,
17 ImportsCommand,
18 makeRawRequest,
19 PluginsCommand,
20 registerUser,
21 ServerInfo,
22 setAccessTokensToServers,
23 setDefaultVideoChannel,
24 updateVideo,
25 uploadVideo,
26 uploadVideoAndGetId,
27 waitJobs
28 } from '@shared/extra-utils'
29 import { VideoDetails, VideoImportState, VideoPlaylist, VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models'
30
31 const expect = chai.expect
32
33 describe('Test plugin filter hooks', function () {
34 let servers: ServerInfo[]
35 let videoUUID: string
36 let threadId: number
37
38 before(async function () {
39 this.timeout(60000)
40
41 servers = await flushAndRunMultipleServers(2)
42 await setAccessTokensToServers(servers)
43 await setDefaultVideoChannel(servers)
44 await doubleFollow(servers[0], servers[1])
45
46 await servers[0].pluginsCommand.install({ path: PluginsCommand.getPluginTestPath() })
47 await servers[0].pluginsCommand.install({ path: PluginsCommand.getPluginTestPath('-filter-translations') })
48
49 for (let i = 0; i < 10; i++) {
50 await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'default video ' + i })
51 }
52
53 const res = await getVideosList(servers[0].url)
54 videoUUID = res.body.data[0].uuid
55
56 await servers[0].configCommand.updateCustomSubConfig({
57 newConfig: {
58 live: { enabled: true },
59 signup: { enabled: true },
60 import: {
61 videos: {
62 http: { enabled: true },
63 torrent: { enabled: true }
64 }
65 }
66 }
67 })
68 })
69
70 it('Should run filter:api.videos.list.params', async function () {
71 const res = await getVideosListPagination(servers[0].url, 0, 2)
72
73 // 2 plugins do +1 to the count parameter
74 expect(res.body.data).to.have.lengthOf(4)
75 })
76
77 it('Should run filter:api.videos.list.result', async function () {
78 const res = await getVideosListPagination(servers[0].url, 0, 0)
79
80 // Plugin do +1 to the total result
81 expect(res.body.total).to.equal(11)
82 })
83
84 it('Should run filter:api.accounts.videos.list.params', async function () {
85 const res = await getAccountVideos(servers[0].url, servers[0].accessToken, 'root', 0, 2)
86
87 // 1 plugin do +1 to the count parameter
88 expect(res.body.data).to.have.lengthOf(3)
89 })
90
91 it('Should run filter:api.accounts.videos.list.result', async function () {
92 const res = await getAccountVideos(servers[0].url, servers[0].accessToken, 'root', 0, 2)
93
94 // Plugin do +2 to the total result
95 expect(res.body.total).to.equal(12)
96 })
97
98 it('Should run filter:api.video-channels.videos.list.params', async function () {
99 const res = await getVideoChannelVideos(servers[0].url, servers[0].accessToken, 'root_channel', 0, 2)
100
101 // 1 plugin do +3 to the count parameter
102 expect(res.body.data).to.have.lengthOf(5)
103 })
104
105 it('Should run filter:api.video-channels.videos.list.result', async function () {
106 const res = await getVideoChannelVideos(servers[0].url, servers[0].accessToken, 'root_channel', 0, 2)
107
108 // Plugin do +3 to the total result
109 expect(res.body.total).to.equal(13)
110 })
111
112 it('Should run filter:api.user.me.videos.list.params', async function () {
113 const res = await getMyVideos(servers[0].url, servers[0].accessToken, 0, 2)
114
115 // 1 plugin do +4 to the count parameter
116 expect(res.body.data).to.have.lengthOf(6)
117 })
118
119 it('Should run filter:api.user.me.videos.list.result', async function () {
120 const res = await getMyVideos(servers[0].url, servers[0].accessToken, 0, 2)
121
122 // Plugin do +4 to the total result
123 expect(res.body.total).to.equal(14)
124 })
125
126 it('Should run filter:api.video.get.result', async function () {
127 const res = await getVideo(servers[0].url, videoUUID)
128
129 expect(res.body.name).to.contain('<3')
130 })
131
132 it('Should run filter:api.video.upload.accept.result', async function () {
133 await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video with bad word' }, HttpStatusCode.FORBIDDEN_403)
134 })
135
136 it('Should run filter:api.live-video.create.accept.result', async function () {
137 const attributes = {
138 name: 'video with bad word',
139 privacy: VideoPrivacy.PUBLIC,
140 channelId: servers[0].videoChannel.id
141 }
142
143 await servers[0].liveCommand.create({ fields: attributes, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
144 })
145
146 it('Should run filter:api.video.pre-import-url.accept.result', async function () {
147 const attributes = {
148 name: 'normal title',
149 privacy: VideoPrivacy.PUBLIC,
150 channelId: servers[0].videoChannel.id,
151 targetUrl: ImportsCommand.getGoodVideoUrl() + 'bad'
152 }
153 await servers[0].importsCommand.importVideo({ attributes, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
154 })
155
156 it('Should run filter:api.video.pre-import-torrent.accept.result', async function () {
157 const attributes = {
158 name: 'bad torrent',
159 privacy: VideoPrivacy.PUBLIC,
160 channelId: servers[0].videoChannel.id,
161 torrentfile: 'video-720p.torrent' as any
162 }
163 await servers[0].importsCommand.importVideo({ attributes, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
164 })
165
166 it('Should run filter:api.video.post-import-url.accept.result', async function () {
167 this.timeout(60000)
168
169 let videoImportId: number
170
171 {
172 const attributes = {
173 name: 'title with bad word',
174 privacy: VideoPrivacy.PUBLIC,
175 channelId: servers[0].videoChannel.id,
176 targetUrl: ImportsCommand.getGoodVideoUrl()
177 }
178 const body = await servers[0].importsCommand.importVideo({ attributes })
179 videoImportId = body.id
180 }
181
182 await waitJobs(servers)
183
184 {
185 const body = await servers[0].importsCommand.getMyVideoImports()
186 const videoImports = body.data
187
188 const videoImport = videoImports.find(i => i.id === videoImportId)
189
190 expect(videoImport.state.id).to.equal(VideoImportState.REJECTED)
191 expect(videoImport.state.label).to.equal('Rejected')
192 }
193 })
194
195 it('Should run filter:api.video.post-import-torrent.accept.result', async function () {
196 this.timeout(60000)
197
198 let videoImportId: number
199
200 {
201 const attributes = {
202 name: 'title with bad word',
203 privacy: VideoPrivacy.PUBLIC,
204 channelId: servers[0].videoChannel.id,
205 torrentfile: 'video-720p.torrent' as any
206 }
207 const body = await servers[0].importsCommand.importVideo({ attributes })
208 videoImportId = body.id
209 }
210
211 await waitJobs(servers)
212
213 {
214 const { data: videoImports } = await servers[0].importsCommand.getMyVideoImports()
215
216 const videoImport = videoImports.find(i => i.id === videoImportId)
217
218 expect(videoImport.state.id).to.equal(VideoImportState.REJECTED)
219 expect(videoImport.state.label).to.equal('Rejected')
220 }
221 })
222
223 it('Should run filter:api.video-thread.create.accept.result', async function () {
224 await servers[0].commentsCommand.createThread({
225 videoId: videoUUID,
226 text: 'comment with bad word',
227 expectedStatus: HttpStatusCode.FORBIDDEN_403
228 })
229 })
230
231 it('Should run filter:api.video-comment-reply.create.accept.result', async function () {
232 const created = await servers[0].commentsCommand.createThread({ videoId: videoUUID, text: 'thread' })
233 threadId = created.id
234
235 await servers[0].commentsCommand.addReply({
236 videoId: videoUUID,
237 toCommentId: threadId,
238 text: 'comment with bad word',
239 expectedStatus: HttpStatusCode.FORBIDDEN_403
240 })
241 await servers[0].commentsCommand.addReply({
242 videoId: videoUUID,
243 toCommentId: threadId,
244 text: 'comment with good word',
245 expectedStatus: HttpStatusCode.OK_200
246 })
247 })
248
249 it('Should run filter:api.video-threads.list.params', async function () {
250 const { data } = await servers[0].commentsCommand.listThreads({ videoId: videoUUID, start: 0, count: 0 })
251
252 // our plugin do +1 to the count parameter
253 expect(data).to.have.lengthOf(1)
254 })
255
256 it('Should run filter:api.video-threads.list.result', async function () {
257 const { total } = await servers[0].commentsCommand.listThreads({ videoId: videoUUID, start: 0, count: 0 })
258
259 // Plugin do +1 to the total result
260 expect(total).to.equal(2)
261 })
262
263 it('Should run filter:api.video-thread-comments.list.params')
264
265 it('Should run filter:api.video-thread-comments.list.result', async function () {
266 const thread = await servers[0].commentsCommand.getThread({ videoId: videoUUID, threadId })
267
268 expect(thread.comment.text.endsWith(' <3')).to.be.true
269 })
270
271 describe('Should run filter:video.auto-blacklist.result', function () {
272
273 async function checkIsBlacklisted (id: number | string, value: boolean) {
274 const res = await getVideoWithToken(servers[0].url, servers[0].accessToken, id)
275 const video: VideoDetails = res.body
276 expect(video.blacklisted).to.equal(value)
277 }
278
279 it('Should blacklist on upload', async function () {
280 const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video please blacklist me' })
281 await checkIsBlacklisted(res.body.video.uuid, true)
282 })
283
284 it('Should blacklist on import', async function () {
285 this.timeout(15000)
286
287 const attributes = {
288 name: 'video please blacklist me',
289 targetUrl: ImportsCommand.getGoodVideoUrl(),
290 channelId: servers[0].videoChannel.id
291 }
292 const body = await servers[0].importsCommand.importVideo({ attributes })
293 await checkIsBlacklisted(body.video.uuid, true)
294 })
295
296 it('Should blacklist on update', async function () {
297 const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video' })
298 const videoId = res.body.video.uuid
299 await checkIsBlacklisted(videoId, false)
300
301 await updateVideo(servers[0].url, servers[0].accessToken, videoId, { name: 'please blacklist me' })
302 await checkIsBlacklisted(videoId, true)
303 })
304
305 it('Should blacklist on remote upload', async function () {
306 this.timeout(120000)
307
308 const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'remote please blacklist me' })
309 await waitJobs(servers)
310
311 await checkIsBlacklisted(res.body.video.uuid, true)
312 })
313
314 it('Should blacklist on remote update', async function () {
315 this.timeout(120000)
316
317 const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video' })
318 await waitJobs(servers)
319
320 const videoId = res.body.video.uuid
321 await checkIsBlacklisted(videoId, false)
322
323 await updateVideo(servers[1].url, servers[1].accessToken, videoId, { name: 'please blacklist me' })
324 await waitJobs(servers)
325
326 await checkIsBlacklisted(videoId, true)
327 })
328 })
329
330 describe('Should run filter:api.user.signup.allowed.result', function () {
331
332 it('Should run on config endpoint', async function () {
333 const body = await servers[0].configCommand.getConfig()
334 expect(body.signup.allowed).to.be.true
335 })
336
337 it('Should allow a signup', async function () {
338 await registerUser(servers[0].url, 'john', 'password')
339 })
340
341 it('Should not allow a signup', async function () {
342 const res = await registerUser(servers[0].url, 'jma', 'password', HttpStatusCode.FORBIDDEN_403)
343
344 expect(res.body.error).to.equal('No jma')
345 })
346 })
347
348 describe('Download hooks', function () {
349 const downloadVideos: VideoDetails[] = []
350
351 before(async function () {
352 this.timeout(120000)
353
354 await servers[0].configCommand.updateCustomSubConfig({
355 newConfig: {
356 transcoding: {
357 webtorrent: {
358 enabled: true
359 },
360 hls: {
361 enabled: true
362 }
363 }
364 }
365 })
366
367 const uuids: string[] = []
368
369 for (const name of [ 'bad torrent', 'bad file', 'bad playlist file' ]) {
370 const uuid = (await uploadVideoAndGetId({ server: servers[0], videoName: name })).uuid
371 uuids.push(uuid)
372 }
373
374 await waitJobs(servers)
375
376 for (const uuid of uuids) {
377 const res = await getVideo(servers[0].url, uuid)
378 downloadVideos.push(res.body)
379 }
380 })
381
382 it('Should run filter:api.download.torrent.allowed.result', async function () {
383 const res = await makeRawRequest(downloadVideos[0].files[0].torrentDownloadUrl, 403)
384 expect(res.body.error).to.equal('Liu Bei')
385
386 await makeRawRequest(downloadVideos[1].files[0].torrentDownloadUrl, 200)
387 await makeRawRequest(downloadVideos[2].files[0].torrentDownloadUrl, 200)
388 })
389
390 it('Should run filter:api.download.video.allowed.result', async function () {
391 {
392 const res = await makeRawRequest(downloadVideos[1].files[0].fileDownloadUrl, 403)
393 expect(res.body.error).to.equal('Cao Cao')
394
395 await makeRawRequest(downloadVideos[0].files[0].fileDownloadUrl, 200)
396 await makeRawRequest(downloadVideos[2].files[0].fileDownloadUrl, 200)
397 }
398
399 {
400 const res = await makeRawRequest(downloadVideos[2].streamingPlaylists[0].files[0].fileDownloadUrl, 403)
401 expect(res.body.error).to.equal('Sun Jian')
402
403 await makeRawRequest(downloadVideos[2].files[0].fileDownloadUrl, 200)
404
405 await makeRawRequest(downloadVideos[0].streamingPlaylists[0].files[0].fileDownloadUrl, 200)
406 await makeRawRequest(downloadVideos[1].streamingPlaylists[0].files[0].fileDownloadUrl, 200)
407 }
408 })
409 })
410
411 describe('Embed filters', function () {
412 const embedVideos: VideoDetails[] = []
413 const embedPlaylists: VideoPlaylist[] = []
414
415 before(async function () {
416 this.timeout(60000)
417
418 await servers[0].configCommand.updateCustomSubConfig({
419 newConfig: {
420 transcoding: {
421 enabled: false
422 }
423 }
424 })
425
426 for (const name of [ 'bad embed', 'good embed' ]) {
427 {
428 const uuid = (await uploadVideoAndGetId({ server: servers[0], videoName: name })).uuid
429 const res = await getVideo(servers[0].url, uuid)
430 embedVideos.push(res.body)
431 }
432
433 {
434 const attributes = { displayName: name, videoChannelId: servers[0].videoChannel.id, privacy: VideoPlaylistPrivacy.PUBLIC }
435 const { id } = await servers[0].playlistsCommand.create({ attributes })
436
437 const playlist = await servers[0].playlistsCommand.get({ playlistId: id })
438 embedPlaylists.push(playlist)
439 }
440 }
441 })
442
443 it('Should run filter:html.embed.video.allowed.result', async function () {
444 const res = await makeRawRequest(servers[0].url + embedVideos[0].embedPath, 200)
445 expect(res.text).to.equal('Lu Bu')
446 })
447
448 it('Should run filter:html.embed.video-playlist.allowed.result', async function () {
449 const res = await makeRawRequest(servers[0].url + embedPlaylists[0].embedPath, 200)
450 expect(res.text).to.equal('Diao Chan')
451 })
452 })
453
454 describe('Search filters', function () {
455
456 before(async function () {
457 await servers[0].configCommand.updateCustomSubConfig({
458 newConfig: {
459 search: {
460 searchIndex: {
461 enabled: true,
462 isDefaultSearch: false,
463 disableLocalSearch: false
464 }
465 }
466 }
467 })
468 })
469
470 it('Should run filter:api.search.videos.local.list.{params,result}', async function () {
471 await servers[0].searchCommand.advancedVideoSearch({
472 search: {
473 search: 'Sun Quan'
474 }
475 })
476
477 await servers[0].serversCommand.waitUntilLog('Run hook filter:api.search.videos.local.list.params', 1)
478 await servers[0].serversCommand.waitUntilLog('Run hook filter:api.search.videos.local.list.result', 1)
479 })
480
481 it('Should run filter:api.search.videos.index.list.{params,result}', async function () {
482 await servers[0].searchCommand.advancedVideoSearch({
483 search: {
484 search: 'Sun Quan',
485 searchTarget: 'search-index'
486 }
487 })
488
489 await servers[0].serversCommand.waitUntilLog('Run hook filter:api.search.videos.local.list.params', 1)
490 await servers[0].serversCommand.waitUntilLog('Run hook filter:api.search.videos.local.list.result', 1)
491 await servers[0].serversCommand.waitUntilLog('Run hook filter:api.search.videos.index.list.params', 1)
492 await servers[0].serversCommand.waitUntilLog('Run hook filter:api.search.videos.index.list.result', 1)
493 })
494
495 it('Should run filter:api.search.video-channels.local.list.{params,result}', async function () {
496 await servers[0].searchCommand.advancedChannelSearch({
497 search: {
498 search: 'Sun Ce'
499 }
500 })
501
502 await servers[0].serversCommand.waitUntilLog('Run hook filter:api.search.video-channels.local.list.params', 1)
503 await servers[0].serversCommand.waitUntilLog('Run hook filter:api.search.video-channels.local.list.result', 1)
504 })
505
506 it('Should run filter:api.search.video-channels.index.list.{params,result}', async function () {
507 await servers[0].searchCommand.advancedChannelSearch({
508 search: {
509 search: 'Sun Ce',
510 searchTarget: 'search-index'
511 }
512 })
513
514 await servers[0].serversCommand.waitUntilLog('Run hook filter:api.search.video-channels.local.list.params', 1)
515 await servers[0].serversCommand.waitUntilLog('Run hook filter:api.search.video-channels.local.list.result', 1)
516 await servers[0].serversCommand.waitUntilLog('Run hook filter:api.search.video-channels.index.list.params', 1)
517 await servers[0].serversCommand.waitUntilLog('Run hook filter:api.search.video-channels.index.list.result', 1)
518 })
519
520 it('Should run filter:api.search.video-playlists.local.list.{params,result}', async function () {
521 await servers[0].searchCommand.advancedPlaylistSearch({
522 search: {
523 search: 'Sun Jian'
524 }
525 })
526
527 await servers[0].serversCommand.waitUntilLog('Run hook filter:api.search.video-playlists.local.list.params', 1)
528 await servers[0].serversCommand.waitUntilLog('Run hook filter:api.search.video-playlists.local.list.result', 1)
529 })
530
531 it('Should run filter:api.search.video-playlists.index.list.{params,result}', async function () {
532 await servers[0].searchCommand.advancedPlaylistSearch({
533 search: {
534 search: 'Sun Jian',
535 searchTarget: 'search-index'
536 }
537 })
538
539 await servers[0].serversCommand.waitUntilLog('Run hook filter:api.search.video-playlists.local.list.params', 1)
540 await servers[0].serversCommand.waitUntilLog('Run hook filter:api.search.video-playlists.local.list.result', 1)
541 await servers[0].serversCommand.waitUntilLog('Run hook filter:api.search.video-playlists.index.list.params', 1)
542 await servers[0].serversCommand.waitUntilLog('Run hook filter:api.search.video-playlists.index.list.result', 1)
543 })
544 })
545
546 after(async function () {
547 await cleanupTests(servers)
548 })
549 })