Files
ims/tests/lib/db/with-user.test.ts
T

54 lines
1.7 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest'
// Mock the pools before importing with-user
vi.mock('../../../lib/db/index', () => {
const mockTx = {
execute: vi.fn().mockResolvedValue(undefined),
}
const mockUserDb = {
transaction: vi.fn().mockImplementation(async (fn: (tx: typeof mockTx) => Promise<unknown>) => fn(mockTx)),
}
const mockAdminDb = { query: vi.fn() }
return {
userDb: mockUserDb,
adminDb: mockAdminDb,
}
})
import { withUser, asAdmin } from '../../../lib/db/with-user'
import { userDb, adminDb } from '../../../lib/db/index'
describe('withUser', () => {
beforeEach(() => vi.clearAllMocks())
it('sets app.user_id GUC via set_config inside transaction', async () => {
const userId = 'test-user-uuid-1234'
const fn = vi.fn().mockResolvedValue('result')
const result = await withUser(userId, fn)
expect(result).toBe('result')
// transaction was called
expect((userDb as unknown as { transaction: ReturnType<typeof vi.fn> }).transaction).toHaveBeenCalledOnce()
// fn received the tx object
expect(fn).toHaveBeenCalledOnce()
// The tx.execute was called (GUC set_config invoked)
const tx = fn.mock.calls[0][0] as { execute: ReturnType<typeof vi.fn> }
expect(tx.execute).toHaveBeenCalledOnce()
})
it('propagates errors from fn', async () => {
const fn = vi.fn().mockRejectedValue(new Error('query failed'))
await expect(withUser('uid', fn)).rejects.toThrow('query failed')
})
})
describe('asAdmin', () => {
it('passes adminDb to fn', async () => {
const fn = vi.fn().mockResolvedValue('admin-result')
const result = await asAdmin(fn)
expect(result).toBe('admin-result')
expect(fn).toHaveBeenCalledWith(adminDb)
})
})