§22 S3: scope-role enforcement + collection-grain visibility — v0.42.0 (@S3) #1

Merged
benstull merged 24 commits from feat/s3-scope-roles-collection-visibility into main 2026-06-06 01:08:55 +00:00
Showing only changes of commit bd6dc6524a - Show all commits
@@ -139,3 +139,21 @@ def test_scoped_routes_404_for_collection_outside_project(app_with_fake_gitea):
with TestClient(app) as client:
r = client.get("/api/projects/default/collections/nope/rfcs")
assert r.status_code == 404
def test_s2_anonymous_empty_public_collection(app_with_fake_gitea):
"""C3.6 (@S2): a public collection with no entries; an anonymous visitor
lands on its catalog → an empty catalog (200, no items), and the propose
action is not available to them (the propose route rejects anonymous)."""
app, _ = app_with_fake_gitea
with TestClient(app) as client:
_add_features_collection() # public, no entries
# Anonymous (no session cookie) reads the empty catalog — 200, [].
r = client.get("/api/projects/default/collections/features/rfcs")
assert r.status_code == 200, r.text
assert r.json()["items"] == []
# No propose action for an anonymous visitor.
r2 = client.post(
"/api/projects/default/collections/features/rfcs/propose",
json={"title": "X", "slug": "x", "pitch": "p", "tags": []})
assert r2.status_code == 401