import httpx
import pytest
from app.clients.qweather_client import QWeatherClient
from app.schemas.weather import map_qweather_now_to_result
@pytest.mark.asyncio
async def test_map_qweather_now_to_result_parses_fields() -> None:
raw = {
"code": "200",
"now": {
"obsTime": "2025-12-13T15:00:00+08:00",
"temp": "12",
"text": "多云",
"humidity": "55",
"windSpeed": "5.4",
"windDir": "西北风",
},
}
result = map_qweather_now_to_result(location="Beijing", raw=raw)
assert result.location == "Beijing"
assert result.observed_at.isoformat() == "2025-12-13T15:00:00+08:00"
assert result.temperature == 12.0
assert result.condition == "多云"
assert result.humidity == 55
assert result.wind_speed == 5.4
assert result.wind_dir == "西北风"
@pytest.mark.asyncio
async def test_qweather_client_city_name_resolves_geo_and_fetches_weather() -> None:
def handler(request: httpx.Request) -> httpx.Response:
if request.url.path == "/geo/v2/city/lookup":
# GeoAPI returns a canonical city name and location id.
return httpx.Response(
200,
json={
"code": "200",
"location": [{"name": "Beijing", "id": "101010100"}],
},
)
if request.url.path == "/v7/weather/now":
assert request.url.params.get("location") == "101010100"
return httpx.Response(
200,
json={
"code": "200",
"now": {
"obsTime": "2025-12-13T15:00:00+08:00",
"temp": "12",
"text": "多云",
"humidity": "55",
"windSpeed": "5.4",
"windDir": "西北风",
},
},
)
raise AssertionError(f"unexpected path: {request.url.path}")
transport = httpx.MockTransport(handler)
async with QWeatherClient(
api_host="https://example.qweatherapi.com",
api_key="test_key",
transport=transport,
) as client:
display_location, raw = await client.get_weather_now(
location="北京",
lang="zh",
geo_lang="en",
unit="m",
resolve_city_name=True,
)
assert display_location == "Beijing"
assert raw["code"] == "200"