- auto_credit.py: scrape Trading Economics Thailand total-vehicle-sales HTML -> total sales + new car sales YoY + vehicle production/passenger/exports - refining_energy.py: scrape EIA prices.php 3:2:1 crack spread (Gulf LLS) + WTI/Brent/gasoline - Both server-rendered HTML scrapers (har-derived-api-client pattern); EIA used instead of RBN (RBN is Cloudflare-challenged, 403 via urllib; EIA is open US gov data, HTTP 200 direct) - collect_auto_credit.py / collect_refining.py CLI -> JSON snapshot - 8 tests; full backend suite 148 OK; live verified (auto 59198/20% YoY; crack 71.10 $/bbl); static scan clean
62 lines
2.9 KiB
Python
62 lines
2.9 KiB
Python
"""Tests for the Auto Credit (Trading Economics) parser."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import unittest
|
|
|
|
from app import auto_credit
|
|
|
|
|
|
def _trading_econ_html() -> str:
|
|
announcement = """
|
|
<table><tr><th>Date</th><th>Time</th><th>Statistic</th><th>Period</th><th>Actual</th><th>Previous</th></tr>
|
|
<tr><td>2026-06-29</td><td>03:45 AM</td><td>New Car Sales YoY</td><td>May</td><td>10.60%</td><td>2.54%</td></tr>
|
|
<tr><td>2026-07-24</td><td>04:20 AM</td><td>New Car Sales YoY</td><td>Jun</td><td>17.26%</td><td>10.60%</td></tr>
|
|
</table>"""
|
|
indicators = """
|
|
<table><tr><th>Indicator</th><th>Actual</th><th>Previous</th><th>Unit</th><th>Period</th></tr>
|
|
<tr><td>Auto Exports</td><td>81526.00</td><td>59434.00</td><td>Units</td><td>Jun 2026</td></tr>
|
|
<tr><td>Vehicle Production</td><td>120391.00</td><td>114214.00</td><td>Units</td><td>Jun 2026</td></tr>
|
|
<tr><td>Passenger Car Sales</td><td>22875.00</td><td>19389.00</td><td>Units</td><td>Jun 2026</td></tr>
|
|
</table>"""
|
|
main = """
|
|
<table><tr><th> </th><th>Actual</th><th>Previous</th><th>Highest</th><th>Lowest</th><th>Dates</th><th>Unit</th><th>Frequency</th><th>Seasonality</th></tr>
|
|
<tr><td></td><td>61244.00</td><td>57765.00</td><td>157529.00</td><td>5338.00</td><td>1980 - 2026</td><td>Units</td><td>Monthly</td><td>Volume, NSA</td></tr>
|
|
</table>"""
|
|
return f"<html><body>{announcement}{indicators}{main}</body></html>"
|
|
|
|
|
|
class AutoCreditParseTest(unittest.TestCase):
|
|
def test_parses_auto_credit_values(self) -> None:
|
|
snap = auto_credit.parse_auto_credit_html(_trading_econ_html())
|
|
self.assertEqual(snap.total_vehicle_sales, 61244.00)
|
|
self.assertEqual(snap.prev_vehicle_sales, 57765.00)
|
|
self.assertEqual(snap.vehicle_production, 120391.00)
|
|
self.assertEqual(snap.passenger_car_sales, 22875.00)
|
|
self.assertEqual(snap.auto_exports, 81526.00)
|
|
# New Car Sales YoY — latest (Jun 2026) is the last announcement row
|
|
self.assertEqual(snap.new_car_sales_yoy, 17.26)
|
|
self.assertEqual(snap.prev_new_car_sales_yoy, 10.60)
|
|
|
|
def test_missing_table_raises(self) -> None:
|
|
with self.assertRaises(auto_credit.AutoCreditError):
|
|
auto_credit.parse_auto_credit_html("<html><body>no data</body></html>")
|
|
|
|
def test_negative_and_percent_handling(self) -> None:
|
|
# negative YoY should parse as negative float
|
|
html_text = """
|
|
<table><tr><td>2026-08-25</td><td>04:00 AM</td><td>New Car Sales YoY</td><td>Jul</td><td>-3.5%</td><td>17.26%</td></tr>
|
|
</table>"""
|
|
snap = auto_credit.parse_auto_credit_html(html_text)
|
|
self.assertEqual(snap.new_car_sales_yoy, -3.5)
|
|
|
|
def test_build_dict(self) -> None:
|
|
snap = auto_credit.parse_auto_credit_html(_trading_econ_html())
|
|
d = snap.to_dict()
|
|
self.assertEqual(d["source"], "tradingeconomics")
|
|
self.assertIn("total_vehicle_sales", d)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|