"""Tests for the CLIENT_SECRET_KEY default guard (#33). Uses the raw function (config.guard_default_secret_key) for the unit-level cases, and the app's wired before_request hook for one end-to-end check. """ import pytest from flask import Flask from config import DEFAULT_SECRET_KEY, guard_default_secret_key def _app(secret_key, debug=False, testing=False): app = Flask(__name__) app.config["SECRET_KEY"] = secret_key app.config["DEBUG"] = debug app.config["TESTING"] = testing return app class TestGuardFunction: def test_default_key_in_production_raises(self): app = _app(DEFAULT_SECRET_KEY, debug=False, testing=False) with pytest.raises(RuntimeError, match="CLIENT_SECRET_KEY"): guard_default_secret_key(app) def test_default_key_with_debug_is_allowed(self): app = _app(DEFAULT_SECRET_KEY, debug=True, testing=False) guard_default_secret_key(app) # must not raise def test_default_key_with_testing_is_allowed(self): app = _app(DEFAULT_SECRET_KEY, debug=False, testing=True) guard_default_secret_key(app) # must not raise def test_custom_key_in_production_is_allowed(self): app = _app("a-real-random-secret", debug=False, testing=False) guard_default_secret_key(app) # must not raise class TestGuardWiredInApp: """The before_request hook registered in create_app() behaves the same way.""" def test_default_key_not_debug_not_testing_raises_on_request(self, monkeypatch): monkeypatch.delenv("FLASK_DEBUG", raising=False) monkeypatch.delenv("CLIENT_SECRET_KEY", raising=False) monkeypatch.setenv("STATION_CODE", "ST-TEST") import config import importlib importlib.reload(config) from app import create_app app = create_app() # Neither debug nor testing set - the production-like case (#33). assert app.config["SECRET_KEY"] == config.DEFAULT_SECRET_KEY assert app.debug is False assert app.testing is False with app.test_request_context("/auth/login"): with pytest.raises(RuntimeError, match="CLIENT_SECRET_KEY"): app.preprocess_request() def test_testing_flag_lets_requests_through(self, monkeypatch): """This is exactly the ordering the whole suite relies on: fixtures call create_app() then set TESTING=True afterwards, and the guard must still see it (checked per-request, not at create_app time).""" monkeypatch.setenv("STATION_CODE", "ST-TEST") import config import importlib importlib.reload(config) from app import create_app app = create_app() app.config["TESTING"] = True with app.test_client() as c: resp = c.get("/auth/login") assert resp.status_code == 200