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 && (
{