"""`application/points/queries.py` against the fake repository (ADR-0016). The HTTP-level behaviour is covered in `tests/integration/qdrant/`. What is worth isolating here is the small amount of logic the service actually owns — raising instead of returning `None`, and folding a query's Arabic letterforms — because both are cheap to test directly and expensive to notice when broken. """ import uuid import pytest from src.application.points.point import PointNotFoundError from src.application.points.queries import ( count_points, get_point, list_file_points, search_points, ) from tests.fakes import FakePointRepository from tests.support.point_contract import SeedSpec, build_point, point_id_for pytestmark = [pytest.mark.unit, pytest.mark.asyncio] TENANT = uuid.UUID("11111111-1111-4111-8111-111111111111") OTHER_TENANT = uuid.UUID("22222222-2222-4222-8222-222222222222") FILE = uuid.UUID("33333333-3333-4333-8333-333333333333") def _repository(*specs: SeedSpec) -> FakePointRepository: repository = FakePointRepository() for spec in specs: repository.add(build_point(spec)) return repository async def test_get_point_returns_the_point_for_its_owner() -> None: repository = _repository(SeedSpec(TENANT, FILE, 0, "hello", 1.0)) point = await get_point(repository, tenant_id=TENANT, point_id=point_id_for(FILE, 0)) assert point.content == "hello" async def test_get_point_raises_for_another_tenants_point() -> None: """Raising, not returning `None`, so a route cannot serve `200 null`.""" repository = _repository(SeedSpec(TENANT, FILE, 0, "hello", 1.0)) with pytest.raises(PointNotFoundError): await get_point(repository, tenant_id=OTHER_TENANT, point_id=point_id_for(FILE, 0)) async def test_get_point_raises_for_an_unknown_point() -> None: repository = _repository() with pytest.raises(PointNotFoundError): await get_point(repository, tenant_id=TENANT, point_id=uuid.uuid4()) async def test_search_points_folds_arabic_letterforms_before_matching() -> None: """The query is normalized the same way ingestion normalized the content. Stored content carries Persian yeh (U+06CC) because `normalize_persian_text` folded it at ingest. A query typed with Arabic yeh (U+064A) is a different codepoint and would match nothing — silently, with no error to notice. """ persian = "مدیریت" arabic = "مديريت" assert persian != arabic repository = _repository(SeedSpec(TENANT, FILE, 0, persian, 1.0)) found = await search_points(repository, tenant_id=TENANT, query=arabic, limit=10) assert [point.content for point in found.points] == [persian] async def test_search_points_does_not_reach_another_tenant() -> None: repository = _repository(SeedSpec(OTHER_TENANT, FILE, 0, "secret", 1.0)) found = await search_points(repository, tenant_id=TENANT, query="secret", limit=10) assert found.points == () async def test_list_file_points_returns_an_empty_page_for_a_foreign_file() -> None: """Indistinguishable from an unknown file — the same non-disclosure rule.""" repository = _repository(SeedSpec(OTHER_TENANT, FILE, 0, "secret", 1.0)) page = await list_file_points(repository, tenant_id=TENANT, file_id=FILE, limit=10) assert page.points == () assert page.next_cursor is None async def test_count_points_excludes_inactive_unless_asked() -> None: repository = _repository( SeedSpec(TENANT, FILE, 0, "live", 1.0), SeedSpec(TENANT, FILE, 1, "gone", 2.0, is_active=False), ) assert await count_points(repository, tenant_id=TENANT) == 1 assert await count_points(repository, tenant_id=TENANT, include_inactive=True) == 2