import os from collections.abc import Callable from typing import Literal import httpx import pytest from _pytest.monkeypatch import MonkeyPatch def mock_get(*args, **kwargs): if kwargs.get("headers", {}).get("Authorization") != "Bearer test": raise httpx.HTTPStatusError( "Invalid API key", request=httpx.Request("GET", ""), response=httpx.Response(401), ) return httpx.Response( 200, json={ "items": [ {"title": "Model 1", "_id": "model1"}, {"title": "Model 2", "_id": "model2"}, ] }, request=httpx.Request("GET", ""), ) def mock_stream(*args, **kwargs): class MockStreamResponse: def __init__(self): self.status_code = 200 def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): pass def iter_bytes(self): yield b"Mocked audio data" return MockStreamResponse() def mock_fishaudio( monkeypatch: MonkeyPatch, methods: list[Literal["list-models", "tts"]], ) -> Callable[[], None]: """ mock fishaudio module :param monkeypatch: pytest monkeypatch fixture :return: unpatch function """ def unpatch() -> None: monkeypatch.undo() if "list-models" in methods: monkeypatch.setattr(httpx, "get", mock_get) if "tts" in methods: monkeypatch.setattr(httpx, "stream", mock_stream) return unpatch MOCK = os.getenv("MOCK_SWITCH", "false").lower() == "true" @pytest.fixture def setup_fishaudio_mock(request, monkeypatch): methods = request.param if hasattr(request, "param") else [] if MOCK: unpatch = mock_fishaudio(monkeypatch, methods=methods) yield if MOCK: unpatch()