"""The liveness endpoint, the session guard and CSRF - no application logic.
These are the tests that stay true whatever this app turns into, which is why
they are the ones the skeleton ships. Each asserts a property of the *default*,
so a route added later inherits it or fails here.
"""
import pytest
from tests.conftest import PASSWORD, csrf_for
def test_healthz_is_public(app_client):
r = app_client.get("/healthz")
assert r.status_code == 200
assert r.get_json() == {"status": "ok"}
def test_health_alias(app_client):
assert app_client.get("/health").status_code == 200
def test_api_requires_a_session(app_client):
"""An unauthenticated API call is a JSON 401, not an HTML redirect - a
fetch() that receives a login page reports a parse error instead of the thing
that actually happened."""
r = app_client.get("/api/me")
assert r.status_code == 401
assert "error" in r.get_json()
def test_a_page_redirects_to_login(app_client):
r = app_client.get("/")
assert r.status_code == 302
assert r.headers["Location"].endswith("/login")
def test_an_unknown_route_is_guarded_not_404(app_client):
"""The guard runs before routing, so a signed-out caller cannot probe which
paths exist. This is the allowlist's whole point: protection is the default,
not something each route opts into."""
r = app_client.get("/api/something-nobody-has-written-yet")
assert r.status_code == 401
def test_static_is_reachable_signed_out(app_client):
assert app_client.get("/static/js/app.js").status_code == 200
def test_a_write_without_the_csrf_token_is_refused(account):
client, _user, _org = account
r = client.post("/api/password", json={"current": PASSWORD, "new": "x" * 14})
assert r.status_code == 403
assert "Stale page" in r.get_json()["error"]
def test_a_write_with_the_csrf_token_is_allowed(account):
client, user, _org = account
r = client.post("/api/password",
json={"current": PASSWORD, "new": "a-longer-new-password"},
headers={"X-CSRF-Token": csrf_for(client)})
assert r.status_code == 200, r.get_json()
@pytest.mark.parametrize("path", ["/login", "/api/login", "/health", "/healthz"])
def test_the_allowlist_is_exactly_what_it_says(app_client, path):
"""Every public path is public because a comment in crud.PUBLIC_PATHS says
why. If this list grows, that comment is the review."""
from app.endpoints.crud import is_public
assert is_public(path)