Merge branch 'fix/asset-service-argument-order' of https://github.com/immich-app/immich into feat/sidecar-asset-files

This commit is contained in:
Jonathan Jogenfors
2025-10-31 00:50:15 +01:00
2 changed files with 33 additions and 15 deletions
+14 -13
View File
@@ -262,32 +262,33 @@ export class AssetService extends BaseService {
sourceAsset, sourceAsset,
targetAsset, targetAsset,
}: { }: {
sourceAsset: { id: string; files: AssetFile[] | null; originalPath: string }; sourceAsset: { files?: AssetFile[] };
targetAsset: { files: AssetFile[] | null }; targetAsset: { id: string; files?: AssetFile[]; originalPath: string };
}) { }) {
if (!targetAsset.files) { if (!sourceAsset.files) {
return; return;
} }
const targetSidecarFile = getAssetFiles(targetAsset.files).sidecarFile; const sourceSidecarPath = getAssetFiles(sourceAsset.files).sidecarFile?.path;
if (!targetSidecarFile) { if (!sourceSidecarPath) {
return; return;
} }
const sourceSidecarFile = getAssetFiles(sourceAsset.files).sidecarFile; if (targetAsset.files) {
const targetSidecar = getAssetFiles(targetAsset.files).sidecarFile;
if (sourceSidecarFile) { if (targetSidecar) {
await this.storageRepository.unlink(sourceSidecarFile.path); await this.storageRepository.unlink(targetSidecar.path);
}
} }
await this.storageRepository.copyFile(targetSidecarFile.path, `${sourceAsset.originalPath}.xmp`); await this.storageRepository.copyFile(sourceSidecarPath, `${targetAsset.originalPath}.xmp`);
await this.assetRepository.upsertFile({ await this.assetRepository.upsertFile({
assetId: sourceAsset.id, assetId: targetAsset.id,
path: `${targetAsset.originalPath}.xmp`,
type: AssetFileType.Sidecar, type: AssetFileType.Sidecar,
path: `${sourceAsset.originalPath}.xmp`,
}); });
await this.jobRepository.queue({ name: JobName.AssetExtractMetadata, data: { id: sourceAsset.id } }); await this.jobRepository.queue({ name: JobName.AssetExtractMetadata, data: { id: targetAsset.id } });
} }
@OnJob({ name: JobName.AssetDeleteCheck, queue: QueueName.BackgroundTask }) @OnJob({ name: JobName.AssetDeleteCheck, queue: QueueName.BackgroundTask })
@@ -1,5 +1,5 @@
import { Kysely } from 'kysely'; import { Kysely } from 'kysely';
import { JobName, SharedLinkType } from 'src/enum'; import { AssetFileType, JobName, SharedLinkType } from 'src/enum';
import { AccessRepository } from 'src/repositories/access.repository'; import { AccessRepository } from 'src/repositories/access.repository';
import { AlbumRepository } from 'src/repositories/album.repository'; import { AlbumRepository } from 'src/repositories/album.repository';
import { AssetRepository } from 'src/repositories/asset.repository'; import { AssetRepository } from 'src/repositories/asset.repository';
@@ -179,12 +179,23 @@ describe(AssetService.name, () => {
const { sut, ctx } = setup(); const { sut, ctx } = setup();
const storageRepo = ctx.getMock(StorageRepository); const storageRepo = ctx.getMock(StorageRepository);
const jobRepo = ctx.getMock(JobRepository); const jobRepo = ctx.getMock(JobRepository);
const assetRepo = ctx.getMock(AssetRepository);
storageRepo.copyFile.mockResolvedValue(); storageRepo.copyFile.mockResolvedValue();
jobRepo.queue.mockResolvedValue(); jobRepo.queue.mockResolvedValue();
const { user } = await ctx.newUser(); const { user } = await ctx.newUser();
const { asset: oldAsset } = await ctx.newAsset({ ownerId: user.id, sidecarPath: '/path/to/my/sidecar.xmp' });
const { asset: oldAssetWithoutSidecar } = await ctx.newAsset({ ownerId: user.id });
const sidecarFile = await ctx.newAssetFile({
assetId: oldAssetWithoutSidecar.id,
path: '/path/to/my/sidecar.xmp',
type: AssetFileType.Sidecar,
});
const oldAsset = { ...oldAssetWithoutSidecar, files: [sidecarFile] };
const { asset: newAsset } = await ctx.newAsset({ ownerId: user.id }); const { asset: newAsset } = await ctx.newAsset({ ownerId: user.id });
await ctx.newExif({ assetId: oldAsset.id, description: 'foo' }); await ctx.newExif({ assetId: oldAsset.id, description: 'foo' });
@@ -196,6 +207,12 @@ describe(AssetService.name, () => {
expect(storageRepo.copyFile).toHaveBeenCalledWith('/path/to/my/sidecar.xmp', `${newAsset.originalPath}.xmp`); expect(storageRepo.copyFile).toHaveBeenCalledWith('/path/to/my/sidecar.xmp', `${newAsset.originalPath}.xmp`);
expect(assetRepo.upsertFile).toHaveBeenCalledWith({
assetId: newAsset.id,
path: `${newAsset.originalPath}.xmp`,
type: AssetFileType.Sidecar,
});
expect(jobRepo.queue).toHaveBeenCalledWith({ expect(jobRepo.queue).toHaveBeenCalledWith({
name: JobName.AssetExtractMetadata, name: JobName.AssetExtractMetadata,
data: { id: newAsset.id }, data: { id: newAsset.id },