100 lines
3.6 KiB
Python
100 lines
3.6 KiB
Python
from src.data_collection.amsc_awos_sources import (
|
|
AmscAwosSourceMixin,
|
|
_amsc_parse_wind_plate_payload,
|
|
_amsc_supported_city_codes,
|
|
)
|
|
|
|
|
|
ZBAA_SAMPLE = {
|
|
"code": 200,
|
|
"msg": "操作成功",
|
|
"data": {
|
|
"18R/36L": {
|
|
"RNO": "18R/36L",
|
|
"OTIME": "2026-05-14 17:19:00",
|
|
"TDZ_TEMP": "20.8",
|
|
"MID_TEMP": "-",
|
|
"END_TEMP": "20.8",
|
|
"TDZ_HUMID": "67",
|
|
"END_HUMID": "67",
|
|
"METAR": "METAR ZBAA 141700Z 12003MPS 050V170 7000 NSC 21/15 Q1014 NOSIG=",
|
|
},
|
|
"18L/36R": {
|
|
"RNO": "18L/36R",
|
|
"OTIME": "2026-05-14 17:19:00",
|
|
"TDZ_TEMP": "21.0",
|
|
"MID_TEMP": "-",
|
|
"END_TEMP": "20.4",
|
|
"METAR": "METAR ZBAA 141700Z 12003MPS 050V170 7000 NSC 21/15 Q1014 NOSIG=",
|
|
},
|
|
"19/01": {
|
|
"RNO": "19/01",
|
|
"OTIME": "2026-05-14 17:19:00",
|
|
"TDZ_TEMP": "20.2",
|
|
"MID_TEMP": "-",
|
|
"END_TEMP": "20.2",
|
|
"METAR": "METAR ZBAA 141700Z 12003MPS 050V170 7000 NSC 21/15 Q1014 NOSIG=",
|
|
},
|
|
},
|
|
}
|
|
|
|
|
|
def test_parse_wind_plate_payload_normalizes_runway_point_temperatures():
|
|
parsed = _amsc_parse_wind_plate_payload(ZBAA_SAMPLE, city_key="beijing", icao="ZBAA")
|
|
|
|
assert parsed["source"] == "amsc_awos"
|
|
assert parsed["source_label"] == "AMSC AWOS Beijing Capital (ZBAA)"
|
|
assert parsed["observation_source_zh"] == "AMSC AWOS 跑道观测气温"
|
|
assert parsed["icao"] == "ZBAA"
|
|
assert parsed["temp_c"] == 21.0
|
|
assert parsed["temp_source"] == "runway_max"
|
|
assert parsed["runway_temp_range"] == (20.2, 21.0)
|
|
assert parsed["observation_time"] == "2026-05-14T17:19:00+00:00"
|
|
assert parsed["observation_time_local"] == "2026-05-15 01:19:00"
|
|
assert parsed["raw_metar"].startswith("METAR ZBAA 141700Z")
|
|
|
|
runway_obs = parsed["runway_obs"]
|
|
assert runway_obs["runway_pairs"] == [("18R", "36L"), ("18L", "36R"), ("19", "01")]
|
|
assert runway_obs["temperatures"] == [(20.8, None), (21.0, None), (20.2, None)]
|
|
pt0 = runway_obs["point_temperatures"][0]
|
|
assert pt0["runway"] == "18R/36L"
|
|
assert pt0["tdz_temp"] == 20.8
|
|
assert pt0["mid_temp"] is None
|
|
assert pt0["end_temp"] == 20.8
|
|
assert pt0["target_runway_max"] == 20.8
|
|
assert pt0["wind_dir"] is None
|
|
assert pt0["wind_speed"] is None
|
|
assert pt0["rvr"] is None
|
|
assert pt0["mor"] is None
|
|
assert pt0["humidity"] == 67.0
|
|
|
|
|
|
def test_parse_wind_plate_payload_rejects_unauthorized_or_empty_payloads():
|
|
assert _amsc_parse_wind_plate_payload(
|
|
{"errCode": -12010, "errMsg": "无权访问此接口"},
|
|
city_key="beijing",
|
|
icao="ZBAA",
|
|
) is None
|
|
assert _amsc_parse_wind_plate_payload({"code": 200, "data": {}}, city_key="beijing", icao="ZBAA") is None
|
|
|
|
|
|
def test_fetch_amsc_official_current_uses_domestic_city_whitelist(monkeypatch):
|
|
import src.data_collection.amsc_awos_sources as _amsc
|
|
monkeypatch.setattr(_amsc, "AMSC_AWOS_BASE_URL", "https://www.amsc.net.cn/gateway/api/saas/rest/amc/AwosController/getWindPlate")
|
|
assert _amsc_supported_city_codes()["beijing"] == "ZBAA"
|
|
assert "new york" not in _amsc_supported_city_codes()
|
|
|
|
class FakeCollector(AmscAwosSourceMixin):
|
|
timeout = 1.0
|
|
|
|
def _amsc_http_get_json(self, url, *, headers=None):
|
|
assert "getWindPlate?cccc=ZBAA" in url
|
|
return ZBAA_SAMPLE
|
|
|
|
data = FakeCollector().fetch_amsc_awos_current("beijing")
|
|
|
|
assert data is not None
|
|
assert data["icao"] == "ZBAA"
|
|
assert data["runway_temp_range"] == (20.2, 21.0)
|
|
assert FakeCollector().fetch_amsc_awos_current("new york") is None
|