from __future__ import annotations from pathlib import Path from prod.bingx.sandbox_status import build_sandbox_status from prod.bingx.sandbox_status import load_sandbox_status from prod.bingx.sandbox_status import write_sandbox_status def test_build_sandbox_status_marks_clean_when_flat(): status = build_sandbox_status( balance_payload={ "balance": { "balance": "12000.5", "equity": "12000.5", "availableMargin": "12000.5", "unrealizedProfit": "0", "usedMargin": "0", } }, positions_payload=[], open_orders_payload={"orders": []}, environment="VST", ) assert status.clean is True assert status.balance == 12000.5 assert status.equity == 12000.5 assert status.open_positions == 0 assert status.open_orders == 0 def test_build_sandbox_status_marks_dirty_when_positions_or_orders_exist(): status = build_sandbox_status( balance_payload={ "balance": { "balance": "12000.5", "equity": "12500.5", "availableMargin": "9000.5", "unrealizedProfit": "500", "usedMargin": "3000", } }, positions_payload=[{"symbol": "BTC-USDT"}, {"symbol": "ETH-USDT"}], open_orders_payload={"orders": [{"symbol": "BTC-USDT"}]}, environment="VST", ) assert status.clean is False assert status.open_positions == 2 assert status.open_orders == 1 assert status.unrealized_profit == 500.0 def test_write_and_load_sandbox_status_round_trip(tmp_path: Path): status = build_sandbox_status( balance_payload={"balance": {"balance": "10", "equity": "11", "availableMargin": "9", "unrealizedProfit": "1", "usedMargin": "2"}}, positions_payload=[], open_orders_payload=[], environment="VST", notes={"source": "unit-test"}, ) path = tmp_path / "bingx_sandbox_status.json" write_sandbox_status(status, path) loaded = load_sandbox_status(path) assert loaded is not None assert loaded["balance"] == 10.0 assert loaded["equity"] == 11.0 assert loaded["clean"] is True assert loaded["notes"]["source"] == "unit-test"