75 lines
2.9 KiB
Python
75 lines
2.9 KiB
Python
"""Tests for BLS CPI-U download and loader."""
|
|
|
|
import httpx
|
|
import respx
|
|
|
|
from admin_analytics.bls.download import download_cpi_file
|
|
from admin_analytics.bls.loader import load_cpi
|
|
from admin_analytics.config import BLS_CPI_URL
|
|
|
|
|
|
class TestDownload:
|
|
@respx.mock
|
|
def test_download_creates_file(self, tmp_path, monkeypatch):
|
|
monkeypatch.setattr("admin_analytics.bls.download.BLS_DATA_DIR", tmp_path)
|
|
respx.get(BLS_CPI_URL).mock(
|
|
return_value=httpx.Response(200, text="series_id\tyear\tperiod\tvalue\n")
|
|
)
|
|
path = download_cpi_file(force=True)
|
|
assert path.exists()
|
|
assert path.parent == tmp_path
|
|
|
|
@respx.mock
|
|
def test_download_skips_when_exists(self, tmp_path, monkeypatch):
|
|
monkeypatch.setattr("admin_analytics.bls.download.BLS_DATA_DIR", tmp_path)
|
|
existing = tmp_path / "cu.data.0.Current"
|
|
existing.write_text("cached")
|
|
path = download_cpi_file(force=False)
|
|
assert path.read_text() == "cached"
|
|
|
|
@respx.mock
|
|
def test_download_force_overwrites(self, tmp_path, monkeypatch):
|
|
monkeypatch.setattr("admin_analytics.bls.download.BLS_DATA_DIR", tmp_path)
|
|
existing = tmp_path / "cu.data.0.Current"
|
|
existing.write_text("old")
|
|
respx.get(BLS_CPI_URL).mock(
|
|
return_value=httpx.Response(200, text="new data")
|
|
)
|
|
path = download_cpi_file(force=True)
|
|
assert path.read_text() == "new data"
|
|
|
|
|
|
class TestLoader:
|
|
def test_load_cpi(self, db_conn, fixtures_dir):
|
|
fixture = fixtures_dir / "cu_data_sample.tsv"
|
|
count = load_cpi(db_conn, fixture)
|
|
# Fixture has 5 valid CUUR0000SA0 monthly rows (M01, M02, M12, M01, M06)
|
|
# Excludes: M13 (annual avg), CUSR0000SA0 (wrong series), S01 (semi-annual)
|
|
assert count == 5
|
|
|
|
def test_load_cpi_correct_values(self, db_conn, fixtures_dir):
|
|
fixture = fixtures_dir / "cu_data_sample.tsv"
|
|
load_cpi(db_conn, fixture)
|
|
rows = db_conn.execute(
|
|
"SELECT year, month, value FROM raw_cpi_u ORDER BY year, month"
|
|
).fetchall()
|
|
assert rows[0] == (2022, 1, 281.148)
|
|
assert rows[-1] == (2023, 6, 305.109)
|
|
|
|
def test_load_cpi_types(self, db_conn, fixtures_dir):
|
|
fixture = fixtures_dir / "cu_data_sample.tsv"
|
|
load_cpi(db_conn, fixture)
|
|
row = db_conn.execute(
|
|
"SELECT year, month, value, series_id FROM raw_cpi_u LIMIT 1"
|
|
).fetchone()
|
|
assert isinstance(row[0], int)
|
|
assert isinstance(row[1], int)
|
|
assert isinstance(row[2], float)
|
|
assert row[3] == "CUUR0000SA0"
|
|
|
|
def test_load_cpi_idempotent(self, db_conn, fixtures_dir):
|
|
fixture = fixtures_dir / "cu_data_sample.tsv"
|
|
load_cpi(db_conn, fixture)
|
|
load_cpi(db_conn, fixture)
|
|
count = db_conn.execute("SELECT COUNT(*) FROM raw_cpi_u").fetchone()[0]
|
|
assert count == 5
|