Skip to content

feat(graphile-test): add setUserContext utility for RLS testing#1094

Closed
pyramation wants to merge 2 commits intomainfrom
devin/1778377136-graphile-test-set-user-context
Closed

feat(graphile-test): add setUserContext utility for RLS testing#1094
pyramation wants to merge 2 commits intomainfrom
devin/1778377136-graphile-test-set-user-context

Conversation

@pyramation
Copy link
Copy Markdown
Contributor

Summary

Two additions to graphile-test:

1. withTransaction on test pg clients (context.ts)

In production, @dataplan/pg provides pgClient.withTransaction(). The raw pg Client used in tests lacks it, which causes plugins that call withTransaction (e.g. the presigned-url plugin's upload mutations) to fail with withTransaction is not a function. This adds a savepoint-based polyfill that is injected once per client inside withPgClient, nesting cleanly inside the test harness's outer transaction.

2. setUserContext utility (utils.ts)

Every RLS integration test in constructive-db copies the same db.setContext({ role: 'authenticated', 'jwt.claims.user_id': ..., 'jwt.claims.database_id': ... }) pattern. This adds a typed convenience function so tests can call setUserContext(db, userId, databaseId) instead.

Review & Testing Checklist for Human

  • withTransaction savepoint semantics: The polyfill uses SAVEPOINT / RELEASE / ROLLBACK TO instead of a real nested transaction. Verify this is sufficient for the plugins that depend on withTransaction — in particular, confirm the presigned-url plugin's usage doesn't rely on true transaction isolation (it shouldn't, since PG savepoints share the parent transaction's isolation).
  • as any cast and mutation of pgClient: The polyfill monkey-patches the pg Client instance. The typeof guard prevents re-patching, but confirm this doesn't interfere with other test utilities that may also augment the client.
  • setUserContext claim names: Hardcodes jwt.claims.user_id and jwt.claims.database_id. Confirm these are the canonical claim names across all constructive RLS policies and won't diverge.

Recommended test: run the storage integration tests in constructive-db (app-integration-storage CI job) after publishing this version — those tests exercise both withTransaction (via upload mutations) and the RLS context pattern that setUserContext standardizes.

Notes

  • The withTransaction polyfill was previously monkey-patched inline in minio-multi-scope-graphql.integration.test.ts in constructive-db. This moves it into the framework so all tests get it automatically and the monkey-patch can be removed.
  • setUserContext is intentionally a standalone function (not a method on PgTestClient) because the claim names are constructive-specific, while PgTestClient lives in the generic pgsql-test package.

Link to Devin session: https://app.devin.ai/sessions/7903d2a3e7a34c6daa605e12d6b80d9e
Requested by: @pyramation

pyramation added 2 commits May 9, 2026 18:22
In production, @dataplan/pg provides withTransaction on the pgClient.
In tests, the raw pg Client lacks it, causing plugins that call
pgClient.withTransaction() (e.g. graphile-presigned-url-plugin) to fail
unless tests manually monkey-patch the method.

This adds a savepoint-based withTransaction implementation to the client
inside the withPgClient callback. Savepoints nest cleanly inside the
test harness's outer transaction, matching production behavior.

Eliminates the need for per-test monkey patches.
Convenience wrapper around db.setContext() with standard constructive JWT claims
(role: authenticated, jwt.claims.user_id, jwt.claims.database_id).

Eliminates the need to copy-paste the same setContext pattern in every test file.
@devin-ai-integration
Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@pyramation pyramation closed this May 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant