Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions backend/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4257,6 +4257,60 @@ def test_other_corp_private_post_chat_is_forbidden(client, demo_analyst_token, s
assert listed.status_code == 403


def test_other_corp_private_post_content_is_forbidden(client, demo_analyst_token, seeded_db) -> None:
response = client.get(
f"/api/posts/{seeded_db['other_private_post_id']}/content",
headers={"Authorization": f"Bearer {demo_analyst_token}"},
)
assert response.status_code == 403


def test_other_corp_private_post_knowledge_graph_is_forbidden(client, demo_analyst_token, seeded_db) -> None:
response = client.get(
f"/api/posts/{seeded_db['other_private_post_id']}/knowledge-graph",
headers={"Authorization": f"Bearer {demo_analyst_token}"},
)
assert response.status_code == 403


def test_other_corp_private_post_evaluation_is_forbidden(client, demo_analyst_token, seeded_db) -> None:
response = client.get(
f"/api/posts/{seeded_db['other_private_post_id']}/evaluation",
headers={"Authorization": f"Bearer {demo_analyst_token}"},
)
assert response.status_code == 403


def test_other_corp_private_post_five_w1h_is_forbidden(client, demo_analyst_token, seeded_db) -> None:
response = client.get(
f"/api/posts/{seeded_db['other_private_post_id']}/five-w1h",
headers={"Authorization": f"Bearer {demo_analyst_token}"},
)
assert response.status_code == 403


def test_other_corp_private_post_lineage_endpoint_is_forbidden(client, demo_analyst_token, seeded_db) -> None:
"""The per-post lineage endpoint (direct/indirect links), not the
corpus-wide /api/lineage graph -- a separate ABAC-gated route."""
response = client.get(
f"/api/posts/{seeded_db['other_private_post_id']}/lineage",
headers={"Authorization": f"Bearer {demo_analyst_token}"},
)
assert response.status_code == 403


def test_other_corp_private_post_bookmark_is_forbidden(client, demo_analyst_token, seeded_db) -> None:
headers = {"Authorization": f"Bearer {demo_analyst_token}"}
read = client.get(f"/api/posts/{seeded_db['other_private_post_id']}/bookmark", headers=headers)
assert read.status_code == 403
written = client.post(
f"/api/posts/{seeded_db['other_private_post_id']}/bookmark",
json={"bookmarked": True},
headers=headers,
)
assert written.status_code == 403


@pytest.mark.skipif(
not (_ORCHESTRATOR_BASE_URL and _ORCHESTRATOR_API_KEY),
reason="set LINEAGEWEAVE_TEST_ORCHESTRATOR_BASE_URL and LINEAGEWEAVE_TEST_ORCHESTRATOR_API_KEY to run",
Expand Down
2 changes: 1 addition & 1 deletion docs/product-technical-gap-baseline.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ adapter, fixture, or HTTP-shaped test double never upgrades a row to
| Noto Sans, palette, table/form/button conventions, modal 50% mask and keyboard semantics | ADR 0118, token CSS, popup dialog implementation, frontend tests | source + unit |
| Keyverse/OIDC login with real account | `auth.py`, OIDC discovery/JWKS boundary, local redirect check | source + local-integration; Keyverse open |
| Authenticated corp/PU attributes | `/api/me` returns DB-backed codes; backend integration test covers `TEST-CORP`/`TEST-PU`, the GNB disclosure is covered by `App.test.tsx`, and desktop/390px Playwright QA verifies the rendered scope | source + unit + local-integration + browser-mocked |
| RBAC/ABAC, public/private visibility, tenant isolation | `_can_see_post` plus W author/admin raw-source exception, analysis eligibility excluding W, API authorization tests, aggregate-only runtime checks | source + local-integration |
| RBAC/ABAC, public/private visibility, tenant isolation | `_can_see_post` plus W author/admin raw-source exception, analysis eligibility excluding W, API authorization tests (extended in this worktree: `/content`, `/knowledge-graph`, `/evaluation`, `/five-w1h`, per-post `/lineage`, `/bookmark` each now have a dedicated other-corp-403 regression test -- all were already correctly gated via `_load_visible_post`, so this closes a test-coverage gap, not a bug), aggregate-only runtime checks | source + local-integration |
| React product surface and PostgreSQL boundary | React routes/components, asyncpg API, Compose stack | source + local-integration |
| Authorized PostgreSQL export import mapping | `scripts/import_postgresql_posts.py`, ADR 0121, hash-verified RFC 2557 MHTML resolver, and synthetic preflight/import tests; authorized relation has artifact-path metadata but no body/content/HTML field | source + unit + local-integration partial; operator artifact files and authorized live import open |
| Bounded large-body search migration | `0035_body_search_prefix.sql`, `0036_normalized_body_search.sql`; live replay completed after bounded rendered-text indexing | source + local-integration |
Expand Down