diff --git a/app/src/components/settings/panels/SearchPanel.test.tsx b/app/src/components/settings/panels/SearchPanel.test.tsx index 1b833cb5d..0ec5066a9 100644 --- a/app/src/components/settings/panels/SearchPanel.test.tsx +++ b/app/src/components/settings/panels/SearchPanel.test.tsx @@ -77,6 +77,29 @@ describe('SearchPanel — unified web-access modes', () => { expect(radio(ALLOW_ALL)).toHaveAttribute('aria-checked', 'false'); }); + test('selecting Disabled persists the disabled engine', async () => { + renderWithProviders(); + const disabled = await screen.findByTestId('search-engine-disabled'); + + fireEvent.click(disabled); + + await waitFor(() => + expect(hoisted.updateSearchSettings).toHaveBeenCalledWith({ engine: 'disabled' }) + ); + }); + + test('disabled settings start with Disabled selected and no needs-key badge', async () => { + hoisted.getSearchSettings.mockResolvedValue({ + result: settings({ engine: 'disabled', effective_engine: 'disabled' }), + }); + renderWithProviders(); + + const disabled = await screen.findByTestId('search-engine-disabled'); + + expect(disabled).toHaveAttribute('aria-checked', 'true'); + expect(within(disabled).queryByText('settings.search.statusNeedsKey')).toBeNull(); + }); + test('selecting "Allow all" persists allow_all: true and hides the editor', async () => { renderWithProviders(); await screen.findByPlaceholderText(PLACEHOLDER); @@ -204,6 +227,42 @@ describe('SearchPanel — unified web-access modes', () => { expect(braveInput.value).toBe(''); }); + test('Parallel and Brave key editors can reveal and clear stored keys', async () => { + hoisted.getSearchSettings.mockResolvedValue({ + result: settings({ parallel_configured: true, brave_configured: true }), + }); + renderWithProviders(); + await screen.findAllByPlaceholderText('settings.search.placeholderStored'); + + const parallel = keyEditor('settings.search.parallelKeyLabel'); + const parallelInput = parallel.getByPlaceholderText( + 'settings.search.placeholderStored' + ) as HTMLInputElement; + expect(parallelInput.type).toBe('password'); + + fireEvent.click(parallel.getByText('settings.search.show')); + expect(parallelInput.type).toBe('text'); + fireEvent.click(parallel.getByText('settings.search.clear')); + + await waitFor(() => + expect(hoisted.updateSearchSettings).toHaveBeenCalledWith({ parallel_api_key: '' }) + ); + + const brave = keyEditor('settings.search.braveKeyLabel'); + const braveInput = brave.getByPlaceholderText( + 'settings.search.placeholderStored' + ) as HTMLInputElement; + expect(braveInput.type).toBe('password'); + + fireEvent.click(brave.getByText('settings.search.show')); + expect(braveInput.type).toBe('text'); + fireEvent.click(brave.getByText('settings.search.clear')); + + await waitFor(() => + expect(hoisted.updateSearchSettings).toHaveBeenCalledWith({ brave_api_key: '' }) + ); + }); + test('Querit key editor can reveal, save, and clear the stored API key', async () => { hoisted.getSearchSettings.mockResolvedValue({ result: settings({ querit_configured: true }) }); renderWithProviders(); diff --git a/app/src/components/settings/panels/SearchPanel.tsx b/app/src/components/settings/panels/SearchPanel.tsx index f338cc2c7..a5c30ddd3 100644 --- a/app/src/components/settings/panels/SearchPanel.tsx +++ b/app/src/components/settings/panels/SearchPanel.tsx @@ -77,6 +77,12 @@ const SearchPanel = ({ embedded = false }: { embedded?: boolean }) => { const initializedRef = useRef(false); const ENGINES: EngineOption[] = [ + { + id: 'disabled', + label: t('settings.search.engineDisabledLabel'), + description: t('settings.search.engineDisabledDesc'), + requiresKey: false, + }, { id: 'managed', label: t('settings.search.engineManagedLabel'), @@ -206,6 +212,7 @@ const SearchPanel = ({ embedded = false }: { embedded?: boolean }) => { const isConfigured = (engine: SearchEngineId): boolean => { if (!settings) return false; + if (engine === 'disabled') return true; if (engine === 'managed') return true; if (engine === 'parallel') return settings.parallel_configured; if (engine === 'brave') return settings.brave_configured; @@ -214,7 +221,7 @@ const SearchPanel = ({ embedded = false }: { embedded?: boolean }) => { }; return ( -
+
{!embedded && ( {