158 lines
5.0 KiB
TypeScript
158 lines
5.0 KiB
TypeScript
/**
|
|
* Tests for commands/config/config.ts (llmconf command)
|
|
*/
|
|
|
|
jest.mock('discord.js', () => {
|
|
const actual = jest.requireActual('discord.js');
|
|
return {
|
|
...actual,
|
|
SlashCommandBuilder: jest.fn().mockImplementation(() => ({
|
|
setName: jest.fn().mockReturnThis(),
|
|
setDescription: jest.fn().mockReturnThis(),
|
|
addNumberOption: jest.fn().mockReturnThis(),
|
|
addIntegerOption: jest.fn().mockReturnThis(),
|
|
addBooleanOption: jest.fn().mockReturnThis(),
|
|
})),
|
|
};
|
|
});
|
|
|
|
const configCommand = require('../commands/config/config');
|
|
|
|
describe('config command (llmconf)', () => {
|
|
let mockInteraction: {
|
|
user: { id: string };
|
|
options: {
|
|
getInteger: jest.Mock;
|
|
getNumber: jest.Mock;
|
|
getBoolean: jest.Mock;
|
|
};
|
|
reply: jest.Mock;
|
|
};
|
|
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
process.env.ADMIN = '123456789012345678';
|
|
// Reset config to defaults
|
|
const state = configCommand.state();
|
|
state.max_new_tokens = 1500;
|
|
state.min_new_tokens = 1;
|
|
state.temperature = 0.8;
|
|
state.top_p = 0.6;
|
|
state.msg_context = 8;
|
|
state.frequency_penalty = 0.0;
|
|
state.presence_penalty = 0.0;
|
|
state.streaming = false;
|
|
mockInteraction = {
|
|
user: { id: '123456789012345678' },
|
|
options: {
|
|
getInteger: jest.fn(),
|
|
getNumber: jest.fn(),
|
|
getBoolean: jest.fn(),
|
|
},
|
|
reply: jest.fn(),
|
|
};
|
|
});
|
|
|
|
it('should have correct command data structure', () => {
|
|
expect(configCommand.data).toBeDefined();
|
|
expect(configCommand.data.setName).toBeDefined();
|
|
expect(configCommand.execute).toBeDefined();
|
|
expect(configCommand.state).toBeDefined();
|
|
});
|
|
|
|
it('should reject non-admin users', async () => {
|
|
mockInteraction.user = { id: 'unauthorized-user' };
|
|
|
|
await configCommand.execute(mockInteraction);
|
|
|
|
expect(mockInteraction.reply).toHaveBeenCalledWith(
|
|
'You are not authorized to change model settings'
|
|
);
|
|
});
|
|
|
|
it('should accept admin users and return config', async () => {
|
|
await configCommand.execute(mockInteraction);
|
|
|
|
expect(mockInteraction.reply).toHaveBeenCalled();
|
|
const replyContent = mockInteraction.reply.mock.calls[0][0];
|
|
expect(replyContent).toContain('max_new_tokens');
|
|
expect(replyContent).toContain('temperature');
|
|
});
|
|
|
|
it('should use default values when options not provided', async () => {
|
|
mockInteraction.options.getInteger.mockReturnValue(null);
|
|
mockInteraction.options.getNumber.mockReturnValue(null);
|
|
|
|
await configCommand.execute(mockInteraction);
|
|
|
|
expect(mockInteraction.reply).toHaveBeenCalled();
|
|
});
|
|
|
|
it('should accept custom temperature value', async () => {
|
|
mockInteraction.options.getNumber.mockImplementation((name: string) => {
|
|
if (name === 'temperature') return 0.9;
|
|
return null;
|
|
});
|
|
|
|
await configCommand.execute(mockInteraction);
|
|
|
|
const state = configCommand.state();
|
|
expect(state.temperature).toBe(0.9);
|
|
});
|
|
|
|
it('should accept custom msg_context value', async () => {
|
|
mockInteraction.options.getInteger.mockImplementation((name: string) => {
|
|
if (name === 'msg_context') return 16;
|
|
return null;
|
|
});
|
|
|
|
await configCommand.execute(mockInteraction);
|
|
|
|
const state = configCommand.state();
|
|
expect(state.msg_context).toBe(16);
|
|
});
|
|
|
|
it('should accept custom streaming value (true)', async () => {
|
|
mockInteraction.options.getBoolean.mockImplementation((name: string) => {
|
|
if (name === 'streaming') return true;
|
|
return null;
|
|
});
|
|
|
|
await configCommand.execute(mockInteraction);
|
|
|
|
const state = configCommand.state();
|
|
expect(state.streaming).toBe(true);
|
|
});
|
|
|
|
it('should accept custom streaming value (false)', async () => {
|
|
mockInteraction.options.getBoolean.mockImplementation((name: string) => {
|
|
if (name === 'streaming') return false;
|
|
return null;
|
|
});
|
|
|
|
await configCommand.execute(mockInteraction);
|
|
|
|
const state = configCommand.state();
|
|
expect(state.streaming).toBe(false);
|
|
});
|
|
|
|
it('should use default streaming value when not provided', async () => {
|
|
mockInteraction.options.getBoolean.mockReturnValue(null);
|
|
|
|
await configCommand.execute(mockInteraction);
|
|
|
|
const state = configCommand.state();
|
|
expect(state.streaming).toBe(false);
|
|
});
|
|
|
|
it('should include streaming in config output', async () => {
|
|
mockInteraction.options.getBoolean.mockReturnValue(null);
|
|
|
|
await configCommand.execute(mockInteraction);
|
|
|
|
expect(mockInteraction.reply).toHaveBeenCalled();
|
|
const replyContent = mockInteraction.reply.mock.calls[0][0];
|
|
expect(replyContent).toContain('streaming =');
|
|
});
|
|
});
|