Files
mroberts 7f5d034a1f feat: auth by default, theme toggle, CoderPad startup, review fixes
- Require a session on every route; public routes opt out with @allow_anonymous
- Split password hashing and pepper loading into passwords.py
- Add a system/light/dark theme toggle backed by light-dark() colors
- Ignore stale 401s from an earlier session, PATCH only changed book fields,
  and block overlapping journal-entry saves
- Add bin/start and CoderPad Vite server settings for the pad's start/restart
- Rewrite README as a mise onboarding guide; expand .gitignore
- Include review-round fixes and tests
2026-10-02 16:49:14 -05:00

76 lines
2.7 KiB
Python

import os
import subprocess
import sys
from pathlib import Path
import db
from tests.support import HTTPS, ApiTestCase, app, db_execute
SCHEMA = Path(__file__).parent.parent / "schema.sql"
class AppTests(ApiTestCase):
def test_health(self):
response = self.call("GET", "/api/health")
self.assertEqual(response.status_code, 200)
self.assertEqual(response.get_json(), {"status": "ok"})
def test_genres_seeded_and_reseeding_is_idempotent(self):
before = db_execute("SELECT last_value FROM genres_id_seq")[0][0]
db_execute(SCHEMA.read_text())
db_execute(SCHEMA.read_text())
self.assertEqual(db_execute("SELECT count(*) FROM genres")[0][0], 16)
self.assertEqual(
db_execute("SELECT last_value FROM genres_id_seq")[0][0], before
)
def test_unknown_route_returns_json_404(self):
response = self.call("GET", "/api/nope")
self.assertEqual(response.status_code, 404)
self.assertIn("error", response.get_json())
def test_mutation_without_json_content_type_is_rejected(self):
response = self.client.post(
"/api/health", data="x", content_type="text/plain", base_url=HTTPS
)
self.assertEqual(response.status_code, 400)
self.assertEqual(
response.get_json(),
{"error": "Request body must be JSON with Content-Type: application/json"},
)
def test_oversized_body_is_rejected_before_parsing(self):
response = self.call(
"POST",
"/api/auth/login",
{"username": "a", "password": "x" * (2 * 1024 * 1024)},
)
self.assertEqual(response.status_code, 413)
self.assertIn("error", response.get_json())
class ConnectionReleaseTests(ApiTestCase):
def test_closed_connection_is_discarded_instead_of_leaking_a_pool_slot(self):
pool = app.extensions["db_pool"]
with self.assertLogs("db", "WARNING"):
for _ in range(pool.maxconn + 1):
with app.app_context():
db.query("SELECT 1")
db._connection().close()
with app.app_context():
self.assertEqual(db.query("SELECT 1 AS one"), [{"one": 1}])
class AppFactoryTests(ApiTestCase):
def test_importing_the_app_module_does_not_connect_to_the_database(self):
result = subprocess.run(
[sys.executable, "-c", "import app"],
cwd=Path(__file__).parent.parent,
env=os.environ | {"DATABASE_URL": "postgresql://[email protected]:9/none"},
capture_output=True,
text=True,
timeout=30,
check=False,
)
self.assertEqual(result.returncode, 0, result.stderr)