model-image-input.client.spec.tsx 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. // @vitest-environment jsdom
  2. /** Image capability defaults, explicit choices, and hidden model metadata. */
  3. import { cleanup, fireEvent, render, screen } from '@testing-library/react'
  4. import { afterEach, describe, expect, it, vi } from 'vitest'
  5. import { ModelImageInput } from '../src/client/ModelImageInput.tsx'
  6. import { en } from '../src/client/locales.ts'
  7. afterEach(cleanup)
  8. describe.each(['inputModalities', 'input'] as const)('%s image input', (field) => {
  9. it.each([
  10. [undefined, 'default'],
  11. [[], 'default'],
  12. [['text'], 'disabled'],
  13. [['text', 'image'], 'enabled'],
  14. [['image'], 'enabled'],
  15. ] as const)('displays %j without materializing an override', (modalities, selected) => {
  16. const onChange = vi.fn()
  17. render(<ModelImageInput model={{ id: 'preview', [field]: modalities }} field={field} position={2} disabled={false} t={key => en[key]} onChange={onChange} />)
  18. expect(screen.getByRole<HTMLSelectElement>('combobox', { name: `${en.modelImageInput} 2` }).value).toBe(selected)
  19. expect(onChange).not.toHaveBeenCalled()
  20. })
  21. it('enables images and keeps unrelated metadata', () => {
  22. const onChange = vi.fn()
  23. const model = { id: 'preview', contextWindow: 123456, systemPromptUpdate: 'in-history' }
  24. render(<ModelImageInput model={model} field={field} position={1} disabled={false} t={key => en[key]} onChange={onChange} />)
  25. fireEvent.change(screen.getByRole('combobox'), { target: { value: 'enabled' } })
  26. expect(onChange).toHaveBeenCalledWith({ ...model, [field]: ['text', 'image'] })
  27. expect(model).not.toHaveProperty(field)
  28. })
  29. it.each(['disabled', 'default'])('selects %s without leaving invalid DeepSeek image limits', (choice) => {
  30. const onChange = vi.fn()
  31. const model = { id: 'vision', [field]: ['image'], description: 'kept', imagePixelBudget: 'low', imageMaxBytes: 12345 }
  32. render(<ModelImageInput model={model} field={field} position={1} disabled={false} t={key => en[key]} onChange={onChange} />)
  33. fireEvent.change(screen.getByRole('combobox'), { target: { value: choice } })
  34. expect(onChange).toHaveBeenCalledWith({
  35. id: 'vision', description: 'kept',
  36. ...choice === 'disabled' ? { [field]: ['text'] } : {},
  37. ...field === 'input' ? { imagePixelBudget: 'low', imageMaxBytes: 12345 } : {},
  38. })
  39. expect(model[field]).toEqual(['image'])
  40. })
  41. it('disables the selector while read-only or saving', () => {
  42. render(<ModelImageInput model={{ id: 'preview' }} field={field} position={1} disabled t={key => en[key]} onChange={vi.fn()} />)
  43. expect(screen.getByRole<HTMLSelectElement>('combobox').disabled).toBe(true)
  44. })
  45. })