|
| 1 | +/** @vitest-environment node */ |
| 2 | +import { DrizzleQueryError } from 'drizzle-orm/errors' |
| 3 | +import { beforeEach, describe, expect, it, vi } from 'vitest' |
| 4 | + |
| 5 | +const { refresh } = vi.hoisted(() => ({ refresh: vi.fn() })) |
| 6 | +vi.mock('@/lib/knowledge/connectors/external-group-sync', () => ({ |
| 7 | + refreshConnectorDirectory: refresh, |
| 8 | +})) |
| 9 | + |
| 10 | +import { executeDirectorySyncJob } from '@/background/knowledge-connector-directory-sync' |
| 11 | +import { GoogleDriveApiError } from '@/connectors/google-drive/google-drive-errors' |
| 12 | +import { ConnectorDirectoryError } from '@/connectors/source-error' |
| 13 | + |
| 14 | +const PAYLOAD = { connectorId: 'connector-1', requestId: 'request-1' } |
| 15 | + |
| 16 | +describe('directory sync worker diagnostics', () => { |
| 17 | + beforeEach(() => vi.clearAllMocks()) |
| 18 | + |
| 19 | + it('preserves successful directory outcomes', async () => { |
| 20 | + refresh.mockResolvedValueOnce('refreshed') |
| 21 | + await expect(executeDirectorySyncJob(PAYLOAD)).resolves.toEqual({ outcome: 'refreshed' }) |
| 22 | + expect(refresh).toHaveBeenCalledWith('connector-1', 'request-1') |
| 23 | + }) |
| 24 | + |
| 25 | + it('includes the Google operation and reason in the final task failure', async () => { |
| 26 | + refresh.mockRejectedValueOnce( |
| 27 | + new ConnectorDirectoryError('private group detail', { |
| 28 | + cause: new GoogleDriveApiError(403, ['forbidden'], 'directory.members.list'), |
| 29 | + }) |
| 30 | + ) |
| 31 | + const error = await executeDirectorySyncJob(PAYLOAD).catch((error: unknown) => error) |
| 32 | + expect(error).toMatchObject({ |
| 33 | + message: |
| 34 | + 'Directory permission sync failed (HTTP 403). Operation: directory.members.list. Google reason: forbidden. Group membership could not be fully verified.', |
| 35 | + }) |
| 36 | + expect(error).not.toHaveProperty('cause') |
| 37 | + expect(String(error)).not.toContain('private') |
| 38 | + }) |
| 39 | + |
| 40 | + it('preserves database codes without exposing the raw driver cause to Trigger', async () => { |
| 41 | + refresh.mockRejectedValueOnce( |
| 42 | + new DrizzleQueryError( |
| 43 | + 'select private SQL', |
| 44 | + ['private value'], |
| 45 | + Object.assign(new Error('private driver detail'), { code: '57014' }) |
| 46 | + ) |
| 47 | + ) |
| 48 | + const error = await executeDirectorySyncJob(PAYLOAD).catch((error: unknown) => error) |
| 49 | + expect(error).toMatchObject({ message: 'Database request failed (SQLSTATE 57014).' }) |
| 50 | + expect(error).not.toHaveProperty('cause') |
| 51 | + expect(String(error)).not.toContain('private') |
| 52 | + }) |
| 53 | + |
| 54 | + it('preserves unclassified failures', async () => { |
| 55 | + const error = new Error('unexpected failure') |
| 56 | + refresh.mockRejectedValueOnce(error) |
| 57 | + await expect(executeDirectorySyncJob(PAYLOAD)).rejects.toBe(error) |
| 58 | + }) |
| 59 | + |
| 60 | + it('retains the database code when a directory refresh wraps the driver failure', async () => { |
| 61 | + refresh.mockRejectedValueOnce( |
| 62 | + new ConnectorDirectoryError('private wrapper', { |
| 63 | + cause: new DrizzleQueryError( |
| 64 | + 'select private SQL', |
| 65 | + ['private value'], |
| 66 | + Object.assign(new Error('private driver detail'), { code: '57014' }) |
| 67 | + ), |
| 68 | + }) |
| 69 | + ) |
| 70 | + const error = await executeDirectorySyncJob(PAYLOAD).catch((error: unknown) => error) |
| 71 | + expect(error).toMatchObject({ |
| 72 | + message: |
| 73 | + 'Directory permission sync failed. Error code: 57014. Group membership could not be fully verified.', |
| 74 | + }) |
| 75 | + expect(error).not.toHaveProperty('cause') |
| 76 | + expect(String(error)).not.toContain('private') |
| 77 | + }) |
| 78 | +}) |
0 commit comments