Remove the next_url extra - the key is always present

next_url became a default table JSON key alongside next, making the
extra a no-op. Requesting ?_extra=next_url now returns the standard
unknown-extra 400 error.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GrHZSypDfMnym1tM5XJAFZ
This commit is contained in:
Claude 2026-07-06 23:59:44 +00:00
commit 4874c29286
No known key found for this signature in database
7 changed files with 23 additions and 43 deletions

View file

@ -722,7 +722,7 @@ def test_config_cache_size(app_client_larger_cache_size):
def test_config_force_https_urls():
with make_app_client(settings={"force_https_urls": True}) as client:
response = client.get(
"/fixtures/facetable.json?_size=3&_facet=state&_extra=next_url,suggested_facets"
"/fixtures/facetable.json?_size=3&_facet=state&_extra=suggested_facets"
)
assert response.json["next_url"].startswith("https://")
assert response.json["facet_results"]["results"]["state"]["results"][0][

View file

@ -739,3 +739,11 @@ async def test_sql_interrupted_html_page_keeps_rich_error(ds_client):
)
assert response.status_code == 400
assert "<textarea" in response.text
@pytest.mark.asyncio
async def test_next_url_extra_no_longer_exists(ds_client):
# next_url is always present in table JSON; the extra was removed
response = await ds_client.get("/fixtures/facetable.json?_extra=next_url")
data = assert_canonical_error(response, 400)
assert data["errors"] == ["Unknown _extra: next_url"]

View file

@ -323,10 +323,6 @@ async def test_paginate_tables_and_views(
fetched = []
count = 0
while path:
if "?" in path:
path += "&_extra=next_url"
else:
path += "?_extra=next_url"
response = await ds_client.get(path)
assert response.status_code == 200
count += 1
@ -359,9 +355,7 @@ async def test_validate_page_size(ds_client, path, expected_error):
@pytest.mark.asyncio
async def test_page_size_zero(ds_client):
"""For _size=0 we return the counts, empty rows and no continuation token"""
response = await ds_client.get(
"/fixtures/no_primary_key.json?_size=0&_extra=count,next_url"
)
response = await ds_client.get("/fixtures/no_primary_key.json?_size=0&_extra=count")
assert response.status_code == 200
assert [] == response.json()["rows"]
assert 202 == response.json()["count"]
@ -372,7 +366,7 @@ async def test_page_size_zero(ds_client):
@pytest.mark.asyncio
async def test_paginate_compound_keys(ds_client):
fetched = []
path = "/fixtures/compound_three_primary_keys.json?_shape=objects&_extra=next_url"
path = "/fixtures/compound_three_primary_keys.json?_shape=objects"
page = 0
while path:
page += 1
@ -393,7 +387,9 @@ async def test_paginate_compound_keys(ds_client):
@pytest.mark.asyncio
async def test_paginate_compound_keys_with_extra_filters(ds_client):
fetched = []
path = "/fixtures/compound_three_primary_keys.json?content__contains=d&_shape=objects&_extra=next_url"
path = (
"/fixtures/compound_three_primary_keys.json?content__contains=d&_shape=objects"
)
page = 0
while path:
page += 1
@ -446,7 +442,7 @@ async def test_paginate_compound_keys_with_extra_filters(ds_client):
],
)
async def test_sortable(ds_client, query_string, sort_key, human_description_en):
path = f"/fixtures/sortable.json?_shape=objects&_extra=human_description_en,next_url&{query_string}"
path = f"/fixtures/sortable.json?_shape=objects&_extra=human_description_en&{query_string}"
fetched = []
page = 0
while path:
@ -850,7 +846,7 @@ def test_page_size_matching_max_returned_rows(
app_client_returned_rows_matches_page_size,
):
fetched = []
path = "/fixtures/no_primary_key.json?_extra=next_url"
path = "/fixtures/no_primary_key.json"
while path:
response = app_client_returned_rows_matches_page_size.get(path)
fetched.extend(response.json["rows"])