UNPKG

@accounter/server

Version:
59 lines 2.96 kB
import { afterAll, beforeAll, describe, expect, it } from 'vitest'; import { TestDatabase } from './helpers/db-setup.js'; /** * Verifies the multi-business RLS migration: * - `get_current_business_scope()` parses the `app.current_business_scope` * array setting and falls back to the single business context when unset. * - tenant_isolation policies read via the scope array (USING) while writes * stay pinned to the single business (WITH CHECK). * * This file asserts the helper behavior and the policy definitions (via * pg_policies). The actual row filtering is exercised under a non-superuser role * in rls-read-visibility.integration.test.ts (USING / reads) and * rls-write-target.integration.test.ts (WITH CHECK / writes) — the test DB * connects as a superuser (BYPASSRLS), so those tests drop to a non-privileged * role to make Postgres evaluate the policies. */ describe('multi-business RLS scope', () => { let db; const A = '11111111-1111-1111-1111-111111111111'; const B = '22222222-2222-2222-2222-222222222222'; beforeAll(async () => { db = new TestDatabase(); await db.connect(); }); afterAll(async () => { // Pool managed by global vitest setup — do not close here. }); it('parses the business scope array setting', async () => { await db.withTransaction(async (client) => { await client.query(`SELECT set_config('app.current_business_id', $1, true)`, [A]); await client.query(`SELECT set_config('app.current_business_scope', $1, true)`, [ `{${A},${B}}`, ]); const res = await client.query(`SELECT accounter_schema.get_current_business_scope() AS scope`); expect(res.rows[0].scope).toEqual([A, B]); }); }); it('falls back to the single business context when scope is unset', async () => { await db.withTransaction(async (client) => { await client.query(`SELECT set_config('app.current_business_id', $1, true)`, [A]); await client.query(`SELECT set_config('app.current_business_scope', '', true)`); const res = await client.query(`SELECT accounter_schema.get_current_business_scope() AS scope`); expect(res.rows[0].scope).toEqual([A]); }); }); it('uses the scope array for reads and the single business for writes', async () => { await db.withTransaction(async (client) => { const res = await client.query(`SELECT qual, with_check FROM pg_policies WHERE schemaname = 'accounter_schema' AND tablename = 'charges' AND policyname = 'tenant_isolation'`); expect(res.rows).toHaveLength(1); expect(res.rows[0].qual).toContain('get_current_business_scope'); expect(res.rows[0].with_check).toContain('get_current_business_id'); }); }); }); //# sourceMappingURL=rls-multi-business.integration.test.js.map