| import sqlite3 |
| import pytest |
| from storage import metrics_db |
|
|
|
|
| @pytest.fixture(autouse=True) |
| def tmp_db(tmp_path, monkeypatch): |
| monkeypatch.setattr(metrics_db, "DB_PATH", tmp_path / "metrics.db") |
|
|
|
|
| def _sample_row(**overrides) -> dict: |
| base = { |
| "ticker": "AAPL", "company_name": "Apple Inc.", "filing_date": "2024-11-01", |
| "period": "FY2024", "form_type": "10-K", "revenue": 391035000000.0, |
| "revenue_yoy_pct": 2.0, "eps": 6.11, "gross_margin": 0.461, |
| "operating_margin": 0.314, "free_cash_flow": 108807000000.0, |
| "guidance_disclosed": 0, "guidance_text": None, |
| "ingested_at": "2026-05-04T12:00:00", |
| "shares_diluted": None, "effective_tax_rate": None, "interest_expense": None, |
| "total_debt": None, "dividends_paid": None, "buybacks": None, |
| "capex": None, "stockholders_equity": None, |
| } |
| return {**base, **overrides} |
|
|
|
|
| def test_init_creates_table(): |
| metrics_db.init_db() |
| with sqlite3.connect(metrics_db.DB_PATH) as conn: |
| tables = [r[0] for r in conn.execute("SELECT name FROM sqlite_master WHERE type='table'").fetchall()] |
| assert "metrics" in tables |
|
|
|
|
| def test_init_migrates_legacy_schema_without_losing_rows(): |
| with sqlite3.connect(metrics_db.DB_PATH) as conn: |
| conn.execute(""" |
| CREATE TABLE metrics ( |
| ticker TEXT PRIMARY KEY, |
| period TEXT, |
| company_name TEXT, |
| filing_date TEXT, |
| revenue REAL |
| ) |
| """) |
| conn.executemany( |
| "INSERT INTO metrics VALUES (?, ?, ?, ?, ?)", |
| [ |
| ("AAPL", "FY2023", "Apple Inc.", "2023-11-03", 383285000000.0), |
| ("MSFT", "FY2024", "Microsoft Corp.", "2024-07-30", 245122000000.0), |
| ], |
| ) |
|
|
| metrics_db.init_db() |
|
|
| with sqlite3.connect(metrics_db.DB_PATH) as conn: |
| rows = conn.execute( |
| "SELECT ticker, period, company_name, filing_date, revenue " |
| "FROM metrics ORDER BY ticker" |
| ).fetchall() |
| pk_columns = [ |
| row[1] |
| for row in sorted( |
| conn.execute("PRAGMA table_info(metrics)").fetchall(), |
| key=lambda row: row[5] or 99, |
| ) |
| if row[5] |
| ] |
| archive_rows = conn.execute( |
| "SELECT ticker, period, revenue FROM metrics_legacy_v1 ORDER BY ticker" |
| ).fetchall() |
|
|
| assert rows == [ |
| ("AAPL", "FY2023", "Apple Inc.", "2023-11-03", 383285000000.0), |
| ("MSFT", "FY2024", "Microsoft Corp.", "2024-07-30", 245122000000.0), |
| ] |
| assert pk_columns == ["ticker", "period"] |
| assert archive_rows == [ |
| ("AAPL", "FY2023", 383285000000.0), |
| ("MSFT", "FY2024", 245122000000.0), |
| ] |
|
|
|
|
| def test_legacy_migration_allows_new_periods_and_is_idempotent(): |
| with sqlite3.connect(metrics_db.DB_PATH) as conn: |
| conn.execute(""" |
| CREATE TABLE metrics ( |
| ticker TEXT PRIMARY KEY, |
| company_name TEXT, |
| filing_date TEXT, |
| revenue REAL |
| ) |
| """) |
| conn.execute( |
| "INSERT INTO metrics VALUES (?, ?, ?, ?)", |
| ("AAPL", "Apple Inc.", "2023-11-03", 383285000000.0), |
| ) |
|
|
| metrics_db.init_db() |
| metrics_db.init_db() |
| metrics_db.upsert_metrics(_sample_row(period="FY2024")) |
|
|
| with sqlite3.connect(metrics_db.DB_PATH) as conn: |
| rows = conn.execute( |
| "SELECT ticker, period, revenue FROM metrics ORDER BY period" |
| ).fetchall() |
| archives = conn.execute( |
| "SELECT name FROM sqlite_master " |
| "WHERE type = 'table' AND name LIKE 'metrics_legacy_v%'" |
| ).fetchall() |
|
|
| assert rows == [ |
| ("AAPL", "FY2024", 391035000000.0), |
| ("AAPL", "LEGACY", 383285000000.0), |
| ] |
| assert archives == [("metrics_legacy_v1",)] |
|
|
|
|
| def test_upsert_and_get(): |
| metrics_db.init_db() |
| metrics_db.upsert_metrics(_sample_row()) |
| result = metrics_db.get_metrics("AAPL") |
| assert result["ticker"] == "AAPL" |
| assert result["revenue"] == 391035000000.0 |
| assert result["form_type"] == "10-K" |
|
|
|
|
| def test_upsert_replaces_on_conflict(): |
| metrics_db.init_db() |
| metrics_db.upsert_metrics(_sample_row(filing_date="2023-11-01", revenue=380000000000.0)) |
| metrics_db.upsert_metrics(_sample_row(filing_date="2024-11-01", revenue=391035000000.0)) |
| result = metrics_db.get_metrics("AAPL") |
| assert result["filing_date"] == "2024-11-01" |
| assert result["revenue"] == 391035000000.0 |
|
|
|
|
| def test_get_missing_returns_none(): |
| metrics_db.init_db() |
| assert metrics_db.get_metrics("ZZZZ") is None |
|
|
|
|
| def test_metric_lineage_round_trip(): |
| metrics_db.init_db() |
| metrics_db.upsert_metrics(_sample_row( |
| period_basis="annual", |
| accession="0000320193-24-000123", |
| report_date="2024-09-28", |
| source_url="https://www.sec.gov/example", |
| metric_contexts={"revenue": {"selection": "exact_annual"}}, |
| quality_warnings=[], |
| data_quality_status="VERIFIED", |
| )) |
| result = metrics_db.get_metrics("AAPL") |
| assert result["metric_contexts"]["revenue"]["selection"] == "exact_annual" |
| assert result["quality_warnings"] == [] |
| assert result["data_quality_status"] == "VERIFIED" |
|
|