import { GoogleGenAI } from '@google/genai' import * as fs from 'fs' import * as path from 'path' import { analyzeWithGemini } from '../gemini-analyzer' import { convertGifToVideo } from '../gif-converter' // Mock dependencies jest.mock('@google/genai') jest.mock('fs') jest.mock('../gif-converter') const EXAMPLE_GIF = path.join(__dirname, 'example.gif') const EXAMPLE_MP4 = path.join(__dirname, 'example.mp4') const EXAMPLE_PNG = path.join(__dirname, 'example.png') const TEST_API_KEY = 'test-api-key' describe('Gemini Analyzer', () => { beforeEach(() => { jest.clearAllMocks() }) it('should throw error if API key is not provided', async () => { await expect( analyzeWithGemini(EXAMPLE_GIF, 'gemini-2.0-flash', '') ).rejects.toThrow('No API key provided') }) it('should handle GIF files by converting to video', async () => { const mockMp4Path = '/tmp/converted-video.mp4' const mockMp4Buffer = Buffer.from('test video data') const mockConvertGifToVideo = convertGifToVideo as jest.Mock mockConvertGifToVideo.mockResolvedValue(mockMp4Path) const mockReadFileSync = fs.readFileSync as jest.Mock mockReadFileSync.mockReturnValue(mockMp4Buffer) const mockGenerateContent = jest .fn() .mockResolvedValue({ text: 'Test description' }) ;(GoogleGenAI as jest.Mock).mockImplementation(() => ({ models: { generateContent: mockGenerateContent }, })) const result = await analyzeWithGemini( EXAMPLE_GIF, 'gemini-2.0-flash', TEST_API_KEY ) expect(mockConvertGifToVideo).toHaveBeenCalledWith(EXAMPLE_GIF) expect(mockReadFileSync).toHaveBeenCalledWith(mockMp4Path) expect(mockGenerateContent).toHaveBeenCalledWith({ model: 'gemini-2.0-flash', contents: [ { parts: [ { inlineData: { mimeType: 'video/mp4', data: mockMp4Buffer.toString('base64'), }, }, { text: expect.any(String), }, ], }, ], }) expect(result).toBe('Test description') }) it('should handle regular image files (png)', async () => { const mockFileBuffer = Buffer.from('test image data') const mockReadFileSync = fs.readFileSync as jest.Mock mockReadFileSync.mockReturnValue(mockFileBuffer) const mockGenerateContent = jest .fn() .mockResolvedValue({ text: 'Test description' }) ;(GoogleGenAI as jest.Mock).mockImplementation(() => ({ models: { generateContent: mockGenerateContent }, })) const result = await analyzeWithGemini( EXAMPLE_PNG, 'gemini-2.0-flash', TEST_API_KEY ) expect(mockReadFileSync).toHaveBeenCalledWith(EXAMPLE_PNG) expect(mockGenerateContent).toHaveBeenCalledWith({ model: 'gemini-2.0-flash', contents: [ { parts: [ { inlineData: { mimeType: 'image/png', data: mockFileBuffer.toString('base64'), }, }, { text: expect.any(String), }, ], }, ], }) expect(result).toBe('Test description') }) it('should handle mp4 files', async () => { const mockFileBuffer = Buffer.from('test video data') const mockReadFileSync = fs.readFileSync as jest.Mock mockReadFileSync.mockReturnValue(mockFileBuffer) const mockGenerateContent = jest .fn() .mockResolvedValue({ text: 'Test description' }) ;(GoogleGenAI as jest.Mock).mockImplementation(() => ({ models: { generateContent: mockGenerateContent }, })) const result = await analyzeWithGemini( EXAMPLE_MP4, 'gemini-2.0-flash', TEST_API_KEY ) expect(mockReadFileSync).toHaveBeenCalledWith(EXAMPLE_MP4) expect(mockGenerateContent).toHaveBeenCalledWith({ model: 'gemini-2.0-flash', contents: [ { parts: [ { inlineData: { mimeType: 'video/mp4', data: mockFileBuffer.toString('base64'), }, }, { text: expect.any(String), }, ], }, ], }) expect(result).toBe('Test description') }) it('should handle API errors', async () => { const mockFileBuffer = Buffer.from('test image data') const mockReadFileSync = fs.readFileSync as jest.Mock mockReadFileSync.mockReturnValue(mockFileBuffer) const mockGenerateContent = jest .fn() .mockRejectedValue(new Error('API Error')) ;(GoogleGenAI as jest.Mock).mockImplementation(() => ({ models: { generateContent: mockGenerateContent }, })) await expect( analyzeWithGemini(EXAMPLE_PNG, 'gemini-2.0-flash', TEST_API_KEY) ).rejects.toThrow('API Error') }) })