"""Tests for the shallow readiness probe and its /ready/ view. The probe never connects to a real DB here: ``_probe`` / ``is_ready`` are patched. What is pinned is the TTL-cache bust behaviour and the view's status-code contract (200 ok / 503 unavailable). """ from unittest.mock import patch from flask import Flask from core.blueprints.base import base_api from core.hardening import readiness def test_ready_false_when_db_raises() -> None: """A failing probe makes the service report not-ready.""" with patch.object(readiness, '_probe', side_effect=Exception('db down')): readiness._CACHE['at'] = 0.0 # bust cache assert readiness.is_ready() is False def test_ready_true_when_probe_ok() -> None: """A clean probe makes the service report ready.""" with patch.object(readiness, '_probe', return_value=None): readiness._CACHE['at'] = 0.0 # bust cache assert readiness.is_ready() is True def test_is_ready_serves_cached_value_within_ttl() -> None: """Within the TTL, a second call returns the cached result without re-probing.""" calls = {'n': 0} def probe() -> None: calls['n'] += 1 with patch.object(readiness, '_probe', side_effect=probe): readiness._CACHE['at'] = 0.0 # bust so the first call probes and caches assert readiness.is_ready() is True assert calls['n'] == 1 assert readiness.is_ready() is True # within TTL: served from cache assert calls['n'] == 1 # _probe was not called again def _client() -> Flask: app = Flask(__name__) app.register_blueprint(base_api) return app def test_ready_view_returns_200_when_ready() -> None: """GET /ready/ returns 200 ok when the service is ready.""" app = _client() with patch('core.blueprints.base.is_ready', return_value=True): resp = app.test_client().get('/ready/') assert resp.status_code == 200 assert resp.get_json() == {'status': 'ok'} def test_ready_view_returns_503_when_not_ready() -> None: """GET /ready/ returns 503 unavailable when the service is not ready.""" app = _client() with patch('core.blueprints.base.is_ready', return_value=False): resp = app.test_client().get('/ready/') assert resp.status_code == 503 assert resp.get_json() == {'status': 'unavailable'}