Files
OpenBB/openbb_platform/providers/bls/tests/test_metadata.py
Danglewood 9061473d9e [V5] openbb-bls: Refactor for V5 + Add Many Endpoints (#7518)
* refactor bls for v5, add 100 widgets

* some CI fixes

* no python 3.15

* fix missing dev group in pyproject.toml

* more pyproject fallout

* action
2026-06-01 19:11:05 +03:00

146 lines
4.8 KiB
Python

"""Tests for the ``BlsMetadata`` singleton."""
import copy
import pytest
from openbb_bls.utils.metadata import BlsMetadata, BlsMetadataDependency
def test_singleton_identity(stub_cache_path):
"""``__new__`` returns the same instance on subsequent calls."""
a = BlsMetadata()
b = BlsMetadata()
assert a is b
def test_deepcopy_returns_self(stub_cache_path):
"""``__deepcopy__`` returns ``self`` to short-circuit deepcopy walkers."""
meta = BlsMetadata()
assert copy.deepcopy(meta) is meta
def test_copy_returns_self(stub_cache_path):
"""``__copy__`` returns ``self`` so ``copy.copy`` also stops."""
meta = BlsMetadata()
assert copy.copy(meta) is meta
def test_call_returns_self(stub_cache_path):
"""The singleton is callable so it can stand in as a FastAPI dependency."""
meta = BlsMetadata()
assert meta() is meta
def test_reset_clears_state(stub_cache_path):
"""``_reset`` zeroes both the instance and the initialised flag."""
BlsMetadata()
assert BlsMetadata._instance is not None
assert BlsMetadata._initialized is True
BlsMetadata._reset()
assert BlsMetadata._instance is None
assert BlsMetadata._initialized is False
def test_categories_populated_from_index(stub_cache_path):
"""``categories`` reflects the keys parsed from ``index.json``."""
meta = BlsMetadata()
assert meta.categories == ["cpi", "ppi"]
assert meta.category_info("cpi") == {
"name": "Consumer Price Index",
"surveys": ["cu"],
"series_count": 2,
}
assert meta.category_info("missing") == {}
def test_get_series_lazy_and_memoised(stub_cache_path):
"""``get_series`` reads the CSV once and caches the result."""
meta = BlsMetadata()
df1 = meta.get_series("cpi")
df2 = meta.get_series("cpi")
assert df1 is df2
assert list(df1["series_id"]) == ["CUUR0000SA0", "CUUR0000SAF1"]
def test_get_codes_lazy_and_memoised(stub_cache_path):
"""``get_codes`` reads JSON once and caches the result."""
meta = BlsMetadata()
a = meta.get_codes("cpi")
b = meta.get_codes("cpi")
assert a is b
assert a["cu"]["area_code"]["0000"] == "U.S. city average"
def test_get_codes_missing_member_returns_empty(stub_cache_path):
"""``get_codes`` for a category lacking ``codes.json`` returns ``{}``."""
meta = BlsMetadata()
assert meta.get_codes("ppi") == {}
def test_unknown_category_raises_keyerror(stub_cache_path):
"""``get_series`` and ``get_codes`` raise ``KeyError`` for unknown keys."""
meta = BlsMetadata()
with pytest.raises(KeyError, match="Unknown BLS category"):
meta.get_series("not-a-real-category")
with pytest.raises(KeyError, match="Unknown BLS category"):
meta.get_codes("not-a-real-category")
def test_missing_archive_skips_load(tmp_path, monkeypatch):
"""Absent archive leaves the singleton with empty state."""
missing = tmp_path / "nope.zip"
monkeypatch.setattr(
"openbb_bls.utils.metadata._core._SHIPPED_CACHE_FILE",
missing,
)
meta = BlsMetadata()
assert meta.categories == []
assert meta._archive_bytes is None
def test_open_without_archive_raises(tmp_path, monkeypatch):
"""``_open`` raises ``FileNotFoundError`` when there is no archive in memory."""
missing = tmp_path / "nope.zip"
monkeypatch.setattr(
"openbb_bls.utils.metadata._core._SHIPPED_CACHE_FILE",
missing,
)
meta = BlsMetadata()
# Force the path through ``get_series`` -> ``_open`` after seeding the
# index manually so the category lookup passes the gate.
meta._index = {"cpi": {"surveys": ["cu"]}}
with pytest.raises(FileNotFoundError, match="BLS cache archive not found"):
meta.get_series("cpi")
def test_archive_without_index_json(tmp_path, make_stub_zip, monkeypatch):
"""An archive lacking ``index.json`` yields an empty category list."""
archive = tmp_path / "no_index.zip"
payload = make_stub_zip(include_index=False)
archive.write_bytes(payload)
monkeypatch.setattr(
"openbb_bls.utils.metadata._core._SHIPPED_CACHE_FILE",
archive,
)
meta = BlsMetadata()
assert meta.categories == []
assert meta._archive_bytes is not None
def test_dependency_wrapper_resolves_to_class(stub_cache_path):
"""``BlsMetadataDependency`` is an Annotated alias on ``BlsMetadata``."""
args = getattr(BlsMetadataDependency, "__metadata__", ())
assert args, "Annotated metadata should not be empty"
origin = getattr(BlsMetadataDependency, "__origin__", None)
assert origin is BlsMetadata
def test_init_no_op_when_already_initialised(stub_cache_path):
"""Calling ``__init__`` again is a no-op once the singleton is ready."""
meta = BlsMetadata()
sentinel = object()
meta._index = sentinel # type: ignore[assignment]
BlsMetadata().__init__()
assert meta._index is sentinel