diff options
41 files changed, 133 insertions, 72 deletions
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 407907e53..baddba758 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml | |||
@@ -46,6 +46,7 @@ jobs: | |||
46 | PGHOST: localhost | 46 | PGHOST: localhost |
47 | NODE_PENDING_JOB_WAIT: 250 | 47 | NODE_PENDING_JOB_WAIT: 250 |
48 | ENABLE_OBJECT_STORAGE_TESTS: true | 48 | ENABLE_OBJECT_STORAGE_TESTS: true |
49 | ENABLE_FFMPEG_THUMBNAIL_PIXEL_COMPARISON_TESTS: true | ||
49 | OBJECT_STORAGE_SCALEWAY_KEY_ID: ${{ secrets.OBJECT_STORAGE_SCALEWAY_KEY_ID }} | 50 | OBJECT_STORAGE_SCALEWAY_KEY_ID: ${{ secrets.OBJECT_STORAGE_SCALEWAY_KEY_ID }} |
50 | OBJECT_STORAGE_SCALEWAY_ACCESS_KEY: ${{ secrets.OBJECT_STORAGE_SCALEWAY_ACCESS_KEY }} | 51 | OBJECT_STORAGE_SCALEWAY_ACCESS_KEY: ${{ secrets.OBJECT_STORAGE_SCALEWAY_ACCESS_KEY }} |
51 | YOUTUBE_DL_DOWNLOAD_BEARER_TOKEN: ${{ secrets.GITHUB_TOKEN }} | 52 | YOUTUBE_DL_DOWNLOAD_BEARER_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
diff --git a/server/controllers/api/videos/upload.ts b/server/controllers/api/videos/upload.ts index 86ab4591e..6c471ff90 100644 --- a/server/controllers/api/videos/upload.ts +++ b/server/controllers/api/videos/upload.ts | |||
@@ -111,7 +111,7 @@ async function addVideoLegacy (req: express.Request, res: express.Response) { | |||
111 | async function addVideoResumable (req: express.Request, res: express.Response) { | 111 | async function addVideoResumable (req: express.Request, res: express.Response) { |
112 | const videoPhysicalFile = res.locals.videoFileResumable | 112 | const videoPhysicalFile = res.locals.videoFileResumable |
113 | const videoInfo = videoPhysicalFile.metadata | 113 | const videoInfo = videoPhysicalFile.metadata |
114 | const files = { previewfile: videoInfo.previewfile } | 114 | const files = { previewfile: videoInfo.previewfile, thumbnailfile: videoInfo.thumbnailfile } |
115 | 115 | ||
116 | const response = await addVideo({ req, res, videoPhysicalFile, videoInfo, files }) | 116 | const response = await addVideo({ req, res, videoPhysicalFile, videoInfo, files }) |
117 | await Redis.Instance.setUploadSession(req.query.upload_id, response) | 117 | await Redis.Instance.setUploadSession(req.query.upload_id, response) |
diff --git a/server/lib/object-storage/pre-signed-urls.ts b/server/lib/object-storage/pre-signed-urls.ts new file mode 100644 index 000000000..46a0750a1 --- /dev/null +++ b/server/lib/object-storage/pre-signed-urls.ts | |||
@@ -0,0 +1,41 @@ | |||
1 | import { GetObjectCommand } from '@aws-sdk/client-s3' | ||
2 | import { getSignedUrl } from '@aws-sdk/s3-request-presigner' | ||
3 | import { CONFIG } from '@server/initializers/config' | ||
4 | import { MStreamingPlaylistVideo, MVideoFile } from '@server/types/models' | ||
5 | import { generateHLSObjectStorageKey, generateWebTorrentObjectStorageKey } from './keys' | ||
6 | import { buildKey, getClient } from './shared' | ||
7 | |||
8 | export function generateWebVideoPresignedUrl (options: { | ||
9 | file: MVideoFile | ||
10 | downloadFilename: string | ||
11 | }) { | ||
12 | const { file, downloadFilename } = options | ||
13 | |||
14 | const key = generateWebTorrentObjectStorageKey(file.filename) | ||
15 | |||
16 | const command = new GetObjectCommand({ | ||
17 | Bucket: CONFIG.OBJECT_STORAGE.VIDEOS.BUCKET_NAME, | ||
18 | Key: buildKey(key, CONFIG.OBJECT_STORAGE.VIDEOS), | ||
19 | ResponseContentDisposition: `attachment; filename=${downloadFilename}` | ||
20 | }) | ||
21 | |||
22 | return getSignedUrl(getClient(), command, { expiresIn: 3600 * 24 }) | ||
23 | } | ||
24 | |||
25 | export function generateHLSFilePresignedUrl (options: { | ||
26 | streamingPlaylist: MStreamingPlaylistVideo | ||
27 | file: MVideoFile | ||
28 | downloadFilename: string | ||
29 | }) { | ||
30 | const { streamingPlaylist, file, downloadFilename } = options | ||
31 | |||
32 | const key = generateHLSObjectStorageKey(streamingPlaylist, file.filename) | ||
33 | |||
34 | const command = new GetObjectCommand({ | ||
35 | Bucket: CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS.BUCKET_NAME, | ||
36 | Key: buildKey(key, CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS), | ||
37 | ResponseContentDisposition: `attachment; filename=${downloadFilename}` | ||
38 | }) | ||
39 | |||
40 | return getSignedUrl(getClient(), command, { expiresIn: 3600 * 24 }) | ||
41 | } | ||
diff --git a/server/middlewares/validators/videos/videos.ts b/server/middlewares/validators/videos/videos.ts index fc2f95aa5..9034772c0 100644 --- a/server/middlewares/validators/videos/videos.ts +++ b/server/middlewares/validators/videos/videos.ts | |||
@@ -223,10 +223,12 @@ const videosAddResumableInitValidator = getCommonVideoEditAttributes().concat([ | |||
223 | 223 | ||
224 | if (!isValidPasswordProtectedPrivacy(req, res)) return cleanup() | 224 | if (!isValidPasswordProtectedPrivacy(req, res)) return cleanup() |
225 | 225 | ||
226 | // multer required unsetting the Content-Type, now we can set it for node-uploadx | 226 | // Multer required unsetting the Content-Type, now we can set it for node-uploadx |
227 | req.headers['content-type'] = 'application/json; charset=utf-8' | 227 | req.headers['content-type'] = 'application/json; charset=utf-8' |
228 | // place previewfile in metadata so that uploadx saves it in .META | 228 | |
229 | // Place thumbnail/previewfile in metadata so that uploadx saves it in .META | ||
229 | if (req.files?.['previewfile']) req.body.previewfile = req.files['previewfile'] | 230 | if (req.files?.['previewfile']) req.body.previewfile = req.files['previewfile'] |
231 | if (req.files?.['thumbnailfile']) req.body.thumbnailfile = req.files['thumbnailfile'] | ||
230 | 232 | ||
231 | return next() | 233 | return next() |
232 | } | 234 | } |
diff --git a/server/tests/api/check-params/live.ts b/server/tests/api/check-params/live.ts index 406a96824..5021db516 100644 --- a/server/tests/api/check-params/live.ts +++ b/server/tests/api/check-params/live.ts | |||
@@ -194,7 +194,7 @@ describe('Test video lives API validator', function () { | |||
194 | it('Should fail with a big thumbnail file', async function () { | 194 | it('Should fail with a big thumbnail file', async function () { |
195 | const fields = baseCorrectParams | 195 | const fields = baseCorrectParams |
196 | const attaches = { | 196 | const attaches = { |
197 | thumbnailfile: buildAbsoluteFixturePath('preview-big.png') | 197 | thumbnailfile: buildAbsoluteFixturePath('custom-preview-big.png') |
198 | } | 198 | } |
199 | 199 | ||
200 | await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches }) | 200 | await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches }) |
@@ -212,7 +212,7 @@ describe('Test video lives API validator', function () { | |||
212 | it('Should fail with a big preview file', async function () { | 212 | it('Should fail with a big preview file', async function () { |
213 | const fields = baseCorrectParams | 213 | const fields = baseCorrectParams |
214 | const attaches = { | 214 | const attaches = { |
215 | previewfile: buildAbsoluteFixturePath('preview-big.png') | 215 | previewfile: buildAbsoluteFixturePath('custom-preview-big.png') |
216 | } | 216 | } |
217 | 217 | ||
218 | await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches }) | 218 | await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches }) |
diff --git a/server/tests/api/check-params/runners.ts b/server/tests/api/check-params/runners.ts index 48821b678..4ba90802f 100644 --- a/server/tests/api/check-params/runners.ts +++ b/server/tests/api/check-params/runners.ts | |||
@@ -752,7 +752,7 @@ describe('Test managing runners', function () { | |||
752 | }) | 752 | }) |
753 | 753 | ||
754 | it('Should fail with an invalid vod audio merge payload', async function () { | 754 | it('Should fail with an invalid vod audio merge payload', async function () { |
755 | const attributes = { name: 'audio_with_preview', previewfile: 'preview.jpg', fixture: 'sample.ogg' } | 755 | const attributes = { name: 'audio_with_preview', previewfile: 'custom-preview.jpg', fixture: 'sample.ogg' } |
756 | await server.videos.upload({ attributes, mode: 'legacy' }) | 756 | await server.videos.upload({ attributes, mode: 'legacy' }) |
757 | 757 | ||
758 | await waitJobs([ server ]) | 758 | await waitJobs([ server ]) |
diff --git a/server/tests/api/check-params/video-imports.ts b/server/tests/api/check-params/video-imports.ts index 7f19b9ee9..8c6f43c12 100644 --- a/server/tests/api/check-params/video-imports.ts +++ b/server/tests/api/check-params/video-imports.ts | |||
@@ -244,7 +244,7 @@ describe('Test video imports API validator', function () { | |||
244 | it('Should fail with a big thumbnail file', async function () { | 244 | it('Should fail with a big thumbnail file', async function () { |
245 | const fields = baseCorrectParams | 245 | const fields = baseCorrectParams |
246 | const attaches = { | 246 | const attaches = { |
247 | thumbnailfile: buildAbsoluteFixturePath('preview-big.png') | 247 | thumbnailfile: buildAbsoluteFixturePath('custom-preview-big.png') |
248 | } | 248 | } |
249 | 249 | ||
250 | await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches }) | 250 | await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches }) |
@@ -262,7 +262,7 @@ describe('Test video imports API validator', function () { | |||
262 | it('Should fail with a big preview file', async function () { | 262 | it('Should fail with a big preview file', async function () { |
263 | const fields = baseCorrectParams | 263 | const fields = baseCorrectParams |
264 | const attaches = { | 264 | const attaches = { |
265 | previewfile: buildAbsoluteFixturePath('preview-big.png') | 265 | previewfile: buildAbsoluteFixturePath('custom-preview-big.png') |
266 | } | 266 | } |
267 | 267 | ||
268 | await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches }) | 268 | await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches }) |
diff --git a/server/tests/api/check-params/video-playlists.ts b/server/tests/api/check-params/video-playlists.ts index 8090897c1..8c3233e0b 100644 --- a/server/tests/api/check-params/video-playlists.ts +++ b/server/tests/api/check-params/video-playlists.ts | |||
@@ -196,7 +196,7 @@ describe('Test video playlists API validator', function () { | |||
196 | attributes: { | 196 | attributes: { |
197 | displayName: 'display name', | 197 | displayName: 'display name', |
198 | privacy: VideoPlaylistPrivacy.UNLISTED, | 198 | privacy: VideoPlaylistPrivacy.UNLISTED, |
199 | thumbnailfile: 'thumbnail.jpg', | 199 | thumbnailfile: 'custom-thumbnail.jpg', |
200 | videoChannelId: server.store.channel.id, | 200 | videoChannelId: server.store.channel.id, |
201 | 201 | ||
202 | ...attributes | 202 | ...attributes |
@@ -260,7 +260,7 @@ describe('Test video playlists API validator', function () { | |||
260 | }) | 260 | }) |
261 | 261 | ||
262 | it('Should fail with a thumbnail file too big', async function () { | 262 | it('Should fail with a thumbnail file too big', async function () { |
263 | const params = getBase({ thumbnailfile: 'preview-big.png' }) | 263 | const params = getBase({ thumbnailfile: 'custom-preview-big.png' }) |
264 | 264 | ||
265 | await command.create(params) | 265 | await command.create(params) |
266 | await command.update(getUpdate(params, playlist.shortUUID)) | 266 | await command.update(getUpdate(params, playlist.shortUUID)) |
diff --git a/server/tests/api/check-params/video-studio.ts b/server/tests/api/check-params/video-studio.ts index add8d9164..4ac0d93ed 100644 --- a/server/tests/api/check-params/video-studio.ts +++ b/server/tests/api/check-params/video-studio.ts | |||
@@ -293,7 +293,7 @@ describe('Test video studio API validator', function () { | |||
293 | it('Should succeed with the correct params', async function () { | 293 | it('Should succeed with the correct params', async function () { |
294 | this.timeout(120000) | 294 | this.timeout(120000) |
295 | 295 | ||
296 | await addWatermark('thumbnail.jpg', HttpStatusCode.NO_CONTENT_204) | 296 | await addWatermark('custom-thumbnail.jpg', HttpStatusCode.NO_CONTENT_204) |
297 | 297 | ||
298 | await waitJobs([ server ]) | 298 | await waitJobs([ server ]) |
299 | }) | 299 | }) |
@@ -322,8 +322,8 @@ describe('Test video studio API validator', function () { | |||
322 | }) | 322 | }) |
323 | 323 | ||
324 | it('Should fail with an invalid file', async function () { | 324 | it('Should fail with an invalid file', async function () { |
325 | await addIntroOutro('add-intro', 'thumbnail.jpg') | 325 | await addIntroOutro('add-intro', 'custom-thumbnail.jpg') |
326 | await addIntroOutro('add-outro', 'thumbnail.jpg') | 326 | await addIntroOutro('add-outro', 'custom-thumbnail.jpg') |
327 | }) | 327 | }) |
328 | 328 | ||
329 | it('Should fail with a file that does not contain video stream', async function () { | 329 | it('Should fail with a file that does not contain video stream', async function () { |
diff --git a/server/tests/api/check-params/videos.ts b/server/tests/api/check-params/videos.ts index 094ab6891..6ee1955a7 100644 --- a/server/tests/api/check-params/videos.ts +++ b/server/tests/api/check-params/videos.ts | |||
@@ -384,7 +384,7 @@ describe('Test videos API validator', function () { | |||
384 | it('Should fail with a big thumbnail file', async function () { | 384 | it('Should fail with a big thumbnail file', async function () { |
385 | const fields = baseCorrectParams | 385 | const fields = baseCorrectParams |
386 | const attaches = { | 386 | const attaches = { |
387 | thumbnailfile: join(root(), 'server', 'tests', 'fixtures', 'preview-big.png'), | 387 | thumbnailfile: join(root(), 'server', 'tests', 'fixtures', 'custom-preview-big.png'), |
388 | fixture: join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4') | 388 | fixture: join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4') |
389 | } | 389 | } |
390 | 390 | ||
@@ -404,7 +404,7 @@ describe('Test videos API validator', function () { | |||
404 | it('Should fail with a big preview file', async function () { | 404 | it('Should fail with a big preview file', async function () { |
405 | const fields = baseCorrectParams | 405 | const fields = baseCorrectParams |
406 | const attaches = { | 406 | const attaches = { |
407 | previewfile: join(root(), 'server', 'tests', 'fixtures', 'preview-big.png'), | 407 | previewfile: join(root(), 'server', 'tests', 'fixtures', 'custom-preview-big.png'), |
408 | fixture: join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4') | 408 | fixture: join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4') |
409 | } | 409 | } |
410 | 410 | ||
@@ -615,7 +615,7 @@ describe('Test videos API validator', function () { | |||
615 | it('Should fail with a big thumbnail file', async function () { | 615 | it('Should fail with a big thumbnail file', async function () { |
616 | const fields = baseCorrectParams | 616 | const fields = baseCorrectParams |
617 | const attaches = { | 617 | const attaches = { |
618 | thumbnailfile: join(root(), 'server', 'tests', 'fixtures', 'preview-big.png') | 618 | thumbnailfile: join(root(), 'server', 'tests', 'fixtures', 'custom-preview-big.png') |
619 | } | 619 | } |
620 | 620 | ||
621 | await makeUploadRequest({ | 621 | await makeUploadRequest({ |
@@ -647,7 +647,7 @@ describe('Test videos API validator', function () { | |||
647 | it('Should fail with a big preview file', async function () { | 647 | it('Should fail with a big preview file', async function () { |
648 | const fields = baseCorrectParams | 648 | const fields = baseCorrectParams |
649 | const attaches = { | 649 | const attaches = { |
650 | previewfile: join(root(), 'server', 'tests', 'fixtures', 'preview-big.png') | 650 | previewfile: join(root(), 'server', 'tests', 'fixtures', 'custom-preview-big.png') |
651 | } | 651 | } |
652 | 652 | ||
653 | await makeUploadRequest({ | 653 | await makeUploadRequest({ |
diff --git a/server/tests/api/live/live.ts b/server/tests/api/live/live.ts index 7ab67b126..2b302a8a2 100644 --- a/server/tests/api/live/live.ts +++ b/server/tests/api/live/live.ts | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | import { expect } from 'chai' | 3 | import { expect } from 'chai' |
4 | import { basename, join } from 'path' | 4 | import { basename, join } from 'path' |
5 | import { SQLCommand, testImage, testLiveVideoResolutions } from '@server/tests/shared' | 5 | import { SQLCommand, testImageGeneratedByFFmpeg, testLiveVideoResolutions } from '@server/tests/shared' |
6 | import { getAllFiles, wait } from '@shared/core-utils' | 6 | import { getAllFiles, wait } from '@shared/core-utils' |
7 | import { ffprobePromise, getVideoStream } from '@shared/ffmpeg' | 7 | import { ffprobePromise, getVideoStream } from '@shared/ffmpeg' |
8 | import { | 8 | import { |
@@ -121,8 +121,8 @@ describe('Test live', function () { | |||
121 | expect(video.downloadEnabled).to.be.false | 121 | expect(video.downloadEnabled).to.be.false |
122 | expect(video.privacy.id).to.equal(VideoPrivacy.PUBLIC) | 122 | expect(video.privacy.id).to.equal(VideoPrivacy.PUBLIC) |
123 | 123 | ||
124 | await testImage(server.url, 'video_short1-preview.webm', video.previewPath) | 124 | await testImageGeneratedByFFmpeg(server.url, 'video_short1-preview.webm', video.previewPath) |
125 | await testImage(server.url, 'video_short1.webm', video.thumbnailPath) | 125 | await testImageGeneratedByFFmpeg(server.url, 'video_short1.webm', video.thumbnailPath) |
126 | 126 | ||
127 | const live = await server.live.get({ videoId: liveVideoUUID }) | 127 | const live = await server.live.get({ videoId: liveVideoUUID }) |
128 | 128 | ||
diff --git a/server/tests/api/runners/runner-studio-transcoding.ts b/server/tests/api/runners/runner-studio-transcoding.ts index 41c556775..443a9d02a 100644 --- a/server/tests/api/runners/runner-studio-transcoding.ts +++ b/server/tests/api/runners/runner-studio-transcoding.ts | |||
@@ -104,7 +104,7 @@ describe('Test runner video studio transcoding', function () { | |||
104 | { | 104 | { |
105 | name: 'add-watermark' as 'add-watermark', | 105 | name: 'add-watermark' as 'add-watermark', |
106 | options: { | 106 | options: { |
107 | file: 'thumbnail.png' | 107 | file: 'custom-thumbnail.png' |
108 | } | 108 | } |
109 | }, | 109 | }, |
110 | { | 110 | { |
diff --git a/server/tests/api/runners/runner-vod-transcoding.ts b/server/tests/api/runners/runner-vod-transcoding.ts index d9da0f40d..ca16d9c10 100644 --- a/server/tests/api/runners/runner-vod-transcoding.ts +++ b/server/tests/api/runners/runner-vod-transcoding.ts | |||
@@ -424,7 +424,7 @@ describe('Test runner VOD transcoding', function () { | |||
424 | 424 | ||
425 | await servers[0].config.enableTranscoding(true, true) | 425 | await servers[0].config.enableTranscoding(true, true) |
426 | 426 | ||
427 | const attributes = { name: 'audio_with_preview', previewfile: 'preview.jpg', fixture: 'sample.ogg' } | 427 | const attributes = { name: 'audio_with_preview', previewfile: 'custom-preview.jpg', fixture: 'sample.ogg' } |
428 | const { uuid } = await servers[0].videos.upload({ attributes, mode: 'legacy' }) | 428 | const { uuid } = await servers[0].videos.upload({ attributes, mode: 'legacy' }) |
429 | videoUUID = uuid | 429 | videoUUID = uuid |
430 | 430 | ||
diff --git a/server/tests/api/transcoding/transcoder.ts b/server/tests/api/transcoding/transcoder.ts index 8a0a7f6d2..3cd247a24 100644 --- a/server/tests/api/transcoding/transcoder.ts +++ b/server/tests/api/transcoding/transcoder.ts | |||
@@ -353,7 +353,7 @@ describe('Test video transcoding', function () { | |||
353 | it('Should merge an audio file with the preview file', async function () { | 353 | it('Should merge an audio file with the preview file', async function () { |
354 | this.timeout(60_000) | 354 | this.timeout(60_000) |
355 | 355 | ||
356 | const attributes = { name: 'audio_with_preview', previewfile: 'preview.jpg', fixture: 'sample.ogg' } | 356 | const attributes = { name: 'audio_with_preview', previewfile: 'custom-preview.jpg', fixture: 'sample.ogg' } |
357 | await servers[1].videos.upload({ attributes, mode }) | 357 | await servers[1].videos.upload({ attributes, mode }) |
358 | 358 | ||
359 | await waitJobs(servers) | 359 | await waitJobs(servers) |
@@ -416,7 +416,7 @@ describe('Test video transcoding', function () { | |||
416 | } | 416 | } |
417 | }) | 417 | }) |
418 | 418 | ||
419 | const attributes = { name: 'audio_with_preview', previewfile: 'preview.jpg', fixture: 'sample.ogg' } | 419 | const attributes = { name: 'audio_with_preview', previewfile: 'custom-preview.jpg', fixture: 'sample.ogg' } |
420 | const { id } = await servers[1].videos.upload({ attributes, mode }) | 420 | const { id } = await servers[1].videos.upload({ attributes, mode }) |
421 | 421 | ||
422 | await waitJobs(servers) | 422 | await waitJobs(servers) |
diff --git a/server/tests/api/transcoding/video-studio.ts b/server/tests/api/transcoding/video-studio.ts index d1298caf7..e97f2b689 100644 --- a/server/tests/api/transcoding/video-studio.ts +++ b/server/tests/api/transcoding/video-studio.ts | |||
@@ -241,7 +241,7 @@ describe('Test video studio', function () { | |||
241 | { | 241 | { |
242 | name: 'add-watermark', | 242 | name: 'add-watermark', |
243 | options: { | 243 | options: { |
244 | file: 'thumbnail.png' | 244 | file: 'custom-thumbnail.png' |
245 | } | 245 | } |
246 | } | 246 | } |
247 | ]) | 247 | ]) |
diff --git a/server/tests/api/videos/multiple-servers.ts b/server/tests/api/videos/multiple-servers.ts index 27ba00d3d..e9aa0e3a1 100644 --- a/server/tests/api/videos/multiple-servers.ts +++ b/server/tests/api/videos/multiple-servers.ts | |||
@@ -9,7 +9,7 @@ import { | |||
9 | completeVideoCheck, | 9 | completeVideoCheck, |
10 | dateIsValid, | 10 | dateIsValid, |
11 | saveVideoInServers, | 11 | saveVideoInServers, |
12 | testImage | 12 | testImageGeneratedByFFmpeg |
13 | } from '@server/tests/shared' | 13 | } from '@server/tests/shared' |
14 | import { buildAbsoluteFixturePath, wait } from '@shared/core-utils' | 14 | import { buildAbsoluteFixturePath, wait } from '@shared/core-utils' |
15 | import { HttpStatusCode, VideoCommentThreadTree, VideoPrivacy } from '@shared/models' | 15 | import { HttpStatusCode, VideoCommentThreadTree, VideoPrivacy } from '@shared/models' |
@@ -70,8 +70,9 @@ describe('Test multiple servers', function () { | |||
70 | }) | 70 | }) |
71 | 71 | ||
72 | describe('Should upload the video and propagate on each server', function () { | 72 | describe('Should upload the video and propagate on each server', function () { |
73 | |||
73 | it('Should upload the video on server 1 and propagate on each server', async function () { | 74 | it('Should upload the video on server 1 and propagate on each server', async function () { |
74 | this.timeout(25000) | 75 | this.timeout(60000) |
75 | 76 | ||
76 | const attributes = { | 77 | const attributes = { |
77 | name: 'my super name for server 1', | 78 | name: 'my super name for server 1', |
@@ -175,8 +176,8 @@ describe('Test multiple servers', function () { | |||
175 | support: 'my super support text for server 2', | 176 | support: 'my super support text for server 2', |
176 | tags: [ 'tag1p2', 'tag2p2', 'tag3p2' ], | 177 | tags: [ 'tag1p2', 'tag2p2', 'tag3p2' ], |
177 | fixture: 'video_short2.webm', | 178 | fixture: 'video_short2.webm', |
178 | thumbnailfile: 'thumbnail.jpg', | 179 | thumbnailfile: 'custom-thumbnail.jpg', |
179 | previewfile: 'preview.jpg' | 180 | previewfile: 'custom-preview.jpg' |
180 | } | 181 | } |
181 | await servers[1].videos.upload({ token: userAccessToken, attributes, mode: 'resumable' }) | 182 | await servers[1].videos.upload({ token: userAccessToken, attributes, mode: 'resumable' }) |
182 | 183 | ||
@@ -229,8 +230,8 @@ describe('Test multiple servers', function () { | |||
229 | size: 750000 | 230 | size: 750000 |
230 | } | 231 | } |
231 | ], | 232 | ], |
232 | thumbnailfile: 'thumbnail', | 233 | thumbnailfile: 'custom-thumbnail', |
233 | previewfile: 'preview' | 234 | previewfile: 'custom-preview' |
234 | } | 235 | } |
235 | 236 | ||
236 | const { data } = await server.videos.list() | 237 | const { data } = await server.videos.list() |
@@ -619,9 +620,9 @@ describe('Test multiple servers', function () { | |||
619 | description: 'my super description updated', | 620 | description: 'my super description updated', |
620 | support: 'my super support text updated', | 621 | support: 'my super support text updated', |
621 | tags: [ 'tag_up_1', 'tag_up_2' ], | 622 | tags: [ 'tag_up_1', 'tag_up_2' ], |
622 | thumbnailfile: 'thumbnail.jpg', | 623 | thumbnailfile: 'custom-thumbnail.jpg', |
623 | originallyPublishedAt: '2019-02-11T13:38:14.449Z', | 624 | originallyPublishedAt: '2019-02-11T13:38:14.449Z', |
624 | previewfile: 'preview.jpg' | 625 | previewfile: 'custom-preview.jpg' |
625 | } | 626 | } |
626 | 627 | ||
627 | updatedAtMin = new Date() | 628 | updatedAtMin = new Date() |
@@ -674,8 +675,8 @@ describe('Test multiple servers', function () { | |||
674 | size: 292677 | 675 | size: 292677 |
675 | } | 676 | } |
676 | ], | 677 | ], |
677 | thumbnailfile: 'thumbnail', | 678 | thumbnailfile: 'custom-thumbnail', |
678 | previewfile: 'preview' | 679 | previewfile: 'custom-preview' |
679 | } | 680 | } |
680 | await completeVideoCheck({ server, originServer: servers[2], videoUUID: videoUpdated.uuid, attributes: checkAttributes }) | 681 | await completeVideoCheck({ server, originServer: servers[2], videoUUID: videoUpdated.uuid, attributes: checkAttributes }) |
681 | } | 682 | } |
@@ -685,7 +686,7 @@ describe('Test multiple servers', function () { | |||
685 | this.timeout(30000) | 686 | this.timeout(30000) |
686 | 687 | ||
687 | const attributes = { | 688 | const attributes = { |
688 | thumbnailfile: 'thumbnail.jpg' | 689 | thumbnailfile: 'custom-thumbnail.jpg' |
689 | } | 690 | } |
690 | 691 | ||
691 | updatedAtMin = new Date() | 692 | updatedAtMin = new Date() |
@@ -761,7 +762,7 @@ describe('Test multiple servers', function () { | |||
761 | for (const server of servers) { | 762 | for (const server of servers) { |
762 | const video = await server.videos.get({ id: videoUUID }) | 763 | const video = await server.videos.get({ id: videoUUID }) |
763 | 764 | ||
764 | await testImage(server.url, 'video_short1-preview.webm', video.previewPath) | 765 | await testImageGeneratedByFFmpeg(server.url, 'video_short1-preview.webm', video.previewPath) |
765 | } | 766 | } |
766 | }) | 767 | }) |
767 | }) | 768 | }) |
diff --git a/server/tests/api/videos/single-server.ts b/server/tests/api/videos/single-server.ts index 0cb64d5a5..66414aa5b 100644 --- a/server/tests/api/videos/single-server.ts +++ b/server/tests/api/videos/single-server.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | 1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ |
2 | 2 | ||
3 | import { expect } from 'chai' | 3 | import { expect } from 'chai' |
4 | import { checkVideoFilesWereRemoved, completeVideoCheck, testImage } from '@server/tests/shared' | 4 | import { checkVideoFilesWereRemoved, completeVideoCheck, testImageGeneratedByFFmpeg } from '@server/tests/shared' |
5 | import { wait } from '@shared/core-utils' | 5 | import { wait } from '@shared/core-utils' |
6 | import { Video, VideoPrivacy } from '@shared/models' | 6 | import { Video, VideoPrivacy } from '@shared/models' |
7 | import { | 7 | import { |
@@ -260,7 +260,7 @@ describe('Test a single server', function () { | |||
260 | 260 | ||
261 | for (const video of data) { | 261 | for (const video of data) { |
262 | const videoName = video.name.replace(' name', '') | 262 | const videoName = video.name.replace(' name', '') |
263 | await testImage(server.url, videoName, video.thumbnailPath) | 263 | await testImageGeneratedByFFmpeg(server.url, videoName, video.thumbnailPath) |
264 | } | 264 | } |
265 | }) | 265 | }) |
266 | 266 | ||
diff --git a/server/tests/api/videos/video-imports.ts b/server/tests/api/videos/video-imports.ts index 192b2aeb9..a684a55a0 100644 --- a/server/tests/api/videos/video-imports.ts +++ b/server/tests/api/videos/video-imports.ts | |||
@@ -3,7 +3,7 @@ | |||
3 | import { expect } from 'chai' | 3 | import { expect } from 'chai' |
4 | import { pathExists, readdir, remove } from 'fs-extra' | 4 | import { pathExists, readdir, remove } from 'fs-extra' |
5 | import { join } from 'path' | 5 | import { join } from 'path' |
6 | import { FIXTURE_URLS, testCaptionFile, testImage } from '@server/tests/shared' | 6 | import { FIXTURE_URLS, testCaptionFile, testImageGeneratedByFFmpeg } from '@server/tests/shared' |
7 | import { areHttpImportTestsDisabled } from '@shared/core-utils' | 7 | import { areHttpImportTestsDisabled } from '@shared/core-utils' |
8 | import { CustomConfig, HttpStatusCode, Video, VideoImportState, VideoPrivacy, VideoResolution, VideoState } from '@shared/models' | 8 | import { CustomConfig, HttpStatusCode, Video, VideoImportState, VideoPrivacy, VideoResolution, VideoState } from '@shared/models' |
9 | import { | 9 | import { |
@@ -67,7 +67,7 @@ async function checkVideoServer2 (server: PeerTubeServer, id: number | string) { | |||
67 | expect(video.description).to.equal('my super description') | 67 | expect(video.description).to.equal('my super description') |
68 | expect(video.tags).to.deep.equal([ 'supertag1', 'supertag2' ]) | 68 | expect(video.tags).to.deep.equal([ 'supertag1', 'supertag2' ]) |
69 | 69 | ||
70 | await testImage(server.url, 'thumbnail', video.thumbnailPath) | 70 | await testImageGeneratedByFFmpeg(server.url, 'custom-thumbnail', video.thumbnailPath) |
71 | 71 | ||
72 | expect(video.files).to.have.lengthOf(1) | 72 | expect(video.files).to.have.lengthOf(1) |
73 | 73 | ||
@@ -126,8 +126,8 @@ describe('Test video imports', function () { | |||
126 | ? '_yt_dlp' | 126 | ? '_yt_dlp' |
127 | : '' | 127 | : '' |
128 | 128 | ||
129 | await testImage(servers[0].url, 'video_import_thumbnail' + suffix, video.thumbnailPath) | 129 | await testImageGeneratedByFFmpeg(servers[0].url, 'video_import_thumbnail' + suffix, video.thumbnailPath) |
130 | await testImage(servers[0].url, 'video_import_preview' + suffix, video.previewPath) | 130 | await testImageGeneratedByFFmpeg(servers[0].url, 'video_import_preview' + suffix, video.previewPath) |
131 | } | 131 | } |
132 | 132 | ||
133 | const bodyCaptions = await servers[0].captions.list({ videoId: video.id }) | 133 | const bodyCaptions = await servers[0].captions.list({ videoId: video.id }) |
@@ -266,7 +266,7 @@ describe('Test video imports', function () { | |||
266 | name: 'my super name', | 266 | name: 'my super name', |
267 | description: 'my super description', | 267 | description: 'my super description', |
268 | tags: [ 'supertag1', 'supertag2' ], | 268 | tags: [ 'supertag1', 'supertag2' ], |
269 | thumbnailfile: 'thumbnail.jpg' | 269 | thumbnailfile: 'custom-thumbnail.jpg' |
270 | } | 270 | } |
271 | }) | 271 | }) |
272 | expect(video.name).to.equal('my super name') | 272 | expect(video.name).to.equal('my super name') |
diff --git a/server/tests/api/videos/video-playlist-thumbnails.ts b/server/tests/api/videos/video-playlist-thumbnails.ts index 356939b93..c274c20bf 100644 --- a/server/tests/api/videos/video-playlist-thumbnails.ts +++ b/server/tests/api/videos/video-playlist-thumbnails.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | 1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ |
2 | 2 | ||
3 | import { expect } from 'chai' | 3 | import { expect } from 'chai' |
4 | import { testImage } from '@server/tests/shared' | 4 | import { testImageGeneratedByFFmpeg } from '@server/tests/shared' |
5 | import { VideoPlaylistPrivacy } from '@shared/models' | 5 | import { VideoPlaylistPrivacy } from '@shared/models' |
6 | import { | 6 | import { |
7 | cleanupTests, | 7 | cleanupTests, |
@@ -83,7 +83,7 @@ describe('Playlist thumbnail', function () { | |||
83 | 83 | ||
84 | for (const server of servers) { | 84 | for (const server of servers) { |
85 | const p = await getPlaylistWithoutThumbnail(server) | 85 | const p = await getPlaylistWithoutThumbnail(server) |
86 | await testImage(server.url, 'thumbnail-playlist', p.thumbnailPath) | 86 | await testImageGeneratedByFFmpeg(server.url, 'thumbnail-playlist', p.thumbnailPath) |
87 | } | 87 | } |
88 | }) | 88 | }) |
89 | 89 | ||
@@ -95,7 +95,7 @@ describe('Playlist thumbnail', function () { | |||
95 | displayName: 'playlist with thumbnail', | 95 | displayName: 'playlist with thumbnail', |
96 | privacy: VideoPlaylistPrivacy.PUBLIC, | 96 | privacy: VideoPlaylistPrivacy.PUBLIC, |
97 | videoChannelId: servers[1].store.channel.id, | 97 | videoChannelId: servers[1].store.channel.id, |
98 | thumbnailfile: 'thumbnail.jpg' | 98 | thumbnailfile: 'custom-thumbnail.jpg' |
99 | } | 99 | } |
100 | }) | 100 | }) |
101 | playlistWithThumbnailId = created.id | 101 | playlistWithThumbnailId = created.id |
@@ -110,7 +110,7 @@ describe('Playlist thumbnail', function () { | |||
110 | 110 | ||
111 | for (const server of servers) { | 111 | for (const server of servers) { |
112 | const p = await getPlaylistWithThumbnail(server) | 112 | const p = await getPlaylistWithThumbnail(server) |
113 | await testImage(server.url, 'thumbnail', p.thumbnailPath) | 113 | await testImageGeneratedByFFmpeg(server.url, 'custom-thumbnail', p.thumbnailPath) |
114 | } | 114 | } |
115 | }) | 115 | }) |
116 | 116 | ||
@@ -135,7 +135,7 @@ describe('Playlist thumbnail', function () { | |||
135 | 135 | ||
136 | for (const server of servers) { | 136 | for (const server of servers) { |
137 | const p = await getPlaylistWithoutThumbnail(server) | 137 | const p = await getPlaylistWithoutThumbnail(server) |
138 | await testImage(server.url, 'thumbnail-playlist', p.thumbnailPath) | 138 | await testImageGeneratedByFFmpeg(server.url, 'thumbnail-playlist', p.thumbnailPath) |
139 | } | 139 | } |
140 | }) | 140 | }) |
141 | 141 | ||
@@ -160,7 +160,7 @@ describe('Playlist thumbnail', function () { | |||
160 | 160 | ||
161 | for (const server of servers) { | 161 | for (const server of servers) { |
162 | const p = await getPlaylistWithThumbnail(server) | 162 | const p = await getPlaylistWithThumbnail(server) |
163 | await testImage(server.url, 'thumbnail', p.thumbnailPath) | 163 | await testImageGeneratedByFFmpeg(server.url, 'custom-thumbnail', p.thumbnailPath) |
164 | } | 164 | } |
165 | }) | 165 | }) |
166 | 166 | ||
@@ -176,7 +176,7 @@ describe('Playlist thumbnail', function () { | |||
176 | 176 | ||
177 | for (const server of servers) { | 177 | for (const server of servers) { |
178 | const p = await getPlaylistWithoutThumbnail(server) | 178 | const p = await getPlaylistWithoutThumbnail(server) |
179 | await testImage(server.url, 'thumbnail-playlist', p.thumbnailPath) | 179 | await testImageGeneratedByFFmpeg(server.url, 'thumbnail-playlist', p.thumbnailPath) |
180 | } | 180 | } |
181 | }) | 181 | }) |
182 | 182 | ||
@@ -192,7 +192,7 @@ describe('Playlist thumbnail', function () { | |||
192 | 192 | ||
193 | for (const server of servers) { | 193 | for (const server of servers) { |
194 | const p = await getPlaylistWithThumbnail(server) | 194 | const p = await getPlaylistWithThumbnail(server) |
195 | await testImage(server.url, 'thumbnail', p.thumbnailPath) | 195 | await testImageGeneratedByFFmpeg(server.url, 'custom-thumbnail', p.thumbnailPath) |
196 | } | 196 | } |
197 | }) | 197 | }) |
198 | 198 | ||
@@ -224,7 +224,7 @@ describe('Playlist thumbnail', function () { | |||
224 | 224 | ||
225 | for (const server of servers) { | 225 | for (const server of servers) { |
226 | const p = await getPlaylistWithThumbnail(server) | 226 | const p = await getPlaylistWithThumbnail(server) |
227 | await testImage(server.url, 'thumbnail', p.thumbnailPath) | 227 | await testImageGeneratedByFFmpeg(server.url, 'custom-thumbnail', p.thumbnailPath) |
228 | } | 228 | } |
229 | }) | 229 | }) |
230 | 230 | ||
diff --git a/server/tests/api/videos/video-playlists.ts b/server/tests/api/videos/video-playlists.ts index 9277b49f4..3bfa874cb 100644 --- a/server/tests/api/videos/video-playlists.ts +++ b/server/tests/api/videos/video-playlists.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | 1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ |
2 | 2 | ||
3 | import { expect } from 'chai' | 3 | import { expect } from 'chai' |
4 | import { checkPlaylistFilesWereRemoved, testImage } from '@server/tests/shared' | 4 | import { checkPlaylistFilesWereRemoved, testImageGeneratedByFFmpeg } from '@server/tests/shared' |
5 | import { wait } from '@shared/core-utils' | 5 | import { wait } from '@shared/core-utils' |
6 | import { uuidToShort } from '@shared/extra-utils' | 6 | import { uuidToShort } from '@shared/extra-utils' |
7 | import { | 7 | import { |
@@ -133,7 +133,7 @@ describe('Test video playlists', function () { | |||
133 | displayName: 'my super playlist', | 133 | displayName: 'my super playlist', |
134 | privacy: VideoPlaylistPrivacy.PUBLIC, | 134 | privacy: VideoPlaylistPrivacy.PUBLIC, |
135 | description: 'my super description', | 135 | description: 'my super description', |
136 | thumbnailfile: 'thumbnail.jpg', | 136 | thumbnailfile: 'custom-thumbnail.jpg', |
137 | videoChannelId: servers[0].store.channel.id | 137 | videoChannelId: servers[0].store.channel.id |
138 | } | 138 | } |
139 | }) | 139 | }) |
@@ -225,7 +225,7 @@ describe('Test video playlists', function () { | |||
225 | displayName: 'my super playlist', | 225 | displayName: 'my super playlist', |
226 | privacy: VideoPlaylistPrivacy.PUBLIC, | 226 | privacy: VideoPlaylistPrivacy.PUBLIC, |
227 | description: 'my super description', | 227 | description: 'my super description', |
228 | thumbnailfile: 'thumbnail.jpg', | 228 | thumbnailfile: 'custom-thumbnail.jpg', |
229 | videoChannelId: servers[0].store.channel.id | 229 | videoChannelId: servers[0].store.channel.id |
230 | } | 230 | } |
231 | }) | 231 | }) |
@@ -286,7 +286,7 @@ describe('Test video playlists', function () { | |||
286 | attributes: { | 286 | attributes: { |
287 | displayName: 'playlist 3', | 287 | displayName: 'playlist 3', |
288 | privacy: VideoPlaylistPrivacy.PUBLIC, | 288 | privacy: VideoPlaylistPrivacy.PUBLIC, |
289 | thumbnailfile: 'thumbnail.jpg', | 289 | thumbnailfile: 'custom-thumbnail.jpg', |
290 | videoChannelId: servers[1].store.channel.id | 290 | videoChannelId: servers[1].store.channel.id |
291 | } | 291 | } |
292 | }) | 292 | }) |
@@ -314,11 +314,11 @@ describe('Test video playlists', function () { | |||
314 | 314 | ||
315 | const playlist2 = body.data.find(p => p.displayName === 'playlist 2') | 315 | const playlist2 = body.data.find(p => p.displayName === 'playlist 2') |
316 | expect(playlist2).to.not.be.undefined | 316 | expect(playlist2).to.not.be.undefined |
317 | await testImage(server.url, 'thumbnail-playlist', playlist2.thumbnailPath) | 317 | await testImageGeneratedByFFmpeg(server.url, 'thumbnail-playlist', playlist2.thumbnailPath) |
318 | 318 | ||
319 | const playlist3 = body.data.find(p => p.displayName === 'playlist 3') | 319 | const playlist3 = body.data.find(p => p.displayName === 'playlist 3') |
320 | expect(playlist3).to.not.be.undefined | 320 | expect(playlist3).to.not.be.undefined |
321 | await testImage(server.url, 'thumbnail', playlist3.thumbnailPath) | 321 | await testImageGeneratedByFFmpeg(server.url, 'custom-thumbnail', playlist3.thumbnailPath) |
322 | } | 322 | } |
323 | 323 | ||
324 | const body = await servers[2].playlists.list({ start: 0, count: 5 }) | 324 | const body = await servers[2].playlists.list({ start: 0, count: 5 }) |
@@ -336,7 +336,7 @@ describe('Test video playlists', function () { | |||
336 | 336 | ||
337 | const playlist2 = body.data.find(p => p.displayName === 'playlist 2') | 337 | const playlist2 = body.data.find(p => p.displayName === 'playlist 2') |
338 | expect(playlist2).to.not.be.undefined | 338 | expect(playlist2).to.not.be.undefined |
339 | await testImage(servers[2].url, 'thumbnail-playlist', playlist2.thumbnailPath) | 339 | await testImageGeneratedByFFmpeg(servers[2].url, 'thumbnail-playlist', playlist2.thumbnailPath) |
340 | 340 | ||
341 | expect(body.data.find(p => p.displayName === 'playlist 3')).to.not.be.undefined | 341 | expect(body.data.find(p => p.displayName === 'playlist 3')).to.not.be.undefined |
342 | }) | 342 | }) |
@@ -502,7 +502,7 @@ describe('Test video playlists', function () { | |||
502 | displayName: 'playlist 3 updated', | 502 | displayName: 'playlist 3 updated', |
503 | description: 'description updated', | 503 | description: 'description updated', |
504 | privacy: VideoPlaylistPrivacy.UNLISTED, | 504 | privacy: VideoPlaylistPrivacy.UNLISTED, |
505 | thumbnailfile: 'thumbnail.jpg', | 505 | thumbnailfile: 'custom-thumbnail.jpg', |
506 | videoChannelId: servers[1].store.channel.id | 506 | videoChannelId: servers[1].store.channel.id |
507 | }, | 507 | }, |
508 | playlistId: playlistServer2Id2 | 508 | playlistId: playlistServer2Id2 |
diff --git a/server/tests/api/videos/video-storyboard.ts b/server/tests/api/videos/video-storyboard.ts index 5fde6ce45..fc4b4450f 100644 --- a/server/tests/api/videos/video-storyboard.ts +++ b/server/tests/api/videos/video-storyboard.ts | |||
@@ -110,7 +110,11 @@ describe('Test video storyboard', function () { | |||
110 | await waitJobs(servers) | 110 | await waitJobs(servers) |
111 | 111 | ||
112 | for (const server of servers) { | 112 | for (const server of servers) { |
113 | await checkStoryboard({ server, uuid, tilesCount: 6, minSize: 250 }) | 113 | try { |
114 | await checkStoryboard({ server, uuid, tilesCount: 6, minSize: 250 }) | ||
115 | } catch { // FIXME: to remove after ffmpeg CI upgrade, ffmpeg CI version (4.3) generates a 7.6s length video | ||
116 | await checkStoryboard({ server, uuid, tilesCount: 8, minSize: 250 }) | ||
117 | } | ||
114 | } | 118 | } |
115 | }) | 119 | }) |
116 | 120 | ||
diff --git a/server/tests/cli/prune-storage.ts b/server/tests/cli/prune-storage.ts index 8bdf2136d..dc8ecd3d3 100644 --- a/server/tests/cli/prune-storage.ts +++ b/server/tests/cli/prune-storage.ts | |||
@@ -85,7 +85,7 @@ describe('Test prune storage scripts', function () { | |||
85 | displayName: 'playlist', | 85 | displayName: 'playlist', |
86 | privacy: VideoPlaylistPrivacy.PUBLIC, | 86 | privacy: VideoPlaylistPrivacy.PUBLIC, |
87 | videoChannelId: server.store.channel.id, | 87 | videoChannelId: server.store.channel.id, |
88 | thumbnailfile: 'thumbnail.jpg' | 88 | thumbnailfile: 'custom-thumbnail.jpg' |
89 | } | 89 | } |
90 | }) | 90 | }) |
91 | } | 91 | } |
diff --git a/server/tests/fixtures/custom-preview-big.png b/server/tests/fixtures/custom-preview-big.png new file mode 100644 index 000000000..03d171af3 --- /dev/null +++ b/server/tests/fixtures/custom-preview-big.png | |||
Binary files differ | |||
diff --git a/server/tests/fixtures/custom-preview.jpg b/server/tests/fixtures/custom-preview.jpg new file mode 100644 index 000000000..5a039d830 --- /dev/null +++ b/server/tests/fixtures/custom-preview.jpg | |||
Binary files differ | |||
diff --git a/server/tests/fixtures/custom-thumbnail-big.jpg b/server/tests/fixtures/custom-thumbnail-big.jpg new file mode 100644 index 000000000..08375e425 --- /dev/null +++ b/server/tests/fixtures/custom-thumbnail-big.jpg | |||
Binary files differ | |||
diff --git a/server/tests/fixtures/custom-thumbnail.jpg b/server/tests/fixtures/custom-thumbnail.jpg new file mode 100644 index 000000000..ef818442d --- /dev/null +++ b/server/tests/fixtures/custom-thumbnail.jpg | |||
Binary files differ | |||
diff --git a/server/tests/fixtures/custom-thumbnail.png b/server/tests/fixtures/custom-thumbnail.png new file mode 100644 index 000000000..9f34daec1 --- /dev/null +++ b/server/tests/fixtures/custom-thumbnail.png | |||
Binary files differ | |||
diff --git a/server/tests/fixtures/preview-big.png b/server/tests/fixtures/preview-big.png deleted file mode 100644 index 612e297f1..000000000 --- a/server/tests/fixtures/preview-big.png +++ /dev/null | |||
Binary files differ | |||
diff --git a/server/tests/fixtures/preview.jpg b/server/tests/fixtures/preview.jpg deleted file mode 100644 index 1421da738..000000000 --- a/server/tests/fixtures/preview.jpg +++ /dev/null | |||
Binary files differ | |||
diff --git a/server/tests/fixtures/thumbnail-big.jpg b/server/tests/fixtures/thumbnail-big.jpg deleted file mode 100644 index 537720d24..000000000 --- a/server/tests/fixtures/thumbnail-big.jpg +++ /dev/null | |||
Binary files differ | |||
diff --git a/server/tests/fixtures/thumbnail.jpg b/server/tests/fixtures/thumbnail.jpg deleted file mode 100644 index 020853780..000000000 --- a/server/tests/fixtures/thumbnail.jpg +++ /dev/null | |||
Binary files differ | |||
diff --git a/server/tests/fixtures/thumbnail.png b/server/tests/fixtures/thumbnail.png deleted file mode 100644 index b331aba3b..000000000 --- a/server/tests/fixtures/thumbnail.png +++ /dev/null | |||
Binary files differ | |||
diff --git a/server/tests/fixtures/video_short1-preview.webm.jpg b/server/tests/fixtures/video_short1-preview.webm.jpg index f5659f6a8..15454942d 100644 --- a/server/tests/fixtures/video_short1-preview.webm.jpg +++ b/server/tests/fixtures/video_short1-preview.webm.jpg | |||
Binary files differ | |||
diff --git a/server/tests/fixtures/video_short1.webm.jpg b/server/tests/fixtures/video_short1.webm.jpg index 26a697daa..b2740d73d 100644 --- a/server/tests/fixtures/video_short1.webm.jpg +++ b/server/tests/fixtures/video_short1.webm.jpg | |||
Binary files differ | |||
diff --git a/server/tests/fixtures/video_short2.webm.jpg b/server/tests/fixtures/video_short2.webm.jpg index 020853780..afe476c7f 100644 --- a/server/tests/fixtures/video_short2.webm.jpg +++ b/server/tests/fixtures/video_short2.webm.jpg | |||
Binary files differ | |||
diff --git a/server/tests/helpers/image.ts b/server/tests/helpers/image.ts index 530c9bacd..6021ffc48 100644 --- a/server/tests/helpers/image.ts +++ b/server/tests/helpers/image.ts | |||
@@ -35,28 +35,28 @@ describe('Image helpers', function () { | |||
35 | const thumbnailSize = { width: 280, height: 157 } | 35 | const thumbnailSize = { width: 280, height: 157 } |
36 | 36 | ||
37 | it('Should skip processing if the source image is okay', async function () { | 37 | it('Should skip processing if the source image is okay', async function () { |
38 | const input = buildAbsoluteFixturePath('thumbnail.jpg') | 38 | const input = buildAbsoluteFixturePath('custom-thumbnail.jpg') |
39 | await processImage({ path: input, destination: imageDestJPG, newSize: thumbnailSize, keepOriginal: true }) | 39 | await processImage({ path: input, destination: imageDestJPG, newSize: thumbnailSize, keepOriginal: true }) |
40 | 40 | ||
41 | await checkBuffers(input, imageDestJPG, true) | 41 | await checkBuffers(input, imageDestJPG, true) |
42 | }) | 42 | }) |
43 | 43 | ||
44 | it('Should not skip processing if the source image does not have the appropriate extension', async function () { | 44 | it('Should not skip processing if the source image does not have the appropriate extension', async function () { |
45 | const input = buildAbsoluteFixturePath('thumbnail.png') | 45 | const input = buildAbsoluteFixturePath('custom-thumbnail.png') |
46 | await processImage({ path: input, destination: imageDestJPG, newSize: thumbnailSize, keepOriginal: true }) | 46 | await processImage({ path: input, destination: imageDestJPG, newSize: thumbnailSize, keepOriginal: true }) |
47 | 47 | ||
48 | await checkBuffers(input, imageDestJPG, false) | 48 | await checkBuffers(input, imageDestJPG, false) |
49 | }) | 49 | }) |
50 | 50 | ||
51 | it('Should not skip processing if the source image does not have the appropriate size', async function () { | 51 | it('Should not skip processing if the source image does not have the appropriate size', async function () { |
52 | const input = buildAbsoluteFixturePath('preview.jpg') | 52 | const input = buildAbsoluteFixturePath('custom-preview.jpg') |
53 | await processImage({ path: input, destination: imageDestJPG, newSize: thumbnailSize, keepOriginal: true }) | 53 | await processImage({ path: input, destination: imageDestJPG, newSize: thumbnailSize, keepOriginal: true }) |
54 | 54 | ||
55 | await checkBuffers(input, imageDestJPG, false) | 55 | await checkBuffers(input, imageDestJPG, false) |
56 | }) | 56 | }) |
57 | 57 | ||
58 | it('Should not skip processing if the source image does not have the appropriate size', async function () { | 58 | it('Should not skip processing if the source image does not have the appropriate size', async function () { |
59 | const input = buildAbsoluteFixturePath('thumbnail-big.jpg') | 59 | const input = buildAbsoluteFixturePath('custom-thumbnail-big.jpg') |
60 | await processImage({ path: input, destination: imageDestJPG, newSize: thumbnailSize, keepOriginal: true }) | 60 | await processImage({ path: input, destination: imageDestJPG, newSize: thumbnailSize, keepOriginal: true }) |
61 | 61 | ||
62 | await checkBuffers(input, imageDestJPG, false) | 62 | await checkBuffers(input, imageDestJPG, false) |
diff --git a/server/tests/shared/checks.ts b/server/tests/shared/checks.ts index feaef37c6..90179c6ac 100644 --- a/server/tests/shared/checks.ts +++ b/server/tests/shared/checks.ts | |||
@@ -61,6 +61,16 @@ async function testImageSize (url: string, imageName: string, imageHTTPPath: str | |||
61 | expect(body.length).to.be.below(maxLength, 'the generated image is way larger than the recorded fixture') | 61 | expect(body.length).to.be.below(maxLength, 'the generated image is way larger than the recorded fixture') |
62 | } | 62 | } |
63 | 63 | ||
64 | async function testImageGeneratedByFFmpeg (url: string, imageName: string, imageHTTPPath: string, extension = '.jpg') { | ||
65 | if (process.env.ENABLE_FFMPEG_THUMBNAIL_PIXEL_COMPARISON_TESTS !== 'true') { | ||
66 | console.log( | ||
67 | 'Pixel comparison of image generated by ffmpeg is disabled. ' + | ||
68 | 'You can enable it using `ENABLE_FFMPEG_THUMBNAIL_PIXEL_COMPARISON_TESTS=true env variable') | ||
69 | } | ||
70 | |||
71 | return testImage(url, imageName, imageHTTPPath, extension) | ||
72 | } | ||
73 | |||
64 | async function testImage (url: string, imageName: string, imageHTTPPath: string, extension = '.jpg') { | 74 | async function testImage (url: string, imageName: string, imageHTTPPath: string, extension = '.jpg') { |
65 | const res = await makeGetRequest({ | 75 | const res = await makeGetRequest({ |
66 | url, | 76 | url, |
@@ -148,6 +158,7 @@ async function checkVideoDuration (server: PeerTubeServer, videoUUID: string, du | |||
148 | 158 | ||
149 | export { | 159 | export { |
150 | dateIsValid, | 160 | dateIsValid, |
161 | testImageGeneratedByFFmpeg, | ||
151 | testImageSize, | 162 | testImageSize, |
152 | testImage, | 163 | testImage, |
153 | expectLogDoesNotContain, | 164 | expectLogDoesNotContain, |
diff --git a/server/tests/shared/videos.ts b/server/tests/shared/videos.ts index 856fabd11..0bd161820 100644 --- a/server/tests/shared/videos.ts +++ b/server/tests/shared/videos.ts | |||
@@ -7,7 +7,7 @@ import { loadLanguages, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO | |||
7 | import { getLowercaseExtension, pick, uuidRegex } from '@shared/core-utils' | 7 | import { getLowercaseExtension, pick, uuidRegex } from '@shared/core-utils' |
8 | import { HttpStatusCode, VideoCaption, VideoDetails, VideoPrivacy, VideoResolution } from '@shared/models' | 8 | import { HttpStatusCode, VideoCaption, VideoDetails, VideoPrivacy, VideoResolution } from '@shared/models' |
9 | import { makeRawRequest, PeerTubeServer, VideoEdit, waitJobs } from '@shared/server-commands' | 9 | import { makeRawRequest, PeerTubeServer, VideoEdit, waitJobs } from '@shared/server-commands' |
10 | import { dateIsValid, expectStartWith, testImage } from './checks' | 10 | import { dateIsValid, expectStartWith, testImageGeneratedByFFmpeg } from './checks' |
11 | import { checkWebTorrentWorks } from './webtorrent' | 11 | import { checkWebTorrentWorks } from './webtorrent' |
12 | 12 | ||
13 | loadLanguages() | 13 | loadLanguages() |
@@ -197,11 +197,11 @@ async function completeVideoCheck (options: { | |||
197 | expect(video.downloadEnabled).to.equal(attributes.downloadEnabled) | 197 | expect(video.downloadEnabled).to.equal(attributes.downloadEnabled) |
198 | 198 | ||
199 | expect(video.thumbnailPath).to.exist | 199 | expect(video.thumbnailPath).to.exist |
200 | await testImage(server.url, attributes.thumbnailfile || attributes.fixture, video.thumbnailPath) | 200 | await testImageGeneratedByFFmpeg(server.url, attributes.thumbnailfile || attributes.fixture, video.thumbnailPath) |
201 | 201 | ||
202 | if (attributes.previewfile) { | 202 | if (attributes.previewfile) { |
203 | expect(video.previewPath).to.exist | 203 | expect(video.previewPath).to.exist |
204 | await testImage(server.url, attributes.previewfile, video.previewPath) | 204 | await testImageGeneratedByFFmpeg(server.url, attributes.previewfile, video.previewPath) |
205 | } | 205 | } |
206 | 206 | ||
207 | await completeWebVideoFilesCheck({ server, originServer, videoUUID: video.uuid, ...pick(attributes, [ 'fixture', 'files' ]) }) | 207 | await completeWebVideoFilesCheck({ server, originServer, videoUUID: video.uuid, ...pick(attributes, [ 'fixture', 'files' ]) }) |
diff --git a/shared/server-commands/server/server.ts b/shared/server-commands/server/server.ts index 6aa4296b0..9a07eb36f 100644 --- a/shared/server-commands/server/server.ts +++ b/shared/server-commands/server/server.ts | |||
@@ -237,7 +237,7 @@ export class PeerTubeServer { | |||
237 | } | 237 | } |
238 | 238 | ||
239 | // Share the environment | 239 | // Share the environment |
240 | const env = Object.create(process.env) | 240 | const env = { ...process.env } |
241 | env['NODE_ENV'] = 'test' | 241 | env['NODE_ENV'] = 'test' |
242 | env['NODE_APP_INSTANCE'] = this.internalServerNumber.toString() | 242 | env['NODE_APP_INSTANCE'] = this.internalServerNumber.toString() |
243 | env['NODE_CONFIG'] = JSON.stringify(configOverride) | 243 | env['NODE_CONFIG'] = JSON.stringify(configOverride) |
diff --git a/shared/server-commands/videos/video-studio-command.ts b/shared/server-commands/videos/video-studio-command.ts index 9fe467cc2..675cd84b7 100644 --- a/shared/server-commands/videos/video-studio-command.ts +++ b/shared/server-commands/videos/video-studio-command.ts | |||
@@ -25,7 +25,7 @@ export class VideoStudioCommand extends AbstractCommand { | |||
25 | { | 25 | { |
26 | name: 'add-watermark', | 26 | name: 'add-watermark', |
27 | options: { | 27 | options: { |
28 | file: 'thumbnail.png' | 28 | file: 'custom-thumbnail.png' |
29 | } | 29 | } |
30 | }, | 30 | }, |
31 | 31 | ||
diff --git a/support/doc/development/tests.md b/support/doc/development/tests.md index e3a65c35f..1c2589c8a 100644 --- a/support/doc/development/tests.md +++ b/support/doc/development/tests.md | |||
@@ -71,6 +71,7 @@ Some env variables can be defined to disable/enable some tests: | |||
71 | * `ENABLE_OBJECT_STORAGE_TESTS=true`: enable object storage tests (needs `chocobozzz/s3-ninja` container first) | 71 | * `ENABLE_OBJECT_STORAGE_TESTS=true`: enable object storage tests (needs `chocobozzz/s3-ninja` container first) |
72 | * `AKISMET_KEY`: specify an Akismet key to test akismet external PeerTube plugin | 72 | * `AKISMET_KEY`: specify an Akismet key to test akismet external PeerTube plugin |
73 | * `OBJECT_STORAGE_SCALEWAY_KEY_ID` and `OBJECT_STORAGE_SCALEWAY_ACCESS_KEY`: specify Scaleway API keys to test object storage ACL (not supported by our `chocobozzz/s3-ninja` container) | 73 | * `OBJECT_STORAGE_SCALEWAY_KEY_ID` and `OBJECT_STORAGE_SCALEWAY_ACCESS_KEY`: specify Scaleway API keys to test object storage ACL (not supported by our `chocobozzz/s3-ninja` container) |
74 | * `ENABLE_FFMPEG_THUMBNAIL_PIXEL_COMPARISON_TESTS=true`: enable pixel comparison on images generated by ffmpeg. Disabled by default because a custom ffmpeg version may fails the tests | ||
74 | 75 | ||
75 | 76 | ||
76 | ### Debug server logs | 77 | ### Debug server logs |