diff --git a/server/src/services/asset.service.ts b/server/src/services/asset.service.ts index 3cece7c581..a77101ce4a 100644 --- a/server/src/services/asset.service.ts +++ b/server/src/services/asset.service.ts @@ -262,32 +262,33 @@ export class AssetService extends BaseService { sourceAsset, targetAsset, }: { - sourceAsset: { id: string; files: AssetFile[] | null; originalPath: string }; - targetAsset: { files: AssetFile[] | null }; + sourceAsset: { files?: AssetFile[] }; + targetAsset: { id: string; files?: AssetFile[]; originalPath: string }; }) { - if (!targetAsset.files) { + if (!sourceAsset.files) { return; } - const targetSidecarFile = getAssetFiles(targetAsset.files).sidecarFile; + const sourceSidecarPath = getAssetFiles(sourceAsset.files).sidecarFile?.path; - if (!targetSidecarFile) { + if (!sourceSidecarPath) { return; } - const sourceSidecarFile = getAssetFiles(sourceAsset.files).sidecarFile; - - if (sourceSidecarFile) { - await this.storageRepository.unlink(sourceSidecarFile.path); + if (targetAsset.files) { + const targetSidecar = getAssetFiles(targetAsset.files).sidecarFile; + if (targetSidecar) { + 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({ - assetId: sourceAsset.id, + assetId: targetAsset.id, + path: `${targetAsset.originalPath}.xmp`, 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 }) diff --git a/server/test/medium/specs/services/asset.service.spec.ts b/server/test/medium/specs/services/asset.service.spec.ts index b3fc481708..2f9950681a 100644 --- a/server/test/medium/specs/services/asset.service.spec.ts +++ b/server/test/medium/specs/services/asset.service.spec.ts @@ -1,5 +1,5 @@ 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 { AlbumRepository } from 'src/repositories/album.repository'; import { AssetRepository } from 'src/repositories/asset.repository'; @@ -179,12 +179,23 @@ describe(AssetService.name, () => { const { sut, ctx } = setup(); const storageRepo = ctx.getMock(StorageRepository); const jobRepo = ctx.getMock(JobRepository); + const assetRepo = ctx.getMock(AssetRepository); storageRepo.copyFile.mockResolvedValue(); jobRepo.queue.mockResolvedValue(); 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 }); 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(assetRepo.upsertFile).toHaveBeenCalledWith({ + assetId: newAsset.id, + path: `${newAsset.originalPath}.xmp`, + type: AssetFileType.Sidecar, + }); + expect(jobRepo.queue).toHaveBeenCalledWith({ name: JobName.AssetExtractMetadata, data: { id: newAsset.id },