""" tests/test_order_manager.py — Order routing and management tests. Covers: - Fractional → 3-step flow - Whole → bracket order routing - DRY_RUN simulation - Spread check threshold - Limit price computation """ from __future__ import annotations import datetime from unittest.mock import patch, MagicMock import pytest from contracts import OrderRequest from execution.order_manager import ( submit_order, check_spread, compute_limit_price, ) @pytest.fixture def buy_order(): return OrderRequest( symbol="AAPL", side="buy", qty=10.0, limit_price=150.50, stop_price=148.00, tp_price=155.00, is_fractional=False, dry_run=True, ) @pytest.fixture def fractional_order(): return OrderRequest( symbol="AAPL", side="buy", qty=0.5, limit_price=150.50, stop_price=148.00, tp_price=155.00, is_fractional=True, dry_run=True, ) class TestOrderRouting: def test_dry_run_whole_order(self, buy_order): """DRY_RUN whole-share order should return a simulated fill.""" result = submit_order(buy_order, alert_callback=lambda *a, **kw: None) assert result is not None def test_dry_run_fractional_order(self, fractional_order): """DRY_RUN fractional order should return a simulated fill.""" result = submit_order(fractional_order, alert_callback=lambda *a, **kw: None) assert result is not None class TestSpreadCheck: def test_dry_run_spread_always_passes(self): """In DRY_RUN, spread check always passes.""" ok, bid, ask, spread_pct = check_spread("AAPL") assert ok @patch("execution.order_manager.config.DRY_RUN", False) @patch("execution.order_manager.broker.get_latest_quote") def test_acceptable_spread(self, mock_quote): mock_quote.return_value = {"bp": 150.00, "ap": 150.10} ok, bid, ask, spread_pct = check_spread("AAPL") assert ok assert spread_pct < 0.5 # 0.067% spread @patch("execution.order_manager.config.DRY_RUN", False) @patch("execution.order_manager.broker.get_latest_quote") def test_wide_spread_rejected(self, mock_quote): mock_quote.return_value = {"bp": 150.00, "ap": 155.00} ok, bid, ask, spread_pct = check_spread("AAPL") assert not ok assert spread_pct > 0.5 class TestLimitPrice: def test_buy_limit_within_spread(self): price = compute_limit_price("buy", bid=150.00, ask=150.10) assert price >= 150.00 assert price <= 150.10 def test_sell_limit_within_spread(self): price = compute_limit_price("sell", bid=150.00, ask=150.10) assert price >= 150.00 assert price <= 150.10 class TestDryRunSimulation: def test_dry_run_returns_fill(self, buy_order): buy_order.dry_run = True result = submit_order(buy_order, alert_callback=lambda *a, **kw: None) assert result is not None