mirror of
https://github.com/immich-app/immich.git
synced 2025-12-25 17:24:58 +03:00
@@ -294,16 +294,16 @@ describe(AssetMediaService.name, () => {
|
||||
|
||||
it('should return profile for profile uploads', () => {
|
||||
expect(sut.getUploadFolder(uploadFile.filename(UploadFieldName.PROFILE_DATA, 'image.jpg'))).toEqual(
|
||||
'upload/profile/admin_id',
|
||||
expect.stringContaining('upload/profile/admin_id'),
|
||||
);
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith('upload/profile/admin_id');
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith(expect.stringContaining('upload/profile/admin_id'));
|
||||
});
|
||||
|
||||
it('should return upload for everything else', () => {
|
||||
expect(sut.getUploadFolder(uploadFile.filename(UploadFieldName.ASSET_DATA, 'image.jpg'))).toEqual(
|
||||
'upload/upload/admin_id/ra/nd',
|
||||
expect.stringContaining('upload/upload/admin_id/ra/nd'),
|
||||
);
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith('upload/upload/admin_id/ra/nd');
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith(expect.stringContaining('upload/upload/admin_id/ra/nd'));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -913,7 +913,7 @@ describe(AssetMediaService.name, () => {
|
||||
|
||||
expect(mocks.job.queue).toHaveBeenCalledWith({
|
||||
name: JobName.FileDelete,
|
||||
data: { files: ['upload/upload/user-id/ra/nd/random-uuid.jpg'] },
|
||||
data: { files: [expect.stringContaining('upload/upload/user-id/ra/nd/random-uuid.jpg')] },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -789,7 +789,7 @@ describe(AuthService.name, () => {
|
||||
).resolves.toEqual(oauthResponse(user));
|
||||
|
||||
expect(mocks.user.update).toHaveBeenCalledWith(user.id, {
|
||||
profileImagePath: `upload/profile/${user.id}/${fileId}.jpg`,
|
||||
profileImagePath: expect.stringContaining(`upload/profile/${user.id}/${fileId}.jpg`),
|
||||
profileChangedAt: expect.any(Date),
|
||||
});
|
||||
expect(mocks.oauth.getProfilePicture).toHaveBeenCalledWith(pictureUrl);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { isAbsolute } from 'node:path';
|
||||
import { SALT_ROUNDS } from 'src/constants';
|
||||
import { UserAdminResponseDto, mapUserAdmin } from 'src/dtos/user.dto';
|
||||
import { BaseService } from 'src/services/base.service';
|
||||
@@ -67,6 +68,63 @@ export class CliService extends BaseService {
|
||||
await this.updateConfig(config);
|
||||
}
|
||||
|
||||
async getSampleFilePaths(): Promise<string[]> {
|
||||
const [assets, people, users] = await Promise.all([
|
||||
this.assetRepository.getFileSamples(),
|
||||
this.personRepository.getFileSamples(),
|
||||
this.userRepository.getFileSamples(),
|
||||
]);
|
||||
|
||||
const paths = [];
|
||||
|
||||
for (const person of people) {
|
||||
paths.push(person.thumbnailPath);
|
||||
}
|
||||
|
||||
for (const user of users) {
|
||||
paths.push(user.profileImagePath);
|
||||
}
|
||||
|
||||
for (const asset of assets) {
|
||||
paths.push(
|
||||
asset.originalPath,
|
||||
asset.sidecarPath,
|
||||
asset.encodedVideoPath,
|
||||
...asset.files.map((file) => file.path),
|
||||
);
|
||||
}
|
||||
|
||||
return paths.filter(Boolean) as string[];
|
||||
}
|
||||
|
||||
async migrateFilePaths({
|
||||
oldValue,
|
||||
newValue,
|
||||
confirm,
|
||||
}: {
|
||||
oldValue: string;
|
||||
newValue: string;
|
||||
confirm: (data: { sourceFolder: string; targetFolder: string }) => Promise<boolean>;
|
||||
}): Promise<boolean> {
|
||||
let sourceFolder = oldValue;
|
||||
if (sourceFolder.startsWith('./')) {
|
||||
sourceFolder = sourceFolder.slice(2);
|
||||
}
|
||||
|
||||
const targetFolder = newValue;
|
||||
if (!isAbsolute(targetFolder)) {
|
||||
throw new Error('Target media location must be an absolute path');
|
||||
}
|
||||
|
||||
if (!(await confirm({ sourceFolder, targetFolder }))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
await this.databaseRepository.migrateFilePaths(sourceFolder, targetFolder);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
return this.databaseRepository.shutdown();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { BadRequestException } from '@nestjs/common';
|
||||
import { APP_MEDIA_LOCATION } from 'src/constants';
|
||||
import { DownloadResponseDto } from 'src/dtos/download.dto';
|
||||
import { DownloadService } from 'src/services/download.service';
|
||||
import { assetStub } from 'test/fixtures/asset.stub';
|
||||
@@ -46,7 +47,11 @@ describe(DownloadService.name, () => {
|
||||
});
|
||||
|
||||
expect(archiveMock.addFile).toHaveBeenCalledTimes(1);
|
||||
expect(archiveMock.addFile).toHaveBeenNthCalledWith(1, 'upload/library/IMG_123.jpg', 'IMG_123.jpg');
|
||||
expect(archiveMock.addFile).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
expect.stringContaining('upload/library/IMG_123.jpg'),
|
||||
'IMG_123.jpg',
|
||||
);
|
||||
});
|
||||
|
||||
it('should log a warning if the original path could not be resolved', async () => {
|
||||
@@ -279,9 +284,15 @@ describe(DownloadService.name, () => {
|
||||
mocks.downloadRepository.downloadAssetIds.mockReturnValue(
|
||||
makeStream([{ id: 'asset-1', livePhotoVideoId: 'asset-3', size: 5000 }]),
|
||||
);
|
||||
|
||||
mocks.downloadRepository.downloadMotionAssetIds.mockReturnValue(
|
||||
makeStream([
|
||||
{ id: 'asset-2', livePhotoVideoId: null, size: 23_456, originalPath: 'upload/encoded-video/uuid-MP.mp4' },
|
||||
{
|
||||
id: 'asset-2',
|
||||
livePhotoVideoId: null,
|
||||
size: 23_456,
|
||||
originalPath: APP_MEDIA_LOCATION + '/encoded-video/uuid-MP.mp4',
|
||||
},
|
||||
]),
|
||||
);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { BadRequestException } from '@nestjs/common';
|
||||
import { Stats } from 'node:fs';
|
||||
import { defaults, SystemConfig } from 'src/config';
|
||||
import { JOBS_LIBRARY_PAGINATION_SIZE } from 'src/constants';
|
||||
import { APP_MEDIA_LOCATION, JOBS_LIBRARY_PAGINATION_SIZE } from 'src/constants';
|
||||
import { mapLibrary } from 'src/dtos/library.dto';
|
||||
import { AssetType, CronJob, ImmichWorker, JobName, JobStatus } from 'src/enum';
|
||||
import { LibraryService } from 'src/services/library.service';
|
||||
@@ -1264,7 +1264,7 @@ describe(LibraryService.name, () => {
|
||||
});
|
||||
|
||||
it('should detect when import path is in immich media folder', async () => {
|
||||
const importPaths = ['upload/thumbs', `${process.cwd()}/xyz`, 'upload/library'];
|
||||
const importPaths = [APP_MEDIA_LOCATION + '/thumbs', `${process.cwd()}/xyz`, APP_MEDIA_LOCATION + '/library'];
|
||||
const library = factory.library({ importPaths });
|
||||
|
||||
mocks.storage.stat.mockResolvedValue({ isDirectory: () => true } as Stats);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { OutputInfo } from 'sharp';
|
||||
import { SystemConfig } from 'src/config';
|
||||
import { APP_MEDIA_LOCATION } from 'src/constants';
|
||||
import { Exif } from 'src/database';
|
||||
import {
|
||||
AssetFileType,
|
||||
@@ -204,19 +205,19 @@ describe(MediaService.name, () => {
|
||||
entityId: assetStub.image.id,
|
||||
pathType: AssetPathType.FullSize,
|
||||
oldPath: '/uploads/user-id/fullsize/path.webp',
|
||||
newPath: 'upload/thumbs/user-id/as/se/asset-id-fullsize.jpeg',
|
||||
newPath: expect.stringContaining('upload/thumbs/user-id/as/se/asset-id-fullsize.jpeg'),
|
||||
});
|
||||
expect(mocks.move.create).toHaveBeenCalledWith({
|
||||
entityId: assetStub.image.id,
|
||||
pathType: AssetPathType.Preview,
|
||||
oldPath: '/uploads/user-id/thumbs/path.jpg',
|
||||
newPath: 'upload/thumbs/user-id/as/se/asset-id-preview.jpeg',
|
||||
newPath: expect.stringContaining('upload/thumbs/user-id/as/se/asset-id-preview.jpeg'),
|
||||
});
|
||||
expect(mocks.move.create).toHaveBeenCalledWith({
|
||||
entityId: assetStub.image.id,
|
||||
pathType: AssetPathType.Thumbnail,
|
||||
oldPath: '/uploads/user-id/webp/path.ext',
|
||||
newPath: 'upload/thumbs/user-id/as/se/asset-id-thumbnail.webp',
|
||||
newPath: expect.stringContaining('upload/thumbs/user-id/as/se/asset-id-thumbnail.webp'),
|
||||
});
|
||||
expect(mocks.move.create).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
@@ -295,7 +296,7 @@ describe(MediaService.name, () => {
|
||||
|
||||
await sut.handleGenerateThumbnails({ id: assetStub.image.id });
|
||||
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith('upload/thumbs/user-id/as/se');
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith(expect.any(String));
|
||||
|
||||
expect(mocks.media.decodeImage).toHaveBeenCalledOnce();
|
||||
expect(mocks.media.decodeImage).toHaveBeenCalledWith(assetStub.image.originalPath, {
|
||||
@@ -315,7 +316,7 @@ describe(MediaService.name, () => {
|
||||
processInvalidImages: false,
|
||||
raw: rawInfo,
|
||||
},
|
||||
'upload/thumbs/user-id/as/se/asset-id-preview.jpeg',
|
||||
expect.any(String),
|
||||
);
|
||||
expect(mocks.media.generateThumbnail).toHaveBeenCalledWith(
|
||||
rawBuffer,
|
||||
@@ -327,7 +328,7 @@ describe(MediaService.name, () => {
|
||||
processInvalidImages: false,
|
||||
raw: rawInfo,
|
||||
},
|
||||
'upload/thumbs/user-id/as/se/asset-id-thumbnail.webp',
|
||||
expect.any(String),
|
||||
);
|
||||
|
||||
expect(mocks.media.generateThumbhash).toHaveBeenCalledOnce();
|
||||
@@ -341,12 +342,12 @@ describe(MediaService.name, () => {
|
||||
{
|
||||
assetId: 'asset-id',
|
||||
type: AssetFileType.Preview,
|
||||
path: 'upload/thumbs/user-id/as/se/asset-id-preview.jpeg',
|
||||
path: expect.any(String),
|
||||
},
|
||||
{
|
||||
assetId: 'asset-id',
|
||||
type: AssetFileType.Thumbnail,
|
||||
path: 'upload/thumbs/user-id/as/se/asset-id-thumbnail.webp',
|
||||
path: expect.any(String),
|
||||
},
|
||||
]);
|
||||
expect(mocks.asset.update).toHaveBeenCalledWith({ id: 'asset-id', thumbhash: thumbhashBuffer });
|
||||
@@ -357,10 +358,10 @@ describe(MediaService.name, () => {
|
||||
mocks.assetJob.getForGenerateThumbnailJob.mockResolvedValue(assetStub.video);
|
||||
await sut.handleGenerateThumbnails({ id: assetStub.video.id });
|
||||
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith('upload/thumbs/user-id/as/se');
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith(expect.any(String));
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/thumbs/user-id/as/se/asset-id-preview.jpeg',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: ['-skip_frame nointra', '-sws_flags accurate_rnd+full_chroma_int'],
|
||||
outputOptions: [
|
||||
@@ -377,12 +378,12 @@ describe(MediaService.name, () => {
|
||||
{
|
||||
assetId: 'asset-id',
|
||||
type: AssetFileType.Preview,
|
||||
path: 'upload/thumbs/user-id/as/se/asset-id-preview.jpeg',
|
||||
path: expect.any(String),
|
||||
},
|
||||
{
|
||||
assetId: 'asset-id',
|
||||
type: AssetFileType.Thumbnail,
|
||||
path: 'upload/thumbs/user-id/as/se/asset-id-thumbnail.webp',
|
||||
path: expect.any(String),
|
||||
},
|
||||
]);
|
||||
});
|
||||
@@ -392,10 +393,10 @@ describe(MediaService.name, () => {
|
||||
mocks.assetJob.getForGenerateThumbnailJob.mockResolvedValue(assetStub.video);
|
||||
await sut.handleGenerateThumbnails({ id: assetStub.video.id });
|
||||
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith('upload/thumbs/user-id/as/se');
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith(expect.any(String));
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/thumbs/user-id/as/se/asset-id-preview.jpeg',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: ['-skip_frame nointra', '-sws_flags accurate_rnd+full_chroma_int'],
|
||||
outputOptions: [
|
||||
@@ -412,12 +413,12 @@ describe(MediaService.name, () => {
|
||||
{
|
||||
assetId: 'asset-id',
|
||||
type: AssetFileType.Preview,
|
||||
path: 'upload/thumbs/user-id/as/se/asset-id-preview.jpeg',
|
||||
path: expect.any(String),
|
||||
},
|
||||
{
|
||||
assetId: 'asset-id',
|
||||
type: AssetFileType.Thumbnail,
|
||||
path: 'upload/thumbs/user-id/as/se/asset-id-thumbnail.webp',
|
||||
path: expect.any(String),
|
||||
},
|
||||
]);
|
||||
});
|
||||
@@ -432,7 +433,7 @@ describe(MediaService.name, () => {
|
||||
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/thumbs/user-id/as/se/asset-id-preview.jpeg',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: ['-skip_frame nointra', '-sws_flags accurate_rnd+full_chroma_int'],
|
||||
outputOptions: [
|
||||
@@ -453,7 +454,7 @@ describe(MediaService.name, () => {
|
||||
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/thumbs/user-id/as/se/asset-id-preview.jpeg',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: ['-sws_flags accurate_rnd+full_chroma_int'],
|
||||
outputOptions: expect.any(Array),
|
||||
@@ -471,7 +472,7 @@ describe(MediaService.name, () => {
|
||||
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/thumbs/user-id/as/se/asset-id-preview.jpeg',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining([expect.stringContaining('scale=-2:1440')]),
|
||||
@@ -485,12 +486,12 @@ describe(MediaService.name, () => {
|
||||
mocks.assetJob.getForGenerateThumbnailJob.mockResolvedValue(assetStub.image);
|
||||
const thumbhashBuffer = Buffer.from('a thumbhash', 'utf8');
|
||||
mocks.media.generateThumbhash.mockResolvedValue(thumbhashBuffer);
|
||||
const previewPath = `upload/thumbs/user-id/as/se/asset-id-preview.${format}`;
|
||||
const thumbnailPath = `upload/thumbs/user-id/as/se/asset-id-thumbnail.webp`;
|
||||
const previewPath = APP_MEDIA_LOCATION + `/thumbs/user-id/as/se/asset-id-preview.${format}`;
|
||||
const thumbnailPath = APP_MEDIA_LOCATION + `/thumbs/user-id/as/se/asset-id-thumbnail.webp`;
|
||||
|
||||
await sut.handleGenerateThumbnails({ id: assetStub.image.id });
|
||||
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith('upload/thumbs/user-id/as/se');
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith(expect.any(String));
|
||||
expect(mocks.media.decodeImage).toHaveBeenCalledOnce();
|
||||
expect(mocks.media.decodeImage).toHaveBeenCalledWith(assetStub.image.originalPath, {
|
||||
colorspace: Colorspace.Srgb,
|
||||
@@ -530,12 +531,12 @@ describe(MediaService.name, () => {
|
||||
mocks.assetJob.getForGenerateThumbnailJob.mockResolvedValue(assetStub.image);
|
||||
const thumbhashBuffer = Buffer.from('a thumbhash', 'utf8');
|
||||
mocks.media.generateThumbhash.mockResolvedValue(thumbhashBuffer);
|
||||
const previewPath = `upload/thumbs/user-id/as/se/asset-id-preview.jpeg`;
|
||||
const thumbnailPath = `upload/thumbs/user-id/as/se/asset-id-thumbnail.${format}`;
|
||||
const previewPath = expect.stringContaining(`upload/thumbs/user-id/as/se/asset-id-preview.jpeg`);
|
||||
const thumbnailPath = expect.stringContaining(`upload/thumbs/user-id/as/se/asset-id-thumbnail.${format}`);
|
||||
|
||||
await sut.handleGenerateThumbnails({ id: assetStub.image.id });
|
||||
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith('upload/thumbs/user-id/as/se');
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith(expect.any(String));
|
||||
expect(mocks.media.decodeImage).toHaveBeenCalledOnce();
|
||||
expect(mocks.media.decodeImage).toHaveBeenCalledWith(assetStub.image.originalPath, {
|
||||
colorspace: Colorspace.Srgb,
|
||||
@@ -658,12 +659,12 @@ describe(MediaService.name, () => {
|
||||
expect(mocks.media.generateThumbnail).toHaveBeenCalledWith(
|
||||
rawBuffer,
|
||||
expect.objectContaining({ processInvalidImages: false }),
|
||||
'upload/thumbs/user-id/as/se/asset-id-preview.jpeg',
|
||||
expect.any(String),
|
||||
);
|
||||
expect(mocks.media.generateThumbnail).toHaveBeenCalledWith(
|
||||
rawBuffer,
|
||||
expect.objectContaining({ processInvalidImages: false }),
|
||||
'upload/thumbs/user-id/as/se/asset-id-thumbnail.webp',
|
||||
expect.any(String),
|
||||
);
|
||||
|
||||
expect(mocks.media.generateThumbhash).toHaveBeenCalledOnce();
|
||||
@@ -704,7 +705,7 @@ describe(MediaService.name, () => {
|
||||
processInvalidImages: false,
|
||||
raw: rawInfo,
|
||||
},
|
||||
'upload/thumbs/user-id/as/se/asset-id-preview.jpeg',
|
||||
expect.any(String),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -734,7 +735,7 @@ describe(MediaService.name, () => {
|
||||
processInvalidImages: false,
|
||||
raw: rawInfo,
|
||||
},
|
||||
'upload/thumbs/user-id/as/se/asset-id-fullsize.webp',
|
||||
expect.any(String),
|
||||
);
|
||||
expect(mocks.media.generateThumbnail).toHaveBeenCalledWith(
|
||||
fullsizeBuffer,
|
||||
@@ -746,7 +747,7 @@ describe(MediaService.name, () => {
|
||||
processInvalidImages: false,
|
||||
raw: rawInfo,
|
||||
},
|
||||
'upload/thumbs/user-id/as/se/asset-id-preview.jpeg',
|
||||
expect.any(String),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -774,7 +775,7 @@ describe(MediaService.name, () => {
|
||||
processInvalidImages: false,
|
||||
raw: rawInfo,
|
||||
},
|
||||
'upload/thumbs/user-id/as/se/asset-id-fullsize.jpeg',
|
||||
expect.any(String),
|
||||
);
|
||||
expect(mocks.media.generateThumbnail).toHaveBeenCalledWith(
|
||||
rawBuffer,
|
||||
@@ -786,7 +787,7 @@ describe(MediaService.name, () => {
|
||||
processInvalidImages: false,
|
||||
raw: rawInfo,
|
||||
},
|
||||
'upload/thumbs/user-id/as/se/asset-id-preview.jpeg',
|
||||
expect.any(String),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -815,7 +816,7 @@ describe(MediaService.name, () => {
|
||||
processInvalidImages: false,
|
||||
raw: rawInfo,
|
||||
},
|
||||
'upload/thumbs/user-id/as/se/asset-id-fullsize.jpeg',
|
||||
expect.any(String),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -838,7 +839,7 @@ describe(MediaService.name, () => {
|
||||
expect(mocks.media.generateThumbnail).not.toHaveBeenCalledWith(
|
||||
expect.anything(),
|
||||
expect.anything(),
|
||||
'upload/thumbs/user-id/as/se/asset-id-fullsize.jpeg',
|
||||
expect.stringContaining('fullsize.jpeg'),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -869,7 +870,7 @@ describe(MediaService.name, () => {
|
||||
processInvalidImages: false,
|
||||
raw: rawInfo,
|
||||
},
|
||||
'upload/thumbs/user-id/as/se/asset-id-fullsize.webp',
|
||||
expect.any(String),
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -911,7 +912,7 @@ describe(MediaService.name, () => {
|
||||
);
|
||||
|
||||
expect(mocks.person.getDataForThumbnailGenerationJob).toHaveBeenCalledWith(personStub.primaryPerson.id);
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith('upload/thumbs/admin_id/pe/rs');
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith(expect.any(String));
|
||||
expect(mocks.media.decodeImage).toHaveBeenCalledWith(personThumbnailStub.newThumbnailMiddle.originalPath, {
|
||||
colorspace: Colorspace.P3,
|
||||
orientation: undefined,
|
||||
@@ -933,12 +934,9 @@ describe(MediaService.name, () => {
|
||||
processInvalidImages: false,
|
||||
size: 250,
|
||||
},
|
||||
'upload/thumbs/admin_id/pe/rs/person-1.jpeg',
|
||||
expect.any(String),
|
||||
);
|
||||
expect(mocks.person.update).toHaveBeenCalledWith({
|
||||
id: 'person-1',
|
||||
thumbnailPath: 'upload/thumbs/admin_id/pe/rs/person-1.jpeg',
|
||||
});
|
||||
expect(mocks.person.update).toHaveBeenCalledWith({ id: 'person-1', thumbnailPath: expect.any(String) });
|
||||
});
|
||||
|
||||
it('should use preview path if video', async () => {
|
||||
@@ -953,7 +951,7 @@ describe(MediaService.name, () => {
|
||||
);
|
||||
|
||||
expect(mocks.person.getDataForThumbnailGenerationJob).toHaveBeenCalledWith(personStub.primaryPerson.id);
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith('upload/thumbs/admin_id/pe/rs');
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith(expect.any(String));
|
||||
expect(mocks.media.decodeImage).toHaveBeenCalledWith(personThumbnailStub.newThumbnailMiddle.previewPath, {
|
||||
colorspace: Colorspace.P3,
|
||||
orientation: undefined,
|
||||
@@ -975,12 +973,9 @@ describe(MediaService.name, () => {
|
||||
processInvalidImages: false,
|
||||
size: 250,
|
||||
},
|
||||
'upload/thumbs/admin_id/pe/rs/person-1.jpeg',
|
||||
expect.any(String),
|
||||
);
|
||||
expect(mocks.person.update).toHaveBeenCalledWith({
|
||||
id: 'person-1',
|
||||
thumbnailPath: 'upload/thumbs/admin_id/pe/rs/person-1.jpeg',
|
||||
});
|
||||
expect(mocks.person.update).toHaveBeenCalledWith({ id: 'person-1', thumbnailPath: expect.any(String) });
|
||||
});
|
||||
|
||||
it('should generate a thumbnail without going negative', async () => {
|
||||
@@ -1015,7 +1010,7 @@ describe(MediaService.name, () => {
|
||||
processInvalidImages: false,
|
||||
size: 250,
|
||||
},
|
||||
'upload/thumbs/admin_id/pe/rs/person-1.jpeg',
|
||||
expect.any(String),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1052,7 +1047,7 @@ describe(MediaService.name, () => {
|
||||
processInvalidImages: false,
|
||||
size: 250,
|
||||
},
|
||||
'upload/thumbs/admin_id/pe/rs/person-1.jpeg',
|
||||
expect.any(String),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1089,7 +1084,7 @@ describe(MediaService.name, () => {
|
||||
processInvalidImages: false,
|
||||
size: 250,
|
||||
},
|
||||
'upload/thumbs/admin_id/pe/rs/person-1.jpeg',
|
||||
expect.any(String),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1126,7 +1121,7 @@ describe(MediaService.name, () => {
|
||||
processInvalidImages: false,
|
||||
size: 250,
|
||||
},
|
||||
'upload/thumbs/admin_id/pe/rs/person-1.jpeg',
|
||||
expect.any(String),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1168,7 +1163,7 @@ describe(MediaService.name, () => {
|
||||
processInvalidImages: false,
|
||||
size: 250,
|
||||
},
|
||||
'upload/thumbs/admin_id/pe/rs/person-1.jpeg',
|
||||
expect.any(String),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1288,7 +1283,7 @@ describe(MediaService.name, () => {
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalled();
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-map 0:1', '-map 0:3']),
|
||||
@@ -1308,7 +1303,7 @@ describe(MediaService.name, () => {
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalled();
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-map 0:0', '-map 0:2']),
|
||||
@@ -1354,7 +1349,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.any(Array),
|
||||
@@ -1369,7 +1364,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.any(Array),
|
||||
@@ -1384,7 +1379,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.any(Array),
|
||||
@@ -1399,7 +1394,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.any(Array),
|
||||
@@ -1416,7 +1411,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.not.arrayContaining([expect.stringContaining('scale')]),
|
||||
@@ -1431,7 +1426,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining([expect.stringMatching(/scale(_.+)?=-2:720/)]),
|
||||
@@ -1446,7 +1441,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining([expect.stringMatching(/scale(_.+)?=720:-2/)]),
|
||||
@@ -1463,7 +1458,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining([expect.stringMatching(/scale(_.+)?=-2:354/)]),
|
||||
@@ -1480,7 +1475,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining([expect.stringMatching(/scale(_.+)?=354:-2/)]),
|
||||
@@ -1497,7 +1492,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-c:v copy', '-c:a aac']),
|
||||
@@ -1518,7 +1513,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.not.arrayContaining(['-tag:v hvc1']),
|
||||
@@ -1539,7 +1534,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-c:v copy', '-tag:v hvc1']),
|
||||
@@ -1554,7 +1549,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-c:v h264', '-c:a copy']),
|
||||
@@ -1568,7 +1563,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-c:v copy', '-c:a copy']),
|
||||
@@ -1627,7 +1622,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-c:v h264', '-maxrate 4500k', '-bufsize 9000k']),
|
||||
@@ -1642,7 +1637,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-c:v h264', '-maxrate 4500k', '-bufsize 9000k']),
|
||||
@@ -1657,7 +1652,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-c:v h264', '-b:v 3104k', '-minrate 1552k', '-maxrate 4500k']),
|
||||
@@ -1672,7 +1667,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-c:v h264', '-c:a copy']),
|
||||
@@ -1693,7 +1688,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-b:v 3104k', '-minrate 1552k', '-maxrate 4500k']),
|
||||
@@ -1714,7 +1709,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.not.arrayContaining([expect.stringContaining('-maxrate')]),
|
||||
@@ -1729,7 +1724,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-cpu-used 2']),
|
||||
@@ -1744,7 +1739,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.not.arrayContaining([expect.stringContaining('-cpu-used')]),
|
||||
@@ -1759,7 +1754,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-threads 2']),
|
||||
@@ -1774,7 +1769,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-threads 1', '-x264-params frame-threads=1:pools=none']),
|
||||
@@ -1789,7 +1784,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.not.arrayContaining([expect.stringContaining('-threads')]),
|
||||
@@ -1804,7 +1799,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-c:v hevc', '-threads 1', '-x265-params frame-threads=1:pools=none']),
|
||||
@@ -1819,7 +1814,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.not.arrayContaining([expect.stringContaining('-threads')]),
|
||||
@@ -1834,7 +1829,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining([
|
||||
@@ -1859,7 +1854,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-preset 4']),
|
||||
@@ -1874,7 +1869,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-svtav1-params mbr=2M']),
|
||||
@@ -1889,7 +1884,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-svtav1-params lp=4']),
|
||||
@@ -1906,7 +1901,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-svtav1-params lp=4:mbr=2M']),
|
||||
@@ -1950,7 +1945,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining(['-init_hw_device cuda=cuda:0', '-filter_hw_device cuda']),
|
||||
outputOptions: expect.arrayContaining([
|
||||
@@ -1987,7 +1982,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining(['-init_hw_device cuda=cuda:0', '-filter_hw_device cuda']),
|
||||
outputOptions: expect.arrayContaining([expect.stringContaining('-multipass')]),
|
||||
@@ -2004,7 +1999,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining(['-init_hw_device cuda=cuda:0', '-filter_hw_device cuda']),
|
||||
outputOptions: expect.arrayContaining(['-cq:v 23', '-maxrate 10000k', '-bufsize 6897k']),
|
||||
@@ -2021,7 +2016,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining(['-init_hw_device cuda=cuda:0', '-filter_hw_device cuda']),
|
||||
outputOptions: expect.not.stringContaining('-maxrate'),
|
||||
@@ -2038,7 +2033,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining(['-init_hw_device cuda=cuda:0', '-filter_hw_device cuda']),
|
||||
outputOptions: expect.not.arrayContaining([expect.stringContaining('-preset')]),
|
||||
@@ -2053,7 +2048,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining(['-init_hw_device cuda=cuda:0', '-filter_hw_device cuda']),
|
||||
outputOptions: expect.not.arrayContaining([expect.stringContaining('-multipass')]),
|
||||
@@ -2070,7 +2065,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining([
|
||||
'-hwaccel cuda',
|
||||
@@ -2092,7 +2087,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining(['-hwaccel cuda', '-hwaccel_output_format cuda']),
|
||||
outputOptions: expect.arrayContaining([
|
||||
@@ -2113,7 +2108,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining(['-hwaccel cuda', '-hwaccel_output_format cuda']),
|
||||
outputOptions: expect.arrayContaining([expect.stringContaining('scale_cuda=-2:720:format=nv12')]),
|
||||
@@ -2130,7 +2125,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining([
|
||||
'-init_hw_device qsv=hw,child_device=/dev/dri/renderD128',
|
||||
@@ -2170,7 +2165,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining([
|
||||
'-init_hw_device qsv=hw,child_device=/dev/dri/renderD128',
|
||||
@@ -2190,7 +2185,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining([
|
||||
'-init_hw_device qsv=hw,child_device=/dev/dri/renderD128',
|
||||
@@ -2210,7 +2205,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining([
|
||||
'-init_hw_device qsv=hw,child_device=/dev/dri/renderD128',
|
||||
@@ -2239,7 +2234,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining([
|
||||
'-init_hw_device qsv=hw,child_device=/dev/dri/renderD129',
|
||||
@@ -2261,7 +2256,7 @@ describe(MediaService.name, () => {
|
||||
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining([
|
||||
'-hwaccel qsv',
|
||||
@@ -2287,7 +2282,7 @@ describe(MediaService.name, () => {
|
||||
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining([
|
||||
'-hwaccel qsv',
|
||||
@@ -2315,7 +2310,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining(['-hwaccel qsv', '-qsv_device /dev/dri/renderD129']),
|
||||
outputOptions: expect.any(Array),
|
||||
@@ -2334,7 +2329,7 @@ describe(MediaService.name, () => {
|
||||
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining([
|
||||
'-hwaccel qsv',
|
||||
@@ -2354,7 +2349,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining([
|
||||
'-init_hw_device vaapi=accel:/dev/dri/renderD128',
|
||||
@@ -2386,7 +2381,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining([
|
||||
'-init_hw_device vaapi=accel:/dev/dri/renderD128',
|
||||
@@ -2410,7 +2405,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining([
|
||||
'-init_hw_device vaapi=accel:/dev/dri/renderD128',
|
||||
@@ -2436,7 +2431,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining([
|
||||
'-init_hw_device vaapi=accel:/dev/dri/renderD128',
|
||||
@@ -2455,7 +2450,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining([
|
||||
'-init_hw_device vaapi=accel:/dev/dri/renderD129',
|
||||
@@ -2476,7 +2471,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining([
|
||||
'-init_hw_device vaapi=accel:/dev/dri/renderD128',
|
||||
@@ -2498,7 +2493,7 @@ describe(MediaService.name, () => {
|
||||
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining([
|
||||
'-hwaccel vaapi',
|
||||
@@ -2523,7 +2518,7 @@ describe(MediaService.name, () => {
|
||||
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining(['-hwaccel vaapi', '-hwaccel_output_format vaapi', '-threads 1']),
|
||||
outputOptions: expect.arrayContaining([
|
||||
@@ -2546,7 +2541,7 @@ describe(MediaService.name, () => {
|
||||
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining(['-hwaccel vaapi', '-hwaccel_output_format vaapi', '-threads 1']),
|
||||
outputOptions: expect.arrayContaining([expect.stringContaining('format=nv12')]),
|
||||
@@ -2565,7 +2560,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining(['-hwaccel vaapi', '-hwaccel_device /dev/dri/renderD129']),
|
||||
outputOptions: expect.any(Array),
|
||||
@@ -2584,7 +2579,7 @@ describe(MediaService.name, () => {
|
||||
expect(mocks.media.transcode).toHaveBeenCalledTimes(2);
|
||||
expect(mocks.media.transcode).toHaveBeenLastCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining([
|
||||
'-init_hw_device vaapi=accel:/dev/dri/renderD128',
|
||||
@@ -2607,7 +2602,7 @@ describe(MediaService.name, () => {
|
||||
expect(mocks.media.transcode).toHaveBeenCalledTimes(3);
|
||||
expect(mocks.media.transcode).toHaveBeenLastCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-c:v h264']),
|
||||
@@ -2624,7 +2619,7 @@ describe(MediaService.name, () => {
|
||||
expect(mocks.media.transcode).toHaveBeenCalledTimes(2);
|
||||
expect(mocks.media.transcode).toHaveBeenLastCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-c:v h264']),
|
||||
@@ -2649,7 +2644,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining([
|
||||
'-hwaccel rkmpp',
|
||||
@@ -2689,7 +2684,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining(['-hwaccel rkmpp', '-hwaccel_output_format drm_prime', '-afbc rga']),
|
||||
outputOptions: expect.arrayContaining([`-c:v hevc_rkmpp`, '-level 153', '-rc_mode AVBR', '-b:v 10000k']),
|
||||
@@ -2706,7 +2701,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining(['-hwaccel rkmpp', '-hwaccel_output_format drm_prime', '-afbc rga']),
|
||||
outputOptions: expect.arrayContaining([`-c:v h264_rkmpp`, '-level 51', '-rc_mode CQP', '-qp_init 30']),
|
||||
@@ -2723,7 +2718,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining(['-hwaccel rkmpp', '-hwaccel_output_format drm_prime', '-afbc rga']),
|
||||
outputOptions: expect.arrayContaining([
|
||||
@@ -2745,7 +2740,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.arrayContaining(['-hwaccel rkmpp', '-hwaccel_output_format drm_prime', '-afbc rga']),
|
||||
outputOptions: expect.arrayContaining([
|
||||
@@ -2764,7 +2759,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: [],
|
||||
outputOptions: expect.arrayContaining([
|
||||
@@ -2786,7 +2781,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining([
|
||||
@@ -2805,7 +2800,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining([
|
||||
@@ -2824,7 +2819,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining([
|
||||
@@ -2843,7 +2838,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-c:v h264', '-c:a copy', '-vf format=yuv420p']),
|
||||
@@ -2858,7 +2853,7 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-c:v h264', '-c:a copy', '-vf scale=-2:720,format=yuv420p']),
|
||||
@@ -2874,19 +2869,15 @@ describe(MediaService.name, () => {
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
|
||||
expect(mocks.media.probe).toHaveBeenCalledWith(assetStub.video.originalPath, { countFrames: true });
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
assetStub.video.originalPath,
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
{
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.any(Array),
|
||||
twoPass: false,
|
||||
progress: {
|
||||
frameCount: probeStub.videoStream2160p.videoStreams[0].frameCount,
|
||||
percentInterval: expect.any(Number),
|
||||
},
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(assetStub.video.originalPath, expect.any(String), {
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.any(Array),
|
||||
twoPass: false,
|
||||
progress: {
|
||||
frameCount: probeStub.videoStream2160p.videoStreams[0].frameCount,
|
||||
percentInterval: expect.any(Number),
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should not count frames for progress when log level is not debug', async () => {
|
||||
@@ -2904,7 +2895,7 @@ describe(MediaService.name, () => {
|
||||
|
||||
expect(mocks.media.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
APP_MEDIA_LOCATION + '/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
expect.objectContaining({
|
||||
inputOptions: expect.any(Array),
|
||||
outputOptions: expect.arrayContaining(['-c:a copy']),
|
||||
|
||||
@@ -587,7 +587,7 @@ describe(MetadataService.name, () => {
|
||||
libraryId: assetStub.livePhotoWithOriginalFileName.libraryId,
|
||||
localDateTime: assetStub.livePhotoWithOriginalFileName.fileCreatedAt,
|
||||
originalFileName: 'asset_1.mp4',
|
||||
originalPath: 'upload/encoded-video/user-id/li/ve/live-photo-motion-asset-MP.mp4',
|
||||
originalPath: expect.stringContaining('upload/encoded-video/user-id/li/ve/live-photo-motion-asset-MP.mp4'),
|
||||
ownerId: assetStub.livePhotoWithOriginalFileName.ownerId,
|
||||
type: AssetType.Video,
|
||||
});
|
||||
@@ -645,7 +645,7 @@ describe(MetadataService.name, () => {
|
||||
libraryId: assetStub.livePhotoWithOriginalFileName.libraryId,
|
||||
localDateTime: assetStub.livePhotoWithOriginalFileName.fileCreatedAt,
|
||||
originalFileName: 'asset_1.mp4',
|
||||
originalPath: 'upload/encoded-video/user-id/li/ve/live-photo-motion-asset-MP.mp4',
|
||||
originalPath: expect.stringContaining('upload/encoded-video/user-id/li/ve/live-photo-motion-asset-MP.mp4'),
|
||||
ownerId: assetStub.livePhotoWithOriginalFileName.ownerId,
|
||||
type: AssetType.Video,
|
||||
});
|
||||
@@ -703,7 +703,7 @@ describe(MetadataService.name, () => {
|
||||
libraryId: assetStub.livePhotoWithOriginalFileName.libraryId,
|
||||
localDateTime: assetStub.livePhotoWithOriginalFileName.fileCreatedAt,
|
||||
originalFileName: 'asset_1.mp4',
|
||||
originalPath: 'upload/encoded-video/user-id/li/ve/live-photo-motion-asset-MP.mp4',
|
||||
originalPath: expect.stringContaining('upload/encoded-video/user-id/li/ve/live-photo-motion-asset-MP.mp4'),
|
||||
ownerId: assetStub.livePhotoWithOriginalFileName.ownerId,
|
||||
type: AssetType.Video,
|
||||
});
|
||||
|
||||
@@ -28,7 +28,7 @@ describe(ServerService.name, () => {
|
||||
diskUseRaw: 300,
|
||||
});
|
||||
|
||||
expect(mocks.storage.checkDiskUsage).toHaveBeenCalledWith('upload/library');
|
||||
expect(mocks.storage.checkDiskUsage).toHaveBeenCalledWith(expect.stringContaining('upload/library'));
|
||||
});
|
||||
|
||||
it('should return the disk space as KiB', async () => {
|
||||
@@ -44,7 +44,7 @@ describe(ServerService.name, () => {
|
||||
diskUseRaw: 300_000,
|
||||
});
|
||||
|
||||
expect(mocks.storage.checkDiskUsage).toHaveBeenCalledWith('upload/library');
|
||||
expect(mocks.storage.checkDiskUsage).toHaveBeenCalledWith(expect.stringContaining('upload/library'));
|
||||
});
|
||||
|
||||
it('should return the disk space as MiB', async () => {
|
||||
@@ -60,7 +60,7 @@ describe(ServerService.name, () => {
|
||||
diskUseRaw: 300_000_000,
|
||||
});
|
||||
|
||||
expect(mocks.storage.checkDiskUsage).toHaveBeenCalledWith('upload/library');
|
||||
expect(mocks.storage.checkDiskUsage).toHaveBeenCalledWith(expect.stringContaining('upload/library'));
|
||||
});
|
||||
|
||||
it('should return the disk space as GiB', async () => {
|
||||
@@ -80,7 +80,7 @@ describe(ServerService.name, () => {
|
||||
diskUseRaw: 300_000_000_000,
|
||||
});
|
||||
|
||||
expect(mocks.storage.checkDiskUsage).toHaveBeenCalledWith('upload/library');
|
||||
expect(mocks.storage.checkDiskUsage).toHaveBeenCalledWith(expect.stringContaining('upload/library'));
|
||||
});
|
||||
|
||||
it('should return the disk space as TiB', async () => {
|
||||
@@ -100,7 +100,7 @@ describe(ServerService.name, () => {
|
||||
diskUseRaw: 300_000_000_000_000,
|
||||
});
|
||||
|
||||
expect(mocks.storage.checkDiskUsage).toHaveBeenCalledWith('upload/library');
|
||||
expect(mocks.storage.checkDiskUsage).toHaveBeenCalledWith(expect.stringContaining('upload/library'));
|
||||
});
|
||||
|
||||
it('should return the disk space as PiB', async () => {
|
||||
@@ -120,7 +120,7 @@ describe(ServerService.name, () => {
|
||||
diskUseRaw: 300_000_000_000_000_000,
|
||||
});
|
||||
|
||||
expect(mocks.storage.checkDiskUsage).toHaveBeenCalledWith('upload/library');
|
||||
expect(mocks.storage.checkDiskUsage).toHaveBeenCalledWith(expect.stringContaining('upload/library'));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Stats } from 'node:fs';
|
||||
import { defaults, SystemConfig } from 'src/config';
|
||||
import { APP_MEDIA_LOCATION } from 'src/constants';
|
||||
import { AssetPathType, JobStatus } from 'src/enum';
|
||||
import { StorageTemplateService } from 'src/services/storage-template.service';
|
||||
import { albumStub } from 'test/fixtures/album.stub';
|
||||
@@ -110,8 +111,10 @@ describe(StorageTemplateService.name, () => {
|
||||
|
||||
it('should migrate single moving picture', async () => {
|
||||
mocks.user.get.mockResolvedValue(userStub.user1);
|
||||
const newMotionPicturePath = `upload/library/${motionAsset.ownerId}/2022/2022-06-19/${motionAsset.originalFileName}`;
|
||||
const newStillPicturePath = `upload/library/${stillAsset.ownerId}/2022/2022-06-19/${stillAsset.originalFileName}`;
|
||||
const newMotionPicturePath =
|
||||
APP_MEDIA_LOCATION + `/library/${motionAsset.ownerId}/2022/2022-06-19/${motionAsset.originalFileName}`;
|
||||
const newStillPicturePath =
|
||||
APP_MEDIA_LOCATION + `/library/${stillAsset.ownerId}/2022/2022-06-19/${stillAsset.originalFileName}`;
|
||||
|
||||
mocks.assetJob.getForStorageTemplateJob.mockResolvedValueOnce(stillAsset);
|
||||
mocks.assetJob.getForStorageTemplateJob.mockResolvedValueOnce(motionAsset);
|
||||
@@ -156,7 +159,9 @@ describe(StorageTemplateService.name, () => {
|
||||
|
||||
expect(mocks.move.create).toHaveBeenCalledWith({
|
||||
entityId: asset.id,
|
||||
newPath: `upload/library/${user.id}/${asset.fileCreatedAt.getFullYear()}/${album.albumName}/${asset.originalFileName}`,
|
||||
newPath: expect.stringContaining(
|
||||
`upload/library/${user.id}/${asset.fileCreatedAt.getFullYear()}/${album.albumName}/${asset.originalFileName}`,
|
||||
),
|
||||
oldPath: asset.originalPath,
|
||||
pathType: AssetPathType.Original,
|
||||
});
|
||||
@@ -177,7 +182,9 @@ describe(StorageTemplateService.name, () => {
|
||||
const month = (asset.fileCreatedAt.getMonth() + 1).toString().padStart(2, '0');
|
||||
expect(mocks.move.create).toHaveBeenCalledWith({
|
||||
entityId: asset.id,
|
||||
newPath: `upload/library/${user.id}/${asset.fileCreatedAt.getFullYear()}/other/${month}/${asset.originalFileName}`,
|
||||
newPath: expect.stringContaining(
|
||||
`upload/library/${user.id}/${asset.fileCreatedAt.getFullYear()}/other/${month}/${asset.originalFileName}`,
|
||||
),
|
||||
oldPath: asset.originalPath,
|
||||
pathType: AssetPathType.Original,
|
||||
});
|
||||
@@ -211,7 +218,9 @@ describe(StorageTemplateService.name, () => {
|
||||
const month = (asset.fileCreatedAt.getMonth() + 1).toString().padStart(2, '0');
|
||||
expect(mocks.move.create).toHaveBeenCalledWith({
|
||||
entityId: asset.id,
|
||||
newPath: `upload/library/${user.id}/${asset.fileCreatedAt.getFullYear()}/${month} - ${album.albumName}/${asset.originalFileName}`,
|
||||
newPath: expect.stringContaining(
|
||||
`upload/library/${user.id}/${asset.fileCreatedAt.getFullYear()}/${month} - ${album.albumName}/${asset.originalFileName}`,
|
||||
),
|
||||
oldPath: asset.originalPath,
|
||||
pathType: AssetPathType.Original,
|
||||
});
|
||||
@@ -234,7 +243,9 @@ describe(StorageTemplateService.name, () => {
|
||||
const month = (asset.fileCreatedAt.getMonth() + 1).toString().padStart(2, '0');
|
||||
expect(mocks.move.create).toHaveBeenCalledWith({
|
||||
entityId: asset.id,
|
||||
newPath: `upload/library/${user.id}/${asset.fileCreatedAt.getFullYear()}/${month}/${asset.originalFileName}`,
|
||||
newPath:
|
||||
APP_MEDIA_LOCATION +
|
||||
`/library/${user.id}/${asset.fileCreatedAt.getFullYear()}/${month}/${asset.originalFileName}`,
|
||||
oldPath: asset.originalPath,
|
||||
pathType: AssetPathType.Original,
|
||||
});
|
||||
@@ -244,8 +255,9 @@ describe(StorageTemplateService.name, () => {
|
||||
mocks.user.get.mockResolvedValue(userStub.user1);
|
||||
|
||||
const asset = assetStub.storageAsset();
|
||||
const previousFailedNewPath = `upload/library/${userStub.user1.id}/2023/Feb/${asset.originalFileName}`;
|
||||
const newPath = `upload/library/${userStub.user1.id}/2022/2022-06-19/${asset.originalFileName}`;
|
||||
const previousFailedNewPath =
|
||||
APP_MEDIA_LOCATION + `/library/${userStub.user1.id}/2023/Feb/${asset.originalFileName}`;
|
||||
const newPath = APP_MEDIA_LOCATION + `/library/${userStub.user1.id}/2022/2022-06-19/${asset.originalFileName}`;
|
||||
|
||||
mocks.storage.checkFileExists.mockImplementation((path) => Promise.resolve(path === asset.originalPath));
|
||||
mocks.move.getByEntity.mockResolvedValue({
|
||||
@@ -284,8 +296,9 @@ describe(StorageTemplateService.name, () => {
|
||||
mocks.user.get.mockResolvedValue(userStub.user1);
|
||||
|
||||
const asset = assetStub.storageAsset({ fileSizeInByte: 5000 });
|
||||
const previousFailedNewPath = `upload/library/${asset.ownerId}/2022/June/${asset.originalFileName}`;
|
||||
const newPath = `upload/library/${asset.ownerId}/2022/2022-06-19/${asset.originalFileName}`;
|
||||
const previousFailedNewPath =
|
||||
APP_MEDIA_LOCATION + `/library/${asset.ownerId}/2022/June/${asset.originalFileName}`;
|
||||
const newPath = APP_MEDIA_LOCATION + `/library/${asset.ownerId}/2022/2022-06-19/${asset.originalFileName}`;
|
||||
|
||||
mocks.storage.checkFileExists.mockImplementation((path) => Promise.resolve(path === previousFailedNewPath));
|
||||
mocks.storage.stat.mockResolvedValue({ size: 5000 } as Stats);
|
||||
@@ -319,7 +332,8 @@ describe(StorageTemplateService.name, () => {
|
||||
|
||||
it('should fail move if copying and hash of asset and the new file do not match', async () => {
|
||||
mocks.user.get.mockResolvedValue(userStub.user1);
|
||||
const newPath = `upload/library/${userStub.user1.id}/2022/2022-06-19/${testAsset.originalFileName}`;
|
||||
const newPath =
|
||||
APP_MEDIA_LOCATION + `/library/${userStub.user1.id}/2022/2022-06-19/${testAsset.originalFileName}`;
|
||||
|
||||
mocks.storage.rename.mockRejectedValue({ code: 'EXDEV' });
|
||||
mocks.storage.stat.mockResolvedValue({ size: 5000 } as Stats);
|
||||
@@ -409,7 +423,7 @@ describe(StorageTemplateService.name, () => {
|
||||
it('should handle an asset with a duplicate destination', async () => {
|
||||
const asset = assetStub.storageAsset();
|
||||
const oldPath = asset.originalPath;
|
||||
const newPath = `upload/library/user-id/2022/2022-06-19/${asset.originalFileName}`;
|
||||
const newPath = APP_MEDIA_LOCATION + `/library/user-id/2022/2022-06-19/${asset.originalFileName}`;
|
||||
const newPath2 = newPath.replace('.jpg', '+1.jpg');
|
||||
|
||||
mocks.assetJob.streamForStorageTemplateJob.mockReturnValue(makeStream([asset]));
|
||||
@@ -466,7 +480,7 @@ describe(StorageTemplateService.name, () => {
|
||||
it('should move an asset', async () => {
|
||||
const asset = assetStub.storageAsset();
|
||||
const oldPath = asset.originalPath;
|
||||
const newPath = `upload/library/user-id/2022/2022-06-19/${asset.originalFileName}`;
|
||||
const newPath = APP_MEDIA_LOCATION + `/library/user-id/2022/2022-06-19/${asset.originalFileName}`;
|
||||
mocks.assetJob.streamForStorageTemplateJob.mockReturnValue(makeStream([asset]));
|
||||
mocks.user.getList.mockResolvedValue([userStub.user1]);
|
||||
mocks.move.create.mockResolvedValue({
|
||||
@@ -502,18 +516,20 @@ describe(StorageTemplateService.name, () => {
|
||||
expect(mocks.assetJob.streamForStorageTemplateJob).toHaveBeenCalled();
|
||||
expect(mocks.storage.rename).toHaveBeenCalledWith(
|
||||
'/original/path.jpg',
|
||||
`upload/library/${user.storageLabel}/2022/2022-06-19/${asset.originalFileName}`,
|
||||
expect.stringContaining(`upload/library/${user.storageLabel}/2022/2022-06-19/${asset.originalFileName}`),
|
||||
);
|
||||
expect(mocks.asset.update).toHaveBeenCalledWith({
|
||||
id: asset.id,
|
||||
originalPath: `upload/library/${user.storageLabel}/2022/2022-06-19/${asset.originalFileName}`,
|
||||
originalPath: expect.stringContaining(
|
||||
`upload/library/${user.storageLabel}/2022/2022-06-19/${asset.originalFileName}`,
|
||||
),
|
||||
});
|
||||
});
|
||||
|
||||
it('should copy the file if rename fails due to EXDEV (rename across filesystems)', async () => {
|
||||
const asset = assetStub.storageAsset({ originalPath: '/path/to/original.jpg', fileSizeInByte: 5000 });
|
||||
const oldPath = asset.originalPath;
|
||||
const newPath = `upload/library/user-id/2022/2022-06-19/${asset.originalFileName}`;
|
||||
const newPath = APP_MEDIA_LOCATION + `/library/user-id/2022/2022-06-19/${asset.originalFileName}`;
|
||||
mocks.assetJob.streamForStorageTemplateJob.mockReturnValue(makeStream([asset]));
|
||||
mocks.storage.rename.mockRejectedValue({ code: 'EXDEV' });
|
||||
mocks.user.getList.mockResolvedValue([userStub.user1]);
|
||||
@@ -572,14 +588,14 @@ describe(StorageTemplateService.name, () => {
|
||||
expect(mocks.assetJob.streamForStorageTemplateJob).toHaveBeenCalled();
|
||||
expect(mocks.storage.rename).toHaveBeenCalledWith(
|
||||
'/original/path.jpg',
|
||||
`upload/library/user-id/2022/2022-06-19/${asset.originalFileName}`,
|
||||
expect.stringContaining(`upload/library/user-id/2022/2022-06-19/${asset.originalFileName}`),
|
||||
);
|
||||
expect(mocks.storage.copyFile).toHaveBeenCalledWith(
|
||||
'/original/path.jpg',
|
||||
`upload/library/user-id/2022/2022-06-19/${asset.originalFileName}`,
|
||||
expect.stringContaining(`upload/library/user-id/2022/2022-06-19/${asset.originalFileName}`),
|
||||
);
|
||||
expect(mocks.storage.stat).toHaveBeenCalledWith(
|
||||
`upload/library/user-id/2022/2022-06-19/${asset.originalFileName}`,
|
||||
expect.stringContaining(`upload/library/user-id/2022/2022-06-19/${asset.originalFileName}`),
|
||||
);
|
||||
expect(mocks.asset.update).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -603,7 +619,7 @@ describe(StorageTemplateService.name, () => {
|
||||
expect(mocks.assetJob.streamForStorageTemplateJob).toHaveBeenCalled();
|
||||
expect(mocks.storage.rename).toHaveBeenCalledWith(
|
||||
'/original/path.jpg',
|
||||
`upload/library/user-id/2022/2022-06-19/${asset.originalFileName}`,
|
||||
expect.stringContaining(`upload/library/user-id/2022/2022-06-19/${asset.originalFileName}`),
|
||||
);
|
||||
expect(mocks.asset.update).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -631,8 +647,8 @@ describe(StorageTemplateService.name, () => {
|
||||
|
||||
expect(mocks.assetJob.streamForStorageTemplateJob).toHaveBeenCalled();
|
||||
expect(mocks.storage.rename).toHaveBeenCalledWith(
|
||||
`upload/library/${user.id}/2022/2022-06-19/IMG_7065.heic`,
|
||||
`upload/library/${user.storageLabel}/2022/2022-06-19/IMG_7065.heic`,
|
||||
expect.stringContaining(`upload/library/${user.id}/2022/2022-06-19/IMG_7065.heic`),
|
||||
expect.stringContaining(`upload/library/${user.storageLabel}/2022/2022-06-19/IMG_7065.heic`),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -657,8 +673,8 @@ describe(StorageTemplateService.name, () => {
|
||||
|
||||
expect(mocks.assetJob.streamForStorageTemplateJob).toHaveBeenCalled();
|
||||
expect(mocks.storage.rename).toHaveBeenCalledWith(
|
||||
`upload/library/${user.id}/2022/2022-06-19/IMG_7065.HEIC`,
|
||||
`upload/library/${user.id}/2022/2022-06-19/IMG_7065.heic`,
|
||||
expect.stringContaining(`upload/library/${user.id}/2022/2022-06-19/IMG_7065.HEIC`),
|
||||
expect.stringContaining(`upload/library/${user.id}/2022/2022-06-19/IMG_7065.heic`),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -683,8 +699,8 @@ describe(StorageTemplateService.name, () => {
|
||||
|
||||
expect(mocks.assetJob.streamForStorageTemplateJob).toHaveBeenCalled();
|
||||
expect(mocks.storage.rename).toHaveBeenCalledWith(
|
||||
`upload/library/${user.id}/2022/2022-06-19/IMG_7065.JPEG`,
|
||||
`upload/library/${user.id}/2022/2022-06-19/IMG_7065.jpg`,
|
||||
expect.stringContaining(`upload/library/${user.id}/2022/2022-06-19/IMG_7065.JPEG`),
|
||||
expect.stringContaining(`upload/library/${user.id}/2022/2022-06-19/IMG_7065.jpg`),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -709,8 +725,8 @@ describe(StorageTemplateService.name, () => {
|
||||
|
||||
expect(mocks.assetJob.streamForStorageTemplateJob).toHaveBeenCalled();
|
||||
expect(mocks.storage.rename).toHaveBeenCalledWith(
|
||||
`upload/library/${user.id}/2022/2022-06-19/IMG_7065.JPG`,
|
||||
`upload/library/${user.id}/2022/2022-06-19/IMG_7065.jpg`,
|
||||
expect.stringContaining(`upload/library/${user.id}/2022/2022-06-19/IMG_7065.JPG`),
|
||||
expect.stringContaining(`upload/library/${user.id}/2022/2022-06-19/IMG_7065.jpg`),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -32,18 +32,36 @@ describe(StorageService.name, () => {
|
||||
upload: true,
|
||||
},
|
||||
});
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith('upload/encoded-video');
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith('upload/library');
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith('upload/profile');
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith('upload/thumbs');
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith('upload/upload');
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith('upload/backups');
|
||||
expect(mocks.storage.createFile).toHaveBeenCalledWith('upload/encoded-video/.immich', expect.any(Buffer));
|
||||
expect(mocks.storage.createFile).toHaveBeenCalledWith('upload/library/.immich', expect.any(Buffer));
|
||||
expect(mocks.storage.createFile).toHaveBeenCalledWith('upload/profile/.immich', expect.any(Buffer));
|
||||
expect(mocks.storage.createFile).toHaveBeenCalledWith('upload/thumbs/.immich', expect.any(Buffer));
|
||||
expect(mocks.storage.createFile).toHaveBeenCalledWith('upload/upload/.immich', expect.any(Buffer));
|
||||
expect(mocks.storage.createFile).toHaveBeenCalledWith('upload/backups/.immich', expect.any(Buffer));
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith(expect.stringContaining('upload/encoded-video'));
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith(expect.stringContaining('upload/library'));
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith(expect.stringContaining('upload/profile'));
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith(expect.stringContaining('upload/thumbs'));
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith(expect.stringContaining('upload/upload'));
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith(expect.stringContaining('upload/backups'));
|
||||
expect(mocks.storage.createFile).toHaveBeenCalledWith(
|
||||
expect.stringContaining('upload/encoded-video/.immich'),
|
||||
expect.any(Buffer),
|
||||
);
|
||||
expect(mocks.storage.createFile).toHaveBeenCalledWith(
|
||||
expect.stringContaining('upload/library/.immich'),
|
||||
expect.any(Buffer),
|
||||
);
|
||||
expect(mocks.storage.createFile).toHaveBeenCalledWith(
|
||||
expect.stringContaining('upload/profile/.immich'),
|
||||
expect.any(Buffer),
|
||||
);
|
||||
expect(mocks.storage.createFile).toHaveBeenCalledWith(
|
||||
expect.stringContaining('upload/thumbs/.immich'),
|
||||
expect.any(Buffer),
|
||||
);
|
||||
expect(mocks.storage.createFile).toHaveBeenCalledWith(
|
||||
expect.stringContaining('upload/upload/.immich'),
|
||||
expect.any(Buffer),
|
||||
);
|
||||
expect(mocks.storage.createFile).toHaveBeenCalledWith(
|
||||
expect.stringContaining('upload/backups/.immich'),
|
||||
expect.any(Buffer),
|
||||
);
|
||||
});
|
||||
|
||||
it('should enable mount folder checking for a new folder type', async () => {
|
||||
@@ -71,11 +89,17 @@ describe(StorageService.name, () => {
|
||||
},
|
||||
});
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledTimes(2);
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith('upload/library');
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith('upload/backups');
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith(expect.stringContaining('upload/library'));
|
||||
expect(mocks.storage.mkdirSync).toHaveBeenCalledWith(expect.stringContaining('upload/backups'));
|
||||
expect(mocks.storage.createFile).toHaveBeenCalledTimes(2);
|
||||
expect(mocks.storage.createFile).toHaveBeenCalledWith('upload/library/.immich', expect.any(Buffer));
|
||||
expect(mocks.storage.createFile).toHaveBeenCalledWith('upload/backups/.immich', expect.any(Buffer));
|
||||
expect(mocks.storage.createFile).toHaveBeenCalledWith(
|
||||
expect.stringContaining('upload/library/.immich'),
|
||||
expect.any(Buffer),
|
||||
);
|
||||
expect(mocks.storage.createFile).toHaveBeenCalledWith(
|
||||
expect.stringContaining('upload/backups/.immich'),
|
||||
expect.any(Buffer),
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw an error if .immich is missing', async () => {
|
||||
@@ -131,7 +155,7 @@ describe(StorageService.name, () => {
|
||||
|
||||
await expect(sut.onBootstrap()).resolves.toBeUndefined();
|
||||
|
||||
expect(mocks.systemMetadata.set).not.toHaveBeenCalled();
|
||||
expect(mocks.systemMetadata.set).not.toHaveBeenCalledWith(SystemMetadataKey.SystemFlags, expect.anything());
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { join, resolve } from 'node:path';
|
||||
import { join } from 'node:path';
|
||||
import { APP_MEDIA_LOCATION } from 'src/constants';
|
||||
import { StorageCore } from 'src/cores/storage.core';
|
||||
import { OnEvent, OnJob } from 'src/decorators';
|
||||
import { DatabaseLock, JobName, JobStatus, QueueName, StorageFolder, SystemMetadataKey } from 'src/enum';
|
||||
@@ -60,6 +61,17 @@ export class StorageService extends BaseService {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
await this.databaseRepository.withLock(DatabaseLock.MediaLocation, async () => {
|
||||
const current = APP_MEDIA_LOCATION;
|
||||
const savedValue = await this.systemMetadataRepository.get(SystemMetadataKey.MediaLocation);
|
||||
const previous = savedValue?.location || '';
|
||||
|
||||
if (previous !== current) {
|
||||
this.logger.log(`Media location changed (from=${previous}, to=${current})`);
|
||||
await this.systemMetadataRepository.set(SystemMetadataKey.MediaLocation, { location: current });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@OnJob({ name: JobName.FileDelete, queue: QueueName.BackgroundTask })
|
||||
@@ -87,9 +99,8 @@ export class StorageService extends BaseService {
|
||||
try {
|
||||
await this.storageRepository.readFile(internalPath);
|
||||
} catch (error) {
|
||||
const fullyQualifiedPath = resolve(process.cwd(), internalPath);
|
||||
this.logger.error(`Failed to read ${fullyQualifiedPath} (${internalPath}): ${error}`);
|
||||
throw new ImmichStartupError(`Failed to read: "${externalPath} (${fullyQualifiedPath}) - ${docsMessage}"`);
|
||||
this.logger.error(`Failed to read (${internalPath}): ${error}`);
|
||||
throw new ImmichStartupError(`Failed to read: "${externalPath} (${internalPath}) - ${docsMessage}"`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -235,11 +235,26 @@ describe(UserService.name, () => {
|
||||
|
||||
await sut.handleUserDelete({ id: user.id });
|
||||
|
||||
expect(mocks.storage.unlinkDir).toHaveBeenCalledWith('upload/library/deleted-user', options);
|
||||
expect(mocks.storage.unlinkDir).toHaveBeenCalledWith('upload/upload/deleted-user', options);
|
||||
expect(mocks.storage.unlinkDir).toHaveBeenCalledWith('upload/profile/deleted-user', options);
|
||||
expect(mocks.storage.unlinkDir).toHaveBeenCalledWith('upload/thumbs/deleted-user', options);
|
||||
expect(mocks.storage.unlinkDir).toHaveBeenCalledWith('upload/encoded-video/deleted-user', options);
|
||||
expect(mocks.storage.unlinkDir).toHaveBeenCalledWith(
|
||||
expect.stringContaining('upload/library/deleted-user'),
|
||||
options,
|
||||
);
|
||||
expect(mocks.storage.unlinkDir).toHaveBeenCalledWith(
|
||||
expect.stringContaining('upload/upload/deleted-user'),
|
||||
options,
|
||||
);
|
||||
expect(mocks.storage.unlinkDir).toHaveBeenCalledWith(
|
||||
expect.stringContaining('upload/profile/deleted-user'),
|
||||
options,
|
||||
);
|
||||
expect(mocks.storage.unlinkDir).toHaveBeenCalledWith(
|
||||
expect.stringContaining('upload/thumbs/deleted-user'),
|
||||
options,
|
||||
);
|
||||
expect(mocks.storage.unlinkDir).toHaveBeenCalledWith(
|
||||
expect.stringContaining('upload/encoded-video/deleted-user'),
|
||||
options,
|
||||
);
|
||||
expect(mocks.album.deleteAll).toHaveBeenCalledWith(user.id);
|
||||
expect(mocks.user.delete).toHaveBeenCalledWith(user, true);
|
||||
});
|
||||
@@ -253,7 +268,7 @@ describe(UserService.name, () => {
|
||||
|
||||
const options = { force: true, recursive: true };
|
||||
|
||||
expect(mocks.storage.unlinkDir).toHaveBeenCalledWith('upload/library/admin', options);
|
||||
expect(mocks.storage.unlinkDir).toHaveBeenCalledWith(expect.stringContaining('upload/library/admin'), options);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user