feat(search): frontend content search (text + warnings) + manga warning banner
Surfaces the analysis pipeline in the UI: - api clients: searchPages() + PageSearchItem/ContentWarning types; listMangas cwInclude/cwExclude; MangaDetail.content_warnings. - /search gains a content-search mode: free-text over OCR+scene and tri-state content-warning toggles (include/exclude), driven by URL params (text, cw_include, cw_exclude) and the new /me/page-search endpoint. Tag browsing is preserved when no content filter is active. - manga detail renders a deduped content-warning banner. Tests: vitest param serialization (searchPages CSV/text/cw, listMangas cw); Playwright text-search + cw-toggle flows (route-mocked). svelte-check + build clean; full vitest (258) + search e2e (7) green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -267,6 +267,14 @@ describe('mangas api client', () => {
|
||||
expect(await getSimilarMangas('b1')).toEqual([]);
|
||||
});
|
||||
|
||||
it('listMangas serializes content-warning include/exclude filters', async () => {
|
||||
fetchSpy.mockResolvedValueOnce(ok(emptyPage()));
|
||||
await listMangas({ cwInclude: ['gore'], cwExclude: ['sexual', 'nudity'] });
|
||||
const url = fetchSpy.mock.calls[0][0] as string;
|
||||
expect(url).toContain('cw_include=gore');
|
||||
expect(url).toContain('cw_exclude=sexual%2Cnudity');
|
||||
});
|
||||
|
||||
it('getManga throws ApiError carrying the envelope code on non-2xx', async () => {
|
||||
fetchSpy.mockResolvedValue(envelope(404, 'not_found', 'manga not found'));
|
||||
await expect(getManga('missing')).rejects.toMatchObject({
|
||||
|
||||
Reference in New Issue
Block a user