|
|
|
|
@ -4,6 +4,7 @@ import { WebhookServer } from '../../src/server';
|
|
|
|
|
import { ResponseQueue } from '../../src/services/response-queue';
|
|
|
|
|
import { GroupSyncService } from '../../src/services/group-sync';
|
|
|
|
|
import { initializeDatabase, ensureUserExists } from '../../src/db';
|
|
|
|
|
import { TaskService } from '../../src/tasks/service';
|
|
|
|
|
|
|
|
|
|
// Simulated ResponseQueue for testing (in-memory array)
|
|
|
|
|
let simulatedQueue: any[] = [];
|
|
|
|
|
@ -54,6 +55,9 @@ beforeEach(() => {
|
|
|
|
|
// Inject testDb for GroupSyncService to use
|
|
|
|
|
GroupSyncService.dbInstance = testDb;
|
|
|
|
|
|
|
|
|
|
// Inject testDb for TaskService to use
|
|
|
|
|
(TaskService as any).dbInstance = testDb;
|
|
|
|
|
|
|
|
|
|
// Ensure database is initialized (recreates tables if dropped)
|
|
|
|
|
initializeDatabase(testDb);
|
|
|
|
|
|
|
|
|
|
@ -783,4 +787,153 @@ describe('WebhookServer', () => {
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('Advanced listings via WebhookServer', () => {
|
|
|
|
|
test('should process "/t ver sin" in group as DM-only with pagination line', async () => {
|
|
|
|
|
// 12 sin dueño en el grupo activo
|
|
|
|
|
for (let i = 1; i <= 12; i++) {
|
|
|
|
|
TaskService.createTask({
|
|
|
|
|
description: `Sin dueño ${i}`,
|
|
|
|
|
due_date: '2025-12-31',
|
|
|
|
|
group_id: 'group-id@g.us',
|
|
|
|
|
created_by: '9999999999',
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
// 2 asignadas (no deben aparecer en "sin")
|
|
|
|
|
TaskService.createTask({
|
|
|
|
|
description: 'Asignada 1',
|
|
|
|
|
due_date: '2025-10-10',
|
|
|
|
|
group_id: 'group-id@g.us',
|
|
|
|
|
created_by: '1111111111',
|
|
|
|
|
}, [{ user_id: '1234567890', assigned_by: '1111111111' }]);
|
|
|
|
|
|
|
|
|
|
TaskService.createTask({
|
|
|
|
|
description: 'Asignada 2',
|
|
|
|
|
due_date: '2025-10-11',
|
|
|
|
|
group_id: 'group-id@g.us',
|
|
|
|
|
created_by: '1111111111',
|
|
|
|
|
}, [{ user_id: '1234567890', assigned_by: '1111111111' }]);
|
|
|
|
|
|
|
|
|
|
const payload = {
|
|
|
|
|
event: 'messages.upsert',
|
|
|
|
|
instance: 'test-instance',
|
|
|
|
|
data: {
|
|
|
|
|
key: {
|
|
|
|
|
remoteJid: 'group-id@g.us',
|
|
|
|
|
participant: '1234567890@s.whatsapp.net'
|
|
|
|
|
},
|
|
|
|
|
message: { conversation: '/t ver sin' }
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const response = await WebhookServer.handleRequest(createTestRequest(payload));
|
|
|
|
|
expect(response.status).toBe(200);
|
|
|
|
|
|
|
|
|
|
const out = SimulatedResponseQueue.getQueue();
|
|
|
|
|
expect(out.length).toBeGreaterThan(0);
|
|
|
|
|
for (const r of out) {
|
|
|
|
|
expect(r.recipient.endsWith('@g.us')).toBe(false);
|
|
|
|
|
}
|
|
|
|
|
const msg = out.map(x => x.message).join('\n');
|
|
|
|
|
expect(msg).toContain('sin dueño');
|
|
|
|
|
expect(msg).toContain('… y 2 más');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('should process "/t ver sin" in DM returning instruction', async () => {
|
|
|
|
|
const payload = {
|
|
|
|
|
event: 'messages.upsert',
|
|
|
|
|
instance: 'test-instance',
|
|
|
|
|
data: {
|
|
|
|
|
key: {
|
|
|
|
|
remoteJid: '1234567890@s.whatsapp.net', // DM
|
|
|
|
|
participant: '1234567890@s.whatsapp.net'
|
|
|
|
|
},
|
|
|
|
|
message: { conversation: '/t ver sin' }
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const response = await WebhookServer.handleRequest(createTestRequest(payload));
|
|
|
|
|
expect(response.status).toBe(200);
|
|
|
|
|
|
|
|
|
|
const out = SimulatedResponseQueue.getQueue();
|
|
|
|
|
expect(out.length).toBeGreaterThan(0);
|
|
|
|
|
const msg = out.map(x => x.message).join('\n');
|
|
|
|
|
expect(msg).toContain('Este comando se usa en grupos');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('should process "/t ver todos" in group showing "Tus tareas" + "Sin dueño (grupo actual)" with pagination in unassigned section', async () => {
|
|
|
|
|
// Tus tareas (2 asignadas)
|
|
|
|
|
TaskService.createTask({
|
|
|
|
|
description: 'Mi Tarea 1',
|
|
|
|
|
due_date: '2025-10-10',
|
|
|
|
|
group_id: 'group-id@g.us',
|
|
|
|
|
created_by: '2222222222',
|
|
|
|
|
}, [{ user_id: '1234567890', assigned_by: '2222222222' }]);
|
|
|
|
|
|
|
|
|
|
TaskService.createTask({
|
|
|
|
|
description: 'Mi Tarea 2',
|
|
|
|
|
due_date: '2025-10-11',
|
|
|
|
|
group_id: 'group-id@g.us',
|
|
|
|
|
created_by: '2222222222',
|
|
|
|
|
}, [{ user_id: '1234567890', assigned_by: '2222222222' }]);
|
|
|
|
|
|
|
|
|
|
// 12 sin dueño para provocar paginación
|
|
|
|
|
for (let i = 1; i <= 12; i++) {
|
|
|
|
|
TaskService.createTask({
|
|
|
|
|
description: `Sin dueño ${i}`,
|
|
|
|
|
due_date: '2025-12-31',
|
|
|
|
|
group_id: 'group-id@g.us',
|
|
|
|
|
created_by: '9999999999',
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const payload = {
|
|
|
|
|
event: 'messages.upsert',
|
|
|
|
|
instance: 'test-instance',
|
|
|
|
|
data: {
|
|
|
|
|
key: {
|
|
|
|
|
remoteJid: 'group-id@g.us',
|
|
|
|
|
participant: '1234567890@s.whatsapp.net'
|
|
|
|
|
},
|
|
|
|
|
message: { conversation: '/t ver todos' }
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const response = await WebhookServer.handleRequest(createTestRequest(payload));
|
|
|
|
|
expect(response.status).toBe(200);
|
|
|
|
|
|
|
|
|
|
const out = SimulatedResponseQueue.getQueue();
|
|
|
|
|
expect(out.length).toBeGreaterThan(0);
|
|
|
|
|
const msg = out.map(x => x.message).join('\n');
|
|
|
|
|
expect(msg).toContain('Tus tareas');
|
|
|
|
|
expect(msg).toContain('sin dueño');
|
|
|
|
|
expect(msg).toContain('… y 2 más');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('should process "/t ver todos" in DM showing "Tus tareas" + instructive note', async () => {
|
|
|
|
|
TaskService.createTask({
|
|
|
|
|
description: 'Mi Tarea A',
|
|
|
|
|
due_date: '2025-11-20',
|
|
|
|
|
group_id: 'group-2@g.us',
|
|
|
|
|
created_by: '1111111111',
|
|
|
|
|
}, [{ user_id: '1234567890', assigned_by: '1111111111' }]);
|
|
|
|
|
|
|
|
|
|
const payload = {
|
|
|
|
|
event: 'messages.upsert',
|
|
|
|
|
instance: 'test-instance',
|
|
|
|
|
data: {
|
|
|
|
|
key: {
|
|
|
|
|
remoteJid: '1234567890@s.whatsapp.net', // DM
|
|
|
|
|
participant: '1234567890@s.whatsapp.net'
|
|
|
|
|
},
|
|
|
|
|
message: { conversation: '/t ver todos' }
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const response = await WebhookServer.handleRequest(createTestRequest(payload));
|
|
|
|
|
expect(response.status).toBe(200);
|
|
|
|
|
|
|
|
|
|
const out = SimulatedResponseQueue.getQueue();
|
|
|
|
|
expect(out.length).toBeGreaterThan(0);
|
|
|
|
|
const msg = out.map(x => x.message).join('\n');
|
|
|
|
|
expect(msg).toContain('Tus tareas');
|
|
|
|
|
expect(msg).toContain('ℹ️ Para ver tareas sin dueño');
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|