Browse Source

test(web): cover model draft and provider input defaults

Yichen Jiang 1 week ago
parent
commit
2a5c227199

+ 27 - 0
packages/client/ui-settings-models/tests/model-list-catalog.client.spec.tsx

@@ -54,3 +54,30 @@ it('uses provider input defaults for a model absent from the installed catalog',
   fireEvent.click(text)
   expect(onChange).toHaveBeenCalledWith([{ id: 'custom', input: ['text', 'image'] }])
 })
+
+it('inherits catalog inputs once an incomplete draft has a model id', async () => {
+  const onChange = vi.fn()
+  const props = {
+    onChange, catalogProvider: 'openai',
+    probe: { settingsNs: 'llm-pi-ai', provider: 'openai' },
+    disabled: false, t: (key: keyof typeof en) => en[key],
+    operations: operations(() => Promise.resolve({
+      kind: 'found', models: [{ id: 'vision', inputModalities: ['text', 'image'] }],
+    })),
+  }
+  const { rerender } = render(<ModelListEditor {...props} models={[{}]} />)
+  fireEvent.click(screen.getByRole('button', { name: `${en.modelAdvanced} 1` }))
+  const image = screen.getByRole<HTMLInputElement>('checkbox', { name: en.modelInputImage })
+  await waitFor(() => { expect(image.disabled).toBe(false) })
+  expect(screen.getByRole<HTMLInputElement>('checkbox', { name: en.modelInputText }).checked).toBe(true)
+  expect(image.checked).toBe(false)
+  expect(onChange).not.toHaveBeenCalled()
+
+  const id = screen.getByLabelText<HTMLInputElement>(`${en.modelId} 1`)
+  expect(id.value).toBe('')
+  fireEvent.change(id, { target: { value: 'vision' } })
+  expect(onChange).toHaveBeenCalledExactlyOnceWith([{ id: 'vision' }])
+  rerender(<ModelListEditor {...props} models={[{ id: 'vision' }]} />)
+  expect(image.checked).toBe(true)
+  expect(onChange).toHaveBeenCalledTimes(1)
+})

+ 29 - 0
packages/client/ui-settings-models/tests/provider-form.client.spec.tsx

@@ -522,6 +522,35 @@ describe('endpoint interrogation', () => {
     expect(mutate).not.toHaveBeenCalled()
   })
 
+  it('inherits a custom provider default input and persists an explicit model override', async () => {
+    const { discover, mutate } = await mountSection({
+      providers: {
+        'acme-gateway': {
+          api: 'openai-completions', baseURL: 'https://gateway.acme.example/v1',
+          defaultInput: ['text', 'image'], models: [{ id: 'custom' }],
+        },
+      },
+      declaredRoutes: ['acme-gateway'],
+    })
+    openEditor('acme-gateway')
+    expandModel(1)
+    const types = within(screen.getByRole('group', { name: `${en.modelInputTypes} 1` }))
+    expect(types.getByRole<HTMLInputElement>('checkbox', { name: en.modelInputText }).checked).toBe(true)
+    const image = types.getByRole<HTMLInputElement>('checkbox', { name: en.modelInputImage })
+    expect(image.checked).toBe(true)
+    expect(image.disabled).toBe(false)
+    expect(discover).not.toHaveBeenCalled()
+    expect(mutate).not.toHaveBeenCalled()
+
+    fireEvent.click(image)
+    fireEvent.click(screen.getByText(en.apply))
+    await waitFor(() => { expect(mutate).toHaveBeenCalledTimes(1) })
+    expect(firstMutate(mutate).ops).toEqual([{
+      op: 'set', path: ['providers', 'acme-gateway', 'models'],
+      value: [{ id: 'custom', input: ['text'] }],
+    }])
+  })
+
   it('asks the endpoint the form shows, with a key that is not yet stored', async () => {
     const discover = vi.fn(() => Promise.resolve(ok([{ id: 'acme-large', contextWindow: 65_536 }])))
     await mountSection({ discover })