// @vitest-environment jsdom import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { NewProjectPanel } from '../../src/components/NewProjectPanel'; describe('NewProjectPanel media provider badges', () => { beforeEach(() => { vi.stubGlobal('ResizeObserver', class { observe() {} disconnect() {} unobserve() {} }); Element.prototype.scrollIntoView = vi.fn(); }); afterEach(() => { cleanup(); vi.unstubAllGlobals(); }); it('treats daemon-restored apiKeyConfigured providers as configured', () => { render( , ); fireEvent.click(screen.getByRole('tab', { name: 'Media' })); fireEvent.click(screen.getByRole('tab', { name: 'Image' })); // Model picker is now a combobox — open the popover so the // provider group + status badge become visible in the DOM. fireEvent.click(screen.getByTestId('model-picker-trigger')); const openaiGroup = screen.getByText('OpenAI').closest('.ds-picker-group'); expect(openaiGroup?.textContent).toContain('Configured'); expect(openaiGroup?.textContent).not.toContain('Integrated'); }); it('hides provider models until the provider has usable credentials', () => { render( , ); fireEvent.click(screen.getByRole('tab', { name: 'Media' })); fireEvent.click(screen.getByRole('tab', { name: 'Image' })); fireEvent.click(screen.getByTestId('model-picker-trigger')); expect(screen.queryByText('OpenAI')).toBeNull(); expect(screen.queryByTestId('model-picker-option-gpt-image-2')).toBeNull(); }); it('does not submit a hidden default model when no image provider is eligible', async () => { const onCreate = vi.fn(); render( , ); fireEvent.click(screen.getByRole('tab', { name: 'Media' })); fireEvent.click(screen.getByRole('tab', { name: 'Image' })); await waitFor(() => { expect(screen.getByTestId('model-picker-trigger').textContent).toContain('Pick a model'); }); fireEvent.change(screen.getByTestId('new-project-name'), { target: { value: 'No configured image model' }, }); fireEvent.click(screen.getByTestId('create-project')); expect(onCreate).toHaveBeenCalledWith( expect.objectContaining({ metadata: expect.objectContaining({ kind: 'image', imageAspect: '1:1', }), }), ); expect(onCreate.mock.calls[0]?.[0].metadata).not.toHaveProperty('imageModel'); }); it('does not treat OpenAI OAuth-only markers as usable image credentials', () => { render( , ); fireEvent.click(screen.getByRole('tab', { name: 'Media' })); fireEvent.click(screen.getByRole('tab', { name: 'Image' })); fireEvent.click(screen.getByTestId('model-picker-trigger')); expect(screen.queryByText('OpenAI')).toBeNull(); expect(screen.queryByTestId('model-picker-option-gpt-image-2')).toBeNull(); }); it('switches away from the default OpenAI model when only another provider is configured', () => { const onCreate = vi.fn(); render( , ); fireEvent.click(screen.getByRole('tab', { name: 'Media' })); fireEvent.click(screen.getByRole('tab', { name: 'Image' })); fireEvent.change(screen.getByTestId('new-project-name'), { target: { value: 'Configured provider image' }, }); fireEvent.click(screen.getByTestId('create-project')); expect(onCreate).toHaveBeenCalledWith( expect.objectContaining({ metadata: expect.objectContaining({ imageModel: 'doubao-seedream-3-0-t2i-250415', }), }), ); }); });