mirror of
https://github.com/immich-app/immich.git
synced 2025-06-04 14:14:23 -04:00
fix(server): double extension when filename has uppercase extension (#17226)
* fix(server): double extension when filename has uppercase extension * Proper tests
This commit is contained in:
parent
b25914c2a5
commit
b8b2898c87
@ -548,4 +548,102 @@ describe(StorageTemplateService.name, () => {
|
|||||||
expect(mocks.asset.update).not.toHaveBeenCalled();
|
expect(mocks.asset.update).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('file rename correctness', () => {
|
||||||
|
it('should not create double extensions when filename has lower extension', async () => {
|
||||||
|
const asset = assetStub.storageAsset({
|
||||||
|
originalPath: 'upload/library/user-id/2022/2022-06-19/IMG_7065.heic',
|
||||||
|
originalFileName: 'IMG_7065.HEIC',
|
||||||
|
});
|
||||||
|
mocks.asset.streamStorageTemplateAssets.mockReturnValue(makeStream([asset]));
|
||||||
|
mocks.user.getList.mockResolvedValue([userStub.storageLabel]);
|
||||||
|
mocks.move.create.mockResolvedValue({
|
||||||
|
id: '123',
|
||||||
|
entityId: asset.id,
|
||||||
|
pathType: AssetPathType.ORIGINAL,
|
||||||
|
oldPath: 'upload/library/user-id/2022/2022-06-19/IMG_7065.heic',
|
||||||
|
newPath: 'upload/library/user-id/2023/2023-02-23/IMG_7065.heic',
|
||||||
|
});
|
||||||
|
|
||||||
|
await sut.handleMigration();
|
||||||
|
|
||||||
|
expect(mocks.asset.streamStorageTemplateAssets).toHaveBeenCalled();
|
||||||
|
expect(mocks.storage.rename).toHaveBeenCalledWith(
|
||||||
|
'upload/library/user-id/2022/2022-06-19/IMG_7065.heic',
|
||||||
|
'upload/library/label-1/2022/2022-06-19/IMG_7065.heic',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not create double extensions when filename has uppercase extension', async () => {
|
||||||
|
const asset = assetStub.storageAsset({
|
||||||
|
originalPath: 'upload/library/user-id/2022/2022-06-19/IMG_7065.HEIC',
|
||||||
|
originalFileName: 'IMG_7065.HEIC',
|
||||||
|
});
|
||||||
|
mocks.asset.streamStorageTemplateAssets.mockReturnValue(makeStream([asset]));
|
||||||
|
mocks.user.getList.mockResolvedValue([userStub.storageLabel]);
|
||||||
|
mocks.move.create.mockResolvedValue({
|
||||||
|
id: '123',
|
||||||
|
entityId: asset.id,
|
||||||
|
pathType: AssetPathType.ORIGINAL,
|
||||||
|
oldPath: 'upload/library/user-id/2022/2022-06-19/IMG_7065.HEIC',
|
||||||
|
newPath: 'upload/library/user-id/2023/2023-02-23/IMG_7065.heic',
|
||||||
|
});
|
||||||
|
|
||||||
|
await sut.handleMigration();
|
||||||
|
|
||||||
|
expect(mocks.asset.streamStorageTemplateAssets).toHaveBeenCalled();
|
||||||
|
expect(mocks.storage.rename).toHaveBeenCalledWith(
|
||||||
|
'upload/library/user-id/2022/2022-06-19/IMG_7065.HEIC',
|
||||||
|
'upload/library/label-1/2022/2022-06-19/IMG_7065.heic',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should normalize the filename to lowercase (JPEG > jpg)', async () => {
|
||||||
|
const asset = assetStub.storageAsset({
|
||||||
|
originalPath: 'upload/library/user-id/2022/2022-06-19/IMG_7065.JPEG',
|
||||||
|
originalFileName: 'IMG_7065.JPEG',
|
||||||
|
});
|
||||||
|
mocks.asset.streamStorageTemplateAssets.mockReturnValue(makeStream([asset]));
|
||||||
|
mocks.user.getList.mockResolvedValue([userStub.storageLabel]);
|
||||||
|
mocks.move.create.mockResolvedValue({
|
||||||
|
id: '123',
|
||||||
|
entityId: asset.id,
|
||||||
|
pathType: AssetPathType.ORIGINAL,
|
||||||
|
oldPath: 'upload/library/user-id/2022/2022-06-19/IMG_7065.JPEG',
|
||||||
|
newPath: 'upload/library/user-id/2023/2023-02-23/IMG_7065.jpg',
|
||||||
|
});
|
||||||
|
|
||||||
|
await sut.handleMigration();
|
||||||
|
|
||||||
|
expect(mocks.asset.streamStorageTemplateAssets).toHaveBeenCalled();
|
||||||
|
expect(mocks.storage.rename).toHaveBeenCalledWith(
|
||||||
|
'upload/library/user-id/2022/2022-06-19/IMG_7065.JPEG',
|
||||||
|
'upload/library/label-1/2022/2022-06-19/IMG_7065.jpg',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should normalize the filename to lowercase (JPG > jpg)', async () => {
|
||||||
|
const asset = assetStub.storageAsset({
|
||||||
|
originalPath: 'upload/library/user-id/2022/2022-06-19/IMG_7065.JPG',
|
||||||
|
originalFileName: 'IMG_7065.JPG',
|
||||||
|
});
|
||||||
|
mocks.asset.streamStorageTemplateAssets.mockReturnValue(makeStream([asset]));
|
||||||
|
mocks.user.getList.mockResolvedValue([userStub.storageLabel]);
|
||||||
|
mocks.move.create.mockResolvedValue({
|
||||||
|
id: '123',
|
||||||
|
entityId: asset.id,
|
||||||
|
pathType: AssetPathType.ORIGINAL,
|
||||||
|
oldPath: 'upload/library/user-id/2022/2022-06-19/IMG_7065.JPG',
|
||||||
|
newPath: 'upload/library/user-id/2023/2023-02-23/IMG_7065.jpg',
|
||||||
|
});
|
||||||
|
|
||||||
|
await sut.handleMigration();
|
||||||
|
|
||||||
|
expect(mocks.asset.streamStorageTemplateAssets).toHaveBeenCalled();
|
||||||
|
expect(mocks.storage.rename).toHaveBeenCalledWith(
|
||||||
|
'upload/library/user-id/2022/2022-06-19/IMG_7065.JPG',
|
||||||
|
'upload/library/label-1/2022/2022-06-19/IMG_7065.jpg',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -220,9 +220,11 @@ export class StorageTemplateService extends BaseService {
|
|||||||
const { storageLabel, filename } = metadata;
|
const { storageLabel, filename } = metadata;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const filenameWithoutExtension = path.basename(filename, path.extname(filename));
|
||||||
|
|
||||||
const source = asset.originalPath;
|
const source = asset.originalPath;
|
||||||
let extension = path.extname(source).split('.').pop() as string;
|
let extension = path.extname(source).split('.').pop() as string;
|
||||||
const sanitized = sanitize(path.basename(filename, `.${extension}`));
|
const sanitized = sanitize(path.basename(filenameWithoutExtension, `.${extension}`));
|
||||||
extension = extension?.toLowerCase();
|
extension = extension?.toLowerCase();
|
||||||
const rootPath = StorageCore.getLibraryFolder({ id: asset.ownerId, storageLabel });
|
const rootPath = StorageCore.getLibraryFolder({ id: asset.ownerId, storageLabel });
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user