@@ -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`),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user