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

4.3.7 Story tests — estimate write + config + bounded sprint/epic roll-ups (incl. statistic switch + at-scale) + badge/settings components + estimate-a-story E2E

Estimate: 24m · Depends on: 4.3.3, 4.3.4, 4.3.5, 4.3.6

The closing test subtask — the same split Stories 4.1.5 / 4.2.6 used: service/component tests + a focused E2E, against the real Postgres (the project convention: no mocks except getSession; tests/helpers/db.ts truncation).

Service (vitest, real Postgres). 4.3.3: setEstimate writes/clears storyPoints in one transaction (value validation: non-negative, in-range, null clears), records a 1.4.6 revision, and is denied cross-workspace by the finding-#26 gate; getEstimationConfig/updateEstimationConfig round-trips the statistic + scale + custom values, validates custom scale (InvalidScaleConfigError), and rejects a non-admin (EstimationConfigForbiddenError). Roll-ups: rollupForSprint returns committed/completed/remaining where completed counts only category = 'done' issues, remaining = committed − completed floored at 0, an unestimated sprint → {0,0,0}, and the aggregate is bounded (NOT a sum over a loaded page); rollupForParent sums the recursive SUBTREE (a grandchild's points roll into the epic); the statistic switch changes which field both roll-ups sum (SUM(storyPoints) vs SUM(estimateMinutes) vs COUNT(*)); empty-sprint / empty-subtree / empty-custom-scale guards.

Component. The EstimateBadge display (estimated / unestimated ) + picker (deck chips + free numeric + clear) + optimistic write + snap-back, on the board card (configured statistic, not raw minutes) + a backlog row; the sprint committed-points + epic roll-up displays (incl. unestimated ); the Estimation settings panel (statistic/scale selection, custom-scale validation, admin gate).

E2E (Playwright) tests/e2e/estimation.spec.ts. A real estimation session against a seeded project with a sprint + an epic/story tree:

  • Estimate a story — open the backlog, click a story's estimate badge, pick a Fibonacci value; the badge updates and survives reload.
  • Sprint roll-up — the story's sprint container committed-points figure increases by the estimate.
  • Epic roll-up — the parent epic's rolled-up subtree total reflects the new estimate (on the detail + list/tree).
  • Detail field — the issue detail shows the story-points field (distinct from the time Estimate) with the same value.
  • Config — an admin switches the scale to custom in settings/project/estimation; the picker deck reflects the custom values.
  • Scale (finding #57) — against pnpm db:seed:large (a large sprint + deep epic subtree), the roll-ups come back from one bounded aggregate each and the DOM stays bounded.

Acceptance criteria

  • pnpm test (real Postgres) covers 4.3.3 (estimate write + validation + revision + workspace gate; config round-trip + custom-scale validation + admin gate; rollupForSprint committed/completed/remaining with the done-category predicate + unestimated 0s + bounded; rollupForParent recursive subtree sum; the statistic switch; empty-input guards) and the components (badge display/picker/optimistic-snap-back, the roll-up displays, the settings panel).
  • pnpm test:e2e --grep estimation runs green over the real stack: estimate a backlog story (survives reload), the sprint committed-points + epic subtree roll-ups update, the detail story-points field shows the value, an admin switches the scale, and the at-scale roll-ups stay bounded (DOM bounded) on db:seed:large.
  • pnpm test:coverage keeps the Story-4.3 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/backlog.spec.ts (4.2.6) + tests/e2e/board-scrum.spec.ts (4.5.4) — the backlog/board E2E patterns to build the estimation E2E on; tests/helpers/db.ts (real-Postgres truncation + large-seed fixture)
  • Story 4.3.3 (service + roll-ups) + 4.3.4/4.3.5/4.3.6 (the UI under test); Story 4.1.5 / 4.2.6 — the sibling test-subtask split this mirrors (no duplication of their association/rank/grooming tests)
  • 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