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