feat: public guest discovery endpoints + privacy fix (v0.3.0) #17

Merged
padreug merged 4 commits from feat/public-guest-endpoints into main 2026-07-19 23:43:39 +00:00
Showing only changes of commit 408b0e1d08 - Show all commits

test: public endpoints + private-field strip

Asserts public_room_dict drops wallet + checkin_instructions, public list
shows active-only + stripped, and public get 404s on inactive. 32 pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019VUQCfdqiLSsFS2jcGnaFD
Padreug 2026-07-20 01:39:39 +02:00

View file

@ -0,0 +1,60 @@
"""Public guest discovery endpoints + the operator-private field strip
(privacy: check-in instructions must never reach a guest)."""
import asyncio
import pytest
from fastapi import HTTPException
from .. import crud, views_api
from ..models import RoomStatus, public_room_dict
from .conftest import make_room
def test_public_room_dict_strips_private_fields():
room = make_room(wallet="w1")
room.checkin_instructions = "gate code 4213, door on the left"
d = public_room_dict(room)
assert "wallet" not in d # operator-internal
assert "checkin_instructions" not in d # private, DM-only
assert d["title"] == "Tower Room" # public fields survive
assert d["price_amount"] == 100
def test_public_rooms_lists_active_only_and_stripped(monkeypatch):
active = make_room("a", status=RoomStatus.active)
active.checkin_instructions = "secret"
inactive = make_room("b", status=RoomStatus.inactive)
async def gr():
return [active, inactive]
monkeypatch.setattr(crud, "get_rooms", gr)
out = asyncio.run(views_api.api_public_rooms())
assert [r["id"] for r in out] == ["a"] # inactive hidden from guests
assert "checkin_instructions" not in out[0]
assert "wallet" not in out[0]
def test_public_room_404_when_inactive(monkeypatch):
async def gr(_):
return make_room(status=RoomStatus.inactive)
monkeypatch.setattr(crud, "get_room", gr)
with pytest.raises(HTTPException) as e:
asyncio.run(views_api.api_public_room("x"))
assert e.value.status_code == 404
def test_public_room_returns_stripped_when_active(monkeypatch):
room = make_room("a", status=RoomStatus.active)
room.checkin_instructions = "gate"
async def gr(_):
return room
monkeypatch.setattr(crud, "get_room", gr)
out = asyncio.run(views_api.api_public_room("a"))
assert out["id"] == "a"
assert "checkin_instructions" not in out
assert "wallet" not in out