animetix-brain / tests /api /test_views_api_coverage.py
MissawB's picture
Upload folder using huggingface_hub
b1e14ec verified
Raw
History Blame Contribute Delete
3.47 kB
"""Coverage tests for animetix.views.api.
``get_task_status`` is a module-level function view that is not wired into the
URL conf via this module (the routed streaming endpoints live in
``animetix.api.streams``). It is driven directly with a ``RequestFactory``
request, with the ``get_session_service`` collaborator patched at the module
level so no real DI / cache is exercised.
"""
import json
from unittest.mock import MagicMock, patch
import pytest
from animetix.views import api as api_mod
from django.core.cache import cache
from django.test import RequestFactory
@pytest.fixture
def rf():
return RequestFactory()
def _sse_events(response):
"""Decode a StreamingHttpResponse into a list of parsed SSE payloads."""
events = []
for chunk in response.streaming_content:
text = chunk.decode("utf-8") if isinstance(chunk, bytes) else chunk
for line in text.splitlines():
line = line.strip()
if line.startswith("data: "):
events.append(json.loads(line[len("data: ") :]))
return events
# --------------------------------------------------------------------------- #
# get_task_status
# --------------------------------------------------------------------------- #
@pytest.mark.django_db
def test_get_task_status_not_ready_returns_204(rf):
cache.clear()
request = rf.get("/x")
with patch.object(api_mod, "get_session_service", return_value=MagicMock()):
resp = api_mod.get_task_status(request, "task-1")
assert resp.status_code == 204
@pytest.mark.django_db
def test_get_task_status_ready_json_result(rf):
cache.set("task_result:task-2", {"ready": True, "result": {"answer": 42}})
request = rf.get("/x")
with patch.object(api_mod, "get_session_service", return_value=MagicMock()):
resp = api_mod.get_task_status(request, "task-2")
assert resp.status_code == 200
assert json.loads(resp.content)["result"] == {"answer": 42}
@pytest.mark.django_db
def test_get_task_status_ready_scenario_renders_fragment(rf):
cache.set(
"task_result:task-3",
{
"ready": True,
"result": {
"scenario": "The Forge",
"reasoning": "because",
"fusion_image": "img.png",
},
},
)
session = MagicMock()
session.get.side_effect = lambda k: {"temp_item_A": "A", "temp_item_B": "B"}.get(k)
request = rf.get("/x")
# render() is the dict-with-"scenario" branch; patch it so we don't depend on the
# archetypist template being collected. Assert the view returned its result.
sentinel = MagicMock(status_code=200)
with (
patch.object(api_mod, "get_session_service", return_value=session),
patch.object(api_mod, "render", return_value=sentinel) as render_mock,
):
resp = api_mod.get_task_status(request, "task-3")
render_mock.assert_called_once()
# the fragment context wires the scenario through to the template
assert render_mock.call_args.args[2]["scenario"] == "The Forge"
assert resp is sentinel
@pytest.mark.django_db
def test_get_task_status_cache_error_returns_204(rf):
request = rf.get("/x")
with (
patch.object(api_mod, "get_session_service", return_value=MagicMock()),
patch.object(api_mod.cache, "get", side_effect=RuntimeError("boom")),
):
resp = api_mod.get_task_status(request, "task-err")
assert resp.status_code == 204