]>
Commit | Line | Data |
---|---|---|
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | |
2 | ||
3 | import { expect } from 'chai' | |
4 | import { | |
5 | HttpStatusCode, | |
6 | PeerTubeProblemDocument, | |
7 | VideoDetails, | |
8 | VideoImportState, | |
9 | VideoPlaylist, | |
10 | VideoPlaylistPrivacy, | |
11 | VideoPrivacy | |
12 | } from '@shared/models' | |
13 | import { | |
14 | cleanupTests, | |
15 | createMultipleServers, | |
16 | doubleFollow, | |
17 | makeActivityPubGetRequest, | |
18 | makeGetRequest, | |
19 | makeRawRequest, | |
20 | PeerTubeServer, | |
21 | PluginsCommand, | |
22 | setAccessTokensToServers, | |
23 | setDefaultVideoChannel, | |
24 | waitJobs | |
25 | } from '@shared/server-commands' | |
26 | import { FIXTURE_URLS } from '../shared' | |
27 | ||
28 | describe('Test plugin filter hooks', function () { | |
29 | let servers: PeerTubeServer[] | |
30 | let videoUUID: string | |
31 | let threadId: number | |
32 | let videoPlaylistUUID: string | |
33 | ||
34 | before(async function () { | |
35 | this.timeout(120000) | |
36 | ||
37 | servers = await createMultipleServers(2) | |
38 | await setAccessTokensToServers(servers) | |
39 | await setDefaultVideoChannel(servers) | |
40 | await doubleFollow(servers[0], servers[1]) | |
41 | ||
42 | await servers[0].plugins.install({ path: PluginsCommand.getPluginTestPath() }) | |
43 | await servers[0].plugins.install({ path: PluginsCommand.getPluginTestPath('-filter-translations') }) | |
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 | } | |
54 | ||
55 | for (let i = 0; i < 10; i++) { | |
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 } }) | |
58 | } | |
59 | ||
60 | const { data } = await servers[0].videos.list() | |
61 | videoUUID = data[0].uuid | |
62 | ||
63 | await servers[0].config.updateCustomSubConfig({ | |
64 | newConfig: { | |
65 | live: { enabled: true }, | |
66 | signup: { enabled: true }, | |
67 | import: { | |
68 | videos: { | |
69 | http: { enabled: true }, | |
70 | torrent: { enabled: true } | |
71 | } | |
72 | } | |
73 | } | |
74 | }) | |
75 | ||
76 | // Root subscribes to itself | |
77 | await servers[0].subscriptions.add({ targetUri: 'root_channel@' + servers[0].host }) | |
78 | }) | |
79 | ||
80 | describe('Videos', function () { | |
81 | ||
82 | it('Should run filter:api.videos.list.params', async function () { | |
83 | const { data } = await servers[0].videos.list({ start: 0, count: 2 }) | |
84 | ||
85 | // 2 plugins do +1 to the count parameter | |
86 | expect(data).to.have.lengthOf(4) | |
87 | }) | |
88 | ||
89 | it('Should run filter:api.videos.list.result', async function () { | |
90 | const { total } = await servers[0].videos.list({ start: 0, count: 0 }) | |
91 | ||
92 | // Plugin do +1 to the total result | |
93 | expect(total).to.equal(11) | |
94 | }) | |
95 | ||
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 | }) | |
101 | ||
102 | // 1 plugin do +1 to the count parameter | |
103 | expect(data).to.have.lengthOf(3) | |
104 | }) | |
105 | ||
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 | }) | |
111 | ||
112 | // Plugin do +1 to the total result | |
113 | expect(total).to.equal(11) | |
114 | }) | |
115 | ||
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 }) | |
118 | ||
119 | // 1 plugin do +1 to the count parameter | |
120 | expect(data).to.have.lengthOf(3) | |
121 | }) | |
122 | ||
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 }) | |
125 | ||
126 | // Plugin do +2 to the total result | |
127 | expect(total).to.equal(12) | |
128 | }) | |
129 | ||
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 }) | |
132 | ||
133 | // 1 plugin do +3 to the count parameter | |
134 | expect(data).to.have.lengthOf(5) | |
135 | }) | |
136 | ||
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 }) | |
139 | ||
140 | // Plugin do +3 to the total result | |
141 | expect(total).to.equal(13) | |
142 | }) | |
143 | ||
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 }) | |
146 | ||
147 | // 1 plugin do +4 to the count parameter | |
148 | expect(data).to.have.lengthOf(6) | |
149 | }) | |
150 | ||
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 }) | |
153 | ||
154 | // Plugin do +4 to the total result | |
155 | expect(total).to.equal(14) | |
156 | }) | |
157 | ||
158 | it('Should run filter:api.user.me.subscription-videos.list.params', async function () { | |
159 | const { data } = await servers[0].videos.listMySubscriptionVideos({ start: 0, count: 2 }) | |
160 | ||
161 | // 1 plugin do +1 to the count parameter | |
162 | expect(data).to.have.lengthOf(3) | |
163 | }) | |
164 | ||
165 | it('Should run filter:api.user.me.subscription-videos.list.result', async function () { | |
166 | const { total } = await servers[0].videos.listMySubscriptionVideos({ start: 0, count: 2 }) | |
167 | ||
168 | // Plugin do +4 to the total result | |
169 | expect(total).to.equal(14) | |
170 | }) | |
171 | ||
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 | }) | |
176 | }) | |
177 | ||
178 | describe('Video/live/import accept', function () { | |
179 | ||
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 | }) | |
183 | ||
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 | } | |
190 | ||
191 | await servers[0].live.create({ fields: attributes, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | |
192 | }) | |
193 | ||
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 | }) | |
203 | ||
204 | it('Should run filter:api.video.pre-import-torrent.accept.result', async function () { | |
205 | const attributes = { | |
206 | name: 'bad torrent', | |
207 | privacy: VideoPrivacy.PUBLIC, | |
208 | channelId: servers[0].store.channel.id, | |
209 | torrentfile: 'video-720p.torrent' as any | |
210 | } | |
211 | await servers[0].imports.importVideo({ attributes, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | |
212 | }) | |
213 | ||
214 | it('Should run filter:api.video.post-import-url.accept.result', async function () { | |
215 | this.timeout(60000) | |
216 | ||
217 | let videoImportId: number | |
218 | ||
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 | } | |
229 | ||
230 | await waitJobs(servers) | |
231 | ||
232 | { | |
233 | const body = await servers[0].imports.getMyVideoImports() | |
234 | const videoImports = body.data | |
235 | ||
236 | const videoImport = videoImports.find(i => i.id === videoImportId) | |
237 | ||
238 | expect(videoImport.state.id).to.equal(VideoImportState.REJECTED) | |
239 | expect(videoImport.state.label).to.equal('Rejected') | |
240 | } | |
241 | }) | |
242 | ||
243 | it('Should run filter:api.video.post-import-torrent.accept.result', async function () { | |
244 | this.timeout(60000) | |
245 | ||
246 | let videoImportId: number | |
247 | ||
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 | } | |
258 | ||
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) | |
265 | ||
266 | expect(videoImport.state.id).to.equal(VideoImportState.REJECTED) | |
267 | expect(videoImport.state.label).to.equal('Rejected') | |
268 | } | |
269 | }) | |
270 | }) | |
271 | ||
272 | describe('Video comments accept', function () { | |
273 | ||
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 | }) | |
280 | }) | |
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 | }) | |
298 | }) | |
299 | ||
300 | it('Should run filter:activity-pub.remote-video-comment.create.accept.result on a thread creation', async function () { | |
301 | this.timeout(30000) | |
302 | ||
303 | await servers[1].comments.createThread({ videoId: videoUUID, text: 'comment with bad word' }) | |
304 | ||
305 | await waitJobs(servers) | |
306 | ||
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 | |
324 | ||
325 | await servers[1].comments.addReply({ | |
326 | videoId: videoUUID, | |
327 | toCommentId: threadIdServer2, | |
328 | text: 'comment with bad word' | |
329 | }) | |
330 | ||
331 | await waitJobs(servers) | |
332 | ||
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 | }) | |
344 | }) | |
345 | ||
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 }) | |
350 | ||
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 | }) | |
377 | }) | |
378 | ||
379 | describe('filter:video.auto-blacklist.result', function () { | |
380 | ||
381 | async function checkIsBlacklisted (id: number | string, value: boolean) { | |
382 | const video = await servers[0].videos.getWithToken({ id }) | |
383 | expect(video.blacklisted).to.equal(value) | |
384 | } | |
385 | ||
386 | it('Should blacklist on upload', async function () { | |
387 | const { uuid } = await servers[0].videos.upload({ attributes: { name: 'video please blacklist me' } }) | |
388 | await checkIsBlacklisted(uuid, true) | |
389 | }) | |
390 | ||
391 | it('Should blacklist on import', async function () { | |
392 | this.timeout(15000) | |
393 | ||
394 | const attributes = { | |
395 | name: 'video please blacklist me', | |
396 | targetUrl: FIXTURE_URLS.goodVideo, | |
397 | channelId: servers[0].store.channel.id | |
398 | } | |
399 | const body = await servers[0].imports.importVideo({ attributes }) | |
400 | await checkIsBlacklisted(body.video.uuid, true) | |
401 | }) | |
402 | ||
403 | it('Should blacklist on update', async function () { | |
404 | const { uuid } = await servers[0].videos.upload({ attributes: { name: 'video' } }) | |
405 | await checkIsBlacklisted(uuid, false) | |
406 | ||
407 | await servers[0].videos.update({ id: uuid, attributes: { name: 'please blacklist me' } }) | |
408 | await checkIsBlacklisted(uuid, true) | |
409 | }) | |
410 | ||
411 | it('Should blacklist on remote upload', async function () { | |
412 | this.timeout(120000) | |
413 | ||
414 | const { uuid } = await servers[1].videos.upload({ attributes: { name: 'remote please blacklist me' } }) | |
415 | await waitJobs(servers) | |
416 | ||
417 | await checkIsBlacklisted(uuid, true) | |
418 | }) | |
419 | ||
420 | it('Should blacklist on remote update', async function () { | |
421 | this.timeout(120000) | |
422 | ||
423 | const { uuid } = await servers[1].videos.upload({ attributes: { name: 'video' } }) | |
424 | await waitJobs(servers) | |
425 | ||
426 | await checkIsBlacklisted(uuid, false) | |
427 | ||
428 | await servers[1].videos.update({ id: uuid, attributes: { name: 'please blacklist me' } }) | |
429 | await waitJobs(servers) | |
430 | ||
431 | await checkIsBlacklisted(uuid, true) | |
432 | }) | |
433 | }) | |
434 | ||
435 | describe('Should run filter:api.user.signup.allowed.result', function () { | |
436 | ||
437 | before(async function () { | |
438 | await servers[0].config.updateExistingSubConfig({ newConfig: { signup: { requiresApproval: false } } }) | |
439 | }) | |
440 | ||
441 | it('Should run on config endpoint', async function () { | |
442 | const body = await servers[0].config.getConfig() | |
443 | expect(body.signup.allowed).to.be.true | |
444 | }) | |
445 | ||
446 | it('Should allow a signup', async function () { | |
447 | await servers[0].registrations.register({ username: 'john1' }) | |
448 | }) | |
449 | ||
450 | it('Should not allow a signup', async function () { | |
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', | |
479 | expectedStatus: HttpStatusCode.FORBIDDEN_403 | |
480 | }) | |
481 | ||
482 | expect((body as unknown as PeerTubeProblemDocument).error).to.equal('No jma 2') | |
483 | }) | |
484 | }) | |
485 | ||
486 | describe('Download hooks', function () { | |
487 | const downloadVideos: VideoDetails[] = [] | |
488 | let downloadVideo2Token: string | |
489 | ||
490 | before(async function () { | |
491 | this.timeout(120000) | |
492 | ||
493 | await servers[0].config.updateCustomSubConfig({ | |
494 | newConfig: { | |
495 | transcoding: { | |
496 | webtorrent: { | |
497 | enabled: true | |
498 | }, | |
499 | hls: { | |
500 | enabled: true | |
501 | } | |
502 | } | |
503 | } | |
504 | }) | |
505 | ||
506 | const uuids: string[] = [] | |
507 | ||
508 | for (const name of [ 'bad torrent', 'bad file', 'bad playlist file' ]) { | |
509 | const uuid = (await servers[0].videos.quickUpload({ name })).uuid | |
510 | uuids.push(uuid) | |
511 | } | |
512 | ||
513 | await waitJobs(servers) | |
514 | ||
515 | for (const uuid of uuids) { | |
516 | downloadVideos.push(await servers[0].videos.get({ id: uuid })) | |
517 | } | |
518 | ||
519 | downloadVideo2Token = await servers[0].videoToken.getVideoFileToken({ videoId: downloadVideos[2].uuid }) | |
520 | }) | |
521 | ||
522 | it('Should run filter:api.download.torrent.allowed.result', async function () { | |
523 | const res = await makeRawRequest({ url: downloadVideos[0].files[0].torrentDownloadUrl, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | |
524 | expect(res.body.error).to.equal('Liu Bei') | |
525 | ||
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 }) | |
528 | }) | |
529 | ||
530 | it('Should run filter:api.download.video.allowed.result', async function () { | |
531 | { | |
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 }) | |
539 | expect(res.body.error).to.equal('Cao Cao') | |
540 | ||
541 | for (const url of allowed) { | |
542 | await makeRawRequest({ url, expectedStatus: HttpStatusCode.OK_200 }) | |
543 | await makeRawRequest({ url, expectedStatus: HttpStatusCode.OK_200 }) | |
544 | } | |
545 | } | |
546 | ||
547 | { | |
548 | const refused = downloadVideos[2].streamingPlaylists[0].files[0].fileDownloadUrl | |
549 | ||
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 | ] | |
555 | ||
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') | |
559 | ||
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 }) | |
563 | ||
564 | // Other files work | |
565 | for (const url of allowed) { | |
566 | await makeRawRequest({ url, expectedStatus: HttpStatusCode.OK_200 }) | |
567 | } | |
568 | } | |
569 | }) | |
570 | }) | |
571 | ||
572 | describe('Embed filters', function () { | |
573 | const embedVideos: VideoDetails[] = [] | |
574 | const embedPlaylists: VideoPlaylist[] = [] | |
575 | ||
576 | before(async function () { | |
577 | this.timeout(60000) | |
578 | ||
579 | await servers[0].config.disableTranscoding() | |
580 | ||
581 | for (const name of [ 'bad embed', 'good embed' ]) { | |
582 | { | |
583 | const uuid = (await servers[0].videos.quickUpload({ name })).uuid | |
584 | embedVideos.push(await servers[0].videos.get({ id: uuid })) | |
585 | } | |
586 | ||
587 | { | |
588 | const attributes = { displayName: name, videoChannelId: servers[0].store.channel.id, privacy: VideoPlaylistPrivacy.PUBLIC } | |
589 | const { id } = await servers[0].playlists.create({ attributes }) | |
590 | ||
591 | const playlist = await servers[0].playlists.get({ playlistId: id }) | |
592 | embedPlaylists.push(playlist) | |
593 | } | |
594 | } | |
595 | }) | |
596 | ||
597 | it('Should run filter:html.embed.video.allowed.result', async function () { | |
598 | const res = await makeGetRequest({ url: servers[0].url, path: embedVideos[0].embedPath, expectedStatus: HttpStatusCode.OK_200 }) | |
599 | expect(res.text).to.equal('Lu Bu') | |
600 | }) | |
601 | ||
602 | it('Should run filter:html.embed.video-playlist.allowed.result', async function () { | |
603 | const res = await makeGetRequest({ url: servers[0].url, path: embedPlaylists[0].embedPath, expectedStatus: HttpStatusCode.OK_200 }) | |
604 | expect(res.text).to.equal('Diao Chan') | |
605 | }) | |
606 | }) | |
607 | ||
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 | ||
629 | describe('Search filters', function () { | |
630 | ||
631 | before(async function () { | |
632 | await servers[0].config.updateCustomSubConfig({ | |
633 | newConfig: { | |
634 | search: { | |
635 | searchIndex: { | |
636 | enabled: true, | |
637 | isDefaultSearch: false, | |
638 | disableLocalSearch: false | |
639 | } | |
640 | } | |
641 | } | |
642 | }) | |
643 | }) | |
644 | ||
645 | it('Should run filter:api.search.videos.local.list.{params,result}', async function () { | |
646 | await servers[0].search.advancedVideoSearch({ | |
647 | search: { | |
648 | search: 'Sun Quan' | |
649 | } | |
650 | }) | |
651 | ||
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) | |
654 | }) | |
655 | ||
656 | it('Should run filter:api.search.videos.index.list.{params,result}', async function () { | |
657 | await servers[0].search.advancedVideoSearch({ | |
658 | search: { | |
659 | search: 'Sun Quan', | |
660 | searchTarget: 'search-index' | |
661 | } | |
662 | }) | |
663 | ||
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) | |
668 | }) | |
669 | ||
670 | it('Should run filter:api.search.video-channels.local.list.{params,result}', async function () { | |
671 | await servers[0].search.advancedChannelSearch({ | |
672 | search: { | |
673 | search: 'Sun Ce' | |
674 | } | |
675 | }) | |
676 | ||
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) | |
679 | }) | |
680 | ||
681 | it('Should run filter:api.search.video-channels.index.list.{params,result}', async function () { | |
682 | await servers[0].search.advancedChannelSearch({ | |
683 | search: { | |
684 | search: 'Sun Ce', | |
685 | searchTarget: 'search-index' | |
686 | } | |
687 | }) | |
688 | ||
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) | |
693 | }) | |
694 | ||
695 | it('Should run filter:api.search.video-playlists.local.list.{params,result}', async function () { | |
696 | await servers[0].search.advancedPlaylistSearch({ | |
697 | search: { | |
698 | search: 'Sun Jian' | |
699 | } | |
700 | }) | |
701 | ||
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) | |
704 | }) | |
705 | ||
706 | it('Should run filter:api.search.video-playlists.index.list.{params,result}', async function () { | |
707 | await servers[0].search.advancedPlaylistSearch({ | |
708 | search: { | |
709 | search: 'Sun Jian', | |
710 | searchTarget: 'search-index' | |
711 | } | |
712 | }) | |
713 | ||
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) | |
718 | }) | |
719 | }) | |
720 | ||
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 | ||
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 | ||
790 | describe('Job queue filters', function () { | |
791 | let videoUUID: string | |
792 | ||
793 | before(async function () { | |
794 | this.timeout(120_000) | |
795 | ||
796 | await servers[0].config.enableMinimumTranscoding() | |
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 | ||
836 | describe('Transcoding filters', async function () { | |
837 | ||
838 | it('Should run filter:transcoding.auto.resolutions-to-transcode.result', async function () { | |
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 | ||
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 | ||
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 | ||
877 | expect(body['@context'].some(c => { | |
878 | return typeof c === 'object' && c.recordedAt === 'https://schema.org/recordedAt' | |
879 | })).to.be.true | |
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 | ||
889 | after(async function () { | |
890 | await cleanupTests(servers) | |
891 | }) | |
892 | }) |