"""ai/scenario_client.py — voir plan Phase 2, §3 : jamais un vrai appel réseau ici (requests.post/get monkeypatchés), et une configuration incomplète (clé/secret/modèle absents) doit échouer proprement AVANT toute tentative réseau.""" import ai from ai.scenario_client import generate_image_url def test_generate_image_url_raises_when_not_configured(): try: generate_image_url("un bureau moderne") assert False, "devrait lever ScenarioNotConfiguredError" except ai.ScenarioNotConfiguredError: pass class _FakeResponse: def __init__(self, json_data): self._json = json_data def raise_for_status(self): pass def json(self): return self._json def test_generate_image_url_polls_until_success_then_returns_the_asset_url(monkeypatch): monkeypatch.setenv("SCENARIO_API_KEY", "fake-key") monkeypatch.setenv("SCENARIO_API_SECRET", "fake-secret") monkeypatch.setenv("SCENARIO_MODEL_ID", "fake-model") calls = {"jobs": 0} def fake_post(url, auth=None, json=None, timeout=None): assert url.endswith("/generate/txt2img") assert json["prompt"] == "un bureau moderne" assert json["modelId"] == "fake-model" return _FakeResponse({"job": {"jobId": "job_1"}}) def fake_get(url, auth=None, timeout=None): if "/jobs/" in url: calls["jobs"] += 1 # Simule un job encore en cours au premier appel, réussi ensuite. status = "running" if calls["jobs"] == 1 else "success" body = {"job": {"status": status}} if status == "success": body["job"]["metadata"] = {"assetIds": ["asset_1"]} return _FakeResponse(body) assert url.endswith("/assets/asset_1") return _FakeResponse({"asset": {"url": "https://scenario.example/final.png"}}) monkeypatch.setattr("ai.scenario_client.requests.post", fake_post) monkeypatch.setattr("ai.scenario_client.requests.get", fake_get) monkeypatch.setattr("ai.scenario_client.time.sleep", lambda s: None) url = generate_image_url("un bureau moderne") assert url == "https://scenario.example/final.png" assert calls["jobs"] == 2 def test_generate_image_url_raises_on_job_failure(monkeypatch): monkeypatch.setenv("SCENARIO_API_KEY", "fake-key") monkeypatch.setenv("SCENARIO_API_SECRET", "fake-secret") monkeypatch.setenv("SCENARIO_MODEL_ID", "fake-model") monkeypatch.setattr("ai.scenario_client.requests.post", lambda *a, **k: _FakeResponse({"job": {"jobId": "job_1"}})) monkeypatch.setattr("ai.scenario_client.requests.get", lambda *a, **k: _FakeResponse({"job": {"status": "failure"}})) try: generate_image_url("un bureau") assert False, "devrait lever ScenarioGenerationError" except ai.ScenarioGenerationError: pass