]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/plugins/filter-hooks.ts
Add runner server tests
[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
86347717 3import { expect } from 'chai'
b379759f
C
4import {
5 HttpStatusCode,
6 PeerTubeProblemDocument,
7 VideoDetails,
8 VideoImportState,
9 VideoPlaylist,
10 VideoPlaylistPrivacy,
11 VideoPrivacy
12} from '@shared/models'
89cd1275 13import {
af971e06 14 cleanupTests,
254d3579 15 createMultipleServers,
59bbcced 16 doubleFollow,
58e735dd 17 makeActivityPubGetRequest,
3545e72c 18 makeGetRequest,
4bc45da3 19 makeRawRequest,
254d3579 20 PeerTubeServer,
59bbcced 21 PluginsCommand,
a1587156 22 setAccessTokensToServers,
6691c522 23 setDefaultVideoChannel,
6c5065a0 24 waitJobs
bf54587a 25} from '@shared/server-commands'
c55e3d72 26import { FIXTURE_URLS } from '../shared'
9b474844 27
9b474844 28describe('Test plugin filter hooks', function () {
254d3579 29 let servers: PeerTubeServer[]
89cd1275
C
30 let videoUUID: string
31 let threadId: number
c5ca7e1e 32 let videoPlaylistUUID: string
9b474844
C
33
34 before(async function () {
1e3e64a6 35 this.timeout(120000)
9b474844 36
254d3579 37 servers = await createMultipleServers(2)
89cd1275 38 await setAccessTokensToServers(servers)
6691c522
C
39 await setDefaultVideoChannel(servers)
40 await doubleFollow(servers[0], servers[1])
89cd1275 41
89d241a7
C
42 await servers[0].plugins.install({ path: PluginsCommand.getPluginTestPath() })
43 await servers[0].plugins.install({ path: PluginsCommand.getPluginTestPath('-filter-translations') })
c5ca7e1e 44 {
45 ({ uuid: videoPlaylistUUID } = await servers[0].playlists.create({
46 attributes: {
47 displayName: 'my super playlist',
48 privacy: VideoPlaylistPrivacy.PUBLIC,
49 description: 'my super description',
50 videoChannelId: servers[0].store.channel.id
51 }
52 }))
53 }
89cd1275
C
54
55 for (let i = 0; i < 10; i++) {
c5ca7e1e 56 const video = await servers[0].videos.upload({ attributes: { name: 'default video ' + i } })
57 await servers[0].playlists.addElement({ playlistId: videoPlaylistUUID, attributes: { videoId: video.id } })
89cd1275
C
58 }
59
89d241a7 60 const { data } = await servers[0].videos.list()
d23dd9fb 61 videoUUID = data[0].uuid
3cabf353 62
89d241a7 63 await servers[0].config.updateCustomSubConfig({
65e6e260
C
64 newConfig: {
65 live: { enabled: true },
66 signup: { enabled: true },
67 import: {
68 videos: {
69 http: { enabled: true },
70 torrent: { enabled: true }
71 }
3cabf353
C
72 }
73 }
74 })
c0687c91
W
75
76 // Root subscribes to itself
77 await servers[0].subscriptions.add({ targetUri: 'root_channel@' + servers[0].host })
9b474844
C
78 })
79
b2a70e3c 80 describe('Videos', function () {
89cd1275 81
b2a70e3c
C
82 it('Should run filter:api.videos.list.params', async function () {
83 const { data } = await servers[0].videos.list({ start: 0, count: 2 })
89cd1275 84
b2a70e3c
C
85 // 2 plugins do +1 to the count parameter
86 expect(data).to.have.lengthOf(4)
87 })
89cd1275 88
b2a70e3c
C
89 it('Should run filter:api.videos.list.result', async function () {
90 const { total } = await servers[0].videos.list({ start: 0, count: 0 })
89cd1275 91
b2a70e3c
C
92 // Plugin do +1 to the total result
93 expect(total).to.equal(11)
c5ca7e1e 94 })
95
b2a70e3c
C
96 it('Should run filter:api.video-playlist.videos.list.params', async function () {
97 const { data } = await servers[0].playlists.listVideos({
98 count: 2,
99 playlistId: videoPlaylistUUID
100 })
c5ca7e1e 101
b2a70e3c
C
102 // 1 plugin do +1 to the count parameter
103 expect(data).to.have.lengthOf(3)
c5ca7e1e 104 })
105
b2a70e3c
C
106 it('Should run filter:api.video-playlist.videos.list.result', async function () {
107 const { total } = await servers[0].playlists.listVideos({
108 count: 0,
109 playlistId: videoPlaylistUUID
110 })
c5ca7e1e 111
b2a70e3c
C
112 // Plugin do +1 to the total result
113 expect(total).to.equal(11)
114 })
38267c0c 115
b2a70e3c
C
116 it('Should run filter:api.accounts.videos.list.params', async function () {
117 const { data } = await servers[0].videos.listByAccount({ handle: 'root', start: 0, count: 2 })
38267c0c 118
b2a70e3c
C
119 // 1 plugin do +1 to the count parameter
120 expect(data).to.have.lengthOf(3)
121 })
38267c0c 122
b2a70e3c
C
123 it('Should run filter:api.accounts.videos.list.result', async function () {
124 const { total } = await servers[0].videos.listByAccount({ handle: 'root', start: 0, count: 2 })
38267c0c 125
b2a70e3c
C
126 // Plugin do +2 to the total result
127 expect(total).to.equal(12)
128 })
38267c0c 129
b2a70e3c
C
130 it('Should run filter:api.video-channels.videos.list.params', async function () {
131 const { data } = await servers[0].videos.listByChannel({ handle: 'root_channel', start: 0, count: 2 })
38267c0c 132
b2a70e3c
C
133 // 1 plugin do +3 to the count parameter
134 expect(data).to.have.lengthOf(5)
135 })
38267c0c 136
b2a70e3c
C
137 it('Should run filter:api.video-channels.videos.list.result', async function () {
138 const { total } = await servers[0].videos.listByChannel({ handle: 'root_channel', start: 0, count: 2 })
38267c0c 139
b2a70e3c
C
140 // Plugin do +3 to the total result
141 expect(total).to.equal(13)
142 })
a4d2ca07 143
b2a70e3c
C
144 it('Should run filter:api.user.me.videos.list.params', async function () {
145 const { data } = await servers[0].videos.listMyVideos({ start: 0, count: 2 })
a4d2ca07 146
b2a70e3c
C
147 // 1 plugin do +4 to the count parameter
148 expect(data).to.have.lengthOf(6)
149 })
a4d2ca07 150
b2a70e3c
C
151 it('Should run filter:api.user.me.videos.list.result', async function () {
152 const { total } = await servers[0].videos.listMyVideos({ start: 0, count: 2 })
a4d2ca07 153
b2a70e3c
C
154 // Plugin do +4 to the total result
155 expect(total).to.equal(14)
156 })
9b474844 157
c0687c91 158 it('Should run filter:api.user.me.subscription-videos.list.params', async function () {
692ae8c3 159 const { data } = await servers[0].videos.listMySubscriptionVideos({ start: 0, count: 2 })
c0687c91 160
692ae8c3
W
161 // 1 plugin do +1 to the count parameter
162 expect(data).to.have.lengthOf(3)
c0687c91
W
163 })
164
165 it('Should run filter:api.user.me.subscription-videos.list.result', async function () {
692ae8c3 166 const { total } = await servers[0].videos.listMySubscriptionVideos({ start: 0, count: 2 })
c0687c91
W
167
168 // Plugin do +4 to the total result
169 expect(total).to.equal(14)
170 })
171
b2a70e3c
C
172 it('Should run filter:api.video.get.result', async function () {
173 const video = await servers[0].videos.get({ id: videoUUID })
174 expect(video.name).to.contain('<3')
175 })
6691c522
C
176 })
177
b2a70e3c 178 describe('Video/live/import accept', function () {
3cabf353 179
b2a70e3c
C
180 it('Should run filter:api.video.upload.accept.result', async function () {
181 await servers[0].videos.upload({ attributes: { name: 'video with bad word' }, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
182 })
2158ac90 183
b2a70e3c
C
184 it('Should run filter:api.live-video.create.accept.result', async function () {
185 const attributes = {
186 name: 'video with bad word',
187 privacy: VideoPrivacy.PUBLIC,
188 channelId: servers[0].store.channel.id
189 }
2158ac90 190
b2a70e3c
C
191 await servers[0].live.create({ fields: attributes, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
192 })
2158ac90 193
b2a70e3c
C
194 it('Should run filter:api.video.pre-import-url.accept.result', async function () {
195 const attributes = {
196 name: 'normal title',
197 privacy: VideoPrivacy.PUBLIC,
198 channelId: servers[0].store.channel.id,
199 targetUrl: FIXTURE_URLS.goodVideo + 'bad'
200 }
201 await servers[0].imports.importVideo({ attributes, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
202 })
2158ac90 203
b2a70e3c 204 it('Should run filter:api.video.pre-import-torrent.accept.result', async function () {
6910f20f 205 const attributes = {
b2a70e3c 206 name: 'bad torrent',
2158ac90 207 privacy: VideoPrivacy.PUBLIC,
89d241a7 208 channelId: servers[0].store.channel.id,
b2a70e3c 209 torrentfile: 'video-720p.torrent' as any
2158ac90 210 }
b2a70e3c
C
211 await servers[0].imports.importVideo({ attributes, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
212 })
2158ac90 213
b2a70e3c
C
214 it('Should run filter:api.video.post-import-url.accept.result', async function () {
215 this.timeout(60000)
2158ac90 216
b2a70e3c 217 let videoImportId: number
2158ac90 218
b2a70e3c
C
219 {
220 const attributes = {
221 name: 'title with bad word',
222 privacy: VideoPrivacy.PUBLIC,
223 channelId: servers[0].store.channel.id,
224 targetUrl: FIXTURE_URLS.goodVideo
225 }
226 const body = await servers[0].imports.importVideo({ attributes })
227 videoImportId = body.id
228 }
2158ac90 229
b2a70e3c 230 await waitJobs(servers)
2158ac90 231
b2a70e3c
C
232 {
233 const body = await servers[0].imports.getMyVideoImports()
234 const videoImports = body.data
2158ac90 235
b2a70e3c 236 const videoImport = videoImports.find(i => i.id === videoImportId)
2158ac90 237
b2a70e3c
C
238 expect(videoImport.state.id).to.equal(VideoImportState.REJECTED)
239 expect(videoImport.state.label).to.equal('Rejected')
2158ac90 240 }
b2a70e3c 241 })
2158ac90 242
b2a70e3c
C
243 it('Should run filter:api.video.post-import-torrent.accept.result', async function () {
244 this.timeout(60000)
2158ac90 245
b2a70e3c 246 let videoImportId: number
2158ac90 247
b2a70e3c
C
248 {
249 const attributes = {
250 name: 'title with bad word',
251 privacy: VideoPrivacy.PUBLIC,
252 channelId: servers[0].store.channel.id,
253 torrentfile: 'video-720p.torrent' as any
254 }
255 const body = await servers[0].imports.importVideo({ attributes })
256 videoImportId = body.id
257 }
2158ac90 258
b2a70e3c
C
259 await waitJobs(servers)
260
261 {
262 const { data: videoImports } = await servers[0].imports.getMyVideoImports()
263
264 const videoImport = videoImports.find(i => i.id === videoImportId)
2158ac90 265
b2a70e3c
C
266 expect(videoImport.state.id).to.equal(VideoImportState.REJECTED)
267 expect(videoImport.state.label).to.equal('Rejected')
268 }
12edc149 269 })
6691c522
C
270 })
271
b2a70e3c 272 describe('Video comments accept', function () {
12edc149 273
b2a70e3c
C
274 it('Should run filter:api.video-thread.create.accept.result', async function () {
275 await servers[0].comments.createThread({
276 videoId: videoUUID,
277 text: 'comment with bad word',
278 expectedStatus: HttpStatusCode.FORBIDDEN_403
279 })
12edc149 280 })
b2a70e3c
C
281
282 it('Should run filter:api.video-comment-reply.create.accept.result', async function () {
283 const created = await servers[0].comments.createThread({ videoId: videoUUID, text: 'thread' })
284 threadId = created.id
285
286 await servers[0].comments.addReply({
287 videoId: videoUUID,
288 toCommentId: threadId,
289 text: 'comment with bad word',
290 expectedStatus: HttpStatusCode.FORBIDDEN_403
291 })
292 await servers[0].comments.addReply({
293 videoId: videoUUID,
294 toCommentId: threadId,
295 text: 'comment with good word',
296 expectedStatus: HttpStatusCode.OK_200
297 })
12edc149 298 })
6691c522 299
b2a70e3c
C
300 it('Should run filter:activity-pub.remote-video-comment.create.accept.result on a thread creation', async function () {
301 this.timeout(30000)
6691c522 302
b2a70e3c 303 await servers[1].comments.createThread({ videoId: videoUUID, text: 'comment with bad word' })
6691c522 304
b2a70e3c 305 await waitJobs(servers)
6691c522 306
b2a70e3c
C
307 {
308 const thread = await servers[0].comments.listThreads({ videoId: videoUUID })
309 expect(thread.data).to.have.lengthOf(1)
310 expect(thread.data[0].text).to.not.include(' bad ')
311 }
312
313 {
314 const thread = await servers[1].comments.listThreads({ videoId: videoUUID })
315 expect(thread.data).to.have.lengthOf(2)
316 }
317 })
318
319 it('Should run filter:activity-pub.remote-video-comment.create.accept.result on a reply creation', async function () {
320 this.timeout(30000)
321
322 const { data } = await servers[1].comments.listThreads({ videoId: videoUUID })
323 const threadIdServer2 = data.find(t => t.text === 'thread').id
6691c522 324
b2a70e3c
C
325 await servers[1].comments.addReply({
326 videoId: videoUUID,
327 toCommentId: threadIdServer2,
328 text: 'comment with bad word'
329 })
6691c522 330
b2a70e3c 331 await waitJobs(servers)
6691c522 332
b2a70e3c
C
333 {
334 const tree = await servers[0].comments.getThread({ videoId: videoUUID, threadId })
335 expect(tree.children).to.have.lengthOf(1)
336 expect(tree.children[0].comment.text).to.not.include(' bad ')
337 }
338
339 {
340 const tree = await servers[1].comments.getThread({ videoId: videoUUID, threadId: threadIdServer2 })
341 expect(tree.children).to.have.lengthOf(2)
342 }
343 })
6691c522
C
344 })
345
b2a70e3c
C
346 describe('Video comments', function () {
347
348 it('Should run filter:api.video-threads.list.params', async function () {
349 const { data } = await servers[0].comments.listThreads({ videoId: videoUUID, start: 0, count: 0 })
d1aed103 350
b2a70e3c
C
351 // our plugin do +1 to the count parameter
352 expect(data).to.have.lengthOf(1)
353 })
354
355 it('Should run filter:api.video-threads.list.result', async function () {
356 const { total } = await servers[0].comments.listThreads({ videoId: videoUUID, start: 0, count: 0 })
357
358 // Plugin do +1 to the total result
359 expect(total).to.equal(2)
360 })
361
362 it('Should run filter:api.video-thread-comments.list.params')
363
364 it('Should run filter:api.video-thread-comments.list.result', async function () {
365 const thread = await servers[0].comments.getThread({ videoId: videoUUID, threadId })
366
367 expect(thread.comment.text.endsWith(' <3')).to.be.true
368 })
369
370 it('Should run filter:api.overviews.videos.list.{params,result}', async function () {
371 await servers[0].overviews.getVideos({ page: 1 })
372
373 // 3 because we get 3 samples per page
374 await servers[0].servers.waitUntilLog('Run hook filter:api.overviews.videos.list.params', 3)
375 await servers[0].servers.waitUntilLog('Run hook filter:api.overviews.videos.list.result', 3)
376 })
d1aed103
C
377 })
378
0260dc8a 379 describe('filter:video.auto-blacklist.result', function () {
6691c522 380
6910f20f 381 async function checkIsBlacklisted (id: number | string, value: boolean) {
89d241a7 382 const video = await servers[0].videos.getWithToken({ id })
6691c522
C
383 expect(video.blacklisted).to.equal(value)
384 }
385
386 it('Should blacklist on upload', async function () {
89d241a7 387 const { uuid } = await servers[0].videos.upload({ attributes: { name: 'video please blacklist me' } })
d23dd9fb 388 await checkIsBlacklisted(uuid, true)
6691c522
C
389 })
390
391 it('Should blacklist on import', async function () {
89566f77
C
392 this.timeout(15000)
393
6691c522
C
394 const attributes = {
395 name: 'video please blacklist me',
59bbcced 396 targetUrl: FIXTURE_URLS.goodVideo,
89d241a7 397 channelId: servers[0].store.channel.id
6691c522 398 }
89d241a7 399 const body = await servers[0].imports.importVideo({ attributes })
6910f20f 400 await checkIsBlacklisted(body.video.uuid, true)
6691c522
C
401 })
402
403 it('Should blacklist on update', async function () {
89d241a7 404 const { uuid } = await servers[0].videos.upload({ attributes: { name: 'video' } })
d23dd9fb 405 await checkIsBlacklisted(uuid, false)
6691c522 406
89d241a7 407 await servers[0].videos.update({ id: uuid, attributes: { name: 'please blacklist me' } })
d23dd9fb 408 await checkIsBlacklisted(uuid, true)
6691c522
C
409 })
410
411 it('Should blacklist on remote upload', async function () {
3d470a53 412 this.timeout(120000)
6691c522 413
89d241a7 414 const { uuid } = await servers[1].videos.upload({ attributes: { name: 'remote please blacklist me' } })
6691c522
C
415 await waitJobs(servers)
416
d23dd9fb 417 await checkIsBlacklisted(uuid, true)
6691c522
C
418 })
419
420 it('Should blacklist on remote update', async function () {
3d470a53 421 this.timeout(120000)
6691c522 422
89d241a7 423 const { uuid } = await servers[1].videos.upload({ attributes: { name: 'video' } })
6691c522
C
424 await waitJobs(servers)
425
d23dd9fb 426 await checkIsBlacklisted(uuid, false)
6691c522 427
89d241a7 428 await servers[1].videos.update({ id: uuid, attributes: { name: 'please blacklist me' } })
6691c522
C
429 await waitJobs(servers)
430
d23dd9fb 431 await checkIsBlacklisted(uuid, true)
6691c522
C
432 })
433 })
434
4ce7eb71
C
435 describe('Should run filter:api.user.signup.allowed.result', function () {
436
b379759f
C
437 before(async function () {
438 await servers[0].config.updateExistingSubConfig({ newConfig: { signup: { requiresApproval: false } } })
439 })
440
4ce7eb71 441 it('Should run on config endpoint', async function () {
89d241a7 442 const body = await servers[0].config.getConfig()
65e6e260 443 expect(body.signup.allowed).to.be.true
4ce7eb71
C
444 })
445
446 it('Should allow a signup', async function () {
b379759f 447 await servers[0].registrations.register({ username: 'john1' })
4ce7eb71
C
448 })
449
450 it('Should not allow a signup', async function () {
b379759f
C
451 const res = await servers[0].registrations.register({
452 username: 'jma 1',
453 expectedStatus: HttpStatusCode.FORBIDDEN_403
454 })
455
456 expect(res.body.error).to.equal('No jma 1')
457 })
458 })
459
460 describe('Should run filter:api.user.request-signup.allowed.result', function () {
461
462 before(async function () {
463 await servers[0].config.updateExistingSubConfig({ newConfig: { signup: { requiresApproval: true } } })
464 })
465
466 it('Should run on config endpoint', async function () {
467 const body = await servers[0].config.getConfig()
468 expect(body.signup.allowed).to.be.true
469 })
470
471 it('Should allow a signup request', async function () {
472 await servers[0].registrations.requestRegistration({ username: 'john2', registrationReason: 'tt' })
473 })
474
475 it('Should not allow a signup request', async function () {
476 const body = await servers[0].registrations.requestRegistration({
477 username: 'jma 2',
478 registrationReason: 'tt',
7926c5f9
C
479 expectedStatus: HttpStatusCode.FORBIDDEN_403
480 })
4ce7eb71 481
b379759f 482 expect((body as unknown as PeerTubeProblemDocument).error).to.equal('No jma 2')
4ce7eb71
C
483 })
484 })
485
4bc45da3
C
486 describe('Download hooks', function () {
487 const downloadVideos: VideoDetails[] = []
868314e8 488 let downloadVideo2Token: string
4bc45da3
C
489
490 before(async function () {
c4244cfd 491 this.timeout(120000)
4bc45da3 492
89d241a7 493 await servers[0].config.updateCustomSubConfig({
65e6e260
C
494 newConfig: {
495 transcoding: {
496 webtorrent: {
497 enabled: true
498 },
499 hls: {
500 enabled: true
501 }
4bc45da3
C
502 }
503 }
504 })
505
506 const uuids: string[] = []
507
508 for (const name of [ 'bad torrent', 'bad file', 'bad playlist file' ]) {
ba2684ce 509 const uuid = (await servers[0].videos.quickUpload({ name })).uuid
4bc45da3
C
510 uuids.push(uuid)
511 }
512
513 await waitJobs(servers)
514
515 for (const uuid of uuids) {
89d241a7 516 downloadVideos.push(await servers[0].videos.get({ id: uuid }))
4bc45da3 517 }
868314e8
C
518
519 downloadVideo2Token = await servers[0].videoToken.getVideoFileToken({ videoId: downloadVideos[2].uuid })
4bc45da3
C
520 })
521
522 it('Should run filter:api.download.torrent.allowed.result', async function () {
3545e72c 523 const res = await makeRawRequest({ url: downloadVideos[0].files[0].torrentDownloadUrl, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
4bc45da3
C
524 expect(res.body.error).to.equal('Liu Bei')
525
3545e72c
C
526 await makeRawRequest({ url: downloadVideos[1].files[0].torrentDownloadUrl, expectedStatus: HttpStatusCode.OK_200 })
527 await makeRawRequest({ url: downloadVideos[2].files[0].torrentDownloadUrl, expectedStatus: HttpStatusCode.OK_200 })
4bc45da3
C
528 })
529
530 it('Should run filter:api.download.video.allowed.result', async function () {
531 {
868314e8
C
532 const refused = downloadVideos[1].files[0].fileDownloadUrl
533 const allowed = [
534 downloadVideos[0].files[0].fileDownloadUrl,
535 downloadVideos[2].files[0].fileDownloadUrl
536 ]
537
538 const res = await makeRawRequest({ url: refused, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
4bc45da3
C
539 expect(res.body.error).to.equal('Cao Cao')
540
868314e8
C
541 for (const url of allowed) {
542 await makeRawRequest({ url, expectedStatus: HttpStatusCode.OK_200 })
543 await makeRawRequest({ url, expectedStatus: HttpStatusCode.OK_200 })
544 }
4bc45da3
C
545 }
546
547 {
868314e8 548 const refused = downloadVideos[2].streamingPlaylists[0].files[0].fileDownloadUrl
3545e72c 549
868314e8
C
550 const allowed = [
551 downloadVideos[2].files[0].fileDownloadUrl,
552 downloadVideos[0].streamingPlaylists[0].files[0].fileDownloadUrl,
553 downloadVideos[1].streamingPlaylists[0].files[0].fileDownloadUrl
554 ]
4bc45da3 555
868314e8
C
556 // Only streaming playlist is refuse
557 const res = await makeRawRequest({ url: refused, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
558 expect(res.body.error).to.equal('Sun Jian')
3545e72c 559
868314e8
C
560 // But not we there is a user in res
561 await makeRawRequest({ url: refused, token: servers[0].accessToken, expectedStatus: HttpStatusCode.OK_200 })
562 await makeRawRequest({ url: refused, query: { videoFileToken: downloadVideo2Token }, expectedStatus: HttpStatusCode.OK_200 })
4bc45da3 563
868314e8
C
564 // Other files work
565 for (const url of allowed) {
566 await makeRawRequest({ url, expectedStatus: HttpStatusCode.OK_200 })
567 }
4bc45da3
C
568 }
569 })
570 })
571
eebd9838
C
572 describe('Embed filters', function () {
573 const embedVideos: VideoDetails[] = []
574 const embedPlaylists: VideoPlaylist[] = []
575
576 before(async function () {
577 this.timeout(60000)
578
c729caf6 579 await servers[0].config.disableTranscoding()
eebd9838
C
580
581 for (const name of [ 'bad embed', 'good embed' ]) {
582 {
ba2684ce 583 const uuid = (await servers[0].videos.quickUpload({ name })).uuid
89d241a7 584 embedVideos.push(await servers[0].videos.get({ id: uuid }))
eebd9838
C
585 }
586
587 {
89d241a7
C
588 const attributes = { displayName: name, videoChannelId: servers[0].store.channel.id, privacy: VideoPlaylistPrivacy.PUBLIC }
589 const { id } = await servers[0].playlists.create({ attributes })
eebd9838 590
89d241a7 591 const playlist = await servers[0].playlists.get({ playlistId: id })
e6346d59 592 embedPlaylists.push(playlist)
eebd9838
C
593 }
594 }
595 })
596
597 it('Should run filter:html.embed.video.allowed.result', async function () {
3545e72c 598 const res = await makeGetRequest({ url: servers[0].url, path: embedVideos[0].embedPath, expectedStatus: HttpStatusCode.OK_200 })
eebd9838
C
599 expect(res.text).to.equal('Lu Bu')
600 })
601
602 it('Should run filter:html.embed.video-playlist.allowed.result', async function () {
3545e72c 603 const res = await makeGetRequest({ url: servers[0].url, path: embedPlaylists[0].embedPath, expectedStatus: HttpStatusCode.OK_200 })
eebd9838
C
604 expect(res.text).to.equal('Diao Chan')
605 })
606 })
607
d91ce83d
C
608 describe('Client HTML filters', function () {
609 let videoUUID: string
610
611 before(async function () {
612 this.timeout(60000)
613
614 const { uuid } = await servers[0].videos.quickUpload({ name: 'html video' })
615 videoUUID = uuid
616 })
617
618 it('Should run filter:html.client.json-ld.result', async function () {
619 const res = await makeGetRequest({ url: servers[0].url, path: '/w/' + videoUUID, expectedStatus: HttpStatusCode.OK_200 })
620 expect(res.text).to.contain('"recordedAt":"http://example.com/recordedAt"')
621 })
622
623 it('Should not run filter:html.client.json-ld.result with an account', async function () {
624 const res = await makeGetRequest({ url: servers[0].url, path: '/a/root', expectedStatus: HttpStatusCode.OK_200 })
625 expect(res.text).not.to.contain('"recordedAt":"http://example.com/recordedAt"')
626 })
627 })
628
74a4d531
C
629 describe('Search filters', function () {
630
631 before(async function () {
89d241a7 632 await servers[0].config.updateCustomSubConfig({
65e6e260
C
633 newConfig: {
634 search: {
635 searchIndex: {
636 enabled: true,
637 isDefaultSearch: false,
638 disableLocalSearch: false
639 }
74a4d531
C
640 }
641 }
642 })
643 })
644
645 it('Should run filter:api.search.videos.local.list.{params,result}', async function () {
89d241a7 646 await servers[0].search.advancedVideoSearch({
af971e06
C
647 search: {
648 search: 'Sun Quan'
649 }
74a4d531
C
650 })
651
89d241a7
C
652 await servers[0].servers.waitUntilLog('Run hook filter:api.search.videos.local.list.params', 1)
653 await servers[0].servers.waitUntilLog('Run hook filter:api.search.videos.local.list.result', 1)
74a4d531
C
654 })
655
656 it('Should run filter:api.search.videos.index.list.{params,result}', async function () {
89d241a7 657 await servers[0].search.advancedVideoSearch({
af971e06
C
658 search: {
659 search: 'Sun Quan',
660 searchTarget: 'search-index'
661 }
74a4d531
C
662 })
663
89d241a7
C
664 await servers[0].servers.waitUntilLog('Run hook filter:api.search.videos.local.list.params', 1)
665 await servers[0].servers.waitUntilLog('Run hook filter:api.search.videos.local.list.result', 1)
666 await servers[0].servers.waitUntilLog('Run hook filter:api.search.videos.index.list.params', 1)
667 await servers[0].servers.waitUntilLog('Run hook filter:api.search.videos.index.list.result', 1)
74a4d531
C
668 })
669
670 it('Should run filter:api.search.video-channels.local.list.{params,result}', async function () {
89d241a7 671 await servers[0].search.advancedChannelSearch({
af971e06
C
672 search: {
673 search: 'Sun Ce'
674 }
74a4d531
C
675 })
676
89d241a7
C
677 await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-channels.local.list.params', 1)
678 await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-channels.local.list.result', 1)
74a4d531
C
679 })
680
681 it('Should run filter:api.search.video-channels.index.list.{params,result}', async function () {
89d241a7 682 await servers[0].search.advancedChannelSearch({
af971e06
C
683 search: {
684 search: 'Sun Ce',
685 searchTarget: 'search-index'
686 }
74a4d531
C
687 })
688
89d241a7
C
689 await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-channels.local.list.params', 1)
690 await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-channels.local.list.result', 1)
691 await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-channels.index.list.params', 1)
692 await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-channels.index.list.result', 1)
74a4d531 693 })
37a44fc9
C
694
695 it('Should run filter:api.search.video-playlists.local.list.{params,result}', async function () {
89d241a7 696 await servers[0].search.advancedPlaylistSearch({
af971e06
C
697 search: {
698 search: 'Sun Jian'
699 }
37a44fc9
C
700 })
701
89d241a7
C
702 await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-playlists.local.list.params', 1)
703 await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-playlists.local.list.result', 1)
37a44fc9
C
704 })
705
706 it('Should run filter:api.search.video-playlists.index.list.{params,result}', async function () {
89d241a7 707 await servers[0].search.advancedPlaylistSearch({
af971e06
C
708 search: {
709 search: 'Sun Jian',
710 searchTarget: 'search-index'
711 }
37a44fc9
C
712 })
713
89d241a7
C
714 await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-playlists.local.list.params', 1)
715 await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-playlists.local.list.result', 1)
716 await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-playlists.index.list.params', 1)
717 await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-playlists.index.list.result', 1)
37a44fc9 718 })
74a4d531
C
719 })
720
d17d7430
C
721 describe('Upload/import/live attributes filters', function () {
722
723 before(async function () {
724 await servers[0].config.enableLive({ transcoding: false, allowReplay: false })
725 await servers[0].config.enableImports()
726 await servers[0].config.disableTranscoding()
727 })
728
729 it('Should run filter:api.video.upload.video-attribute.result', async function () {
730 for (const mode of [ 'legacy' as 'legacy', 'resumable' as 'resumable' ]) {
731 const { id } = await servers[0].videos.upload({ attributes: { name: 'video', description: 'upload' }, mode })
732
733 const video = await servers[0].videos.get({ id })
734 expect(video.description).to.equal('upload - filter:api.video.upload.video-attribute.result')
735 }
736 })
737
738 it('Should run filter:api.video.import-url.video-attribute.result', async function () {
739 const attributes = {
740 name: 'video',
741 description: 'import url',
742 channelId: servers[0].store.channel.id,
743 targetUrl: FIXTURE_URLS.goodVideo,
744 privacy: VideoPrivacy.PUBLIC
745 }
746 const { video: { id } } = await servers[0].imports.importVideo({ attributes })
747
748 const video = await servers[0].videos.get({ id })
749 expect(video.description).to.equal('import url - filter:api.video.import-url.video-attribute.result')
750 })
751
752 it('Should run filter:api.video.import-torrent.video-attribute.result', async function () {
753 const attributes = {
754 name: 'video',
755 description: 'import torrent',
756 channelId: servers[0].store.channel.id,
757 magnetUri: FIXTURE_URLS.magnet,
758 privacy: VideoPrivacy.PUBLIC
759 }
760 const { video: { id } } = await servers[0].imports.importVideo({ attributes })
761
762 const video = await servers[0].videos.get({ id })
763 expect(video.description).to.equal('import torrent - filter:api.video.import-torrent.video-attribute.result')
764 })
765
766 it('Should run filter:api.video.live.video-attribute.result', async function () {
767 const fields = {
768 name: 'live',
769 description: 'live',
770 channelId: servers[0].store.channel.id,
771 privacy: VideoPrivacy.PUBLIC
772 }
773 const { id } = await servers[0].live.create({ fields })
774
775 const video = await servers[0].videos.get({ id })
776 expect(video.description).to.equal('live - filter:api.video.live.video-attribute.result')
777 })
778 })
779
65058050
C
780 describe('Stats filters', function () {
781
782 it('Should run filter:api.server.stats.get.result', async function () {
783 const data = await servers[0].stats.get()
784
785 expect((data as any).customStats).to.equal(14)
786 })
787
788 })
789
22df69fd
C
790 describe('Job queue filters', function () {
791 let videoUUID: string
792
793 before(async function () {
794 this.timeout(120_000)
795
f59462ec 796 await servers[0].config.enableMinimumTranscoding()
22df69fd
C
797 const { uuid } = await servers[0].videos.quickUpload({ name: 'studio' })
798
799 const video = await servers[0].videos.get({ id: uuid })
800 expect(video.duration).at.least(2)
801 videoUUID = video.uuid
802
803 await waitJobs(servers)
804
805 await servers[0].config.enableStudio()
806 })
807
808 it('Should run filter:job-queue.process.params', async function () {
809 this.timeout(120_000)
810
811 await servers[0].videoStudio.createEditionTasks({
812 videoId: videoUUID,
813 tasks: [
814 {
815 name: 'add-intro',
816 options: {
817 file: 'video_very_short_240p.mp4'
818 }
819 }
820 ]
821 })
822
823 await waitJobs(servers)
824
825 await servers[0].servers.waitUntilLog('Run hook filter:job-queue.process.params', 1, false)
826
827 const video = await servers[0].videos.get({ id: videoUUID })
828 expect(video.duration).at.most(2)
829 })
830
831 it('Should run filter:job-queue.process.result', async function () {
832 await servers[0].servers.waitUntilLog('Run hook filter:job-queue.process.result', 1, false)
833 })
834 })
835
ebb9e53a
C
836 describe('Transcoding filters', async function () {
837
64fd6158 838 it('Should run filter:transcoding.auto.resolutions-to-transcode.result', async function () {
ebb9e53a
C
839 const { uuid } = await servers[0].videos.quickUpload({ name: 'transcode-filter' })
840
841 await waitJobs(servers)
842
843 const video = await servers[0].videos.get({ id: uuid })
844 expect(video.files).to.have.lengthOf(2)
845 expect(video.files.find(f => f.resolution.id === 100 as any)).to.exist
846 })
847 })
848
0260dc8a
C
849 describe('Video channel filters', async function () {
850
851 it('Should run filter:api.video-channels.list.params', async function () {
852 const { data } = await servers[0].channels.list({ start: 0, count: 0 })
853
854 // plugin do +1 to the count parameter
855 expect(data).to.have.lengthOf(1)
856 })
857
858 it('Should run filter:api.video-channels.list.result', async function () {
859 const { total } = await servers[0].channels.list({ start: 0, count: 1 })
860
861 // plugin do +1 to the total parameter
862 expect(total).to.equal(4)
863 })
864
865 it('Should run filter:api.video-channel.get.result', async function () {
866 const channel = await servers[0].channels.get({ channelName: 'root_channel' })
867 expect(channel.displayName).to.equal('Main root channel <3')
868 })
869 })
870
58e735dd
C
871 describe('Activity Pub', function () {
872
873 it('Should run filter:activity-pub.activity.context.build.result', async function () {
874 const { body } = await makeActivityPubGetRequest(servers[0].url, '/w/' + videoUUID)
875 expect(body.type).to.equal('Video')
876
2b02a9b9
C
877 expect(body['@context'].some(c => {
878 return typeof c === 'object' && c.recordedAt === 'https://schema.org/recordedAt'
879 })).to.be.true
58e735dd
C
880 })
881
882 it('Should run filter:activity-pub.video.json-ld.build.result', async function () {
883 const { body } = await makeActivityPubGetRequest(servers[0].url, '/w/' + videoUUID)
884 expect(body.name).to.equal('default video 0')
885 expect(body.videoName).to.equal('default video 0')
886 })
887 })
888
9b474844 889 after(async function () {
89cd1275 890 await cleanupTests(servers)
9b474844
C
891 })
892})