From: Chocobozzz Date: Thu, 8 Jul 2021 09:49:38 +0000 (+0200) Subject: Introduce captions command X-Git-Tag: v3.4.0-rc.1~200^2~29 X-Git-Url: https://git.immae.eu/?a=commitdiff_plain;h=a2470c9f4bfc7f49f4b94de935bacdd53fd54f29;hp=e3d15a6a9aed97a004d9dac1b7a6499d794e080a;p=github%2FChocobozzz%2FPeerTube.git Introduce captions command --- diff --git a/scripts/benchmark.ts b/scripts/benchmark.ts index 0cadb36d9..fcfc67bf7 100644 --- a/scripts/benchmark.ts +++ b/scripts/benchmark.ts @@ -5,7 +5,6 @@ import * as autocannon from 'autocannon' import { addVideoCommentReply, addVideoCommentThread, - createVideoCaption, flushAndRunServer, getVideosList, killallServers, @@ -244,9 +243,7 @@ async function prepare () { } for (const caption of [ 'ar', 'fr', 'en', 'zh' ]) { - await createVideoCaption({ - url: server.url, - accessToken: server.accessToken, + await server.captionsCommand.createVideoCaption({ language: caption, videoId: video.id, fixture: 'subtitle-good2.vtt' diff --git a/server/tests/api/check-params/video-captions.ts b/server/tests/api/check-params/video-captions.ts index c0595c04d..baab0f276 100644 --- a/server/tests/api/check-params/video-captions.ts +++ b/server/tests/api/check-params/video-captions.ts @@ -1,8 +1,7 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ import 'mocha' -import { VideoCreateResult } from '@shared/models' -import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' +import { HttpStatusCode } from '@shared/core-utils' import { buildAbsoluteFixturePath, cleanupTests, @@ -15,8 +14,8 @@ import { setAccessTokensToServers, uploadVideo, userLogin -} from '../../../../shared/extra-utils' -import { createVideoCaption } from '../../../../shared/extra-utils/videos/video-captions' +} from '@shared/extra-utils' +import { VideoCreateResult } from '@shared/models' describe('Test video captions API validator', function () { const path = '/api/v1/videos/' @@ -159,9 +158,7 @@ describe('Test video captions API validator', function () { // }) it('Should succeed with a valid captionfile extension and octet-stream mime type', async function () { - await createVideoCaption({ - url: server.url, - accessToken: server.accessToken, + await server.captionsCommand.createVideoCaption({ language: 'zh', videoId: video.uuid, fixture: 'subtitle-good.srt', diff --git a/server/tests/api/search/search-videos.ts b/server/tests/api/search/search-videos.ts index a0375fbf0..513538917 100644 --- a/server/tests/api/search/search-videos.ts +++ b/server/tests/api/search/search-videos.ts @@ -4,7 +4,6 @@ import 'mocha' import * as chai from 'chai' import { cleanupTests, - createVideoCaption, flushAndRunServer, immutableAssign, SearchCommand, @@ -54,18 +53,14 @@ describe('Test videos search', function () { const videoId = res.body.video.id videoUUID = res.body.video.uuid - await createVideoCaption({ - url: server.url, - accessToken: server.accessToken, + await server.captionsCommand.createVideoCaption({ language: 'en', videoId, fixture: 'subtitle-good2.vtt', mimeType: 'application/octet-stream' }) - await createVideoCaption({ - url: server.url, - accessToken: server.accessToken, + await server.captionsCommand.createVideoCaption({ language: 'aa', videoId, fixture: 'subtitle-good2.vtt', diff --git a/server/tests/api/server/follows.ts b/server/tests/api/server/follows.ts index 466932d63..520442c6e 100644 --- a/server/tests/api/server/follows.ts +++ b/server/tests/api/server/follows.ts @@ -8,7 +8,6 @@ import { cleanupTests, completeVideoCheck, createUser, - createVideoCaption, dateIsValid, deleteVideoComment, expectAccountFollows, @@ -17,7 +16,6 @@ import { getVideoCommentThreads, getVideosList, getVideoThreadComments, - listVideoCaptions, rateVideo, ServerInfo, setAccessTokensToServers, @@ -26,7 +24,7 @@ import { userLogin, waitJobs } from '@shared/extra-utils' -import { Video, VideoCaption, VideoComment, VideoCommentThreadTree, VideoPrivacy } from '@shared/models' +import { Video, VideoComment, VideoCommentThreadTree, VideoPrivacy } from '@shared/models' const expect = chai.expect @@ -385,9 +383,7 @@ describe('Test follows', function () { } { - await createVideoCaption({ - url: servers[2].url, - accessToken: servers[2].accessToken, + await servers[2].captionsCommand.createVideoCaption({ language: 'ar', videoId: video4.id, fixture: 'subtitle-good2.vtt' @@ -543,11 +539,11 @@ describe('Test follows', function () { }) it('Should have propagated captions', async function () { - const res = await listVideoCaptions(servers[0].url, video4.id) - expect(res.body.total).to.equal(1) - expect(res.body.data).to.have.lengthOf(1) + const body = await servers[0].captionsCommand.listVideoCaptions({ videoId: video4.id }) + expect(body.total).to.equal(1) + expect(body.data).to.have.lengthOf(1) - const caption1: VideoCaption = res.body.data[0] + const caption1 = body.data[0] expect(caption1.language.id).to.equal('ar') expect(caption1.language.label).to.equal('Arabic') expect(caption1.captionPath).to.match(new RegExp('^/lazy-static/video-captions/.+-ar.vtt$')) diff --git a/server/tests/api/videos/video-captions.ts b/server/tests/api/videos/video-captions.ts index 14ecedfa6..83ee809b8 100644 --- a/server/tests/api/videos/video-captions.ts +++ b/server/tests/api/videos/video-captions.ts @@ -1,25 +1,20 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ -import * as chai from 'chai' import 'mocha' +import * as chai from 'chai' import { checkVideoFilesWereRemoved, cleanupTests, doubleFollow, flushAndRunMultipleServers, removeVideo, + ServerInfo, + setAccessTokensToServers, + testCaptionFile, uploadVideo, - wait -} from '../../../../shared/extra-utils' -import { ServerInfo, setAccessTokensToServers } from '../../../../shared/extra-utils/index' -import { waitJobs } from '../../../../shared/extra-utils/server/jobs' -import { - createVideoCaption, - deleteVideoCaption, - listVideoCaptions, - testCaptionFile -} from '../../../../shared/extra-utils/videos/video-captions' -import { VideoCaption } from '../../../../shared/models/videos/caption/video-caption.model' + wait, + waitJobs +} from '@shared/extra-utils' const expect = chai.expect @@ -47,26 +42,22 @@ describe('Test video captions', function () { it('Should list the captions and return an empty list', async function () { for (const server of servers) { - const res = await listVideoCaptions(server.url, videoUUID) - expect(res.body.total).to.equal(0) - expect(res.body.data).to.have.lengthOf(0) + const body = await server.captionsCommand.listVideoCaptions({ videoId: videoUUID }) + expect(body.total).to.equal(0) + expect(body.data).to.have.lengthOf(0) } }) it('Should create two new captions', async function () { this.timeout(30000) - await createVideoCaption({ - url: servers[0].url, - accessToken: servers[0].accessToken, + await servers[0].captionsCommand.createVideoCaption({ language: 'ar', videoId: videoUUID, fixture: 'subtitle-good1.vtt' }) - await createVideoCaption({ - url: servers[0].url, - accessToken: servers[0].accessToken, + await servers[0].captionsCommand.createVideoCaption({ language: 'zh', videoId: videoUUID, fixture: 'subtitle-good2.vtt', @@ -78,17 +69,17 @@ describe('Test video captions', function () { it('Should list these uploaded captions', async function () { for (const server of servers) { - const res = await listVideoCaptions(server.url, videoUUID) - expect(res.body.total).to.equal(2) - expect(res.body.data).to.have.lengthOf(2) + const body = await server.captionsCommand.listVideoCaptions({ videoId: videoUUID }) + expect(body.total).to.equal(2) + expect(body.data).to.have.lengthOf(2) - const caption1: VideoCaption = res.body.data[0] + const caption1 = body.data[0] expect(caption1.language.id).to.equal('ar') expect(caption1.language.label).to.equal('Arabic') expect(caption1.captionPath).to.match(new RegExp('^/lazy-static/video-captions/' + uuidRegex + '-ar.vtt$')) await testCaptionFile(server.url, caption1.captionPath, 'Subtitle good 1.') - const caption2: VideoCaption = res.body.data[1] + const caption2 = body.data[1] expect(caption2.language.id).to.equal('zh') expect(caption2.language.label).to.equal('Chinese') expect(caption2.captionPath).to.match(new RegExp('^/lazy-static/video-captions/' + uuidRegex + '-zh.vtt$')) @@ -99,9 +90,7 @@ describe('Test video captions', function () { it('Should replace an existing caption', async function () { this.timeout(30000) - await createVideoCaption({ - url: servers[0].url, - accessToken: servers[0].accessToken, + await servers[0].captionsCommand.createVideoCaption({ language: 'ar', videoId: videoUUID, fixture: 'subtitle-good2.vtt' @@ -112,11 +101,11 @@ describe('Test video captions', function () { it('Should have this caption updated', async function () { for (const server of servers) { - const res = await listVideoCaptions(server.url, videoUUID) - expect(res.body.total).to.equal(2) - expect(res.body.data).to.have.lengthOf(2) + const body = await server.captionsCommand.listVideoCaptions({ videoId: videoUUID }) + expect(body.total).to.equal(2) + expect(body.data).to.have.lengthOf(2) - const caption1: VideoCaption = res.body.data[0] + const caption1 = body.data[0] expect(caption1.language.id).to.equal('ar') expect(caption1.language.label).to.equal('Arabic') expect(caption1.captionPath).to.match(new RegExp('^/lazy-static/video-captions/' + uuidRegex + '-ar.vtt$')) @@ -127,9 +116,7 @@ describe('Test video captions', function () { it('Should replace an existing caption with a srt file and convert it', async function () { this.timeout(30000) - await createVideoCaption({ - url: servers[0].url, - accessToken: servers[0].accessToken, + await servers[0].captionsCommand.createVideoCaption({ language: 'ar', videoId: videoUUID, fixture: 'subtitle-good.srt' @@ -143,11 +130,11 @@ describe('Test video captions', function () { it('Should have this caption updated and converted', async function () { for (const server of servers) { - const res = await listVideoCaptions(server.url, videoUUID) - expect(res.body.total).to.equal(2) - expect(res.body.data).to.have.lengthOf(2) + const body = await server.captionsCommand.listVideoCaptions({ videoId: videoUUID }) + expect(body.total).to.equal(2) + expect(body.data).to.have.lengthOf(2) - const caption1: VideoCaption = res.body.data[0] + const caption1 = body.data[0] expect(caption1.language.id).to.equal('ar') expect(caption1.language.label).to.equal('Arabic') expect(caption1.captionPath).to.match(new RegExp('^/lazy-static/video-captions/' + uuidRegex + '-ar.vtt$')) @@ -172,18 +159,18 @@ describe('Test video captions', function () { it('Should remove one caption', async function () { this.timeout(30000) - await deleteVideoCaption(servers[0].url, servers[0].accessToken, videoUUID, 'ar') + await servers[0].captionsCommand.deleteVideoCaption({ videoId: videoUUID, language: 'ar' }) await waitJobs(servers) }) it('Should only list the caption that was not deleted', async function () { for (const server of servers) { - const res = await listVideoCaptions(server.url, videoUUID) - expect(res.body.total).to.equal(1) - expect(res.body.data).to.have.lengthOf(1) + const body = await server.captionsCommand.listVideoCaptions({ videoId: videoUUID }) + expect(body.total).to.equal(1) + expect(body.data).to.have.lengthOf(1) - const caption: VideoCaption = res.body.data[0] + const caption = body.data[0] expect(caption.language.id).to.equal('zh') expect(caption.language.label).to.equal('Chinese') diff --git a/server/tests/api/videos/video-imports.ts b/server/tests/api/videos/video-imports.ts index a4a9132b4..14aed604f 100644 --- a/server/tests/api/videos/video-imports.ts +++ b/server/tests/api/videos/video-imports.ts @@ -11,7 +11,6 @@ import { getVideo, getVideosList, immutableAssign, - listVideoCaptions, ServerInfo, setAccessTokensToServers, testCaptionFile @@ -25,7 +24,7 @@ import { getYoutubeVideoUrl, importVideo } from '../../../../shared/extra-utils/videos/video-imports' -import { VideoCaption, VideoDetails, VideoImport, VideoPrivacy, VideoResolution } from '../../../../shared/models/videos' +import { VideoDetails, VideoImport, VideoPrivacy, VideoResolution } from '../../../../shared/models/videos' const expect = chai.expect @@ -36,8 +35,8 @@ describe('Test video imports', function () { if (areHttpImportTestsDisabled()) return - async function checkVideosServer1 (url: string, idHttp: string, idMagnet: string, idTorrent: string) { - const resHttp = await getVideo(url, idHttp) + async function checkVideosServer1 (server: ServerInfo, idHttp: string, idMagnet: string, idTorrent: string) { + const resHttp = await getVideo(server.url, idHttp) const videoHttp: VideoDetails = resHttp.body expect(videoHttp.name).to.equal('small video - youtube') @@ -55,9 +54,9 @@ describe('Test video imports', function () { expect(originallyPublishedAt.getMonth()).to.equal(0) expect(originallyPublishedAt.getFullYear()).to.equal(2019) - const resMagnet = await getVideo(url, idMagnet) + const resMagnet = await getVideo(server.url, idMagnet) const videoMagnet: VideoDetails = resMagnet.body - const resTorrent = await getVideo(url, idTorrent) + const resTorrent = await getVideo(server.url, idTorrent) const videoTorrent: VideoDetails = resTorrent.body for (const video of [ videoMagnet, videoTorrent ]) { @@ -73,12 +72,12 @@ describe('Test video imports', function () { expect(videoTorrent.name).to.contain('你好 世界 720p.mp4') expect(videoMagnet.name).to.contain('super peertube2 video') - const resCaptions = await listVideoCaptions(url, idHttp) - expect(resCaptions.body.total).to.equal(2) + const bodyCaptions = await server.captionsCommand.listVideoCaptions({ videoId: idHttp }) + expect(bodyCaptions.total).to.equal(2) } - async function checkVideoServer2 (url: string, id: number | string) { - const res = await getVideo(url, id) + async function checkVideoServer2 (server: ServerInfo, id: number | string) { + const res = await getVideo(server.url, id) const video: VideoDetails = res.body expect(video.name).to.equal('my super name') @@ -91,8 +90,8 @@ describe('Test video imports', function () { expect(video.files).to.have.lengthOf(1) - const resCaptions = await listVideoCaptions(url, id) - expect(resCaptions.body.total).to.equal(2) + const bodyCaptions = await server.captionsCommand.listVideoCaptions({ videoId: id }) + expect(bodyCaptions.total).to.equal(2) } before(async function () { @@ -135,8 +134,8 @@ describe('Test video imports', function () { await testImage(servers[0].url, 'video_import_thumbnail', res.body.video.thumbnailPath) await testImage(servers[0].url, 'video_import_preview', res.body.video.previewPath) - const resCaptions = await listVideoCaptions(servers[0].url, res.body.video.id) - const videoCaptions: VideoCaption[] = resCaptions.body.data + const bodyCaptions = await servers[0].captionsCommand.listVideoCaptions({ videoId: res.body.video.id }) + const videoCaptions = bodyCaptions.data expect(videoCaptions).to.have.lengthOf(2) const enCaption = videoCaptions.find(caption => caption.language.id === 'en') @@ -241,7 +240,7 @@ Ajouter un sous-titre est vraiment facile`) expect(res.body.data).to.have.lengthOf(3) const [ videoHttp, videoMagnet, videoTorrent ] = res.body.data - await checkVideosServer1(server.url, videoHttp.uuid, videoMagnet.uuid, videoTorrent.uuid) + await checkVideosServer1(server, videoHttp.uuid, videoMagnet.uuid, videoTorrent.uuid) } }) @@ -273,10 +272,10 @@ Ajouter un sous-titre est vraiment facile`) expect(res.body.total).to.equal(4) expect(res.body.data).to.have.lengthOf(4) - await checkVideoServer2(server.url, res.body.data[0].uuid) + await checkVideoServer2(server, res.body.data[0].uuid) const [ , videoHttp, videoMagnet, videoTorrent ] = res.body.data - await checkVideosServer1(server.url, videoHttp.uuid, videoMagnet.uuid, videoTorrent.uuid) + await checkVideosServer1(server, videoHttp.uuid, videoMagnet.uuid, videoTorrent.uuid) } }) diff --git a/shared/extra-utils/server/servers.ts b/shared/extra-utils/server/servers.ts index a4432902f..170360341 100644 --- a/shared/extra-utils/server/servers.ts +++ b/shared/extra-utils/server/servers.ts @@ -18,7 +18,7 @@ import { makeGetRequest } from '../requests/requests' import { SearchCommand } from '../search' import { SocketIOCommand } from '../socket' import { AccountsCommand, BlocklistCommand, SubscriptionsCommand } from '../users' -import { LiveCommand, ServicesCommand, BlacklistCommand } from '../videos' +import { LiveCommand, ServicesCommand, BlacklistCommand, CaptionsCommand } from '../videos' import { ConfigCommand } from './config-command' import { ContactFormCommand } from './contact-form-command' import { DebugCommand } from './debug-command' @@ -103,6 +103,7 @@ interface ServerInfo { liveCommand?: LiveCommand servicesCommand?: ServicesCommand blacklistCommand?: BlacklistCommand + captionsCommand?: CaptionsCommand } function parallelTests () { @@ -331,6 +332,7 @@ async function runServer (server: ServerInfo, configOverrideArg?: any, args = [] server.liveCommand = new LiveCommand(server) server.servicesCommand = new ServicesCommand(server) server.blacklistCommand = new BlacklistCommand(server) + server.captionsCommand = new CaptionsCommand(server) res(server) }) diff --git a/shared/extra-utils/videos/captions-command.ts b/shared/extra-utils/videos/captions-command.ts new file mode 100644 index 000000000..908b6dae6 --- /dev/null +++ b/shared/extra-utils/videos/captions-command.ts @@ -0,0 +1,66 @@ +import { ResultList, VideoCaption } from '@shared/models' +import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' +import { buildAbsoluteFixturePath } from '../miscs/miscs' +import { AbstractCommand, OverrideCommandOptions } from '../shared' + +export class CaptionsCommand extends AbstractCommand { + + createVideoCaption (options: OverrideCommandOptions & { + videoId: string | number + language: string + fixture: string + mimeType?: string + }) { + const { videoId, language, fixture, mimeType } = options + + const path = '/api/v1/videos/' + videoId + '/captions/' + language + + const captionfile = buildAbsoluteFixturePath(fixture) + const captionfileAttach = mimeType + ? [ captionfile, { contentType: mimeType } ] + : captionfile + + return this.putUploadRequest({ + ...options, + + path, + fields: {}, + attaches: { + captionfile: captionfileAttach + }, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } + + listVideoCaptions (options: OverrideCommandOptions & { + videoId: string | number + }) { + const { videoId } = options + const path = '/api/v1/videos/' + videoId + '/captions' + + return this.getRequestBody>({ + ...options, + + path, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + deleteVideoCaption (options: OverrideCommandOptions & { + videoId: string | number + language: string + }) { + const { videoId, language } = options + const path = '/api/v1/videos/' + videoId + '/captions/' + language + + return this.deleteRequest({ + ...options, + + path, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } +} diff --git a/shared/extra-utils/videos/captions.ts b/shared/extra-utils/videos/captions.ts new file mode 100644 index 000000000..2246bd133 --- /dev/null +++ b/shared/extra-utils/videos/captions.ts @@ -0,0 +1,17 @@ +import { expect } from 'chai' +import * as request from 'supertest' +import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' + +async function testCaptionFile (url: string, captionPath: string, containsString: string) { + const res = await request(url) + .get(captionPath) + .expect(HttpStatusCode.OK_200) + + expect(res.text).to.contain(containsString) +} + +// --------------------------------------------------------------------------- + +export { + testCaptionFile +} diff --git a/shared/extra-utils/videos/index.ts b/shared/extra-utils/videos/index.ts index 67f5faf54..03b4756d5 100644 --- a/shared/extra-utils/videos/index.ts +++ b/shared/extra-utils/videos/index.ts @@ -1,8 +1,9 @@ export * from './blacklist-command' +export * from './captions' +export * from './captions-command' export * from './live-command' export * from './live' export * from './services-command' -export * from './video-captions' export * from './video-change-ownership' export * from './video-channels' export * from './video-comments' diff --git a/shared/extra-utils/videos/video-captions.ts b/shared/extra-utils/videos/video-captions.ts deleted file mode 100644 index 62eec7b90..000000000 --- a/shared/extra-utils/videos/video-captions.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { makeDeleteRequest, makeGetRequest, makeUploadRequest } from '../requests/requests' -import * as request from 'supertest' -import * as chai from 'chai' -import { buildAbsoluteFixturePath } from '../miscs/miscs' -import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' - -const expect = chai.expect - -function createVideoCaption (args: { - url: string - accessToken: string - videoId: string | number - language: string - fixture: string - mimeType?: string - statusCodeExpected?: number -}) { - const path = '/api/v1/videos/' + args.videoId + '/captions/' + args.language - - const captionfile = buildAbsoluteFixturePath(args.fixture) - const captionfileAttach = args.mimeType ? [ captionfile, { contentType: args.mimeType } ] : captionfile - - return makeUploadRequest({ - method: 'PUT', - url: args.url, - path, - token: args.accessToken, - fields: {}, - attaches: { - captionfile: captionfileAttach - }, - statusCodeExpected: args.statusCodeExpected || HttpStatusCode.NO_CONTENT_204 - }) -} - -function listVideoCaptions (url: string, videoId: string | number) { - const path = '/api/v1/videos/' + videoId + '/captions' - - return makeGetRequest({ - url, - path, - statusCodeExpected: HttpStatusCode.OK_200 - }) -} - -function deleteVideoCaption (url: string, token: string, videoId: string | number, language: string) { - const path = '/api/v1/videos/' + videoId + '/captions/' + language - - return makeDeleteRequest({ - url, - token, - path, - statusCodeExpected: HttpStatusCode.NO_CONTENT_204 - }) -} - -async function testCaptionFile (url: string, captionPath: string, containsString: string) { - const res = await request(url) - .get(captionPath) - .expect(HttpStatusCode.OK_200) - - expect(res.text).to.contain(containsString) -} - -// --------------------------------------------------------------------------- - -export { - createVideoCaption, - listVideoCaptions, - testCaptionFile, - deleteVideoCaption -}