From b6f18cbe81120a8a4dded96e0d83967caf0de20f Mon Sep 17 00:00:00 2001 From: Michael Manganiello Date: Tue, 31 Oct 2023 06:08:34 -0400 Subject: [PATCH] fix(server): Correctly set album start and end dates (#4698) * fix(server): Correctly set album start and end dates Currently, the query that retrieves album assets uses `ORDER BY assets.fileCreatedAt DESC`, which makes the existing logic return the start/end dates reversed (with `startDate` being taken from the first asset in the array). Instead of using the index-based approach, this change iterates through assets to get the min/max `fileCreatedAt`. This will avoid any future issues, if the query ordering changes, or becomes customizable (e.g. in case the user prefers to visualize older assets first). * fix: Maintain constant cost and only swap variables if needed --- .../src/domain/album/album-response.dto.spec.ts | 16 ++++++++++++++++ server/src/domain/album/album-response.dto.ts | 13 +++++++++++-- .../src/domain/metadata/metadata.service.spec.ts | 2 +- server/test/fixtures/asset.stub.ts | 10 +++++----- 4 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 server/src/domain/album/album-response.dto.spec.ts diff --git a/server/src/domain/album/album-response.dto.spec.ts b/server/src/domain/album/album-response.dto.spec.ts new file mode 100644 index 000000000..c8485af65 --- /dev/null +++ b/server/src/domain/album/album-response.dto.spec.ts @@ -0,0 +1,16 @@ +import { albumStub } from '@test'; +import { mapAlbum } from './album-response.dto'; + +describe('mapAlbum', () => { + it('should set start and end dates', () => { + const dto = mapAlbum(albumStub.twoAssets, false); + expect(dto.startDate).toEqual(new Date('2023-02-22T05:06:29.716Z')); + expect(dto.endDate).toEqual(new Date('2023-02-23T05:06:29.716Z')); + }); + + it('should not set start and end dates for empty assets', () => { + const dto = mapAlbum(albumStub.empty, false); + expect(dto.startDate).toBeUndefined(); + expect(dto.endDate).toBeUndefined(); + }); +}); diff --git a/server/src/domain/album/album-response.dto.ts b/server/src/domain/album/album-response.dto.ts index 9f0e134c7..b426bc37d 100644 --- a/server/src/domain/album/album-response.dto.ts +++ b/server/src/domain/album/album-response.dto.ts @@ -36,6 +36,15 @@ export const mapAlbum = (entity: AlbumEntity, withAssets: boolean): AlbumRespons const hasSharedLink = entity.sharedLinks?.length > 0; const hasSharedUser = sharedUsers.length > 0; + let startDate = assets.at(0)?.fileCreatedAt || undefined; + let endDate = assets.at(-1)?.fileCreatedAt || undefined; + // Swap dates if start date is greater than end date. + if (startDate && endDate && startDate > endDate) { + const temp = startDate; + startDate = endDate; + endDate = temp; + } + return { albumName: entity.albumName, description: entity.description, @@ -48,8 +57,8 @@ export const mapAlbum = (entity: AlbumEntity, withAssets: boolean): AlbumRespons sharedUsers, shared: hasSharedUser || hasSharedLink, hasSharedLink, - startDate: assets.at(0)?.fileCreatedAt || undefined, - endDate: assets.at(-1)?.fileCreatedAt || undefined, + startDate, + endDate, assets: (withAssets ? assets : []).map((asset) => mapAsset(asset)), assetCount: entity.assets?.length || 0, }; diff --git a/server/src/domain/metadata/metadata.service.spec.ts b/server/src/domain/metadata/metadata.service.spec.ts index 86befcee8..e6ca7f199 100644 --- a/server/src/domain/metadata/metadata.service.spec.ts +++ b/server/src/domain/metadata/metadata.service.spec.ts @@ -277,7 +277,7 @@ describe(MetadataService.name, () => { id: assetStub.withLocation.id, duration: null, fileCreatedAt: assetStub.withLocation.createdAt, - localDateTime: new Date('2023-02-23T05:06:29.716Z'), + localDateTime: new Date('2023-02-22T05:06:29.716Z'), }); }); diff --git a/server/test/fixtures/asset.stub.ts b/server/test/fixtures/asset.stub.ts index 345481843..4c6288c40 100644 --- a/server/test/fixtures/asset.stub.ts +++ b/server/test/fixtures/asset.stub.ts @@ -434,8 +434,8 @@ export const assetStub = { withLocation: Object.freeze({ id: 'asset-with-favorite-id', deviceAssetId: 'device-asset-id', - fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'), - fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'), + fileModifiedAt: new Date('2023-02-22T05:06:29.716Z'), + fileCreatedAt: new Date('2023-02-22T05:06:29.716Z'), owner: userStub.user1, ownerId: 'user-id', deviceId: 'device-id', @@ -447,9 +447,9 @@ export const assetStub = { webpPath: null, thumbhash: null, encodedVideoPath: null, - createdAt: new Date('2023-02-23T05:06:29.716Z'), - updatedAt: new Date('2023-02-23T05:06:29.716Z'), - localDateTime: new Date('2023-02-23T05:06:29.716Z'), + createdAt: new Date('2023-02-22T05:06:29.716Z'), + updatedAt: new Date('2023-02-22T05:06:29.716Z'), + localDateTime: new Date('2023-02-22T05:06:29.716Z'), isFavorite: false, isArchived: false, isReadOnly: false,