import pytest from inkwell.app import create_app @pytest.fixture def app(): return create_app() async def test_create_device_requires_auth(app): # No session cookie and no bearer header → 401 before any DB access. client = app.test_client() resp = await client.post("/api/auth/devices", json={"name": "phone"}) assert resp.status_code == 401 async def test_list_devices_requires_auth(app): client = app.test_client() resp = await client.get("/api/auth/devices") assert resp.status_code == 401 async def test_revoke_device_requires_auth(app): client = app.test_client() resp = await client.delete("/api/auth/devices/00000000-0000-0000-0000-000000000000") assert resp.status_code == 401 async def test_revoke_self_requires_auth(app): client = app.test_client() resp = await client.delete("/api/auth/devices/self") assert resp.status_code == 401 def test_revoke_self_routes_to_the_self_revoke_view(app): # The static rule must win over `/devices/`, or "self" would be read as # a malformed UUID and 404. Checked on the URL map, because every route behind # login_required reads the database. The view's 400 is in test_integration.py. endpoint, _ = app.url_map.bind("localhost").match("/api/auth/devices/self", method="DELETE") assert endpoint == "auth.revoke_own_device" async def test_device_login_validates_input(app): # Missing credentials → 400 before any DB access, so it's checkable without a # database. The other paths are in test_integration.py. client = app.test_client() resp = await client.post("/api/auth/device-login", json={}) assert resp.status_code == 400