# Collab Editor - Test Plan Companion document to [SPECIFICATION.md](./SPECIFICATION.md). Covers the critical paths that, if broken, would cause data loss, publishing failures, or security holes. Intentionally **not** exhaustive - the project is evolving fast, and these tests are chosen to survive refactors. ## Principles - Test **behavior**, not implementation details. - Focus on what **breaks silently** (data loss, corrupt publish, auth bypass). - Keep tests **decoupled from internals** so they survive refactors. - Fast to run - no heavy dependencies (Playwright PDF, real HF API) in the main suite. ## Stack | Layer | Tool | Scope | |-------|------|-------| | Backend unit/integration | Vitest + Supertest | Publisher, API routes, auth guards | | Yjs helpers | In-memory Y.Doc fixtures | Publisher extraction, storage logic | | Frontend unit | Vitest + Testing Library | Agent tool execution, undo batching | | E2E | Playwright (`backend/e2e`, `frontend/tests`) | Critical editor flows: load, edit, comments, publish round-trip | E2E is opt-in (`npm run test:e2e` in `backend/`, plus Playwright specs in `frontend/tests/`); the fast suite (`npm run test`) stays hermetic and Playwright-free so it can run in CI without a browser install. --- ## 1. Publisher Pipeline (P0) The core value of the product. If publishing breaks, the article disappears. ### 1.1 Y.Doc extraction | # | Test | Given / When / Then | Priority | |---|------|---------------------|----------| | 1.1.1 | Extract frontmatter from Y.Doc | Given a Y.Doc with title, authors, affiliations in `Y.Map("frontmatter")` / When `extractFromYDoc` runs / Then returned object contains all frontmatter fields with correct types | P0 | | 1.1.2 | Extract content from empty doc | Given a Y.Doc with an empty `Y.XmlFragment("default")` / When extracted / Then returns empty content without throwing | P0 | | 1.1.3 | Extract with citations | Given a Y.Doc with entries in `Y.Map("citations")` / When extracted / Then citations map is included in output as CSL-JSON | P0 | ### 1.2 HTML generation | # | Test | Given / When / Then | Priority | |---|------|---------------------|----------| | 1.2.1 | Produces valid self-contained HTML | Given extracted doc data / When `renderArticleHTML` runs / Then output is valid HTML with inline CSS, no external stylesheet links | P0 | | 1.2.2 | CSS variables resolved | Given template CSS with `@custom-media` / When `resolveCustomMedia` runs / Then output contains only standard `@media` rules, no `@custom-media` | P0 | | 1.2.3 | TOC generated from headings | Given content with h2 and h3 / When rendered / Then HTML contains TOC nav with matching anchor links | P1 | | 1.2.4 | Theme toggle present | Given any doc / When rendered / Then output contains theme toggle SVG (sun/moon) and associated script | P1 | | 1.2.5 | Bibliography injected | Given doc with citations / When rendered / Then HTML contains bibliography section with formatted entries | P0 | ### 1.3 Post-processing | # | Test | Given / When / Then | Priority | |---|------|---------------------|----------| | 1.3.1 | Accordion to details/summary | Given HTML with accordion div / When post-processed / Then output uses `
` and `` tags | P1 | | 1.3.2 | htmlEmbed to iframe | Given HTML with htmlEmbed node / When post-processed / Then output contains `