soulsync/tests/search
Broque Thomas 7145368d42 Basic search: visual overhaul + per-source picker in hybrid mode
Two things in this commit. Functional download / matched-download
behaviour is untouched — same JS handlers, same routes for the
download actions, same album-expand interaction.

VISUAL REDESIGN
- Glass search-bar card with accent radial wash + focus ring + pill
  primary search button
- Source chip row above the search bar (see below)
- Always-visible compact filter pill row (Type / Format / Sort) —
  pills carry both ``bs-filter-pill`` (new visual) and ``filter-btn``
  (legacy class for ``resetFilters`` + ``applyFiltersAndSort`` in
  wishlist-tools.js to keep working)
- Accent-tinted status pill matching the dashboard / auto-sync look
- Album result cards: glass card with accent left-edge stripe,
  52px brand-tinted cover icon, chevron expand indicator, pill
  action buttons (Download / Matched Album), accent glow on hover
- Track result cards: glass row with accent stripe, 44px icon,
  pill action buttons (Stream / Download / Matched Download)
- Multi-disc separators inside expanded album track lists styled
  with the accent treatment
- Responsive: action button columns stack vertically below 900px

New CSS lives in a self-contained ``webui/static/basic-search-v2.css``
sheet linked from index.html. Selectors are scoped to
``#basic-search-section`` for any class that already exists in
style.css (``.album-result-card``, ``.album-icon``, ``.track-*``,
etc.); the new ``bs-*`` prefixed classes for the search bar /
filters / source row / status are unscoped because they only exist
in the new markup. ``!important`` is used on the card-level rules
to defeat the original unscoped ``.album-result-card`` etc. rules
in style.css that would otherwise leak heavyweight padding /
box-shadow / 56px icon styles into the new design.

Also removed ``overflow: hidden`` from the original
``.album-result-card`` and ``.track-result-card`` rules in style.css
— those two classes only render in ``downloads.js`` basic search
results (verified via grep, two render sites only), so the
removal can't impact any other UI.

SOURCE PICKER (hybrid mode)
- New ``GET /api/search/sources`` endpoint returns the list of
  active sources from the orchestrator's chain (or the single
  active source in single-source mode).
- Frontend renders a chip row above the search bar. Click a chip
  to target that source for the next search; the chip's brand
  accent fills.
- In single-source mode the lone chip is rendered as a dashed-
  border label so the user always knows what they're searching
  but can't accidentally try to switch to sources that aren't
  configured.
- ``/api/search`` accepts an optional ``source`` body param. When
  set, ``core/search/basic.py:run_basic_search`` resolves the
  client directly via ``orchestrator.client(source)`` and calls
  its ``.search()`` instead of going through the hybrid chain.
- Backwards compatible: omitting ``source`` falls through to the
  original ``orchestrator.search()`` call exactly as before.
  Unknown source names also fall back to the default — typo
  protection.

TESTS (5 new + 6 pre-existing = 11 total in test_search_basic.py)
- source param routes to specific client, NOT orchestrator chain
- no source param preserves original orchestrator-default behaviour
- unknown source name falls back to orchestrator default
- ``run_basic_soulseek_search`` backwards-compat alias preserved
- source-targeted path serialises albums + tracks correctly

101 search-suite tests pass.
2026-05-28 10:22:07 -07:00
..
__init__.py Lift /api/search and /api/enhanced-search/* into core/search/ 2026-04-27 15:07:11 -07:00
test_search_basic.py Basic search: visual overhaul + per-source picker in hybrid mode 2026-05-28 10:22:07 -07:00
test_search_cache.py Search cache: preserve falsy provider returns to match original behavior 2026-04-27 15:19:52 -07:00
test_search_library_check.py Lift /api/search and /api/enhanced-search/* into core/search/ 2026-04-27 15:07:11 -07:00
test_search_orchestrator.py Cin-6: Rename soulseek_client global → download_orchestrator 2026-05-04 23:23:32 -07:00
test_search_sources.py feat(import): show MusicBrainz variants 2026-05-24 21:29:22 +03:00
test_search_stream.py Cin-6: Rename soulseek_client global → download_orchestrator 2026-05-04 23:23:32 -07:00