mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
filters_from_request plugin hook, now used in TableView
- New `filters_from_request` plugin hook, closes #473 - Used it to extract the logic from TableView that handles `_search` and `_through` and `_where` - refs #1518 Also needed for this plugin work: https://github.com/simonw/datasette-leaflet-freedraw/issues/7
This commit is contained in:
parent
0663d5525c
commit
aa7f0037a4
7 changed files with 354 additions and 112 deletions
|
|
@ -1,4 +1,6 @@
|
|||
from datasette.filters import Filters
|
||||
from datasette.filters import Filters, through_filters, where_filters, search_filters
|
||||
from datasette.utils.asgi import Request
|
||||
from .fixtures import app_client
|
||||
import pytest
|
||||
|
||||
|
||||
|
|
@ -74,3 +76,86 @@ def test_build_where(args, expected_where, expected_params):
|
|||
sql_bits, actual_params = f.build_where_clauses("table")
|
||||
assert expected_where == sql_bits
|
||||
assert {f"p{i}": param for i, param in enumerate(expected_params)} == actual_params
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_through_filters_from_request(app_client):
|
||||
request = Request.fake(
|
||||
'/?_through={"table":"roadside_attraction_characteristics","column":"characteristic_id","value":"1"}'
|
||||
)
|
||||
filter_args = await (
|
||||
through_filters(
|
||||
request=request,
|
||||
datasette=app_client.ds,
|
||||
table="roadside_attractions",
|
||||
database="fixtures",
|
||||
)
|
||||
)()
|
||||
assert filter_args.where_clauses == [
|
||||
"pk in (select attraction_id from roadside_attraction_characteristics where characteristic_id = :p0)"
|
||||
]
|
||||
assert filter_args.params == {"p0": "1"}
|
||||
assert filter_args.human_descriptions == [
|
||||
'roadside_attraction_characteristics.characteristic_id = "1"'
|
||||
]
|
||||
assert filter_args.extra_context == {}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_through_filters_from_request(app_client):
|
||||
request = Request.fake(
|
||||
'/?_through={"table":"roadside_attraction_characteristics","column":"characteristic_id","value":"1"}'
|
||||
)
|
||||
filter_args = await (
|
||||
through_filters(
|
||||
request=request,
|
||||
datasette=app_client.ds,
|
||||
table="roadside_attractions",
|
||||
database="fixtures",
|
||||
)
|
||||
)()
|
||||
assert filter_args.where_clauses == [
|
||||
"pk in (select attraction_id from roadside_attraction_characteristics where characteristic_id = :p0)"
|
||||
]
|
||||
assert filter_args.params == {"p0": "1"}
|
||||
assert filter_args.human_descriptions == [
|
||||
'roadside_attraction_characteristics.characteristic_id = "1"'
|
||||
]
|
||||
assert filter_args.extra_context == {}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_where_filters_from_request(app_client):
|
||||
request = Request.fake("/?_where=pk+>+3")
|
||||
filter_args = await (
|
||||
where_filters(
|
||||
request=request,
|
||||
datasette=app_client.ds,
|
||||
database="fixtures",
|
||||
)
|
||||
)()
|
||||
assert filter_args.where_clauses == ["pk > 3"]
|
||||
assert filter_args.params == {}
|
||||
assert filter_args.human_descriptions == []
|
||||
assert filter_args.extra_context == {
|
||||
"extra_wheres_for_ui": [{"text": "pk > 3", "remove_url": "/"}]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_search_filters_from_request(app_client):
|
||||
request = Request.fake("/?_search=bobcat")
|
||||
filter_args = await (
|
||||
search_filters(
|
||||
request=request,
|
||||
datasette=app_client.ds,
|
||||
database="fixtures",
|
||||
table="searchable",
|
||||
)
|
||||
)()
|
||||
assert filter_args.where_clauses == [
|
||||
"rowid in (select rowid from searchable_fts where searchable_fts match escape_fts(:search))"
|
||||
]
|
||||
assert filter_args.params == {"search": "bobcat"}
|
||||
assert filter_args.human_descriptions == ['search matches "bobcat"']
|
||||
assert filter_args.extra_context == {"supports_search": True, "search": "bobcat"}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ from .fixtures import (
|
|||
from click.testing import CliRunner
|
||||
from datasette.app import Datasette
|
||||
from datasette import cli, hookimpl
|
||||
from datasette.filters import FilterArguments
|
||||
from datasette.plugins import get_plugins, DEFAULT_PLUGINS, pm
|
||||
from datasette.utils.sqlite import sqlite3
|
||||
from datasette.utils import CustomRow
|
||||
|
|
@ -977,3 +978,20 @@ def test_hook_register_commands():
|
|||
}
|
||||
pm.unregister(name="verify")
|
||||
importlib.reload(cli)
|
||||
|
||||
|
||||
def test_hook_filters_from_request(app_client):
|
||||
class ReturnNothingPlugin:
|
||||
__name__ = "ReturnNothingPlugin"
|
||||
|
||||
@hookimpl
|
||||
def filters_from_request(self, request):
|
||||
if request.args.get("_nothing"):
|
||||
return FilterArguments(["1 = 0"], human_descriptions=["NOTHING"])
|
||||
|
||||
pm.register(ReturnNothingPlugin(), name="ReturnNothingPlugin")
|
||||
response = app_client.get("/fixtures/facetable?_nothing=1")
|
||||
assert "0 rows\n where NOTHING" in response.text
|
||||
json_response = app_client.get("/fixtures/facetable.json?_nothing=1")
|
||||
assert json_response.json["rows"] == []
|
||||
pm.unregister(name="ReturnNothingPlugin")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue