mirror of
https://github.com/immich-app/immich.git
synced 2024-12-29 15:11:58 +00:00
chore(server): change save
-> update
in asset repository (#8055)
* `save` -> `update` * change return type * include relations * fix tests * remove when mocks * fix * stricter typing * simpler type
This commit is contained in:
parent
9e4bab7494
commit
2daed747cd
14 changed files with 128 additions and 138 deletions
|
@ -548,19 +548,19 @@ describe(AssetService.name, () => {
|
||||||
await expect(sut.update(authStub.admin, 'asset-1', { isArchived: false })).rejects.toBeInstanceOf(
|
await expect(sut.update(authStub.admin, 'asset-1', { isArchived: false })).rejects.toBeInstanceOf(
|
||||||
BadRequestException,
|
BadRequestException,
|
||||||
);
|
);
|
||||||
expect(assetMock.save).not.toHaveBeenCalled();
|
expect(assetMock.update).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update the asset', async () => {
|
it('should update the asset', async () => {
|
||||||
accessMock.asset.checkOwnerAccess.mockResolvedValue(new Set(['asset-1']));
|
accessMock.asset.checkOwnerAccess.mockResolvedValue(new Set(['asset-1']));
|
||||||
assetMock.save.mockResolvedValue(assetStub.image);
|
assetMock.getById.mockResolvedValue(assetStub.image);
|
||||||
await sut.update(authStub.admin, 'asset-1', { isFavorite: true });
|
await sut.update(authStub.admin, 'asset-1', { isFavorite: true });
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({ id: 'asset-1', isFavorite: true });
|
expect(assetMock.update).toHaveBeenCalledWith({ id: 'asset-1', isFavorite: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update the exif description', async () => {
|
it('should update the exif description', async () => {
|
||||||
accessMock.asset.checkOwnerAccess.mockResolvedValue(new Set(['asset-1']));
|
accessMock.asset.checkOwnerAccess.mockResolvedValue(new Set(['asset-1']));
|
||||||
assetMock.save.mockResolvedValue(assetStub.image);
|
assetMock.getById.mockResolvedValue(assetStub.image);
|
||||||
await sut.update(authStub.admin, 'asset-1', { description: 'Test description' });
|
await sut.update(authStub.admin, 'asset-1', { description: 'Test description' });
|
||||||
expect(assetMock.upsertExif).toHaveBeenCalledWith({ assetId: 'asset-1', description: 'Test description' });
|
expect(assetMock.upsertExif).toHaveBeenCalledWith({ assetId: 'asset-1', description: 'Test description' });
|
||||||
});
|
});
|
||||||
|
|
|
@ -324,7 +324,19 @@ export class AssetService {
|
||||||
const { description, dateTimeOriginal, latitude, longitude, ...rest } = dto;
|
const { description, dateTimeOriginal, latitude, longitude, ...rest } = dto;
|
||||||
await this.updateMetadata({ id, description, dateTimeOriginal, latitude, longitude });
|
await this.updateMetadata({ id, description, dateTimeOriginal, latitude, longitude });
|
||||||
|
|
||||||
const asset = await this.assetRepository.save({ id, ...rest });
|
await this.assetRepository.update({ id, ...rest });
|
||||||
|
const asset = await this.assetRepository.getById(id, {
|
||||||
|
exifInfo: true,
|
||||||
|
owner: true,
|
||||||
|
smartInfo: true,
|
||||||
|
tags: true,
|
||||||
|
faces: {
|
||||||
|
person: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!asset) {
|
||||||
|
throw new BadRequestException('Asset not found');
|
||||||
|
}
|
||||||
return mapAsset(asset, { auth });
|
return mapAsset(asset, { auth });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,27 +93,27 @@ export class AuditService {
|
||||||
|
|
||||||
switch (pathType) {
|
switch (pathType) {
|
||||||
case AssetPathType.ENCODED_VIDEO: {
|
case AssetPathType.ENCODED_VIDEO: {
|
||||||
await this.assetRepository.save({ id, encodedVideoPath: pathValue });
|
await this.assetRepository.update({ id, encodedVideoPath: pathValue });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AssetPathType.JPEG_THUMBNAIL: {
|
case AssetPathType.JPEG_THUMBNAIL: {
|
||||||
await this.assetRepository.save({ id, resizePath: pathValue });
|
await this.assetRepository.update({ id, resizePath: pathValue });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AssetPathType.WEBP_THUMBNAIL: {
|
case AssetPathType.WEBP_THUMBNAIL: {
|
||||||
await this.assetRepository.save({ id, webpPath: pathValue });
|
await this.assetRepository.update({ id, webpPath: pathValue });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AssetPathType.ORIGINAL: {
|
case AssetPathType.ORIGINAL: {
|
||||||
await this.assetRepository.save({ id, originalPath: pathValue });
|
await this.assetRepository.update({ id, originalPath: pathValue });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AssetPathType.SIDECAR: {
|
case AssetPathType.SIDECAR: {
|
||||||
await this.assetRepository.save({ id, sidecarPath: pathValue });
|
await this.assetRepository.update({ id, sidecarPath: pathValue });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -584,7 +584,7 @@ describe(LibraryService.name, () => {
|
||||||
|
|
||||||
await expect(sut.handleAssetRefresh(mockLibraryJob)).resolves.toBe(JobStatus.SUCCESS);
|
await expect(sut.handleAssetRefresh(mockLibraryJob)).resolves.toBe(JobStatus.SUCCESS);
|
||||||
|
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({ id: assetStub.image.id, isOffline: true });
|
expect(assetMock.update).toHaveBeenCalledWith({ id: assetStub.image.id, isOffline: true });
|
||||||
expect(jobMock.queue).not.toHaveBeenCalled();
|
expect(jobMock.queue).not.toHaveBeenCalled();
|
||||||
expect(jobMock.queueAll).not.toHaveBeenCalled();
|
expect(jobMock.queueAll).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
@ -602,7 +602,7 @@ describe(LibraryService.name, () => {
|
||||||
|
|
||||||
await expect(sut.handleAssetRefresh(mockLibraryJob)).resolves.toBe(JobStatus.SUCCESS);
|
await expect(sut.handleAssetRefresh(mockLibraryJob)).resolves.toBe(JobStatus.SUCCESS);
|
||||||
|
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({ id: assetStub.offline.id, isOffline: false });
|
expect(assetMock.update).toHaveBeenCalledWith({ id: assetStub.offline.id, isOffline: false });
|
||||||
|
|
||||||
expect(jobMock.queue).toHaveBeenCalledWith({
|
expect(jobMock.queue).toHaveBeenCalledWith({
|
||||||
name: JobName.METADATA_EXTRACTION,
|
name: JobName.METADATA_EXTRACTION,
|
||||||
|
@ -631,7 +631,7 @@ describe(LibraryService.name, () => {
|
||||||
assetMock.getByLibraryIdAndOriginalPath.mockResolvedValue(assetStub.image);
|
assetMock.getByLibraryIdAndOriginalPath.mockResolvedValue(assetStub.image);
|
||||||
assetMock.create.mockResolvedValue(assetStub.image);
|
assetMock.create.mockResolvedValue(assetStub.image);
|
||||||
|
|
||||||
expect(assetMock.save).not.toHaveBeenCalled();
|
expect(assetMock.update).not.toHaveBeenCalled();
|
||||||
|
|
||||||
await expect(sut.handleAssetRefresh(mockLibraryJob)).resolves.toBe(JobStatus.SUCCESS);
|
await expect(sut.handleAssetRefresh(mockLibraryJob)).resolves.toBe(JobStatus.SUCCESS);
|
||||||
});
|
});
|
||||||
|
@ -1257,7 +1257,7 @@ describe(LibraryService.name, () => {
|
||||||
|
|
||||||
await sut.watchAll();
|
await sut.watchAll();
|
||||||
|
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({ id: assetStub.external.id, isOffline: true });
|
expect(assetMock.update).toHaveBeenCalledWith({ id: assetStub.external.id, isOffline: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle an error event', async () => {
|
it('should handle an error event', async () => {
|
||||||
|
|
|
@ -173,7 +173,7 @@ export class LibraryService extends EventEmitter {
|
||||||
this.logger.debug(`Detected deleted file at ${path} in library ${library.id}`);
|
this.logger.debug(`Detected deleted file at ${path} in library ${library.id}`);
|
||||||
const asset = await this.assetRepository.getByLibraryIdAndOriginalPath(library.id, path);
|
const asset = await this.assetRepository.getByLibraryIdAndOriginalPath(library.id, path);
|
||||||
if (asset && matcher(path)) {
|
if (asset && matcher(path)) {
|
||||||
await this.assetRepository.save({ id: asset.id, isOffline: true });
|
await this.assetRepository.update({ id: asset.id, isOffline: true });
|
||||||
}
|
}
|
||||||
this.emit(StorageEventType.UNLINK, path);
|
this.emit(StorageEventType.UNLINK, path);
|
||||||
};
|
};
|
||||||
|
@ -429,7 +429,7 @@ export class LibraryService extends EventEmitter {
|
||||||
// Mark asset as offline
|
// Mark asset as offline
|
||||||
this.logger.debug(`Marking asset as offline: ${assetPath}`);
|
this.logger.debug(`Marking asset as offline: ${assetPath}`);
|
||||||
|
|
||||||
await this.assetRepository.save({ id: existingAssetEntity.id, isOffline: true });
|
await this.assetRepository.update({ id: existingAssetEntity.id, isOffline: true });
|
||||||
return JobStatus.SUCCESS;
|
return JobStatus.SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
// File can't be accessed and does not already exist in db
|
// File can't be accessed and does not already exist in db
|
||||||
|
@ -462,7 +462,7 @@ export class LibraryService extends EventEmitter {
|
||||||
if (stats && existingAssetEntity?.isOffline) {
|
if (stats && existingAssetEntity?.isOffline) {
|
||||||
// File was previously offline but is now online
|
// File was previously offline but is now online
|
||||||
this.logger.debug(`Marking previously-offline asset as online: ${assetPath}`);
|
this.logger.debug(`Marking previously-offline asset as online: ${assetPath}`);
|
||||||
await this.assetRepository.save({ id: existingAssetEntity.id, isOffline: false });
|
await this.assetRepository.update({ id: existingAssetEntity.id, isOffline: false });
|
||||||
doRefresh = true;
|
doRefresh = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -205,7 +205,7 @@ describe(MediaService.name, () => {
|
||||||
assetMock.getByIds.mockResolvedValue([]);
|
assetMock.getByIds.mockResolvedValue([]);
|
||||||
await sut.handleGenerateJpegThumbnail({ id: assetStub.image.id });
|
await sut.handleGenerateJpegThumbnail({ id: assetStub.image.id });
|
||||||
expect(mediaMock.resize).not.toHaveBeenCalled();
|
expect(mediaMock.resize).not.toHaveBeenCalled();
|
||||||
expect(assetMock.save).not.toHaveBeenCalledWith();
|
expect(assetMock.update).not.toHaveBeenCalledWith();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should skip video thumbnail generation if no video stream', async () => {
|
it('should skip video thumbnail generation if no video stream', async () => {
|
||||||
|
@ -213,7 +213,7 @@ describe(MediaService.name, () => {
|
||||||
assetMock.getByIds.mockResolvedValue([assetStub.video]);
|
assetMock.getByIds.mockResolvedValue([assetStub.video]);
|
||||||
await sut.handleGenerateJpegThumbnail({ id: assetStub.image.id });
|
await sut.handleGenerateJpegThumbnail({ id: assetStub.image.id });
|
||||||
expect(mediaMock.resize).not.toHaveBeenCalled();
|
expect(mediaMock.resize).not.toHaveBeenCalled();
|
||||||
expect(assetMock.save).not.toHaveBeenCalledWith();
|
expect(assetMock.update).not.toHaveBeenCalledWith();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate a thumbnail for an image', async () => {
|
it('should generate a thumbnail for an image', async () => {
|
||||||
|
@ -227,7 +227,7 @@ describe(MediaService.name, () => {
|
||||||
quality: 80,
|
quality: 80,
|
||||||
colorspace: Colorspace.SRGB,
|
colorspace: Colorspace.SRGB,
|
||||||
});
|
});
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: 'asset-id',
|
id: 'asset-id',
|
||||||
resizePath: 'upload/thumbs/user-id/as/se/asset-id.jpeg',
|
resizePath: 'upload/thumbs/user-id/as/se/asset-id.jpeg',
|
||||||
});
|
});
|
||||||
|
@ -246,7 +246,7 @@ describe(MediaService.name, () => {
|
||||||
quality: 80,
|
quality: 80,
|
||||||
colorspace: Colorspace.P3,
|
colorspace: Colorspace.P3,
|
||||||
});
|
});
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: 'asset-id',
|
id: 'asset-id',
|
||||||
resizePath: 'upload/thumbs/user-id/as/se/asset-id.jpeg',
|
resizePath: 'upload/thumbs/user-id/as/se/asset-id.jpeg',
|
||||||
});
|
});
|
||||||
|
@ -271,7 +271,7 @@ describe(MediaService.name, () => {
|
||||||
twoPass: false,
|
twoPass: false,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: 'asset-id',
|
id: 'asset-id',
|
||||||
resizePath: 'upload/thumbs/user-id/as/se/asset-id.jpeg',
|
resizePath: 'upload/thumbs/user-id/as/se/asset-id.jpeg',
|
||||||
});
|
});
|
||||||
|
@ -296,7 +296,7 @@ describe(MediaService.name, () => {
|
||||||
twoPass: false,
|
twoPass: false,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: 'asset-id',
|
id: 'asset-id',
|
||||||
resizePath: 'upload/thumbs/user-id/as/se/asset-id.jpeg',
|
resizePath: 'upload/thumbs/user-id/as/se/asset-id.jpeg',
|
||||||
});
|
});
|
||||||
|
@ -337,7 +337,7 @@ describe(MediaService.name, () => {
|
||||||
assetMock.getByIds.mockResolvedValue([]);
|
assetMock.getByIds.mockResolvedValue([]);
|
||||||
await sut.handleGenerateWebpThumbnail({ id: assetStub.image.id });
|
await sut.handleGenerateWebpThumbnail({ id: assetStub.image.id });
|
||||||
expect(mediaMock.resize).not.toHaveBeenCalled();
|
expect(mediaMock.resize).not.toHaveBeenCalled();
|
||||||
expect(assetMock.save).not.toHaveBeenCalledWith();
|
expect(assetMock.update).not.toHaveBeenCalledWith();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate a thumbnail', async () => {
|
it('should generate a thumbnail', async () => {
|
||||||
|
@ -350,7 +350,7 @@ describe(MediaService.name, () => {
|
||||||
quality: 80,
|
quality: 80,
|
||||||
colorspace: Colorspace.SRGB,
|
colorspace: Colorspace.SRGB,
|
||||||
});
|
});
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: 'asset-id',
|
id: 'asset-id',
|
||||||
webpPath: 'upload/thumbs/user-id/as/se/asset-id.webp',
|
webpPath: 'upload/thumbs/user-id/as/se/asset-id.webp',
|
||||||
});
|
});
|
||||||
|
@ -370,7 +370,7 @@ describe(MediaService.name, () => {
|
||||||
quality: 80,
|
quality: 80,
|
||||||
colorspace: Colorspace.P3,
|
colorspace: Colorspace.P3,
|
||||||
});
|
});
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: 'asset-id',
|
id: 'asset-id',
|
||||||
webpPath: 'upload/thumbs/user-id/as/se/asset-id.webp',
|
webpPath: 'upload/thumbs/user-id/as/se/asset-id.webp',
|
||||||
});
|
});
|
||||||
|
@ -397,7 +397,7 @@ describe(MediaService.name, () => {
|
||||||
await sut.handleGenerateThumbhashThumbnail({ id: assetStub.image.id });
|
await sut.handleGenerateThumbhashThumbnail({ id: assetStub.image.id });
|
||||||
|
|
||||||
expect(mediaMock.generateThumbhash).toHaveBeenCalledWith('/uploads/user-id/thumbs/path.jpg');
|
expect(mediaMock.generateThumbhash).toHaveBeenCalledWith('/uploads/user-id/thumbs/path.jpg');
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({ id: 'asset-id', thumbhash: thumbhashBuffer });
|
expect(assetMock.update).toHaveBeenCalledWith({ id: 'asset-id', thumbhash: thumbhashBuffer });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -172,7 +172,7 @@ export class MediaService {
|
||||||
}
|
}
|
||||||
|
|
||||||
const resizePath = await this.generateThumbnail(asset, 'jpeg');
|
const resizePath = await this.generateThumbnail(asset, 'jpeg');
|
||||||
await this.assetRepository.save({ id: asset.id, resizePath });
|
await this.assetRepository.update({ id: asset.id, resizePath });
|
||||||
return JobStatus.SUCCESS;
|
return JobStatus.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ export class MediaService {
|
||||||
}
|
}
|
||||||
|
|
||||||
const webpPath = await this.generateThumbnail(asset, 'webp');
|
const webpPath = await this.generateThumbnail(asset, 'webp');
|
||||||
await this.assetRepository.save({ id: asset.id, webpPath });
|
await this.assetRepository.update({ id: asset.id, webpPath });
|
||||||
return JobStatus.SUCCESS;
|
return JobStatus.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ export class MediaService {
|
||||||
}
|
}
|
||||||
|
|
||||||
const thumbhash = await this.mediaRepository.generateThumbhash(asset.resizePath);
|
const thumbhash = await this.mediaRepository.generateThumbhash(asset.resizePath);
|
||||||
await this.assetRepository.save({ id: asset.id, thumbhash });
|
await this.assetRepository.update({ id: asset.id, thumbhash });
|
||||||
|
|
||||||
return JobStatus.SUCCESS;
|
return JobStatus.SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -286,7 +286,7 @@ export class MediaService {
|
||||||
if (asset.encodedVideoPath) {
|
if (asset.encodedVideoPath) {
|
||||||
this.logger.log(`Transcoded video exists for asset ${asset.id}, but is no longer required. Deleting...`);
|
this.logger.log(`Transcoded video exists for asset ${asset.id}, but is no longer required. Deleting...`);
|
||||||
await this.jobRepository.queue({ name: JobName.DELETE_FILES, data: { files: [asset.encodedVideoPath] } });
|
await this.jobRepository.queue({ name: JobName.DELETE_FILES, data: { files: [asset.encodedVideoPath] } });
|
||||||
await this.assetRepository.save({ id: asset.id, encodedVideoPath: null });
|
await this.assetRepository.update({ id: asset.id, encodedVideoPath: null });
|
||||||
}
|
}
|
||||||
|
|
||||||
return JobStatus.SKIPPED;
|
return JobStatus.SKIPPED;
|
||||||
|
@ -321,7 +321,7 @@ export class MediaService {
|
||||||
|
|
||||||
this.logger.log(`Successfully encoded ${asset.id}`);
|
this.logger.log(`Successfully encoded ${asset.id}`);
|
||||||
|
|
||||||
await this.assetRepository.save({ id: asset.id, encodedVideoPath: output });
|
await this.assetRepository.update({ id: asset.id, encodedVideoPath: output });
|
||||||
|
|
||||||
return JobStatus.SUCCESS;
|
return JobStatus.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,7 +117,7 @@ describe(MetadataService.name, () => {
|
||||||
await expect(sut.handleLivePhotoLinking({ id: assetStub.image.id })).resolves.toBe(JobStatus.FAILED);
|
await expect(sut.handleLivePhotoLinking({ id: assetStub.image.id })).resolves.toBe(JobStatus.FAILED);
|
||||||
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.image.id], { exifInfo: true });
|
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.image.id], { exifInfo: true });
|
||||||
expect(assetMock.findLivePhotoMatch).not.toHaveBeenCalled();
|
expect(assetMock.findLivePhotoMatch).not.toHaveBeenCalled();
|
||||||
expect(assetMock.save).not.toHaveBeenCalled();
|
expect(assetMock.update).not.toHaveBeenCalled();
|
||||||
expect(albumMock.removeAsset).not.toHaveBeenCalled();
|
expect(albumMock.removeAsset).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ describe(MetadataService.name, () => {
|
||||||
await expect(sut.handleLivePhotoLinking({ id: assetStub.image.id })).resolves.toBe(JobStatus.FAILED);
|
await expect(sut.handleLivePhotoLinking({ id: assetStub.image.id })).resolves.toBe(JobStatus.FAILED);
|
||||||
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.image.id], { exifInfo: true });
|
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.image.id], { exifInfo: true });
|
||||||
expect(assetMock.findLivePhotoMatch).not.toHaveBeenCalled();
|
expect(assetMock.findLivePhotoMatch).not.toHaveBeenCalled();
|
||||||
expect(assetMock.save).not.toHaveBeenCalled();
|
expect(assetMock.update).not.toHaveBeenCalled();
|
||||||
expect(albumMock.removeAsset).not.toHaveBeenCalled();
|
expect(albumMock.removeAsset).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ describe(MetadataService.name, () => {
|
||||||
await expect(sut.handleLivePhotoLinking({ id: assetStub.image.id })).resolves.toBe(JobStatus.SKIPPED);
|
await expect(sut.handleLivePhotoLinking({ id: assetStub.image.id })).resolves.toBe(JobStatus.SKIPPED);
|
||||||
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.image.id], { exifInfo: true });
|
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.image.id], { exifInfo: true });
|
||||||
expect(assetMock.findLivePhotoMatch).not.toHaveBeenCalled();
|
expect(assetMock.findLivePhotoMatch).not.toHaveBeenCalled();
|
||||||
expect(assetMock.save).not.toHaveBeenCalled();
|
expect(assetMock.update).not.toHaveBeenCalled();
|
||||||
expect(albumMock.removeAsset).not.toHaveBeenCalled();
|
expect(albumMock.removeAsset).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ describe(MetadataService.name, () => {
|
||||||
otherAssetId: assetStub.livePhotoMotionAsset.id,
|
otherAssetId: assetStub.livePhotoMotionAsset.id,
|
||||||
type: AssetType.IMAGE,
|
type: AssetType.IMAGE,
|
||||||
});
|
});
|
||||||
expect(assetMock.save).not.toHaveBeenCalled();
|
expect(assetMock.update).not.toHaveBeenCalled();
|
||||||
expect(albumMock.removeAsset).not.toHaveBeenCalled();
|
expect(albumMock.removeAsset).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -182,11 +182,11 @@ describe(MetadataService.name, () => {
|
||||||
otherAssetId: assetStub.livePhotoStillAsset.id,
|
otherAssetId: assetStub.livePhotoStillAsset.id,
|
||||||
type: AssetType.VIDEO,
|
type: AssetType.VIDEO,
|
||||||
});
|
});
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: assetStub.livePhotoStillAsset.id,
|
id: assetStub.livePhotoStillAsset.id,
|
||||||
livePhotoVideoId: assetStub.livePhotoMotionAsset.id,
|
livePhotoVideoId: assetStub.livePhotoMotionAsset.id,
|
||||||
});
|
});
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({ id: assetStub.livePhotoMotionAsset.id, isVisible: false });
|
expect(assetMock.update).toHaveBeenCalledWith({ id: assetStub.livePhotoMotionAsset.id, isVisible: false });
|
||||||
expect(albumMock.removeAsset).toHaveBeenCalledWith(assetStub.livePhotoMotionAsset.id);
|
expect(albumMock.removeAsset).toHaveBeenCalledWith(assetStub.livePhotoMotionAsset.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -248,7 +248,7 @@ describe(MetadataService.name, () => {
|
||||||
|
|
||||||
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.image.id]);
|
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.image.id]);
|
||||||
expect(assetMock.upsertExif).not.toHaveBeenCalled();
|
expect(assetMock.upsertExif).not.toHaveBeenCalled();
|
||||||
expect(assetMock.save).not.toHaveBeenCalled();
|
expect(assetMock.update).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle a date in a sidecar file', async () => {
|
it('should handle a date in a sidecar file', async () => {
|
||||||
|
@ -267,7 +267,7 @@ describe(MetadataService.name, () => {
|
||||||
await sut.handleMetadataExtraction({ id: assetStub.image.id });
|
await sut.handleMetadataExtraction({ id: assetStub.image.id });
|
||||||
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.sidecar.id]);
|
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.sidecar.id]);
|
||||||
expect(assetMock.upsertExif).toHaveBeenCalledWith(expect.objectContaining({ dateTimeOriginal: sidecarDate }));
|
expect(assetMock.upsertExif).toHaveBeenCalledWith(expect.objectContaining({ dateTimeOriginal: sidecarDate }));
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: assetStub.image.id,
|
id: assetStub.image.id,
|
||||||
duration: null,
|
duration: null,
|
||||||
fileCreatedAt: sidecarDate,
|
fileCreatedAt: sidecarDate,
|
||||||
|
@ -282,7 +282,7 @@ describe(MetadataService.name, () => {
|
||||||
await sut.handleMetadataExtraction({ id: assetStub.image.id });
|
await sut.handleMetadataExtraction({ id: assetStub.image.id });
|
||||||
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.image.id]);
|
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.image.id]);
|
||||||
expect(assetMock.upsertExif).toHaveBeenCalledWith(expect.objectContaining({ iso: 160 }));
|
expect(assetMock.upsertExif).toHaveBeenCalledWith(expect.objectContaining({ iso: 160 }));
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: assetStub.image.id,
|
id: assetStub.image.id,
|
||||||
duration: null,
|
duration: null,
|
||||||
fileCreatedAt: assetStub.image.createdAt,
|
fileCreatedAt: assetStub.image.createdAt,
|
||||||
|
@ -304,7 +304,7 @@ describe(MetadataService.name, () => {
|
||||||
expect(assetMock.upsertExif).toHaveBeenCalledWith(
|
expect(assetMock.upsertExif).toHaveBeenCalledWith(
|
||||||
expect.objectContaining({ city: 'City', state: 'State', country: 'Country' }),
|
expect.objectContaining({ city: 'City', state: 'State', country: 'Country' }),
|
||||||
);
|
);
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: assetStub.withLocation.id,
|
id: assetStub.withLocation.id,
|
||||||
duration: null,
|
duration: null,
|
||||||
fileCreatedAt: assetStub.withLocation.createdAt,
|
fileCreatedAt: assetStub.withLocation.createdAt,
|
||||||
|
@ -333,7 +333,7 @@ describe(MetadataService.name, () => {
|
||||||
expect(storageMock.writeFile).not.toHaveBeenCalled();
|
expect(storageMock.writeFile).not.toHaveBeenCalled();
|
||||||
expect(jobMock.queue).not.toHaveBeenCalled();
|
expect(jobMock.queue).not.toHaveBeenCalled();
|
||||||
expect(jobMock.queueAll).not.toHaveBeenCalled();
|
expect(jobMock.queueAll).not.toHaveBeenCalled();
|
||||||
expect(assetMock.save).not.toHaveBeenCalledWith(
|
expect(assetMock.update).not.toHaveBeenCalledWith(
|
||||||
expect.objectContaining({ assetType: AssetType.VIDEO, isVisible: false }),
|
expect.objectContaining({ assetType: AssetType.VIDEO, isVisible: false }),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -376,7 +376,7 @@ describe(MetadataService.name, () => {
|
||||||
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.livePhotoStillAsset.id]);
|
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.livePhotoStillAsset.id]);
|
||||||
expect(assetMock.create).toHaveBeenCalled(); // This could have arguments added
|
expect(assetMock.create).toHaveBeenCalled(); // This could have arguments added
|
||||||
expect(storageMock.writeFile).toHaveBeenCalledWith(assetStub.livePhotoMotionAsset.originalPath, video);
|
expect(storageMock.writeFile).toHaveBeenCalledWith(assetStub.livePhotoMotionAsset.originalPath, video);
|
||||||
expect(assetMock.save).toHaveBeenNthCalledWith(1, {
|
expect(assetMock.update).toHaveBeenNthCalledWith(1, {
|
||||||
id: assetStub.livePhotoStillAsset.id,
|
id: assetStub.livePhotoStillAsset.id,
|
||||||
livePhotoVideoId: fileStub.livePhotoMotion.uuid,
|
livePhotoVideoId: fileStub.livePhotoMotion.uuid,
|
||||||
});
|
});
|
||||||
|
@ -404,7 +404,7 @@ describe(MetadataService.name, () => {
|
||||||
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.livePhotoStillAsset.id]);
|
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.livePhotoStillAsset.id]);
|
||||||
expect(assetMock.create).toHaveBeenCalled(); // This could have arguments added
|
expect(assetMock.create).toHaveBeenCalled(); // This could have arguments added
|
||||||
expect(storageMock.writeFile).toHaveBeenCalledWith(assetStub.livePhotoMotionAsset.originalPath, video);
|
expect(storageMock.writeFile).toHaveBeenCalledWith(assetStub.livePhotoMotionAsset.originalPath, video);
|
||||||
expect(assetMock.save).toHaveBeenNthCalledWith(1, {
|
expect(assetMock.update).toHaveBeenNthCalledWith(1, {
|
||||||
id: assetStub.livePhotoStillAsset.id,
|
id: assetStub.livePhotoStillAsset.id,
|
||||||
livePhotoVideoId: fileStub.livePhotoMotion.uuid,
|
livePhotoVideoId: fileStub.livePhotoMotion.uuid,
|
||||||
});
|
});
|
||||||
|
@ -430,7 +430,7 @@ describe(MetadataService.name, () => {
|
||||||
expect(storageMock.readFile).toHaveBeenCalledWith(assetStub.livePhotoStillAsset.originalPath, expect.any(Object));
|
expect(storageMock.readFile).toHaveBeenCalledWith(assetStub.livePhotoStillAsset.originalPath, expect.any(Object));
|
||||||
expect(assetMock.create).toHaveBeenCalled(); // This could have arguments added
|
expect(assetMock.create).toHaveBeenCalled(); // This could have arguments added
|
||||||
expect(storageMock.writeFile).toHaveBeenCalledWith(assetStub.livePhotoMotionAsset.originalPath, video);
|
expect(storageMock.writeFile).toHaveBeenCalledWith(assetStub.livePhotoMotionAsset.originalPath, video);
|
||||||
expect(assetMock.save).toHaveBeenNthCalledWith(1, {
|
expect(assetMock.update).toHaveBeenNthCalledWith(1, {
|
||||||
id: assetStub.livePhotoStillAsset.id,
|
id: assetStub.livePhotoStillAsset.id,
|
||||||
livePhotoVideoId: fileStub.livePhotoMotion.uuid,
|
livePhotoVideoId: fileStub.livePhotoMotion.uuid,
|
||||||
});
|
});
|
||||||
|
@ -470,7 +470,7 @@ describe(MetadataService.name, () => {
|
||||||
expect(assetMock.create).toHaveBeenCalledTimes(0);
|
expect(assetMock.create).toHaveBeenCalledTimes(0);
|
||||||
expect(storageMock.writeFile).toHaveBeenCalledTimes(0);
|
expect(storageMock.writeFile).toHaveBeenCalledTimes(0);
|
||||||
// The still asset gets saved by handleMetadataExtraction, but not the video
|
// The still asset gets saved by handleMetadataExtraction, but not the video
|
||||||
expect(assetMock.save).toHaveBeenCalledTimes(1);
|
expect(assetMock.update).toHaveBeenCalledTimes(1);
|
||||||
expect(jobMock.queue).toHaveBeenCalledTimes(0);
|
expect(jobMock.queue).toHaveBeenCalledTimes(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -529,7 +529,7 @@ describe(MetadataService.name, () => {
|
||||||
projectionType: 'EQUIRECTANGULAR',
|
projectionType: 'EQUIRECTANGULAR',
|
||||||
timeZone: tags.tz,
|
timeZone: tags.tz,
|
||||||
});
|
});
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: assetStub.image.id,
|
id: assetStub.image.id,
|
||||||
duration: null,
|
duration: null,
|
||||||
fileCreatedAt: new Date('1970-01-01'),
|
fileCreatedAt: new Date('1970-01-01'),
|
||||||
|
@ -545,7 +545,7 @@ describe(MetadataService.name, () => {
|
||||||
|
|
||||||
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.image.id]);
|
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.image.id]);
|
||||||
expect(assetMock.upsertExif).toHaveBeenCalled();
|
expect(assetMock.upsertExif).toHaveBeenCalled();
|
||||||
expect(assetMock.save).toHaveBeenCalledWith(
|
expect(assetMock.update).toHaveBeenCalledWith(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: assetStub.image.id,
|
id: assetStub.image.id,
|
||||||
duration: '00:00:06.210',
|
duration: '00:00:06.210',
|
||||||
|
@ -561,7 +561,7 @@ describe(MetadataService.name, () => {
|
||||||
|
|
||||||
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.image.id]);
|
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.image.id]);
|
||||||
expect(assetMock.upsertExif).toHaveBeenCalled();
|
expect(assetMock.upsertExif).toHaveBeenCalled();
|
||||||
expect(assetMock.save).toHaveBeenCalledWith(
|
expect(assetMock.update).toHaveBeenCalledWith(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: assetStub.image.id,
|
id: assetStub.image.id,
|
||||||
duration: '00:00:08.410',
|
duration: '00:00:08.410',
|
||||||
|
@ -577,7 +577,7 @@ describe(MetadataService.name, () => {
|
||||||
|
|
||||||
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.image.id]);
|
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.image.id]);
|
||||||
expect(assetMock.upsertExif).toHaveBeenCalled();
|
expect(assetMock.upsertExif).toHaveBeenCalled();
|
||||||
expect(assetMock.save).toHaveBeenCalledWith(
|
expect(assetMock.update).toHaveBeenCalledWith(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: assetStub.image.id,
|
id: assetStub.image.id,
|
||||||
duration: '00:00:06.200',
|
duration: '00:00:06.200',
|
||||||
|
@ -593,7 +593,7 @@ describe(MetadataService.name, () => {
|
||||||
|
|
||||||
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.image.id]);
|
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.image.id]);
|
||||||
expect(assetMock.upsertExif).toHaveBeenCalled();
|
expect(assetMock.upsertExif).toHaveBeenCalled();
|
||||||
expect(assetMock.save).toHaveBeenCalledWith(
|
expect(assetMock.update).toHaveBeenCalledWith(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: assetStub.image.id,
|
id: assetStub.image.id,
|
||||||
duration: '00:00:06.207',
|
duration: '00:00:06.207',
|
||||||
|
@ -638,13 +638,13 @@ describe(MetadataService.name, () => {
|
||||||
it('should do nothing if asset could not be found', async () => {
|
it('should do nothing if asset could not be found', async () => {
|
||||||
assetMock.getByIds.mockResolvedValue([]);
|
assetMock.getByIds.mockResolvedValue([]);
|
||||||
await expect(sut.handleSidecarSync({ id: assetStub.image.id })).resolves.toBe(JobStatus.FAILED);
|
await expect(sut.handleSidecarSync({ id: assetStub.image.id })).resolves.toBe(JobStatus.FAILED);
|
||||||
expect(assetMock.save).not.toHaveBeenCalled();
|
expect(assetMock.update).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should do nothing if asset has no sidecar path', async () => {
|
it('should do nothing if asset has no sidecar path', async () => {
|
||||||
assetMock.getByIds.mockResolvedValue([assetStub.image]);
|
assetMock.getByIds.mockResolvedValue([assetStub.image]);
|
||||||
await expect(sut.handleSidecarSync({ id: assetStub.image.id })).resolves.toBe(JobStatus.FAILED);
|
await expect(sut.handleSidecarSync({ id: assetStub.image.id })).resolves.toBe(JobStatus.FAILED);
|
||||||
expect(assetMock.save).not.toHaveBeenCalled();
|
expect(assetMock.update).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set sidecar path if exists (sidecar named photo.ext.xmp)', async () => {
|
it('should set sidecar path if exists (sidecar named photo.ext.xmp)', async () => {
|
||||||
|
@ -653,7 +653,7 @@ describe(MetadataService.name, () => {
|
||||||
|
|
||||||
await expect(sut.handleSidecarSync({ id: assetStub.sidecar.id })).resolves.toBe(JobStatus.SUCCESS);
|
await expect(sut.handleSidecarSync({ id: assetStub.sidecar.id })).resolves.toBe(JobStatus.SUCCESS);
|
||||||
expect(storageMock.checkFileExists).toHaveBeenCalledWith(`${assetStub.sidecar.originalPath}.xmp`, constants.R_OK);
|
expect(storageMock.checkFileExists).toHaveBeenCalledWith(`${assetStub.sidecar.originalPath}.xmp`, constants.R_OK);
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: assetStub.sidecar.id,
|
id: assetStub.sidecar.id,
|
||||||
sidecarPath: assetStub.sidecar.sidecarPath,
|
sidecarPath: assetStub.sidecar.sidecarPath,
|
||||||
});
|
});
|
||||||
|
@ -670,7 +670,7 @@ describe(MetadataService.name, () => {
|
||||||
assetStub.sidecarWithoutExt.sidecarPath,
|
assetStub.sidecarWithoutExt.sidecarPath,
|
||||||
constants.R_OK,
|
constants.R_OK,
|
||||||
);
|
);
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: assetStub.sidecarWithoutExt.id,
|
id: assetStub.sidecarWithoutExt.id,
|
||||||
sidecarPath: assetStub.sidecarWithoutExt.sidecarPath,
|
sidecarPath: assetStub.sidecarWithoutExt.sidecarPath,
|
||||||
});
|
});
|
||||||
|
@ -688,7 +688,7 @@ describe(MetadataService.name, () => {
|
||||||
assetStub.sidecarWithoutExt.sidecarPath,
|
assetStub.sidecarWithoutExt.sidecarPath,
|
||||||
constants.R_OK,
|
constants.R_OK,
|
||||||
);
|
);
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: assetStub.sidecar.id,
|
id: assetStub.sidecar.id,
|
||||||
sidecarPath: assetStub.sidecar.sidecarPath,
|
sidecarPath: assetStub.sidecar.sidecarPath,
|
||||||
});
|
});
|
||||||
|
@ -700,7 +700,7 @@ describe(MetadataService.name, () => {
|
||||||
|
|
||||||
await expect(sut.handleSidecarSync({ id: assetStub.sidecar.id })).resolves.toBe(JobStatus.SUCCESS);
|
await expect(sut.handleSidecarSync({ id: assetStub.sidecar.id })).resolves.toBe(JobStatus.SUCCESS);
|
||||||
expect(storageMock.checkFileExists).toHaveBeenCalledWith(`${assetStub.sidecar.originalPath}.xmp`, constants.R_OK);
|
expect(storageMock.checkFileExists).toHaveBeenCalledWith(`${assetStub.sidecar.originalPath}.xmp`, constants.R_OK);
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: assetStub.sidecar.id,
|
id: assetStub.sidecar.id,
|
||||||
sidecarPath: null,
|
sidecarPath: null,
|
||||||
});
|
});
|
||||||
|
@ -724,16 +724,15 @@ describe(MetadataService.name, () => {
|
||||||
assetMock.getByIds.mockResolvedValue([assetStub.image]);
|
assetMock.getByIds.mockResolvedValue([assetStub.image]);
|
||||||
storageMock.checkFileExists.mockResolvedValue(false);
|
storageMock.checkFileExists.mockResolvedValue(false);
|
||||||
await sut.handleSidecarDiscovery({ id: assetStub.image.id });
|
await sut.handleSidecarDiscovery({ id: assetStub.image.id });
|
||||||
expect(assetMock.save).not.toHaveBeenCalled();
|
expect(assetMock.update).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update a image asset when a sidecar is found', async () => {
|
it('should update a image asset when a sidecar is found', async () => {
|
||||||
assetMock.getByIds.mockResolvedValue([assetStub.image]);
|
assetMock.getByIds.mockResolvedValue([assetStub.image]);
|
||||||
assetMock.save.mockResolvedValue(assetStub.image);
|
|
||||||
storageMock.checkFileExists.mockResolvedValue(true);
|
storageMock.checkFileExists.mockResolvedValue(true);
|
||||||
await sut.handleSidecarDiscovery({ id: assetStub.image.id });
|
await sut.handleSidecarDiscovery({ id: assetStub.image.id });
|
||||||
expect(storageMock.checkFileExists).toHaveBeenCalledWith('/original/path.jpg.xmp', constants.R_OK);
|
expect(storageMock.checkFileExists).toHaveBeenCalledWith('/original/path.jpg.xmp', constants.R_OK);
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: assetStub.image.id,
|
id: assetStub.image.id,
|
||||||
sidecarPath: '/original/path.jpg.xmp',
|
sidecarPath: '/original/path.jpg.xmp',
|
||||||
});
|
});
|
||||||
|
@ -741,11 +740,10 @@ describe(MetadataService.name, () => {
|
||||||
|
|
||||||
it('should update a video asset when a sidecar is found', async () => {
|
it('should update a video asset when a sidecar is found', async () => {
|
||||||
assetMock.getByIds.mockResolvedValue([assetStub.video]);
|
assetMock.getByIds.mockResolvedValue([assetStub.video]);
|
||||||
assetMock.save.mockResolvedValue(assetStub.video);
|
|
||||||
storageMock.checkFileExists.mockResolvedValue(true);
|
storageMock.checkFileExists.mockResolvedValue(true);
|
||||||
await sut.handleSidecarDiscovery({ id: assetStub.video.id });
|
await sut.handleSidecarDiscovery({ id: assetStub.video.id });
|
||||||
expect(storageMock.checkFileExists).toHaveBeenCalledWith('/original/path.ext.xmp', constants.R_OK);
|
expect(storageMock.checkFileExists).toHaveBeenCalledWith('/original/path.ext.xmp', constants.R_OK);
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: assetStub.image.id,
|
id: assetStub.image.id,
|
||||||
sidecarPath: '/original/path.ext.xmp',
|
sidecarPath: '/original/path.ext.xmp',
|
||||||
});
|
});
|
||||||
|
|
|
@ -177,8 +177,8 @@ export class MetadataService {
|
||||||
|
|
||||||
const [photoAsset, motionAsset] = asset.type === AssetType.IMAGE ? [asset, match] : [match, asset];
|
const [photoAsset, motionAsset] = asset.type === AssetType.IMAGE ? [asset, match] : [match, asset];
|
||||||
|
|
||||||
await this.assetRepository.save({ id: photoAsset.id, livePhotoVideoId: motionAsset.id });
|
await this.assetRepository.update({ id: photoAsset.id, livePhotoVideoId: motionAsset.id });
|
||||||
await this.assetRepository.save({ id: motionAsset.id, isVisible: false });
|
await this.assetRepository.update({ id: motionAsset.id, isVisible: false });
|
||||||
await this.albumRepository.removeAsset(motionAsset.id);
|
await this.albumRepository.removeAsset(motionAsset.id);
|
||||||
|
|
||||||
// Notify clients to hide the linked live photo asset
|
// Notify clients to hide the linked live photo asset
|
||||||
|
@ -249,7 +249,7 @@ export class MetadataService {
|
||||||
if (dateTimeOriginal && timeZoneOffset) {
|
if (dateTimeOriginal && timeZoneOffset) {
|
||||||
localDateTime = new Date(dateTimeOriginal.getTime() + timeZoneOffset * 60_000);
|
localDateTime = new Date(dateTimeOriginal.getTime() + timeZoneOffset * 60_000);
|
||||||
}
|
}
|
||||||
await this.assetRepository.save({
|
await this.assetRepository.update({
|
||||||
id: asset.id,
|
id: asset.id,
|
||||||
duration: tags.Duration ? this.getDuration(tags.Duration) : null,
|
duration: tags.Duration ? this.getDuration(tags.Duration) : null,
|
||||||
localDateTime,
|
localDateTime,
|
||||||
|
@ -317,7 +317,7 @@ export class MetadataService {
|
||||||
await this.repository.writeTags(sidecarPath, exif);
|
await this.repository.writeTags(sidecarPath, exif);
|
||||||
|
|
||||||
if (!asset.sidecarPath) {
|
if (!asset.sidecarPath) {
|
||||||
await this.assetRepository.save({ id, sidecarPath });
|
await this.assetRepository.update({ id, sidecarPath });
|
||||||
}
|
}
|
||||||
|
|
||||||
return JobStatus.SUCCESS;
|
return JobStatus.SUCCESS;
|
||||||
|
@ -435,7 +435,7 @@ export class MetadataService {
|
||||||
this.storageCore.ensureFolders(motionPath);
|
this.storageCore.ensureFolders(motionPath);
|
||||||
await this.storageRepository.writeFile(motionAsset.originalPath, video);
|
await this.storageRepository.writeFile(motionAsset.originalPath, video);
|
||||||
await this.jobRepository.queue({ name: JobName.METADATA_EXTRACTION, data: { id: motionAsset.id } });
|
await this.jobRepository.queue({ name: JobName.METADATA_EXTRACTION, data: { id: motionAsset.id } });
|
||||||
await this.assetRepository.save({ id: asset.id, livePhotoVideoId: motionAsset.id });
|
await this.assetRepository.update({ id: asset.id, livePhotoVideoId: motionAsset.id });
|
||||||
|
|
||||||
// If the asset already had an associated livePhotoVideo, delete it, because
|
// If the asset already had an associated livePhotoVideo, delete it, because
|
||||||
// its checksum doesn't match the checksum of the motionAsset we just extracted
|
// its checksum doesn't match the checksum of the motionAsset we just extracted
|
||||||
|
@ -587,7 +587,7 @@ export class MetadataService {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sidecarPath) {
|
if (sidecarPath) {
|
||||||
await this.assetRepository.save({ id: asset.id, sidecarPath });
|
await this.assetRepository.update({ id: asset.id, sidecarPath });
|
||||||
return JobStatus.SUCCESS;
|
return JobStatus.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -598,7 +598,7 @@ export class MetadataService {
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
`Sidecar file was not found. Checked paths '${sidecarPathWithExt}' and '${sidecarPathWithoutExt}'. Removing sidecarPath for asset ${asset.id}`,
|
`Sidecar file was not found. Checked paths '${sidecarPathWithExt}' and '${sidecarPathWithoutExt}'. Removing sidecarPath for asset ${asset.id}`,
|
||||||
);
|
);
|
||||||
await this.assetRepository.save({ id: asset.id, sidecarPath: null });
|
await this.assetRepository.update({ id: asset.id, sidecarPath: null });
|
||||||
|
|
||||||
return JobStatus.SUCCESS;
|
return JobStatus.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,6 +90,25 @@ export type AssetCreate = Pick<
|
||||||
> &
|
> &
|
||||||
Partial<AssetEntity>;
|
Partial<AssetEntity>;
|
||||||
|
|
||||||
|
export type AssetWithoutRelations = Omit<
|
||||||
|
AssetEntity,
|
||||||
|
| 'livePhotoVideo'
|
||||||
|
| 'stack'
|
||||||
|
| 'albums'
|
||||||
|
| 'faces'
|
||||||
|
| 'owner'
|
||||||
|
| 'library'
|
||||||
|
| 'exifInfo'
|
||||||
|
| 'sharedLinks'
|
||||||
|
| 'smartInfo'
|
||||||
|
| 'smartSearch'
|
||||||
|
| 'tags'
|
||||||
|
>;
|
||||||
|
|
||||||
|
export type AssetUpdateOptions = Pick<AssetWithoutRelations, 'id'> & Partial<AssetWithoutRelations>;
|
||||||
|
|
||||||
|
export type AssetUpdateAllOptions = Omit<Partial<AssetWithoutRelations>, 'id'>;
|
||||||
|
|
||||||
export interface MonthDay {
|
export interface MonthDay {
|
||||||
day: number;
|
day: number;
|
||||||
month: number;
|
month: number;
|
||||||
|
@ -138,8 +157,8 @@ export interface IAssetRepository {
|
||||||
deleteAll(ownerId: string): Promise<void>;
|
deleteAll(ownerId: string): Promise<void>;
|
||||||
getAll(pagination: PaginationOptions, options?: AssetSearchOptions): Paginated<AssetEntity>;
|
getAll(pagination: PaginationOptions, options?: AssetSearchOptions): Paginated<AssetEntity>;
|
||||||
getAllByDeviceId(userId: string, deviceId: string): Promise<string[]>;
|
getAllByDeviceId(userId: string, deviceId: string): Promise<string[]>;
|
||||||
updateAll(ids: string[], options: Partial<AssetEntity>): Promise<void>;
|
updateAll(ids: string[], options: Partial<AssetUpdateAllOptions>): Promise<void>;
|
||||||
save(asset: Pick<AssetEntity, 'id'> & Partial<AssetEntity>): Promise<AssetEntity>;
|
update(asset: AssetUpdateOptions): Promise<void>;
|
||||||
remove(asset: AssetEntity): Promise<void>;
|
remove(asset: AssetEntity): Promise<void>;
|
||||||
softDeleteAll(ids: string[]): Promise<void>;
|
softDeleteAll(ids: string[]): Promise<void>;
|
||||||
restoreAll(ids: string[]): Promise<void>;
|
restoreAll(ids: string[]): Promise<void>;
|
||||||
|
|
|
@ -111,7 +111,7 @@ describe(StorageTemplateService.name, () => {
|
||||||
expect(storageMock.checkFileExists).not.toHaveBeenCalled();
|
expect(storageMock.checkFileExists).not.toHaveBeenCalled();
|
||||||
expect(storageMock.rename).not.toHaveBeenCalled();
|
expect(storageMock.rename).not.toHaveBeenCalled();
|
||||||
expect(storageMock.copyFile).not.toHaveBeenCalled();
|
expect(storageMock.copyFile).not.toHaveBeenCalled();
|
||||||
expect(assetMock.save).not.toHaveBeenCalled();
|
expect(assetMock.update).not.toHaveBeenCalled();
|
||||||
expect(moveMock.create).not.toHaveBeenCalled();
|
expect(moveMock.create).not.toHaveBeenCalled();
|
||||||
expect(moveMock.update).not.toHaveBeenCalled();
|
expect(moveMock.update).not.toHaveBeenCalled();
|
||||||
expect(storageMock.stat).not.toHaveBeenCalled();
|
expect(storageMock.stat).not.toHaveBeenCalled();
|
||||||
|
@ -122,14 +122,6 @@ describe(StorageTemplateService.name, () => {
|
||||||
const newMotionPicturePath = `upload/library/${userStub.user1.id}/2022/2022-06-19/${assetStub.livePhotoStillAsset.id}.mp4`;
|
const newMotionPicturePath = `upload/library/${userStub.user1.id}/2022/2022-06-19/${assetStub.livePhotoStillAsset.id}.mp4`;
|
||||||
const newStillPicturePath = `upload/library/${userStub.user1.id}/2022/2022-06-19/${assetStub.livePhotoStillAsset.id}.jpeg`;
|
const newStillPicturePath = `upload/library/${userStub.user1.id}/2022/2022-06-19/${assetStub.livePhotoStillAsset.id}.jpeg`;
|
||||||
|
|
||||||
when(assetMock.save)
|
|
||||||
.calledWith({ id: assetStub.livePhotoStillAsset.id, originalPath: newStillPicturePath })
|
|
||||||
.mockResolvedValue(assetStub.livePhotoStillAsset);
|
|
||||||
|
|
||||||
when(assetMock.save)
|
|
||||||
.calledWith({ id: assetStub.livePhotoMotionAsset.id, originalPath: newMotionPicturePath })
|
|
||||||
.mockResolvedValue(assetStub.livePhotoMotionAsset);
|
|
||||||
|
|
||||||
when(assetMock.getByIds)
|
when(assetMock.getByIds)
|
||||||
.calledWith([assetStub.livePhotoStillAsset.id], { exifInfo: true })
|
.calledWith([assetStub.livePhotoStillAsset.id], { exifInfo: true })
|
||||||
.mockResolvedValue([assetStub.livePhotoStillAsset]);
|
.mockResolvedValue([assetStub.livePhotoStillAsset]);
|
||||||
|
@ -175,11 +167,11 @@ describe(StorageTemplateService.name, () => {
|
||||||
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.livePhotoStillAsset.id], { exifInfo: true });
|
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.livePhotoStillAsset.id], { exifInfo: true });
|
||||||
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.livePhotoMotionAsset.id], { exifInfo: true });
|
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.livePhotoMotionAsset.id], { exifInfo: true });
|
||||||
expect(storageMock.checkFileExists).toHaveBeenCalledTimes(2);
|
expect(storageMock.checkFileExists).toHaveBeenCalledTimes(2);
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: assetStub.livePhotoStillAsset.id,
|
id: assetStub.livePhotoStillAsset.id,
|
||||||
originalPath: newStillPicturePath,
|
originalPath: newStillPicturePath,
|
||||||
});
|
});
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: assetStub.livePhotoMotionAsset.id,
|
id: assetStub.livePhotoMotionAsset.id,
|
||||||
originalPath: newMotionPicturePath,
|
originalPath: newMotionPicturePath,
|
||||||
});
|
});
|
||||||
|
@ -200,10 +192,6 @@ describe(StorageTemplateService.name, () => {
|
||||||
newPath: previousFailedNewPath,
|
newPath: previousFailedNewPath,
|
||||||
});
|
});
|
||||||
|
|
||||||
when(assetMock.save)
|
|
||||||
.calledWith({ id: assetStub.image.id, originalPath: newPath })
|
|
||||||
.mockResolvedValue(assetStub.image);
|
|
||||||
|
|
||||||
when(assetMock.getByIds)
|
when(assetMock.getByIds)
|
||||||
.calledWith([assetStub.image.id], { exifInfo: true })
|
.calledWith([assetStub.image.id], { exifInfo: true })
|
||||||
.mockResolvedValue([assetStub.image]);
|
.mockResolvedValue([assetStub.image]);
|
||||||
|
@ -232,7 +220,7 @@ describe(StorageTemplateService.name, () => {
|
||||||
oldPath: assetStub.image.originalPath,
|
oldPath: assetStub.image.originalPath,
|
||||||
newPath,
|
newPath,
|
||||||
});
|
});
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: assetStub.image.id,
|
id: assetStub.image.id,
|
||||||
originalPath: newPath,
|
originalPath: newPath,
|
||||||
});
|
});
|
||||||
|
@ -257,10 +245,6 @@ describe(StorageTemplateService.name, () => {
|
||||||
newPath: previousFailedNewPath,
|
newPath: previousFailedNewPath,
|
||||||
});
|
});
|
||||||
|
|
||||||
when(assetMock.save)
|
|
||||||
.calledWith({ id: assetStub.image.id, originalPath: newPath })
|
|
||||||
.mockResolvedValue(assetStub.image);
|
|
||||||
|
|
||||||
when(assetMock.getByIds)
|
when(assetMock.getByIds)
|
||||||
.calledWith([assetStub.image.id], { exifInfo: true })
|
.calledWith([assetStub.image.id], { exifInfo: true })
|
||||||
.mockResolvedValue([assetStub.image]);
|
.mockResolvedValue([assetStub.image]);
|
||||||
|
@ -291,7 +275,7 @@ describe(StorageTemplateService.name, () => {
|
||||||
oldPath: previousFailedNewPath,
|
oldPath: previousFailedNewPath,
|
||||||
newPath,
|
newPath,
|
||||||
});
|
});
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: assetStub.image.id,
|
id: assetStub.image.id,
|
||||||
originalPath: newPath,
|
originalPath: newPath,
|
||||||
});
|
});
|
||||||
|
@ -307,10 +291,6 @@ describe(StorageTemplateService.name, () => {
|
||||||
.mockResolvedValue({ size: 5000 } as Stats);
|
.mockResolvedValue({ size: 5000 } as Stats);
|
||||||
when(cryptoMock.hashFile).calledWith(newPath).mockResolvedValue(Buffer.from('different-hash', 'utf8'));
|
when(cryptoMock.hashFile).calledWith(newPath).mockResolvedValue(Buffer.from('different-hash', 'utf8'));
|
||||||
|
|
||||||
when(assetMock.save)
|
|
||||||
.calledWith({ id: assetStub.image.id, originalPath: newPath })
|
|
||||||
.mockResolvedValue(assetStub.image);
|
|
||||||
|
|
||||||
when(assetMock.getByIds)
|
when(assetMock.getByIds)
|
||||||
.calledWith([assetStub.image.id], { exifInfo: true })
|
.calledWith([assetStub.image.id], { exifInfo: true })
|
||||||
.mockResolvedValue([assetStub.image]);
|
.mockResolvedValue([assetStub.image]);
|
||||||
|
@ -345,7 +325,7 @@ describe(StorageTemplateService.name, () => {
|
||||||
expect(storageMock.copyFile).toHaveBeenCalledWith(assetStub.image.originalPath, newPath);
|
expect(storageMock.copyFile).toHaveBeenCalledWith(assetStub.image.originalPath, newPath);
|
||||||
expect(storageMock.unlink).toHaveBeenCalledWith(newPath);
|
expect(storageMock.unlink).toHaveBeenCalledWith(newPath);
|
||||||
expect(storageMock.unlink).toHaveBeenCalledTimes(1);
|
expect(storageMock.unlink).toHaveBeenCalledTimes(1);
|
||||||
expect(assetMock.save).not.toHaveBeenCalled();
|
expect(assetMock.update).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it.each`
|
it.each`
|
||||||
|
@ -374,10 +354,6 @@ describe(StorageTemplateService.name, () => {
|
||||||
newPath: previousFailedNewPath,
|
newPath: previousFailedNewPath,
|
||||||
});
|
});
|
||||||
|
|
||||||
when(assetMock.save)
|
|
||||||
.calledWith({ id: assetStub.image.id, originalPath: newPath })
|
|
||||||
.mockResolvedValue(assetStub.image);
|
|
||||||
|
|
||||||
when(assetMock.getByIds)
|
when(assetMock.getByIds)
|
||||||
.calledWith([assetStub.image.id], { exifInfo: true })
|
.calledWith([assetStub.image.id], { exifInfo: true })
|
||||||
.mockResolvedValue([assetStub.image]);
|
.mockResolvedValue([assetStub.image]);
|
||||||
|
@ -404,7 +380,7 @@ describe(StorageTemplateService.name, () => {
|
||||||
expect(storageMock.rename).not.toHaveBeenCalled();
|
expect(storageMock.rename).not.toHaveBeenCalled();
|
||||||
expect(storageMock.copyFile).not.toHaveBeenCalled();
|
expect(storageMock.copyFile).not.toHaveBeenCalled();
|
||||||
expect(moveMock.update).not.toHaveBeenCalled();
|
expect(moveMock.update).not.toHaveBeenCalled();
|
||||||
expect(assetMock.save).not.toHaveBeenCalled();
|
expect(assetMock.update).not.toHaveBeenCalled();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -427,7 +403,6 @@ describe(StorageTemplateService.name, () => {
|
||||||
items: [assetStub.image],
|
items: [assetStub.image],
|
||||||
hasNextPage: false,
|
hasNextPage: false,
|
||||||
});
|
});
|
||||||
assetMock.save.mockResolvedValue(assetStub.image);
|
|
||||||
userMock.getList.mockResolvedValue([userStub.user1]);
|
userMock.getList.mockResolvedValue([userStub.user1]);
|
||||||
moveMock.create.mockResolvedValue({
|
moveMock.create.mockResolvedValue({
|
||||||
id: '123',
|
id: '123',
|
||||||
|
@ -449,7 +424,7 @@ describe(StorageTemplateService.name, () => {
|
||||||
|
|
||||||
expect(assetMock.getAll).toHaveBeenCalled();
|
expect(assetMock.getAll).toHaveBeenCalled();
|
||||||
expect(storageMock.checkFileExists).toHaveBeenCalledTimes(2);
|
expect(storageMock.checkFileExists).toHaveBeenCalledTimes(2);
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: assetStub.image.id,
|
id: assetStub.image.id,
|
||||||
originalPath: 'upload/library/user-id/2023/2023-02-23/asset-id+1.jpg',
|
originalPath: 'upload/library/user-id/2023/2023-02-23/asset-id+1.jpg',
|
||||||
});
|
});
|
||||||
|
@ -474,7 +449,7 @@ describe(StorageTemplateService.name, () => {
|
||||||
expect(storageMock.rename).not.toHaveBeenCalled();
|
expect(storageMock.rename).not.toHaveBeenCalled();
|
||||||
expect(storageMock.copyFile).not.toHaveBeenCalled();
|
expect(storageMock.copyFile).not.toHaveBeenCalled();
|
||||||
expect(storageMock.checkFileExists).not.toHaveBeenCalledTimes(2);
|
expect(storageMock.checkFileExists).not.toHaveBeenCalledTimes(2);
|
||||||
expect(assetMock.save).not.toHaveBeenCalled();
|
expect(assetMock.update).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should skip when an asset is probably a duplicate', async () => {
|
it('should skip when an asset is probably a duplicate', async () => {
|
||||||
|
@ -495,7 +470,7 @@ describe(StorageTemplateService.name, () => {
|
||||||
expect(storageMock.rename).not.toHaveBeenCalled();
|
expect(storageMock.rename).not.toHaveBeenCalled();
|
||||||
expect(storageMock.copyFile).not.toHaveBeenCalled();
|
expect(storageMock.copyFile).not.toHaveBeenCalled();
|
||||||
expect(storageMock.checkFileExists).not.toHaveBeenCalledTimes(2);
|
expect(storageMock.checkFileExists).not.toHaveBeenCalledTimes(2);
|
||||||
expect(assetMock.save).not.toHaveBeenCalled();
|
expect(assetMock.update).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should move an asset', async () => {
|
it('should move an asset', async () => {
|
||||||
|
@ -503,7 +478,6 @@ describe(StorageTemplateService.name, () => {
|
||||||
items: [assetStub.image],
|
items: [assetStub.image],
|
||||||
hasNextPage: false,
|
hasNextPage: false,
|
||||||
});
|
});
|
||||||
assetMock.save.mockResolvedValue(assetStub.image);
|
|
||||||
userMock.getList.mockResolvedValue([userStub.user1]);
|
userMock.getList.mockResolvedValue([userStub.user1]);
|
||||||
moveMock.create.mockResolvedValue({
|
moveMock.create.mockResolvedValue({
|
||||||
id: '123',
|
id: '123',
|
||||||
|
@ -520,7 +494,7 @@ describe(StorageTemplateService.name, () => {
|
||||||
'/original/path.jpg',
|
'/original/path.jpg',
|
||||||
'upload/library/user-id/2023/2023-02-23/asset-id.jpg',
|
'upload/library/user-id/2023/2023-02-23/asset-id.jpg',
|
||||||
);
|
);
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: assetStub.image.id,
|
id: assetStub.image.id,
|
||||||
originalPath: 'upload/library/user-id/2023/2023-02-23/asset-id.jpg',
|
originalPath: 'upload/library/user-id/2023/2023-02-23/asset-id.jpg',
|
||||||
});
|
});
|
||||||
|
@ -531,7 +505,6 @@ describe(StorageTemplateService.name, () => {
|
||||||
items: [assetStub.image],
|
items: [assetStub.image],
|
||||||
hasNextPage: false,
|
hasNextPage: false,
|
||||||
});
|
});
|
||||||
assetMock.save.mockResolvedValue(assetStub.image);
|
|
||||||
userMock.getList.mockResolvedValue([userStub.storageLabel]);
|
userMock.getList.mockResolvedValue([userStub.storageLabel]);
|
||||||
moveMock.create.mockResolvedValue({
|
moveMock.create.mockResolvedValue({
|
||||||
id: '123',
|
id: '123',
|
||||||
|
@ -548,7 +521,7 @@ describe(StorageTemplateService.name, () => {
|
||||||
'/original/path.jpg',
|
'/original/path.jpg',
|
||||||
'upload/library/label-1/2023/2023-02-23/asset-id.jpg',
|
'upload/library/label-1/2023/2023-02-23/asset-id.jpg',
|
||||||
);
|
);
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: assetStub.image.id,
|
id: assetStub.image.id,
|
||||||
originalPath: 'upload/library/label-1/2023/2023-02-23/asset-id.jpg',
|
originalPath: 'upload/library/label-1/2023/2023-02-23/asset-id.jpg',
|
||||||
});
|
});
|
||||||
|
@ -592,7 +565,7 @@ describe(StorageTemplateService.name, () => {
|
||||||
expect(storageMock.utimes).toHaveBeenCalledWith(newPath, expect.any(Date), expect.any(Date));
|
expect(storageMock.utimes).toHaveBeenCalledWith(newPath, expect.any(Date), expect.any(Date));
|
||||||
expect(storageMock.unlink).toHaveBeenCalledWith(assetStub.image.originalPath);
|
expect(storageMock.unlink).toHaveBeenCalledWith(assetStub.image.originalPath);
|
||||||
expect(storageMock.unlink).toHaveBeenCalledTimes(1);
|
expect(storageMock.unlink).toHaveBeenCalledTimes(1);
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.update).toHaveBeenCalledWith({
|
||||||
id: assetStub.image.id,
|
id: assetStub.image.id,
|
||||||
originalPath: newPath,
|
originalPath: newPath,
|
||||||
});
|
});
|
||||||
|
@ -630,7 +603,7 @@ describe(StorageTemplateService.name, () => {
|
||||||
'upload/library/user-id/2023/2023-02-23/asset-id.jpg',
|
'upload/library/user-id/2023/2023-02-23/asset-id.jpg',
|
||||||
);
|
);
|
||||||
expect(storageMock.stat).toHaveBeenCalledWith('upload/library/user-id/2023/2023-02-23/asset-id.jpg');
|
expect(storageMock.stat).toHaveBeenCalledWith('upload/library/user-id/2023/2023-02-23/asset-id.jpg');
|
||||||
expect(assetMock.save).not.toHaveBeenCalled();
|
expect(assetMock.update).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not update the database if the move fails', async () => {
|
it('should not update the database if the move fails', async () => {
|
||||||
|
@ -656,7 +629,7 @@ describe(StorageTemplateService.name, () => {
|
||||||
'/original/path.jpg',
|
'/original/path.jpg',
|
||||||
'upload/library/user-id/2023/2023-02-23/asset-id.jpg',
|
'upload/library/user-id/2023/2023-02-23/asset-id.jpg',
|
||||||
);
|
);
|
||||||
expect(assetMock.save).not.toHaveBeenCalled();
|
expect(assetMock.update).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not move read-only asset', async () => {
|
it('should not move read-only asset', async () => {
|
||||||
|
@ -670,7 +643,6 @@ describe(StorageTemplateService.name, () => {
|
||||||
],
|
],
|
||||||
hasNextPage: false,
|
hasNextPage: false,
|
||||||
});
|
});
|
||||||
assetMock.save.mockResolvedValue(assetStub.image);
|
|
||||||
userMock.getList.mockResolvedValue([userStub.user1]);
|
userMock.getList.mockResolvedValue([userStub.user1]);
|
||||||
|
|
||||||
await sut.handleMigration();
|
await sut.handleMigration();
|
||||||
|
@ -678,7 +650,7 @@ describe(StorageTemplateService.name, () => {
|
||||||
expect(assetMock.getAll).toHaveBeenCalled();
|
expect(assetMock.getAll).toHaveBeenCalled();
|
||||||
expect(storageMock.rename).not.toHaveBeenCalled();
|
expect(storageMock.rename).not.toHaveBeenCalled();
|
||||||
expect(storageMock.copyFile).not.toHaveBeenCalled();
|
expect(storageMock.copyFile).not.toHaveBeenCalled();
|
||||||
expect(assetMock.save).not.toHaveBeenCalled();
|
expect(assetMock.update).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -286,19 +286,19 @@ export class StorageCore {
|
||||||
private savePath(pathType: PathType, id: string, newPath: string) {
|
private savePath(pathType: PathType, id: string, newPath: string) {
|
||||||
switch (pathType) {
|
switch (pathType) {
|
||||||
case AssetPathType.ORIGINAL: {
|
case AssetPathType.ORIGINAL: {
|
||||||
return this.assetRepository.save({ id, originalPath: newPath });
|
return this.assetRepository.update({ id, originalPath: newPath });
|
||||||
}
|
}
|
||||||
case AssetPathType.JPEG_THUMBNAIL: {
|
case AssetPathType.JPEG_THUMBNAIL: {
|
||||||
return this.assetRepository.save({ id, resizePath: newPath });
|
return this.assetRepository.update({ id, resizePath: newPath });
|
||||||
}
|
}
|
||||||
case AssetPathType.WEBP_THUMBNAIL: {
|
case AssetPathType.WEBP_THUMBNAIL: {
|
||||||
return this.assetRepository.save({ id, webpPath: newPath });
|
return this.assetRepository.update({ id, webpPath: newPath });
|
||||||
}
|
}
|
||||||
case AssetPathType.ENCODED_VIDEO: {
|
case AssetPathType.ENCODED_VIDEO: {
|
||||||
return this.assetRepository.save({ id, encodedVideoPath: newPath });
|
return this.assetRepository.update({ id, encodedVideoPath: newPath });
|
||||||
}
|
}
|
||||||
case AssetPathType.SIDECAR: {
|
case AssetPathType.SIDECAR: {
|
||||||
return this.assetRepository.save({ id, sidecarPath: newPath });
|
return this.assetRepository.update({ id, sidecarPath: newPath });
|
||||||
}
|
}
|
||||||
case PersonPathType.FACE: {
|
case PersonPathType.FACE: {
|
||||||
return this.personRepository.update({ id, thumbnailPath: newPath });
|
return this.personRepository.update({ id, thumbnailPath: newPath });
|
||||||
|
|
|
@ -6,6 +6,8 @@ import {
|
||||||
AssetSearchOptions,
|
AssetSearchOptions,
|
||||||
AssetStats,
|
AssetStats,
|
||||||
AssetStatsOptions,
|
AssetStatsOptions,
|
||||||
|
AssetUpdateAllOptions,
|
||||||
|
AssetUpdateOptions,
|
||||||
IAssetRepository,
|
IAssetRepository,
|
||||||
LivePhotoSearchOptions,
|
LivePhotoSearchOptions,
|
||||||
MapMarker,
|
MapMarker,
|
||||||
|
@ -275,7 +277,7 @@ export class AssetRepository implements IAssetRepository {
|
||||||
|
|
||||||
@GenerateSql({ params: [[DummyValue.UUID], { deviceId: DummyValue.STRING }] })
|
@GenerateSql({ params: [[DummyValue.UUID], { deviceId: DummyValue.STRING }] })
|
||||||
@Chunked()
|
@Chunked()
|
||||||
async updateAll(ids: string[], options: Partial<AssetEntity>): Promise<void> {
|
async updateAll(ids: string[], options: AssetUpdateAllOptions): Promise<void> {
|
||||||
await this.repository.update({ id: In(ids) }, options);
|
await this.repository.update({ id: In(ids) }, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,21 +291,8 @@ export class AssetRepository implements IAssetRepository {
|
||||||
await this.repository.restore({ id: In(ids) });
|
await this.repository.restore({ id: In(ids) });
|
||||||
}
|
}
|
||||||
|
|
||||||
async save(asset: Partial<AssetEntity>): Promise<AssetEntity> {
|
async update(asset: AssetUpdateOptions): Promise<void> {
|
||||||
const { id } = await this.repository.save(asset);
|
await this.repository.update(asset.id, asset);
|
||||||
return this.repository.findOneOrFail({
|
|
||||||
where: { id },
|
|
||||||
relations: {
|
|
||||||
exifInfo: true,
|
|
||||||
owner: true,
|
|
||||||
smartInfo: true,
|
|
||||||
tags: true,
|
|
||||||
faces: {
|
|
||||||
person: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
withDeleted: true,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async remove(asset: AssetEntity): Promise<void> {
|
async remove(asset: AssetEntity): Promise<void> {
|
||||||
|
|
|
@ -24,7 +24,7 @@ export const newAssetRepositoryMock = (): jest.Mocked<IAssetRepository> => {
|
||||||
getLibraryAssetPaths: jest.fn(),
|
getLibraryAssetPaths: jest.fn(),
|
||||||
getByLibraryIdAndOriginalPath: jest.fn(),
|
getByLibraryIdAndOriginalPath: jest.fn(),
|
||||||
deleteAll: jest.fn(),
|
deleteAll: jest.fn(),
|
||||||
save: jest.fn(),
|
update: jest.fn(),
|
||||||
remove: jest.fn(),
|
remove: jest.fn(),
|
||||||
findLivePhotoMatch: jest.fn(),
|
findLivePhotoMatch: jest.fn(),
|
||||||
getMapMarkers: jest.fn(),
|
getMapMarkers: jest.fn(),
|
||||||
|
|
Loading…
Reference in a new issue