import { Test, TestingModule } from '@nestjs/testing'; import { AIGatewayService } from '../ai-gateway.service'; describe('AIGatewayService', () => { let service: AIGatewayService; beforeEach(async () => { // Clear env before each test delete process.env.OPENAI_API_KEY; delete process.env.SENSENOVA_API_KEY; const module: TestingModule = await Test.createTestingModule({ providers: [AIGatewayService], }).compile(); service = module.get(AIGatewayService); }); describe('initialization', () => { it('should have no providers when no API keys set', () => { const providers = service.getRegisteredProviders(); expect(providers).toEqual([]); }); }); describe('fallback mock responses', () => { it('should greet when asked "你好"', async () => { const result = await service.chat('any-model', [ { role: 'user', content: '你好' }, ]); expect(result).toContain('你好!我是宇之然 AI 助手'); }); it('should greet in English for "hello"', async () => { const result = await service.chat('any-model', [ { role: 'user', content: 'hello' }, ]); expect(result).toContain('Hello! I am YuZhiRan AI assistant'); }); it('should provide prompt tips when asked about 提示词', async () => { const result = await service.chat('any-model', [ { role: 'user', content: '如何写好提示词?' }, ]); expect(result).toContain('明确角色'); expect(result).toContain('输出格式'); }); it('should provide model info when asked about 大模型', async () => { const result = await service.chat('any-model', [ { role: 'user', content: '有哪些大模型?' }, ]); expect(result).toContain('GPT'); expect(result).toContain('Claude'); expect(result).toContain('DeepSeek'); }); it('should return generic fallback for unknown queries', async () => { const result = await service.chat('any-model', [ { role: 'user', content: '今天的天气怎么样?' }, ]); expect(result).toContain('模拟模式'); expect(result).toContain('API Key'); }); }); describe('model routing', () => { it('should route deepseek-v4-flash to its provider (but fallback to mock)', async () => { const result = await service.chat('deepseek-v4-flash', [ { role: 'user', content: '你好' }, ]); // Falls back to mock since no API key expect(result).toContain('宇之然 AI 助手'); }); it('should route general model to openai provider (but fallback to mock)', async () => { const result = await service.chat('general', [ { role: 'user', content: '你好' }, ]); expect(result).toContain('宇之然 AI 助手'); }); it('should handle unknown model names by falling back', async () => { const result = await service.chat('unknown-model-xyz', [ { role: 'user', content: '测试' }, ]); expect(result).toContain('模拟模式'); }); }); describe('contextual fallback', () => { it('should include user message in fallback response', async () => { const result = await service.chat('any', [ { role: 'user', content: '如何学习 Python 编程?' }, ]); expect(result).toContain('Python'); }); it('should handle multi-turn conversations', async () => { const messages = [ { role: 'user' as const, content: '你是谁?' }, { role: 'assistant' as const, content: '我是 AI 助手。' }, { role: 'user' as const, content: '提示词有什么技巧?' }, ]; const result = await service.chat('any', messages); expect(result).toContain('提示词'); }); it('should truncate long user messages', async () => { const longMsg = 'a'.repeat(200); const result = await service.chat('any', [ { role: 'user', content: longMsg }, ]); expect(result).toContain('...'); }); }); });