test(recorder): cover non-JSON body branch (HTML 502, plain text, binary)#132
Conversation
…ary) Adds 4 tests that exercise the `body_kind="text"` fallback in `RecordingTransport`/`_response_to_dict` plus the matching branch in `build_response`. Covers the real-world case where a CDN/proxy 502 returns `<html>...</html>` or other non-JSON payloads — previously unexercised per the Wave 5 audit (F-Q-08). Closes #100 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Code Review — PR #132: Non-JSON body branch coverageOverall: Solid testing PR that fills a real coverage gap. The Issues1. Multi-line docstrings/comments violate CLAUDE.md style CLAUDE.md is explicit: "Never write multi-paragraph docstrings or multi-line comment blocks — one short line max." Three of the four new test functions have two-line docstrings, and the section header is a verbose multi-line block comment: # ---------------------------------------------------------------------------
# Non-JSON body coverage (#100 — F-Q-08)
#
# Real-world recordings will eventually capture an HTML 502 ...
# ---------------------------------------------------------------------------The existing tests in this file use single-line docstrings consistently (e.g. 2. This test records a plain-text 503 and asserts the fixture shape, but never replays it. The plain-text replay path ( 3. Binary replay asserts only that an error is raised, not that bytes survived
replay = ReplayTransport(fixtures_dir)
with KalshiClient(transport=replay, max_retries=0) as client, pytest.raises(KalshiServerError):
client.exchange.status()This checks liveness but not correctness — if pytest.raises(KalshiServerError) as exc_info:
...
assert body.decode("latin-1") in str(exc_info.value) # or assert exc_info.value.status_code == 502For truly non-printable binary content the string check is awkward, but at minimum 4. Minor: In Nits
SummaryThe core coverage is valuable and the implementation is correct per the PR description. The blocking items are:
Item 3 (binary replay assertion strength) is a nice-to-have. Everything else is minor. |
Summary
Wave 2 #100: pin
RecordingTransport's non-JSON body branch — previously only JSON responses had test coverage, so a regression in the latin-1 fallback / text branch ofbuild_responsewould go silently undetected.4 new tests in
tests/test_mock_transport.py(+127 lines):test_record_non_json_html_body_persists_as_text— 502 withtext/htmlbody; assertsbody_kind == "text", byte-for-byte round-trip, content-type preservedtest_replay_non_json_html_body_surfaces_server_error— replays from disk only; verifiesKalshiServerError(status_code=502)with the HTML payload visible in the messagetest_record_non_json_plain_text_body_persists_as_text— 503 withtext/plain; charset=utf-8test_record_non_json_binary_body_persists_as_text—application/octet-streambody containing every byte 0x00–0xFF (invalid UTF-8) to prove the latin-1 round-trip is losslessImplementation notes:
max_retries=0on the test config keeps 502/503 from triggering the SDK retry loop and piling up duplicate recorded pairsKalshiClientcontext before reading fixture files from disk so they hit the post-perf: O(1) qsize, AWS Full Jitter, buffered recordings #111 buffered/flush-on-close shape correctlyRecorder bugs found: none. Behavior is correct; latin-1 round-trip is lossless and
build_responsereconstructs non-JSON bodies properly.Closes #100
Test plan
uv run ruff check .cleanuv run mypy kalshi/clean (strict)