mirror of
https://github.com/immich-app/immich.git
synced 2026-05-18 03:10:24 +03:00
Merge branch 'main' into feat/mobile-ocr
This commit is contained in:
@@ -115,4 +115,33 @@ describe(AssetJobRepository.name, () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getForOcr', () => {
|
||||
it('should not return the edited preview file', async () => {
|
||||
const { ctx, sut } = setup();
|
||||
const { user } = await ctx.newUser();
|
||||
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
||||
|
||||
await ctx.newAssetFile({
|
||||
assetId: asset.id,
|
||||
type: AssetFileType.Preview,
|
||||
path: 'preview_edited.jpg',
|
||||
isEdited: true,
|
||||
});
|
||||
await ctx.newAssetFile({
|
||||
assetId: asset.id,
|
||||
type: AssetFileType.Preview,
|
||||
path: 'preview_unedited.jpg',
|
||||
isEdited: false,
|
||||
});
|
||||
|
||||
const result = await sut.getForOcr(asset.id);
|
||||
|
||||
expect(result).toEqual(
|
||||
expect.objectContaining({
|
||||
previewFile: 'preview_unedited.jpg',
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,6 +5,7 @@ import { AccessRepository } from 'src/repositories/access.repository';
|
||||
import { AssetEditRepository } from 'src/repositories/asset-edit.repository';
|
||||
import { AssetRepository } from 'src/repositories/asset.repository';
|
||||
import { DatabaseRepository } from 'src/repositories/database.repository';
|
||||
import { JobRepository } from 'src/repositories/job.repository';
|
||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||
import { PersonRepository } from 'src/repositories/person.repository';
|
||||
import { StorageRepository } from 'src/repositories/storage.repository';
|
||||
@@ -20,7 +21,7 @@ const setup = (db?: Kysely<DB>) => {
|
||||
return newMediumService(PersonService, {
|
||||
database: db || defaultDatabase,
|
||||
real: [AccessRepository, DatabaseRepository, PersonRepository, AssetRepository, AssetEditRepository],
|
||||
mock: [LoggingRepository, StorageRepository],
|
||||
mock: [JobRepository, LoggingRepository, StorageRepository],
|
||||
});
|
||||
};
|
||||
|
||||
@@ -89,6 +90,7 @@ describe(PersonService.name, () => {
|
||||
const { person } = await ctx.newPerson({ ownerId: user.id });
|
||||
const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 200, height: 200 });
|
||||
await ctx.newExif({ assetId: asset.id, exifImageHeight: 200, exifImageWidth: 200 });
|
||||
ctx.getMock(JobRepository).queueAll.mockResolvedValue();
|
||||
|
||||
const auth = factory.auth({ user });
|
||||
|
||||
@@ -128,6 +130,7 @@ describe(PersonService.name, () => {
|
||||
const { person } = await ctx.newPerson({ ownerId: user.id });
|
||||
const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 150, height: 200 });
|
||||
await ctx.newExif({ assetId: asset.id, exifImageHeight: 200, exifImageWidth: 200 });
|
||||
ctx.getMock(JobRepository).queueAll.mockResolvedValue();
|
||||
|
||||
await ctx.newEdits(asset.id, {
|
||||
edits: [
|
||||
@@ -199,6 +202,7 @@ describe(PersonService.name, () => {
|
||||
const { person } = await ctx.newPerson({ ownerId: user.id });
|
||||
const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 100, height: 200 });
|
||||
await ctx.newExif({ assetId: asset.id, exifImageWidth: 200, exifImageHeight: 100 });
|
||||
ctx.getMock(JobRepository).queueAll.mockResolvedValue();
|
||||
|
||||
await ctx.newEdits(asset.id, {
|
||||
edits: [
|
||||
@@ -263,6 +267,7 @@ describe(PersonService.name, () => {
|
||||
const { person } = await ctx.newPerson({ ownerId: user.id });
|
||||
const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 200, height: 100 });
|
||||
await ctx.newExif({ assetId: asset.id, exifImageHeight: 100, exifImageWidth: 200 });
|
||||
ctx.getMock(JobRepository).queueAll.mockResolvedValue();
|
||||
|
||||
await ctx.newEdits(asset.id, {
|
||||
edits: [
|
||||
@@ -327,6 +332,7 @@ describe(PersonService.name, () => {
|
||||
const { person } = await ctx.newPerson({ ownerId: user.id });
|
||||
const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 200, height: 150 });
|
||||
await ctx.newExif({ assetId: asset.id, exifImageHeight: 200, exifImageWidth: 200 });
|
||||
ctx.getMock(JobRepository).queueAll.mockResolvedValue();
|
||||
|
||||
await ctx.newEdits(asset.id, {
|
||||
edits: [
|
||||
@@ -400,6 +406,7 @@ describe(PersonService.name, () => {
|
||||
const { person } = await ctx.newPerson({ ownerId: user.id });
|
||||
const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 150, height: 100 });
|
||||
await ctx.newExif({ assetId: asset.id, exifImageHeight: 100, exifImageWidth: 200 });
|
||||
ctx.getMock(JobRepository).queueAll.mockResolvedValue();
|
||||
|
||||
await ctx.newEdits(asset.id, {
|
||||
edits: [
|
||||
@@ -473,6 +480,7 @@ describe(PersonService.name, () => {
|
||||
const { person } = await ctx.newPerson({ ownerId: user.id });
|
||||
const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 200, height: 150 });
|
||||
await ctx.newExif({ assetId: asset.id, exifImageHeight: 200, exifImageWidth: 150 });
|
||||
ctx.getMock(JobRepository).queueAll.mockResolvedValue();
|
||||
|
||||
await ctx.newEdits(asset.id, {
|
||||
edits: [
|
||||
@@ -543,6 +551,7 @@ describe(PersonService.name, () => {
|
||||
const { person } = await ctx.newPerson({ ownerId: user.id });
|
||||
const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 150, height: 100 });
|
||||
await ctx.newExif({ assetId: asset.id, exifImageHeight: 200, exifImageWidth: 200 });
|
||||
ctx.getMock(JobRepository).queueAll.mockResolvedValue();
|
||||
|
||||
await ctx.newEdits(asset.id, {
|
||||
edits: [
|
||||
@@ -622,6 +631,7 @@ describe(PersonService.name, () => {
|
||||
const { person } = await ctx.newPerson({ ownerId: user.id });
|
||||
const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 100, height: 100 });
|
||||
await ctx.newExif({ assetId: asset.id, exifImageHeight: 100, exifImageWidth: 100 });
|
||||
ctx.getMock(JobRepository).queueAll.mockResolvedValue();
|
||||
|
||||
await ctx.newEdits(asset.id, {
|
||||
edits: [
|
||||
@@ -692,6 +702,7 @@ describe(PersonService.name, () => {
|
||||
const { person } = await ctx.newPerson({ ownerId: user.id });
|
||||
const { asset } = await ctx.newAsset({ id: factory.uuid(), ownerId: user.id, width: 100, height: 100 });
|
||||
await ctx.newExif({ assetId: asset.id, exifImageHeight: 200, exifImageWidth: 100, orientation: '6' });
|
||||
ctx.getMock(JobRepository).queueAll.mockResolvedValue();
|
||||
|
||||
await ctx.newEdits(asset.id, {
|
||||
edits: [
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Kysely } from 'kysely';
|
||||
import { SearchSuggestionType } from 'src/dtos/search.dto';
|
||||
import { AccessRepository } from 'src/repositories/access.repository';
|
||||
import { AssetRepository } from 'src/repositories/asset.repository';
|
||||
import { DatabaseRepository } from 'src/repositories/database.repository';
|
||||
@@ -108,4 +109,25 @@ describe(SearchService.name, () => {
|
||||
expect(response.assets.items[0].id).toBe(unstackedAsset.id);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSearchSuggestions', () => {
|
||||
it('should filter out empty search suggestions', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
const { user } = await ctx.newUser();
|
||||
|
||||
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
||||
await ctx.newExif({ assetId: asset.id, make: 'Canon' });
|
||||
|
||||
const { asset: assetWithEmptyMake } = await ctx.newAsset({ ownerId: user.id });
|
||||
await ctx.newExif({ assetId: assetWithEmptyMake.id, make: '' });
|
||||
|
||||
const auth = factory.auth({ user: { id: user.id } });
|
||||
const suggestions = await sut.getSearchSuggestions(auth, {
|
||||
type: SearchSuggestionType.CAMERA_MAKE,
|
||||
includeNull: true,
|
||||
});
|
||||
|
||||
expect(suggestions).toEqual(['Canon', null]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -372,6 +372,43 @@ describe(SharedLinkService.name, () => {
|
||||
});
|
||||
|
||||
describe('get', () => {
|
||||
it('should return an album shared link with assets', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
const { user } = await ctx.newUser();
|
||||
const auth = factory.auth({ user });
|
||||
const { album } = await ctx.newAlbum({ ownerId: user.id });
|
||||
|
||||
const [{ asset: asset1 }, { asset: asset2 }] = await Promise.all([
|
||||
ctx.newAsset({ ownerId: user.id }),
|
||||
ctx.newAsset({ ownerId: user.id }),
|
||||
]);
|
||||
await Promise.all([
|
||||
ctx.newExif({ assetId: asset1.id, make: 'Canon' }),
|
||||
ctx.newExif({ assetId: asset2.id, make: 'Canon' }),
|
||||
]);
|
||||
|
||||
const sharedLinkRepo = ctx.get(SharedLinkRepository);
|
||||
const sharedLink = await sharedLinkRepo.create({
|
||||
key: randomBytes(16),
|
||||
id: factory.uuid(),
|
||||
userId: user.id,
|
||||
albumId: album.id,
|
||||
allowUpload: true,
|
||||
type: SharedLinkType.Album,
|
||||
});
|
||||
|
||||
await sharedLinkRepo.addAssets(sharedLink.id, [asset1.id, asset2.id]);
|
||||
const result = await sut.get(auth, sharedLink.id);
|
||||
const assetIds = result.assets.map((asset) => asset.id);
|
||||
|
||||
expect(result).toMatchObject({
|
||||
id: sharedLink.id,
|
||||
album: expect.objectContaining({ id: album.id }),
|
||||
});
|
||||
expect(assetIds).toHaveLength(2);
|
||||
expect(assetIds).toEqual(expect.arrayContaining([asset1.id, asset2.id]));
|
||||
});
|
||||
|
||||
it('should not return trashed assets for an individual shared link', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
const { user } = await ctx.newUser();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Kysely } from 'kysely';
|
||||
import { serverVersion } from 'src/constants';
|
||||
import { JobName } from 'src/enum';
|
||||
import { CronRepository } from 'src/repositories/cron.repository';
|
||||
import { DatabaseRepository } from 'src/repositories/database.repository';
|
||||
import { JobRepository } from 'src/repositories/job.repository';
|
||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||
@@ -16,7 +17,7 @@ const setup = (db?: Kysely<DB>) => {
|
||||
return newMediumService(VersionService, {
|
||||
database: db || defaultDatabase,
|
||||
real: [DatabaseRepository, VersionHistoryRepository],
|
||||
mock: [LoggingRepository, JobRepository],
|
||||
mock: [LoggingRepository, JobRepository, CronRepository],
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user