""" Unit tests for the E2E fixture-mode switch in utils/groq_client.py. Scope: fixture mode is what lets the (not-yet-built) E2E/crawler suite walk the app without spending real Groq tokens — see docs/qa/test-strategy.md and the project-e2e-testing-design memory. These tests only verify the switch itself behaves correctly; they don't touch real Groq (ADR-0009 keeps that out of scope for automation). """ import importlib import os import pytest @pytest.fixture def fixture_mode(monkeypatch): """Reloads utils.groq_client with E2E_FIXTURE_MODE=1, then reloads it back off afterward so other tests aren't affected by module-level state.""" monkeypatch.setenv("E2E_FIXTURE_MODE", "1") import utils.groq_client as gc importlib.reload(gc) yield gc monkeypatch.delenv("E2E_FIXTURE_MODE", raising=False) importlib.reload(gc) def test_call_groq_json_returns_fixture_without_network(fixture_mode): data = fixture_mode.call_groq_json("system", "user", fixture="businessIdentity") assert data["businessName"] == "Ada's Fresh Kitchen" def test_call_groq_json_without_fixture_key_raises(fixture_mode): with pytest.raises(RuntimeError, match="no fixture key"): fixture_mode.call_groq_json("system", "user") def test_call_groq_json_missing_fixture_file_raises(fixture_mode): with pytest.raises(RuntimeError, match="no fixture file"): fixture_mode.call_groq_json("system", "user", fixture="does-not-exist") def test_call_groq_stream_yields_chunks_shaped_like_the_real_sdk(fixture_mode): chunks = list(fixture_mode.call_groq_stream("system", "user", fixture="chat_response")) assert len(chunks) > 1 rebuilt = "".join(c.choices[0].delta.content for c in chunks) assert "subscription" in rebuilt def test_call_groq_transcribe_returns_object_with_text(fixture_mode): result = fixture_mode.call_groq_transcribe(file=("a.webm", b"", "audio/webm"), fixture="transcript") assert "meals a day" in result.text @pytest.fixture def demo_mode(monkeypatch): monkeypatch.setenv("DEMO_MODE", "1") monkeypatch.setenv("E2E_FIXTURE_MODE", "1") import utils.groq_client as gc importlib.reload(gc) yield gc monkeypatch.delenv("E2E_FIXTURE_MODE", raising=False) monkeypatch.delenv("DEMO_MODE", raising=False) importlib.reload(gc) def test_demo_mode_turns_json_text_into_test_environment_but_keeps_structure(demo_mode): data = demo_mode.call_groq_json("system", "user", fixture="planning_tasks") tasks = data["suggestions"] assert tasks and all(t["title"] == "Test Environment" for t in tasks) assert all(t["column"] in {"todo", "in_progress", "done"} for t in tasks) def test_demo_mode_stream_says_test_environment(demo_mode): chunks = list(demo_mode.call_groq_stream("system", "user", fixture="chat_response")) assert "".join(c.choices[0].delta.content for c in chunks).strip() == "Test Environment" def test_demo_mode_needs_fixture_mode(): os.environ["DEMO_MODE"] = "1" try: import utils.groq_client as gc importlib.reload(gc) assert gc.DEMO_MODE is False finally: os.environ.pop("DEMO_MODE", None) importlib.reload(gc) def test_fixture_mode_is_off_by_default(): import utils.groq_client as gc importlib.reload(gc) assert gc.FIXTURE_MODE is False