This commit is contained in:
Simon Willison 2026-10-12 18:14:28 +00:00 • committed by GitHub
commit dec829d7ae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 180 additions and 7 deletions

View file

@ -5,7 +5,17 @@ from datasette.utils.asgi import Response
async def can_render(
datasette, columns, rows, sql, query_name, database, table, request, view_name
datasette,
columns,
rows,
sql,
query_name,
database,
table,
request,
path,
full_path,
view_name,
):
# We stash this on datasette so the calling unit test can see it
datasette._can_render_saw = {
@ -17,13 +27,26 @@ async def can_render(
"database": database,
"table": table,
"request": request,
"path": path,
"full_path": full_path,
"view_name": view_name,
}
return not request.args.get("_no_can_render")
async def render_test_all_parameters(
datasette, columns, rows, sql, query_name, database, table, request, view_name, data
datasette,
columns,
rows,
sql,
query_name,
database,
table,
request,
path,
full_path,
view_name,
data,
):
headers = {}
for custom_header in request.args.getlist("header"):
@ -41,6 +64,8 @@ async def render_test_all_parameters(
"database": database,
"table": table,
"request": request,
"path": path,
"full_path": full_path,
"view_name": view_name,
"1+1": result.first()[0],
},

View file

@ -624,11 +624,50 @@ async def test_hook_register_output_renderer_all_parameters(ds_client):
"database": "fixtures",
"table": "facetable",
"request": '<asgi.Request method="GET" url="http://localhost/fixtures/facetable.testall">',
"path": "/fixtures/facetable",
"full_path": "/fixtures/facetable",
"view_name": "table",
"1+1": 2,
}
@pytest.mark.asyncio
@pytest.mark.parametrize(
"path,expected_path,expected_full_path",
(
(
"/fixtures/facetable.testall?_sort_desc=pk&_size=2",
"/fixtures/facetable",
"/fixtures/facetable?_sort_desc=pk&_size=2",
),
(
"/fixtures/simple_primary_key/1.testall",
"/fixtures/simple_primary_key/1",
"/fixtures/simple_primary_key/1",
),
(
"/fixtures/-/query.testall?sql=select+1",
"/fixtures/-/query",
"/fixtures/-/query?sql=select+1",
),
(
"/fixtures/pragma_cache_size.testall",
"/fixtures/pragma_cache_size",
"/fixtures/pragma_cache_size",
),
),
)
async def test_hook_register_output_renderer_path_and_full_path(
ds_client, path, expected_path, expected_full_path
):
# https://github.com/simonw/datasette/issues/1179
response = await ds_client.get(path)
assert response.status_code == 200
data = json.loads(response.text)
assert data["path"] == expected_path
assert data["full_path"] == expected_full_path
@pytest.mark.asyncio
async def test_hook_register_output_renderer_custom_status_code(ds_client):
response = await ds_client.get(
@ -701,10 +740,34 @@ async def test_hook_register_output_renderer_can_render(ds_client):
"query_name": None,
"database": "fixtures",
"table": "facetable",
"path": "/fixtures/facetable",
"full_path": "/fixtures/facetable?_no_can_render=1",
"view_name": "table",
}.items() <= ds_client.ds._can_render_saw.items()
@pytest.mark.asyncio
async def test_hook_register_output_renderer_renderers_extra_links(ds_client):
# https://github.com/simonw/datasette/issues/1179
# Links from a .json page previously came out as
# /fixtures/facetable.json?_format=testall - which returned JSON
response = await ds_client.get("/fixtures/facetable.json?_extra=renderers")
assert response.status_code == 200
renderers = response.json()["renderers"]
assert renderers["json"] == "/fixtures/facetable.json?_extra=renderers&_labels=on"
assert (
renderers["testall"]
== "/fixtures/facetable.testall?_extra=renderers&_labels=on"
)
saw = ds_client.ds._can_render_saw
assert saw["path"] == "/fixtures/facetable"
assert saw["full_path"] == "/fixtures/facetable?_extra=renderers"
# Following the link should run the renderer
response = await ds_client.get(renderers["testall"])
assert response.status_code == 200
assert response.headers["content-type"] == "text/plain"
@pytest.mark.asyncio
async def test_hook_register_output_renderer_can_render_canned_query(ds_client):
# https://github.com/simonw/datasette/issues/2711

View file

@ -578,6 +578,56 @@ def test_path_with_format_can_override_request_path():
assert "/foo.json?x=1" == actual
@pytest.mark.parametrize(
"path,url_vars,expected",
[
# https://github.com/simonw/datasette/issues/1179
("/db/table.Notebook", {"format": "Notebook"}, "/db/table.json"),
("/db/table.csv?_size=max", {"format": "csv"}, "/db/table.json?_size=max"),
("/db/table", {}, "/db/table.json"),
],
)
def test_path_with_format_replaces_current_format(path, url_vars, expected):
request = Request.fake(path, url_vars=url_vars)
assert utils.path_with_format(request=request, format="json") == expected
def test_path_with_format_replaces_current_format_with_path_override():
request = Request.fake("/prefix/db/table.csv?x=1", url_vars={"format": "csv"})
actual = utils.path_with_format(
request=request, path="/db/table.csv", format="json"
)
assert actual == "/db/table.json?x=1"
@pytest.mark.parametrize(
"path,url_vars,expected_path,expected_full_path",
[
("/db/table", {}, "/db/table", "/db/table"),
("/db/table.json", {"format": "json"}, "/db/table", "/db/table"),
(
"/db/table.Notebook?_sort=pk",
{"format": "Notebook"},
"/db/table",
"/db/table?_sort=pk",
),
(
"/prefix/db/-/query.csv?sql=select+1",
{"format": "csv"},
"/prefix/db/-/query",
"/prefix/db/-/query?sql=select+1",
),
],
)
def test_path_without_format(path, url_vars, expected_path, expected_full_path):
request = Request.fake(path, url_vars=url_vars)
assert utils.path_without_format(request) == expected_path
assert (
utils.path_without_format(request, include_query_string=True)
== expected_full_path
)
@pytest.mark.parametrize(
"bytes,expected",
[