Skip to content

Commit c0a7aaf

Browse files
authored
Merge pull request #1087 from constructive-io/feat/graphile-test-with-transaction
feat(graphile-test): add withTransaction to pgClient in test context
2 parents 8b46d44 + df8938a commit c0a7aaf

1 file changed

Lines changed: 22 additions & 2 deletions

File tree

graphile/graphile-test/src/context.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,28 @@ export const runGraphQLInContext = async <T = ExecutionResult>({
270270
_pgSettings: Record<string, string> | null,
271271
callback: (client: Client) => T | Promise<T>
272272
): Promise<T> => {
273-
// Simply use the test client - it's already in a transaction
274-
// The pgSettings have already been applied above via setContextOnClient
273+
// Augment the client with withTransaction if it doesn't already have it.
274+
// In production, @dataplan/pg provides this method. In tests the raw pg
275+
// Client lacks it, so we implement it via savepoints (which nest cleanly
276+
// inside the test harness's outer transaction).
277+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
278+
const client = pgClient as any;
279+
if (typeof client.withTransaction !== 'function') {
280+
client.withTransaction = async (
281+
cb: (txClient: Client) => unknown | Promise<unknown>
282+
) => {
283+
const sp = `wt_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
284+
await client.query(`SAVEPOINT ${sp}`);
285+
try {
286+
const result = await cb(client);
287+
await client.query(`RELEASE SAVEPOINT ${sp}`);
288+
return result;
289+
} catch (err) {
290+
await client.query(`ROLLBACK TO SAVEPOINT ${sp}`);
291+
throw err;
292+
}
293+
};
294+
}
275295
return callback(pgClient);
276296
};
277297

0 commit comments

Comments
 (0)