4.2 KiB
4.2 KiB
UI sweep coverage (plan §7.5)
Gate: every line below executes for BOTH personas unless marked "admin-only". Status: ✅ swept+green · 🔲 pending (future sweep runs).
| # | Page / control | admin | restricted |
|---|---|---|---|
| 1 | Login: bad password rejected; good login lands authed; logout | ✅ | ✅ |
| 2 | Dashboard: sections render (Recently Added / Not Started) | ✅ | ✅ (hidden lib absent) |
| 3 | Dashboard: hidden library visibility (Audiobooks) | ✅ visible | ✅ absent |
| 4 | Search: results scoped (/api/media-items/search) |
✅ | ✅ no leaks |
| 5 | Media list: no hidden items in payloads | ✅ | ✅ |
| 6 | Library browse grid + pagination | 🔲 | 🔲 |
| 7 | Library create / edit / delete (admin) | 🔲 | n/a |
| 8 | Admin visibility toggle roundtrip (hide → restricted loses → unhide) | 🔲 | 🔲 |
| 9 | Media detail: edit metadata / archive / delete | 🔲 | n/a |
| 10 | Reader: open, page turn, TOC, bookmark, highlight, note, settings | 🔲 | 🔲 |
| 11 | Collections: CRUD, add/remove items, smart-rule editor | 🔲 | 🔲 |
| 12 | Series: list/detail | 🔲 | 🔲 |
| 13 | Stats screens + range filters | 🔲 | 🔲 |
| 14 | Admin: users CRUD, visibility matrix, settings toggles, processing issues | 🔲 | n/a |
| 15 | Upload: EPUB generated at runtime, upload → appears → delete | 🔲 | n/a |
| 16 | Auth edges: restricted → admin URL; anonymous → media URL | 🔲 | ✅ (detail/404) |
| 17 | OPDS / KOReader | API-covered (invariant test) | API-covered |
| 18 | Podcasts: page renders (empty state before any feed) | 🔲 | 🔲 |
| 19 | Podcasts: add-feed modal → feed page (member flow) | 🔲 | 🔲 |
| 20 | Podcasts: feed detail — episode list lifecycle (download/queue/failed+retry states inline), Download All, gap banner | 🔲 | 🔲 |
| 21 | Podcasts: cross-user invisibility — own feed only (RLS §20 surfaces) | 🔲 | 🔲 |
| 22 | Podcasts: order selector re-renders episode list; serial suggestion shown only for serial/audiobook feeds | 🔲 | 🔲 |
| 23 | Podcasts: audio reader "Ep N/M" + prev/next episode; chain-advance to next episode | 🔲 | 🔲 |
Podcast-specific sweep notes (plan task 1.10)
- The download lifecycle needs a fetchable enclosure: sweep with a local
feed server fixture (the integration tests use
swapFeedServer; the Playwright run needs the same trick) — otherwise episodes stay pending and rows 20's queue/failed states can't render. - Row 21 rides
TestPodcastRLSSurfaces(API level) until the sweep lands; the page-level check is the 404 render for a foreign feed id. - Row 23 chains by page navigation — assert the URL becomes the next episode's reader and progress carries over.
2026-10-30 — round-3 regression probes (live-server, env-gated)
Two specs added against a RUNNING dev server (skip unless
BH_FEED=<feed uuid> is set for the first):
confirm_probe.spec.ts— everyhx-confirmmust open the GLOBAL confirm modal, never a native dialog. Pins the htmx-2 detail-shape fix (detail.question, notdetail.element) and the modal's presence on signed-in pages (it used to live inside SidebarSignIn).add_order_probe.spec.ts— the add-modal "Download order" select reveals when "Download all episodes now" is checked (CSS sibling selector; the checkbox must stay a sibling of.podcast-add-order).
2026-10-30 — episode collections (plan item 2.3) — sweep candidates
New controls the Playwright sweep should cover once it lands:
- Collection picker modal: Books/Episodes tab pair — episodes tab loads
?scope=episodes, selection persists across tab switches and htmx swaps (shared bookPicker store). - Collection detail: episode rows (play link carries
?queue=collection:<id>; chain hops keep the param), "Not downloaded" badge, "Unavailable / Remove entry" hint row for collected-but-unsubscribed feeds (All Libraries view), header "Play as Sequence" button. - Player (collection mode): order dropdown + reverse button ABSENT (feed-mode only); "Ep N/M" reflects collection order; auto-advance follows the collection chain, and back-to-detail exits to the collection page.
- API-level pins live in
TestPodcastEpisodeCollections(7 subtests incl. the family-lens auditor case) +TestPodcastPlayerOrderControl.