194 lines
6.1 KiB
TypeScript
194 lines
6.1 KiB
TypeScript
/**
|
|
* 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)');
|
|
});
|
|
});
|
|
});
|