feat: add visibility filter param and author_name to tree list endpoint

GET /trees now accepts ?visibility=private|team|link|public to scope results.
TreeListResponse includes author_name (full_name or email) and visibility.
Author names fetched in single query to avoid N+1.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-02-24 03:25:26 -05:00
parent 8c982a95ec
commit 29c3d5eed6
3 changed files with 77 additions and 2 deletions

View File

@@ -391,3 +391,59 @@ class TestTrees:
assert response.status_code == 200
trees = response.json()
assert isinstance(trees, list)
class TestVisibilityFilter:
"""Test that visibility filtering and author_name work correctly."""
@pytest.mark.asyncio
async def test_private_tree_only_visible_to_author(
self, client: AsyncClient, auth_headers: dict, test_user: dict
):
"""A private tree created by test_user should appear in their own list."""
tree_data = {
"name": "Private Flow Test",
"tree_structure": {"id": "root", "type": "decision", "question": "Q?", "options": [], "children": []},
}
create_resp = await client.post("/api/v1/trees", json=tree_data, headers=auth_headers)
assert create_resp.status_code == 201
tree_id = create_resp.json()["id"]
# Set visibility to private
vis_resp = await client.patch(
f"/api/v1/trees/{tree_id}/visibility",
json={"visibility": "private"},
headers=auth_headers
)
assert vis_resp.status_code == 200
# Verify it still appears for the author
list_resp = await client.get("/api/v1/trees", headers=auth_headers)
assert list_resp.status_code == 200
ids = [t["id"] for t in list_resp.json()]
assert tree_id in ids
@pytest.mark.asyncio
async def test_visibility_query_param_filters_correctly(
self, client: AsyncClient, auth_headers: dict
):
"""?visibility=public should only return trees with visibility='public'."""
resp = await client.get("/api/v1/trees?visibility=public", headers=auth_headers)
assert resp.status_code == 200
trees = resp.json()
for tree in trees:
assert tree["visibility"] == "public", f"Tree {tree['id']} has visibility={tree['visibility']}"
@pytest.mark.asyncio
async def test_author_name_present_in_list_response(
self, client: AsyncClient, auth_headers: dict, test_tree: dict
):
"""TreeListResponse should include author_name field."""
resp = await client.get("/api/v1/trees", headers=auth_headers)
assert resp.status_code == 200
trees = resp.json()
assert len(trees) >= 1
# author_name key should be present (value may be None for system/default trees)
assert "author_name" in trees[0]
# visibility key should be present
assert "visibility" in trees[0]