mirror of
https://github.com/immich-app/immich.git
synced 2025-05-24 01:12:58 -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();
|
||||
});
|
||||
});
|
||||
|
||||
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;
|
||||
|
||||
try {
|
||||
const filenameWithoutExtension = path.basename(filename, path.extname(filename));
|
||||
|
||||
const source = asset.originalPath;
|
||||
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();
|
||||
const rootPath = StorageCore.getLibraryFolder({ id: asset.ownerId, storageLabel });
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user