Files
devplacepy/tests/unit/services/dbapi/policy.py
T
retoor d31ccba6c1 feat: add admin/internal database API with CRUD, read-only query, and natural-language SQL endpoints
Add a new `/dbapi` router package providing a generic database API over `dataset`, restricted to admin sessions, admin API keys, and the internal gateway key. Includes:

- `tables.py`: list all tables and inspect table schemas
- `crud.py`: full CRUD operations (GET, POST, PATCH, DELETE) with soft-delete awareness, born-live inserts, `?include_deleted`, `.../restore`, and `?hard=true` purge
- `query.py`: validated read-only SELECT execution via sqlglot parsing, classification, and EXPLAIN dry-run; async query jobs with WebSocket streaming via `DbApiJobService`
- `nl.py`: natural-language-to-SQL conversion using the platform AI gateway with re-prompting until validation passes

Also register `DbApiJobService` and `PubSubService` in the service manager, add `DBAPI_DIR` to config data paths, and force cleartext `http://` connections to HTTP/1.1 in `curl_transport` to fix large request failures against uvicorn's HTTP/1.1-only internal gateway.
2026-06-14 23:00:30 +00:00

49 lines
1.3 KiB
Python

# retoor <retoor@molodetz.nl>
import pytest
from devplacepy.database import set_setting
from devplacepy.services.dbapi import policy
from devplacepy.services.dbapi.policy import DbApiBadTable
def test_assert_table_accepts_known_table(local_db):
assert policy.assert_table("users") == "users"
def test_assert_table_rejects_bad_name(local_db):
with pytest.raises(DbApiBadTable):
policy.assert_table("users; drop")
def test_assert_table_rejects_denied(local_db):
with pytest.raises(DbApiBadTable):
policy.assert_table("sessions")
def test_assert_table_rejects_unknown(local_db):
with pytest.raises(DbApiBadTable):
policy.assert_table("table_that_does_not_exist_zzz")
def test_allowed_tables_excludes_deny(local_db):
tables = policy.allowed_tables()
assert "sessions" not in tables
assert "password_resets" not in tables
assert "users" in tables
def test_soft_delete_aware():
assert policy.soft_delete_aware("posts") is True
assert policy.soft_delete_aware("users") is False
def test_deny_tables_includes_setting(local_db):
set_setting("dbapi_deny_tables", "users, news")
try:
deny = policy.deny_tables()
assert "users" in deny and "news" in deny
assert "sessions" in deny
finally:
set_setting("dbapi_deny_tables", "")