Skip to content

Test coverage: _list_all max_pages cap + expose on public *_all() methods #98

Description

@TexasCoding

From Wave 5 — F-Q-04, F-Q-17, F-N-14. Severity: medium.

Coverage gap (F-Q-04)

`_list_all` (`kalshi/resources/_base.py:147-185` sync, `:260-291` async) hard-codes `max_pages: int = 1000` as a safety net for "server never repeats a cursor but never returns empty either". Cursor-loop detection is well-tested; the bare numeric cap isn't.

A refactor turning `for _ in range(max_pages)` into `while page.cursor` would compile, ship, and hang.

Test: mock an endpoint returning a fresh unique cursor on every call. Call `_list_all` with `max_pages=3`. Assert exactly 3 requests fired and 3 items yielded. Mirror sync/async.

Coverage gap (F-Q-17)

Empty-string cursor termination is asserted at the model level (`Page.has_next`) but no end-to-end test confirms `_list_all` stops after a page returns `{"cursor": ""}`. Borderline pinned — explicit assertion would catch a regression that forwards cursor unconditionally.

Test: mock a single-page response with `{"items": [{"id": "a"}], "cursor": ""}`. Assert `route.call_count == 1` after `list(_list_all(...))`.

Architecture gap (F-N-14)

The `max_pages` arg exists on `_list_all` but no public `*_all()` method forwards it. Callers can't raise the limit without subclassing the resource. For long histories (`markets.list_trades_all` over years, `historical.trades_all` with no `min_ts`), 1000 pages × default page size could exhaust the data well before the user expects, returning a silent partial.

Fix options:

  • Expose `max_pages` as a kwarg on the public `*_all()` methods (same 1000 default).
  • Raise a sentinel error when the cap is hit so users learn the iterator terminated artificially. Today the iterator just `break`s with no signal.

The two test gaps stay either way; exposing the kwarg adds a public API surface that should also have its own test.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions