PRIX / src /__tests__ /bot.test.ts
Rachit-Tw's picture
Upload 169 files
9284ad7 verified
Raw
History Blame Contribute Delete
3.46 kB
import { jest, expect, describe, beforeEach, it } from '@jest/globals'
import { Bot } from '../bot'
import { Options, AIOptions } from '../options'
// Mock chatgpt module
jest.mock('chatgpt', () => ({
ChatGPTAPI: jest.fn().mockImplementation(() => ({
sendMessage: jest.fn(),
})),
ChatGPTError: class ChatGPTError extends Error {
status?: number
constructor(message: string, status?: number) {
super(message)
this.status = status
}
},
}))
describe('Bot', () => {
let options: Options
let aiOptions: AIOptions
beforeEach(() => {
jest.clearAllMocks()
options = new Options(
false, false, false, '0', false, false, null, '',
'meta-llama/llama-4-scout-17b-16e-instruct',
'llama-3.3-70b-versatile',
'0.0', '3', '120000', '1', '1',
'https://api.groq.com/openai/v1', 'en-US', false, 'minor', '0', 'false', 'true'
)
aiOptions = new AIOptions('meta-llama/llama-4-scout-17b-16e-instruct')
})
describe('constructor', () => {
it('should throw error if API key is missing', () => {
const originalKey = process.env.GROQ_API_KEY
delete process.env.GROQ_API_KEY
delete process.env.AI_API_KEY
expect(() => new Bot(options, aiOptions)).toThrow("Missing 'GROQ_API_KEY' or 'AI_API_KEY'")
process.env.GROQ_API_KEY = originalKey
})
it('should initialize with valid API key', () => {
const bot = new Bot(options, aiOptions)
expect(bot).toBeInstanceOf(Bot)
})
it('should set up fallback models for heavy models', () => {
const heavyOptions = new AIOptions('llama-3.3-70b-versatile')
const bot = new Bot(options, heavyOptions)
expect(bot).toBeInstanceOf(Bot)
})
})
describe('chat', () => {
it('should return empty response for empty message', async () => {
const bot = new Bot(options, aiOptions)
const result = await bot.chat('', {})
expect(result).toEqual(['', {}])
})
it('should handle AI errors gracefully', async () => {
const { ChatGPTAPI } = await import('chatgpt')
const mockSendMessage = jest.fn().mockRejectedValue(new Error('API Error'))
;(ChatGPTAPI as jest.Mock).mockImplementation(() => ({
sendMessage: mockSendMessage,
}))
const bot = new Bot(options, aiOptions)
const result = await bot.chat('test message', {})
expect(result[0]).toBe('') // Should return empty on error
})
it('should implement retry logic on rate limit', async () => {
const { ChatGPTAPI } = await import('chatgpt')
const mockSendMessage = jest.fn()
.mockRejectedValueOnce({ status: 429, message: 'Rate limited' })
.mockResolvedValueOnce({ text: 'Success', id: 'msg-1' })
;(ChatGPTAPI as jest.Mock).mockImplementation(() => ({
sendMessage: mockSendMessage,
}))
const bot = new Bot(options, aiOptions)
// Should switch to fallback model on 429
await bot.chat('test', {})
expect(mockSendMessage).toHaveBeenCalled()
})
})
describe('fallback chain', () => {
it('should cycle through fallback models on errors', () => {
const heavyOptions = new AIOptions('llama-3.3-70b-versatile')
const bot = new Bot(options, heavyOptions)
// Fallback chain should be initialized
expect(bot).toBeInstanceOf(Bot)
})
})
})