huskies: merge 867
This commit is contained in:
@@ -538,4 +538,124 @@ fn cannot_reject_from_archived() {
|
||||
));
|
||||
}
|
||||
|
||||
// ── Freeze / Unfreeze ───────────────────────────────────────────────
|
||||
|
||||
#[test]
|
||||
fn freeze_from_active_stages() {
|
||||
for s in [Stage::Upcoming, Stage::Backlog, Stage::Coding, Stage::Qa] {
|
||||
let result = transition(s.clone(), PipelineEvent::Freeze).unwrap();
|
||||
assert!(
|
||||
matches!(result, Stage::Frozen { .. }),
|
||||
"expected Frozen from {s:?}"
|
||||
);
|
||||
if let Stage::Frozen { resume_to } = result {
|
||||
assert_eq!(*resume_to, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn freeze_from_merge() {
|
||||
let m = Stage::Merge {
|
||||
feature_branch: fb("f"),
|
||||
commits_ahead: nz(1),
|
||||
};
|
||||
let result = transition(m.clone(), PipelineEvent::Freeze).unwrap();
|
||||
assert!(matches!(result, Stage::Frozen { .. }));
|
||||
if let Stage::Frozen { resume_to } = result {
|
||||
assert_eq!(*resume_to, m);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unfreeze_restores_prior_stage() {
|
||||
let prior = Stage::Coding;
|
||||
let frozen = Stage::Frozen {
|
||||
resume_to: Box::new(prior.clone()),
|
||||
};
|
||||
let result = transition(frozen, PipelineEvent::Unfreeze).unwrap();
|
||||
assert_eq!(result, prior);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cannot_freeze_done() {
|
||||
let s = Stage::Done {
|
||||
merged_at: chrono::Utc::now(),
|
||||
merge_commit: sha("abc"),
|
||||
};
|
||||
let result = transition(s, PipelineEvent::Freeze);
|
||||
assert!(matches!(
|
||||
result,
|
||||
Err(TransitionError::InvalidTransition { .. })
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cannot_freeze_archived() {
|
||||
let s = Stage::Archived {
|
||||
archived_at: chrono::Utc::now(),
|
||||
reason: ArchiveReason::Completed,
|
||||
};
|
||||
let result = transition(s, PipelineEvent::Freeze);
|
||||
assert!(matches!(
|
||||
result,
|
||||
Err(TransitionError::InvalidTransition { .. })
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cannot_unfreeze_coding() {
|
||||
let result = transition(Stage::Coding, PipelineEvent::Unfreeze);
|
||||
assert!(matches!(
|
||||
result,
|
||||
Err(TransitionError::InvalidTransition { .. })
|
||||
));
|
||||
}
|
||||
|
||||
/// Regression test: freeze → unfreeze round-trip via `apply_transition`.
|
||||
/// Verifies that the CRDT shows the correct prior stage restored.
|
||||
#[test]
|
||||
fn regression_freeze_unfreeze_restores_crdt_stage() {
|
||||
crate::crdt_state::init_for_test();
|
||||
crate::db::ensure_content_store();
|
||||
|
||||
let story_id = "9950_story_freeze_regression";
|
||||
let content = "---\nname: Freeze Regression\n---\n# Story\n";
|
||||
crate::db::write_item_with_content(story_id, "2_current", content);
|
||||
|
||||
// Confirm starting stage.
|
||||
let item = read_typed(story_id).unwrap().unwrap();
|
||||
assert!(
|
||||
matches!(item.stage, Stage::Coding),
|
||||
"should start at Coding"
|
||||
);
|
||||
|
||||
// Freeze.
|
||||
super::apply::transition_to_frozen(story_id).expect("freeze should succeed");
|
||||
|
||||
let item = read_typed(story_id).unwrap().unwrap();
|
||||
assert!(
|
||||
matches!(item.stage, Stage::Frozen { .. }),
|
||||
"should be Frozen after freeze: {:?}",
|
||||
item.stage
|
||||
);
|
||||
if let Stage::Frozen { ref resume_to } = item.stage {
|
||||
assert!(
|
||||
matches!(**resume_to, Stage::Coding),
|
||||
"resume_to should be Coding: {:?}",
|
||||
resume_to
|
||||
);
|
||||
}
|
||||
|
||||
// Unfreeze.
|
||||
super::apply::transition_to_unfrozen(story_id).expect("unfreeze should succeed");
|
||||
|
||||
let item = read_typed(story_id).unwrap().unwrap();
|
||||
assert!(
|
||||
matches!(item.stage, Stage::Coding),
|
||||
"should be restored to Coding after unfreeze: {:?}",
|
||||
item.stage
|
||||
);
|
||||
}
|
||||
|
||||
// ── ProjectionError Display ─────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user