mirror of
https://github.com/immich-app/immich.git
synced 2026-08-02 00:48:08 -07:00
tests
This commit is contained in:
@@ -120,6 +120,16 @@ describe(SearchController.name, () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should reject a deprecated field combined with a new structure field', async () => {
|
||||
const { status, body } = await request(ctx.getHttpServer())
|
||||
.post('/search/metadata')
|
||||
.send({ filter: {}, city: 'Oslo' });
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(
|
||||
errorDto.validationError([{ path: ['city'], message: 'Deprecated field city cannot be combined with filter' }]),
|
||||
);
|
||||
});
|
||||
|
||||
describe('POST /search/random', () => {
|
||||
it('should be an authenticated route', async () => {
|
||||
await request(ctx.getHttpServer()).post('/search/random');
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { BadRequestException } from '@nestjs/common';
|
||||
import { BadRequestException, UnauthorizedException } from '@nestjs/common';
|
||||
import { mapAsset } from 'src/dtos/asset-response.dto';
|
||||
import { SearchSuggestionType } from 'src/dtos/search.dto';
|
||||
import { AssetVisibility } from 'src/enum';
|
||||
import { SearchService } from 'src/services/search.service';
|
||||
import { AssetFactory } from 'test/factories/asset.factory';
|
||||
import { AuthFactory } from 'test/factories/auth.factory';
|
||||
import { authStub } from 'test/fixtures/auth.stub';
|
||||
import { getForAsset } from 'test/mappers';
|
||||
import { newUuid } from 'test/small.factory';
|
||||
import { newTestService, ServiceMocks } from 'test/utils';
|
||||
import { beforeEach, vitest } from 'vitest';
|
||||
|
||||
@@ -215,6 +217,66 @@ describe(SearchService.name, () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('new shape routing', () => {
|
||||
it('should route a filter request to the V3 search and a flat request to the legacy search', async () => {
|
||||
const auth = AuthFactory.create();
|
||||
|
||||
mocks.search.searchMetadataV3.mockResolvedValue({ hasNextPage: false, items: [] });
|
||||
await sut.searchMetadata(auth, { filter: {} });
|
||||
expect(mocks.search.searchMetadataV3).toHaveBeenCalled();
|
||||
expect(mocks.search.searchMetadata).not.toHaveBeenCalled();
|
||||
|
||||
mocks.search.searchMetadata.mockResolvedValue({ hasNextPage: false, items: [] });
|
||||
await sut.searchMetadata(auth, { city: 'Oslo' });
|
||||
expect(mocks.search.searchMetadata).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should route statistics, random, and smart filter requests to their V3 search', async () => {
|
||||
const auth = AuthFactory.create();
|
||||
|
||||
mocks.search.searchStatisticsV3.mockResolvedValue({ total: 0 });
|
||||
await expect(sut.searchStatistics(auth, { filter: {} })).resolves.toEqual({ total: 0 });
|
||||
|
||||
mocks.search.searchRandomV3.mockResolvedValue([]);
|
||||
await expect(sut.searchRandom(auth, { filter: {} })).resolves.toEqual([]);
|
||||
|
||||
mocks.search.searchSmartV3.mockResolvedValue({ hasNextPage: false, items: [] });
|
||||
mocks.machineLearning.encodeText.mockResolvedValue('[1, 2, 3]');
|
||||
await sut.searchSmart(auth, { filter: {}, query: 'test' });
|
||||
expect(mocks.search.searchSmartV3).toHaveBeenCalledWith(
|
||||
{ size: 100, offset: 0 },
|
||||
expect.objectContaining({ embedding: '[1, 2, 3]' }),
|
||||
);
|
||||
});
|
||||
|
||||
it('should reject an invalid cursor', async () => {
|
||||
await expect(sut.searchMetadata(AuthFactory.create(), { cursor: '???' })).rejects.toThrowError(
|
||||
new BadRequestException('Invalid cursor'),
|
||||
);
|
||||
});
|
||||
|
||||
it('should reject an unelevated session whose filter could match locked assets', async () => {
|
||||
const filter = { visibility: { in: [AssetVisibility.Locked, AssetVisibility.Timeline] } };
|
||||
await expect(sut.searchMetadata(AuthFactory.create(), { filter })).rejects.toBeInstanceOf(UnauthorizedException);
|
||||
});
|
||||
|
||||
it('should reject a shared link without a top-level album constraint', async () => {
|
||||
const auth = AuthFactory.from().sharedLink().build();
|
||||
|
||||
await expect(sut.searchMetadata(auth, { filter: {} })).rejects.toThrowError(
|
||||
new BadRequestException('Shared link access is only allowed in combination with an albumIds filter'),
|
||||
);
|
||||
|
||||
const albumId = newUuid();
|
||||
mocks.access.album.checkSharedLinkAccess.mockResolvedValue(new Set([albumId]));
|
||||
await expect(
|
||||
sut.searchMetadata(auth, { filter: { or: [{ albumIds: { any: [albumId] } }] } }),
|
||||
).rejects.toThrowError(
|
||||
new BadRequestException('Shared link access is only allowed in combination with an albumIds filter'),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('searchSmart', () => {
|
||||
beforeEach(() => {
|
||||
mocks.search.searchSmart.mockResolvedValue({ hasNextPage: false, items: [] });
|
||||
|
||||
Reference in New Issue
Block a user