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-240Done

4.4.7 Story tests — sprint lifecycle state machine (start/complete/carry-over/provisioning/report) + focused E2E (plan → start → move → complete → report)

Estimate: 24m · Depends on: 4.4.2, 4.4.3, 4.4.4, 4.4.5, 4.4.6

The closing test subtask — Vitest over the real Postgres (the project convention: no mocks except getSession; tests/helpers/db.ts truncation) for the lifecycle service + a focused Playwright E2E over the whole flow. The at-scale combined Scrum journey (drag + WIP + swimlanes on a large active sprint) is Story 4.7's, not duplicated here (this story's scale proof is the bounded aggregates/paginated report asserted in 4.4.3 / 4.4.4 against db:seed:large).

Service / unit (vitest, real Postgres). Start: startSprint flips planned→active, stamps the window + the immutable committedPoints/committedIssueCount baseline, ensures a scrum board exists (created once, idempotent on a second start), records a revision; SprintAlreadyActiveError on a second active sprint in the project (+ the partial-unique backstop still refuses with the service bypassed); a different project starts concurrently; invalid window + non-planned rejected. Complete: completeSprint flips active→complete, sets completedAt, moves only the non-done-category issues to the backlog (rank restored) OR into a same-project planned sprint, leaves done issues on the sprint, frees the one-active slot, records revisions, and is ONE transaction (forced mid-batch failure → none moved); InvalidCarryOverTargetError on a cross-project/non-planned target; no-incomplete completes cleanly. Report: getSprintReport returns the completed/incomplete lists (bounded/paginated), the committed (baseline) / completed / not-completed points (via rollupForSprint; unestimated → "—"/0s), and the addedAfterStart scope-change; the counts come from aggregates, not page sums. Tenancy: cross-workspace start/complete/report denied by the finding-#26 gate.

E2E (Playwright) tests/e2e/sprint-lifecycle.spec.ts. Against a seeded project with a planned sprint holding issues: open /backlogStart sprint (modal: name/duration/goal) → the sprint goes active and the app navigates to /boards; move some issues to a done status; back on the backlog (or the scrum header once 4.5 lands) → Complete sprint → the modal shows the completed/incomplete split + the carry-over chooser → choose Backlog → confirm → the sprint report shows the completed/incomplete lists + committed/completed points + the scope-change, and the unfinished issues are back in the backlog. Assert the empty-sprint Start button is disabled and a second start shows the already-active message.

Acceptance criteria

  • pnpm test (real Postgres) covers: start (transition + window + scope-lock baseline + idempotent scrum-board ensure + revision), the one-active service error + the index backstop + per-project concurrency, complete (transition + done/unfinished split + carry-over to backlog AND to a planned sprint + same-project guard + one-tx rollback + freed slot), and the report (paginated lists + committed/completed/not-completed points incl. unestimated "—" + scope-change + aggregate counts), plus the cross-workspace denial.
  • pnpm test:e2e --grep sprint-lifecycle runs green over the real stack: plan → start (modal, navigate to board) → move issues to done → complete (carry-over chooser) → the sprint report; the disabled empty-sprint Start and the already-active message are asserted.
  • pnpm test:coverage keeps the Story-4.4 service/mapper files ≥90% branch/fn/line (the CI coverage gate); the suite uses the real-Postgres harness + the single allowed getSession mock; it does NOT duplicate the at-scale combined Scrum journey (Story 4.7).

Context refs

  • tests/helpers/db.ts — real-Postgres truncation harness + the seed/fixture pattern (a planned sprint with issues; a project with a configured workflow so done-category statuses exist)
  • Stories 4.4.2 / 4.4.3 / 4.4.4 (service flows) + 4.4.5 / 4.4.6 (the modals) — the units under test; Story 4.7 — the test story the at-scale combined Scrum journey defers to
  • tests/e2e/backlog.spec.ts (4.2.6) + tests/e2e/board-scrum.spec.ts (4.5.4) — the sibling E2Es this composes the lifecycle flow on top of
  • motir-core-coverage-gate (≥90% per-file; empty-input guards need a direct test) + motir-core-local-postgres (sandbox PG@5433 + Playwright chromium) + motir-core/CLAUDE.md (real Postgres, no mocks, single getSession mock)