fix(assets): address bot review comments

- Soften offset param prose: it's not deprecated, just not preferred for
  sequential walks. Random-access UIs (jump-to-page, item count displays)
  legitimately still want offset, so dropping the 'deprecated' framing
  rather than promoting it to a machine-readable deprecated:true flag.
- Add explicit HTTP status assertions before every json() / next_cursor
  read in test_list_cursor.py so a failing request surfaces as an HTTP
  error instead of a confusing KeyError on a 4xx/5xx body.
This commit is contained in:
Matt Miller 2026-05-20 13:52:54 -07:00
parent 9b0042d78c
commit 33a57cc9e8
2 changed files with 12 additions and 2 deletions

View File

@ -1518,8 +1518,11 @@ paths:
type: integer
default: 0
description: |
Deprecated in favor of `after` cursor pagination. When both are
supplied, `after` wins and `offset` is ignored.
Offset-based pagination. Cursor pagination via `after` is preferred
for sequential walks (stable across concurrent inserts/deletes) but
`offset` remains fully supported for random access (jump-to-page
UIs, "showing items XY of N" displays). When both are supplied,
`after` wins and `offset` is ignored.
- name: after
in: query
schema:

View File

@ -109,6 +109,7 @@ def test_cursor_wins_over_offset(http: requests.Session, api_base: str, asset_fa
},
timeout=120,
)
assert r.status_code == 200, r.text
cursor = r.json()["next_cursor"]
assert cursor is not None
@ -144,6 +145,7 @@ def test_next_cursor_absent_when_no_more_results(http: requests.Session, api_bas
},
timeout=120,
)
assert r.status_code == 200, r.text
body = r.json()
assert body["has_more"] is False
assert "next_cursor" not in body
@ -159,6 +161,7 @@ def test_cursor_pagination_first_page_mints_cursor(http: requests.Session, api_b
params={"include_tags": "unit-tests,cursor-first-page", "sort": "name", "order": "asc", "limit": "2"},
timeout=120,
)
assert r.status_code == 200, r.text
body = r.json()
assert body["has_more"] is True
assert body.get("next_cursor"), "first page must mint a cursor when more rows exist"
@ -175,6 +178,7 @@ def test_cursor_no_spurious_cursor_when_page_size_equals_remainder(http: request
params={"include_tags": "unit-tests,cursor-exact-multiple", "sort": "name", "order": "asc", "limit": "2"},
timeout=120,
)
assert r.status_code == 200, r.text
cursor = r.json()["next_cursor"]
assert cursor is not None
# Page 2 — should exhaust the set with no cursor for a phantom page 3
@ -183,6 +187,7 @@ def test_cursor_no_spurious_cursor_when_page_size_equals_remainder(http: request
params={"include_tags": "unit-tests,cursor-exact-multiple", "sort": "name", "order": "asc", "limit": "2", "after": cursor},
timeout=120,
)
assert r2.status_code == 200, r2.text
body = r2.json()
assert len(body["assets"]) == 2
assert body["has_more"] is False
@ -245,6 +250,7 @@ def test_cursor_order_mismatch_returns_400(http: requests.Session, api_base: str
},
timeout=120,
)
assert r.status_code == 200, r.text
cursor = r.json()["next_cursor"]
assert cursor is not None
@ -321,5 +327,6 @@ def test_cursor_pagination_stable_after_delete(http: requests.Session, api_base:
},
timeout=120,
)
assert r2.status_code == 200, r2.text
body2 = r2.json()
assert [a["name"] for a in body2["assets"]] == names[2:]