"""TDD tests for new conftest fixtures.
These tests verify the behavior of three new fixtures that will be added to conftest.py:
- fake_call_factory: Creates a fake call function with optional return value
- order_response_factory: Creates a mock HTTP response for order placement
- place_order_client_factory: Creates a client that captures place_order() calls
Tests are written in RED phase (expected to fail until fixtures are implemented).
"""
from __future__ import annotations
import asyncio
from typing import Any
class TestFakeCallFactory:
"""Tests for fake_call_factory fixture."""
def test_fake_call_factory_returns_tuple(self, fake_call_factory):
"""Verify fake_call_factory returns (captured, fake_call) tuple."""
result = fake_call_factory()
assert isinstance(result, tuple)
assert len(result) == 2
def test_fake_call_factory_captures_function_reference(self, fake_call_factory):
"""Verify fake_call_factory captures the function being called."""
captured, fake_call = fake_call_factory()
async def dummy_func(x: int, y: int) -> int:
return x + y
asyncio.run(fake_call(dummy_func, 1, 2))
assert captured["func"] == dummy_func
def test_fake_call_factory_captures_positional_args(self, fake_call_factory):
"""Verify fake_call_factory captures positional arguments."""
captured, fake_call = fake_call_factory()
async def dummy_func(x: int, y: int) -> int:
return x + y
asyncio.run(fake_call(dummy_func, 42, 99))
assert captured["args"] == (42, 99)
def test_fake_call_factory_captures_keyword_args(self, fake_call_factory):
"""Verify fake_call_factory captures keyword arguments."""
captured, fake_call = fake_call_factory()
async def dummy_func(x: int, y: int) -> int:
return x + y
asyncio.run(fake_call(dummy_func, 1, 2, z=3, w=4))
assert captured["kwargs"] == {"z": 3, "w": 4}
def test_fake_call_factory_returns_default_value(self, fake_call_factory):
"""Verify fake_call_factory returns 'ok' by default."""
captured, fake_call = fake_call_factory()
async def dummy_func() -> None:
pass
result = asyncio.run(fake_call(dummy_func))
assert result == "ok"
def test_fake_call_factory_accepts_custom_return_value(self, fake_call_factory):
"""Verify fake_call_factory accepts optional return_value parameter."""
custom_return = {"status": "success", "data": [1, 2, 3]}
captured, fake_call = fake_call_factory(return_value=custom_return)
async def dummy_func() -> None:
pass
result = asyncio.run(fake_call(dummy_func))
assert result == custom_return
def test_fake_call_factory_with_mixed_args_and_kwargs(self, fake_call_factory):
"""Verify fake_call_factory handles mixed args and kwargs correctly."""
captured, fake_call = fake_call_factory()
async def dummy_func(a: int, b: int, c: int = 0) -> int:
return a + b + c
asyncio.run(fake_call(dummy_func, 10, 20, c=30, d=40))
assert captured["args"] == (10, 20)
assert captured["kwargs"] == {"c": 30, "d": 40}
class TestOrderResponseFactory:
"""Tests for order_response_factory fixture."""
def test_order_response_factory_creates_response(self, order_response_factory):
"""Verify order_response_factory creates a response object."""
response = order_response_factory()
assert response is not None
def test_order_response_factory_sets_status_code_201(self, order_response_factory):
"""Verify order_response_factory sets status_code to 201."""
response = order_response_factory()
assert response.status_code == 201
def test_order_response_factory_sets_location_header(self, order_response_factory):
"""Verify order_response_factory sets Location header with order ID."""
account_hash = "test_account_hash"
order_id = 987654321
response = order_response_factory(account_hash=account_hash, order_id=order_id)
expected_location = f"https://api.schwabapi.com/trader/v1/accounts/{account_hash}/orders/{order_id}"
assert response.headers["Location"] == expected_location
def test_order_response_factory_sets_url(self, order_response_factory):
"""Verify order_response_factory sets url to orders endpoint."""
account_hash = "my_account"
response = order_response_factory(account_hash=account_hash)
expected_url = (
f"https://api.schwabapi.com/trader/v1/accounts/{account_hash}/orders"
)
assert response.url == expected_url
def test_order_response_factory_has_raise_for_status(self, order_response_factory):
"""Verify order_response_factory response has raise_for_status method."""
response = order_response_factory()
assert hasattr(response, "raise_for_status")
assert callable(response.raise_for_status)
def test_order_response_factory_raise_for_status_succeeds(
self, order_response_factory
):
"""Verify raise_for_status() doesn't raise for 201 status."""
response = order_response_factory()
# Should not raise
response.raise_for_status()
def test_order_response_factory_has_text_and_content(self, order_response_factory):
"""Verify order_response_factory response has text and content attributes."""
response = order_response_factory()
assert hasattr(response, "text")
assert hasattr(response, "content")
class TestPlaceOrderClientFactory:
"""Tests for place_order_client_factory fixture."""
def test_place_order_client_factory_creates_client(
self, place_order_client_factory
):
"""Verify place_order_client_factory creates a client object."""
client = place_order_client_factory()
assert client is not None
def test_place_order_client_factory_client_has_place_order_method(
self, place_order_client_factory
):
"""Verify client has place_order method."""
client = place_order_client_factory()
assert hasattr(client, "place_order")
assert callable(client.place_order)
def test_place_order_client_factory_captures_place_order_call(
self, place_order_client_factory
):
"""Verify client captures place_order() calls."""
client = place_order_client_factory()
async def run_test() -> None:
await client.place_order("account123", {"symbol": "AAPL", "quantity": 10})
asyncio.run(run_test())
assert client.captured is not None
assert "args" in client.captured
assert "kwargs" in client.captured
def test_place_order_client_factory_captures_positional_args(
self, place_order_client_factory
):
"""Verify client captures positional arguments to place_order()."""
client = place_order_client_factory()
async def run_test() -> None:
await client.place_order("account123", {"symbol": "AAPL"})
asyncio.run(run_test())
assert client.captured["args"] == ("account123", {"symbol": "AAPL"})
def test_place_order_client_factory_captures_keyword_args(
self, place_order_client_factory
):
"""Verify client captures keyword arguments to place_order()."""
client = place_order_client_factory()
async def run_test() -> None:
await client.place_order(
"account123", {"symbol": "AAPL"}, session="EXTENDED", duration="GTC"
)
asyncio.run(run_test())
assert client.captured["kwargs"] == {"session": "EXTENDED", "duration": "GTC"}
def test_place_order_client_factory_returns_response(
self, place_order_client_factory
):
"""Verify client.place_order() returns a response object."""
client = place_order_client_factory()
async def run_test() -> Any:
return await client.place_order("account123", {"symbol": "AAPL"})
response = asyncio.run(run_test())
assert response is not None
assert hasattr(response, "status_code")
assert response.status_code == 201
def test_place_order_client_factory_response_has_location_header(
self, place_order_client_factory
):
"""Verify client.place_order() response has Location header."""
client = place_order_client_factory()
async def run_test() -> Any:
return await client.place_order("account123", {"symbol": "AAPL"})
response = asyncio.run(run_test())
assert "Location" in response.headers
assert "orders" in response.headers["Location"]