mirror of
https://github.com/samsonjs/immich.git
synced 2026-04-27 15:07:45 +00:00
refactor: asset update medium tests (#24718)
This commit is contained in:
parent
50d7956c07
commit
3d2196b0f2
2 changed files with 180 additions and 81 deletions
|
|
@ -0,0 +1,90 @@
|
||||||
|
import { Kysely } from 'kysely';
|
||||||
|
import { AssetRepository } from 'src/repositories/asset.repository';
|
||||||
|
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { BaseService } from 'src/services/base.service';
|
||||||
|
import { newMediumService } from 'test/medium.factory';
|
||||||
|
import { getKyselyDB } from 'test/utils';
|
||||||
|
|
||||||
|
let defaultDatabase: Kysely<DB>;
|
||||||
|
|
||||||
|
const setup = (db?: Kysely<DB>) => {
|
||||||
|
const { ctx } = newMediumService(BaseService, {
|
||||||
|
database: db || defaultDatabase,
|
||||||
|
real: [],
|
||||||
|
mock: [LoggingRepository],
|
||||||
|
});
|
||||||
|
return { ctx, sut: ctx.get(AssetRepository) };
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
defaultDatabase = await getKyselyDB();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(AssetRepository.name, () => {
|
||||||
|
describe('upsertExif', () => {
|
||||||
|
it('should append to locked columns', async () => {
|
||||||
|
const { ctx, sut } = setup();
|
||||||
|
const { user } = await ctx.newUser();
|
||||||
|
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
||||||
|
await ctx.newExif({
|
||||||
|
assetId: asset.id,
|
||||||
|
dateTimeOriginal: '2023-11-19T18:11:00',
|
||||||
|
lockedProperties: ['dateTimeOriginal'],
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
ctx.database
|
||||||
|
.selectFrom('asset_exif')
|
||||||
|
.select('lockedProperties')
|
||||||
|
.where('assetId', '=', asset.id)
|
||||||
|
.executeTakeFirstOrThrow(),
|
||||||
|
).resolves.toEqual({ lockedProperties: ['dateTimeOriginal'] });
|
||||||
|
|
||||||
|
await sut.upsertExif(
|
||||||
|
{ assetId: asset.id, lockedProperties: ['description'] },
|
||||||
|
{ lockedPropertiesBehavior: 'append' },
|
||||||
|
);
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
ctx.database
|
||||||
|
.selectFrom('asset_exif')
|
||||||
|
.select('lockedProperties')
|
||||||
|
.where('assetId', '=', asset.id)
|
||||||
|
.executeTakeFirstOrThrow(),
|
||||||
|
).resolves.toEqual({ lockedProperties: ['description', 'dateTimeOriginal'] });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should deduplicate locked columns', async () => {
|
||||||
|
const { ctx, sut } = setup();
|
||||||
|
const { user } = await ctx.newUser();
|
||||||
|
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
||||||
|
await ctx.newExif({
|
||||||
|
assetId: asset.id,
|
||||||
|
dateTimeOriginal: '2023-11-19T18:11:00',
|
||||||
|
lockedProperties: ['dateTimeOriginal', 'description'],
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
ctx.database
|
||||||
|
.selectFrom('asset_exif')
|
||||||
|
.select('lockedProperties')
|
||||||
|
.where('assetId', '=', asset.id)
|
||||||
|
.executeTakeFirstOrThrow(),
|
||||||
|
).resolves.toEqual({ lockedProperties: ['dateTimeOriginal', 'description'] });
|
||||||
|
|
||||||
|
await sut.upsertExif(
|
||||||
|
{ assetId: asset.id, lockedProperties: ['description'] },
|
||||||
|
{ lockedPropertiesBehavior: 'append' },
|
||||||
|
);
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
ctx.database
|
||||||
|
.selectFrom('asset_exif')
|
||||||
|
.select('lockedProperties')
|
||||||
|
.where('assetId', '=', asset.id)
|
||||||
|
.executeTakeFirstOrThrow(),
|
||||||
|
).resolves.toEqual({ lockedProperties: ['description', 'dateTimeOriginal'] });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -270,13 +270,13 @@ describe(AssetService.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('update', () => {
|
describe('update', () => {
|
||||||
it('should update dateTimeOriginal', async () => {
|
it('should automatically lock lockable columns', async () => {
|
||||||
const { sut, ctx } = setup();
|
const { sut, ctx } = setup();
|
||||||
ctx.getMock(JobRepository).queue.mockResolvedValue();
|
ctx.getMock(JobRepository).queue.mockResolvedValue();
|
||||||
const { user } = await ctx.newUser();
|
const { user } = await ctx.newUser();
|
||||||
const auth = factory.auth({ user });
|
const auth = factory.auth({ user });
|
||||||
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
||||||
await ctx.newExif({ assetId: asset.id, description: 'test' });
|
await ctx.newExif({ assetId: asset.id, dateTimeOriginal: '2023-11-19T18:11:00' });
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
ctx.database
|
ctx.database
|
||||||
|
|
@ -285,7 +285,14 @@ describe(AssetService.name, () => {
|
||||||
.where('assetId', '=', asset.id)
|
.where('assetId', '=', asset.id)
|
||||||
.executeTakeFirstOrThrow(),
|
.executeTakeFirstOrThrow(),
|
||||||
).resolves.toEqual({ lockedProperties: null });
|
).resolves.toEqual({ lockedProperties: null });
|
||||||
await sut.update(auth, asset.id, { dateTimeOriginal: '2023-11-19T18:11:00' });
|
|
||||||
|
await sut.update(auth, asset.id, {
|
||||||
|
latitude: 42,
|
||||||
|
longitude: 42,
|
||||||
|
rating: 3,
|
||||||
|
description: 'foo',
|
||||||
|
dateTimeOriginal: '2023-11-19T18:11:00+01:00',
|
||||||
|
});
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
ctx.database
|
ctx.database
|
||||||
|
|
@ -293,7 +300,21 @@ describe(AssetService.name, () => {
|
||||||
.select('lockedProperties')
|
.select('lockedProperties')
|
||||||
.where('assetId', '=', asset.id)
|
.where('assetId', '=', asset.id)
|
||||||
.executeTakeFirstOrThrow(),
|
.executeTakeFirstOrThrow(),
|
||||||
).resolves.toEqual({ lockedProperties: ['dateTimeOriginal'] });
|
).resolves.toEqual({
|
||||||
|
lockedProperties: ['timeZone', 'rating', 'description', 'latitude', 'longitude', 'dateTimeOriginal'],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update dateTimeOriginal', async () => {
|
||||||
|
const { sut, ctx } = setup();
|
||||||
|
ctx.getMock(JobRepository).queue.mockResolvedValue();
|
||||||
|
const { user } = await ctx.newUser();
|
||||||
|
const auth = factory.auth({ user });
|
||||||
|
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
||||||
|
await ctx.newExif({ assetId: asset.id, description: 'test' });
|
||||||
|
|
||||||
|
await sut.update(auth, asset.id, { dateTimeOriginal: '2023-11-19T18:11:00' });
|
||||||
|
|
||||||
await expect(ctx.get(AssetRepository).getById(asset.id, { exifInfo: true })).resolves.toEqual(
|
await expect(ctx.get(AssetRepository).getById(asset.id, { exifInfo: true })).resolves.toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
exifInfo: expect.objectContaining({ dateTimeOriginal: '2023-11-19T18:11:00+00:00', timeZone: null }),
|
exifInfo: expect.objectContaining({ dateTimeOriginal: '2023-11-19T18:11:00+00:00', timeZone: null }),
|
||||||
|
|
@ -309,22 +330,8 @@ describe(AssetService.name, () => {
|
||||||
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
||||||
await ctx.newExif({ assetId: asset.id, description: 'test' });
|
await ctx.newExif({ assetId: asset.id, description: 'test' });
|
||||||
|
|
||||||
await expect(
|
|
||||||
ctx.database
|
|
||||||
.selectFrom('asset_exif')
|
|
||||||
.select('lockedProperties')
|
|
||||||
.where('assetId', '=', asset.id)
|
|
||||||
.executeTakeFirstOrThrow(),
|
|
||||||
).resolves.toEqual({ lockedProperties: null });
|
|
||||||
await sut.update(auth, asset.id, { dateTimeOriginal: '2023-11-19T18:11:00.000-07:00' });
|
await sut.update(auth, asset.id, { dateTimeOriginal: '2023-11-19T18:11:00.000-07:00' });
|
||||||
|
|
||||||
await expect(
|
|
||||||
ctx.database
|
|
||||||
.selectFrom('asset_exif')
|
|
||||||
.select('lockedProperties')
|
|
||||||
.where('assetId', '=', asset.id)
|
|
||||||
.executeTakeFirstOrThrow(),
|
|
||||||
).resolves.toEqual({ lockedProperties: ['timeZone', 'dateTimeOriginal'] });
|
|
||||||
await expect(ctx.get(AssetRepository).getById(asset.id, { exifInfo: true })).resolves.toEqual(
|
await expect(ctx.get(AssetRepository).getById(asset.id, { exifInfo: true })).resolves.toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
exifInfo: expect.objectContaining({ dateTimeOriginal: '2023-11-20T01:11:00+00:00', timeZone: 'UTC-7' }),
|
exifInfo: expect.objectContaining({ dateTimeOriginal: '2023-11-20T01:11:00+00:00', timeZone: 'UTC-7' }),
|
||||||
|
|
@ -334,6 +341,42 @@ describe(AssetService.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('updateAll', () => {
|
describe('updateAll', () => {
|
||||||
|
it('should automatically lock lockable columns', async () => {
|
||||||
|
const { sut, ctx } = setup();
|
||||||
|
ctx.getMock(JobRepository).queueAll.mockResolvedValue();
|
||||||
|
const { user } = await ctx.newUser();
|
||||||
|
const auth = factory.auth({ user });
|
||||||
|
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
||||||
|
await ctx.newExif({ assetId: asset.id, dateTimeOriginal: '2023-11-19T18:11:00' });
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
ctx.database
|
||||||
|
.selectFrom('asset_exif')
|
||||||
|
.select('lockedProperties')
|
||||||
|
.where('assetId', '=', asset.id)
|
||||||
|
.executeTakeFirstOrThrow(),
|
||||||
|
).resolves.toEqual({ lockedProperties: null });
|
||||||
|
|
||||||
|
await sut.updateAll(auth, {
|
||||||
|
ids: [asset.id],
|
||||||
|
latitude: 42,
|
||||||
|
description: 'foo',
|
||||||
|
longitude: 42,
|
||||||
|
rating: 3,
|
||||||
|
dateTimeOriginal: '2023-11-19T18:11:00+01:00',
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
ctx.database
|
||||||
|
.selectFrom('asset_exif')
|
||||||
|
.select('lockedProperties')
|
||||||
|
.where('assetId', '=', asset.id)
|
||||||
|
.executeTakeFirstOrThrow(),
|
||||||
|
).resolves.toEqual({
|
||||||
|
lockedProperties: ['timeZone', 'rating', 'description', 'latitude', 'longitude', 'dateTimeOriginal'],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should relatively update assets', async () => {
|
it('should relatively update assets', async () => {
|
||||||
const { sut, ctx } = setup();
|
const { sut, ctx } = setup();
|
||||||
ctx.getMock(JobRepository).queueAll.mockResolvedValue();
|
ctx.getMock(JobRepository).queueAll.mockResolvedValue();
|
||||||
|
|
@ -344,13 +387,6 @@ describe(AssetService.name, () => {
|
||||||
|
|
||||||
await sut.updateAll(auth, { ids: [asset.id], dateTimeRelative: -11 });
|
await sut.updateAll(auth, { ids: [asset.id], dateTimeRelative: -11 });
|
||||||
|
|
||||||
await expect(
|
|
||||||
ctx.database
|
|
||||||
.selectFrom('asset_exif')
|
|
||||||
.select('lockedProperties')
|
|
||||||
.where('assetId', '=', asset.id)
|
|
||||||
.executeTakeFirstOrThrow(),
|
|
||||||
).resolves.toEqual({ lockedProperties: ['timeZone', 'dateTimeOriginal'] });
|
|
||||||
await expect(ctx.get(AssetRepository).getById(asset.id, { exifInfo: true })).resolves.toEqual(
|
await expect(ctx.get(AssetRepository).getById(asset.id, { exifInfo: true })).resolves.toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
exifInfo: expect.objectContaining({
|
exifInfo: expect.objectContaining({
|
||||||
|
|
@ -359,66 +395,39 @@ describe(AssetService.name, () => {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
it('should update dateTimeOriginal', async () => {
|
it('should update dateTimeOriginal', async () => {
|
||||||
const { sut, ctx } = setup();
|
const { sut, ctx } = setup();
|
||||||
ctx.getMock(JobRepository).queueAll.mockResolvedValue();
|
ctx.getMock(JobRepository).queueAll.mockResolvedValue();
|
||||||
const { user } = await ctx.newUser();
|
const { user } = await ctx.newUser();
|
||||||
const auth = factory.auth({ user });
|
const auth = factory.auth({ user });
|
||||||
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
||||||
await ctx.newExif({ assetId: asset.id, description: 'test' });
|
await ctx.newExif({ assetId: asset.id, description: 'test' });
|
||||||
|
|
||||||
await expect(
|
await sut.updateAll(auth, { ids: [asset.id], dateTimeOriginal: '2023-11-19T18:11:00' });
|
||||||
ctx.database
|
|
||||||
.selectFrom('asset_exif')
|
|
||||||
.select('lockedProperties')
|
|
||||||
.where('assetId', '=', asset.id)
|
|
||||||
.executeTakeFirstOrThrow(),
|
|
||||||
).resolves.toEqual({ lockedProperties: null });
|
|
||||||
await sut.updateAll(auth, { ids: [asset.id], dateTimeOriginal: '2023-11-19T18:11:00' });
|
|
||||||
|
|
||||||
await expect(
|
await expect(ctx.get(AssetRepository).getById(asset.id, { exifInfo: true })).resolves.toEqual(
|
||||||
ctx.database
|
expect.objectContaining({
|
||||||
.selectFrom('asset_exif')
|
exifInfo: expect.objectContaining({ dateTimeOriginal: '2023-11-19T18:11:00+00:00', timeZone: null }),
|
||||||
.select('lockedProperties')
|
}),
|
||||||
.where('assetId', '=', asset.id)
|
);
|
||||||
.executeTakeFirstOrThrow(),
|
});
|
||||||
).resolves.toEqual({ lockedProperties: ['dateTimeOriginal'] });
|
|
||||||
await expect(ctx.get(AssetRepository).getById(asset.id, { exifInfo: true })).resolves.toEqual(
|
|
||||||
expect.objectContaining({
|
|
||||||
exifInfo: expect.objectContaining({ dateTimeOriginal: '2023-11-19T18:11:00+00:00', timeZone: null }),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update dateTimeOriginal with time zone', async () => {
|
it('should update dateTimeOriginal with time zone', async () => {
|
||||||
const { sut, ctx } = setup();
|
const { sut, ctx } = setup();
|
||||||
ctx.getMock(JobRepository).queueAll.mockResolvedValue();
|
ctx.getMock(JobRepository).queueAll.mockResolvedValue();
|
||||||
const { user } = await ctx.newUser();
|
const { user } = await ctx.newUser();
|
||||||
const auth = factory.auth({ user });
|
const auth = factory.auth({ user });
|
||||||
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
||||||
await ctx.newExif({ assetId: asset.id, description: 'test' });
|
await ctx.newExif({ assetId: asset.id, description: 'test' });
|
||||||
|
|
||||||
await expect(
|
await sut.updateAll(auth, { ids: [asset.id], dateTimeOriginal: '2023-11-19T18:11:00.000-07:00' });
|
||||||
ctx.database
|
|
||||||
.selectFrom('asset_exif')
|
await expect(ctx.get(AssetRepository).getById(asset.id, { exifInfo: true })).resolves.toEqual(
|
||||||
.select('lockedProperties')
|
expect.objectContaining({
|
||||||
.where('assetId', '=', asset.id)
|
exifInfo: expect.objectContaining({ dateTimeOriginal: '2023-11-20T01:11:00+00:00', timeZone: 'UTC-7' }),
|
||||||
.executeTakeFirstOrThrow(),
|
}),
|
||||||
).resolves.toEqual({ lockedProperties: null });
|
);
|
||||||
await sut.updateAll(auth, { ids: [asset.id], dateTimeOriginal: '2023-11-19T18:11:00.000-07:00' });
|
});
|
||||||
await expect(
|
|
||||||
ctx.database
|
|
||||||
.selectFrom('asset_exif')
|
|
||||||
.select('lockedProperties')
|
|
||||||
.where('assetId', '=', asset.id)
|
|
||||||
.executeTakeFirstOrThrow(),
|
|
||||||
).resolves.toEqual({ lockedProperties: ['timeZone', 'dateTimeOriginal'] });
|
|
||||||
await expect(ctx.get(AssetRepository).getById(asset.id, { exifInfo: true })).resolves.toEqual(
|
|
||||||
expect.objectContaining({
|
|
||||||
exifInfo: expect.objectContaining({ dateTimeOriginal: '2023-11-20T01:11:00+00:00', timeZone: 'UTC-7' }),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue