import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { OpencodeRuntimePanel } from '@/pages/Models/OpencodeRuntimePanel'; const { opencodeState } = vi.hoisted(() => ({ opencodeState: { status: { state: 'running', port: 4096, url: 'http://127.0.0.1:4096' }, runtimeConfigSummary: { model: 'openai/gpt-5.4', smallModel: null, providerIds: ['openai'], providerCount: 1, }, loading: false, error: null, refreshStatus: vi.fn(), loadRuntimeConfigSummary: vi.fn(), restart: vi.fn(), start: vi.fn(), }, })); vi.mock('@/stores/opencode', () => ({ useOpencodeStore: (selector: (state: typeof opencodeState) => unknown) => selector(opencodeState), })); vi.mock('react-i18next', () => ({ useTranslation: () => ({ t: (key: string, fallback?: string | Record) => { if (typeof fallback === 'string') return fallback; return key; }, }), })); describe('OpencodeRuntimePanel', () => { beforeEach(() => { vi.clearAllMocks(); opencodeState.status = { state: 'running', port: 4096, url: 'http://127.0.0.1:4096' }; opencodeState.runtimeConfigSummary = { model: 'openai/gpt-5.4', smallModel: null, providerIds: ['openai'], providerCount: 1, }; opencodeState.loading = false; opencodeState.error = null; }); it('shows runtime status, port, configured model, and provider count', () => { render(); expect(screen.getByText('Makelore runtime')).toBeInTheDocument(); expect(document.body.textContent).not.toMatch(/opencode/i); expect(screen.getByText('running')).toBeInTheDocument(); expect(screen.getByText('4096')).toBeInTheDocument(); expect(screen.getByText('openai/gpt-5.4')).toBeInTheDocument(); expect(screen.getByText('1')).toBeInTheDocument(); expect(opencodeState.refreshStatus).toHaveBeenCalledOnce(); expect(opencodeState.loadRuntimeConfigSummary).toHaveBeenCalledOnce(); }); it('restarts the runtime from the panel and refreshes the summary', async () => { render(); fireEvent.click(screen.getByRole('button', { name: /restart runtime/i })); await waitFor(() => expect(opencodeState.restart).toHaveBeenCalledOnce()); expect(opencodeState.loadRuntimeConfigSummary).toHaveBeenCalledTimes(2); }); it('starts the runtime when it is stopped', async () => { opencodeState.status = { state: 'stopped', port: 4096 }; render(); fireEvent.click(screen.getByRole('button', { name: /start runtime/i })); await waitFor(() => expect(opencodeState.start).toHaveBeenCalledOnce()); }); });