Add unit test coverage for shared pure-logic modules (240 tests)
Track 1.1 of master plan: expand from sexp-only tests to cover DTOs, HTTP signatures, HMAC auth, URL utilities, Jinja filters, calendar helpers, config freeze, activity bus registry, parse utilities, sexp helpers, error classes, and jinja bridge render API. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
96
shared/tests/test_errors.py
Normal file
96
shared/tests/test_errors.py
Normal file
@@ -0,0 +1,96 @@
|
||||
"""Tests for error classes and error page rendering."""
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from shared.browser.app.errors import AppError, _error_page
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# AppError
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class TestAppError:
|
||||
def test_single_message(self):
|
||||
err = AppError("Something went wrong")
|
||||
assert str(err) == "Something went wrong"
|
||||
assert err.messages == ["Something went wrong"]
|
||||
assert err.status_code == 400
|
||||
|
||||
def test_custom_status_code(self):
|
||||
err = AppError("Not found", status_code=404)
|
||||
assert err.status_code == 404
|
||||
assert str(err) == "Not found"
|
||||
|
||||
def test_list_of_messages(self):
|
||||
err = AppError(["Error 1", "Error 2", "Error 3"])
|
||||
assert err.messages == ["Error 1", "Error 2", "Error 3"]
|
||||
assert str(err) == "Error 1" # first message as str
|
||||
|
||||
def test_tuple_of_messages(self):
|
||||
err = AppError(("A", "B"))
|
||||
assert err.messages == ["A", "B"]
|
||||
|
||||
def test_set_of_messages(self):
|
||||
err = AppError({"only one"})
|
||||
assert err.messages == ["only one"]
|
||||
|
||||
def test_empty_list(self):
|
||||
err = AppError([])
|
||||
assert err.messages == []
|
||||
assert str(err) == ""
|
||||
|
||||
def test_is_value_error(self):
|
||||
"""AppError should be catchable as ValueError for backwards compat."""
|
||||
err = AppError("test")
|
||||
assert isinstance(err, ValueError)
|
||||
|
||||
def test_default_status_is_400(self):
|
||||
err = AppError("test")
|
||||
assert err.status_code == 400
|
||||
|
||||
def test_integer_message_coerced(self):
|
||||
err = AppError([42, "text"])
|
||||
assert err.messages == ["42", "text"]
|
||||
|
||||
def test_status_code_override(self):
|
||||
err = AppError("conflict", status_code=409)
|
||||
assert err.status_code == 409
|
||||
|
||||
def test_messages_are_strings(self):
|
||||
err = AppError([None, 123, True])
|
||||
assert all(isinstance(m, str) for m in err.messages)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# _error_page
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class TestErrorPage:
|
||||
def test_returns_html_string(self):
|
||||
html = _error_page("Not Found")
|
||||
assert isinstance(html, str)
|
||||
assert "<!DOCTYPE html>" in html
|
||||
|
||||
def test_contains_message(self):
|
||||
html = _error_page("Something broke")
|
||||
assert "Something broke" in html
|
||||
|
||||
def test_contains_error_gif(self):
|
||||
html = _error_page("Error")
|
||||
assert "/static/errors/error.gif" in html
|
||||
|
||||
def test_contains_reload_link(self):
|
||||
html = _error_page("Error")
|
||||
assert "Reload" in html
|
||||
|
||||
def test_html_in_message(self):
|
||||
"""Messages can contain HTML (used by fragment_error handler)."""
|
||||
html = _error_page("The <b>account</b> service is unavailable")
|
||||
assert "<b>account</b>" in html
|
||||
|
||||
def test_self_contained(self):
|
||||
"""Error page should include its own styles (no external CSS deps)."""
|
||||
html = _error_page("Error")
|
||||
assert "<style>" in html
|
||||
assert "</style>" in html
|
||||
Reference in New Issue
Block a user