|
|
|
@ -1,13 +1,36 @@
|
|
|
|
import { describe, test, expect, beforeEach, afterEach, mock } from 'bun:test';
|
|
|
|
import { describe, test, expect, beforeEach, afterEach, beforeAll, afterAll } from 'bun:test';
|
|
|
|
|
|
|
|
import { Database } from 'bun:sqlite';
|
|
|
|
import { WebhookServer } from '../../src/server';
|
|
|
|
import { WebhookServer } from '../../src/server';
|
|
|
|
import { ResponseQueue } from '../../src/services/response-queue';
|
|
|
|
import { ResponseQueue } from '../../src/services/response-queue';
|
|
|
|
|
|
|
|
import { initializeDatabase } from '../../src/db';
|
|
|
|
|
|
|
|
|
|
|
|
// Mock the ResponseQueue
|
|
|
|
// Mock the ResponseQueue
|
|
|
|
let mockAdd: any;
|
|
|
|
let mockAdd: any;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Test database instance
|
|
|
|
|
|
|
|
let testDb: Database;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
beforeAll(() => {
|
|
|
|
|
|
|
|
// Create in-memory test database
|
|
|
|
|
|
|
|
testDb = new Database(':memory:');
|
|
|
|
|
|
|
|
// Initialize schema
|
|
|
|
|
|
|
|
initializeDatabase(testDb);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
afterAll(() => {
|
|
|
|
|
|
|
|
// Close the test database
|
|
|
|
|
|
|
|
testDb.close();
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
beforeEach(() => {
|
|
|
|
mockAdd = mock(() => Promise.resolve());
|
|
|
|
mockAdd = mock(() => Promise.resolve());
|
|
|
|
ResponseQueue.add = mockAdd;
|
|
|
|
ResponseQueue.add = mockAdd;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Reset database state between tests
|
|
|
|
|
|
|
|
testDb.exec('DELETE FROM task_assignments');
|
|
|
|
|
|
|
|
testDb.exec('DELETE FROM tasks');
|
|
|
|
|
|
|
|
testDb.exec('DELETE FROM users');
|
|
|
|
|
|
|
|
testDb.exec('DELETE FROM groups');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
describe('WebhookServer', () => {
|
|
|
|
describe('WebhookServer', () => {
|
|
|
|
@ -499,6 +522,11 @@ describe('WebhookServer', () => {
|
|
|
|
const response = await WebhookServer.handleRequest(request);
|
|
|
|
const response = await WebhookServer.handleRequest(request);
|
|
|
|
expect(response.status).toBe(200);
|
|
|
|
expect(response.status).toBe(200);
|
|
|
|
expect(mockAdd).toHaveBeenCalled();
|
|
|
|
expect(mockAdd).toHaveBeenCalled();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Verify user was created in real database
|
|
|
|
|
|
|
|
const user = testDb.query("SELECT * FROM users WHERE id = ?").get('1234567890');
|
|
|
|
|
|
|
|
expect(user).toBeDefined();
|
|
|
|
|
|
|
|
expect(user.id).toBe('1234567890');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test('should ignore messages if user creation fails', async () => {
|
|
|
|
test('should ignore messages if user creation fails', async () => {
|
|
|
|
@ -517,36 +545,15 @@ describe('WebhookServer', () => {
|
|
|
|
const response = await WebhookServer.handleRequest(request);
|
|
|
|
const response = await WebhookServer.handleRequest(request);
|
|
|
|
expect(response.status).toBe(200);
|
|
|
|
expect(response.status).toBe(200);
|
|
|
|
expect(mockAdd).not.toHaveBeenCalled();
|
|
|
|
expect(mockAdd).not.toHaveBeenCalled();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Verify no user was created
|
|
|
|
|
|
|
|
const userCount = testDb.query("SELECT COUNT(*) as count FROM users").get();
|
|
|
|
|
|
|
|
expect(userCount.count).toBe(0);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// New tests for user validation
|
|
|
|
// Integration tests with real database
|
|
|
|
describe('User validation in handleMessageUpsert', () => {
|
|
|
|
describe('User validation in handleMessageUpsert', () => {
|
|
|
|
let mockEnsureUserExists: any;
|
|
|
|
|
|
|
|
let consoleSpy: any;
|
|
|
|
|
|
|
|
let originalConsoleLog: any;
|
|
|
|
|
|
|
|
let originalEnsureUserExists: any;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
beforeEach(async () => {
|
|
|
|
|
|
|
|
// Import the db module dynamically to mock ensureUserExists locally
|
|
|
|
|
|
|
|
const dbModule = await import('../../src/db');
|
|
|
|
|
|
|
|
originalEnsureUserExists = dbModule.ensureUserExists;
|
|
|
|
|
|
|
|
mockEnsureUserExists = mock(() => '1234567890');
|
|
|
|
|
|
|
|
dbModule.ensureUserExists = mockEnsureUserExists;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
originalConsoleLog = console.log;
|
|
|
|
|
|
|
|
consoleSpy = mock(() => {});
|
|
|
|
|
|
|
|
console.log = consoleSpy;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
afterEach(async () => {
|
|
|
|
|
|
|
|
// Restore the original functions manually
|
|
|
|
|
|
|
|
const dbModule = await import('../../src/db');
|
|
|
|
|
|
|
|
dbModule.ensureUserExists = originalEnsureUserExists;
|
|
|
|
|
|
|
|
console.log = originalConsoleLog;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
test('should proceed with valid user', async () => {
|
|
|
|
test('should proceed with valid user', async () => {
|
|
|
|
mockEnsureUserExists.mockReturnValue('1234567890');
|
|
|
|
|
|
|
|
const payload = {
|
|
|
|
const payload = {
|
|
|
|
event: 'messages.upsert',
|
|
|
|
event: 'messages.upsert',
|
|
|
|
instance: 'test-instance',
|
|
|
|
instance: 'test-instance',
|
|
|
|
@ -561,12 +568,15 @@ describe('WebhookServer', () => {
|
|
|
|
const request = createTestRequest(payload);
|
|
|
|
const request = createTestRequest(payload);
|
|
|
|
const response = await WebhookServer.handleRequest(request);
|
|
|
|
const response = await WebhookServer.handleRequest(request);
|
|
|
|
expect(response.status).toBe(200);
|
|
|
|
expect(response.status).toBe(200);
|
|
|
|
expect(mockEnsureUserExists).toHaveBeenCalledWith('1234567890@s.whatsapp.net');
|
|
|
|
|
|
|
|
expect(mockAdd).toHaveBeenCalled();
|
|
|
|
expect(mockAdd).toHaveBeenCalled();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Verify user was created in real database
|
|
|
|
|
|
|
|
const user = testDb.query("SELECT * FROM users WHERE id = ?").get('1234567890');
|
|
|
|
|
|
|
|
expect(user).toBeDefined();
|
|
|
|
|
|
|
|
expect(user.id).toBe('1234567890');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test('should ignore message if user validation fails', async () => {
|
|
|
|
test('should ignore message if user validation fails', async () => {
|
|
|
|
mockEnsureUserExists.mockReturnValue(null);
|
|
|
|
|
|
|
|
const payload = {
|
|
|
|
const payload = {
|
|
|
|
event: 'messages.upsert',
|
|
|
|
event: 'messages.upsert',
|
|
|
|
instance: 'test-instance',
|
|
|
|
instance: 'test-instance',
|
|
|
|
@ -581,13 +591,17 @@ describe('WebhookServer', () => {
|
|
|
|
const request = createTestRequest(payload);
|
|
|
|
const request = createTestRequest(payload);
|
|
|
|
const response = await WebhookServer.handleRequest(request);
|
|
|
|
const response = await WebhookServer.handleRequest(request);
|
|
|
|
expect(response.status).toBe(200);
|
|
|
|
expect(response.status).toBe(200);
|
|
|
|
expect(mockEnsureUserExists).toHaveBeenCalledWith('invalid-user@s.whatsapp.net');
|
|
|
|
|
|
|
|
expect(mockAdd).not.toHaveBeenCalled();
|
|
|
|
expect(mockAdd).not.toHaveBeenCalled();
|
|
|
|
expect(consoleSpy).toHaveBeenCalledWith('⚠️ Failed to ensure user exists, ignoring message');
|
|
|
|
|
|
|
|
|
|
|
|
// Verify no user was created
|
|
|
|
|
|
|
|
const userCount = testDb.query("SELECT COUNT(*) as count FROM users").get();
|
|
|
|
|
|
|
|
expect(userCount.count).toBe(0);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test('should handle database errors during user validation', async () => {
|
|
|
|
test('should handle database errors during user validation', async () => {
|
|
|
|
mockEnsureUserExists.mockImplementation(() => { throw new Error('DB error'); });
|
|
|
|
// Force a database error by corrupting the database state
|
|
|
|
|
|
|
|
testDb.exec('DROP TABLE users');
|
|
|
|
|
|
|
|
|
|
|
|
const payload = {
|
|
|
|
const payload = {
|
|
|
|
event: 'messages.upsert',
|
|
|
|
event: 'messages.upsert',
|
|
|
|
instance: 'test-instance',
|
|
|
|
instance: 'test-instance',
|
|
|
|
@ -602,9 +616,10 @@ describe('WebhookServer', () => {
|
|
|
|
const request = createTestRequest(payload);
|
|
|
|
const request = createTestRequest(payload);
|
|
|
|
const response = await WebhookServer.handleRequest(request);
|
|
|
|
const response = await WebhookServer.handleRequest(request);
|
|
|
|
expect(response.status).toBe(200);
|
|
|
|
expect(response.status).toBe(200);
|
|
|
|
expect(mockEnsureUserExists).toHaveBeenCalledWith('1234567890@s.whatsapp.net');
|
|
|
|
|
|
|
|
expect(mockAdd).not.toHaveBeenCalled();
|
|
|
|
expect(mockAdd).not.toHaveBeenCalled();
|
|
|
|
expect(consoleSpy).toHaveBeenCalledWith('⚠️ Failed to ensure user exists, ignoring message');
|
|
|
|
|
|
|
|
|
|
|
|
// Reinitialize database for subsequent tests
|
|
|
|
|
|
|
|
initializeDatabase(testDb);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|