insert test that exercises against an in-memory Datasette instance, refs #8

This commit is contained in:
Simon Willison 2023-07-24 15:18:54 -07:00
commit c03cbb2bbc
2 changed files with 80 additions and 5 deletions

View file

@ -39,7 +39,7 @@ setup(
"pytest-httpx",
"cogapp",
"pytest-mock",
"datasette",
"datasette>=1.0a2",
]
},
python_requires=">=3.7",

View file

@ -1,7 +1,18 @@
import asyncio
from click.testing import CliRunner
from datasette.app import Datasette
from dclient.cli import cli
import httpx
import json
import pathlib
import pytest
@pytest.fixture
def non_mocked_hosts():
# This ensures httpx-mock will not affect Datasette's own
# httpx calls made in the tests by datasette.client:
return ["localhost"]
def test_insert_mocked(httpx_mock, tmpdir):
@ -10,13 +21,12 @@ def test_insert_mocked(httpx_mock, tmpdir):
"ok": True,
"database": "data",
"table": "table1",
"table_url": "http://localhost:8012/data/table1",
"table_api_url": "http://localhost:8012/data/table1.json",
"table_url": "http://datasette.example.com/data/table1",
"table_api_url": "http://datasette.example.com/data/table1.json",
"schema": "CREATE TABLE [table1] (...)",
"row_count": 100,
}
)
(tmpdir / "data.csv")
path = pathlib.Path(tmpdir) / "data.csv"
path.write_text("a,b,c\n1,2,3\n")
runner = CliRunner()
@ -24,7 +34,7 @@ def test_insert_mocked(httpx_mock, tmpdir):
cli,
[
"insert",
"https://localhost:8012/data",
"https://datasette.example.com/data",
"table1",
str(path),
"--csv",
@ -38,3 +48,68 @@ def test_insert_mocked(httpx_mock, tmpdir):
request = httpx_mock.get_request()
assert request.headers["authorization"] == "Bearer x"
assert json.loads(request.read()) == {"rows": [{"a": 1, "b": 2, "c": 3}]}
def test_insert_against_datasette(httpx_mock, tmpdir):
ds = Datasette(
metadata={
"permissions": {
"create-table": {"id": "*"},
"insert-row": {"id": "*"},
"update-row": {"id": "*"},
}
}
)
ds.add_memory_database("data")
token = ds.create_token("actor")
loop = asyncio.get_event_loop()
def custom_response(request: httpx.Request):
# Need to run this in async loop, because dclient itself uses
# sync HTTPX and not async HTTPX
async def run():
response = await ds.client.request(
request.method,
request.url.path,
json=json.loads(request.read()),
headers=request.headers,
)
# Create a fresh response to avoid an error where stream has been consumed
return httpx.Response(
status_code=response.status_code,
headers=response.headers,
content=response.content,
)
return loop.run_until_complete(run())
httpx_mock.add_callback(custom_response)
path = pathlib.Path(tmpdir) / "data.csv"
path.write_text("a,b,c\n1,2,3\n")
runner = CliRunner()
result = runner.invoke(
cli,
[
"insert",
"http://datasette.example.com/data",
"table1",
str(path),
"--csv",
"--token",
token,
"--create",
],
catch_exceptions=False,
)
assert result.exit_code == 0
# Datasette should have the new rows
async def fetch_table():
response = await ds.client.get("/data/table1.json?_shape=array")
return response
response = loop.run_until_complete(fetch_table())
assert response.json() == [{"rowid": 1, "a": 1, "b": 2, "c": 3}]