diff options
author | Chocobozzz <me@florianbigard.com> | 2019-07-22 11:14:58 +0200 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2019-07-24 10:58:16 +0200 |
commit | 6691c52280363fc42f7865230ebb3741f02fff23 (patch) | |
tree | 071f9a4d7814c46dcfec100268cb0a0cc76e5204 | |
parent | 89cd12756035a146bbcc4db78cd3cd64f2f3d88d (diff) | |
download | PeerTube-6691c52280363fc42f7865230ebb3741f02fff23.tar.gz PeerTube-6691c52280363fc42f7865230ebb3741f02fff23.tar.zst PeerTube-6691c52280363fc42f7865230ebb3741f02fff23.zip |
Add filter hooks tests
-rw-r--r-- | server/controllers/api/videos/comment.ts | 2 | ||||
-rw-r--r-- | server/controllers/api/videos/import.ts | 2 | ||||
-rw-r--r-- | server/controllers/api/videos/index.ts | 36 | ||||
-rw-r--r-- | server/lib/activitypub/process/process-create.ts | 4 | ||||
-rw-r--r-- | server/lib/activitypub/videos.ts | 28 | ||||
-rw-r--r-- | server/lib/video-blacklist.ts | 33 | ||||
-rw-r--r-- | server/middlewares/validators/videos/video-comments.ts | 10 | ||||
-rw-r--r-- | server/tests/fixtures/peertube-plugin-test/main.js | 57 | ||||
-rw-r--r-- | server/tests/plugins/filter-hooks.ts | 123 | ||||
-rw-r--r-- | shared/models/plugins/server-hook.model.ts | 6 |
10 files changed, 260 insertions, 41 deletions
diff --git a/server/controllers/api/videos/comment.ts b/server/controllers/api/videos/comment.ts index feda71bdd..39d521f5f 100644 --- a/server/controllers/api/videos/comment.ts +++ b/server/controllers/api/videos/comment.ts | |||
@@ -110,7 +110,7 @@ async function listVideoThreadComments (req: express.Request, res: express.Respo | |||
110 | const apiOptions = await Hooks.wrapObject({ | 110 | const apiOptions = await Hooks.wrapObject({ |
111 | videoId: video.id, | 111 | videoId: video.id, |
112 | threadId: res.locals.videoCommentThread.id, | 112 | threadId: res.locals.videoCommentThread.id, |
113 | user: user | 113 | user |
114 | }, 'filter:api.video-thread-comments.list.params') | 114 | }, 'filter:api.video-thread-comments.list.params') |
115 | 115 | ||
116 | resultList = await Hooks.wrapPromiseFun( | 116 | resultList = await Hooks.wrapPromiseFun( |
diff --git a/server/controllers/api/videos/import.ts b/server/controllers/api/videos/import.ts index dcba0e08f..47c6f122c 100644 --- a/server/controllers/api/videos/import.ts +++ b/server/controllers/api/videos/import.ts | |||
@@ -245,7 +245,7 @@ function insertIntoDB (parameters: { | |||
245 | if (thumbnailModel) await videoCreated.addAndSaveThumbnail(thumbnailModel, t) | 245 | if (thumbnailModel) await videoCreated.addAndSaveThumbnail(thumbnailModel, t) |
246 | if (previewModel) await videoCreated.addAndSaveThumbnail(previewModel, t) | 246 | if (previewModel) await videoCreated.addAndSaveThumbnail(previewModel, t) |
247 | 247 | ||
248 | await autoBlacklistVideoIfNeeded(video, user, t) | 248 | await autoBlacklistVideoIfNeeded({ video, user, isRemote: false, isNew: true, transaction: t }) |
249 | 249 | ||
250 | // Set tags to the video | 250 | // Set tags to the video |
251 | if (tags) { | 251 | if (tags) { |
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts index 11e468df2..6a79a16c7 100644 --- a/server/controllers/api/videos/index.ts +++ b/server/controllers/api/videos/index.ts | |||
@@ -268,7 +268,13 @@ async function addVideo (req: express.Request, res: express.Response) { | |||
268 | }, { transaction: t }) | 268 | }, { transaction: t }) |
269 | } | 269 | } |
270 | 270 | ||
271 | const videoWasAutoBlacklisted = await autoBlacklistVideoIfNeeded(video, res.locals.oauth.token.User, t) | 271 | const videoWasAutoBlacklisted = await autoBlacklistVideoIfNeeded({ |
272 | video, | ||
273 | user: res.locals.oauth.token.User, | ||
274 | isRemote: false, | ||
275 | isNew: true, | ||
276 | transaction: t | ||
277 | }) | ||
272 | if (!videoWasAutoBlacklisted) await federateVideoIfNeeded(video, true, t) | 278 | if (!videoWasAutoBlacklisted) await federateVideoIfNeeded(video, true, t) |
273 | 279 | ||
274 | auditLogger.create(getAuditIdFromRes(res), new VideoAuditView(videoCreated.toFormattedDetailsJSON())) | 280 | auditLogger.create(getAuditIdFromRes(res), new VideoAuditView(videoCreated.toFormattedDetailsJSON())) |
@@ -336,16 +342,16 @@ async function updateVideo (req: express.Request, res: express.Response) { | |||
336 | const sequelizeOptions = { transaction: t } | 342 | const sequelizeOptions = { transaction: t } |
337 | const oldVideoChannel = videoInstance.VideoChannel | 343 | const oldVideoChannel = videoInstance.VideoChannel |
338 | 344 | ||
339 | if (videoInfoToUpdate.name !== undefined) videoInstance.set('name', videoInfoToUpdate.name) | 345 | if (videoInfoToUpdate.name !== undefined) videoInstance.name = videoInfoToUpdate.name |
340 | if (videoInfoToUpdate.category !== undefined) videoInstance.set('category', videoInfoToUpdate.category) | 346 | if (videoInfoToUpdate.category !== undefined) videoInstance.category = videoInfoToUpdate.category |
341 | if (videoInfoToUpdate.licence !== undefined) videoInstance.set('licence', videoInfoToUpdate.licence) | 347 | if (videoInfoToUpdate.licence !== undefined) videoInstance.licence = videoInfoToUpdate.licence |
342 | if (videoInfoToUpdate.language !== undefined) videoInstance.set('language', videoInfoToUpdate.language) | 348 | if (videoInfoToUpdate.language !== undefined) videoInstance.language = videoInfoToUpdate.language |
343 | if (videoInfoToUpdate.nsfw !== undefined) videoInstance.set('nsfw', videoInfoToUpdate.nsfw) | 349 | if (videoInfoToUpdate.nsfw !== undefined) videoInstance.nsfw = videoInfoToUpdate.nsfw |
344 | if (videoInfoToUpdate.waitTranscoding !== undefined) videoInstance.set('waitTranscoding', videoInfoToUpdate.waitTranscoding) | 350 | if (videoInfoToUpdate.waitTranscoding !== undefined) videoInstance.waitTranscoding = videoInfoToUpdate.waitTranscoding |
345 | if (videoInfoToUpdate.support !== undefined) videoInstance.set('support', videoInfoToUpdate.support) | 351 | if (videoInfoToUpdate.support !== undefined) videoInstance.support = videoInfoToUpdate.support |
346 | if (videoInfoToUpdate.description !== undefined) videoInstance.set('description', videoInfoToUpdate.description) | 352 | if (videoInfoToUpdate.description !== undefined) videoInstance.description = videoInfoToUpdate.description |
347 | if (videoInfoToUpdate.commentsEnabled !== undefined) videoInstance.set('commentsEnabled', videoInfoToUpdate.commentsEnabled) | 353 | if (videoInfoToUpdate.commentsEnabled !== undefined) videoInstance.commentsEnabled = videoInfoToUpdate.commentsEnabled |
348 | if (videoInfoToUpdate.downloadEnabled !== undefined) videoInstance.set('downloadEnabled', videoInfoToUpdate.downloadEnabled) | 354 | if (videoInfoToUpdate.downloadEnabled !== undefined) videoInstance.downloadEnabled = videoInfoToUpdate.downloadEnabled |
349 | 355 | ||
350 | if (videoInfoToUpdate.originallyPublishedAt !== undefined && videoInfoToUpdate.originallyPublishedAt !== null) { | 356 | if (videoInfoToUpdate.originallyPublishedAt !== undefined && videoInfoToUpdate.originallyPublishedAt !== null) { |
351 | videoInstance.originallyPublishedAt = new Date(videoInfoToUpdate.originallyPublishedAt) | 357 | videoInstance.originallyPublishedAt = new Date(videoInfoToUpdate.originallyPublishedAt) |
@@ -398,6 +404,14 @@ async function updateVideo (req: express.Request, res: express.Response) { | |||
398 | await ScheduleVideoUpdateModel.deleteByVideoId(videoInstanceUpdated.id, t) | 404 | await ScheduleVideoUpdateModel.deleteByVideoId(videoInstanceUpdated.id, t) |
399 | } | 405 | } |
400 | 406 | ||
407 | await autoBlacklistVideoIfNeeded({ | ||
408 | video: videoInstanceUpdated, | ||
409 | user: res.locals.oauth.token.User, | ||
410 | isRemote: false, | ||
411 | isNew: false, | ||
412 | transaction: t | ||
413 | }) | ||
414 | |||
401 | const isNewVideo = wasPrivateVideo && videoInstanceUpdated.privacy !== VideoPrivacy.PRIVATE | 415 | const isNewVideo = wasPrivateVideo && videoInstanceUpdated.privacy !== VideoPrivacy.PRIVATE |
402 | 416 | ||
403 | // Don't send update if the video was unfederated | 417 | // Don't send update if the video was unfederated |
diff --git a/server/lib/activitypub/process/process-create.ts b/server/lib/activitypub/process/process-create.ts index daf846513..b9f584aa5 100644 --- a/server/lib/activitypub/process/process-create.ts +++ b/server/lib/activitypub/process/process-create.ts | |||
@@ -48,9 +48,9 @@ export { | |||
48 | async function processCreateVideo (activity: ActivityCreate) { | 48 | async function processCreateVideo (activity: ActivityCreate) { |
49 | const videoToCreateData = activity.object as VideoTorrentObject | 49 | const videoToCreateData = activity.object as VideoTorrentObject |
50 | 50 | ||
51 | const { video, created } = await getOrCreateVideoAndAccountAndChannel({ videoObject: videoToCreateData }) | 51 | const { video, created, autoBlacklisted } = await getOrCreateVideoAndAccountAndChannel({ videoObject: videoToCreateData }) |
52 | 52 | ||
53 | if (created) Notifier.Instance.notifyOnNewVideo(video) | 53 | if (created && !autoBlacklisted) Notifier.Instance.notifyOnNewVideo(video) |
54 | 54 | ||
55 | return video | 55 | return video |
56 | } | 56 | } |
diff --git a/server/lib/activitypub/videos.ts b/server/lib/activitypub/videos.ts index dade6b55f..67b433165 100644 --- a/server/lib/activitypub/videos.ts +++ b/server/lib/activitypub/videos.ts | |||
@@ -224,11 +224,11 @@ async function getOrCreateVideoAndAccountAndChannel (options: { | |||
224 | if (!fetchedVideo) throw new Error('Cannot fetch remote video with url: ' + videoUrl) | 224 | if (!fetchedVideo) throw new Error('Cannot fetch remote video with url: ' + videoUrl) |
225 | 225 | ||
226 | const channelActor = await getOrCreateVideoChannelFromVideoObject(fetchedVideo) | 226 | const channelActor = await getOrCreateVideoChannelFromVideoObject(fetchedVideo) |
227 | const video = await retryTransactionWrapper(createVideo, fetchedVideo, channelActor, syncParam.thumbnail) | 227 | const { autoBlacklisted, videoCreated } = await retryTransactionWrapper(createVideo, fetchedVideo, channelActor, syncParam.thumbnail) |
228 | 228 | ||
229 | await syncVideoExternalAttributes(video, fetchedVideo, syncParam) | 229 | await syncVideoExternalAttributes(videoCreated, fetchedVideo, syncParam) |
230 | 230 | ||
231 | return { video, created: true } | 231 | return { video: videoCreated, created: true, autoBlacklisted } |
232 | } | 232 | } |
233 | 233 | ||
234 | async function updateVideoFromAP (options: { | 234 | async function updateVideoFromAP (options: { |
@@ -354,7 +354,13 @@ async function updateVideoFromAP (options: { | |||
354 | } | 354 | } |
355 | }) | 355 | }) |
356 | 356 | ||
357 | const autoBlacklisted = await autoBlacklistVideoIfNeeded(video, undefined, undefined) | 357 | const autoBlacklisted = await autoBlacklistVideoIfNeeded({ |
358 | video, | ||
359 | user: undefined, | ||
360 | isRemote: true, | ||
361 | isNew: false, | ||
362 | transaction: undefined | ||
363 | }) | ||
358 | 364 | ||
359 | if (autoBlacklisted) Notifier.Instance.notifyOnVideoAutoBlacklist(video) | 365 | if (autoBlacklisted) Notifier.Instance.notifyOnVideoAutoBlacklist(video) |
360 | else if (!wasPrivateVideo || wasUnlistedVideo) Notifier.Instance.notifyOnNewVideo(video) // Notify our users? | 366 | else if (!wasPrivateVideo || wasUnlistedVideo) Notifier.Instance.notifyOnNewVideo(video) // Notify our users? |
@@ -467,7 +473,7 @@ async function createVideo (videoObject: VideoTorrentObject, channelActor: Actor | |||
467 | thumbnailModel = await promiseThumbnail | 473 | thumbnailModel = await promiseThumbnail |
468 | } | 474 | } |
469 | 475 | ||
470 | const videoCreated: VideoModel = await sequelizeTypescript.transaction(async t => { | 476 | const { autoBlacklisted, videoCreated } = await sequelizeTypescript.transaction(async t => { |
471 | const sequelizeOptions = { transaction: t } | 477 | const sequelizeOptions = { transaction: t } |
472 | 478 | ||
473 | const videoCreated = await video.save(sequelizeOptions) | 479 | const videoCreated = await video.save(sequelizeOptions) |
@@ -506,9 +512,17 @@ async function createVideo (videoObject: VideoTorrentObject, channelActor: Actor | |||
506 | }) | 512 | }) |
507 | await Promise.all(videoCaptionsPromises) | 513 | await Promise.all(videoCaptionsPromises) |
508 | 514 | ||
515 | const autoBlacklisted = await autoBlacklistVideoIfNeeded({ | ||
516 | video, | ||
517 | user: undefined, | ||
518 | isRemote: true, | ||
519 | isNew: true, | ||
520 | transaction: t | ||
521 | }) | ||
522 | |||
509 | logger.info('Remote video with uuid %s inserted.', videoObject.uuid) | 523 | logger.info('Remote video with uuid %s inserted.', videoObject.uuid) |
510 | 524 | ||
511 | return videoCreated | 525 | return { autoBlacklisted, videoCreated } |
512 | }) | 526 | }) |
513 | 527 | ||
514 | if (waitThumbnail === false) { | 528 | if (waitThumbnail === false) { |
@@ -519,7 +533,7 @@ async function createVideo (videoObject: VideoTorrentObject, channelActor: Actor | |||
519 | }) | 533 | }) |
520 | } | 534 | } |
521 | 535 | ||
522 | return videoCreated | 536 | return { autoBlacklisted, videoCreated } |
523 | } | 537 | } |
524 | 538 | ||
525 | async function videoActivityObjectToDBAttributes ( | 539 | async function videoActivityObjectToDBAttributes ( |
diff --git a/server/lib/video-blacklist.ts b/server/lib/video-blacklist.ts index 9bc996f5a..9749ce2f6 100644 --- a/server/lib/video-blacklist.ts +++ b/server/lib/video-blacklist.ts | |||
@@ -8,10 +8,17 @@ import { logger } from '../helpers/logger' | |||
8 | import { UserAdminFlag } from '../../shared/models/users/user-flag.model' | 8 | import { UserAdminFlag } from '../../shared/models/users/user-flag.model' |
9 | import { Hooks } from './plugins/hooks' | 9 | import { Hooks } from './plugins/hooks' |
10 | 10 | ||
11 | async function autoBlacklistVideoIfNeeded (video: VideoModel, user?: UserModel, transaction?: Transaction) { | 11 | async function autoBlacklistVideoIfNeeded (parameters: { |
12 | video: VideoModel, | ||
13 | user?: UserModel, | ||
14 | isRemote: boolean, | ||
15 | isNew: boolean, | ||
16 | transaction?: Transaction | ||
17 | }) { | ||
18 | const { video, user, isRemote, isNew, transaction } = parameters | ||
12 | const doAutoBlacklist = await Hooks.wrapPromiseFun( | 19 | const doAutoBlacklist = await Hooks.wrapPromiseFun( |
13 | autoBlacklistNeeded, | 20 | autoBlacklistNeeded, |
14 | { video, user }, | 21 | { video, user, isRemote, isNew }, |
15 | 'filter:video.auto-blacklist.result' | 22 | 'filter:video.auto-blacklist.result' |
16 | ) | 23 | ) |
17 | 24 | ||
@@ -23,17 +30,33 @@ async function autoBlacklistVideoIfNeeded (video: VideoModel, user?: UserModel, | |||
23 | reason: 'Auto-blacklisted. Moderator review required.', | 30 | reason: 'Auto-blacklisted. Moderator review required.', |
24 | type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED | 31 | type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED |
25 | } | 32 | } |
26 | await VideoBlacklistModel.create(videoBlacklistToCreate, { transaction }) | 33 | const [ videoBlacklist ] = await VideoBlacklistModel.findOrCreate({ |
34 | where: { | ||
35 | videoId: video.id | ||
36 | }, | ||
37 | defaults: videoBlacklistToCreate, | ||
38 | transaction | ||
39 | }) | ||
40 | |||
41 | video.VideoBlacklist = videoBlacklist | ||
27 | 42 | ||
28 | logger.info('Video %s auto-blacklisted.', video.uuid) | 43 | logger.info('Video %s auto-blacklisted.', video.uuid) |
29 | 44 | ||
30 | return true | 45 | return true |
31 | } | 46 | } |
32 | 47 | ||
33 | async function autoBlacklistNeeded (parameters: { video: VideoModel, user?: UserModel }) { | 48 | async function autoBlacklistNeeded (parameters: { |
34 | const { user } = parameters | 49 | video: VideoModel, |
50 | isRemote: boolean, | ||
51 | isNew: boolean, | ||
52 | user?: UserModel | ||
53 | }) { | ||
54 | const { user, video, isRemote, isNew } = parameters | ||
35 | 55 | ||
56 | // Already blacklisted | ||
57 | if (video.VideoBlacklist) return false | ||
36 | if (!CONFIG.AUTO_BLACKLIST.VIDEOS.OF_USERS.ENABLED || !user) return false | 58 | if (!CONFIG.AUTO_BLACKLIST.VIDEOS.OF_USERS.ENABLED || !user) return false |
59 | if (isRemote || isNew) return false | ||
37 | 60 | ||
38 | if (user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) || user.hasAdminFlag(UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST)) return false | 61 | if (user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) || user.hasAdminFlag(UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST)) return false |
39 | 62 | ||
diff --git a/server/middlewares/validators/videos/video-comments.ts b/server/middlewares/validators/videos/video-comments.ts index 9c1bfaeaa..6b8e2f318 100644 --- a/server/middlewares/validators/videos/video-comments.ts +++ b/server/middlewares/validators/videos/video-comments.ts | |||
@@ -210,13 +210,15 @@ async function isVideoCommentAccepted (req: express.Request, res: express.Respon | |||
210 | if (isReply) { | 210 | if (isReply) { |
211 | const acceptReplyParameters = Object.assign(acceptParameters, { parentComment: res.locals.videoComment }) | 211 | const acceptReplyParameters = Object.assign(acceptParameters, { parentComment: res.locals.videoComment }) |
212 | 212 | ||
213 | acceptedResult = await Hooks.wrapObject( | 213 | acceptedResult = await Hooks.wrapFun( |
214 | isLocalVideoCommentReplyAccepted(acceptReplyParameters), | 214 | isLocalVideoCommentReplyAccepted, |
215 | acceptReplyParameters, | ||
215 | 'filter:api.video-comment-reply.create.accept.result' | 216 | 'filter:api.video-comment-reply.create.accept.result' |
216 | ) | 217 | ) |
217 | } else { | 218 | } else { |
218 | acceptedResult = await Hooks.wrapObject( | 219 | acceptedResult = await Hooks.wrapFun( |
219 | isLocalVideoThreadAccepted(acceptParameters), | 220 | isLocalVideoThreadAccepted, |
221 | acceptParameters, | ||
220 | 'filter:api.video-thread.create.accept.result' | 222 | 'filter:api.video-thread.create.accept.result' |
221 | ) | 223 | ) |
222 | } | 224 | } |
diff --git a/server/tests/fixtures/peertube-plugin-test/main.js b/server/tests/fixtures/peertube-plugin-test/main.js index c5317ab41..7c53f6afe 100644 --- a/server/tests/fixtures/peertube-plugin-test/main.js +++ b/server/tests/fixtures/peertube-plugin-test/main.js | |||
@@ -26,7 +26,7 @@ async function register ({ registerHook, registerSetting, settingsManager, stora | |||
26 | 26 | ||
27 | registerHook({ | 27 | registerHook({ |
28 | target: 'filter:api.videos.list.result', | 28 | target: 'filter:api.videos.list.result', |
29 | handler: obj => ({ data: obj.data, total: obj.total + 1 }) | 29 | handler: obj => addToTotal(obj) |
30 | }) | 30 | }) |
31 | 31 | ||
32 | registerHook({ | 32 | registerHook({ |
@@ -41,12 +41,51 @@ async function register ({ registerHook, registerSetting, settingsManager, stora | |||
41 | registerHook({ | 41 | registerHook({ |
42 | target: 'filter:api.video.upload.accept.result', | 42 | target: 'filter:api.video.upload.accept.result', |
43 | handler: ({ accepted }, { videoBody }) => { | 43 | handler: ({ accepted }, { videoBody }) => { |
44 | if (accepted !== false) return { accepted: true } | 44 | if (!accepted) return { accepted: false } |
45 | if (videoBody.name.indexOf('bad word') !== -1) return { accepted: false, errorMessage: 'bad word '} | 45 | if (videoBody.name.indexOf('bad word') !== -1) return { accepted: false, errorMessage: 'bad word '} |
46 | 46 | ||
47 | return { accepted: true } | 47 | return { accepted: true } |
48 | } | 48 | } |
49 | }) | 49 | }) |
50 | |||
51 | registerHook({ | ||
52 | target: 'filter:api.video-thread.create.accept.result', | ||
53 | handler: ({ accepted }, { commentBody }) => checkCommentBadWord(accepted, commentBody) | ||
54 | }) | ||
55 | |||
56 | registerHook({ | ||
57 | target: 'filter:api.video-comment-reply.create.accept.result', | ||
58 | handler: ({ accepted }, { commentBody }) => checkCommentBadWord(accepted, commentBody) | ||
59 | }) | ||
60 | |||
61 | registerHook({ | ||
62 | target: 'filter:api.video-threads.list.params', | ||
63 | handler: obj => addToCount(obj) | ||
64 | }) | ||
65 | |||
66 | registerHook({ | ||
67 | target: 'filter:api.video-threads.list.result', | ||
68 | handler: obj => addToTotal(obj) | ||
69 | }) | ||
70 | |||
71 | registerHook({ | ||
72 | target: 'filter:api.video-thread-comments.list.result', | ||
73 | handler: obj => { | ||
74 | obj.data.forEach(c => c.text += ' <3') | ||
75 | |||
76 | return obj | ||
77 | } | ||
78 | }) | ||
79 | |||
80 | registerHook({ | ||
81 | target: 'filter:video.auto-blacklist.result', | ||
82 | handler: (blacklisted, { video }) => { | ||
83 | if (blacklisted) return true | ||
84 | if (video.name.includes('please blacklist me')) return true | ||
85 | |||
86 | return false | ||
87 | } | ||
88 | }) | ||
50 | } | 89 | } |
51 | 90 | ||
52 | async function unregister () { | 91 | async function unregister () { |
@@ -63,3 +102,17 @@ module.exports = { | |||
63 | function addToCount (obj) { | 102 | function addToCount (obj) { |
64 | return Object.assign({}, obj, { count: obj.count + 1 }) | 103 | return Object.assign({}, obj, { count: obj.count + 1 }) |
65 | } | 104 | } |
105 | |||
106 | function addToTotal (result) { | ||
107 | return { | ||
108 | data: result.data, | ||
109 | total: result.total + 1 | ||
110 | } | ||
111 | } | ||
112 | |||
113 | function checkCommentBadWord (accepted, commentBody) { | ||
114 | if (!accepted) return { accepted: false } | ||
115 | if (commentBody.text.indexOf('bad word') !== -1) return { accepted: false, errorMessage: 'bad word '} | ||
116 | |||
117 | return { accepted: true } | ||
118 | } | ||
diff --git a/server/tests/plugins/filter-hooks.ts b/server/tests/plugins/filter-hooks.ts index 4fc2c437b..ec0679b04 100644 --- a/server/tests/plugins/filter-hooks.ts +++ b/server/tests/plugins/filter-hooks.ts | |||
@@ -11,15 +11,28 @@ import { | |||
11 | } from '../../../shared/extra-utils/server/servers' | 11 | } from '../../../shared/extra-utils/server/servers' |
12 | import { | 12 | import { |
13 | addVideoCommentReply, | 13 | addVideoCommentReply, |
14 | addVideoCommentThread, deleteVideoComment, | 14 | addVideoCommentThread, |
15 | getPluginTestPath, getVideosList, | 15 | deleteVideoComment, |
16 | installPlugin, removeVideo, | 16 | getPluginTestPath, |
17 | getVideosList, | ||
18 | installPlugin, | ||
19 | removeVideo, | ||
17 | setAccessTokensToServers, | 20 | setAccessTokensToServers, |
18 | updateVideo, | 21 | updateVideo, |
19 | uploadVideo, | 22 | uploadVideo, |
20 | viewVideo, | 23 | viewVideo, |
21 | getVideosListPagination, getVideo | 24 | getVideosListPagination, |
25 | getVideo, | ||
26 | getVideoCommentThreads, | ||
27 | getVideoThreadComments, | ||
28 | getVideoWithToken, | ||
29 | setDefaultVideoChannel, | ||
30 | waitJobs, | ||
31 | doubleFollow | ||
22 | } from '../../../shared/extra-utils' | 32 | } from '../../../shared/extra-utils' |
33 | import { VideoCommentThreadTree } from '../../../shared/models/videos/video-comment.model' | ||
34 | import { VideoDetails } from '../../../shared/models/videos' | ||
35 | import { getYoutubeVideoUrl, importVideo } from '../../../shared/extra-utils/videos/video-imports' | ||
23 | 36 | ||
24 | const expect = chai.expect | 37 | const expect = chai.expect |
25 | 38 | ||
@@ -33,6 +46,8 @@ describe('Test plugin filter hooks', function () { | |||
33 | 46 | ||
34 | servers = await flushAndRunMultipleServers(2) | 47 | servers = await flushAndRunMultipleServers(2) |
35 | await setAccessTokensToServers(servers) | 48 | await setAccessTokensToServers(servers) |
49 | await setDefaultVideoChannel(servers) | ||
50 | await doubleFollow(servers[0], servers[1]) | ||
36 | 51 | ||
37 | await installPlugin({ | 52 | await installPlugin({ |
38 | url: servers[0].url, | 53 | url: servers[0].url, |
@@ -54,7 +69,7 @@ describe('Test plugin filter hooks', function () { | |||
54 | videoUUID = res.body.data[0].uuid | 69 | videoUUID = res.body.data[0].uuid |
55 | }) | 70 | }) |
56 | 71 | ||
57 | it('Should run filter:api.videos.list.params hook', async function () { | 72 | it('Should run filter:api.videos.list.params', async function () { |
58 | const res = await getVideosListPagination(servers[0].url, 0, 2) | 73 | const res = await getVideosListPagination(servers[0].url, 0, 2) |
59 | 74 | ||
60 | // 2 plugins do +1 to the count parameter | 75 | // 2 plugins do +1 to the count parameter |
@@ -74,6 +89,104 @@ describe('Test plugin filter hooks', function () { | |||
74 | expect(res.body.name).to.contain('<3') | 89 | expect(res.body.name).to.contain('<3') |
75 | }) | 90 | }) |
76 | 91 | ||
92 | it('Should run filter:api.video.upload.accept.result', async function () { | ||
93 | await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video with bad word' }, 403) | ||
94 | }) | ||
95 | |||
96 | it('Should run filter:api.video-thread.create.accept.result', async function () { | ||
97 | await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'comment with bad word', 403) | ||
98 | }) | ||
99 | |||
100 | it('Should run filter:api.video-comment-reply.create.accept.result', async function () { | ||
101 | const res = await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'thread') | ||
102 | threadId = res.body.comment.id | ||
103 | |||
104 | await addVideoCommentReply(servers[0].url, servers[0].accessToken, videoUUID, threadId, 'comment with bad word', 403) | ||
105 | await addVideoCommentReply(servers[0].url, servers[0].accessToken, videoUUID, threadId, 'comment with good word', 200) | ||
106 | }) | ||
107 | |||
108 | it('Should run filter:api.video-threads.list.params', async function () { | ||
109 | const res = await getVideoCommentThreads(servers[0].url, videoUUID, 0, 0) | ||
110 | |||
111 | // our plugin do +1 to the count parameter | ||
112 | expect(res.body.data).to.have.lengthOf(1) | ||
113 | }) | ||
114 | |||
115 | it('Should run filter:api.video-threads.list.result', async function () { | ||
116 | const res = await getVideoCommentThreads(servers[0].url, videoUUID, 0, 0) | ||
117 | |||
118 | // Plugin do +1 to the total result | ||
119 | expect(res.body.total).to.equal(2) | ||
120 | }) | ||
121 | |||
122 | it('Should run filter:api.video-thread-comments.list.params') | ||
123 | |||
124 | it('Should run filter:api.video-thread-comments.list.result', async function () { | ||
125 | const res = await getVideoThreadComments(servers[0].url, videoUUID, threadId) | ||
126 | |||
127 | const thread = res.body as VideoCommentThreadTree | ||
128 | expect(thread.comment.text.endsWith(' <3')).to.be.true | ||
129 | }) | ||
130 | |||
131 | describe('Should run filter:video.auto-blacklist.result', function () { | ||
132 | |||
133 | async function checkIsBlacklisted (oldRes: any, value: boolean) { | ||
134 | const videoId = oldRes.body.video.uuid | ||
135 | |||
136 | const res = await getVideoWithToken(servers[0].url, servers[0].accessToken, videoId) | ||
137 | const video: VideoDetails = res.body | ||
138 | expect(video.blacklisted).to.equal(value) | ||
139 | } | ||
140 | |||
141 | it('Should blacklist on upload', async function () { | ||
142 | const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, { name: 'video please blacklist me' }) | ||
143 | await checkIsBlacklisted(res, true) | ||
144 | }) | ||
145 | |||
146 | it('Should blacklist on import', async function () { | ||
147 | const attributes = { | ||
148 | name: 'video please blacklist me', | ||
149 | targetUrl: getYoutubeVideoUrl(), | ||
150 | channelId: servers[0].videoChannel.id | ||
151 | } | ||
152 | const res = await importVideo(servers[0].url, servers[0].accessToken, attributes) | ||
153 | await checkIsBlacklisted(res, true) | ||
154 | }) | ||
155 | |||
156 | it('Should blacklist on update', async function () { | ||
157 | const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, { name: 'video' }) | ||
158 | const videoId = res.body.video.uuid | ||
159 | await checkIsBlacklisted(res, false) | ||
160 | |||
161 | await updateVideo(servers[ 0 ].url, servers[ 0 ].accessToken, videoId, { name: 'please blacklist me' }) | ||
162 | await checkIsBlacklisted(res, true) | ||
163 | }) | ||
164 | |||
165 | it('Should blacklist on remote upload', async function () { | ||
166 | this.timeout(45000) | ||
167 | |||
168 | const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, { name: 'remote please blacklist me' }) | ||
169 | await waitJobs(servers) | ||
170 | |||
171 | await checkIsBlacklisted(res, true) | ||
172 | }) | ||
173 | |||
174 | it('Should blacklist on remote update', async function () { | ||
175 | this.timeout(45000) | ||
176 | |||
177 | const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, { name: 'video' }) | ||
178 | await waitJobs(servers) | ||
179 | |||
180 | const videoId = res.body.video.uuid | ||
181 | await checkIsBlacklisted(res, false) | ||
182 | |||
183 | await updateVideo(servers[1].url, servers[1].accessToken, videoId, { name: 'please blacklist me' }) | ||
184 | await waitJobs(servers) | ||
185 | |||
186 | await checkIsBlacklisted(res, true) | ||
187 | }) | ||
188 | }) | ||
189 | |||
77 | after(async function () { | 190 | after(async function () { |
78 | await cleanupTests(servers) | 191 | await cleanupTests(servers) |
79 | }) | 192 | }) |
diff --git a/shared/models/plugins/server-hook.model.ts b/shared/models/plugins/server-hook.model.ts index 30469856c..a7f88f3c4 100644 --- a/shared/models/plugins/server-hook.model.ts +++ b/shared/models/plugins/server-hook.model.ts | |||
@@ -7,12 +7,12 @@ export type ServerFilterHookName = | |||
7 | 'filter:api.video-thread.create.accept.result' | | 7 | 'filter:api.video-thread.create.accept.result' | |
8 | 'filter:api.video-comment-reply.create.accept.result' | | 8 | 'filter:api.video-comment-reply.create.accept.result' | |
9 | 9 | ||
10 | 'filter:api.video-thread-comments.list.params' | | ||
11 | 'filter:api.video-thread-comments.list.result' | | ||
12 | |||
13 | 'filter:api.video-threads.list.params' | | 10 | 'filter:api.video-threads.list.params' | |
14 | 'filter:api.video-threads.list.result' | | 11 | 'filter:api.video-threads.list.result' | |
15 | 12 | ||
13 | 'filter:api.video-thread-comments.list.params' | | ||
14 | 'filter:api.video-thread-comments.list.result' | | ||
15 | |||
16 | 'filter:video.auto-blacklist.result' | 16 | 'filter:video.auto-blacklist.result' |
17 | 17 | ||
18 | export type ServerActionHookName = | 18 | export type ServerActionHookName = |