UNPKG

@rolme/ytscript

Version:

A CLI tool to download YouTube transcripts and generate summaries

105 lines (104 loc) 4.59 kB
import { describe, it, expect, vi, beforeEach } from 'vitest'; import { ChatGPTProvider } from '../../../../services/providers/chatgpt.js'; import { AIError } from '../../../../types/ai.js'; describe('ChatGPTProvider', () => { let provider; beforeEach(() => { provider = new ChatGPTProvider('test-openai-key'); vi.clearAllMocks(); global.fetch = vi.fn(); }); describe('initialization', () => { it('should create instance with API key', () => { expect(provider).toBeInstanceOf(ChatGPTProvider); expect(provider.name).toBe('chatgpt'); }); it('should throw error if API key is missing', () => { expect(() => new ChatGPTProvider('')).toThrow('OpenAI API key is required'); }); }); describe('summarize', () => { const mockTranscript = 'Sample transcript for summarization'; const mockResponse = { choices: [ { message: { content: 'Generated summary of the video' } } ] }; it('should generate summary successfully with default options', async () => { global.fetch = vi.fn().mockResolvedValue({ ok: true, json: () => Promise.resolve(mockResponse) }); const result = await provider.summarize(mockTranscript); expect(result).toBe(mockResponse.choices[0].message.content); expect(global.fetch).toHaveBeenCalledWith('https://api.openai.com/v1/chat/completions', expect.objectContaining({ method: 'POST', headers: { 'Authorization': 'Bearer test-openai-key', 'Content-Type': 'application/json', }, body: expect.stringContaining('concise') })); }); it('should use provided style and length options', async () => { global.fetch = vi.fn().mockResolvedValue({ ok: true, json: () => Promise.resolve(mockResponse) }); await provider.summarize(mockTranscript, { style: 'detailed', maxLength: 1000 }); const requestBody = JSON.parse(global.fetch.mock.calls[0][1].body); expect(requestBody.messages[1].content).toContain('detailed'); expect(requestBody.messages[1].content).toContain('1000'); }); it('should handle API errors gracefully', async () => { global.fetch = vi.fn().mockResolvedValue({ ok: false, statusText: 'Rate limit exceeded' }); await expect(provider.summarize(mockTranscript)).rejects.toThrow(AIError); }); it('should handle network errors', async () => { global.fetch = vi.fn().mockRejectedValue(new Error('Network Error')); await expect(provider.summarize(mockTranscript)).rejects.toThrow(AIError); }); it('should handle invalid API response', async () => { global.fetch = vi.fn().mockResolvedValue({ ok: true, json: () => Promise.resolve({ choices: [] }) }); await expect(provider.summarize(mockTranscript)).rejects.toThrow('Invalid response from OpenAI API'); }); it('should include system message in API request', async () => { global.fetch = vi.fn().mockResolvedValue({ ok: true, json: () => Promise.resolve(mockResponse) }); await provider.summarize(mockTranscript); const requestBody = JSON.parse(global.fetch.mock.calls[0][1].body); expect(requestBody.messages[0]).toEqual({ role: 'system', content: 'You are a helpful assistant that summarizes video transcripts accurately and concisely.' }); }); it('should use correct model and parameters', async () => { global.fetch = vi.fn().mockResolvedValue({ ok: true, json: () => Promise.resolve(mockResponse) }); await provider.summarize(mockTranscript); const requestBody = JSON.parse(global.fetch.mock.calls[0][1].body); expect(requestBody).toEqual(expect.objectContaining({ model: 'gpt-4-turbo-preview', temperature: 0.3, max_tokens: 500 })); }); }); });