You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
taskbot/tests/unit/server.command-logging.test.ts

229 lines
6.8 KiB
TypeScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* Command logging and datehandling tests.
*
* Covers tarea command logging, date parsing edge cases, XSS/SQL
* injection resilience, and sender ID normalization.
*/
import { describe, test, expect } from 'bun:test';
import { WebhookServer } from '../../src/server';
import { SimulatedResponseQueue } from '../helpers/queue';
import { createTestRequest, getFutureDate, registerServerTestLifecycle } from '../helpers/server-test-harness';
const testDb = registerServerTestLifecycle();
// ── Tests ──────────────────────────────────────────────────────────────
describe('tarea command logging', () => {
test('should log basic tarea command', async () => {
const payload = {
event: 'messages.upsert',
instance: 'test-instance',
data: {
key: {
remoteJid: 'group-id@g.us',
participant: 'user123@s.whatsapp.net',
},
message: { conversation: 'tarea test' },
},
};
await WebhookServer.handleRequest(createTestRequest(payload));
expect(SimulatedResponseQueue.get().length).toBeGreaterThan(0);
});
test('should log command with due date', async () => {
const futureDate = getFutureDate(3);
const payload = {
event: 'messages.upsert',
instance: 'test-instance',
data: {
key: {
remoteJid: 'group-id@g.us',
participant: 'user123@s.whatsapp.net',
},
message: {
conversation: `tarea nueva Finish project @user2 ${futureDate}`,
contextInfo: {
mentionedJid: ['user2@s.whatsapp.net'],
},
},
},
};
await WebhookServer.handleRequest(createTestRequest(payload));
expect(SimulatedResponseQueue.get().length).toBeGreaterThan(0);
});
});
describe('WebhookServer — Date handling & edge cases', () => {
test('should handle XSS/SQL injection attempts', async () => {
const maliciousMessage = `tarea nueva <script>alert('xss')</script>'; DROP TABLE tasks; --`;
const payload = {
event: 'messages.upsert',
instance: 'test-instance',
data: {
key: {
remoteJid: 'group-id@g.us',
participant: 'sender-id@s.whatsapp.net',
},
message: { conversation: maliciousMessage },
},
};
const request = createTestRequest(payload);
const response = await WebhookServer.handleRequest(request);
expect(response.status).toBe(200);
expect(SimulatedResponseQueue.get().length).toBeGreaterThan(0);
});
test('should handle multiple dates in command (use last one as due date)', async () => {
const futureDate1 = getFutureDate(3);
const futureDate2 = getFutureDate(5);
const payload = {
event: 'messages.upsert',
instance: 'test-instance',
data: {
key: {
remoteJid: 'group-id@g.us',
participant: 'sender-id@s.whatsapp.net',
},
message: { conversation: `tarea nueva Test task ${futureDate1} some text ${futureDate2}` },
},
};
await WebhookServer.handleRequest(createTestRequest(payload));
expect(SimulatedResponseQueue.get().length).toBeGreaterThan(0);
});
test('should ignore past dates as due dates', async () => {
const pastDate = '2020-01-01';
const payload = {
event: 'messages.upsert',
instance: 'test-instance',
data: {
key: {
remoteJid: 'group-id@g.us',
participant: 'sender-id@s.whatsapp.net',
},
message: { conversation: `tarea nueva Old task ${pastDate}` },
},
};
await WebhookServer.handleRequest(createTestRequest(payload));
expect(SimulatedResponseQueue.get().length).toBeGreaterThan(0);
});
test('should handle multiple past dates correctly', async () => {
const payload = {
event: 'messages.upsert',
instance: 'test-instance',
data: {
key: {
remoteJid: 'group-id@g.us',
participant: 'sender-id@s.whatsapp.net',
},
message: { conversation: 'tarea nueva Test 2020-01-01 2020-02-01' },
},
};
await WebhookServer.handleRequest(createTestRequest(payload));
expect(SimulatedResponseQueue.get().length).toBeGreaterThan(0);
});
test('should handle mixed valid and invalid date formats', async () => {
const futureDate = getFutureDate(3);
const payload = {
event: 'messages.upsert',
instance: 'test-instance',
data: {
key: {
remoteJid: 'group-id@g.us',
participant: 'sender-id@s.whatsapp.net',
},
message: { conversation: `tarea nueva Test invalid-date ${futureDate} another-bad` },
},
};
await WebhookServer.handleRequest(createTestRequest(payload));
expect(SimulatedResponseQueue.get().length).toBeGreaterThan(0);
});
test('should normalize sender ID before processing', async () => {
const payload = {
event: 'messages.upsert',
instance: 'test-instance',
data: {
key: {
remoteJid: 'group-id@g.us',
participant: 'sender-id:12@s.whatsapp.net',
},
message: { conversation: 'tarea nueva Test' },
},
};
const request = createTestRequest(payload);
const response = await WebhookServer.handleRequest(request);
expect(response.status).toBe(200);
expect(SimulatedResponseQueue.get().length).toBeGreaterThan(0);
});
test('should ignore messages with invalid sender ID', async () => {
const payload = {
event: 'messages.upsert',
instance: 'test-instance',
data: {
key: {
remoteJid: 'group-id@g.us',
participant: 'invalid!@#$',
},
message: { conversation: 'tarea nueva Test' },
},
};
const request = createTestRequest(payload);
const response = await WebhookServer.handleRequest(request);
expect(response.status).toBe(200);
expect(SimulatedResponseQueue.get().length).toBe(0);
});
test('should ensure user exists and use normalized ID', async () => {
const payload = {
event: 'messages.upsert',
instance: 'test-instance',
data: {
key: {
remoteJid: 'group-id@g.us',
participant: '1234567890@s.whatsapp.net',
},
message: { conversation: 'tarea nueva Test user' },
},
};
const request = createTestRequest(payload);
const response = await WebhookServer.handleRequest(request);
expect(response.status).toBe(200);
expect(SimulatedResponseQueue.get().length).toBeGreaterThan(0);
const user = testDb.query('SELECT * FROM users WHERE id = ?').get('1234567890');
expect(user).toBeDefined();
expect((user as any).id).toBe('1234567890');
});
test('should ignore messages if user creation fails', async () => {
const payload = {
event: 'messages.upsert',
instance: 'test-instance',
data: {
key: {
remoteJid: 'group-id@g.us',
participant: 'invalid!user@s.whatsapp.net',
},
message: { conversation: 'tarea nueva Test' },
},
};
const request = createTestRequest(payload);
const response = await WebhookServer.handleRequest(request);
expect(response.status).toBe(200);
expect(SimulatedResponseQueue.get().length).toBe(0);
const userCount = testDb.query('SELECT COUNT(*) as count FROM users').get();
expect((userCount as any).count).toBe(0);
});
});