Skip to content

Commit

Permalink
First unit test for writable canned queries, refs #698
Browse files Browse the repository at this point in the history
Message also now shows number of affected rows after executing query.
  • Loading branch information
simonw committed Jun 3, 2020
1 parent 49eed3f commit f45c44a
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 11 deletions.
13 changes: 9 additions & 4 deletions datasette/views/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,18 @@ async def data(
if write:
if request.method == "POST":
params = await request.post_vars()
write_ok = await self.ds.databases[database].execute_write(
cursor = await self.ds.databases[database].execute_write(
sql, params, block=True
)
self.ds.add_message(request, "Query executed")
return self.redirect(
request, request.path
self.ds.add_message(
request,
"Query executed, {} row{} affected".format(
cursor.rowcount, "" if cursor.rowcount == 1 else "s"
),
)
return self.redirect(request, request.path)
else:

async def extra_template():
return {
"request": request,
Expand All @@ -156,6 +160,7 @@ async def extra_template():
"success_message": request.args.get("_success") or "",
"canned_write": True,
}

return (
{
"database": database,
Expand Down
37 changes: 30 additions & 7 deletions tests/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import tempfile
import textwrap
import time
from urllib.parse import unquote, quote
from urllib.parse import unquote, quote, urlencode


# This temp file is used by one of the plugin config tests
Expand Down Expand Up @@ -54,10 +54,26 @@ def __init__(self, asgi_app):
async def get(
self, path, allow_redirects=True, redirect_count=0, method="GET", cookies=None
):
return await self._get(path, allow_redirects, redirect_count, method, cookies)
return await self._request(
path, allow_redirects, redirect_count, method, cookies
)

async def _get(
self, path, allow_redirects=True, redirect_count=0, method="GET", cookies=None
@async_to_sync
async def post(
self, path, post_data=None, allow_redirects=True, redirect_count=0, cookies=None
):
return await self._request(
path, allow_redirects, redirect_count, "POST", cookies, post_data
)

async def _request(
self,
path,
allow_redirects=True,
redirect_count=0,
method="GET",
cookies=None,
post_data=None,
):
query_string = b""
if "?" in path:
Expand All @@ -83,7 +99,13 @@ async def _get(
"headers": headers,
}
instance = ApplicationCommunicator(self.asgi_app, scope)
await instance.send_input({"type": "http.request"})

if post_data:
body = urlencode(post_data, doseq=True).encode("utf-8")
await instance.send_input({"type": "http.request", "body": body})
else:
await instance.send_input({"type": "http.request"})

# First message back should be response.start with headers and status
messages = []
start = await instance.receive_output(2)
Expand All @@ -110,7 +132,7 @@ async def _get(
redirect_count, self.max_redirects
)
location = response.headers["Location"]
return await self._get(
return await self._request(
location, allow_redirects=True, redirect_count=redirect_count + 1
)
return response
Expand All @@ -128,6 +150,7 @@ def make_app_client(
inspect_data=None,
static_mounts=None,
template_dir=None,
metadata=None,
):
with tempfile.TemporaryDirectory() as tmpdir:
filepath = os.path.join(tmpdir, filename)
Expand Down Expand Up @@ -161,7 +184,7 @@ def make_app_client(
immutables=immutables,
memory=memory,
cors=cors,
metadata=METADATA,
metadata=metadata or METADATA,
plugins_dir=PLUGINS_DIR,
config=config,
inspect_data=inspect_data,
Expand Down
43 changes: 43 additions & 0 deletions tests/test_canned_write.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import pytest
from .fixtures import make_app_client


@pytest.fixture(scope="session")
def canned_write_client():
for client in make_app_client(
extra_databases={"data.db": "create table names (name text)"},
metadata={
"databases": {
"data": {
"queries": {
"add_name": {
"sql": "insert into names (name) values (:name)",
"write": True,
},
"delete_name": {
"sql": "delete from names where rowid = :rowid",
"write": True,
},
"update_name": {
"sql": "update names set name = :name where rowid = :rowid",
"params": ["rowid", "name"],
"write": True,
},
}
}
}
},
):
yield client


def test_insert(canned_write_client):
response = canned_write_client.post(
"/data/add_name", {"name": "Hello"}, allow_redirects=False
)
assert 302 == response.status
assert "/data/add_name" == response.headers["Location"]
messages = canned_write_client.ds.unsign(
response.cookies["ds_messages"], "messages"
)
assert [["Query executed, 1 row affected", 1]] == messages

0 comments on commit f45c44a

Please sign in to comment.