fix(viz_routes): address PR #767 review — param parity + always-on page_number

- Replace bare int() casts for start/end/context_chars in chunk_context_endpoint
  with _parse_int_param, matching visualization.py bounds (0–10M for offsets,
  0–10K for context_chars), and add the missing end > start guard.
- Initialize page_number from chunk_context.page_number so non-file doc_types
  surface it; include page_number, chunk_index, and total_chunks unconditionally
  in the response. Only highlighted_page_image stays gated on its own truthiness.
- Add a chunk_index forwarding regression test that asserts the new kwargs reach
  get_chunk_with_context and appear in the response payload.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Chris Coutinho
2026-05-08 19:14:43 +02:00
co-authored by Claude Opus 4.7
parent a33a365a69
commit 53e6dba5a2
2 changed files with 67 additions and 6 deletions
@@ -259,6 +259,58 @@ class TestChunkContextCredentialPath:
assert "failed to fetch chunk context" in data["error"].lower()
class TestChunkContextParameterForwarding:
"""Verify new chunk_index / total_chunks query params reach the lookup.
Regression guard for PR #767: the whole point of the fix is that callers
pass chunk_index, and it must arrive at get_chunk_with_context as the
primary Qdrant lookup key.
"""
def test_chunk_index_and_total_chunks_forwarded(self):
mock_nc_client = _make_mock_nc_client()
mock_ctx = _make_mock_chunk_context()
mock_ctx.chunk_index = 7
mock_ctx.total_chunks = 10
with (
patch(
"nextcloud_mcp_server.api.visualization.validate_token_and_get_user",
new_callable=AsyncMock,
return_value=("testuser", True),
),
patch(
"nextcloud_mcp_server.api.visualization.get_user_client_basic_auth",
new_callable=AsyncMock,
return_value=mock_nc_client,
),
patch(
"nextcloud_mcp_server.api.visualization.get_chunk_with_context",
new_callable=AsyncMock,
return_value=mock_ctx,
) as mock_get_chunk,
):
app = create_test_app()
client = TestClient(app)
response = client.get(
"/api/v1/chunk-context?doc_type=note&doc_id=42"
"&start=0&end=10&chunk_index=7&total_chunks=10",
headers={"Authorization": "Bearer test-token"},
)
assert response.status_code == 200
kwargs = mock_get_chunk.await_args.kwargs
assert kwargs["chunk_index"] == 7
assert kwargs["total_chunks"] == 10
data = response.json()
assert data["chunk_index"] == 7
assert data["total_chunks"] == 10
# page_number must be present even when None (frontend may scroll
# by it for non-file doc types)
assert "page_number" in data
class TestChunkContextConfigErrors:
"""Tests for configuration failure paths."""