/** * Tests for util.ts * Tests database operations, reaction handling, and message serialization */ import { MessageReaction, User, Message, Attachment } from 'discord.js'; import { openDb, recordReaction, serializeMessageHistory, REAL_NAMES, LOSER_WHITELIST, parseRealNames, parseLoserWhitelist, } from '../util'; // Mock discord.js jest.mock('discord.js', () => { const actual = jest.requireActual('discord.js'); return { ...actual, MessageReaction: jest.fn(), User: jest.fn(), Message: jest.fn(), }; }); // Mock sqlite jest.mock('sqlite', () => ({ open: jest.fn(() => Promise.resolve({ get: jest.fn(), run: jest.fn(), all: jest.fn(), close: jest.fn(), }) ), })); jest.mock('sqlite3', () => ({ Database: jest.fn(), })); describe('util.ts', () => { beforeAll(async () => { await openDb(); }); describe('parseRealNames', () => { it('should parse REAL_NAMES from environment variable', () => { const result = parseRealNames('user1:James,user2:Vincent,user3:Myles'); expect(result).toEqual({ user1: 'James', user2: 'Vincent', user3: 'Myles', }); }); it('should return empty object when input is empty', () => { const result = parseRealNames(''); expect(result).toEqual({}); }); it('should handle whitespace in entries', () => { const result = parseRealNames(' user1:James , user2:Vincent '); expect(result).toEqual({ user1: 'James', user2: 'Vincent', }); }); it('should skip malformed entries', () => { const result = parseRealNames('user1:James,invalidEntry,user2:Vincent'); expect(result).toEqual({ user1: 'James', user2: 'Vincent', }); }); }); describe('parseLoserWhitelist', () => { it('should parse LOSER_WHITELIST from environment variable', () => { const result = parseLoserWhitelist('James,Vincent,Myles,Sam'); expect(result).toEqual(['James', 'Vincent', 'Myles', 'Sam']); }); it('should return empty array when input is empty', () => { const result = parseLoserWhitelist(''); expect(result).toEqual([]); }); it('should handle whitespace in entries', () => { const result = parseLoserWhitelist(' James , Vincent , Myles '); expect(result).toEqual(['James', 'Vincent', 'Myles']); }); }); describe('REAL_NAMES', () => { it('should contain expected username mappings', () => { expect(REAL_NAMES.vinso1445).toBe('Vincent'); expect(REAL_NAMES.scoliono).toBe('James'); expect(REAL_NAMES.gnuwu).toBe('David'); }); it('should include Hatsune Miku', () => { expect(REAL_NAMES['Hatsune Miku']).toBe('Hatsune Miku'); }); }); describe('LOSER_WHITELIST', () => { it('should contain the whitelisted first names', () => { expect(LOSER_WHITELIST).toContain('James'); expect(LOSER_WHITELIST).toContain('Vincent'); expect(LOSER_WHITELIST).toContain('Myles'); expect(LOSER_WHITELIST).toContain('Sam'); }); it('should not contain non-whitelisted names', () => { expect(LOSER_WHITELIST).not.toContain('David'); expect(LOSER_WHITELIST).not.toContain('Adam'); expect(LOSER_WHITELIST).not.toContain('Jake'); }); }); describe('serializeMessageHistory', () => { it('should return undefined for messages without content', async () => { const mockMessage = { cleanContent: '', createdAt: new Date(), author: { username: 'testuser' }, type: 0, reactions: { cache: new Map() }, } as unknown as Message; const result = await serializeMessageHistory(mockMessage); expect(result).toBeUndefined(); }); it('should serialize a valid message with content', async () => { const mockDate = new Date('2024-01-01T00:00:00Z'); const mockMessage = { cleanContent: 'Hello, world!', createdAt: mockDate, author: { username: 'testuser' }, type: 0, reactions: { cache: new Map() }, } as unknown as Message; const result = await serializeMessageHistory(mockMessage); expect(result).toBeDefined(); expect(result?.content).toBe('Hello, world!'); expect(result?.author).toBe('testuser'); expect(result?.timestamp).toBe(mockDate.toUTCString()); }); it('should include real name if available', async () => { const mockMessage = { cleanContent: 'Test message', createdAt: new Date(), author: { username: 'vinso1445' }, type: 0, reactions: { cache: new Map() }, } as unknown as Message; const result = await serializeMessageHistory(mockMessage); expect(result?.name).toBe('Vincent'); }); it('should serialize reactions', async () => { const mockReaction = { emoji: { name: '👍' }, count: 5, }; const mockMessage = { cleanContent: 'Test', createdAt: new Date(), author: { username: 'testuser' }, type: 0, reactions: { cache: new Map([['reaction1', mockReaction]]), }, } as unknown as Message; const result = await serializeMessageHistory(mockMessage); expect(result?.reactions).toBeDefined(); expect(result?.reactions).toContain(':+1:'); expect(result?.reactions).toContain('(5)'); }); }); });