commit 56b20b7333b887f4524fe7c9da323fbb4b25e825
parent 739a9658bdc5ec66ff24d10a489d0dca4c39b944
Author: triesap <tyson@radroots.org>
Date: Tue, 28 Apr 2026 19:13:46 +0000
tests: prove pack day batch workflow
- add no-printer workflow coverage for batch print success and queue failure
- expose the batch print executor injection hook to crate-local tests
- keep the action presentation proof under the workflow filter
- run the workflow filter from the checked-in app validation script
Diffstat:
4 files changed, 110 insertions(+), 6 deletions(-)
diff --git a/crates/launchers/desktop/src/pack_day_print.rs b/crates/launchers/desktop/src/pack_day_print.rs
@@ -48,7 +48,7 @@ pub struct PackDayBatchPrintCommandPlan {
}
#[derive(Clone, Debug, Eq, PartialEq)]
-struct PackDayPrintCommandResult {
+pub(crate) struct PackDayPrintCommandResult {
success: bool,
exit_code: Option<i32>,
stderr: String,
@@ -56,7 +56,7 @@ struct PackDayPrintCommandResult {
impl PackDayPrintCommandResult {
#[cfg(test)]
- fn succeeded() -> Self {
+ pub(crate) fn succeeded() -> Self {
Self {
success: true,
exit_code: Some(0),
@@ -65,7 +65,7 @@ impl PackDayPrintCommandResult {
}
#[cfg(test)]
- fn failed(exit_code: Option<i32>, stderr: impl Into<String>) -> Self {
+ pub(crate) fn failed(exit_code: Option<i32>, stderr: impl Into<String>) -> Self {
Self {
success: false,
exit_code,
@@ -819,7 +819,7 @@ fn execute_pack_day_print_plan_with(
})
}
-fn execute_pack_day_batch_print_plan_with(
+pub(crate) fn execute_pack_day_batch_print_plan_with(
plan: &PackDayBatchPrintCommandPlan,
mut run_command: impl FnMut(
&PackDayPrintCommandPlan,
diff --git a/crates/launchers/desktop/src/runtime.rs b/crates/launchers/desktop/src/runtime.rs
@@ -4875,7 +4875,8 @@ mod tests {
};
use crate::pack_day_host_handoff::PackDayHostHandoffError;
use crate::pack_day_print::{
- prepared_customer_label_asset_root, PackDayBatchPrintError, PackDayPrintError,
+ execute_pack_day_batch_print_plan_with, prepared_customer_label_asset_root,
+ PackDayBatchPrintError, PackDayPrintCommandResult, PackDayPrintError,
};
#[derive(Clone)]
@@ -7848,6 +7849,108 @@ mod tests {
}
#[test]
+ fn pack_day_batch_workflow_success_submits_frozen_v1_and_records_success() {
+ let (runtime, paths) = bootstrapped_runtime("pack_day_batch_workflow_success");
+ let (_, farm_id) = provision_ready_farmer_account(&runtime);
+
+ seed_order_workspace(&runtime, farm_id);
+ assert!(runtime.open_pack_day(None).expect("pack day should open"));
+ assert!(runtime
+ .export_pack_day()
+ .expect("pack day export should succeed"));
+
+ let (request, plan) = runtime
+ .prepare_pack_day_batch_print()
+ .expect("batch print should prepare")
+ .expect("batch print should produce a plan");
+ let mut submitted = Vec::new();
+
+ execute_pack_day_batch_print_plan_with(&plan, |print_plan| {
+ submitted.push(PackDayBatchPrintArtifact::from_print_kind(print_plan.kind));
+ Ok(PackDayPrintCommandResult::succeeded())
+ })
+ .expect("batch print execution should succeed");
+
+ assert_eq!(submitted, Vec::from(PackDayBatchPrintArtifact::all_v1()));
+ assert!(runtime
+ .finish_pack_day_batch_print(request.clone(), Ok(()))
+ .expect("batch print success should apply"));
+
+ let summary = runtime.summary();
+ let batch_print = &summary.pack_day_projection.batch_print;
+ assert_eq!(batch_print.status, PackDayBatchPrintStatus::Succeeded);
+ assert_eq!(batch_print.request, Some(request));
+ assert_eq!(batch_print.failed_artifact, None);
+ assert_eq!(batch_print.failure, None);
+
+ cleanup_bootstrapped_runtime_paths(&paths);
+ }
+
+ #[test]
+ fn pack_day_batch_workflow_queue_failure_records_failed_artifact_state() {
+ let (runtime, paths) = bootstrapped_runtime("pack_day_batch_workflow_queue_failure");
+ let (_, farm_id) = provision_ready_farmer_account(&runtime);
+
+ seed_order_workspace(&runtime, farm_id);
+ assert!(runtime.open_pack_day(None).expect("pack day should open"));
+ assert!(runtime
+ .export_pack_day()
+ .expect("pack day export should succeed"));
+
+ let (request, plan) = runtime
+ .prepare_pack_day_batch_print()
+ .expect("batch print should prepare")
+ .expect("batch print should produce a plan");
+ let mut submitted = Vec::new();
+
+ let execution_error = execute_pack_day_batch_print_plan_with(&plan, |print_plan| {
+ submitted.push(PackDayBatchPrintArtifact::from_print_kind(print_plan.kind));
+ match print_plan.kind {
+ PackDayPrintKind::PrintPackSheet => Ok(PackDayPrintCommandResult::succeeded()),
+ PackDayPrintKind::PrintPickupRoster => Ok(PackDayPrintCommandResult::failed(
+ Some(2),
+ "lp stopped before submit",
+ )),
+ PackDayPrintKind::PrintCustomerLabels => {
+ panic!("batch should stop before customer labels")
+ }
+ }
+ })
+ .expect_err("batch print execution should fail");
+
+ assert_eq!(
+ submitted,
+ vec![
+ PackDayBatchPrintArtifact::from_print_kind(PackDayPrintKind::PrintPackSheet),
+ PackDayBatchPrintArtifact::from_print_kind(PackDayPrintKind::PrintPickupRoster),
+ ]
+ );
+ let failed_artifact =
+ PackDayBatchPrintArtifact::from_print_kind(PackDayPrintKind::PrintPickupRoster);
+ let runtime_error = runtime
+ .finish_pack_day_batch_print(request.clone(), Err(execution_error))
+ .expect_err("batch print failure should surface");
+ assert!(matches!(
+ runtime_error,
+ DesktopAppRuntimeCommandError::PackDayBatchPrint(PackDayBatchPrintError::QueueExit {
+ ..
+ })
+ ));
+
+ let summary = runtime.summary();
+ let batch_print = &summary.pack_day_projection.batch_print;
+ assert_eq!(batch_print.status, PackDayBatchPrintStatus::Failed);
+ assert_eq!(batch_print.request, Some(request));
+ assert_eq!(batch_print.failed_artifact, Some(failed_artifact));
+ assert_eq!(
+ batch_print.failure,
+ Some(PackDayBatchPrintFailureKind::QueueExit)
+ );
+
+ cleanup_bootstrapped_runtime_paths(&paths);
+ }
+
+ #[test]
fn runtime_finish_pack_day_print_records_failures_in_state() {
let (runtime, paths) = bootstrapped_runtime("pack_day_print_failure");
let (_, farm_id) = provision_ready_farmer_account(&runtime);
diff --git a/crates/launchers/desktop/src/window.rs b/crates/launchers/desktop/src/window.rs
@@ -13841,7 +13841,7 @@ mod tests {
}
#[test]
- fn pack_day_batch_print_action_only_surfaces_after_a_successful_export() {
+ fn pack_day_batch_workflow_action_only_surfaces_after_a_successful_export() {
let temp_dir = TestDirectory::new();
write_artifact(temp_dir.path(), "pack_sheet.txt");
write_artifact(temp_dir.path(), "pickup_roster.txt");
diff --git a/scripts/check.sh b/scripts/check.sh
@@ -11,6 +11,7 @@ cargo test -p radroots_app_state pack_day
cargo test -p radroots_app_i18n pack_day
cargo test -p radroots_app pack_day_print
cargo test -p radroots_app pack_day_batch
+cargo test -p radroots_app pack_day_batch_workflow
cargo test -p radroots_app source_guards
cargo check -p radroots_app