- bot_regional.py: parse BOT BTWS_STAT regional report (reportID per region) -> private consumption index + nondurable index + monthly series - North reportID=954 verified live (idx 100.3, series 6mo); region-keyed for extension to other regions - collect_bot_regional.py CLI -> JSON snapshot - 4 tests; full backend suite 152 OK; compileall ok
60 lines
2.7 KiB
Python
60 lines
2.7 KiB
Python
"""Tests for the BOT regional consumption parser."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import unittest
|
|
|
|
from app import bot_regional
|
|
|
|
|
|
def _bot_html() -> str:
|
|
return """
|
|
<html><head><title>RG_NR_042_S3 ดัชนีและเครื่องชี้การอุปโภคบริโภคภาคเอกชนของภาคเหนือ</title></head>
|
|
<body>
|
|
<table>
|
|
<tr><th>ลำดับ</th><th>รายการ</th><th>มิ.ย. 2569 p</th><th>พ.ค. 2569 r</th><th>เม.ย. 2569 r</th></tr>
|
|
<tr><td>1</td><td>ดัชนีการอุปโภคบริโภคภาคเอกชน 1/</td><td>100.3</td><td>98.4</td><td>101.2</td></tr>
|
|
<tr><td>2</td><td>ดัชนีการใช้จ่ายสินค้าไม่คงทน 2/</td><td>98.1</td><td>95.8</td><td>100.7</td></tr>
|
|
<tr><td>3</td><td>ดัชนีสินค้าอุปโภคบริโภคหมุนเวียนเร็ว</td><td>93.9</td><td>90.2</td><td>96.4</td></tr>
|
|
</table>
|
|
</body></html>
|
|
"""
|
|
|
|
|
|
class BotRegionalParseTest(unittest.TestCase):
|
|
def test_parses_consumption_index(self) -> None:
|
|
parsed = bot_regional.parse_bot_regional_html(_bot_html())
|
|
self.assertEqual(parsed["columns"][0], "มิ.ย. 2569 p")
|
|
self.assertIn("ดัชนีการอุปโภค", str(parsed["rows"].keys()))
|
|
# consumption index row value
|
|
key = next(k for k in parsed["rows"] if "ดัชนีการอุปโภค" in k)
|
|
self.assertEqual(parsed["rows"][key][0], 100.3)
|
|
|
|
def test_fetch_region_builds_snapshot(self) -> None:
|
|
# Use a fake fetch to avoid network
|
|
actual_fetch = bot_regional._fetch
|
|
bot_regional._fetch = lambda rid, timeout=30: _bot_html()
|
|
try:
|
|
snap = bot_regional.fetch_region("north")
|
|
self.assertEqual(snap.region, "north")
|
|
self.assertEqual(snap.consumption_index, 100.3)
|
|
self.assertEqual(snap.nondurable_index, 98.1)
|
|
# series is parallel to months
|
|
self.assertIsNotNone(snap.months)
|
|
self.assertIsNotNone(snap.consumption_series)
|
|
self.assertEqual(len(snap.months), len(snap.consumption_series))
|
|
finally:
|
|
bot_regional._fetch = actual_fetch
|
|
|
|
def test_unknown_region_raises(self) -> None:
|
|
with self.assertRaises(bot_regional.BotRegionalError):
|
|
bot_regional.fetch_region("mars")
|
|
|
|
def test_missing_table_raises(self) -> None:
|
|
with self.assertRaises(bot_regional.BotRegionalError):
|
|
bot_regional.parse_bot_regional_html("<html>no data</html>")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|