/** * #95279: the Bot Mode model picker's catalog read must always SETTLE, and it * must not churn the network on every surface remount. * * The read rides the BOT's own socket — a second, lazily dialed pool backend * that can wedge (cold pool spawn, dropped remote hop) without the primary * socket noticing. Two defects made the picker unusable while Bots was active: * * 1. The RPC had no deadline, so a wedged dial left it pending forever and * the spinner never settled ("model picker never settles"). * 2. Every fetch forced `refresh: true`, bypassing the react-query cache, so * each Bots view remount (tab re-front, dialog reopen, pane visibility * flip) knocked the picker back into loading and discarded the staged * selection mid-edit. * * Pinned here through the real component: bounded settlement into the * free-text fallback, one cached unforced read across remounts, and no * dispatch at all for a row whose connection is gone. */ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { render, waitFor } from '@testing-library/react' import type { ReactNode } from 'react' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { ModelPicker } from './model-picker' import type { RosterRow } from './types' const { hostMock } = vi.hoisted(() => ({ hostMock: { request: vi.fn(), requestProfile: vi.fn(), state: { connectionId: { get: () => 'local' }, gateway: { get: () => 'open' }, profile: { get: () => 'default' } } } })) vi.mock('@hermes/plugin-sdk', async () => { const { useQuery } = await import('@tanstack/react-query') return { Button: (props: React.ComponentProps<'button'>) =>