mirror of
https://github.com/simonw/datasette.git
synced 2026-06-02 23:26:59 +02:00
Add actor= parameter to datasette.client methods (#2688)
`datasette.client.get(path, actor={"id": "root"}` now makes the internal request with that actor as `request.actor` - same for the other HTTP verb methods on `datasette.client`.
Upgraded relevant tests to use the new `actor=` mechanism.
This commit is contained in:
parent
0b639a8122
commit
9c164572d3
11 changed files with 149 additions and 53 deletions
|
|
@ -2654,9 +2654,21 @@ class DatasetteClient:
|
|||
path = f"http://localhost{path}"
|
||||
return path
|
||||
|
||||
def _apply_actor(self, kwargs):
|
||||
"""If ``actor=`` was supplied, convert it into a signed ds_actor cookie."""
|
||||
actor = kwargs.pop("actor", None)
|
||||
if actor is None:
|
||||
return
|
||||
cookies = dict(kwargs.get("cookies") or {})
|
||||
if "ds_actor" in cookies:
|
||||
raise TypeError("Cannot pass both actor= and a ds_actor cookie")
|
||||
cookies["ds_actor"] = self.actor_cookie(actor)
|
||||
kwargs["cookies"] = cookies
|
||||
|
||||
async def _request(self, method, path, skip_permission_checks=False, **kwargs):
|
||||
from datasette.permissions import SkipPermissions
|
||||
|
||||
self._apply_actor(kwargs)
|
||||
with _DatasetteClientContext():
|
||||
if skip_permission_checks:
|
||||
with SkipPermissions():
|
||||
|
|
@ -2722,6 +2734,7 @@ class DatasetteClient:
|
|||
from datasette.permissions import SkipPermissions
|
||||
|
||||
avoid_path_rewrites = kwargs.pop("avoid_path_rewrites", None)
|
||||
self._apply_actor(kwargs)
|
||||
with _DatasetteClientContext():
|
||||
if skip_permission_checks:
|
||||
with SkipPermissions():
|
||||
|
|
|
|||
|
|
@ -1312,6 +1312,28 @@ These methods can be used with :ref:`internals_datasette_urls` - for example:
|
|||
|
||||
For documentation on available ``**kwargs`` options and the shape of the HTTPX Response object refer to the `HTTPX Async documentation <https://www.python-httpx.org/async/>`__.
|
||||
|
||||
.. _internals_datasette_client_actor:
|
||||
|
||||
Authenticating as an actor
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
All ``datasette.client`` methods accept an optional ``actor=`` parameter. When set to a dictionary describing an actor, the request is made with a signed ``ds_actor`` cookie identifying that actor — as if the request had been made by a user who is signed in as that actor.
|
||||
|
||||
This is a convenient shorthand equivalent to signing the cookie manually using ``datasette.client.actor_cookie()``.
|
||||
|
||||
Example usage:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
response = await datasette.client.get(
|
||||
"/-/actor.json", actor={"id": "root"}
|
||||
)
|
||||
assert response.json() == {"actor": {"id": "root"}}
|
||||
|
||||
This parameter works with all HTTP methods (``get``, ``post``, ``put``, ``patch``, ``delete``, ``options``, ``head``) and the generic ``request`` method.
|
||||
|
||||
Passing both ``actor=`` and a ``ds_actor`` cookie via ``cookies=`` raises a ``TypeError``. Other unrelated cookies can be combined with ``actor=``.
|
||||
|
||||
Bypassing permission checks
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
|||
|
|
@ -553,8 +553,7 @@ async def test_actions_json(ds_client):
|
|||
original_root_enabled = ds_client.ds.root_enabled
|
||||
try:
|
||||
ds_client.ds.root_enabled = True
|
||||
cookies = {"ds_actor": ds_client.actor_cookie({"id": "root"})}
|
||||
response = await ds_client.get("/-/actions.json", cookies=cookies)
|
||||
response = await ds_client.get("/-/actions.json", actor={"id": "root"})
|
||||
data = response.json()
|
||||
finally:
|
||||
ds_client.ds.root_enabled = original_root_enabled
|
||||
|
|
|
|||
|
|
@ -933,9 +933,7 @@ async def test_set_column_type_ui_data_includes_applicable_types(
|
|||
await ds_ct_editor_permission.invoke_startup()
|
||||
response = await ds_ct_editor_permission.client.get(
|
||||
"/data/posts",
|
||||
cookies={
|
||||
"ds_actor": ds_ct_editor_permission.client.actor_cookie({"id": "editor"})
|
||||
},
|
||||
actor={"id": "editor"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = _window_data_from_html(response.text, "_setColumnTypeData")
|
||||
|
|
|
|||
|
|
@ -1003,10 +1003,10 @@ async def test_navigation_menu_links(
|
|||
# Enable root user if testing with root actor
|
||||
if actor_id == "root":
|
||||
ds_client.ds.root_enabled = True
|
||||
cookies = {}
|
||||
kwargs = {}
|
||||
if actor_id:
|
||||
cookies = {"ds_actor": ds_client.actor_cookie({"id": actor_id})}
|
||||
html = (await ds_client.get("/", cookies=cookies)).text
|
||||
kwargs["actor"] = {"id": actor_id}
|
||||
html = (await ds_client.get("/", **kwargs)).text
|
||||
soup = Soup(html, "html.parser")
|
||||
details = soup.find("nav").find("details")
|
||||
if not actor_id:
|
||||
|
|
@ -1215,8 +1215,7 @@ async def test_actions_page(ds_client):
|
|||
original_root_enabled = ds_client.ds.root_enabled
|
||||
try:
|
||||
ds_client.ds.root_enabled = True
|
||||
cookies = {"ds_actor": ds_client.actor_cookie({"id": "root"})}
|
||||
response = await ds_client.get("/-/actions", cookies=cookies)
|
||||
response = await ds_client.get("/-/actions", actor={"id": "root"})
|
||||
assert response.status_code == 200
|
||||
assert "Registered actions" in response.text
|
||||
assert "<th>Name</th>" in response.text
|
||||
|
|
@ -1233,8 +1232,7 @@ async def test_actions_page_does_not_display_none_string(ds_client):
|
|||
original_root_enabled = ds_client.ds.root_enabled
|
||||
try:
|
||||
ds_client.ds.root_enabled = True
|
||||
cookies = {"ds_actor": ds_client.actor_cookie({"id": "root"})}
|
||||
response = await ds_client.get("/-/actions", cookies=cookies)
|
||||
response = await ds_client.get("/-/actions", actor={"id": "root"})
|
||||
assert response.status_code == 200
|
||||
assert "<code>None</code>" not in response.text
|
||||
finally:
|
||||
|
|
@ -1247,11 +1245,11 @@ async def test_permission_debug_tabs_with_query_string(ds_client):
|
|||
original_root_enabled = ds_client.ds.root_enabled
|
||||
try:
|
||||
ds_client.ds.root_enabled = True
|
||||
cookies = {"ds_actor": ds_client.actor_cookie({"id": "root"})}
|
||||
actor = {"id": "root"}
|
||||
|
||||
# Test /-/allowed with query string
|
||||
response = await ds_client.get(
|
||||
"/-/allowed?action=view-table&page_size=50", cookies=cookies
|
||||
"/-/allowed?action=view-table&page_size=50", actor=actor
|
||||
)
|
||||
assert response.status_code == 200
|
||||
# Check that Rules and Check tabs have the query string
|
||||
|
|
@ -1263,7 +1261,7 @@ async def test_permission_debug_tabs_with_query_string(ds_client):
|
|||
|
||||
# Test /-/rules with query string
|
||||
response = await ds_client.get(
|
||||
"/-/rules?action=view-database&parent=test", cookies=cookies
|
||||
"/-/rules?action=view-database&parent=test", actor=actor
|
||||
)
|
||||
assert response.status_code == 200
|
||||
# Check that Allowed and Check tabs have the query string
|
||||
|
|
@ -1271,7 +1269,7 @@ async def test_permission_debug_tabs_with_query_string(ds_client):
|
|||
assert 'href="/-/check?action=view-database&parent=test"' in response.text
|
||||
|
||||
# Test /-/check with query string
|
||||
response = await ds_client.get("/-/check?action=execute-sql", cookies=cookies)
|
||||
response = await ds_client.get("/-/check?action=execute-sql", actor=actor)
|
||||
assert response.status_code == 200
|
||||
# Check that Allowed and Rules tabs have the query string
|
||||
assert 'href="/-/allowed?action=execute-sql"' in response.text
|
||||
|
|
|
|||
|
|
@ -311,3 +311,76 @@ async def test_in_client_with_skip_permission_checks():
|
|||
assert all(in_client_values), f"Expected all True, got {in_client_values}"
|
||||
finally:
|
||||
ds.pm.unregister(name="test_in_client_skip_plugin")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_actor_parameter_sets_cookie(datasette):
|
||||
"""Passing actor= should sign a ds_actor cookie and authenticate the request."""
|
||||
response = await datasette.client.get("/-/actor.json", actor={"id": "root"})
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {"actor": {"id": "root"}}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_actor_parameter_works_with_request_method(datasette):
|
||||
response = await datasette.client.request(
|
||||
"GET", "/-/actor.json", actor={"id": "root"}
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {"actor": {"id": "root"}}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
"method", ["get", "post", "options", "head", "put", "patch", "delete"]
|
||||
)
|
||||
async def test_actor_parameter_all_http_methods(datasette, method):
|
||||
"""actor= should not cause errors on any HTTP verb wrapper."""
|
||||
client_method = getattr(datasette.client, method)
|
||||
# Just verify no TypeError about unexpected 'actor' kwarg
|
||||
response = await client_method("/", actor={"id": "root"})
|
||||
assert isinstance(response, httpx.Response)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_actor_parameter_conflicts_with_ds_actor_cookie(datasette):
|
||||
"""Passing both actor= and a ds_actor cookie should raise TypeError."""
|
||||
with pytest.raises(TypeError, match="actor"):
|
||||
await datasette.client.get(
|
||||
"/-/actor.json",
|
||||
actor={"id": "root"},
|
||||
cookies={"ds_actor": datasette.client.actor_cookie({"id": "other"})},
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_actor_parameter_merges_with_other_cookies(datasette):
|
||||
"""actor= should coexist with unrelated cookies."""
|
||||
response = await datasette.client.get(
|
||||
"/-/actor.json",
|
||||
actor={"id": "root"},
|
||||
cookies={"unrelated": "value"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {"actor": {"id": "root"}}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_actor_parameter_with_skip_permission_checks(
|
||||
datasette_with_permissions,
|
||||
):
|
||||
"""actor= should be compatible with skip_permission_checks."""
|
||||
ds = datasette_with_permissions
|
||||
# Non-admin actor with skip_permission_checks=True should get 200
|
||||
response = await ds.client.get(
|
||||
"/test_db.json",
|
||||
actor={"id": "user"},
|
||||
skip_permission_checks=True,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
# Admin actor on its own should also get 200
|
||||
response = await ds.client.get("/test_db.json", actor={"id": "admin"})
|
||||
assert response.status_code == 200
|
||||
# Non-admin actor should get 403
|
||||
response = await ds.client.get("/test_db.json", actor={"id": "user"})
|
||||
assert response.status_code == 403
|
||||
|
|
|
|||
|
|
@ -117,9 +117,7 @@ async def test_allowed_json_with_actor(ds_with_permissions):
|
|||
"""Test /-/allowed.json includes actor information."""
|
||||
response = await ds_with_permissions.client.get(
|
||||
"/-/allowed.json?action=view-table",
|
||||
cookies={
|
||||
"ds_actor": ds_with_permissions.client.actor_cookie({"id": "test_user"})
|
||||
},
|
||||
actor={"id": "test_user"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
|
|
@ -252,7 +250,7 @@ async def test_rules_json_basic(
|
|||
# Use root actor for rules endpoint (requires permissions-debug)
|
||||
response = await ds_with_permissions.client.get(
|
||||
path,
|
||||
cookies={"ds_actor": ds_with_permissions.client.actor_cookie({"id": "root"})},
|
||||
actor={"id": "root"},
|
||||
)
|
||||
assert response.status_code == expected_status
|
||||
data = response.json()
|
||||
|
|
@ -264,7 +262,7 @@ async def test_rules_json_response_structure(ds_with_permissions):
|
|||
"""Test that /-/rules.json returns the expected structure."""
|
||||
response = await ds_with_permissions.client.get(
|
||||
"/-/rules.json?action=view-instance",
|
||||
cookies={"ds_actor": ds_with_permissions.client.actor_cookie({"id": "root"})},
|
||||
actor={"id": "root"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
|
|
@ -294,7 +292,7 @@ async def test_rules_json_includes_all_rules(ds_with_permissions):
|
|||
# Root user should see rules for everything
|
||||
response = await ds_with_permissions.client.get(
|
||||
"/-/rules.json?action=view-table",
|
||||
cookies={"ds_actor": ds_with_permissions.client.actor_cookie({"id": "root"})},
|
||||
actor={"id": "root"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
|
|
@ -326,7 +324,7 @@ async def test_rules_json_pagination():
|
|||
# Test basic pagination structure - just verify it returns paginated results
|
||||
response = await ds.client.get(
|
||||
"/-/rules.json?action=view-table&page_size=2&page=1",
|
||||
cookies={"ds_actor": ds.client.actor_cookie({"id": "root"})},
|
||||
actor={"id": "root"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
|
|
@ -343,7 +341,7 @@ async def test_rules_json_with_actor(ds_with_permissions):
|
|||
# Use root actor (rules endpoint requires permissions-debug)
|
||||
response = await ds_with_permissions.client.get(
|
||||
"/-/rules.json?action=view-table",
|
||||
cookies={"ds_actor": ds_with_permissions.client.actor_cookie({"id": "root"})},
|
||||
actor={"id": "root"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
|
|
@ -374,7 +372,7 @@ async def test_root_user_respects_settings_deny():
|
|||
# Root user should NOT see the denied database
|
||||
response = await ds.client.get(
|
||||
"/-/allowed.json?action=view-database",
|
||||
cookies={"ds_actor": ds.client.actor_cookie({"id": "root"})},
|
||||
actor={"id": "root"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
|
|
@ -415,7 +413,7 @@ async def test_root_user_respects_settings_deny_tables():
|
|||
# Root user should NOT see tables from the content database
|
||||
response = await ds.client.get(
|
||||
"/-/allowed.json?action=view-table",
|
||||
cookies={"ds_actor": ds.client.actor_cookie({"id": "root"})},
|
||||
actor={"id": "root"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
|
|
@ -475,7 +473,7 @@ async def test_execute_sql_requires_view_database():
|
|||
# User should NOT have execute-sql permission because view-database is denied
|
||||
response = await ds.client.get(
|
||||
"/-/allowed.json?action=execute-sql",
|
||||
cookies={"ds_actor": ds.client.actor_cookie({"id": "test_user"})},
|
||||
actor={"id": "test_user"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
|
|
@ -491,7 +489,7 @@ async def test_execute_sql_requires_view_database():
|
|||
# (may be 403 or 302 redirect to login/error page depending on middleware)
|
||||
response = await ds.client.get(
|
||||
"/secret?sql=SELECT+1",
|
||||
cookies={"ds_actor": ds.client.actor_cookie({"id": "test_user"})},
|
||||
actor={"id": "test_user"},
|
||||
)
|
||||
assert response.status_code in (302, 403), (
|
||||
f"Expected 302 or 403 when trying to execute SQL without view-database permission, "
|
||||
|
|
|
|||
|
|
@ -1171,10 +1171,10 @@ async def test_api_explorer_visibility(
|
|||
try:
|
||||
prev_config = perms_ds.config
|
||||
perms_ds.config = config or {}
|
||||
cookies = {}
|
||||
kwargs = {}
|
||||
if is_logged_in:
|
||||
cookies = {"ds_actor": perms_ds.client.actor_cookie({"id": "user"})}
|
||||
response = await perms_ds.client.get("/-/api", cookies=cookies)
|
||||
kwargs["actor"] = {"id": "user"}
|
||||
response = await perms_ds.client.get("/-/api", **kwargs)
|
||||
if expected_visible_tables:
|
||||
assert response.status_code == 200
|
||||
# Search HTML for stuff matching:
|
||||
|
|
@ -1208,8 +1208,7 @@ async def test_view_table_token_cannot_gain_access_without_base_permission(perms
|
|||
# Restricted token claims access to perms_ds_two/t1 only
|
||||
"_r": {"r": {"perms_ds_two": {"t1": ["vt"]}}},
|
||||
}
|
||||
cookies = {"ds_actor": perms_ds.client.actor_cookie(actor)}
|
||||
response = await perms_ds.client.get("/perms_ds_two/t1.json", cookies=cookies)
|
||||
response = await perms_ds.client.get("/perms_ds_two/t1.json", actor=actor)
|
||||
assert response.status_code == 403
|
||||
finally:
|
||||
perms_ds.config = previous_config
|
||||
|
|
@ -1328,7 +1327,7 @@ async def test_actor_restrictions(
|
|||
if restrictions:
|
||||
actor["_r"] = restrictions
|
||||
method = getattr(perms_ds.client, verb)
|
||||
kwargs = {"cookies": {"ds_actor": perms_ds.client.actor_cookie(actor)}}
|
||||
kwargs = {"actor": actor}
|
||||
if body:
|
||||
kwargs["json"] = body
|
||||
perms_ds._permission_checks.clear()
|
||||
|
|
@ -1459,7 +1458,7 @@ async def test_actor_restrictions_do_not_expand_allowed_resources(perms_ds):
|
|||
# And explicit permission checks should still deny
|
||||
response = await perms_ds.client.get(
|
||||
"/perms_ds_one/t1.json",
|
||||
cookies={"ds_actor": perms_ds.client.actor_cookie(actor)},
|
||||
actor=actor,
|
||||
)
|
||||
assert response.status_code == 403
|
||||
finally:
|
||||
|
|
@ -1527,18 +1526,17 @@ async def test_actor_restrictions_json_endpoints_show_filtered_listings(perms_ds
|
|||
"""Test that /.json and /db.json show correct filtered listings - issue #2534"""
|
||||
|
||||
actor = {"id": "user", "_r": {"r": {"perms_ds_one": {"t1": ["vt"]}}}}
|
||||
cookies = {"ds_actor": perms_ds.client.actor_cookie(actor)}
|
||||
|
||||
# /.json should be 403 (no view-instance permission)
|
||||
response = await perms_ds.client.get("/.json", cookies=cookies)
|
||||
response = await perms_ds.client.get("/.json", actor=actor)
|
||||
assert response.status_code == 403
|
||||
|
||||
# /perms_ds_one.json should be 403 (no view-database permission)
|
||||
response = await perms_ds.client.get("/perms_ds_one.json", cookies=cookies)
|
||||
response = await perms_ds.client.get("/perms_ds_one.json", actor=actor)
|
||||
assert response.status_code == 403
|
||||
|
||||
# /perms_ds_one/t1.json should be 200
|
||||
response = await perms_ds.client.get("/perms_ds_one/t1.json", cookies=cookies)
|
||||
response = await perms_ds.client.get("/perms_ds_one/t1.json", actor=actor)
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
|
|
@ -1547,10 +1545,9 @@ async def test_actor_restrictions_view_instance_only(perms_ds):
|
|||
"""Test actor restricted to view-instance only - issue #2534"""
|
||||
|
||||
actor = {"id": "user", "_r": {"a": ["vi"]}}
|
||||
cookies = {"ds_actor": perms_ds.client.actor_cookie(actor)}
|
||||
|
||||
# /.json should be 200 (has view-instance permission)
|
||||
response = await perms_ds.client.get("/.json", cookies=cookies)
|
||||
response = await perms_ds.client.get("/.json", actor=actor)
|
||||
assert response.status_code == 200
|
||||
|
||||
# But no databases should be visible (no view-database permission)
|
||||
|
|
|
|||
|
|
@ -1024,7 +1024,7 @@ async def test_hook_view_actions(ds_client):
|
|||
assert get_actions_links(response.text) == []
|
||||
response_2 = await ds_client.get(
|
||||
"/fixtures/simple_view",
|
||||
cookies={"ds_actor": ds_client.actor_cookie({"id": "bob"})},
|
||||
actor={"id": "bob"},
|
||||
)
|
||||
assert ">View actions<" in response_2.text
|
||||
assert sorted(
|
||||
|
|
@ -1088,7 +1088,7 @@ async def test_hook_row_actions(ds_client):
|
|||
|
||||
response_2 = await ds_client.get(
|
||||
"/fixtures/facet_cities/1",
|
||||
cookies={"ds_actor": ds_client.actor_cookie({"id": "sam"})},
|
||||
actor={"id": "sam"},
|
||||
)
|
||||
assert get_actions_links(response_2.text) == [
|
||||
{
|
||||
|
|
@ -1116,9 +1116,7 @@ async def test_hook_homepage_actions(ds_client):
|
|||
# No button for anonymous users
|
||||
assert "<span>Homepage actions</span>" not in response.text
|
||||
# Signed in user gets an action
|
||||
response2 = await ds_client.get(
|
||||
"/", cookies={"ds_actor": ds_client.actor_cookie({"id": "troy"})}
|
||||
)
|
||||
response2 = await ds_client.get("/", actor={"id": "troy"})
|
||||
assert "<span>Homepage actions</span>" in response2.text
|
||||
assert get_actions_links(response2.text) == [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ async def test_schema_permission_enforcement(schema_ds, url):
|
|||
# Authenticated user with permission should succeed
|
||||
response = await schema_ds.client.get(
|
||||
url,
|
||||
cookies={"ds_actor": schema_ds.client.actor_cookie({"id": "root"})},
|
||||
actor={"id": "root"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
|
|
@ -171,7 +171,7 @@ async def test_instance_schema_respects_database_permissions(schema_ds):
|
|||
# Authenticated user should see all databases
|
||||
response = await schema_ds.client.get(
|
||||
"/-/schema.json",
|
||||
cookies={"ds_actor": schema_ds.client.actor_cookie({"id": "root"})},
|
||||
actor={"id": "root"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ async def test_tables_search_with_auth(ds_with_tables):
|
|||
# Editor user should see content.articles
|
||||
response = await ds_with_tables.client.get(
|
||||
"/-/tables.json?q=articles",
|
||||
cookies={"ds_actor": ds_with_tables.client.actor_cookie({"id": "editor"})},
|
||||
actor={"id": "editor"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
|
|
@ -104,7 +104,7 @@ async def test_tables_search_partial_match(ds_with_tables):
|
|||
# Search for "com" should match "comments"
|
||||
response = await ds_with_tables.client.get(
|
||||
"/-/tables.json?q=com",
|
||||
cookies={"ds_actor": ds_with_tables.client.actor_cookie({"id": "user"})},
|
||||
actor={"id": "user"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
|
|
@ -120,7 +120,7 @@ async def test_tables_search_respects_database_permissions(ds_with_tables):
|
|||
# Even authenticated users shouldn't see it because database is denied
|
||||
response = await ds_with_tables.client.get(
|
||||
"/-/tables.json?q=secrets",
|
||||
cookies={"ds_actor": ds_with_tables.client.actor_cookie({"id": "user"})},
|
||||
actor={"id": "user"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
|
|
@ -135,7 +135,7 @@ async def test_tables_search_respects_table_permissions(ds_with_tables):
|
|||
# Regular authenticated user searching for "users"
|
||||
response = await ds_with_tables.client.get(
|
||||
"/-/tables.json?q=users",
|
||||
cookies={"ds_actor": ds_with_tables.client.actor_cookie({"id": "regular"})},
|
||||
actor={"id": "regular"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
|
|
@ -150,7 +150,7 @@ async def test_tables_search_response_structure(ds_with_tables):
|
|||
"""Test that response has correct structure."""
|
||||
response = await ds_with_tables.client.get(
|
||||
"/-/tables.json?q=users",
|
||||
cookies={"ds_actor": ds_with_tables.client.actor_cookie({"id": "user"})},
|
||||
actor={"id": "user"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue