5 tests calling the view functions directly with a fake auth key: _owned_room 403/404, list-rooms wallet filter, room update applies only mutable fields (wallet/id immutable), settings PUT merges editable fields. 28 pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019VUQCfdqiLSsFS2jcGnaFD
93 lines
2.9 KiB
Python
93 lines
2.9 KiB
Python
"""Operator admin endpoint logic (backs the admin UI). Calls the view
|
|
functions directly with a fake auth key (bypassing FastAPI's Depends) and
|
|
monkeypatched crud — no live server."""
|
|
|
|
import asyncio
|
|
from types import SimpleNamespace
|
|
|
|
import pytest
|
|
from fastapi import HTTPException
|
|
|
|
from .. import crud, views_api
|
|
from ..models import ChateletSettings, CreateRoomData, RoomStatus
|
|
from .conftest import make_room
|
|
|
|
|
|
def _key(wallet_id: str = "w1"):
|
|
return SimpleNamespace(wallet=SimpleNamespace(id=wallet_id, user="u1"))
|
|
|
|
|
|
def test_owned_room_rejects_other_wallet(monkeypatch):
|
|
async def gr(_):
|
|
return make_room(wallet="w1")
|
|
|
|
monkeypatch.setattr(crud, "get_room", gr)
|
|
with pytest.raises(HTTPException) as e:
|
|
asyncio.run(views_api._owned_room("room1", _key("w2")))
|
|
assert e.value.status_code == 403
|
|
|
|
|
|
def test_owned_room_404_when_missing(monkeypatch):
|
|
async def gr(_):
|
|
return None
|
|
|
|
monkeypatch.setattr(crud, "get_room", gr)
|
|
with pytest.raises(HTTPException) as e:
|
|
asyncio.run(views_api._owned_room("nope", _key()))
|
|
assert e.value.status_code == 404
|
|
|
|
|
|
def test_list_rooms_filters_to_calling_wallet(monkeypatch):
|
|
async def gr():
|
|
return [make_room("a", wallet="w1"), make_room("b", wallet="w2")]
|
|
|
|
monkeypatch.setattr(crud, "get_rooms", gr)
|
|
out = asyncio.run(views_api.api_list_rooms(key=_key("w1")))
|
|
assert [r.id for r in out] == ["a"]
|
|
|
|
|
|
def test_update_room_applies_mutable_fields_only(monkeypatch):
|
|
room = make_room("room1", wallet="w1", status=RoomStatus.inactive)
|
|
|
|
async def gr(_):
|
|
return room
|
|
|
|
async def ur(r):
|
|
return r
|
|
|
|
monkeypatch.setattr(crud, "get_room", gr)
|
|
monkeypatch.setattr(crud, "update_room", ur)
|
|
|
|
data = CreateRoomData(
|
|
wallet="attacker", title="New Title", price_amount=200,
|
|
price_currency="USD", max_guests=5, checkin_instructions="gate 7",
|
|
)
|
|
out = asyncio.run(views_api.api_update_room("room1", data, key=_key("w1")))
|
|
assert out.title == "New Title"
|
|
assert out.price_amount == 200
|
|
assert out.checkin_instructions == "gate 7"
|
|
assert out.wallet == "w1" # wallet is NOT client-mutable
|
|
assert out.id == "room1" # id unchanged
|
|
|
|
|
|
def test_update_settings_merges_editable_fields(monkeypatch):
|
|
existing = ChateletSettings(operator_id=None, deposit_percent=100)
|
|
|
|
async def gs():
|
|
return existing
|
|
|
|
async def us(s):
|
|
return s
|
|
|
|
monkeypatch.setattr(crud, "get_or_create_settings", gs)
|
|
monkeypatch.setattr(crud, "update_settings", us)
|
|
|
|
incoming = ChateletSettings(
|
|
operator_id="op1", deposit_percent=50, default_hold_minutes=45,
|
|
relays=["wss://relay.example"],
|
|
)
|
|
out = asyncio.run(views_api.api_update_settings(incoming, key=_key()))
|
|
assert out.operator_id == "op1"
|
|
assert out.deposit_percent == 50
|
|
assert out.default_hold_minutes == 45
|
|
assert out.relays == ["wss://relay.example"]
|