diff --git a/pyproject.toml b/pyproject.toml index a03038f..2ddb9e0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,6 +37,10 @@ explicit_package_bases = true module = "pytest" ignore_missing_imports = true +[[tool.mypy.overrides]] +module = "fakeredis" +ignore_missing_imports = true + [tool.pytest.ini_options] testpaths = ["tests"] addopts = "-v --tb=short" diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/app.py b/src/app.py new file mode 100644 index 0000000..a981949 --- /dev/null +++ b/src/app.py @@ -0,0 +1,22 @@ +from flask import Flask + +from src.queue.handler import QueueHandler + + +def create_app() -> Flask: + """Erstellt und konfiguriert die Flask-App.""" + app = Flask(__name__) + app.config.from_mapping( + REDIS_HOST="localhost", + REDIS_PORT=6379, + ) + app.queue_handler = QueueHandler( # type: ignore[attr-defined] + redis_host=app.config["REDIS_HOST"], + redis_port=app.config["REDIS_PORT"], + ) + + @app.route("/health") + def health() -> dict[str, object]: + return {"status": "ok", "queue_size": app.queue_handler.queue_size()} # type: ignore[attr-defined] + + return app diff --git a/tests/test_app.py b/tests/test_app.py new file mode 100644 index 0000000..246751e --- /dev/null +++ b/tests/test_app.py @@ -0,0 +1,62 @@ +"""Tests für die Flask-App-Factory mit fakeredis.""" + +from __future__ import annotations + +import fakeredis +from flask import Flask +from flask.testing import FlaskClient + +from src.app import create_app +from src.queue.handler import QueueHandler + + +def test_create_app_returns_flask_app() -> None: + """create_app() liefert eine Flask-App-Instanz zurück.""" + app = create_app() + assert isinstance(app, Flask) + + +def test_health_returns_status_ok() -> None: + """GET /health liefert 200 und JSON mit status=ok.""" + app = create_app() + + # QueueHandler mit fakeredis ersetzen + fake_redis = fakeredis.FakeRedis(decode_responses=True) + qh = QueueHandler.__new__(QueueHandler) + qh.redis = fake_redis + qh.stream_key = "bsn:submissions" + qh.processed_set = "bsn:processed" + qh.stream_ids_hash = "bsn:stream_ids" + qh.group_name = "bsn-workers" + qh._ensure_consumer_group() + app.queue_handler = qh # type: ignore[attr-defined] + + client: FlaskClient = app.test_client() + response = client.get("/health") + assert response.status_code == 200 + data = response.get_json() + assert data is not None + assert data["status"] == "ok" + + +def test_health_queue_size_is_integer() -> None: + """GET /health liefert queue_size als Integer.""" + app = create_app() + + # QueueHandler mit fakeredis ersetzen + fake_redis = fakeredis.FakeRedis(decode_responses=True) + qh = QueueHandler.__new__(QueueHandler) + qh.redis = fake_redis + qh.stream_key = "bsn:submissions" + qh.processed_set = "bsn:processed" + qh.stream_ids_hash = "bsn:stream_ids" + qh.group_name = "bsn-workers" + qh._ensure_consumer_group() + app.queue_handler = qh # type: ignore[attr-defined] + + client = app.test_client() + response = client.get("/health") + assert response.status_code == 200 + data = response.get_json() + assert data is not None + assert isinstance(data["queue_size"], int)