mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
New JSON design for query views (#2118)
* Refs #2111, closes #2110 * New Context dataclass/subclass mechanism, refs #2127 * Define QueryContext and extract get_tables() method, refs #2127 * Fix OPTIONS bug by porting DaatbaseView to be a View subclass * Expose async_view_for_class.view_class for test_routes test * Error/truncated aruments for renderers, closes #2130
This commit is contained in:
parent
5139c0886a
commit
1377a290cd
15 changed files with 579 additions and 112 deletions
|
|
@ -638,22 +638,21 @@ def test_database_page_for_database_with_dot_in_name(app_client_with_dot):
|
|||
@pytest.mark.asyncio
|
||||
async def test_custom_sql(ds_client):
|
||||
response = await ds_client.get(
|
||||
"/fixtures.json?sql=select+content+from+simple_primary_key&_shape=objects"
|
||||
"/fixtures.json?sql=select+content+from+simple_primary_key"
|
||||
)
|
||||
data = response.json()
|
||||
assert {"sql": "select content from simple_primary_key", "params": {}} == data[
|
||||
"query"
|
||||
]
|
||||
assert [
|
||||
{"content": "hello"},
|
||||
{"content": "world"},
|
||||
{"content": ""},
|
||||
{"content": "RENDER_CELL_DEMO"},
|
||||
{"content": "RENDER_CELL_ASYNC"},
|
||||
] == data["rows"]
|
||||
assert ["content"] == data["columns"]
|
||||
assert "fixtures" == data["database"]
|
||||
assert not data["truncated"]
|
||||
assert data == {
|
||||
"rows": [
|
||||
{"content": "hello"},
|
||||
{"content": "world"},
|
||||
{"content": ""},
|
||||
{"content": "RENDER_CELL_DEMO"},
|
||||
{"content": "RENDER_CELL_ASYNC"},
|
||||
],
|
||||
"columns": ["content"],
|
||||
"ok": True,
|
||||
"truncated": False,
|
||||
}
|
||||
|
||||
|
||||
def test_sql_time_limit(app_client_shorter_time_limit):
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ def test_serve_with_get(tmp_path_factory):
|
|||
)
|
||||
assert 0 == result.exit_code, result.output
|
||||
assert {
|
||||
"database": "_memory",
|
||||
"truncated": False,
|
||||
"columns": ["sqlite_version()"],
|
||||
}.items() <= json.loads(result.output).items()
|
||||
|
|
|
|||
|
|
@ -248,6 +248,9 @@ async def test_css_classes_on_body(ds_client, path, expected_classes):
|
|||
assert classes == expected_classes
|
||||
|
||||
|
||||
templates_considered_re = re.compile(r"<!-- Templates considered: (.*?) -->")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
"path,expected_considered",
|
||||
|
|
@ -271,7 +274,10 @@ async def test_css_classes_on_body(ds_client, path, expected_classes):
|
|||
async def test_templates_considered(ds_client, path, expected_considered):
|
||||
response = await ds_client.get(path)
|
||||
assert response.status_code == 200
|
||||
assert f"<!-- Templates considered: {expected_considered} -->" in response.text
|
||||
match = templates_considered_re.search(response.text)
|
||||
assert match, "No templates considered comment found"
|
||||
actual_considered = match.group(1)
|
||||
assert actual_considered == expected_considered
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
"""
|
||||
Tests for the datasette.app.Datasette class
|
||||
"""
|
||||
from datasette import Forbidden
|
||||
import dataclasses
|
||||
from datasette import Forbidden, Context
|
||||
from datasette.app import Datasette, Database
|
||||
from itsdangerous import BadSignature
|
||||
import pytest
|
||||
from typing import Optional
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
|
@ -136,6 +138,22 @@ async def test_datasette_render_template_no_request():
|
|||
assert "Error " in rendered
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_datasette_render_template_with_dataclass():
|
||||
@dataclasses.dataclass
|
||||
class ExampleContext(Context):
|
||||
title: str
|
||||
status: int
|
||||
error: str
|
||||
|
||||
context = ExampleContext(title="Hello", status=200, error="Error message")
|
||||
ds = Datasette(memory=True)
|
||||
await ds.invoke_startup()
|
||||
rendered = await ds.render_template("error.html", context)
|
||||
assert "<h1>Hello</h1>" in rendered
|
||||
assert "Error message" in rendered
|
||||
|
||||
|
||||
def test_datasette_error_if_string_not_list(tmpdir):
|
||||
# https://github.com/simonw/datasette/issues/1985
|
||||
db_path = str(tmpdir / "data.db")
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import pytest
|
|||
],
|
||||
)
|
||||
async def test_add_message_sets_cookie(ds_client, qs, expected):
|
||||
response = await ds_client.get(f"/fixtures.message?{qs}")
|
||||
response = await ds_client.get(f"/fixtures.message?sql=select+1&{qs}")
|
||||
signed = response.cookies["ds_messages"]
|
||||
decoded = ds_client.ds.unsign(signed, "messages")
|
||||
assert expected == decoded
|
||||
|
|
@ -21,7 +21,9 @@ async def test_add_message_sets_cookie(ds_client, qs, expected):
|
|||
@pytest.mark.asyncio
|
||||
async def test_messages_are_displayed_and_cleared(ds_client):
|
||||
# First set the message cookie
|
||||
set_msg_response = await ds_client.get("/fixtures.message?add_msg=xmessagex")
|
||||
set_msg_response = await ds_client.get(
|
||||
"/fixtures.message?sql=select+1&add_msg=xmessagex"
|
||||
)
|
||||
# Now access a page that displays messages
|
||||
response = await ds_client.get("/", cookies=set_msg_response.cookies)
|
||||
# Messages should be in that HTML
|
||||
|
|
|
|||
|
|
@ -121,9 +121,8 @@ async def test_hook_extra_css_urls(ds_client, path, expected_decoded_object):
|
|||
][0]["href"]
|
||||
# This link has a base64-encoded JSON blob in it
|
||||
encoded = special_href.split("/")[3]
|
||||
assert expected_decoded_object == json.loads(
|
||||
base64.b64decode(encoded).decode("utf8")
|
||||
)
|
||||
actual_decoded_object = json.loads(base64.b64decode(encoded).decode("utf8"))
|
||||
assert expected_decoded_object == actual_decoded_object
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
|
|
|||
|
|
@ -700,7 +700,6 @@ async def test_max_returned_rows(ds_client):
|
|||
"/fixtures.json?sql=select+content+from+no_primary_key"
|
||||
)
|
||||
data = response.json()
|
||||
assert {"sql": "select content from no_primary_key", "params": {}} == data["query"]
|
||||
assert data["truncated"]
|
||||
assert 100 == len(data["rows"])
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue