Files
app/backend/tests/api/routes/test_session.py
T
Melvin StroblandClaude Fable 5 c254d487ba Recover from a dead session, and report a node problem once
An expired or orphaned session left the app on a half-rendered page instead of
the login screen: a properly signed token naming a user who no longer exists
answered 404, which the client does not treat as an authentication failure. All
failures in get_current_user are 401 now, and the client stops retrying them,
so a dead session goes straight back to the login screen.

- Clicking an edge names the two nodes it runs between, not just the message.
- A node with a problem shows one badge carrying the whole explanation, rather
  than a corner badge and a status dot saying the same thing twice. The dot is
  back to what it is good at: whether the node ran.
- The sidebar's collapse control sits in the sidebar, where a phone still finds
  one in the chrome because there is no sidebar on screen to hold it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WzrvW7rjQbynnhF6pxh6i
2026-08-15 19:19:57 +02:00

46 lines
1.4 KiB
Python

"""A session the server will not accept must say so as an auth failure.
The client clears the stored token and returns to the login screen on 401. Any
other status leaves the browser holding a token that can never work, stuck on a
page that will not load.
"""
import uuid
from datetime import timedelta
from fastapi.testclient import TestClient
from app.core import security
from app.core.config import settings
PROTECTED = [
f"{settings.API_V1_STR}/users/me",
f"{settings.API_V1_STR}/flows/",
]
def token_for(subject: str) -> str:
return security.create_access_token(subject, timedelta(days=1))
def test_no_token_is_unauthorised(client: TestClient) -> None:
for path in PROTECTED:
assert client.get(path).status_code == 401
def test_a_token_we_did_not_sign_is_unauthorised(client: TestClient) -> None:
headers = {"Authorization": "Bearer not.a.real.token"}
for path in PROTECTED:
assert client.get(path, headers=headers).status_code == 401
def test_a_token_for_a_user_who_is_gone_is_unauthorised(
client: TestClient,
) -> None:
# Properly signed, but the user it names no longer exists — which is what a
# browser holds after the database is reset.
headers = {"Authorization": f"Bearer {token_for(str(uuid.uuid4()))}"}
for path in PROTECTED:
response = client.get(path, headers=headers)
assert response.status_code == 401, path