corrige tests para adaptarlos a que ahora no se escribe sin responsable en las respuestas sobre tareas, solo se deja el emoji

main
borja 11 months ago
parent de257cf65f
commit ab832e208b

File diff suppressed because it is too large Load Diff

@ -7,336 +7,336 @@ import { GroupSyncService } from '../../../src/services/group-sync';
let memDb: Database; let memDb: Database;
const testContextBase = { const testContextBase = {
sender: '1234567890', sender: '1234567890',
groupId: 'test-group@g.us', groupId: 'test-group@g.us',
mentions: [] as string[], mentions: [] as string[],
}; };
beforeEach(() => { beforeEach(() => {
memDb = new Database(':memory:'); memDb = new Database(':memory:');
initializeDatabase(memDb); initializeDatabase(memDb);
(CommandService as any).dbInstance = memDb; (CommandService as any).dbInstance = memDb;
(TaskService as any).dbInstance = memDb; (TaskService as any).dbInstance = memDb;
(GroupSyncService as any).dbInstance = memDb; (GroupSyncService as any).dbInstance = memDb;
GroupSyncService.activeGroupsCache.clear(); GroupSyncService.activeGroupsCache.clear();
}); });
test('listar grupo por defecto con /t ver en grupo e incluir “… y X más”', async () => { test('listar grupo por defecto con /t ver en grupo e incluir “… y X más”', async () => {
// Insert group and cache it as active // Insert group and cache it as active
memDb.exec(` memDb.exec(`
INSERT OR IGNORE INTO groups (id, community_id, name, active) INSERT OR IGNORE INTO groups (id, community_id, name, active)
VALUES ('test-group@g.us', 'test-community', 'Test Group', 1) VALUES ('test-group@g.us', 'test-community', 'Test Group', 1)
`); `);
GroupSyncService.activeGroupsCache.clear(); GroupSyncService.activeGroupsCache.clear();
GroupSyncService.activeGroupsCache.set('test-group@g.us', 'Test Group'); GroupSyncService.activeGroupsCache.set('test-group@g.us', 'Test Group');
// Crear 12 tareas sin asignados en el grupo // Crear 12 tareas sin asignados en el grupo
for (let i = 1; i <= 12; i++) { for (let i = 1; i <= 12; i++) {
TaskService.createTask({ TaskService.createTask({
description: `Task ${i}`, description: `Task ${i}`,
due_date: '2025-12-31', due_date: '2025-12-31',
group_id: 'test-group@g.us', group_id: 'test-group@g.us',
created_by: '1234567890', created_by: '1234567890',
}); });
} }
const responses = await CommandService.handle({ const responses = await CommandService.handle({
sender: '1234567890', sender: '1234567890',
groupId: 'test-group@g.us', groupId: 'test-group@g.us',
mentions: [], mentions: [],
message: '/t ver' message: '/t ver'
}); });
expect(responses.length).toBe(1); expect(responses.length).toBe(1);
expect(responses[0].recipient).toBe('1234567890'); expect(responses[0].recipient).toBe('1234567890');
expect(responses[0].message).toContain('Test Group'); expect(responses[0].message).toContain('Test Group');
// Debe indicar que hay 2 más (límite 10) // Debe indicar que hay 2 más (límite 10)
expect(responses[0].message).toContain('… y 2 más'); expect(responses[0].message).toContain('… y 2 más');
// Debe mostrar “sin responsable” // Debe mostrar “sin responsable”
expect(responses[0].message).toContain('sin responsable'); expect(responses[0].message).toContain('🙅');
}); });
test('listar “mis” por defecto en DM con /t ver', async () => { test('listar “mis” por defecto en DM con /t ver', async () => {
// Insert groups and cache them // Insert groups and cache them
memDb.exec(` memDb.exec(`
INSERT OR REPLACE INTO groups (id, community_id, name, active) VALUES INSERT OR REPLACE INTO groups (id, community_id, name, active) VALUES
('test-group@g.us', 'test-community', 'Test Group', 1), ('test-group@g.us', 'test-community', 'Test Group', 1),
('group-2@g.us', 'test-community', 'Group 2', 1) ('group-2@g.us', 'test-community', 'Group 2', 1)
`); `);
GroupSyncService.activeGroupsCache.clear(); GroupSyncService.activeGroupsCache.clear();
GroupSyncService.activeGroupsCache.set('test-group@g.us', 'Test Group'); GroupSyncService.activeGroupsCache.set('test-group@g.us', 'Test Group');
GroupSyncService.activeGroupsCache.set('group-2@g.us', 'Group 2'); GroupSyncService.activeGroupsCache.set('group-2@g.us', 'Group 2');
// Crear 2 tareas asignadas al usuario en distintos grupos // Crear 2 tareas asignadas al usuario en distintos grupos
const t1 = TaskService.createTask({ const t1 = TaskService.createTask({
description: 'G1 Task', description: 'G1 Task',
due_date: '2025-11-20', due_date: '2025-11-20',
group_id: 'test-group@g.us', group_id: 'test-group@g.us',
created_by: '1111111111', created_by: '1111111111',
}, [{ user_id: '1234567890', assigned_by: '1111111111' }]); }, [{ user_id: '1234567890', assigned_by: '1111111111' }]);
const t2 = TaskService.createTask({ const t2 = TaskService.createTask({
description: 'G2 Task', description: 'G2 Task',
due_date: '2025-11-25', due_date: '2025-11-25',
group_id: 'group-2@g.us', group_id: 'group-2@g.us',
created_by: '2222222222', created_by: '2222222222',
}, [{ user_id: '1234567890', assigned_by: '2222222222' }]); }, [{ user_id: '1234567890', assigned_by: '2222222222' }]);
const responses = await CommandService.handle({ const responses = await CommandService.handle({
sender: '1234567890', sender: '1234567890',
// Contexto de DM: usar un JID que NO sea de grupo // Contexto de DM: usar un JID que NO sea de grupo
groupId: '1234567890@s.whatsapp.net', groupId: '1234567890@s.whatsapp.net',
mentions: [], mentions: [],
message: '/t ver' message: '/t ver'
}); });
expect(responses.length).toBe(1); expect(responses.length).toBe(1);
expect(responses[0].recipient).toBe('1234567890'); expect(responses[0].recipient).toBe('1234567890');
const msg = responses[0].message; const msg = responses[0].message;
expect(msg).toContain('Test Group'); expect(msg).toContain('Test Group');
expect(msg).toContain('Group 2'); expect(msg).toContain('Group 2');
expect(msg).toMatch(/- `\d{4}` G1 Task/); expect(msg).toMatch(/- `\d{4}` G1 Task/);
expect(msg).toMatch(/- `\d{4}` G2 Task/); expect(msg).toMatch(/- `\d{4}` G2 Task/);
}); });
test('completar tarea: camino feliz, ya completada y no encontrada', async () => { test('completar tarea: camino feliz, ya completada y no encontrada', async () => {
// Insertar grupo y cache // Insertar grupo y cache
memDb.exec(` memDb.exec(`
INSERT OR IGNORE INTO groups (id, community_id, name, active) INSERT OR IGNORE INTO groups (id, community_id, name, active)
VALUES ('test-group@g.us', 'test-community', 'Test Group', 1) VALUES ('test-group@g.us', 'test-community', 'Test Group', 1)
`); `);
GroupSyncService.activeGroupsCache.clear(); GroupSyncService.activeGroupsCache.clear();
GroupSyncService.activeGroupsCache.set('test-group@g.us', 'Test Group'); GroupSyncService.activeGroupsCache.set('test-group@g.us', 'Test Group');
const taskId = TaskService.createTask({ const taskId = TaskService.createTask({
description: 'Completar yo', description: 'Completar yo',
due_date: '2025-10-10', due_date: '2025-10-10',
group_id: 'test-group@g.us', group_id: 'test-group@g.us',
created_by: '1111111111', created_by: '1111111111',
}); });
const dc = Number((memDb.prepare(`SELECT display_code FROM tasks WHERE id = ?`).get(taskId) as any)?.display_code || 0); const dc = Number((memDb.prepare(`SELECT display_code FROM tasks WHERE id = ?`).get(taskId) as any)?.display_code || 0);
// 1) Camino feliz // 1) Camino feliz
let responses = await CommandService.handle({ let responses = await CommandService.handle({
sender: '1234567890', sender: '1234567890',
groupId: 'test-group@g.us', groupId: 'test-group@g.us',
mentions: [], mentions: [],
message: `/t x ${dc}` message: `/t x ${dc}`
}); });
expect(responses.length).toBe(1); expect(responses.length).toBe(1);
expect(responses[0].recipient).toBe('1234567890'); expect(responses[0].recipient).toBe('1234567890');
expect(responses[0].message).toMatch(/^✅ `\d{4}` _completada_/); expect(responses[0].message).toMatch(/^✅ `\d{4}` _completada_/);
// 2) Ya completada (ahora no debe resolverse por display_code → no encontrada) // 2) Ya completada (ahora no debe resolverse por display_code → no encontrada)
responses = await CommandService.handle({ responses = await CommandService.handle({
sender: '1234567890', sender: '1234567890',
groupId: 'test-group@g.us', groupId: 'test-group@g.us',
mentions: [], mentions: [],
message: `/t x ${dc}` message: `/t x ${dc}`
}); });
expect(responses.length).toBe(1); expect(responses.length).toBe(1);
expect(responses[0].message).toContain('no encontrada'); expect(responses[0].message).toContain('no encontrada');
// 3) No encontrada // 3) No encontrada
responses = await CommandService.handle({ responses = await CommandService.handle({
sender: '1234567890', sender: '1234567890',
groupId: 'test-group@g.us', groupId: 'test-group@g.us',
mentions: [], mentions: [],
message: `/t x 999999` message: `/t x 999999`
}); });
expect(responses.length).toBe(1); expect(responses.length).toBe(1);
expect(responses[0].message).toContain('no encontrada'); expect(responses[0].message).toContain('no encontrada');
}); });
test('ver sin en grupo activo: solo sin dueño y paginación', async () => { test('ver sin en grupo activo: solo sin dueño y paginación', async () => {
// Insertar grupo y cachearlo como activo // Insertar grupo y cachearlo como activo
memDb.exec(` memDb.exec(`
INSERT OR IGNORE INTO groups (id, community_id, name, active) INSERT OR IGNORE INTO groups (id, community_id, name, active)
VALUES ('test-group@g.us', 'test-community', 'Test Group', 1) VALUES ('test-group@g.us', 'test-community', 'Test Group', 1)
`); `);
GroupSyncService.activeGroupsCache.clear(); GroupSyncService.activeGroupsCache.clear();
GroupSyncService.activeGroupsCache.set('test-group@g.us', 'Test Group'); GroupSyncService.activeGroupsCache.set('test-group@g.us', 'Test Group');
// 12 tareas sin dueño (para provocar “… y 2 más” con límite 10) // 12 tareas sin dueño (para provocar “… y 2 más” con límite 10)
for (let i = 1; i <= 12; i++) { for (let i = 1; i <= 12; i++) {
TaskService.createTask({ TaskService.createTask({
description: `Unassigned ${i}`, description: `Unassigned ${i}`,
due_date: '2025-12-31', due_date: '2025-12-31',
group_id: 'test-group@g.us', group_id: 'test-group@g.us',
created_by: '9999999999', created_by: '9999999999',
}); });
} }
// 2 tareas asignadas (no deben aparecer en "ver sin") // 2 tareas asignadas (no deben aparecer en "ver sin")
TaskService.createTask({ TaskService.createTask({
description: 'Asignada 1', description: 'Asignada 1',
due_date: '2025-11-01', due_date: '2025-11-01',
group_id: 'test-group@g.us', group_id: 'test-group@g.us',
created_by: '1111111111', created_by: '1111111111',
}, [{ user_id: '1234567890', assigned_by: '1111111111' }]); }, [{ user_id: '1234567890', assigned_by: '1111111111' }]);
TaskService.createTask({ TaskService.createTask({
description: 'Asignada 2', description: 'Asignada 2',
due_date: '2025-11-02', due_date: '2025-11-02',
group_id: 'test-group@g.us', group_id: 'test-group@g.us',
created_by: '1111111111', created_by: '1111111111',
}, [{ user_id: '1234567890', assigned_by: '1111111111' }]); }, [{ user_id: '1234567890', assigned_by: '1111111111' }]);
const responses = await CommandService.handle({ const responses = await CommandService.handle({
sender: '1234567890', sender: '1234567890',
groupId: 'test-group@g.us', groupId: 'test-group@g.us',
mentions: [], mentions: [],
message: '/t ver sin' message: '/t ver sin'
}); });
expect(responses.length).toBe(1); expect(responses.length).toBe(1);
expect(responses[0].recipient).toBe('1234567890'); expect(responses[0].recipient).toBe('1234567890');
const msg = responses[0].message; const msg = responses[0].message;
expect(msg).toContain('Test Group'); expect(msg).toContain('Test Group');
expect(msg).toContain('sin responsable'); expect(msg).toContain('🙅');
expect(msg).toContain('… y 2 más'); expect(msg).toContain('… y 2 más');
expect(msg).not.toContain('Asignada 1'); expect(msg).not.toContain('Asignada 1');
expect(msg).not.toContain('Asignada 2'); expect(msg).not.toContain('Asignada 2');
}); });
test('ver sin por DM devuelve instrucción', async () => { test('ver sin por DM devuelve instrucción', async () => {
const responses = await CommandService.handle({ const responses = await CommandService.handle({
sender: '1234567890', sender: '1234567890',
// DM: no es un JID de grupo // DM: no es un JID de grupo
groupId: '1234567890@s.whatsapp.net', groupId: '1234567890@s.whatsapp.net',
mentions: [], mentions: [],
message: '/t ver sin' message: '/t ver sin'
}); });
expect(responses.length).toBe(1); expect(responses.length).toBe(1);
expect(responses[0].recipient).toBe('1234567890'); expect(responses[0].recipient).toBe('1234567890');
expect(responses[0].message).toContain('Este comando se usa en grupos'); expect(responses[0].message).toContain('Este comando se usa en grupos');
}); });
test('ver todos en grupo: “Tus tareas” + “Sin dueño (grupo actual)” con paginación en la sección sin dueño', async () => { test('ver todos en grupo: “Tus tareas” + “Sin dueño (grupo actual)” con paginación en la sección sin dueño', async () => {
// Insertar grupo y cachearlo como activo // Insertar grupo y cachearlo como activo
memDb.exec(` memDb.exec(`
INSERT OR IGNORE INTO groups (id, community_id, name, active) INSERT OR IGNORE INTO groups (id, community_id, name, active)
VALUES ('test-group@g.us', 'test-community', 'Test Group', 1) VALUES ('test-group@g.us', 'test-community', 'Test Group', 1)
`); `);
GroupSyncService.activeGroupsCache.clear(); GroupSyncService.activeGroupsCache.clear();
GroupSyncService.activeGroupsCache.set('test-group@g.us', 'Test Group'); GroupSyncService.activeGroupsCache.set('test-group@g.us', 'Test Group');
// Tus tareas (2 asignadas al usuario) // Tus tareas (2 asignadas al usuario)
TaskService.createTask({ TaskService.createTask({
description: 'Mi Tarea 1', description: 'Mi Tarea 1',
due_date: '2025-10-10', due_date: '2025-10-10',
group_id: 'test-group@g.us', group_id: 'test-group@g.us',
created_by: '2222222222', created_by: '2222222222',
}, [{ user_id: '1234567890', assigned_by: '2222222222' }]); }, [{ user_id: '1234567890', assigned_by: '2222222222' }]);
TaskService.createTask({ TaskService.createTask({
description: 'Mi Tarea 2', description: 'Mi Tarea 2',
due_date: '2025-10-11', due_date: '2025-10-11',
group_id: 'test-group@g.us', group_id: 'test-group@g.us',
created_by: '2222222222', created_by: '2222222222',
}, [{ user_id: '1234567890', assigned_by: '2222222222' }]); }, [{ user_id: '1234567890', assigned_by: '2222222222' }]);
// 12 sin dueño en el grupo (provoca “… y 2 más” en esa sección) // 12 sin dueño en el grupo (provoca “… y 2 más” en esa sección)
for (let i = 1; i <= 12; i++) { for (let i = 1; i <= 12; i++) {
TaskService.createTask({ TaskService.createTask({
description: `Sin dueño ${i}`, description: `Sin dueño ${i}`,
due_date: '2025-12-31', due_date: '2025-12-31',
group_id: 'test-group@g.us', group_id: 'test-group@g.us',
created_by: '9999999999', created_by: '9999999999',
}); });
} }
const responses = await CommandService.handle({ const responses = await CommandService.handle({
sender: '1234567890', sender: '1234567890',
groupId: 'test-group@g.us', groupId: 'test-group@g.us',
mentions: [], mentions: [],
message: '/t ver todos' message: '/t ver todos'
}); });
expect(responses.length).toBe(1); expect(responses.length).toBe(1);
const msg = responses[0].message; const msg = responses[0].message;
expect(msg).toContain('Tus tareas'); expect(msg).toContain('Tus tareas');
expect(msg).toContain('Test Group'); expect(msg).toContain('Test Group');
expect(msg).toContain('sin responsable'); expect(msg).toContain('🙅');
expect(msg).toContain('… y 2 más'); // paginación en la sección “sin dueño” expect(msg).toContain('… y 2 más'); // paginación en la sección “sin dueño”
}); });
test('ver todos por DM: “Tus tareas” + nota instructiva para ver sin dueño desde el grupo', async () => { test('ver todos por DM: “Tus tareas” + nota instructiva para ver sin dueño desde el grupo', async () => {
// 2 tareas asignadas al usuario en cualquier grupo (no importa para este test) // 2 tareas asignadas al usuario en cualquier grupo (no importa para este test)
TaskService.createTask({ TaskService.createTask({
description: 'Mi Tarea A', description: 'Mi Tarea A',
due_date: '2025-11-20', due_date: '2025-11-20',
group_id: 'group-1@g.us', group_id: 'group-1@g.us',
created_by: '1111111111', created_by: '1111111111',
}, [{ user_id: '1234567890', assigned_by: '1111111111' }]); }, [{ user_id: '1234567890', assigned_by: '1111111111' }]);
TaskService.createTask({ TaskService.createTask({
description: 'Mi Tarea B', description: 'Mi Tarea B',
due_date: '2025-11-21', due_date: '2025-11-21',
group_id: 'group-2@g.us', group_id: 'group-2@g.us',
created_by: '1111111111', created_by: '1111111111',
}, [{ user_id: '1234567890', assigned_by: '1111111111' }]); }, [{ user_id: '1234567890', assigned_by: '1111111111' }]);
const responses = await CommandService.handle({ const responses = await CommandService.handle({
sender: '1234567890', sender: '1234567890',
groupId: '1234567890@s.whatsapp.net', // DM groupId: '1234567890@s.whatsapp.net', // DM
mentions: [], mentions: [],
message: '/t ver todos' message: '/t ver todos'
}); });
expect(responses.length).toBe(1); expect(responses.length).toBe(1);
const msg = responses[0].message; const msg = responses[0].message;
expect(msg).toContain('Tus tareas'); expect(msg).toContain('Tus tareas');
expect(msg).toContain(' Para ver tareas sin responsable'); expect(msg).toContain(' Para ver tareas sin responsable');
}); });
afterEach(() => { afterEach(() => {
try { memDb.close(); } catch {} try { memDb.close(); } catch { }
}); });
describe('CommandService', () => { describe('CommandService', () => {
test('should ignore non-tarea commands', async () => { test('should ignore non-tarea commands', async () => {
const responses = await CommandService.handle({ const responses = await CommandService.handle({
...testContextBase, ...testContextBase,
message: '/othercommand' message: '/othercommand'
}); });
expect(responses).toEqual([]); expect(responses).toEqual([]);
}); });
test('acepta alias /t y responde con formato compacto', async () => { test('acepta alias /t y responde con formato compacto', async () => {
const responses = await CommandService.handle({ const responses = await CommandService.handle({
...testContextBase, ...testContextBase,
message: '/t n Test task' message: '/t n Test task'
}); });
expect(responses.length).toBe(1); expect(responses.length).toBe(1);
expect(responses[0].recipient).toBe('1234567890'); expect(responses[0].recipient).toBe('1234567890');
// Debe empezar con "📝 `0001` " // Debe empezar con "📝 `0001` "
expect(responses[0].message).toMatch(/^📝 `\d{4}` /); expect(responses[0].message).toMatch(/^📝 `\d{4}` /);
// Debe mostrar la descripción en texto plano (sin cursiva) // Debe mostrar la descripción en texto plano (sin cursiva)
expect(responses[0].message).toContain(' Test task'); expect(responses[0].message).toContain(' Test task');
expect(responses[0].message).not.toContain('_Test task_'); expect(responses[0].message).not.toContain('_Test task_');
// No debe usar el texto antiguo "Tarea <id> creada" // No debe usar el texto antiguo "Tarea <id> creada"
expect(responses[0].message).not.toMatch(/Tarea \d+ creada/); expect(responses[0].message).not.toMatch(/Tarea \d+ creada/);
}); });
test('should return error response on failure', async () => { test('should return error response on failure', async () => {
// Forzar error temporalmente // Forzar error temporalmente
const original = TaskService.createTask; const original = TaskService.createTask;
(TaskService as any).createTask = () => { throw new Error('forced'); }; (TaskService as any).createTask = () => { throw new Error('forced'); };
const responses = await CommandService.handle({ const responses = await CommandService.handle({
...testContextBase, ...testContextBase,
message: '/tarea nueva Test task' message: '/tarea nueva Test task'
}); });
expect(responses.length).toBe(1); expect(responses.length).toBe(1);
expect(responses[0].recipient).toBe('1234567890'); expect(responses[0].recipient).toBe('1234567890');
expect(responses[0].message).toBe('Error processing command'); expect(responses[0].message).toBe('Error processing command');
// Restaurar // Restaurar
(TaskService as any).createTask = original; (TaskService as any).createTask = original;
}); });
}); });

Loading…
Cancel
Save