test(config): cover trailing-slash stripping + extra_headers#131
Conversation
Adds tests/test_config.py with 10 tests closing the Wave 5 audit gaps: - F-Q-05: __post_init__ rstrips trailing slashes on base_url and ws_base_url, multiple-slash defense, validation still passes after stripping, and an end-to-end signed GET against a trailing-slash base that asserts no // in the wire URL (regression for the auth-signing failure mode the post-init prevents). - F-Q-06: extra_headers reach the wire via respx, coexist with per-request KALSHI-ACCESS-* auth headers (no overwrite either direction), persist across multiple requests, and the default_factory dict is per-instance. Closes #99 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Code Review — PR #131: test(config): cover trailing-slash stripping + extra_headersVerdict: Approve with minor suggestions. Clean, well-structured, test-only PR. The tests are correctly scoped to Docstring inconsistency (bug)The module-level docstring says "Wave 5 audit": """...
Covers two gaps flagged by Wave 5 audit (issue #99):
...
"""But the PR description says "Wave 2 #99". The PR description is likely correct. Fix the docstring. Missing: async transport coverage
Missing: auth-header collision behaviorThe PR description claims extras "coexist with KALSHI-ACCESS-{KEY,SIGNATURE,TIMESTAMP} (no overwrite either direction)". The existing tests verify auth headers are present when extras are set, but there's no test for the collision direction — i.e., what happens when a user passes: extra_headers={"KALSHI-ACCESS-KEY": "user-supplied"}In practice, per-request headers passed to def test_extra_headers_cannot_overwrite_auth_headers(self, test_auth: KalshiAuth) -> None:
config = KalshiConfig(
...,
extra_headers={"KALSHI-ACCESS-KEY": "user-supplied"},
)
...
assert request.headers["KALSHI-ACCESS-KEY"] == "test-key-id" # auth winsStyle: module docstring length
Minor: a few WHAT commentsPer CLAUDE.md, comments should explain the non-obvious WHY, not describe what the code does. Two comments are borderline: # Defensive: rstrip("/") removes all of them, not just one.This describes what # Route asserts the URL has no // before "markets". If the trailing slash
# had leaked through, httpx would emit /trade-api/v2//markets and miss this route.The route URL in the mock already makes this obvious. Consider dropping. The What's good
|
Summary
Wave 2 #99: pin two thin
KalshiConfigbehaviors that were unexercised by unit tests.New
tests/test_config.py(163 lines, 10 tests):F-Q-05 — trailing-slash stripping
.demo()classmethod, and validation passing after stripping//appears in the wire URL whenbase_urlends in/F-Q-06 —
extra_headersKALSHI-ACCESS-{KEY,SIGNATURE,TIMESTAMP}(no overwrite either direction), and persist across multiple requestsdefault_factory=dictgives eachKalshiConfiginstance its own dictBugs found: none — behavior matched documentation.
File choice: new
tests/test_config.pyrather than extending the already-28KBtest_client.py.test_config_ws.pyalready owns the WS-URL slice; this file owns the broaderKalshiConfigsurface.Closes #99
Test plan
uv run ruff check .cleanuv run mypy kalshi/clean (strict)