Files
OpenBB/openbb_platform/providers/ecb/tests/test_helpers.py
Danglewood 869cfed125 [Release] openbb-v5.0.0 (#7741)
* merge branch develop with main

* bump desktop version

* fix the merge

* sync Cargo.lock to desktop 2.0.0

* fix cli conftest.py

---------

Co-authored-by: deeleeramone <>
2026-09-29 10:58:44 -07:00

207 lines
6.4 KiB
Python

from openbb_ecb.utils.helpers import (
parse_sdmx_csv,
parse_sdmx_json,
parse_sdmx_period,
parse_series_keys,
period_end,
)
def test_parse_sdmx_csv():
text = (
"KEY,FREQ,OBS_VALUE,TIME_PERIOD,EXTRA\n"
"EXR.D.USD,D,1.5,2024-01-01,\n"
"OTHER,M,,2024-02,keep\n"
"ZZZ.A.B,A,bad,2024,x\n"
)
rows = parse_sdmx_csv(text, "EXR")
assert rows[0]["series_key"] == "D.USD"
assert rows[0]["FREQ"] == "D" and rows[0]["OBS_VALUE"] == 1.5
assert "EXTRA" not in rows[0] and "KEY" not in rows[0]
assert rows[0]["date"] == "2024-01-01"
assert rows[1]["series_key"] == "OTHER" and rows[1]["OBS_VALUE"] is None
assert rows[1]["EXTRA"] == "keep"
assert rows[2]["series_key"] == "ZZZ.A.B" and rows[2]["OBS_VALUE"] is None
def test_parse_sdmx_period_all_formats():
assert parse_sdmx_period("2024-06-23") == "2024-06-23"
assert parse_sdmx_period("2024-06") == "2024-06-01"
assert parse_sdmx_period("2024-Q2") == "2024-04-01"
assert parse_sdmx_period("2024-S1") == "2024-01-01"
assert parse_sdmx_period("2024-S2") == "2024-07-01"
assert parse_sdmx_period("2024-W23") == "2024-06-03"
assert parse_sdmx_period("2024") == "2024-01-01"
assert (
parse_sdmx_period("2024-06", start="2024-06-30T00:00:00+02:00") == "2024-06-30"
)
def test_parse_sdmx_period_fallbacks():
assert parse_sdmx_period("") == ""
assert parse_sdmx_period("garbage-Q9") == "garbage-Q9"
def test_period_end_all_formats():
assert period_end("2024-Q3") == "2024-09-30"
assert period_end("2024-02") == "2024-02-29"
assert period_end("2023") == "2023-12-31"
assert period_end("2024-06-15", end="2024-06-30T00:00:00") == "2024-06-30"
def test_period_end_fallbacks():
assert period_end("") == ""
assert period_end("2024-W10") == parse_sdmx_period("2024-W10")
assert period_end("bad-Q9") == "bad-Q9"
def test_parse_sdmx_json_empty():
assert parse_sdmx_json({}) == []
assert parse_sdmx_json({"dataSets": []}) == []
def test_parse_sdmx_json_dimensions_and_attributes():
message = {
"dataSets": [
{
"series": {
"0": {
"attributes": [0, None, 9],
"observations": {"0": [2.0, 0, None]},
}
}
}
],
"structure": {
"dimensions": {
"series": [{"id": "FREQ", "values": [{"id": "D", "name": "Daily"}]}],
"observation": [
{"id": "TIME_PERIOD", "values": [{"id": "2024-01-01"}]}
],
},
"attributes": {
"series": [
{"id": "UNIT", "values": [{"id": "EUR", "name": "Euro"}]},
{"id": "EMPTY", "values": []},
{"id": "OOR", "values": []},
],
"observation": [
{"id": "OBS_STATUS", "values": [{"id": "A", "name": "Normal"}]}
],
},
},
}
rows = parse_sdmx_json(message)
assert len(rows) == 1
row = rows[0]
assert row["FREQ"] == "D"
assert row["FREQ__label"] == "Daily"
assert row["series_key"] == "D"
assert row["_dim_ids"] == ["FREQ"]
assert row["UNIT"] == "EUR"
assert row["OBS_STATUS"] == "A"
assert row["OBS_VALUE"] == 2.0
def test_parse_sdmx_json_plain_values_and_no_obs_dims():
message = {
"dataSets": [{"series": {"0": {"observations": {"0": [1.0]}}}}],
"structure": {"dimensions": {"series": [{"id": "FREQ", "values": ["D"]}]}},
}
rows = parse_sdmx_json(message)
assert rows[0]["FREQ"] == "D"
assert rows[0]["OBS_VALUE"] == 1.0
def test_parse_sdmx_json_edge_branches():
message = {
"dataSets": [
{
"series": {
"0:0:0": {"observations": {}},
"0:5": {
"observations": {
"0": [],
"1": [2.0, 9],
}
},
}
}
],
"structure": {
"dimensions": {
"series": [
{"id": "FREQ", "values": [{"id": "D", "name": "Daily"}]},
{"id": "CURRENCY", "values": [{"id": "USD", "name": "US dollar"}]},
],
"observation": [
{
"id": "TIME_PERIOD",
"values": [{"id": "2024-01-01"}, "2024-01-02"],
}
],
},
"attributes": {
"series": [],
"observation": [
{"id": "OBS_STATUS", "values": [{"id": "A", "name": "Normal"}]}
],
},
},
}
rows = parse_sdmx_json(message)
out_of_range = [r for r in rows if r["FREQ"] == "D" and r["CURRENCY"] is None]
assert out_of_range
assert out_of_range[0]["series_key"] == "D"
assert any(r["OBS_VALUE"] is None for r in out_of_range)
assert all("OBS_STATUS" not in r for r in out_of_range)
def test_parse_series_keys_empty():
assert parse_series_keys({}) == []
assert parse_series_keys({"dataSets": []}) == []
def test_parse_series_keys_decodes_records():
message = {
"dataSets": [
{
"series": {
"0:0": {},
"0:1:0": {},
"0:5": {},
"": {},
}
}
],
"structure": {
"dimensions": {
"series": [
{"id": "FREQ", "values": [{"id": "D", "name": "Daily"}]},
{
"id": "CURRENCY",
"values": [{"id": "USD", "name": "US dollar"}, "JPY"],
},
]
}
},
}
by_key = {r["series_key"]: r for r in parse_series_keys(message)}
full = by_key["D.USD"]
assert full["FREQ"] == "D"
assert full["CURRENCY"] == "USD"
assert full["FREQ__label"] == "Daily"
assert full["name"] == "Daily — US dollar"
plain = by_key["D.JPY"]
assert plain["CURRENCY"] == "JPY"
assert plain["CURRENCY__label"] is None
assert plain["name"] == "Daily"
out_of_range = by_key["D"]
assert out_of_range["CURRENCY"] is None
empty = by_key[""]
assert empty["name"] == ""