test(integration): add coverage for repositories, auth resolution, and the two-phase upload
This commit is contained in:
113
tests/integration/postgres/test_repositories.py
Normal file
113
tests/integration/postgres/test_repositories.py
Normal file
@@ -0,0 +1,113 @@
|
||||
import uuid
|
||||
|
||||
import pytest
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from src.infrastructure.postgres.repositories import ingestion_jobs as jobs_repo
|
||||
from src.infrastructure.postgres.repositories import source_files as source_files_repo
|
||||
from tests.support.factories import create_tenant
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.integration,
|
||||
pytest.mark.postgres,
|
||||
pytest.mark.asyncio(loop_scope="session"),
|
||||
]
|
||||
|
||||
|
||||
async def test_source_files_get_by_id_is_tenant_scoped(db_session: AsyncSession) -> None:
|
||||
owner = await create_tenant(db_session)
|
||||
other = await create_tenant(db_session)
|
||||
source_file_id = uuid.uuid4()
|
||||
source_files_repo.create(
|
||||
db_session,
|
||||
source_file_id=source_file_id,
|
||||
tenant_id=owner.id,
|
||||
domain="general",
|
||||
source_filename="report.csv",
|
||||
source_type="csv",
|
||||
content_sha256="a" * 64,
|
||||
byte_size=10,
|
||||
storage_uri="tenants/x/source-files/y/original",
|
||||
created_by_api_key_id=None,
|
||||
)
|
||||
await db_session.commit()
|
||||
|
||||
found_for_owner = await source_files_repo.get_by_id(
|
||||
db_session, tenant_id=owner.id, source_file_id=source_file_id
|
||||
)
|
||||
found_for_other = await source_files_repo.get_by_id(
|
||||
db_session, tenant_id=other.id, source_file_id=source_file_id
|
||||
)
|
||||
|
||||
assert found_for_owner is not None
|
||||
assert found_for_other is None
|
||||
|
||||
|
||||
async def test_source_files_find_active_by_content_hash_matches_tenant_domain_hash(
|
||||
db_session: AsyncSession,
|
||||
) -> None:
|
||||
tenant = await create_tenant(db_session)
|
||||
source_files_repo.create(
|
||||
db_session,
|
||||
source_file_id=uuid.uuid4(),
|
||||
tenant_id=tenant.id,
|
||||
domain="general",
|
||||
source_filename="report.csv",
|
||||
source_type="csv",
|
||||
content_sha256="b" * 64,
|
||||
byte_size=10,
|
||||
storage_uri="tenants/x/source-files/y/original",
|
||||
created_by_api_key_id=None,
|
||||
)
|
||||
await db_session.commit()
|
||||
|
||||
found = await source_files_repo.find_active_by_content_hash(
|
||||
db_session, tenant_id=tenant.id, domain="general", content_sha256="b" * 64
|
||||
)
|
||||
not_found_other_domain = await source_files_repo.find_active_by_content_hash(
|
||||
db_session, tenant_id=tenant.id, domain="other", content_sha256="b" * 64
|
||||
)
|
||||
|
||||
assert found is not None
|
||||
assert not_found_other_domain is None
|
||||
|
||||
|
||||
async def test_ingestion_jobs_mark_terminal_rejects_non_running_job(
|
||||
db_session: AsyncSession,
|
||||
) -> None:
|
||||
"""A job already in a terminal state must not be re-marked (ADR-0017)."""
|
||||
tenant = await create_tenant(db_session)
|
||||
source_file_id = uuid.uuid4()
|
||||
source_files_repo.create(
|
||||
db_session,
|
||||
source_file_id=source_file_id,
|
||||
tenant_id=tenant.id,
|
||||
domain="general",
|
||||
source_filename="report.csv",
|
||||
source_type="csv",
|
||||
content_sha256="c" * 64,
|
||||
byte_size=10,
|
||||
storage_uri="tenants/x/source-files/y/original",
|
||||
created_by_api_key_id=None,
|
||||
)
|
||||
await db_session.flush()
|
||||
job = jobs_repo.create_running(
|
||||
db_session,
|
||||
tenant_id=tenant.id,
|
||||
source_file_id=source_file_id,
|
||||
requested_by_api_key_id=None,
|
||||
chunking_strategy="fixed_size",
|
||||
)
|
||||
await db_session.commit()
|
||||
|
||||
first = await jobs_repo.mark_terminal(
|
||||
db_session, tenant_id=tenant.id, ingestion_job_id=job.id, status="succeeded"
|
||||
)
|
||||
await db_session.commit()
|
||||
second = await jobs_repo.mark_terminal(
|
||||
db_session, tenant_id=tenant.id, ingestion_job_id=job.id, status="failed"
|
||||
)
|
||||
|
||||
assert first is not None
|
||||
assert first.status == "succeeded"
|
||||
assert second is None
|
||||
Reference in New Issue
Block a user