diff --git a/tests/test_cli.py b/tests/test_cli.py index 10b673a5..d73cfbe0 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -39,7 +39,6 @@ ) from weather_briefing.composition.providers import ( PUBLISHER_BUILDERS, - WEATHER_PROVIDER_BUILDERS, _build_jma, _build_nea, _build_open_meteo, @@ -1490,8 +1489,24 @@ def test_parse_run_time_returns_now_when_value_is_none(monkeypatch) -> None: assert result.timezone_name == "Asia/Shanghai" -def test_runtime_provider_builders_cover_declared_configuration_names() -> None: - assert set(WEATHER_PROVIDER_BUILDERS) == set(WeatherProviderName) +@pytest.mark.parametrize("name", tuple(WeatherProviderName)) +async def test_build_weather_provider_dispatch_is_exhaustive( + async_client: httpx.AsyncClient, + name: WeatherProviderName, +) -> None: + settings = _make_fake_settings( + qweather_project_id="project", + qweather_credential_id="credential", + qweather_private_key=base64.b64encode(b"fake-private-key-content").decode(), + qweather_base_url="https://qweather.example.invalid", + ) + + provider = _build_weather_provider(name, settings, async_client, jma_office_code="130000") + + assert provider is not None + + +def test_publisher_builders_cover_declared_configuration_names() -> None: assert set(PUBLISHER_BUILDERS) == set(PublisherName) diff --git a/weather_briefing/composition/providers.py b/weather_briefing/composition/providers.py index 491b01cc..6c2be3eb 100644 --- a/weather_briefing/composition/providers.py +++ b/weather_briefing/composition/providers.py @@ -258,16 +258,15 @@ def build_weather_provider( jma_office_code: str | None = None, ) -> WeatherContextProvider: """Build one configured weather provider adapter.""" - builder = WEATHER_PROVIDER_BUILDERS.get(name) - if builder is None: - raise ValueError(f"Unsupported weather provider: {name}") if name == WeatherProviderName.QWEATHER: return _build_qweather(settings, client, output_language=output_language) + if name == WeatherProviderName.OPEN_METEO: + return _build_open_meteo(settings, client) if name == WeatherProviderName.NEA_SINGAPORE: - return NEASingaporeNowcastProvider(client, api_key=settings.nea_api_key) + return _build_nea(settings, client) if name == WeatherProviderName.JMA_JAPAN: return _build_jma(settings, client, office_code=jma_office_code) - return builder(settings, client) + raise ValueError(f"Unsupported weather provider: {name}") def _build_qweather( @@ -319,11 +318,3 @@ def aqicn_provider(settings: Settings, client: httpx.AsyncClient) -> AirQualityP if not settings.aqicn_api_token: return None return AQICNProvider(client, token=settings.aqicn_api_token) - - -WEATHER_PROVIDER_BUILDERS: dict[str, Callable[[Settings, httpx.AsyncClient], WeatherContextProvider]] = { - WeatherProviderName.QWEATHER: _build_qweather, - WeatherProviderName.OPEN_METEO: _build_open_meteo, - WeatherProviderName.NEA_SINGAPORE: _build_nea, - WeatherProviderName.JMA_JAPAN: _build_jma, -}