fix(server): skip invisible assets for thumbnail generation and ml (#8891)

* skip invisible assets for thumbnail generation and ml

* no need to update job status

* fix thumbhash check order

* linting
This commit is contained in:
Mert
2024-04-18 21:37:55 -04:00
committed by GitHub
parent 112d6d60ec
commit 596c35dc00
5 changed files with 77 additions and 19 deletions

View File

@@ -1,8 +1,7 @@
import { AssetEntity } from 'src/entities/asset.entity';
import { SystemConfigKey } from 'src/entities/system-config.entity';
import { IAssetRepository, WithoutProperty } from 'src/interfaces/asset.interface';
import { IDatabaseRepository } from 'src/interfaces/database.interface';
import { IJobRepository, JobName } from 'src/interfaces/job.interface';
import { IJobRepository, JobName, JobStatus } from 'src/interfaces/job.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { IMachineLearningRepository } from 'src/interfaces/machine-learning.interface';
import { ISearchRepository } from 'src/interfaces/search.interface';
@@ -19,11 +18,6 @@ import { newSearchRepositoryMock } from 'test/repositories/search.repository.moc
import { newSystemConfigRepositoryMock } from 'test/repositories/system-config.repository.mock';
import { Mocked } from 'vitest';
const asset = {
id: 'asset-1',
previewPath: 'path/to/resize.ext',
} as AssetEntity;
describe(SmartInfoService.name, () => {
let sut: SmartInfoService;
let assetMock: Mocked<IAssetRepository>;
@@ -44,7 +38,7 @@ describe(SmartInfoService.name, () => {
loggerMock = newLoggerRepositoryMock();
sut = new SmartInfoService(assetMock, databaseMock, jobMock, machineMock, searchMock, configMock, loggerMock);
assetMock.getByIds.mockResolvedValue([asset]);
assetMock.getByIds.mockResolvedValue([assetStub.image]);
});
it('should work', () => {
@@ -92,17 +86,16 @@ describe(SmartInfoService.name, () => {
it('should do nothing if machine learning is disabled', async () => {
configMock.load.mockResolvedValue([{ key: SystemConfigKey.MACHINE_LEARNING_ENABLED, value: false }]);
await sut.handleEncodeClip({ id: '123' });
expect(await sut.handleEncodeClip({ id: '123' })).toEqual(JobStatus.SKIPPED);
expect(assetMock.getByIds).not.toHaveBeenCalled();
expect(machineMock.encodeImage).not.toHaveBeenCalled();
});
it('should skip assets without a resize path', async () => {
const asset = { previewPath: '' } as AssetEntity;
assetMock.getByIds.mockResolvedValue([asset]);
assetMock.getByIds.mockResolvedValue([assetStub.noResizePath]);
await sut.handleEncodeClip({ id: asset.id });
expect(await sut.handleEncodeClip({ id: assetStub.noResizePath.id })).toEqual(JobStatus.FAILED);
expect(searchMock.upsert).not.toHaveBeenCalled();
expect(machineMock.encodeImage).not.toHaveBeenCalled();
@@ -111,14 +104,23 @@ describe(SmartInfoService.name, () => {
it('should save the returned objects', async () => {
machineMock.encodeImage.mockResolvedValue([0.01, 0.02, 0.03]);
await sut.handleEncodeClip({ id: asset.id });
expect(await sut.handleEncodeClip({ id: assetStub.image.id })).toEqual(JobStatus.SUCCESS);
expect(machineMock.encodeImage).toHaveBeenCalledWith(
'http://immich-machine-learning:3003',
{ imagePath: 'path/to/resize.ext' },
{ imagePath: assetStub.image.previewPath },
{ enabled: true, modelName: 'ViT-B-32__openai' },
);
expect(searchMock.upsert).toHaveBeenCalledWith('asset-1', [0.01, 0.02, 0.03]);
expect(searchMock.upsert).toHaveBeenCalledWith(assetStub.image.id, [0.01, 0.02, 0.03]);
});
it('should skip invisible assets', async () => {
assetMock.getByIds.mockResolvedValue([assetStub.livePhotoMotionAsset]);
expect(await sut.handleEncodeClip({ id: assetStub.livePhotoMotionAsset.id })).toEqual(JobStatus.SKIPPED);
expect(machineMock.encodeImage).not.toHaveBeenCalled();
expect(searchMock.upsert).not.toHaveBeenCalled();
});
});