Repository navigation
test: review features on every engine (unit, component, live, e2e), and the bugs that found - #485
Merged
Merged
Conversation
Unit matrices per feature and engine, component tests for the two screens, FOX_IT_DB=1 live tests that run the new catalog and backup SQL against each container, and the e2e additions. Written because none of the new SQL in #484 has run against a real server yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ervers; fix what they found
Unit: routine-privileges.matrix.test.ts names every engine (fails when one is
added without an answer): which catalog its first rung reads routine grants
from, the exact REVOKE for PROCEDURE / FUNCTION / ROUTINE or the refusal, how
each spelling normalises, and where splitHeldPrivileges puts each object type.
schema-compare.matrix.test.ts: the light Compare check equals the capability
table for every engine, spelling and non-engine.
Live (FOX_IT_DB=1, access-live.test.ts): per engine, create a role, table,
function and procedure, grant, read back through probeDbAccess, split as the
Grants view does, revoke with Database Access SQL and with the grid's SQL,
read again. Skipped by name when a server does not answer its own probe.
Fixed, each failing live before and passing after:
- SQL Server: privileges were never read on a database with the server's
default collation (UNION collation conflict on permission_name).
- TiDB: the first rung read mysql.procs_priv, which TiDB lacks, so it fell
back and lost role memberships; and its information_schema TABLE_/
SCHEMA_PRIVILEGES are empty, so table and schema grants now come from
mysql.tables_priv and mysql.db. Routine grants are refused (TiDB has none).
- CockroachDB rejects ON ROUTINE: the Postgres-family routine rung now reports
FUNCTION or PROCEDURE from information_schema.routines.
- Db2: routine REVOKE needs RESTRICT (both emitters), and CONNECT granted to a
role was filtered out of DBAUTH.
- Redis and MongoDB were offered SQL GRANT text; they now refuse with the
existing non-SQL reason.
- isKnownEngine('constructor') was true (`in` walks the prototype).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016PyNv48vpYUw2HhpjYFNUi
backup-live.test.ts (FOX_IT_DB=1): SQL Server runs the panel's BACKUP, msdb lists it first, and the restore built from that key passes RESTORE VERIFYONLY; Db2 takes the CLP backup, DB_HISTORY lists it, and TAKEN AT names an image db2ckbkp verifies; ClickHouse backs up to its allowed disk, system.backups lists it, and the picked backup restores beside the live database; DuckDB EXPORT/IMPORT keeps every row; CockroachDB BACKUP INTO a nodelocal collection restores under a new name. Each fails when its history query returns the wrong key (checked by mutating each). backup-history.matrix.test.ts: every engine says whether it keeps a history (and that the query is a read), whether the panel can run its backup (and that it needs editor.ddl), and that hostile restore keys never reach the restore as written. The local ClickHouse gets a backup disk (docker/init/clickhouse/backups.xml), so its backup path runs instead of being refused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016PyNv48vpYUw2HhpjYFNUi
…ngine AccessGrantsStage.dialects.test.tsx renders the Grants stage once per grant-capable engine on a catalog shaped like that engine's: one view with no mode switch, the grid opens on what is held (routines included, whatever the catalog calls them), the database-, schema- or system-wide grant is listed under it, and the general section is there to edit it. ClickHouse, which has no grid cells or builder, names its table grant instead of hiding it, and says the builder does not support it. BackupRestorePanel.dialects.test.tsx: run offered exactly where the backup is SQL the server runs, history exactly where the server keeps one, both waiting for a password not in this session, failed run and failed listing showing the server's message, an empty history saying so, and a pick undone by "Restore the newest instead". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016PyNv48vpYUw2HhpjYFNUi
…fix SQL Server backup listing Seeds: every engine gains fox_reader, holding SELECT on demo_a.customers, EXECUTE on demo_a.fn_get_discount (where the engine has routines; Db2's seed gains the function) and one database-, schema- or system-wide grant. Re-runnable. access-assistant-dialects: per engine, Grants opens on fox_reader with no mode switch, the table and function boxes ticked, the wide grant listed under the grid, and nothing to change. The "reached at least one database" check was inside beforeAll, where it never ran as a test; it is a test again. The Principals and Grants-stage waits are shared helpers now. backup-restore-ui: SQL Server runs the backup once confirmed, msdb lists it, picking it points the restore at that file, and "Restore the newest instead" undoes it. Postgres offers no server actions. Fixed: the SQL Server history query used TOP (20), and /sql/execute pages every read with OFFSET … FETCH, which SQL Server refuses beside TOP, so "List backups" always failed in the app. backup-live now runs history through the same pager (it passed bare before). seed-all.sh: the Db2 seed ran every statement without a connection (SQL1024N): bash execs the last command of `su -c`, so the CLP lost its back end between `connect` and `-tvf`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016PyNv48vpYUw2HhpjYFNUi
Contributor
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 0751f9db-c4bc-41e1-ae9f-62d3a1f7288e) |
Brings in main, with source-map-js 1.2.2 (#482). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016PyNv48vpYUw2HhpjYFNUi
Contributor
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: bd06a775-d06d-486c-ad4b-8f5769b4af79) |
huyplb
changed the base branch from
feat/access-backup-recommendations
to
main
October 6, 2026 16:13
This was referenced Oct 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements
docs/plans/2026-10-06-review-features-test-plan.mdon top of #484. Every layer ran here against real servers: 11 docker-compose engines (Db2 included), plus DuckDB and SQLite.What was added
Unit (
packages/sql)Each matrix names every engine, and a test fails when an engine is added without an answer.
routine-privileges.matrix.test.ts: per engine:splitHeldPrivilegesputs each object type, including DENYbackup-history.matrix.test.ts: per engine:editor.ddl)schema-compare.matrix.test.ts: the light Compare check equalsdialectFeatures().schemaComparefor every engine, spelling and non-engine.Component (
web-ui)AccessGrantsStage.dialects.test.tsx: one render per grant-capable engine.BackupRestorePanel.dialects.test.tsx: run and list offered exactly where they should be; the password, error and empty states; pick, then "Restore the newest instead".Live (
FOX_IT_DB=1)Each engine is skipped by name, with the server's message, when its own probe fails.
access-live.test.ts, per engine:probeDbAccessand split them as the Grants view doesbackup-live.test.ts:RESTORE VERIFYONLYon the picked fileTAKEN AT→db2ckbkpsystem.backups→ restore under_restored/sql/execute.--no-file-parallelism.E2E (
apps/e2e)fox_reader: SELECT on a table, EXECUTE onfn_get_discount(Db2's seed gains the function), and one wide grant.access-assistant-dialects: Grants opens on that role with the boxes ticked and the wide grant listed under the grid.backup-restore-ui: on SQL Server, run → confirm → listed → pick → restore names that file.Bugs found and fixed
Each failed before its fix and passes after. That was checked by reverting each fix (or mutating the SQL) and rerunning.
UNION(permission_namevs a role name on a default-collation database)TOP (20)next to the pager'sOFFSET … FETCHmysql.procs_priv, which TiDB lacks, so it fell back and lost role membershipsinformation_schemaTABLE_ and SCHEMA_PRIVILEGES are empty even for root; now read frommysql.tables_privandmysql.dbREVOKE … ON ROUTINEis a syntax error; the routine rung now reports FUNCTION or PROCEDURE frominformation_schema.routinesRESTRICT(both emitters)isKnownEngine('constructor')was trueseed-all.sh(Db2)su -c)The local ClickHouse also gets a backup disk (
docker/init/clickhouse/backups.xml), so its backup path runs instead of being refused.Results
npx vitest run: 5843 passed, 0 failed.npm run test-ids: no drift.Not covered
SELECT TOP … ORDER BYinto the sameTOP+OFFSETerrorgenerated-ddl-livefails on SQL Server for "alters a table whose names need quoting" (it fails on the base commit too)npm audit(source-map-js); this PR does not touch dependencies.🤖 Generated with Claude Code
https://claude.ai/code/session_016PyNv48vpYUw2HhpjYFNUi
Generated by Claude Code
Note
Medium Risk
Touches privilege catalog SQL and GRANT/REVOKE generation across many engines (including SQL Server and TiDB), which are security-sensitive paths; most risk is mitigated by extensive new live and matrix tests rather than broad refactors.
Overview
Adds cross-engine test coverage for Access Grants, Backup & Restore, and schema-compare, plus production fixes those tests exposed.
Testing: New unit matrix tests in
packages/sql(routine privileges, backup history/run permissions, schema-compare parity). Component tests renderAccessGrantsStageandBackupRestorePanelonce per dialect.FOX_IT_DB=1live suites grant/revoke against real containers and exercise backup → history → restore round-trips. E2E gains seededfox_readerroles in Docker init scripts, a Grants test that asserts held grid cells and “also holds” text, SQL Server backup run/list/pick in the browser, and shared helpers for the Principals/Grants flow.SQL & infra fixes: TiDB reads grants from
mysql.tables_priv/mysql.dband skips routine catalogs; SQL Server privilegeUNIONusesDATABASE_DEFAULTcollation and dropsTOPfrom msdb history for the SQL pager; CockroachDB routine revokes require FUNCTION/PROCEDURE; Db2 routine revokes appendRESTRICTand role CONNECT grants are included; Postgres-family routine grants joininformation_schema.routines; Redis/MongoDB are marked unsupported for SQL GRANT;isKnownEngineusesObject.hasOwn. ClickHouse gets an allowed backup disk config;seed-all.shkeeps a single Db2 CLP session.A test plan doc describes the layered strategy.
Reviewed by Cursor Bugbot for commit 28211f9. Bugbot is set up for automated code reviews on this repo. Configure here.