Recipe search card on the AI assistant screen
CI / ci (push) Successful in 2m1s
CI / ci (pull_request) Successful in 1m55s

Add a Recipe search card to /settings/ai: a SearXNG | Brave segmented
control, the SearXNG URL pre-filled from the saved settings, or the Brave
API key shown masked (last four characters) with Replace. The provider,
URL and new key are a draft saved together with PATCH
/api/v1/settings/recipe-search; Test calls the recipe-search test
endpoint and shows "Found N recipes for 'chicken tikka masala'" or the
error.

The leave-without-saving guard moves to page level so it covers both the
AI assistant form and the card; the shell test now renders in a data
router as main.tsx does.

Maestro task: 0698ae2c-f65e-408e-a9c6-198edc2c5696

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-06 10:27:16 -04:00
co-authored by Claude Opus 5.5
parent e9a35a7f57
commit cb42ffa280
8 changed files with 646 additions and 33 deletions
+3 -3
View File
@@ -1,9 +1,9 @@
import { render, screen, within } from '@testing-library/react'
import { MemoryRouter } from 'react-router'
import { afterEach, describe, expect, it, vi } from 'vitest'
import { AppRoutes } from '../App.tsx'
import { ApiProviders, SETTINGS_API } from '../test/ApiProviders.tsx'
import { declaredStyle, outerSize } from '../test/cssRules.ts'
import { InDataRouter } from '../test/dataRouter.tsx'
import { expectMinHitArea } from '../test/hitArea.ts'
import { stubFetchByPath } from '../test/fetchStub.ts'
import { mockViewport } from '../test/matchMedia.ts'
@@ -25,11 +25,11 @@ function renderAt(path: string, width: number) {
const resize = mockViewport(width)
stubFetchByPath(SETTINGS_API)
render(
<MemoryRouter initialEntries={[path]}>
<InDataRouter path={path}>
<ApiProviders>
<AppRoutes />
</ApiProviders>
</MemoryRouter>,
</InDataRouter>,
)
return resize
}