"""用 A 企业的令牌访问 B 企业的资源,一律 404(架构 §3.3 第 3 层)。""" from __future__ import annotations import httpx from tests.conftest import project_with_tender, register, run_parse async def test_other_tenant_resources_are_not_found(app_client: httpx.AsyncClient) -> None: a = await register(app_client, "甲公司") b = await register(app_client, "乙公司") project_id, doc_id = await project_with_tender(a) job = await run_parse(a, doc_id) assert job["status"] == "succeeded" for path in ( f"/projects/{project_id}", f"/projects/{project_id}/checklist", f"/projects/{project_id}/checklist/items", f"/documents/{doc_id}", f"/documents/{doc_id}/pages", f"/documents/{doc_id}/file?variant=normalized", f"/parse-jobs/{job['id']}", ): r = await b.get(path) assert r.status_code == 404, (path, r.status_code, r.text) r = await b.post(f"/documents/{doc_id}/parse-jobs", json={"expected_charge": 1}) assert r.status_code == 404 r = await b.post(f"/parse-jobs/{job['id']}/cancel") assert r.status_code == 404 assert (await b.get("/projects")).json()["items"] == [] assert [p["id"] for p in (await a.get("/projects")).json()["items"]] == [project_id] async def test_database_blocks_queries_without_tenant() -> None: """代码漏了租户条件时,行级安全策略兜底:没设租户什么都查不到。""" from sqlalchemy import text from bid_doctor.core.db import anonymous_tx async with anonymous_tx() as s: for table in ("project", "source_document", "checklist_item", "quota_entry", "citation"): assert (await s.execute(text(f"SELECT count(*) FROM {table}"))).scalar_one() == 0