UNPKG

@accounter/server

Version:
111 lines (93 loc) 3.35 kB
import { describe, it, expect, vi } from 'vitest'; import { createApplication, createModule, Injectable, Scope, gql, Inject } from 'graphql-modules'; import { TenantAwareDBClient } from '../tenant-db-client.js'; import { DBProvider } from '../db.provider.js'; import { AuthContextProvider } from '../../auth/providers/auth-context.provider.js'; describe('TenantAwareDBClient DI Integration', () => { it('should be injectable into providers and operation-scoped', async () => { // 1. Setup Mocks const mockPool = { connect: vi.fn(), query: vi.fn(), end: vi.fn(), on: vi.fn() }; @Injectable() class MockDBProvider { pool = mockPool; } @Injectable() class MockAuthContextProvider { getAuthContext = vi.fn().mockResolvedValue({ authType: 'jwt', tenant: { businessId: 'business-1' }, user: { userId: 'user-1', role: 'admin' }, }); } // 2. Create Test Provider @Injectable({ scope: Scope.Operation }) class TestProvider { constructor(@Inject(TenantAwareDBClient) public db: TenantAwareDBClient) {} } // 3. Create Module const testModule = createModule({ id: 'test-module', typeDefs: gql` type Query { test: String } ` }); // 4. Create App const app = createApplication({ modules: [testModule], providers: [ TestProvider, TenantAwareDBClient, { provide: DBProvider, useClass: MockDBProvider }, { provide: AuthContextProvider, useClass: MockAuthContextProvider }, ] }); // 5. Verify Injection & Scope const controller1 = app.createOperationController({ context: {} }); const service1 = controller1.injector.get(TestProvider); expect(service1).toBeDefined(); expect(service1.db).toBeInstanceOf(TenantAwareDBClient); const controller2 = app.createOperationController({ context: {} }); const service2 = controller2.injector.get(TestProvider); // Verify different instances (Operation Scope) expect(service1).not.toBe(service2); expect(service1.db).not.toBe(service2.db); // Verify they are disposed await controller1.destroy(); await controller2.destroy(); }); it('should throw error when auth context is null during query', async () => { const mockPool = { connect: vi.fn() }; @Injectable() class MockDBProvider { pool = mockPool; } @Injectable() class MockAuthContextProvider { getAuthContext = vi.fn().mockResolvedValue(null); } const testModule = createModule({ id: 'test-module-fail', typeDefs: gql` type Query { test: String } ` }); const app = createApplication({ modules: [testModule], providers: [ TenantAwareDBClient, { provide: DBProvider, useClass: MockDBProvider }, { provide: AuthContextProvider, useClass: MockAuthContextProvider }, ] }); const controller = app.createOperationController({ context: {} }); const dbClient = controller.injector.get(TenantAwareDBClient); await expect(dbClient.query('SELECT 1')).rejects.toThrow('Auth context not available. TenantAwareDBClient requires active authentication.'); }); });