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