Initial curated RAGcore source from c16667f0c9397e2bfc8dd0255b114fba23c8d05e
This commit is contained in:
commit
7ca726caf2
659 files changed
+98171
No files matched your search
@@ -0,0 +1,141 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
import yaml
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from ragcore.api.v1.jobs.dependencies import get_job_service, get_jobs_sync_principal
|
||||
from ragcore.application.jobs import JobService
|
||||
from ragcore.application.jobs.models import Job
|
||||
from ragcore.domain.authorization import Principal, PrincipalType
|
||||
from ragcore.domain.control import Role
|
||||
from ragcore.main import create_app
|
||||
|
||||
|
||||
class FakeJobRepository:
|
||||
def __init__(self) -> None:
|
||||
self.jobs: dict[UUID, Job] = {}
|
||||
|
||||
async def enqueue(self, job: Job) -> Job:
|
||||
self.jobs[job.id] = job
|
||||
return job
|
||||
|
||||
async def get(self, job_id: UUID) -> Job | None:
|
||||
return self.jobs.get(job_id)
|
||||
|
||||
async def get_owned(self, job_id: UUID, *, workspace_id: UUID | None) -> Job | None:
|
||||
job = self.jobs.get(job_id)
|
||||
if job is None:
|
||||
return None
|
||||
if workspace_id is not None and job.workspace_id != workspace_id:
|
||||
return None
|
||||
return job
|
||||
|
||||
|
||||
def _job(*, workspace_id: UUID | None = None, **overrides: object) -> Job:
|
||||
payload: dict[str, object] = {"blob_digest": "a" * 64}
|
||||
if workspace_id is not None:
|
||||
payload["workspace_id"] = str(workspace_id)
|
||||
defaults: dict[str, object] = dict(
|
||||
id=uuid4(),
|
||||
workspace_id=workspace_id,
|
||||
job_key=f"job-{uuid4()}",
|
||||
operation="ingest_upload",
|
||||
target_key="blob:abc",
|
||||
profile_version="upload-v1",
|
||||
payload=payload,
|
||||
available_at=datetime.now(UTC),
|
||||
trace_id="trace",
|
||||
)
|
||||
defaults.update(overrides)
|
||||
return Job(**defaults) # type: ignore[arg-type]
|
||||
|
||||
|
||||
def _fixture():
|
||||
workspace_id = uuid4()
|
||||
principal = Principal(
|
||||
uuid4(), workspace_id, PrincipalType.SERVICE_ACCOUNT, frozenset({Role.EDITOR})
|
||||
)
|
||||
repository = FakeJobRepository()
|
||||
app = create_app()
|
||||
app.dependency_overrides[get_job_service] = lambda: JobService(repository) # type: ignore[arg-type]
|
||||
app.dependency_overrides[get_jobs_sync_principal] = lambda: principal
|
||||
return app, repository, principal
|
||||
|
||||
|
||||
def test_openapi_and_runtime_expose_same_job_operations() -> None:
|
||||
app, _, _ = _fixture()
|
||||
document = yaml.safe_load(
|
||||
(Path(__file__).parents[4] / "docs" / "contracts" / "openapi.yaml").read_text()
|
||||
)
|
||||
assert "/v1/jobs/{job_id}" in document["paths"]
|
||||
documented = {method.lower() for method in document["paths"]["/v1/jobs/{job_id}"]}
|
||||
runtime = {method.lower() for method in app.openapi()["paths"]["/v1/jobs/{job_id}"]}
|
||||
assert runtime == documented
|
||||
|
||||
|
||||
def test_get_job_resolves_the_upload_status_url() -> None:
|
||||
app, repository, principal = _fixture()
|
||||
job = _job(workspace_id=principal.workspace_id)
|
||||
asyncio.run(repository.enqueue(job))
|
||||
|
||||
response = TestClient(app).get(f"/v1/jobs/{job.id}")
|
||||
|
||||
assert response.status_code == 200
|
||||
body = response.json()
|
||||
assert body["id"] == str(job.id)
|
||||
assert body["operation"] == "ingest_upload"
|
||||
assert body["status"] == "ready"
|
||||
assert body["attempt_count"] == 0
|
||||
assert body["max_attempts"] == 3
|
||||
|
||||
|
||||
def test_get_job_unknown_id_is_404_problem_details() -> None:
|
||||
app, _, _ = _fixture()
|
||||
response = TestClient(app).get(f"/v1/jobs/{uuid4()}")
|
||||
assert response.status_code == 404
|
||||
assert response.json()["code"] == "JOB_NOT_FOUND"
|
||||
|
||||
|
||||
def test_get_job_cross_workspace_is_404_not_leaked() -> None:
|
||||
app, repository, _ = _fixture()
|
||||
job = _job(workspace_id=uuid4())
|
||||
asyncio.run(repository.enqueue(job))
|
||||
|
||||
response = TestClient(app).get(f"/v1/jobs/{job.id}")
|
||||
|
||||
assert response.status_code == 404
|
||||
assert response.json()["code"] == "JOB_NOT_FOUND"
|
||||
|
||||
|
||||
def test_get_job_without_ownership_is_404_for_a_workspace_scoped_caller() -> None:
|
||||
"""A job with no owner is nobody's, not everyone's.
|
||||
|
||||
This route used to accept any job whose payload simply lacked a
|
||||
``workspace_id`` -- a fail-open default that handed unowned work to
|
||||
whichever tenant asked for it first. Ownership is a column now, and an
|
||||
absent owner (a legacy row that migration 0018 would not guess at) reads
|
||||
exactly like a job that does not exist.
|
||||
"""
|
||||
|
||||
app, repository, _ = _fixture()
|
||||
job = _job(workspace_id=None)
|
||||
asyncio.run(repository.enqueue(job))
|
||||
|
||||
response = TestClient(app).get(f"/v1/jobs/{job.id}")
|
||||
|
||||
assert response.status_code == 404
|
||||
assert response.json()["code"] == "JOB_NOT_FOUND"
|
||||
|
||||
|
||||
def test_missing_authentication_is_problem_details() -> None:
|
||||
app, _, _ = _fixture()
|
||||
app.dependency_overrides.pop(get_jobs_sync_principal)
|
||||
response = TestClient(app).get(f"/v1/jobs/{uuid4()}")
|
||||
assert response.status_code == 401
|
||||
assert response.headers["content-type"].startswith("application/problem+json")
|
||||
assert response.json()["code"] == "AUTHENTICATION_REQUIRED"
|
||||
Reference in new issue
Block a user