// @vitest-environment jsdom import { describe, it, expect, vi, beforeEach } from 'vitest'; import '@testing-library/jest-dom/vitest'; import { render, screen, fireEvent, cleanup, waitFor } from '@testing-library/react'; import React from 'react'; const { mockGet, mockSet, mockRefresh } = vi.hoisted(() => ({ mockGet: vi.fn(), mockSet: vi.fn(), mockRefresh: vi.fn() })); vi.mock('../../src/renderer/inbox/api.js', () => ({ inboxApi: { getVisionModels: mockGet, setVisionModel: mockSet, refreshVisionCache: mockRefresh } })); import { VisionSection } from '../../src/renderer/inbox/components/settings/VisionSection'; describe('VisionSection', () => { beforeEach(() => { vi.clearAllMocks(); cleanup(); mockGet.mockResolvedValue({ models: ['gemma3:12b-vision', 'llava:13b'], at: '2026-05-10T05:00:00Z', selected: 'gemma3:12b-vision' }); mockSet.mockResolvedValue({ ok: true }); mockRefresh.mockResolvedValue({ ok: true, models: ['gemma3:12b-vision', 'llava:13b'] }); }); it('open 시 cache 로드 + dropdown 옵션 표시 + 선택된 모델 default', async () => { render(); await waitFor(() => { expect(screen.getByLabelText('이미지 분석 모델')).toHaveValue('gemma3:12b-vision'); }); expect(screen.getByText('gemma3:12b-vision')).toBeInTheDocument(); expect(screen.getByText('llava:13b')).toBeInTheDocument(); expect(screen.getByText(/마지막 감지/)).toBeInTheDocument(); }); it('dropdown 변경 → setVisionModel 호출', async () => { render(); await waitFor(() => screen.getByLabelText('이미지 분석 모델')); fireEvent.change(screen.getByLabelText('이미지 분석 모델'), { target: { value: 'llava:13b' } }); await waitFor(() => { expect(mockSet).toHaveBeenCalledWith('llava:13b'); }); }); it('비활성 선택 → setVisionModel(null)', async () => { render(); await waitFor(() => screen.getByLabelText('이미지 분석 모델')); fireEvent.change(screen.getByLabelText('이미지 분석 모델'), { target: { value: '' } }); await waitFor(() => { expect(mockSet).toHaveBeenCalledWith(null); }); }); it('다시 감지 클릭 → refreshVisionCache 호출 + 결과 표시', async () => { render(); await waitFor(() => screen.getByRole('button', { name: /다시 감지/ })); fireEvent.click(screen.getByRole('button', { name: /다시 감지/ })); await waitFor(() => { expect(mockRefresh).toHaveBeenCalled(); }); await waitFor(() => { expect(screen.getByText(/감지 완료/)).toBeInTheDocument(); }); }); });