MotirBuilding in public
MOTIR · moooon
onMotir
You’re viewing a public project. Anyone can view it — no account needed. Sign in to submit, upvote, or comment on requests.View-only — you can’t edit work items
MOTIR-371

6.7 Tests — the combined Epic-6 journey (build → save → gate → fire) + search/reporting/automation at scale

Done
Description

The Epic-6 cross-cutting test story, re-scoped (the 3.5/4.7/5.6 precedent) to the non-duplicative remainder now that the per-story closers own their surfaces (6.1.6 — filter compilation + injection; 6.4.8, shipped — the access-level × role matrix; the future 6.2/6.3/6.5/6.6/6.8 closers — their own features). Two deliverables:

1. The combined Epic-6 journey (6.7.2). The stub's sentence, exercised as ONE flow asserting the seams that only exist BETWEEN stories: an admin builds an advanced filter (negation + a custom-field row — the 6.1 surface), saves and names it (6.2), backs a dashboard widget with it (6.3), creates an automation rule from the built-in action set (6.6), and transitions a matching issue — the rule fires through the job lane, its action writes through the shipped services (History records it attributed to automation, the 5.4 watcher email fires with the dedupe contract intact, the saved-filter result set and the widget count track the change). Then the gate: a non-admin in a limited/private project (the shipped 6.4 levels) can use what the level grants but every Epic-6 ADMIN surface — saved-filter management, dashboard editing, the rule admin in the 6.5 hub — is hidden in the UI AND 403 at the API (the surfaces 6.4 could not test because they did not exist yet). Then the unwind: delete the saved filter under the live widget → the designed stale state (the 6.1 stale-referent durability rule, one story up), never a crash; disable the rule → no further firing; delete the rule → its History entries keep rendering via the deleted-referent fallback (the 5.5.1 grammar). Each story proves its own link; THIS spec proves the chain.

2. Search / reporting / automation at scale (6.7.1 fixture + 6.7.3 specs). A real team's project is years deep: thousands of issues spread over months of created/resolved history. No existing fixture builds that shape (tree 2.5.16, board 3.5.1, sprint 4.7.1, collab 5.6.1 — all current-dated, none carries saved filters / dashboards / rules). 6.7.1 builds the reporting-shaped corpus — 10k issues (cap-parameterised) time-spread across ~26 weeks with status/priority/assignee/kind/label/component/custom-field spread, plus named saved filters, a populated dashboard, and enabled rules — through the shipped services (one recorded deviation: the documented timestamp back-dating pass, since no service accepts historical dates). 6.7.3 asserts the scaled behaviour: builder + saved filters over the corpus run INDEXED (EXPLAIN: no seq-scan at corpus size), the 6.3 widgets and built-in reports (created-vs-resolved, status distribution) aggregate in SQL — no response carries the row set (the finding-#57 sentinel for Epic 6) — a bulk transition sweep fires rules exactly once (no loss, no duplicates under job retries), and the combined a11y sweep covers the fully-populated 6.5 admin hub + a populated dashboard in light AND dark (the state no per-story sweep renders).

Out of scope: everything an owning closer already tests (listed in the re-scope note); the key-change × old-URL redirect behaviour (Story 6.8 owns it, including saved filters that reference the old key); the cross-feature COLLABORATION journey (5.6.2 owns it); load/stress tooling beyond the bounded-read + EXPLAIN assertions (the CI-lane cap pattern applies instead).

Verification

  • Pull the Story branch (requires Stories 6.1–6.6 merged; 6.4 already shipped), pnpm install, pnpm prisma migrate dev (no migration — test-only story), pnpm db:seed, pnpm dev.
  • pnpm db:seed:reporting (6.7.1) → the corpus exists: 10k issues (CI cap reduced) spread over ~26 weeks of created/resolved dates with full field spread, 5+ named saved filters, a dashboard whose widgets consume them, 3+ enabled automation rules — seeded through the shipped services, deterministic across reseeds, self-check green (incl. the documented timestamp pass).
  • pnpm test:e2e --grep epic6-journey — the combined journey passes: build → save → widget → rule → transition → fire (History attributed to automation, ONE deduped watcher email, widget count tracks), the non-admin gate (UI hidden + API 403 on every Epic-6 admin surface), and the unwind (filter delete → stale widget state; rule disable → silence; rule delete → fallback-rendering History).
  • pnpm test:e2e --grep epic6-at-scale — over the corpus: filter + saved-filter application paginates with count (no full-set response — network census), widgets and reports render from SQL aggregates, the bulk-transition sweep fires exactly N rules, and the combined admin-hub + dashboard strict axe sweep reports zero violations in both themes; the CI lane runs at the reduced cap.
  • pnpm test — the role × Epic-6-admin-endpoint matrix (driven from the route inventory) and the exactly-once firing properties pass at the service layer; pnpm test:coverage holds the gate; all sibling suites stay green.
  • Drift check: the specs assert NO unbounded read exists on the reporting path (the finding-#57 sentinel for Epic 6).