feat: añadir /admin ver todos para listar tareas activas globales
Co-authored-by: aider (openrouter/openai/gpt-5) <aider@aider.chat>main
parent
1d7c1e2f1d
commit
c912ee362e
@ -0,0 +1,77 @@
|
||||
import Database from 'bun:sqlite';
|
||||
import { initializeDatabase, ensureUserExists } from '../../../src/db';
|
||||
import { AdminService } from '../../../src/services/admin';
|
||||
import { TaskService } from '../../../src/tasks/service';
|
||||
|
||||
describe('AdminService - /admin ver todos', () => {
|
||||
let memdb: Database;
|
||||
const ADMIN = '34600123456';
|
||||
const OTHER = '34999999999';
|
||||
|
||||
beforeEach(() => {
|
||||
process.env.NODE_ENV = 'test';
|
||||
process.env.GROUP_GATING_MODE = 'off';
|
||||
process.env.ADMIN_USERS = ADMIN;
|
||||
|
||||
memdb = new Database(':memory:');
|
||||
initializeDatabase(memdb);
|
||||
(AdminService as any).dbInstance = memdb;
|
||||
(TaskService as any).dbInstance = memdb;
|
||||
|
||||
// seed groups
|
||||
memdb.prepare(`
|
||||
INSERT INTO groups (id, community_id, name, active, last_verified)
|
||||
VALUES ('g1@g.us', 'comm', 'Grupo Uno', 1, strftime('%Y-%m-%d %H:%M:%f','now'))
|
||||
`).run();
|
||||
memdb.prepare(`
|
||||
INSERT INTO groups (id, community_id, name, active, last_verified)
|
||||
VALUES ('g2@g.us', 'comm', 'Grupo Dos', 1, strftime('%Y-%m-%d %H:%M:%f','now'))
|
||||
`).run();
|
||||
|
||||
// seed tasks
|
||||
const creator = ensureUserExists(ADMIN, memdb)!;
|
||||
TaskService.createTask({ description: 'Alpha', due_date: '2025-10-10', group_id: 'g1@g.us', created_by: creator }, []);
|
||||
TaskService.createTask({ description: 'Beta', due_date: '2025-10-05', group_id: 'g2@g.us', created_by: creator }, []);
|
||||
TaskService.createTask({ description: 'Gamma', due_date: null, group_id: 'g1@g.us', created_by: creator }, []);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
try { memdb.close(); } catch {}
|
||||
});
|
||||
|
||||
it('lista todas las tareas activas y responde por DM al admin', async () => {
|
||||
const res = await AdminService.handle({
|
||||
sender: ADMIN,
|
||||
groupId: 'g1@g.us',
|
||||
message: '/admin ver todos'
|
||||
});
|
||||
expect(res.length).toBe(1);
|
||||
expect(res[0].recipient).toBe(ADMIN);
|
||||
expect(res[0].message).toContain('Tareas activas');
|
||||
expect(res[0].message).toContain('Alpha');
|
||||
expect(res[0].message).toContain('Beta');
|
||||
expect(res[0].message).toContain('Gamma');
|
||||
});
|
||||
|
||||
it('respeta un límite numérico y menciona truncado cuando aplica', async () => {
|
||||
const res = await AdminService.handle({
|
||||
sender: ADMIN,
|
||||
groupId: 'g1@g.us',
|
||||
message: '/admin ver todos 2'
|
||||
});
|
||||
expect(res.length).toBe(1);
|
||||
expect(res[0].recipient).toBe(ADMIN);
|
||||
expect(res[0].message).toContain('mostrando 2');
|
||||
});
|
||||
|
||||
it('rechaza usuarios no autorizados', async () => {
|
||||
process.env.ADMIN_USERS = ADMIN; // sigue igual, pero probamos otro sender
|
||||
const res = await AdminService.handle({
|
||||
sender: OTHER,
|
||||
groupId: 'g1@g.us',
|
||||
message: '/admin ver todos'
|
||||
});
|
||||
expect(res.length).toBe(1);
|
||||
expect(res[0].message).toContain('No estás autorizado');
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,63 @@
|
||||
import Database from 'bun:sqlite';
|
||||
import { initializeDatabase, ensureUserExists } from '../../../src/db';
|
||||
import { TaskService } from '../../../src/tasks/service';
|
||||
|
||||
describe('TaskService - listAllActive', () => {
|
||||
let memdb: Database;
|
||||
|
||||
beforeEach(() => {
|
||||
process.env.NODE_ENV = 'test';
|
||||
process.env.GROUP_GATING_MODE = 'off';
|
||||
memdb = new Database(':memory:');
|
||||
initializeDatabase(memdb);
|
||||
(TaskService as any).dbInstance = memdb;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
try { memdb.close(); } catch {}
|
||||
});
|
||||
|
||||
function seedGroup(id: string, name: string = 'Group') {
|
||||
memdb.prepare(`
|
||||
INSERT INTO groups (id, community_id, name, active, last_verified)
|
||||
VALUES (?, 'comm-1', ?, 1, strftime('%Y-%m-%d %H:%M:%f','now'))
|
||||
`).run(id, name);
|
||||
}
|
||||
|
||||
function createTask(desc: string, due: string | null, groupId: string | null, creator: string) {
|
||||
const ensured = ensureUserExists(creator, memdb)!;
|
||||
return TaskService.createTask(
|
||||
{ description: desc, due_date: due, group_id: groupId, created_by: ensured },
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
it('devuelve solo tareas activas en orden por due_date (NULL al final)', () => {
|
||||
seedGroup('g1@g.us', 'G1');
|
||||
seedGroup('g2@g.us', 'G2');
|
||||
|
||||
const c = '34600123456';
|
||||
const t1 = createTask('Tarea A', '2025-10-10', 'g1@g.us', c);
|
||||
const t2 = createTask('Tarea B', '2025-10-05', 'g2@g.us', c);
|
||||
const t3 = createTask('Tarea C', null, 'g1@g.us', c);
|
||||
const t4 = createTask('Tarea D', '2025-10-01', 'g2@g.us', c);
|
||||
|
||||
// Completar una de ellas para que no aparezca
|
||||
TaskService.completeTask(t4, c);
|
||||
|
||||
const rows = TaskService.listAllActive(10);
|
||||
expect(rows.map(r => r.description)).toEqual(['Tarea B', 'Tarea A', 'Tarea C']);
|
||||
expect(TaskService.countAllActive()).toBe(3);
|
||||
});
|
||||
|
||||
it('respeta el límite indicado', () => {
|
||||
seedGroup('g1@g.us', 'G1');
|
||||
const c = '34600123456';
|
||||
createTask('Tarea 1', '2025-10-02', 'g1@g.us', c);
|
||||
createTask('Tarea 2', '2025-10-03', 'g1@g.us', c);
|
||||
createTask('Tarea 3', '2025-10-04', 'g1@g.us', c);
|
||||
|
||||
const rows = TaskService.listAllActive(2);
|
||||
expect(rows.length).toBe(2);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue