]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/plugins/filter-hooks.ts
Introduce import 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,
a1587156 10 doubleFollow,
af971e06 11 flushAndRunMultipleServers,
38267c0c 12 getAccountVideos,
a4d2ca07 13 getMyVideos,
6691c522 14 getVideo,
38267c0c 15 getVideoChannelVideos,
6691c522 16 getVideoCommentThreads,
a1587156
C
17 getVideosList,
18 getVideosListPagination,
6691c522
C
19 getVideoThreadComments,
20 getVideoWithToken,
6910f20f 21 ImportsCommand,
4bc45da3 22 makeRawRequest,
ae2abfd3 23 PluginsCommand,
a1587156 24 registerUser,
af971e06 25 ServerInfo,
a1587156 26 setAccessTokensToServers,
6691c522 27 setDefaultVideoChannel,
a1587156
C
28 updateVideo,
29 uploadVideo,
4bc45da3 30 uploadVideoAndGetId,
af971e06
C
31 waitJobs,
32 waitUntilLog
33} from '@shared/extra-utils'
6910f20f 34import { VideoCommentThreadTree, VideoDetails, VideoImportState, VideoPlaylist, VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models'
9b474844
C
35
36const expect = chai.expect
37
38describe('Test plugin filter hooks', function () {
89cd1275
C
39 let servers: ServerInfo[]
40 let videoUUID: string
41 let threadId: number
9b474844
C
42
43 before(async function () {
4076e2ef 44 this.timeout(60000)
9b474844 45
89cd1275
C
46 servers = await flushAndRunMultipleServers(2)
47 await setAccessTokensToServers(servers)
6691c522
C
48 await setDefaultVideoChannel(servers)
49 await doubleFollow(servers[0], servers[1])
89cd1275 50
ae2abfd3
C
51 await servers[0].pluginsCommand.install({ path: PluginsCommand.getPluginTestPath() })
52 await servers[0].pluginsCommand.install({ path: PluginsCommand.getPluginTestPath('-filter-translations') })
89cd1275
C
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
3cabf353 60
65e6e260
C
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 }
3cabf353
C
70 }
71 }
72 })
9b474844
C
73 })
74
6691c522 75 it('Should run filter:api.videos.list.params', async function () {
89cd1275
C
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
38267c0c
C
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 () {
c824e8a0 111 const res = await getVideoChannelVideos(servers[0].url, servers[0].accessToken, 'root_channel', 0, 2)
38267c0c
C
112
113 // Plugin do +3 to the total result
114 expect(res.body.total).to.equal(13)
115 })
116
a4d2ca07
C
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
89cd1275
C
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')
9b474844
C
135 })
136
6691c522 137 it('Should run filter:api.video.upload.accept.result', async function () {
f2eb23cd 138 await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video with bad word' }, HttpStatusCode.FORBIDDEN_403)
6691c522
C
139 })
140
3cabf353
C
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
04aed767 148 await servers[0].liveCommand.create({ fields: attributes, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
3cabf353
C
149 })
150
2158ac90 151 it('Should run filter:api.video.pre-import-url.accept.result', async function () {
6910f20f 152 const attributes = {
2158ac90
RK
153 name: 'normal title',
154 privacy: VideoPrivacy.PUBLIC,
155 channelId: servers[0].videoChannel.id,
6910f20f 156 targetUrl: ImportsCommand.getGoodVideoUrl() + 'bad'
2158ac90 157 }
6910f20f 158 await servers[0].importsCommand.importVideo({ attributes, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
2158ac90
RK
159 })
160
161 it('Should run filter:api.video.pre-import-torrent.accept.result', async function () {
6910f20f 162 const attributes = {
2158ac90
RK
163 name: 'bad torrent',
164 privacy: VideoPrivacy.PUBLIC,
165 channelId: servers[0].videoChannel.id,
166 torrentfile: 'video-720p.torrent' as any
167 }
6910f20f 168 await servers[0].importsCommand.importVideo({ attributes, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
2158ac90
RK
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 {
6910f20f 177 const attributes = {
2158ac90
RK
178 name: 'title with bad word',
179 privacy: VideoPrivacy.PUBLIC,
180 channelId: servers[0].videoChannel.id,
6910f20f 181 targetUrl: ImportsCommand.getGoodVideoUrl()
2158ac90 182 }
6910f20f
C
183 const body = await servers[0].importsCommand.importVideo({ attributes })
184 videoImportId = body.id
2158ac90
RK
185 }
186
187 await waitJobs(servers)
188
189 {
6910f20f
C
190 const body = await servers[0].importsCommand.getMyVideoImports()
191 const videoImports = body.data
2158ac90
RK
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 {
6910f20f 206 const attributes = {
2158ac90
RK
207 name: 'title with bad word',
208 privacy: VideoPrivacy.PUBLIC,
209 channelId: servers[0].videoChannel.id,
210 torrentfile: 'video-720p.torrent' as any
211 }
6910f20f
C
212 const body = await servers[0].importsCommand.importVideo({ attributes })
213 videoImportId = body.id
2158ac90
RK
214 }
215
216 await waitJobs(servers)
217
218 {
6910f20f 219 const { data: videoImports } = await servers[0].importsCommand.getMyVideoImports()
2158ac90
RK
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
6691c522 228 it('Should run filter:api.video-thread.create.accept.result', async function () {
f2eb23cd 229 await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'comment with bad word', HttpStatusCode.FORBIDDEN_403)
6691c522
C
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
f2eb23cd
RK
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)
6691c522
C
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
6910f20f
C
272 async function checkIsBlacklisted (id: number | string, value: boolean) {
273 const res = await getVideoWithToken(servers[0].url, servers[0].accessToken, id)
6691c522
C
274 const video: VideoDetails = res.body
275 expect(video.blacklisted).to.equal(value)
276 }
277
278 it('Should blacklist on upload', async function () {
a1587156 279 const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video please blacklist me' })
6910f20f 280 await checkIsBlacklisted(res.body.video.uuid, true)
6691c522
C
281 })
282
283 it('Should blacklist on import', async function () {
89566f77
C
284 this.timeout(15000)
285
6691c522
C
286 const attributes = {
287 name: 'video please blacklist me',
6910f20f 288 targetUrl: ImportsCommand.getGoodVideoUrl(),
6691c522
C
289 channelId: servers[0].videoChannel.id
290 }
6910f20f
C
291 const body = await servers[0].importsCommand.importVideo({ attributes })
292 await checkIsBlacklisted(body.video.uuid, true)
6691c522
C
293 })
294
295 it('Should blacklist on update', async function () {
a1587156 296 const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video' })
6691c522 297 const videoId = res.body.video.uuid
6910f20f 298 await checkIsBlacklisted(videoId, false)
6691c522 299
a1587156 300 await updateVideo(servers[0].url, servers[0].accessToken, videoId, { name: 'please blacklist me' })
6910f20f 301 await checkIsBlacklisted(videoId, true)
6691c522
C
302 })
303
304 it('Should blacklist on remote upload', async function () {
3d470a53 305 this.timeout(120000)
6691c522 306
a1587156 307 const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'remote please blacklist me' })
6691c522
C
308 await waitJobs(servers)
309
6910f20f 310 await checkIsBlacklisted(res.body.video.uuid, true)
6691c522
C
311 })
312
313 it('Should blacklist on remote update', async function () {
3d470a53 314 this.timeout(120000)
6691c522 315
a1587156 316 const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video' })
6691c522
C
317 await waitJobs(servers)
318
319 const videoId = res.body.video.uuid
6910f20f 320 await checkIsBlacklisted(videoId, false)
6691c522
C
321
322 await updateVideo(servers[1].url, servers[1].accessToken, videoId, { name: 'please blacklist me' })
323 await waitJobs(servers)
324
6910f20f 325 await checkIsBlacklisted(videoId, true)
6691c522
C
326 })
327 })
328
4ce7eb71
C
329 describe('Should run filter:api.user.signup.allowed.result', function () {
330
331 it('Should run on config endpoint', async function () {
65e6e260
C
332 const body = await servers[0].configCommand.getConfig()
333 expect(body.signup.allowed).to.be.true
4ce7eb71
C
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 () {
f2eb23cd 341 const res = await registerUser(servers[0].url, 'jma', 'password', HttpStatusCode.FORBIDDEN_403)
4ce7eb71
C
342
343 expect(res.body.error).to.equal('No jma')
344 })
345 })
346
4bc45da3
C
347 describe('Download hooks', function () {
348 const downloadVideos: VideoDetails[] = []
349
350 before(async function () {
c4244cfd 351 this.timeout(120000)
4bc45da3 352
65e6e260
C
353 await servers[0].configCommand.updateCustomSubConfig({
354 newConfig: {
355 transcoding: {
356 webtorrent: {
357 enabled: true
358 },
359 hls: {
360 enabled: true
361 }
4bc45da3
C
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
eebd9838
C
410 describe('Embed filters', function () {
411 const embedVideos: VideoDetails[] = []
412 const embedPlaylists: VideoPlaylist[] = []
413
414 before(async function () {
415 this.timeout(60000)
416
65e6e260
C
417 await servers[0].configCommand.updateCustomSubConfig({
418 newConfig: {
419 transcoding: {
420 enabled: false
421 }
eebd9838
C
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 {
e6346d59
C
433 const attributes = { displayName: name, videoChannelId: servers[0].videoChannel.id, privacy: VideoPlaylistPrivacy.PUBLIC }
434 const { id } = await servers[0].playlistsCommand.create({ attributes })
eebd9838 435
e6346d59
C
436 const playlist = await servers[0].playlistsCommand.get({ playlistId: id })
437 embedPlaylists.push(playlist)
eebd9838
C
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
74a4d531
C
453 describe('Search filters', function () {
454
455 before(async function () {
65e6e260
C
456 await servers[0].configCommand.updateCustomSubConfig({
457 newConfig: {
458 search: {
459 searchIndex: {
460 enabled: true,
461 isDefaultSearch: false,
462 disableLocalSearch: false
463 }
74a4d531
C
464 }
465 }
466 })
467 })
468
469 it('Should run filter:api.search.videos.local.list.{params,result}', async function () {
af971e06
C
470 await servers[0].searchCommand.advancedVideoSearch({
471 search: {
472 search: 'Sun Quan'
473 }
74a4d531
C
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 () {
af971e06
C
481 await servers[0].searchCommand.advancedVideoSearch({
482 search: {
483 search: 'Sun Quan',
484 searchTarget: 'search-index'
485 }
74a4d531
C
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 () {
af971e06
C
495 await servers[0].searchCommand.advancedChannelSearch({
496 search: {
497 search: 'Sun Ce'
498 }
74a4d531
C
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 () {
af971e06
C
506 await servers[0].searchCommand.advancedChannelSearch({
507 search: {
508 search: 'Sun Ce',
509 searchTarget: 'search-index'
510 }
74a4d531
C
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 })
37a44fc9
C
518
519 it('Should run filter:api.search.video-playlists.local.list.{params,result}', async function () {
af971e06
C
520 await servers[0].searchCommand.advancedPlaylistSearch({
521 search: {
522 search: 'Sun Jian'
523 }
37a44fc9
C
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 () {
af971e06
C
531 await servers[0].searchCommand.advancedPlaylistSearch({
532 search: {
533 search: 'Sun Jian',
534 searchTarget: 'search-index'
535 }
37a44fc9
C
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 })
74a4d531
C
543 })
544
9b474844 545 after(async function () {
89cd1275 546 await cleanupTests(servers)
9b474844
C
547 })
548})