From 01f181689e0dcc4d13b81a07365418b63c083ade Mon Sep 17 00:00:00 2001 From: hermes Date: Fri, 16 Oct 2026 09:00:44 +0000 Subject: [PATCH] test(mcp): pin paging past the end and the per-page summary From the Pullfrog review of #48: an offset at or past `total` returns an empty page with `next_offset: null`, and every page carries the same `summary` (it covers all rows). Assert both. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01V3syn2fN2LNo5pvTSqc6eh --- crates/idx-mcp/tests/mcp.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/crates/idx-mcp/tests/mcp.rs b/crates/idx-mcp/tests/mcp.rs index c35ef5a..906c87f 100644 --- a/crates/idx-mcp/tests/mcp.rs +++ b/crates/idx-mcp/tests/mcp.rs @@ -357,6 +357,8 @@ fn ownership_tools_read_the_local_database() { json!({"from": "2026-01-30", "to": "2026-02-27", "limit": 2, "offset": next}), ); paged.extend(page["changes"].as_array().unwrap().iter().cloned()); + // The summary covers all rows, so every page carries the same one. + assert_eq!(page["summary"], all["summary"], "offset {next}"); offset = page["next_offset"].as_u64(); } assert_eq!(paged.len() as u64, total); @@ -377,6 +379,21 @@ fn ownership_tools_read_the_local_database() { ); assert!(all["summary"]["tickers"].as_u64().unwrap() >= 1, "{all}"); + // Past the end: an empty last page, not an error. + for past in [total, total + 5] { + let page = client.ok( + "get_ownership_changes", + json!({"from": "2026-01-30", "to": "2026-02-27", "offset": past}), + ); + assert_eq!(page["total"], total, "offset {past}"); + assert_eq!( + page["changes"].as_array().unwrap().len(), + 0, + "offset {past}" + ); + assert!(page["next_offset"].is_null(), "offset {past}: {page}"); + } + let (is_error, body) = client.call( "get_ownership_changes", json!({"from": "2026-01-30", "to": "2026-02-27", "limit": 301}),