Add video file update hook tests

pull/5898/head
Chocobozzz 2023-07-25 15:17:58 +02:00
parent 3b46eec8ae
commit 9901c8d690
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
5 changed files with 61 additions and 16 deletions

View File

@ -45,7 +45,7 @@ export async function isVideoFileAccepted (options: {
videoFile: express.VideoUploadFile videoFile: express.VideoUploadFile
hook: Extract<ServerFilterHookName, 'filter:api.video.upload.accept.result' | 'filter:api.video.update-file.accept.result'> hook: Extract<ServerFilterHookName, 'filter:api.video.upload.accept.result' | 'filter:api.video.update-file.accept.result'>
}) { }) {
const { req, res, videoFile } = options const { req, res, videoFile, hook } = options
// Check we accept this video // Check we accept this video
const acceptParameters = { const acceptParameters = {
@ -53,11 +53,7 @@ export async function isVideoFileAccepted (options: {
videoFile, videoFile,
user: res.locals.oauth.token.User user: res.locals.oauth.token.User
} }
const acceptedResult = await Hooks.wrapFun( const acceptedResult = await Hooks.wrapFun(isLocalVideoFileAccepted, acceptParameters, hook)
isLocalVideoFileAccepted,
acceptParameters,
'filter:api.video.upload.accept.result'
)
if (!acceptedResult || acceptedResult.accepted !== true) { if (!acceptedResult || acceptedResult.accepted !== true) {
logger.info('Refused local video file.', { acceptedResult, acceptParameters }) logger.info('Refused local video file.', { acceptedResult, acceptParameters })

View File

@ -9,6 +9,8 @@ async function register ({ registerHook, registerSetting, settingsManager, stora
'action:api.video.uploaded', 'action:api.video.uploaded',
'action:api.video.viewed', 'action:api.video.viewed',
'action:api.video.file-updated',
'action:api.video-channel.created', 'action:api.video-channel.created',
'action:api.video-channel.updated', 'action:api.video-channel.updated',
'action:api.video-channel.deleted', 'action:api.video-channel.deleted',
@ -160,6 +162,16 @@ async function register ({ registerHook, registerSetting, settingsManager, stora
}) })
} }
registerHook({
target: 'filter:api.video.update-file.accept.result',
handler: ({ accepted }, { videoFile }) => {
if (!accepted) return { accepted: false }
if (videoFile.filename.includes('webm')) return { accepted: false, errorMessage: 'no webm' }
return { accepted: true }
}
})
registerHook({ registerHook({
target: 'filter:api.video.pre-import-url.accept.result', target: 'filter:api.video.pre-import-url.accept.result',
handler: ({ accepted }, { videoImportBody }) => { handler: ({ accepted }, { videoImportBody }) => {

View File

@ -40,6 +40,8 @@ describe('Test plugin action hooks', function () {
} }
}) })
await servers[0].config.enableFileUpdate()
await doubleFollow(servers[0], servers[1]) await doubleFollow(servers[0], servers[1])
}) })
@ -70,6 +72,12 @@ describe('Test plugin action hooks', function () {
await checkHook('action:api.video.viewed') await checkHook('action:api.video.viewed')
}) })
it('Should run action:api.video.file-updated', async function () {
await servers[0].videos.replaceSourceFile({ videoId: videoUUID, fixture: 'video_short.mp4' })
await checkHook('action:api.video.file-updated')
})
it('Should run action:api.video.deleted', async function () { it('Should run action:api.video.deleted', async function () {
await servers[0].videos.remove({ id: videoUUID }) await servers[0].videos.remove({ id: videoUUID })

View File

@ -64,6 +64,11 @@ describe('Test plugin filter hooks', function () {
newConfig: { newConfig: {
live: { enabled: true }, live: { enabled: true },
signup: { enabled: true }, signup: { enabled: true },
videoFile: {
update: {
enabled: true
}
},
import: { import: {
videos: { videos: {
http: { enabled: true }, http: { enabled: true },
@ -178,7 +183,19 @@ describe('Test plugin filter hooks', function () {
describe('Video/live/import accept', function () { describe('Video/live/import accept', function () {
it('Should run filter:api.video.upload.accept.result', async function () { it('Should run filter:api.video.upload.accept.result', async function () {
await servers[0].videos.upload({ attributes: { name: 'video with bad word' }, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) const options = { attributes: { name: 'video with bad word' }, expectedStatus: HttpStatusCode.FORBIDDEN_403 }
await servers[0].videos.upload({ mode: 'legacy', ...options })
await servers[0].videos.upload({ mode: 'resumable', ...options })
})
it('Should run filter:api.video.update-file.accept.result', async function () {
const res = await servers[0].videos.replaceSourceFile({
videoId: videoUUID,
fixture: 'video_short1.webm',
completedExpectedStatus: HttpStatusCode.FORBIDDEN_403
})
expect((res as any)?.error).to.equal('no webm')
}) })
it('Should run filter:api.live-video.create.accept.result', async function () { it('Should run filter:api.live-video.create.accept.result', async function () {

View File

@ -394,6 +394,7 @@ export class VideosCommand extends AbstractCommand {
attributes?: VideoEdit attributes?: VideoEdit
mode?: 'legacy' | 'resumable' // default legacy mode?: 'legacy' | 'resumable' // default legacy
waitTorrentGeneration?: boolean // default true waitTorrentGeneration?: boolean // default true
completedExpectedStatus?: HttpStatusCode
} = {}) { } = {}) {
const { mode = 'legacy', waitTorrentGeneration = true } = options const { mode = 'legacy', waitTorrentGeneration = true } = options
let defaultChannelId = 1 let defaultChannelId = 1
@ -461,8 +462,9 @@ export class VideosCommand extends AbstractCommand {
async buildResumeUpload (options: OverrideCommandOptions & { async buildResumeUpload (options: OverrideCommandOptions & {
path: string path: string
attributes: { fixture?: string } & { [id: string]: any } attributes: { fixture?: string } & { [id: string]: any }
completedExpectedStatus?: HttpStatusCode // When the upload is finished
}): Promise<VideoCreateResult> { }): Promise<VideoCreateResult> {
const { path, attributes, expectedStatus = HttpStatusCode.OK_200 } = options const { path, attributes, expectedStatus = HttpStatusCode.OK_200, completedExpectedStatus } = options
let size = 0 let size = 0
let videoFilePath: string let videoFilePath: string
@ -503,7 +505,8 @@ export class VideosCommand extends AbstractCommand {
path, path,
pathUploadId, pathUploadId,
videoFilePath, videoFilePath,
size size,
expectedStatus: completedExpectedStatus
}) })
if (result.statusCode === HttpStatusCode.OK_200) { if (result.statusCode === HttpStatusCode.OK_200) {
@ -600,12 +603,14 @@ export class VideosCommand extends AbstractCommand {
try { try {
readable.pause() readable.pause()
const byterangeStart = start + chunk.length - 1
const headers = { const headers = {
'Authorization': 'Bearer ' + token, 'Authorization': 'Bearer ' + token,
'Content-Type': 'application/octet-stream', 'Content-Type': 'application/octet-stream',
'Content-Range': contentRangeBuilder 'Content-Range': contentRangeBuilder
? contentRangeBuilder(start, chunk) ? contentRangeBuilder(start, chunk)
: `bytes ${start}-${start + chunk.length - 1}/${size}`, : `bytes ${start}-${byterangeStart}/${size}`,
'Content-Length': contentLength ? contentLength + '' : chunk.length + '' 'Content-Length': contentLength ? contentLength + '' : chunk.length + ''
} }
@ -625,13 +630,19 @@ export class VideosCommand extends AbstractCommand {
start += chunk.length start += chunk.length
// Last request, check final status
if (byterangeStart + 1 === size) {
if (res.statusCode === expectedStatus) { if (res.statusCode === expectedStatus) {
return resolve(res) return resolve(res)
} }
if (res.statusCode !== HttpStatusCode.PERMANENT_REDIRECT_308) { if (res.statusCode !== HttpStatusCode.PERMANENT_REDIRECT_308) {
readable.off('data', onData) readable.off('data', onData)
return reject(new Error('Incorrect transient behaviour sending intermediary chunks'))
// eslint-disable-next-line max-len
const message = `Incorrect transient behaviour sending intermediary chunks. Status code is ${res.statusCode} instead of ${expectedStatus}`
return reject(new Error(message))
}
} }
readable.resume() readable.resume()
@ -694,6 +705,7 @@ export class VideosCommand extends AbstractCommand {
replaceSourceFile (options: OverrideCommandOptions & { replaceSourceFile (options: OverrideCommandOptions & {
videoId: number | string videoId: number | string
fixture: string fixture: string
completedExpectedStatus?: HttpStatusCode
}) { }) {
return this.buildResumeUpload({ return this.buildResumeUpload({
...options, ...options,