Skip to content

moooon

Motir

Vibe your whole project. Bring an idea — Motir's three AI layers plan it, track it, and ship it, end to end. You're looking at Motir, built in Motir.

  • Vibe Project
  • Open Source
  • AI Agent
  • AI Loop
1
requests
0
upvotes
145
planned
1,361
shipped

Motir · Work items

MOTIR-224Done

4.2.6 Story tests — bulk/create service + selection/drag/create components + at-scale backlog-grooming E2E

Estimate: 24m · Depends on: 4.2.2, 4.2.3, 4.2.4, 4.2.5

The closing test subtask — the same split Stories 4.1.5 / 4.5.4 used: this Story's OWN service/component tests + a focused at-scale backlog E2E, against the real Postgres (the project convention: no mocks except getSession; tests/helpers/db.ts truncation). Story 4.1's single-issue association/rank + bounded reads are already proven in 4.1.5; this proves the bulk composition + the grooming UI on top.

Service (vitest, real Postgres). 4.2.2: bulkAssignToSprint / bulkMoveToBacklog move the whole batch in ONE transaction (a forced mid-batch failure rolls back — assert NONE moved, not a partial set), the same-project guard rejects a batch with a cross-project member (atomic), the batch bound rejects oversize, an empty itemIds is a guarded no-op, and each move records a 1.4.6 revision; createBacklogIssue creates + appends a backlog_rank + optionally assigns in one tx and records the revision.

Component. The container/list render + bounded count + virtualized window (DOM stays bounded on a large seed); the selection model (click / shift-range / ⌘-toggle, survives lazy-load); drag reorder (single-row rank write) + drag-into-sprint (assign + counts) + snap-back on failure; inline create into backlog + sprint; the menu actions; the empty/loading/error states.

E2E (Playwright) tests/e2e/backlog.spec.ts. A real grooming session against a seeded project with sprints + a backlog:

  • Render/backlog shows the sprint container(s) over the ranked backlog; the Backlog nav item leads here.
  • Rank — drag a row between two neighbours; its order changes and survives reload (single-row rank).
  • Assign — drag a backlog row into a sprint; it leaves the backlog, the sprint count increments; drag it back; it restores in rank order.
  • Bulk — multi-select two rows and Move to sprint; both move in one action; (a forced failure path leaves none moved).
  • Create — inline-create an issue into the backlog and into a sprint.
  • Scale (finding #57) — against pnpm db:seed:large, the backlog renders a bounded first page + count, lazy-loads on scroll (DOM bounded), and drag still works out of the virtualized list.

Defers nothing to a later test story (4.2 is self-contained); the Scrum-board + combined at-scale Scrum journey is Stories 4.5.4 / 4.7, not here.

Acceptance criteria

  • pnpm test (real Postgres) covers 4.2.2 (atomic bulk move + rollback-on-failure, same-project batch guard, batch bound, empty-input no-op, create-into-sprint, 1.4.6 revisions) and the components (container/list/bounded-count/virtualized window, selection model incl. shift-range + survive-lazy-load, drag reorder/assign/snap-back, inline create, menu, states).
  • pnpm test:e2e --grep backlog runs green over the real stack: render + nav, drag-reorder (survives reload), drag-assign + count update + restore, atomic multi-select bulk move, inline create into backlog + sprint, and the at-scale bounded/virtualized/lazy-load grooming (DOM bounded, drag works) on db:seed:large.
  • pnpm test:coverage keeps the Story-4.2 service/route + component files ≥90% branch/fn/line (the CI coverage gate); the suite uses the real-Postgres harness + the single allowed getSession mock.

Context refs

  • tests/e2e/board-ui.spec.ts (3.2.7) + tests/e2e/board-swimlanes.spec.ts (3.3.7) — the dnd-kit + virtualized-list E2E patterns (drag, drop, scroll) to build the backlog E2E on; tests/helpers/db.ts (real-Postgres truncation + large-seed fixture)
  • Story 4.2.2 (bulk/create service) + 4.2.3/4.2.4/4.2.5 (the UI under test); Story 4.1.5 — the single-issue association/rank/bounded-read tests this builds atop (no duplication)
  • prodect-core-coverage-gate (≥90% per-file; empty-input guards need a direct test) + prodect-core-local-postgres (sandbox PG@5433 + Playwright) + motir-core/CLAUDE.md (real-Postgres, no mocks, single getSession mock) + the prodect-e2e-selector-gotchas / prodect-e2e-run-harness-oom lessons