Files
workspace/apps/whatsapp-crm/tests/integration.test.ts

253 lines
8.7 KiB
TypeScript

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()
})
})
})