"""Unit tests for core.cache.""" import pytest from flask import Flask from core.cache import cache_max_age, cache_reference_data @pytest.fixture(autouse=True) def test_app_in_context(): """No-op override: these tests don't need a DB-backed app context.""" yield @pytest.fixture(autouse=True) def test_app_request(): """No-op override: these tests don't need a request context.""" yield @pytest.fixture def app(): """Minimal Flask app with routes that exercise cache_max_age.""" _app = Flask(__name__) @_app.route('/cached') @cache_max_age(60) def cached_view(): """Return 200 with a 60-second cache.""" from flask import make_response return make_response('ok', 200) @_app.route('/no-cache') @cache_max_age(0) def no_cache_view(): """Return 200 with caching disabled (ttl=0).""" from flask import make_response return make_response('ok', 200) @_app.route('/error') @cache_max_age(60) def error_view(): """Return 404 — cache header should not be set.""" from flask import make_response return make_response('not found', 404) @_app.route('/callable') @cache_max_age(lambda: 120) def callable_ttl_view(): """Return 200 with TTL sourced from a callable.""" from flask import make_response return make_response('ok', 200) @_app.route('/reference') @cache_reference_data def reference_view(): """Return 200 cached via the reference-data binding.""" from flask import make_response return make_response('ok', 200) return _app def test_sets_max_age_on_200(app): """Cache-Control: public, max-age is set on a successful response.""" with app.test_client() as client: res = client.get('/cached') assert res.status_code == 200 assert res.cache_control.max_age == 60 assert res.cache_control.public is True def test_sets_vary_authorization_on_cached_response(app): """A cached 2xx response carries Vary: Authorization. This keys a shared cache per caller so it cannot replay a 200 to a would-be-403 identity. """ with app.test_client() as client: assert 'Authorization' in client.get('/cached').vary def test_no_vary_authorization_when_not_cached(app): """Vary: Authorization is added only when the response is actually cached.""" with app.test_client() as client: assert 'Authorization' not in client.get('/no-cache').vary # ttl=0 assert 'Authorization' not in client.get('/error').vary # non-2xx def test_no_header_when_ttl_is_zero(app): """No Cache-Control header when TTL is 0.""" with app.test_client() as client: res = client.get('/no-cache') assert res.cache_control.max_age is None def test_no_header_on_non_2xx(app): """No Cache-Control header on non-2xx responses.""" with app.test_client() as client: res = client.get('/error') assert res.status_code == 404 assert res.cache_control.max_age is None def test_callable_ttl(app): """TTL callable is invoked at request time.""" with app.test_client() as client: res = client.get('/callable') assert res.cache_control.max_age == 120 def test_reference_binding_reads_config_at_request_time(app): """cache_reference_data honors OWS_REFERENCE_CACHE_TTL_SECONDS from config.""" app.config['OWS_REFERENCE_CACHE_TTL_SECONDS'] = 42 with app.test_client() as client: res = client.get('/reference') assert res.cache_control.max_age == 42 assert res.cache_control.public is True def test_reference_binding_disabled_when_ttl_zero(app): """cache_reference_data sets no cache header when the config TTL is 0.""" app.config['OWS_REFERENCE_CACHE_TTL_SECONDS'] = 0 with app.test_client() as client: res = client.get('/reference') assert res.cache_control.max_age is None assert not res.cache_control.public