fix(server): live photo match library (#32080)
(cherry picked from commit 05658ecba8679f54c4b95deeec3940b54ab0ecf7)
This commit is contained in:
@@ -698,13 +698,14 @@ export class AssetRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
findLivePhotoMatch(options: LivePhotoSearchOptions) {
|
findLivePhotoMatch(options: LivePhotoSearchOptions) {
|
||||||
const { ownerId, otherAssetId, livePhotoCID, type } = options;
|
const { ownerId, libraryId, otherAssetId, livePhotoCID, type } = options;
|
||||||
return this.db
|
return this.db
|
||||||
.selectFrom('asset')
|
.selectFrom('asset')
|
||||||
.select(['asset.id', 'asset.ownerId'])
|
.select(['asset.id', 'asset.ownerId'])
|
||||||
.innerJoin('asset_exif', 'asset.id', 'asset_exif.assetId')
|
.innerJoin('asset_exif', 'asset.id', 'asset_exif.assetId')
|
||||||
.where('id', '!=', asUuid(otherAssetId))
|
.where('id', '!=', asUuid(otherAssetId))
|
||||||
.where('ownerId', '=', asUuid(ownerId))
|
.where('ownerId', '=', asUuid(ownerId))
|
||||||
|
.$call((qb) => (libraryId ? qb.where('libraryId', '=', asUuid(libraryId)) : qb.where('libraryId', 'is', null)))
|
||||||
.where('type', '=', type)
|
.where('type', '=', type)
|
||||||
.where('asset_exif.livePhotoCID', '=', livePhotoCID)
|
.where('asset_exif.livePhotoCID', '=', livePhotoCID)
|
||||||
.limit(1)
|
.limit(1)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { AssetFileType, AssetOrder, AssetOrderBy, AssetVisibility } from 'src/enum.js';
|
import { AssetFileType, AssetOrder, AssetOrderBy, AssetType, AssetVisibility } from 'src/enum.js';
|
||||||
import { AssetRepository } from 'src/repositories/asset.repository.js';
|
import { AssetRepository } from 'src/repositories/asset.repository.js';
|
||||||
|
import { LibraryRepository } from 'src/repositories/library.repository.js';
|
||||||
import { LoggingRepository } from 'src/repositories/logging.repository.js';
|
import { LoggingRepository } from 'src/repositories/logging.repository.js';
|
||||||
import { DB } from 'src/schema/index.js';
|
import { DB } from 'src/schema/index.js';
|
||||||
import { BaseService } from 'src/services/base.service.js';
|
import { BaseService } from 'src/services/base.service.js';
|
||||||
@@ -564,6 +565,60 @@ describe(AssetRepository.name, () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('findLivePhotoMatch', () => {
|
||||||
|
type LibraryKind = 'upload' | 'external' | 'other external';
|
||||||
|
|
||||||
|
const setupLivePhoto = async ({ still, motion }: { still: LibraryKind; motion: LibraryKind }) => {
|
||||||
|
const { ctx, sut } = setup();
|
||||||
|
const { user } = await ctx.newUser();
|
||||||
|
const newLibrary = () =>
|
||||||
|
ctx
|
||||||
|
.get(LibraryRepository)
|
||||||
|
.create({ ownerId: user.id, name: 'library', importPaths: [], exclusionPatterns: [] });
|
||||||
|
const [external, otherExternal] = await Promise.all([newLibrary(), newLibrary()]);
|
||||||
|
const libraryIds = { upload: null, external: external.id, 'other external': otherExternal.id };
|
||||||
|
const livePhotoCID = 'live-photo-cid';
|
||||||
|
|
||||||
|
const [{ asset: stillAsset }, { asset: motionAsset }] = await Promise.all([
|
||||||
|
ctx.newAsset({ ownerId: user.id, type: AssetType.Image, libraryId: libraryIds[still] }),
|
||||||
|
ctx.newAsset({ ownerId: user.id, type: AssetType.Video, libraryId: libraryIds[motion] }),
|
||||||
|
]);
|
||||||
|
await Promise.all([
|
||||||
|
ctx.newExif({ assetId: stillAsset.id, livePhotoCID }),
|
||||||
|
ctx.newExif({ assetId: motionAsset.id, livePhotoCID }),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const match = await sut.findLivePhotoMatch({
|
||||||
|
ownerId: user.id,
|
||||||
|
libraryId: libraryIds[still],
|
||||||
|
livePhotoCID,
|
||||||
|
otherAssetId: stillAsset.id,
|
||||||
|
type: AssetType.Video,
|
||||||
|
});
|
||||||
|
|
||||||
|
return { match, motionAsset };
|
||||||
|
};
|
||||||
|
|
||||||
|
it.each<LibraryKind>(['upload', 'external'])(
|
||||||
|
'should match a motion video in the same %s library',
|
||||||
|
async (library) => {
|
||||||
|
const { match, motionAsset } = await setupLivePhoto({ still: library, motion: library });
|
||||||
|
|
||||||
|
expect(match).toEqual({ id: motionAsset.id, ownerId: motionAsset.ownerId });
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
it.each<{ still: LibraryKind; motion: LibraryKind }>([
|
||||||
|
{ still: 'upload', motion: 'external' },
|
||||||
|
{ still: 'external', motion: 'upload' },
|
||||||
|
{ still: 'external', motion: 'other external' },
|
||||||
|
])('should not match a still in the $still library to a motion video in the $motion library', async (libraries) => {
|
||||||
|
const { match } = await setupLivePhoto(libraries);
|
||||||
|
|
||||||
|
expect(match).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('createAll', () => {
|
describe('createAll', () => {
|
||||||
it('should return an empty array when given an empty input', async () => {
|
it('should return an empty array when given an empty input', async () => {
|
||||||
const { sut } = setup();
|
const { sut } = setup();
|
||||||
|
|||||||
Reference in New Issue
Block a user