Files
PolyWeather/tests/test_observation_source_adapters.py
2026-06-16 23:01:29 +08:00

262 lines
8.3 KiB
Python

def test_source_adapter_normalizes_amsc_awos_payload_to_observation_record():
from web.services.observation_source_adapters import collect_observation_source
calls = []
class FakeWeather:
def _attach_china_amsc_awos_data(self, results, city, use_fahrenheit):
calls.append((city, use_fahrenheit))
results["amos"] = {
"source": "amsc_awos",
"source_label": "AMSC AWOS",
"temp_c": "24.3",
"observation_time": "2026-06-14T01:00:00+00:00",
"observation_time_local": "2026-06-14 09:00",
"icao": "ZSQD",
"station_label": "Qingdao Jiaodong",
"runway": "17L",
}
result = collect_observation_source(
FakeWeather(),
"AMSC_AWOS",
"Qingdao",
use_fahrenheit=False,
)
assert calls == [("qingdao", False)]
assert result.source == "amsc_awos"
assert result.city == "qingdao"
assert result.status == "ok"
assert result.error == ""
assert len(result.records) == 1
record = result.records[0]
assert record.source == "amsc_awos"
assert record.city == "qingdao"
assert record.value == 24.3
assert record.observed_at == "2026-06-14T01:00:00+00:00"
assert record.observed_at_local == "2026-06-14 09:00"
assert record.station_code == "ZSQD"
assert record.station_name == "Qingdao Jiaodong"
assert record.runway == "17L"
assert record.value_unit == "c"
assert record.source_label == "AMSC AWOS"
assert record.payload["temp_c"] == "24.3"
def test_source_adapter_flattens_nearby_source_lists():
from web.services.observation_source_adapters import collect_observation_source
class FakeWeather:
def _attach_hko_obs_official_nearby(self, results, city, use_fahrenheit):
results["hko_obs_nearby"] = [
{
"source": "hko_obs",
"source_label": "HKO",
"temperature_c": 28.1,
"observation_time": "2026-06-14T01:00:00+00:00",
"station_code": "LFS",
"station_name": "Lau Fau Shan",
},
{
"source": "hko_obs",
"source_label": "HKO",
"temperature_c": 27.6,
"observation_time": "2026-06-14T01:00:00+00:00",
"station_code": "HKO",
"station_name": "Hong Kong Observatory",
},
]
result = collect_observation_source(
FakeWeather(),
"hko_obs",
"shenzhen",
use_fahrenheit=False,
)
assert result.status == "ok"
assert [record.station_code for record in result.records] == ["LFS", "HKO"]
assert [record.value for record in result.records] == [28.1, 27.6]
def test_source_adapter_collects_mgm_with_keyword_flags_and_station_metadata():
from web.services.observation_source_adapters import collect_observation_source
calls = []
class FakeWeather:
def _attach_turkish_mgm_data(
self,
results,
city,
*,
include_mgm=True,
include_nearby=True,
):
calls.append((city, include_mgm, include_nearby))
if not include_mgm:
return
results["mgm"] = {
"source": "mgm",
"source_label": "MGM",
"station_code": "17128",
"station_name": "Esenboga Airport",
"obs_time": "2026-06-15T14:20:00Z",
"current": {"temp": 19.0},
}
result = collect_observation_source(
FakeWeather(),
"mgm",
"ankara",
use_fahrenheit=False,
)
assert calls == [("ankara", True, True)]
assert result.status == "ok"
assert len(result.records) == 1
record = result.records[0]
assert record.source == "mgm"
assert record.source_label == "MGM"
assert record.value == 19.0
assert record.observed_at == "2026-06-15T14:20:00Z"
assert record.station_code == "17128"
assert record.station_name == "Esenboga Airport"
def test_source_adapter_collects_jma_official_nearby_rows():
from web.services.observation_source_adapters import collect_observation_source
calls = []
class FakeWeather:
def _attach_japan_official_nearby(self, results, city, use_fahrenheit):
calls.append((city, use_fahrenheit))
results["jma_current"] = {
"source": "jma_amedas",
"source_label": "JMA",
"temp": 23.4,
"obs_time": "2026-06-16T06:00:00+09:00",
"station_code": "44166",
"station_name": "Haneda",
}
result = collect_observation_source(
FakeWeather(),
"jma_amedas",
"tokyo",
use_fahrenheit=False,
)
assert calls == [("tokyo", False)]
assert result.status == "ok"
assert len(result.records) == 1
assert result.records[0].source == "jma_amedas"
assert result.records[0].value == 23.4
assert result.records[0].observed_at == "2026-06-16T06:00:00+09:00"
assert result.records[0].station_code == "44166"
def test_source_adapter_collects_cwa_direct_settlement_payload():
from web.services.observation_source_adapters import collect_observation_source
calls = []
class FakeWeather:
def fetch_cwa_taipei_settlement_current(self):
calls.append("fetch_cwa")
return {
"source": "cwa",
"source_label": "CWA",
"station_code": "466920",
"station_name": "Taipei",
"observation_time": "2026-06-16T06:00:00+08:00",
"current": {"temp": 29.2},
}
result = collect_observation_source(
FakeWeather(),
"cwa",
"taipei",
use_fahrenheit=False,
)
assert calls == ["fetch_cwa"]
assert result.status == "ok"
assert result.records[0].source == "cwa"
assert result.records[0].value == 29.2
assert result.records[0].observed_at == "2026-06-16T06:00:00+08:00"
assert result.records[0].station_code == "466920"
def test_source_adapter_collects_metar_for_low_frequency_cities():
from web.services.observation_source_adapters import collect_observation_source
calls = []
class FakeWeather:
def fetch_metar(self, city, use_fahrenheit=False, utc_offset=0):
calls.append((city, use_fahrenheit, utc_offset))
return {
"source": "metar",
"icao": "LEMD",
"station_name": "Madrid Barajas",
"observation_time": "2026-06-16T12:00:00.000Z",
"current": {"temp": 28.0},
}
result = collect_observation_source(
FakeWeather(),
"metar",
"madrid",
use_fahrenheit=False,
)
assert calls == [("madrid", False, 3600)]
assert result.status == "ok"
assert result.records[0].source == "metar"
assert result.records[0].value == 28.0
assert result.records[0].observed_at == "2026-06-16T12:00:00.000Z"
assert result.records[0].station_code == "LEMD"
def test_source_adapter_reports_parse_error_for_unusable_source_rows():
from web.services.observation_source_adapters import collect_observation_source
class FakeWeather:
def _attach_china_amsc_awos_data(self, results, city, use_fahrenheit):
results["bad"] = {
"source": "amsc_awos",
"observation_time": "2026-06-14T01:00:00+00:00",
"icao": "ZSQD",
}
result = collect_observation_source(
FakeWeather(),
"amsc_awos",
"qingdao",
use_fahrenheit=False,
)
assert result.status == "parse_error"
assert result.error == "source response had no usable temperature"
assert result.records == ()
def test_source_adapter_reports_unsupported_source_without_calling_weather():
from web.services.observation_source_adapters import collect_observation_source
result = collect_observation_source(
object(),
"unknown_source",
"qingdao",
use_fahrenheit=False,
)
assert result.status == "unsupported"
assert result.error == "unsupported observation source"
assert result.records == ()