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-136

2.6.2 Default-workflow graph-conformance suite (vitest, constant-derived)

Done
Description

Estimate: 30m · Depends on: 2.6.1

Add tests/workflows/transition-conformance.test.ts — a graph-complete conformance guard over the default workflow, consolidating what transition-validation.test.ts only SAMPLES. The suite derives the edge set from the defaultWorkflow.ts constant (NOT a hardcoded copy), so any future edit that adds/drops a status or transition is caught.

Drive everything through the shipped path — workItemsService.updateStatus validated by workflowsService.canTransition, against a createTestProject project (which auto-seeds the six default statuses + fifteen transitions). Assertions:

  • Restricted mode (the default): for EVERY one of the 15 default transition edges, a work item sitting in the from status transitions to the to status successfully (and records exactly one updated revision). For EVERY non-edge in the 6×6 grid that is neither a default edge nor a self-loop, updateStatus is rejected with IllegalTransitionError. Both loops are generated from the constant — the test body enumerates statuses × statuses and partitions by membership in the default edge set.
  • No-op self-transitions (status → same status) succeed WITHOUT writing a revision, for all six statuses.
  • Open mode: after flipping the project policy to open (via workflowsService / the 2.2 management path), the full cartesian product of (real status → real status) is accepted — proving open mode bypasses the edge set — while an unknown target key still raises UnknownStatusError.
  • Terminal-set conformance: the statuses with category: done exactly match { done, cancelled } (the readiness predicate’s terminal set, finding #21), derived from the seeded statuses, not hardcoded.

Keep it complementary to transition-validation.test.ts (which keeps its hand-picked cases + the atomicity/tenant-gate cases) — this file owns the exhaustive graph sweep. Do not duplicate the atomicity / cross-workspace cases.

Acceptance criteria

  • New file tests/workflows/transition-conformance.test.ts; passes under pnpm test on real Postgres.
  • The legal-edge and illegal-non-edge sets are computed FROM the default workflow constant; locally deleting one edge from defaultWorkflow.ts makes the suite fail (manually verified, noted in the PR).
  • All 15 default edges are each exercised through updateStatus; every non-edge non-self pair is asserted to raise IllegalTransitionError.
  • Self-transitions write no revision; open-mode accepts the full real×real product; unknown key → UnknownStatusError.
  • Terminal category: done set asserted to equal { done, cancelled }.
  • Each test describe names the invariant it protects (per the project test convention).

Context refs

  • lib/workflows/defaultWorkflow.ts — the 6 statuses + 15 transitions the suite derives from
  • lib/services/workflowsService.ts (canTransition, policy-mode toggle), lib/services/workItemsService.ts (updateStatus)
  • lib/workItems/errors.ts (IllegalTransitionError, UnknownStatusError)
  • tests/workflows/transition-validation.test.ts (2.2.4) + tests/workflows/default-workflow.test.ts — the sampled coverage this completes
  • tests/fixtures/projectFixtures.ts (createTestProject), tests/helpers/db.ts