# tests/test_async_client.py
"""Tests for the async AsyncIhyee client."""
from __future__ import annotations

import pytest
import respx
from httpx import Response

from ihyee import AsyncIhyee
from ihyee.exceptions import AuthError, RateLimitError
from ihyee.models import FetchResponse, SearchResponse

from conftest import MOCK_ERROR_401, MOCK_ERROR_429, MOCK_FETCH_RESPONSE, MOCK_SEARCH_RESPONSE

BASE = "https://mock.ihyee.test"


class TestAsyncSearch:
    @respx.mock
    @pytest.mark.asyncio
    async def test_search_returns_typed_response(self):
        respx.post(f"{BASE}/v1/search").mock(
            return_value=Response(200, json=MOCK_SEARCH_RESPONSE)
        )
        async with AsyncIhyee(api_key="key", base_url=BASE) as client:
            result = await client.search("test query")
        assert isinstance(result, SearchResponse)
        assert result.content[0].text.summary == "A short summary."


class TestAsyncFetch:
    @respx.mock
    @pytest.mark.asyncio
    async def test_fetch_returns_typed_response(self):
        respx.post(f"{BASE}/v1/fetch").mock(
            return_value=Response(200, json=MOCK_FETCH_RESPONSE)
        )
        async with AsyncIhyee(api_key="key", base_url=BASE) as client:
            result = await client.fetch(["https://example.com"])
        assert isinstance(result, FetchResponse)


class TestAsyncRender:
    @respx.mock
    @pytest.mark.asyncio
    async def test_render_returns_typed_response(self):
        respx.post(f"{BASE}/v1/render").mock(
            return_value=Response(200, json=MOCK_FETCH_RESPONSE)
        )
        async with AsyncIhyee(api_key="key", base_url=BASE) as client:
            result = await client.render("https://spa.example.com")
        assert isinstance(result, FetchResponse)


class TestAsyncErrors:
    @respx.mock
    @pytest.mark.asyncio
    async def test_401_raises_auth_error(self):
        respx.post(f"{BASE}/v1/search").mock(
            return_value=Response(401, json=MOCK_ERROR_401)
        )
        async with AsyncIhyee(api_key="bad", base_url=BASE) as client:
            with pytest.raises(AuthError):
                await client.search("test")

    @respx.mock
    @pytest.mark.asyncio
    async def test_429_raises_rate_limit(self):
        respx.post(f"{BASE}/v1/fetch").mock(
            return_value=Response(429, json=MOCK_ERROR_429)
        )
        async with AsyncIhyee(api_key="key", base_url=BASE) as client:
            with pytest.raises(RateLimitError) as exc:
                await client.fetch(["https://example.com"])
        assert exc.value.retry_after == 30
