import { SupabaseContactRepository } from '../repositories/SupabaseContactRepository' // Mock V2AudienceEngine since it requires real Supabase jest.mock('../engine/V2AudienceEngine', () => ({ V2AudienceEngine: jest.fn().mockImplementation(() => ({ getContactIdsByAudienceCriteriaV2: jest.fn().mockResolvedValue(new Set(['c1', 'c2'])), matchesContactByAudienceCriteriaV2: jest.fn().mockResolvedValue(true), })), })) function mockSupabase() { const chainable = { select: jest.fn().mockReturnThis(), eq: jest.fn().mockReturnThis(), in: jest.fn().mockResolvedValue({ data: [{ id: 'c1', email: 'a@b.com' }, { id: 'c2', email: 'c@d.com' }], error: null, }), } return { from: jest.fn().mockReturnValue(chainable), _chainable: chainable, } } describe('SupabaseContactRepository', () => { it('creates instance with supabase and clickhouse clients', () => { const repo = new SupabaseContactRepository({ supabaseClient: mockSupabase(), clickhouseClient: {}, debug: false, }) expect(repo).toBeDefined() }) describe('getContactIdsByAudienceCriteriaV2', () => { it('delegates to V2AudienceEngine', async () => { const repo = new SupabaseContactRepository({ supabaseClient: mockSupabase() }) const result = await repo.getContactIdsByAudienceCriteriaV2('org-1', 'proj-1', { groups: [] }) expect(result).toBeInstanceOf(Set) expect(result.size).toBe(2) }) }) describe('matchesContactByAudienceCriteriaV2', () => { it('delegates to V2AudienceEngine', async () => { const repo = new SupabaseContactRepository({ supabaseClient: mockSupabase() }) const result = await repo.matchesContactByAudienceCriteriaV2('org-1', 'proj-1', { groups: [] }, 'c1') expect(result).toBe(true) }) }) describe('findByIds', () => { it('queries Supabase for contacts by IDs', async () => { const supabase = mockSupabase() const repo = new SupabaseContactRepository({ supabaseClient: supabase }) const { data } = await repo.findByIds('org-1', 'proj-1', ['c1', 'c2']) expect(supabase.from).toHaveBeenCalledWith('contacts') expect(supabase._chainable.select).toHaveBeenCalledWith('*') expect(supabase._chainable.eq).toHaveBeenCalledWith('organization_id', 'org-1') expect(supabase._chainable.eq).toHaveBeenCalledWith('project_id', 'proj-1') expect(supabase._chainable.in).toHaveBeenCalledWith('id', ['c1', 'c2']) expect(data).toHaveLength(2) }) it('throws when Supabase returns an error', async () => { const supabase = mockSupabase() supabase._chainable.in = jest.fn().mockResolvedValue({ data: null, error: new Error('DB error'), }) const repo = new SupabaseContactRepository({ supabaseClient: supabase }) await expect(repo.findByIds('org-1', 'proj-1', ['c1'])).rejects.toThrow('DB error') }) }) })