Build 060.3: add REST trade schema validation

This commit is contained in:
2026-07-18 14:16:47 +03:00
parent 013efd8a97
commit c0f69ee94a
4 changed files with 896 additions and 1 deletions

View File

@@ -8,9 +8,11 @@ import pytest
from src.market_data.acquisition.exceptions import (
InstrumentReferenceSchemaError,
TradeSchemaError,
)
from src.market_data.acquisition.validation.schema import (
validate_exchange_info_schema,
validate_rest_agg_trades_schema,
)
@@ -265,4 +267,163 @@ def test_reject_non_object_payload_collection_item(key: str) -> None:
InstrumentReferenceSchemaError,
match=rf"\.{key}\[0\] должен быть JSON-объектом",
):
validate_exchange_info_schema(document)
validate_exchange_info_schema(document)
def test_validate_rest_agg_trades_document() -> None:
document = [
{
"a": 2134857062,
"p": "64497.25",
"q": "0.005",
"T": 1784218066823,
"m": False,
},
{
"a": 2134857063,
"p": "64498.10",
"q": "0.002",
"T": 1784218067000,
"m": True,
},
]
validated = validate_rest_agg_trades_schema(document)
assert len(validated.items) == 2
assert validated.items[0]["a"] == 2134857062
assert validated.items[0]["p"] == "64497.25"
assert validated.items[0]["q"] == "0.005"
assert validated.items[0]["T"] == 1784218066823
assert validated.items[0]["m"] is False
assert isinstance(validated.items, tuple)
assert isinstance(validated.items[0], MappingProxyType)
def test_validate_empty_rest_agg_trades_document() -> None:
validated = validate_rest_agg_trades_schema([])
assert validated.items == ()
def test_rest_agg_trades_schema_preserves_unchecked_field_values() -> None:
document = [
{
"a": "invalid-id",
"p": None,
"q": [],
"T": False,
"m": 123,
}
]
validated = validate_rest_agg_trades_schema(document)
assert validated.items[0]["a"] == "invalid-id"
assert validated.items[0]["p"] is None
assert validated.items[0]["q"] == []
assert validated.items[0]["T"] is False
assert validated.items[0]["m"] == 123
def test_rest_agg_trades_schema_preserves_additional_fields() -> None:
document = [
{
"a": 2134857062,
"p": "64497.25",
"q": "0.005",
"T": 1784218066823,
"m": False,
"extra": "preserved",
}
]
validated = validate_rest_agg_trades_schema(document)
assert validated.items[0]["extra"] == "preserved"
@pytest.mark.parametrize(
"document",
[
None,
{},
"invalid",
123,
],
)
def test_reject_non_list_rest_agg_trades_root(
document: object,
) -> None:
with pytest.raises(
TradeSchemaError,
match=r"\$ должен быть JSON-массивом",
):
validate_rest_agg_trades_schema(document)
@pytest.mark.parametrize(
"item",
[
None,
[],
"invalid",
123,
],
)
def test_reject_non_object_rest_agg_trade_item(
item: object,
) -> None:
with pytest.raises(
TradeSchemaError,
match=r"\$\[0\] должен быть JSON-объектом",
):
validate_rest_agg_trades_schema([item])
@pytest.mark.parametrize(
"missing_key",
[
"a",
"p",
"q",
"T",
"m",
],
)
def test_reject_rest_agg_trade_with_missing_required_field(
missing_key: str,
) -> None:
item: dict[str, object] = {
"a": 2134857062,
"p": "64497.25",
"q": "0.005",
"T": 1784218066823,
"m": False,
}
del item[missing_key]
with pytest.raises(
TradeSchemaError,
match=rf"\$\[0\]\.{missing_key} отсутствует",
):
validate_rest_agg_trades_schema([item])
def test_reject_rest_agg_trade_with_non_string_key() -> None:
document = [
{
"a": 2134857062,
"p": "64497.25",
"q": "0.005",
"T": 1784218066823,
"m": False,
1: "invalid",
}
]
with pytest.raises(
TradeSchemaError,
match=r"\$\[0\] содержит нестроковый ключ типа int",
):
validate_rest_agg_trades_schema(document)