import { initDB, createContact, createTask, createMessage, getContactById, getTasksByContactId, getMessagesByContactId, updateContact, updateTask, closeDB } from '@/lib/db' import { STAGES } from '@/lib/types' beforeAll(async () => { await initDB() }) afterAll(() => { closeDB() }) beforeEach(() => { const db = require('@/lib/db').getDB() db.run('DELETE FROM tasks') db.run('DELETE FROM messages') db.run('DELETE FROM contacts') }) describe('Integration Tests', () => { describe('10.1 Full Pipeline Tests', () => { it('test_full_contact_lifecycle', async () => { const contact = createContact({ name: 'Test User', phone: '+5511999999991' }) expect(contact.id).toBeGreaterThan(0) const updated = updateContact(contact.id, { stage: STAGES.DECIDINDO }) expect(updated?.stage).toBe(STAGES.DECIDINDO) const fetched = getContactById(contact.id) expect(fetched?.name).toBe('Test User') expect(fetched?.stage).toBe(STAGES.DECIDINDO) }) it('test_contact_with_tasks_lifecycle', async () => { const contact = createContact({ name: 'Task User', phone: '+5511999999992' }) const task1 = createTask({ contact_id: contact.id, title: 'Task 1', due_date: '2026-04-10' }) const task2 = createTask({ contact_id: contact.id, title: 'Task 2', due_date: '2026-04-15' }) const tasks = getTasksByContactId(contact.id) expect(tasks).toHaveLength(2) updateTask(task1.id, { status: 'completed' }) const allTasks = getTasksByContactId(contact.id) const pending = allTasks.filter(t => t.status === 'pending') expect(pending).toHaveLength(1) }) it('test_contact_with_messages_lifecycle', async () => { const contact = createContact({ name: 'Message User', phone: '+5511999999993' }) const msg1 = createMessage({ contact_id: contact.id, external_id: 'msg-1', body: 'Hello', from_phone: contact.phone, timestamp: 1704067200, has_media: false, }) const msg2 = createMessage({ contact_id: contact.id, external_id: 'msg-2', body: 'How are you?', from_phone: contact.phone, timestamp: 1704070800, has_media: false, }) const messages = getMessagesByContactId(contact.id) expect(messages).toHaveLength(2) expect(messages[0].body).toBe('How are you?') }) it('test_duplicate_message_filtered', async () => { const contact = createContact({ name: 'Dupe User', phone: '+5511999999994' }) createMessage({ contact_id: contact.id, external_id: 'same-id', body: 'First message', from_phone: contact.phone, timestamp: 1704067200, }) const duplicate = createMessage({ contact_id: contact.id, external_id: 'same-id', body: 'Duplicate message', from_phone: contact.phone, timestamp: 1704070800, }) expect(duplicate).toBeNull() const messages = getMessagesByContactId(contact.id) expect(messages).toHaveLength(1) expect(messages[0].body).toBe('First message') }) }) describe('10.2 Multi-Feature Tests', () => { it('test_search_finds_contact_with_tasks', async () => { createContact({ name: 'Searchable Contact', phone: '+5511999999991' }) const contact2 = createContact({ name: 'Other Contact', phone: '+5511999999992' }) createTask({ contact_id: contact2.id, title: 'Important Task', due_date: '2026-04-10' }) const { searchContacts } = require('@/lib/db') const results = searchContacts('Searchable') expect(results).toHaveLength(1) expect(results[0].name).toBe('Searchable Contact') }) it('test_filter_stage_preserves_tasks', async () => { const contact1 = createContact({ name: 'Lead 1', phone: '+5511999999991' }) const contact2 = createContact({ name: 'Lead 2', phone: '+5511999999992' }) updateContact(contact1.id, { stage: STAGES.DECIDINDO }) createTask({ contact_id: contact1.id, title: 'Task for Decidindo', due_date: '2026-04-10' }) createTask({ contact_id: contact2.id, title: 'Task for Leads', due_date: '2026-04-10' }) const { getContactsByStage } = require('@/lib/db') const leads = getContactsByStage(STAGES.LEADS_DE_ENTRADA) const decidindo = getContactsByStage(STAGES.DECIDINDO) expect(leads).toHaveLength(1) expect(decidindo).toHaveLength(1) const decidindoTasks = getTasksByContactId(decidindo[0].id) expect(decidindoTasks).toHaveLength(1) }) it('test_payment_status_update_preserves_all_data', async () => { const contact = createContact({ name: 'Payment User', phone: '+5511999999991', notes: 'Initial note' }) createTask({ contact_id: contact.id, title: 'Task 1', due_date: '2026-04-10' }) createMessage({ contact_id: contact.id, external_id: 'msg-1', body: 'Message 1', from_phone: contact.phone, timestamp: 1704067200, }) updateContact(contact.id, { payment_status: 'paid', notes: 'Updated note' }) const updated = getContactById(contact.id) expect(updated?.payment_status).toBe('paid') expect(updated?.notes).toBe('Updated note') const tasks = getTasksByContactId(contact.id) expect(tasks).toHaveLength(1) const messages = getMessagesByContactId(contact.id) expect(messages).toHaveLength(1) }) }) describe('10.3 Performance Tests', () => { it('test_bulk_contact_creation', async () => { const startTime = Date.now() for (let i = 0; i < 50; i++) { createContact({ name: `Contact ${i}`, phone: `+551199999${String(i).padStart(4, '0')}` }) } const elapsed = Date.now() - startTime expect(elapsed).toBeLessThan(2000) }) it('test_bulk_task_creation', async () => { const contact = createContact({ name: 'Bulk User', phone: '+5511999999991' }) for (let i = 0; i < 20; i++) { createTask({ contact_id: contact.id, title: `Task ${i}`, due_date: '2026-04-10' }) } const tasks = getTasksByContactId(contact.id) expect(tasks).toHaveLength(20) }) it('test_bulk_message_creation', async () => { const contact = createContact({ name: 'Bulk Msg User', phone: '+5511999999991' }) for (let i = 0; i < 20; i++) { createMessage({ contact_id: contact.id, external_id: `msg-${i}`, body: `Message ${i}`, from_phone: contact.phone, timestamp: 1704067200 + i * 3600, }) } const messages = getMessagesByContactId(contact.id) expect(messages).toHaveLength(20) }) }) describe('10.4 Edge Cases', () => { it('test_delete_contact_cascades_tasks_and_messages', async () => { const contact = createContact({ name: 'To Delete', phone: '+5511999999991' }) createTask({ contact_id: contact.id, title: 'Task', due_date: '2026-04-10' }) createMessage({ contact_id: contact.id, external_id: 'msg-1', body: 'Message', from_phone: contact.phone, timestamp: 1704067200, }) const { deleteContact } = require('@/lib/db') deleteContact(contact.id) const tasks = getTasksByContactId(contact.id) const messages = getMessagesByContactId(contact.id) expect(tasks).toHaveLength(0) expect(messages).toHaveLength(0) }) it('test_stage_transitions_all_stages', async () => { const contact = createContact({ name: 'Stage User', phone: '+5511999999991' }) expect(contact.stage).toBe(STAGES.LEADS_DE_ENTRADA) let updated = updateContact(contact.id, { stage: STAGES.DECIDINDO }) expect(updated?.stage).toBe(STAGES.DECIDINDO) updated = updateContact(contact.id, { stage: STAGES.DISCUSSAO_DE_CONTRATO }) expect(updated?.stage).toBe(STAGES.DISCUSSAO_DE_CONTRATO) updated = updateContact(contact.id, { stage: STAGES.DECISAO_FINAL }) expect(updated?.stage).toBe(STAGES.DECISAO_FINAL) }) it('test_task_completion_updates_correctly', async () => { const contact = createContact({ name: 'Task User', phone: '+5511999999991' }) const task = createTask({ contact_id: contact.id, title: 'To Complete', due_date: '2026-04-10' }) const completed = updateTask(task.id, { status: 'completed' }) expect(completed?.status).toBe('completed') expect(completed?.completed_at).not.toBeNull() const reOpened = updateTask(task.id, { status: 'pending' }) expect(reOpened?.status).toBe('pending') expect(reOpened?.completed_at).toBeNull() }) }) })