app

Local-first trade for farms and co-ops
git clone https://radroots.dev/git/app.git
Log | Files | Refs | README | LICENSE

commit 7faace3aab6b2b4a6accb856dca5c44d129d4438
parent dc27eca1611d21a98445e713b2be3c3204b4f083
Author: triesap <tyson@radroots.org>
Date:   Wed, 22 Apr 2026 22:07:26 +0000

app: clean pack day prepared print assets

- sweep the prepared customer-label print root during desktop bootstrap
- remove request-scoped prepared assets after label print completion and export resets
- clean partial prepared-output directories when planner writes fail
- add focused pack day tests for bootstrap, completion, re-export, and window-reset cleanup

Diffstat:
Mcrates/launchers/desktop/src/pack_day_print.rs | 90++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
Mcrates/launchers/desktop/src/runtime.rs | 1828++++++++++++++++++++++++++++++++++++++++---------------------------------------
2 files changed, 1006 insertions(+), 912 deletions(-)

diff --git a/crates/launchers/desktop/src/pack_day_print.rs b/crates/launchers/desktop/src/pack_day_print.rs @@ -6,7 +6,8 @@ use std::path::{Component, Path, PathBuf}; use std::process::Command; use radroots_app_models::{ - PackDayExportArtifactKind, PackDayExportBundle, PackDayPrintKind, PackDayPrintLabelStock, + PackDayExportArtifactKind, PackDayExportBundle, PackDayExportInstanceId, PackDayPrintKind, + PackDayPrintLabelStock, }; use thiserror::Error; @@ -267,6 +268,18 @@ fn io_errors_match(left: &io::Error, right: &io::Error) -> bool { left.kind() == right.kind() && left.to_string() == right.to_string() } +pub(crate) fn cleanup_prepared_customer_label_asset_root() -> io::Result<()> { + cleanup_prepared_customer_label_assets_at_path(prepared_customer_label_asset_root()) +} + +pub(crate) fn cleanup_prepared_customer_label_assets_for_export_instance( + export_instance_id: PackDayExportInstanceId, +) -> io::Result<()> { + cleanup_prepared_customer_label_assets_at_path( + prepared_customer_label_asset_directory_for_export_instance(export_instance_id), + ) +} + pub fn plan_pack_day_print( bundle: &PackDayExportBundle, kind: PackDayPrintKind, @@ -398,6 +411,8 @@ fn prepare_customer_label_stock_asset( let target_path = prepared_customer_label_asset_path(bundle, stock); let prepared_asset = render_customer_label_stock_asset(&source_contents, stock); fs::write(&target_path, prepared_asset).map_err(|source| { + let _ = + cleanup_prepared_customer_label_assets_for_export_instance(bundle.export_instance_id); PackDayPrintError::WritePreparedAsset { kind, path: target_path.clone(), @@ -408,10 +423,36 @@ fn prepare_customer_label_stock_asset( Ok(target_path) } +pub(crate) fn prepared_customer_label_asset_root() -> PathBuf { + let root = std::env::temp_dir().join(CUSTOMER_LABEL_PREPARED_ASSET_ROOT); + + #[cfg(test)] + { + root.join(format!("{:?}", std::thread::current().id())) + } + + #[cfg(not(test))] + { + root + } +} + +fn cleanup_prepared_customer_label_assets_at_path(path: PathBuf) -> io::Result<()> { + match fs::remove_dir_all(&path) { + Ok(()) => Ok(()), + Err(error) if error.kind() == io::ErrorKind::NotFound => Ok(()), + Err(error) => Err(error), + } +} + +fn prepared_customer_label_asset_directory_for_export_instance( + export_instance_id: PackDayExportInstanceId, +) -> PathBuf { + prepared_customer_label_asset_root().join(export_instance_id.to_string()) +} + fn prepared_customer_label_asset_directory(bundle: &PackDayExportBundle) -> PathBuf { - std::env::temp_dir() - .join(CUSTOMER_LABEL_PREPARED_ASSET_ROOT) - .join(bundle.export_instance_id.to_string()) + prepared_customer_label_asset_directory_for_export_instance(bundle.export_instance_id) } fn prepared_customer_label_asset_path( @@ -642,9 +683,10 @@ fn run_macos_print_command( #[cfg(test)] mod tests { use super::{ - LETTER_MEDIA_OPTION, PackDayPrintCommandResult, PackDayPrintError, - execute_pack_day_print_plan_with, plan_pack_day_print, - prepared_customer_label_asset_directory, prepared_customer_label_asset_path, + cleanup_prepared_customer_label_asset_root, execute_pack_day_print_plan_with, + plan_pack_day_print, prepared_customer_label_asset_directory, + prepared_customer_label_asset_path, prepared_customer_label_asset_root, + PackDayPrintCommandResult, PackDayPrintError, LETTER_MEDIA_OPTION, }; use radroots_app_models::{ PackDayExportArtifact, PackDayExportArtifactKind, PackDayExportBundle, @@ -774,11 +816,10 @@ mod tests { ); assert!(plan.target_path.is_file()); assert!(!plan.target_path.starts_with(temp_dir.path())); - assert!( - plan.target_path - .to_string_lossy() - .contains(bundle.export_instance_id.to_string().as_str()) - ); + assert!(plan + .target_path + .to_string_lossy() + .contains(bundle.export_instance_id.to_string().as_str())); assert_eq!( fs::read_to_string(&source_path).expect("source labels should stay untouched"), "Willow farm\nCasey\nOrder: R-1001\nPickup: North barn\nWindow: 2026-04-23T16:00:00Z to 2026-04-23T19:00:00Z\n\n---\n\nWillow farm\nTaylor\nOrder: R-1002\nPickup: North barn\nWindow: 2026-04-23T16:00:00Z to 2026-04-23T19:00:00Z\n" @@ -878,7 +919,20 @@ mod tests { other => panic!("unexpected error: {other:?}"), } - let _ = fs::remove_dir_all(prepared_customer_label_asset_directory(&bundle)); + assert!(!prepared_directory.exists()); + } + + #[test] + fn cleanup_prepared_customer_label_asset_root_removes_existing_directories() { + let root = prepared_customer_label_asset_root(); + let stale_directory = root.join(PackDayExportInstanceId::new().to_string()); + fs::create_dir_all(&stale_directory).expect("stale prepared directory should create"); + fs::write(stale_directory.join("stale.ps"), "stale").expect("stale asset should write"); + + cleanup_prepared_customer_label_asset_root() + .expect("prepared customer label asset root should clean"); + + assert!(!root.exists()); } #[test] @@ -926,12 +980,10 @@ mod tests { .expect("pack sheet print plan should build"); assert_eq!(plan.target_path, pack_sheet_path); - assert!( - execute_pack_day_print_plan_with(&plan, |_| { - Ok(PackDayPrintCommandResult::succeeded()) - }) - .is_ok() - ); + assert!(execute_pack_day_print_plan_with(&plan, |_| { + Ok(PackDayPrintCommandResult::succeeded()) + }) + .is_ok()); } #[test] diff --git a/crates/launchers/desktop/src/runtime.rs b/crates/launchers/desktop/src/runtime.rs @@ -5,9 +5,9 @@ use std::sync::{Arc, Mutex, MutexGuard, PoisonError}; use chrono::{Duration, Utc}; use radroots_app_core::{ + prepare_pack_day_export_bundle_at_data_root, write_prepared_pack_day_export_bundle, AppBuildIdentity, AppDesktopRuntimePaths, AppRuntimeCapture, AppRuntimeMode, AppRuntimePathsError, AppRuntimeSnapshot, AppSharedAccountsPaths, PackDayExportWriteError, - prepare_pack_day_export_bundle_at_data_root, write_prepared_pack_day_export_bundle, }; use radroots_app_models::{ ActiveSurface, AppActivityContext, AppActivityKind, AppIdentityProjection, AppStartupGate, @@ -17,12 +17,12 @@ use radroots_app_models::{ FarmSetupProjection, FarmSummary, FarmerSection, FulfillmentWindowId, LoggedOutStartupProjection, OrderDetailProjection, OrderId, OrderRecoveryProjection, OrdersFilter, OrdersListProjection, OrdersScreenQueryState, PackDayExportBundle, - PackDayExportStatus, PackDayHostHandoffKind, PackDayHostHandoffStatus, PackDayPrintKind, - PackDayPrintStatus, PackDayProjection, PackDayScreenQueryState, PersonalSection, - PickupLocationRecord, ProductEditorDraft, ProductId, ProductsFilter, ProductsListProjection, - ProductsSort, RecoveryKind, RecoveryQueueProjection, RecoveryRecordId, RecoveryState, - ReminderDeadlineProjection, ReminderDeliveryState, ReminderFeedProjection, ReminderId, - ReminderKind, ReminderLogEntryProjection, ReminderLogProjection, ReminderSurface, + PackDayExportInstanceId, PackDayExportStatus, PackDayHostHandoffKind, PackDayHostHandoffStatus, + PackDayPrintKind, PackDayPrintStatus, PackDayProjection, PackDayScreenQueryState, + PersonalSection, PickupLocationRecord, ProductEditorDraft, ProductId, ProductsFilter, + ProductsListProjection, ProductsSort, RecoveryKind, RecoveryQueueProjection, RecoveryRecordId, + RecoveryState, ReminderDeadlineProjection, ReminderDeliveryState, ReminderFeedProjection, + ReminderId, ReminderKind, ReminderLogEntryProjection, ReminderLogProjection, ReminderSurface, ReminderUrgency, SettingsAccountProjection, SettingsPreference, SettingsSection, ShellSection, TodayAgendaProjection, }; @@ -30,17 +30,17 @@ use radroots_app_remote_signer::{ RadrootsAppRemoteSignerApprovedSession, RadrootsAppRemoteSignerPendingSession, }; use radroots_app_sqlite::{ - APP_ACTIVITY_CONTEXT_LIMIT, AppSqliteError, AppSqliteStore, BuyerRepeatDemandApplyOutcome, - DatabaseTarget, StoredPendingSyncOperation, StoredSyncConflict, derive_farm_rules_readiness, + derive_farm_rules_readiness, AppSqliteError, AppSqliteStore, BuyerRepeatDemandApplyOutcome, + DatabaseTarget, StoredPendingSyncOperation, StoredSyncConflict, APP_ACTIVITY_CONTEXT_LIMIT, }; use radroots_app_state::{ - APP_STATE_FILE_NAME, AppShellProjection, AppStateCommand, AppStatePersistenceRepository, + derive_sync_projection, AppShellProjection, AppStateCommand, AppStatePersistenceRepository, AppStateStore, AppStateStoreError, BuyerBrowseScreenProjection, BuyerCartScreenProjection, BuyerOrdersScreenProjection, BuyerSearchScreenProjection, BuyerSearchScreenQueryState, FarmSetupFlowStage, FarmWorkspaceReadinessProjection, HomeRoute, OrdersScreenProjection, PackDayExportRequest, PackDayHostHandoffRequest, PackDayPrintRequest, PackDayScreenProjection, PersistedAppState, PersonalWorkspaceProjection, ProductsScreenProjection, - ProductsScreenQueryState, derive_sync_projection, + ProductsScreenQueryState, APP_STATE_FILE_NAME, }; use radroots_app_sync::{ AppSyncProjection, AppSyncRequest, AppSyncResult, AppSyncTransport, AppSyncTransportError, @@ -54,19 +54,23 @@ use tracing::error; use uuid::Uuid; use crate::accounts::{ - DesktopAccountsBootstrapError, DesktopAccountsCommandError, DesktopAccountsProjectionError, - DesktopLocalIdentityImportRequest, bootstrap_desktop_accounts, generate_local_account, - identity_projection_from_manager, import_local_account, remove_selected_local_key, - reset_local_device_state, select_active_surface, select_local_account, + bootstrap_desktop_accounts, generate_local_account, identity_projection_from_manager, + import_local_account, remove_selected_local_key, reset_local_device_state, + select_active_surface, select_local_account, DesktopAccountsBootstrapError, + DesktopAccountsCommandError, DesktopAccountsProjectionError, DesktopLocalIdentityImportRequest, }; use crate::pack_day_host_handoff::{ - PackDayHostHandoffCommandPlan, PackDayHostHandoffError, plan_pack_day_host_handoff, + plan_pack_day_host_handoff, PackDayHostHandoffCommandPlan, PackDayHostHandoffError, +}; +use crate::pack_day_print::{ + cleanup_prepared_customer_label_asset_root, + cleanup_prepared_customer_label_assets_for_export_instance, plan_pack_day_print, + PackDayPrintCommandPlan, PackDayPrintError, }; -use crate::pack_day_print::{PackDayPrintCommandPlan, PackDayPrintError, plan_pack_day_print}; use crate::remote_signer::{ - DesktopRemoteSignerError, DesktopRemoteSignerPaths, activate_pending_session, - apply_remote_signer_custody, clear_pending_session, load_pending_session, purge_all_state, - reconcile_startup, store_pending_session, + activate_pending_session, apply_remote_signer_custody, clear_pending_session, + load_pending_session, purge_all_state, reconcile_startup, store_pending_session, + DesktopRemoteSignerError, DesktopRemoteSignerPaths, }; const APP_DATABASE_FILE_NAME: &str = "app.sqlite3"; @@ -884,6 +888,14 @@ impl DesktopAppRuntimeState { default_nostr_relay_url: String, runtime_snapshot: AppRuntimeSnapshot, ) -> Result<Self, DesktopAppRuntimeBootstrapError> { + if let Err(error) = cleanup_prepared_customer_label_asset_root() { + error!( + target: "pack_day", + event = "pack_day.print_prepared_asset_bootstrap_sweep_failed", + error = %error, + "failed to sweep prepared pack day print assets during bootstrap" + ); + } let database_path = paths.app.data.join(APP_DATABASE_FILE_NAME); let sqlite_store = AppSqliteStore::open(DatabaseTarget::Path(database_path.clone()))?; let database_schema_version = sqlite_store.schema_version()?; @@ -1777,6 +1789,7 @@ impl DesktopAppRuntimeState { let Some(farm_id) = self.selected_farm_id() else { return Ok(false); }; + let previous_export_instance_id = self.current_pack_day_export_instance_id(); let Some(fulfillment_window_id) = self .state_store .pack_day_projection() @@ -1808,6 +1821,10 @@ impl DesktopAppRuntimeState { let _ = self .state_store .apply_in_memory(AppStateCommand::begin_pack_day_export(request.clone())); + self.cleanup_prepared_pack_day_print_assets_if_export_changed( + previous_export_instance_id, + "export_reset", + ); let prepared = prepare_pack_day_export_bundle_at_data_root(data_root.as_path(), &source, Utc::now()); @@ -1911,14 +1928,32 @@ impl DesktopAppRuntimeState { return Ok(false); } + let cleanup_export_instance_id = (request.kind == PackDayPrintKind::PrintCustomerLabels) + .then_some(request.export_instance_id); + match result { - Ok(()) => Ok(self - .state_store - .apply_in_memory(AppStateCommand::succeed_pack_day_print(request))), + Ok(()) => { + let changed = self + .state_store + .apply_in_memory(AppStateCommand::succeed_pack_day_print(request)); + if let Some(export_instance_id) = cleanup_export_instance_id { + self.cleanup_prepared_pack_day_print_assets_for_export_instance( + export_instance_id, + "print_completion", + ); + } + Ok(changed) + } Err(error) => { let _ = self .state_store .apply_in_memory(AppStateCommand::fail_pack_day_print(request)); + if let Some(export_instance_id) = cleanup_export_instance_id { + self.cleanup_prepared_pack_day_print_assets_for_export_instance( + export_instance_id, + "print_completion", + ); + } Err(error.into()) } } @@ -2348,6 +2383,7 @@ impl DesktopAppRuntimeState { context: &DesktopSelectedAccountContext, include_personal: bool, ) -> bool { + let previous_export_instance_id = self.current_pack_day_export_instance_id(); let personal_changed = if include_personal { self.state_store .apply_in_memory(AppStateCommand::replace_personal_projection( @@ -2447,6 +2483,10 @@ impl DesktopAppRuntimeState { self.close_product_editor() }; let shell_changed = self.sync_truthful_farmer_section(); + self.cleanup_prepared_pack_day_print_assets_if_export_changed( + previous_export_instance_id, + "context_refresh", + ); personal_changed || farm_setup_changed @@ -3128,6 +3168,7 @@ impl DesktopAppRuntimeState { &mut self, query: PackDayScreenQueryState, ) -> Result<bool, AppSqliteError> { + let previous_export_instance_id = self.current_pack_day_export_instance_id(); let fulfillment_window_changed = self.state_store .apply_in_memory(AppStateCommand::set_pack_day_fulfillment_window( @@ -3143,6 +3184,10 @@ impl DesktopAppRuntimeState { &continuity_state, )?; let context_changed = self.apply_selected_account_context(&selected_account_context); + self.cleanup_prepared_pack_day_print_assets_if_export_changed( + previous_export_instance_id, + "query_reset", + ); Ok(fulfillment_window_changed || context_changed) } @@ -3261,6 +3306,46 @@ impl DesktopAppRuntimeState { (fulfillment_window.fulfillment_window_id == bundle.fulfillment_window_id).then_some(bundle) } + fn current_pack_day_export_instance_id(&self) -> Option<PackDayExportInstanceId> { + self.current_pack_day_export_bundle() + .map(|bundle| bundle.export_instance_id) + } + + fn cleanup_prepared_pack_day_print_assets_for_export_instance( + &self, + export_instance_id: PackDayExportInstanceId, + trigger: &'static str, + ) { + if let Err(error) = + cleanup_prepared_customer_label_assets_for_export_instance(export_instance_id) + { + error!( + target: "pack_day", + event = "pack_day.print_prepared_asset_cleanup_failed", + trigger, + export_instance_id = %export_instance_id, + error = %error, + "failed to clean prepared pack day print assets" + ); + } + } + + fn cleanup_prepared_pack_day_print_assets_if_export_changed( + &self, + previous_export_instance_id: Option<PackDayExportInstanceId>, + trigger: &'static str, + ) { + let current_export_instance_id = self.current_pack_day_export_instance_id(); + if let Some(export_instance_id) = previous_export_instance_id + .filter(|export_instance_id| Some(*export_instance_id) != current_export_instance_id) + { + self.cleanup_prepared_pack_day_print_assets_for_export_instance( + export_instance_id, + trigger, + ); + } + } + fn current_pack_day_host_handoff_request_matches( &self, request: &PackDayHostHandoffRequest, @@ -4624,23 +4709,23 @@ mod tests { FarmOperatingRulesRecord, FarmOrderMethod, FarmProfileRecord, FarmReadiness, FarmReadinessBlocker, FarmSetupDraft, FarmSetupProjection, FarmSummary, FarmerActivationProjection, FarmerSection, FulfillmentWindowId, FulfillmentWindowRecord, - LoggedOutStartupProjection, OrderId, OrderStatus, OrdersFilter, PackDayExportStatus, - PackDayHostHandoffKind, PackDayHostHandoffStatus, PackDayPackListRow, PackDayPrintKind, - PackDayPrintStatus, PackDayProductTotalRow, PackDayProjection, PackDayRosterRow, - PersonalSection, PickupLocationId, PickupLocationRecord, ProductEditorDraft, ProductStatus, - ProductsFilter, ProductsSort, RecoveryKind, RecoveryRecordId, ReminderDeliveryState, - ReminderFeedProjection, ReminderKind, SelectedSurfaceProjection, SettingsPreference, - SettingsSection, ShellSection, TodayAgendaProjection, TodaySetupTask, TodaySetupTaskKind, - TodaySummary, + LoggedOutStartupProjection, OrderId, OrderStatus, OrdersFilter, PackDayExportInstanceId, + PackDayExportStatus, PackDayHostHandoffKind, PackDayHostHandoffStatus, PackDayPackListRow, + PackDayPrintKind, PackDayPrintStatus, PackDayProductTotalRow, PackDayProjection, + PackDayRosterRow, PersonalSection, PickupLocationId, PickupLocationRecord, + ProductEditorDraft, ProductStatus, ProductsFilter, ProductsSort, RecoveryKind, + RecoveryRecordId, ReminderDeliveryState, ReminderFeedProjection, ReminderKind, + SelectedSurfaceProjection, SettingsPreference, SettingsSection, ShellSection, + TodayAgendaProjection, TodaySetupTask, TodaySetupTaskKind, TodaySummary, }; use radroots_app_remote_signer::{ RadrootsAppRemoteSignerPendingSession, RadrootsAppRemoteSignerSessionRecord, }; - use radroots_app_sqlite::{AppSqliteStore, DatabaseTarget, latest_schema_version}; + use radroots_app_sqlite::{latest_schema_version, AppSqliteStore, DatabaseTarget}; use radroots_app_state::{ - APP_STATE_FILE_NAME, AppStateCommand, AppStatePersistenceRepository, AppStateRepository, + AppStateCommand, AppStatePersistenceRepository, AppStateRepository, AppStateRepositoryError, AppStateStore, AppStateStoreError, FileBackedAppStateRepository, - HomeRoute, + HomeRoute, APP_STATE_FILE_NAME, }; use radroots_app_sync::{ AppSyncRequest, AppSyncResult, AppSyncRunStatus, AppSyncTransport, AppSyncTransportError, @@ -4657,13 +4742,13 @@ mod tests { use crate::accounts::DesktopLocalIdentityImportRequest; use super::{ - APP_DATABASE_FILE_NAME, DesktopAppRuntime, DesktopAppRuntimeActivityContextError, + default_sync_transport, DesktopAppRuntime, DesktopAppRuntimeActivityContextError, DesktopAppRuntimeCommandError, DesktopAppRuntimeMetadataSummary, DesktopAppRuntimeState, - DesktopAppSyncStatusSummary, DesktopRemoteSignerPaths, SYNC_TRANSPORT_UNAVAILABLE_MESSAGE, - default_sync_transport, + DesktopAppSyncStatusSummary, DesktopRemoteSignerPaths, APP_DATABASE_FILE_NAME, + SYNC_TRANSPORT_UNAVAILABLE_MESSAGE, }; use crate::pack_day_host_handoff::PackDayHostHandoffError; - use crate::pack_day_print::PackDayPrintError; + use crate::pack_day_print::{prepared_customer_label_asset_root, PackDayPrintError}; #[derive(Clone)] struct SharedRecordedSyncTransport(Arc<Mutex<RecordedAppSyncTransport>>); @@ -4775,12 +4860,10 @@ mod tests { assert_eq!(summary.startup_gate, AppStartupGate::SetupRequired); assert_eq!(summary.home_route, HomeRoute::SetupRequired); assert!(summary.settings_account_projection.roster.is_empty()); - assert!( - summary - .settings_account_projection - .selected_account - .is_none() - ); + assert!(summary + .settings_account_projection + .selected_account + .is_none()); assert_eq!( summary.logged_out_startup, LoggedOutStartupProjection::default() @@ -4888,12 +4971,10 @@ mod tests { .expect("pending sync operation should save"); } - assert!( - runtime - .lock_state_mut() - .refresh_selected_account_sync() - .expect("sync status should refresh") - ); + assert!(runtime + .lock_state_mut() + .refresh_selected_account_sync() + .expect("sync status should refresh")); let summary = runtime.summary(); @@ -4947,11 +5028,9 @@ mod tests { }), ); - assert!( - runtime - .open_new_product_editor() - .expect("new product editor should open") - ); + assert!(runtime + .open_new_product_editor() + .expect("new product editor should open")); let summary = runtime.summary(); let pending_operations = runtime @@ -4976,11 +5055,9 @@ mod tests { let runtime = memory_runtime(); let (account_id, _) = provision_ready_farmer_account(&runtime); - assert!( - runtime - .open_new_product_editor() - .expect("new product editor should open") - ); + assert!(runtime + .open_new_product_editor() + .expect("new product editor should open")); let recorded = install_recorded_sync_transport( &runtime, @@ -4997,11 +5074,9 @@ mod tests { }), ); - assert!( - runtime - .sync_on_app_launch() - .expect("launch sync should succeed") - ); + assert!(runtime + .sync_on_app_launch() + .expect("launch sync should succeed")); let summary = runtime.summary(); let recorded = recorded.lock().expect("recorded transport"); @@ -5040,11 +5115,9 @@ mod tests { let runtime = memory_runtime(); let (_, _) = provision_ready_farmer_account(&runtime); - assert!( - runtime - .open_new_product_editor() - .expect("new product editor should open") - ); + assert!(runtime + .open_new_product_editor() + .expect("new product editor should open")); let recorded = install_recorded_sync_transport( &runtime, @@ -5061,11 +5134,9 @@ mod tests { }), ); - assert!( - runtime - .sync_on_foreground_resume() - .expect("resume sync should succeed") - ); + assert!(runtime + .sync_on_foreground_resume() + .expect("resume sync should succeed")); let request = recorded .lock() @@ -5082,17 +5153,13 @@ mod tests { let runtime = memory_runtime(); let (account_id, _) = provision_ready_farmer_account(&runtime); - assert!( - runtime - .open_new_product_editor() - .expect("new product editor should open") - ); + assert!(runtime + .open_new_product_editor() + .expect("new product editor should open")); - assert!( - runtime - .sync_on_manual_refresh() - .expect("manual refresh should complete") - ); + assert!(runtime + .sync_on_manual_refresh() + .expect("manual refresh should complete")); let summary = runtime.summary(); let pending_operations = runtime @@ -5112,15 +5179,13 @@ mod tests { SyncCheckpointState::Failed ); assert_eq!(summary.sync_status.pending_write_count, 1); - assert!( - summary - .sync_status - .projection - .checkpoint - .last_error_message - .as_deref() - .is_some_and(|message| { message.contains(SYNC_TRANSPORT_UNAVAILABLE_MESSAGE) }) - ); + assert!(summary + .sync_status + .projection + .checkpoint + .last_error_message + .as_deref() + .is_some_and(|message| { message.contains(SYNC_TRANSPORT_UNAVAILABLE_MESSAGE) })); assert_eq!(pending_operations.len(), 1); assert_eq!(pending_operations[0].operation.attempt_count, 1); } @@ -5130,11 +5195,9 @@ mod tests { let runtime = memory_runtime(); let (account_id, farm_id) = provision_ready_farmer_account(&runtime); - assert!( - runtime - .open_new_product_editor() - .expect("new product editor should open") - ); + assert!(runtime + .open_new_product_editor() + .expect("new product editor should open")); runtime .lock_state() @@ -5155,12 +5218,10 @@ mod tests { }, ) .expect("blocking conflict should save"); - assert!( - runtime - .lock_state_mut() - .refresh_selected_account_sync() - .expect("sync status should refresh") - ); + assert!(runtime + .lock_state_mut() + .refresh_selected_account_sync() + .expect("sync status should refresh")); let recorded = install_recorded_sync_transport( &runtime, @@ -5177,11 +5238,9 @@ mod tests { }), ); - assert!( - !runtime - .sync_on_app_launch() - .expect("blocked launch sync should skip") - ); + assert!(!runtime + .sync_on_app_launch() + .expect("blocked launch sync should skip")); let summary = runtime.summary(); @@ -5225,21 +5284,17 @@ mod tests { }, ) .expect("blocking conflict should save"); - assert!( - runtime - .lock_state_mut() - .refresh_selected_account_sync() - .expect("sync status should refresh") - ); + assert!(runtime + .lock_state_mut() + .refresh_selected_account_sync() + .expect("sync status should refresh")); - assert!( - runtime - .resolve_sync_conflict( - conflict_id.as_str(), - SyncConflictResolutionStatus::AcceptedLocal, - ) - .expect("conflict resolution should succeed") - ); + assert!(runtime + .resolve_sync_conflict( + conflict_id.as_str(), + SyncConflictResolutionStatus::AcceptedLocal, + ) + .expect("conflict resolution should succeed")); let summary = runtime.summary(); @@ -5264,13 +5319,11 @@ mod tests { summary.sync_status.conflicts[0].conflict.resolution, SyncConflictResolutionStatus::AcceptedLocal ); - assert!( - summary.sync_status.conflicts[0] - .conflict - .resolved_at - .as_deref() - .is_some() - ); + assert!(summary.sync_status.conflicts[0] + .conflict + .resolved_at + .as_deref() + .is_some()); } #[test] @@ -5278,11 +5331,9 @@ mod tests { let runtime = memory_runtime(); let (account_id, farm_id) = provision_ready_farmer_account(&runtime); - assert!( - runtime - .open_new_product_editor() - .expect("new product editor should open") - ); + assert!(runtime + .open_new_product_editor() + .expect("new product editor should open")); runtime .lock_state() @@ -5303,12 +5354,10 @@ mod tests { }, ) .expect("review-required conflict should save"); - assert!( - runtime - .lock_state_mut() - .refresh_selected_account_sync() - .expect("sync status should refresh") - ); + assert!(runtime + .lock_state_mut() + .refresh_selected_account_sync() + .expect("sync status should refresh")); let recorded = install_recorded_sync_transport( &runtime, @@ -5325,11 +5374,9 @@ mod tests { }), ); - assert!( - runtime - .sync_on_manual_refresh() - .expect("manual refresh should succeed") - ); + assert!(runtime + .sync_on_manual_refresh() + .expect("manual refresh should succeed")); let recorded = recorded.lock().expect("recorded transport"); let request = recorded @@ -5422,11 +5469,9 @@ mod tests { startup_issue: None, }); - assert!( - runtime - .clear_startup_pending_remote_signer_session() - .expect("clear pending should succeed") - ); + assert!(runtime + .clear_startup_pending_remote_signer_session() + .expect("clear pending should succeed")); assert!(runtime.begin_generate_key_startup()); assert_eq!( runtime.summary().logged_out_startup.phase, @@ -5441,11 +5486,9 @@ mod tests { let (runtime, paths) = bootstrapped_runtime("restart_pending_recovery"); let pending_session = fixture_pending_session(); - assert!( - runtime - .store_startup_pending_remote_signer_session(&pending_session) - .expect("store pending should succeed") - ); + assert!(runtime + .store_startup_pending_remote_signer_session(&pending_session) + .expect("store pending should succeed")); let restarted = restart_runtime(paths.clone()); let restored = restarted @@ -5474,16 +5517,12 @@ mod tests { let (runtime, paths) = bootstrapped_runtime("restart_after_explicit_cancel"); let pending_session = fixture_pending_session(); - assert!( - runtime - .store_startup_pending_remote_signer_session(&pending_session) - .expect("store pending should succeed") - ); - assert!( - runtime - .clear_startup_pending_remote_signer_session() - .expect("clear pending should succeed") - ); + assert!(runtime + .store_startup_pending_remote_signer_session(&pending_session) + .expect("store pending should succeed")); + assert!(runtime + .clear_startup_pending_remote_signer_session() + .expect("clear pending should succeed")); let restarted = restart_runtime(paths.clone()); @@ -5549,11 +5588,9 @@ mod tests { let (runtime, paths) = bootstrapped_runtime("restart_buyer_search_detail"); let (account_id, farm_id) = provision_ready_farmer_account(&runtime); - assert!( - runtime - .select_active_surface(ActiveSurface::Personal) - .expect("surface should switch into marketplace") - ); + assert!(runtime + .select_active_surface(ActiveSurface::Personal) + .expect("surface should switch into marketplace")); let fulfillment_window_id = seed_buyer_marketplace_support( &runtime, account_id.as_str(), @@ -5583,16 +5620,12 @@ mod tests { )) .expect("buyer detail product should attach a fulfillment window"); - assert!( - runtime - .set_personal_search_query("salad") - .expect("buyer search query should update") - ); - assert!( - runtime - .open_personal_product_detail(PersonalSection::Search, product_id) - .expect("buyer search detail should open") - ); + assert!(runtime + .set_personal_search_query("salad") + .expect("buyer search query should update")); + assert!(runtime + .open_personal_product_detail(PersonalSection::Search, product_id) + .expect("buyer search detail should open")); let restarted = restart_runtime(paths.clone()); let summary = restarted.summary(); @@ -5632,26 +5665,18 @@ mod tests { "2026-04-20T09:30:00Z", ); - assert!( - runtime - .set_products_search_query("pea") - .expect("products query should update") - ); - assert!( - runtime - .select_products_filter(ProductsFilter::Drafts) - .expect("products filter should update") - ); - assert!( - runtime - .select_products_sort(ProductsSort::Name) - .expect("products sort should update") - ); - assert!( - runtime - .open_existing_product_editor(product_id) - .expect("product editor should open") - ); + assert!(runtime + .set_products_search_query("pea") + .expect("products query should update")); + assert!(runtime + .select_products_filter(ProductsFilter::Drafts) + .expect("products filter should update")); + assert!(runtime + .select_products_sort(ProductsSort::Name) + .expect("products sort should update")); + assert!(runtime + .open_existing_product_editor(product_id) + .expect("product editor should open")); let restarted = restart_runtime(paths.clone()); let summary = restarted.summary(); @@ -5697,16 +5722,12 @@ mod tests { )) .expect("order should update to packed"); - assert!( - runtime - .select_orders_filter(OrdersFilter::Packed) - .expect("orders filter should update") - ); - assert!( - runtime - .open_order_detail(order_id) - .expect("order detail should open") - ); + assert!(runtime + .select_orders_filter(OrdersFilter::Packed) + .expect("orders filter should update")); + assert!(runtime + .open_order_detail(order_id) + .expect("order detail should open")); let restarted = restart_runtime(paths.clone()); let summary = restarted.summary(); @@ -5734,11 +5755,9 @@ mod tests { let (_, farm_id) = provision_ready_farmer_account(&runtime); let (fulfillment_window_id, _) = seed_order_workspace(&runtime, farm_id); - assert!( - runtime - .open_orders_fulfillment_window(fulfillment_window_id) - .expect("orders window should open") - ); + assert!(runtime + .open_orders_fulfillment_window(fulfillment_window_id) + .expect("orders window should open")); let mut persisted_state = runtime.lock_state().state_store.persisted_state().clone(); persisted_state.seller.orders_query.fulfillment_window_id = Some(FulfillmentWindowId::new()); @@ -5756,14 +5775,12 @@ mod tests { ShellSection::Farmer(FarmerSection::Orders) ); assert_eq!(summary.orders_projection.query.fulfillment_window_id, None); - assert!( - summary - .orders_projection - .list - .rows - .iter() - .any(|row| { row.fulfillment_window_id == Some(fulfillment_window_id) }) - ); + assert!(summary + .orders_projection + .list + .rows + .iter() + .any(|row| { row.fulfillment_window_id == Some(fulfillment_window_id) })); cleanup_bootstrapped_runtime_paths(&paths); } @@ -5796,13 +5813,11 @@ mod tests { summary.pack_day_projection.query.fulfillment_window_id, None ); - assert!( - summary - .pack_day_projection - .projection - .fulfillment_window - .is_some() - ); + assert!(summary + .pack_day_projection + .projection + .fulfillment_window + .is_some()); assert_ne!( summary.pack_day_projection.query.fulfillment_window_id, Some(stale_fulfillment_window_id) @@ -6073,34 +6088,28 @@ mod tests { let _ = provision_ready_farmer_account(&runtime); assert!(!runtime.select_farmer_section(FarmerSection::PackDay)); - assert!( - !runtime - .open_pack_day(None) - .expect("pack day route should stay blocked") - ); + assert!(!runtime + .open_pack_day(None) + .expect("pack day route should stay blocked")); assert_eq!( runtime.summary().shell_projection.selected_section, ShellSection::Farmer(FarmerSection::Today) ); - assert!( - runtime - .summary() - .pack_day_projection - .projection - .fulfillment_window - .is_none() - ); + assert!(runtime + .summary() + .pack_day_projection + .projection + .fulfillment_window + .is_none()); } #[test] fn runtime_routes_between_farmer_home_and_products_through_explicit_methods() { let runtime = memory_runtime(); - assert!( - runtime - .generate_local_account(Some("Farmer".to_owned())) - .expect("account should generate") - ); + assert!(runtime + .generate_local_account(Some("Farmer".to_owned())) + .expect("account should generate")); let account_id = runtime .summary() .settings_account_projection @@ -6136,11 +6145,9 @@ mod tests { .expect("sqlite store") .save_farm_setup(account_id.as_str(), &farm_setup_projection) .expect("farm setup should save"); - assert!( - runtime - .select_local_account(account_id.as_str()) - .expect("account should select") - ); + assert!(runtime + .select_local_account(account_id.as_str()) + .expect("account should select")); assert!(runtime.select_farmer_section(FarmerSection::Products)); assert_eq!( @@ -6277,20 +6284,16 @@ mod tests { .expect("account should refresh after buyer workspace seeding"); let summary = runtime.summary(); assert_eq!(summary.personal_projection.search.listings.rows.len(), 2); - assert!( - summary - .personal_projection - .search - .query - .fulfillment_methods - .is_empty() - ); - - assert!( - runtime - .set_personal_search_query("pea") - .expect("buyer search query should apply") - ); + assert!(summary + .personal_projection + .search + .query + .fulfillment_methods + .is_empty()); + + assert!(runtime + .set_personal_search_query("pea") + .expect("buyer search query should apply")); let searched = runtime.summary(); assert_eq!(searched.personal_projection.search.listings.rows.len(), 1); assert_eq!( @@ -6298,11 +6301,9 @@ mod tests { "Pea shoots" ); - assert!( - runtime - .set_personal_search_fulfillment_method(FarmOrderMethod::Pickup, true) - .expect("buyer fulfillment filter should apply") - ); + assert!(runtime + .set_personal_search_fulfillment_method(FarmOrderMethod::Pickup, true) + .expect("buyer fulfillment filter should apply")); let filtered = runtime.summary(); assert_eq!( filtered @@ -6325,11 +6326,9 @@ mod tests { fn runtime_personal_product_detail_adds_to_cart_and_routes_into_cart() { let runtime = memory_runtime(); let (account_id, farm_id) = provision_ready_farmer_account(&runtime); - assert!( - runtime - .select_active_surface(ActiveSurface::Personal) - .expect("surface should switch into marketplace") - ); + assert!(runtime + .select_active_surface(ActiveSurface::Personal) + .expect("surface should switch into marketplace")); let fulfillment_window_id = seed_buyer_marketplace_support( &runtime, account_id.as_str(), @@ -6359,17 +6358,13 @@ mod tests { )) .expect("buyer detail product should attach a fulfillment window"); - assert!( - runtime - .open_personal_product_detail(PersonalSection::Browse, product_id) - .expect("buyer detail should open") - ); + assert!(runtime + .open_personal_product_detail(PersonalSection::Browse, product_id) + .expect("buyer detail should open")); assert!(runtime.increase_personal_product_quantity(PersonalSection::Browse)); - assert!( - runtime - .add_personal_product_to_cart(PersonalSection::Browse, false) - .expect("buyer product should add to cart") - ); + assert!(runtime + .add_personal_product_to_cart(PersonalSection::Browse, false) + .expect("buyer product should add to cart")); let summary = runtime.summary(); assert_eq!( @@ -6395,14 +6390,12 @@ mod tests { .as_deref(), Some("North field farm") ); - assert!( - summary - .personal_projection - .cart - .cart - .replace_confirmation - .is_none() - ); + assert!(summary + .personal_projection + .cart + .cart + .replace_confirmation + .is_none()); assert_eq!( summary .personal_projection @@ -6419,11 +6412,9 @@ mod tests { fn runtime_cross_farm_buyer_add_requires_replace_confirmation() { let runtime = memory_runtime(); let (account_id, farm_id) = provision_ready_farmer_account(&runtime); - assert!( - runtime - .select_active_surface(ActiveSurface::Personal) - .expect("surface should switch into marketplace") - ); + assert!(runtime + .select_active_surface(ActiveSurface::Personal) + .expect("surface should switch into marketplace")); let first_window_id = seed_buyer_marketplace_support( &runtime, account_id.as_str(), @@ -6452,16 +6443,12 @@ mod tests { where id = '{first_product_id}'" )) .expect("first product should attach a fulfillment window"); - assert!( - runtime - .open_personal_product_detail(PersonalSection::Browse, first_product_id) - .expect("first buyer detail should open") - ); - assert!( - runtime - .add_personal_product_to_cart(PersonalSection::Browse, false) - .expect("first buyer product should add to cart") - ); + assert!(runtime + .open_personal_product_detail(PersonalSection::Browse, first_product_id) + .expect("first buyer detail should open")); + assert!(runtime + .add_personal_product_to_cart(PersonalSection::Browse, false) + .expect("first buyer product should add to cart")); let other_farm_id = FarmId::new(); runtime @@ -6504,16 +6491,12 @@ mod tests { )) .expect("second product should attach a fulfillment window"); - assert!( - runtime - .open_personal_product_detail(PersonalSection::Browse, second_product_id) - .expect("second buyer detail should open") - ); - assert!( - runtime - .add_personal_product_to_cart(PersonalSection::Browse, false) - .expect("cross-farm add should require confirmation") - ); + assert!(runtime + .open_personal_product_detail(PersonalSection::Browse, second_product_id) + .expect("second buyer detail should open")); + assert!(runtime + .add_personal_product_to_cart(PersonalSection::Browse, false) + .expect("cross-farm add should require confirmation")); let confirmation_summary = runtime.summary(); assert_eq!( @@ -6545,11 +6528,9 @@ mod tests { "Willow Farm" ); - assert!( - runtime - .add_personal_product_to_cart(PersonalSection::Browse, true) - .expect("confirmed cross-farm add should replace the cart") - ); + assert!(runtime + .add_personal_product_to_cart(PersonalSection::Browse, true) + .expect("confirmed cross-farm add should replace the cart")); let replaced_summary = runtime.summary(); assert_eq!( replaced_summary.shell_projection.selected_section, @@ -6572,25 +6553,21 @@ mod tests { .as_deref(), Some("Willow Farm") ); - assert!( - replaced_summary - .personal_projection - .cart - .cart - .replace_confirmation - .is_none() - ); + assert!(replaced_summary + .personal_projection + .cart + .cart + .replace_confirmation + .is_none()); } #[test] fn runtime_removing_buyer_cart_line_clears_cart_and_checkout_readiness() { let runtime = memory_runtime(); let (account_id, farm_id) = provision_ready_farmer_account(&runtime); - assert!( - runtime - .select_active_surface(ActiveSurface::Personal) - .expect("surface should switch into marketplace") - ); + assert!(runtime + .select_active_surface(ActiveSurface::Personal) + .expect("surface should switch into marketplace")); let fulfillment_window_id = seed_buyer_marketplace_support( &runtime, account_id.as_str(), @@ -6619,22 +6596,16 @@ mod tests { where id = '{product_id}'" )) .expect("buyer detail product should attach a fulfillment window"); - assert!( - runtime - .open_personal_product_detail(PersonalSection::Browse, product_id) - .expect("buyer detail should open") - ); - assert!( - runtime - .add_personal_product_to_cart(PersonalSection::Browse, false) - .expect("buyer product should add to cart") - ); + assert!(runtime + .open_personal_product_detail(PersonalSection::Browse, product_id) + .expect("buyer detail should open")); + assert!(runtime + .add_personal_product_to_cart(PersonalSection::Browse, false) + .expect("buyer product should add to cart")); - assert!( - runtime - .remove_personal_cart_line(product_id) - .expect("buyer cart line should remove") - ); + assert!(runtime + .remove_personal_cart_line(product_id) + .expect("buyer cart line should remove")); let summary = runtime.summary(); assert!(summary.personal_projection.cart.cart.lines.is_empty()); @@ -6650,11 +6621,9 @@ mod tests { fn runtime_places_buyer_order_and_routes_into_personal_orders() { let runtime = memory_runtime(); let (account_id, farm_id) = provision_ready_farmer_account(&runtime); - assert!( - runtime - .select_active_surface(ActiveSurface::Personal) - .expect("surface should switch into marketplace") - ); + assert!(runtime + .select_active_surface(ActiveSurface::Personal) + .expect("surface should switch into marketplace")); let fulfillment_window_id = seed_buyer_marketplace_support( &runtime, account_id.as_str(), @@ -6683,31 +6652,23 @@ mod tests { where id = '{product_id}'" )) .expect("buyer detail product should attach a fulfillment window"); - assert!( - runtime - .open_personal_product_detail(PersonalSection::Browse, product_id) - .expect("buyer detail should open") - ); - assert!( - runtime - .add_personal_product_to_cart(PersonalSection::Browse, false) - .expect("buyer product should add to cart") - ); - assert!( - runtime - .save_personal_checkout_draft(BuyerCheckoutDraft { - name: "Casey Buyer".to_owned(), - email: "casey@example.com".to_owned(), - phone: "555-0101".to_owned(), - order_note: "Leave by the cooler".to_owned(), - }) - .expect("buyer checkout draft should save") - ); - assert!( - runtime - .place_personal_order() - .expect("buyer order should place") - ); + assert!(runtime + .open_personal_product_detail(PersonalSection::Browse, product_id) + .expect("buyer detail should open")); + assert!(runtime + .add_personal_product_to_cart(PersonalSection::Browse, false) + .expect("buyer product should add to cart")); + assert!(runtime + .save_personal_checkout_draft(BuyerCheckoutDraft { + name: "Casey Buyer".to_owned(), + email: "casey@example.com".to_owned(), + phone: "555-0101".to_owned(), + order_note: "Leave by the cooler".to_owned(), + }) + .expect("buyer checkout draft should save")); + assert!(runtime + .place_personal_order() + .expect("buyer order should place")); let summary = runtime.summary(); assert_eq!( @@ -6754,11 +6715,9 @@ mod tests { fn runtime_opens_buyer_order_detail_from_personal_orders() { let runtime = memory_runtime(); let (account_id, farm_id) = provision_ready_farmer_account(&runtime); - assert!( - runtime - .select_active_surface(ActiveSurface::Personal) - .expect("surface should switch into marketplace") - ); + assert!(runtime + .select_active_surface(ActiveSurface::Personal) + .expect("surface should switch into marketplace")); let fulfillment_window_id = seed_buyer_marketplace_support( &runtime, account_id.as_str(), @@ -6787,40 +6746,30 @@ mod tests { where id = '{product_id}'" )) .expect("buyer detail product should attach a fulfillment window"); - assert!( - runtime - .open_personal_product_detail(PersonalSection::Browse, product_id) - .expect("buyer detail should open") - ); - assert!( - runtime - .add_personal_product_to_cart(PersonalSection::Browse, false) - .expect("buyer product should add to cart") - ); - assert!( - runtime - .save_personal_checkout_draft(BuyerCheckoutDraft { - name: "Casey Buyer".to_owned(), - email: "casey@example.com".to_owned(), - phone: String::new(), - order_note: String::new(), - }) - .expect("buyer checkout draft should save") - ); - assert!( - runtime - .place_personal_order() - .expect("buyer order should place") - ); + assert!(runtime + .open_personal_product_detail(PersonalSection::Browse, product_id) + .expect("buyer detail should open")); + assert!(runtime + .add_personal_product_to_cart(PersonalSection::Browse, false) + .expect("buyer product should add to cart")); + assert!(runtime + .save_personal_checkout_draft(BuyerCheckoutDraft { + name: "Casey Buyer".to_owned(), + email: "casey@example.com".to_owned(), + phone: String::new(), + order_note: String::new(), + }) + .expect("buyer checkout draft should save")); + assert!(runtime + .place_personal_order() + .expect("buyer order should place")); let order_id = runtime.summary().personal_projection.orders.list.rows[0].order_id; assert!(runtime.select_personal_section(PersonalSection::Browse)); assert!(runtime.lock_state_mut().set_personal_order_detail(None)); - assert!( - runtime - .open_personal_order_detail(order_id) - .expect("buyer order detail should open") - ); + assert!(runtime + .open_personal_order_detail(order_id) + .expect("buyer order detail should open")); let summary = runtime.summary(); assert_eq!( @@ -6843,11 +6792,9 @@ mod tests { fn runtime_repeat_personal_order_readds_only_currently_eligible_items() { let runtime = memory_runtime(); let (account_id, farm_id) = provision_ready_farmer_account(&runtime); - assert!( - runtime - .select_active_surface(ActiveSurface::Personal) - .expect("surface should switch into marketplace") - ); + assert!(runtime + .select_active_surface(ActiveSurface::Personal) + .expect("surface should switch into marketplace")); let fulfillment_window_id = seed_buyer_marketplace_support( &runtime, account_id.as_str(), @@ -6885,41 +6832,29 @@ mod tests { where id in ('{available_product_id}', '{unavailable_product_id}')" )) .expect("buyer detail products should attach a fulfillment window"); - assert!( - runtime - .open_personal_product_detail(PersonalSection::Browse, available_product_id) - .expect("available buyer detail should open") - ); - assert!( - runtime - .add_personal_product_to_cart(PersonalSection::Browse, false) - .expect("available buyer product should add to cart") - ); - assert!( - runtime - .open_personal_product_detail(PersonalSection::Browse, unavailable_product_id) - .expect("unavailable buyer detail should open") - ); - assert!( - runtime - .add_personal_product_to_cart(PersonalSection::Browse, false) - .expect("second buyer product should add to cart") - ); - assert!( - runtime - .save_personal_checkout_draft(BuyerCheckoutDraft { - name: "Casey Buyer".to_owned(), - email: "casey@example.com".to_owned(), - phone: String::new(), - order_note: String::new(), - }) - .expect("buyer checkout draft should save") - ); - assert!( - runtime - .place_personal_order() - .expect("buyer order should place") - ); + assert!(runtime + .open_personal_product_detail(PersonalSection::Browse, available_product_id) + .expect("available buyer detail should open")); + assert!(runtime + .add_personal_product_to_cart(PersonalSection::Browse, false) + .expect("available buyer product should add to cart")); + assert!(runtime + .open_personal_product_detail(PersonalSection::Browse, unavailable_product_id) + .expect("unavailable buyer detail should open")); + assert!(runtime + .add_personal_product_to_cart(PersonalSection::Browse, false) + .expect("second buyer product should add to cart")); + assert!(runtime + .save_personal_checkout_draft(BuyerCheckoutDraft { + name: "Casey Buyer".to_owned(), + email: "casey@example.com".to_owned(), + phone: String::new(), + order_note: String::new(), + }) + .expect("buyer checkout draft should save")); + assert!(runtime + .place_personal_order() + .expect("buyer order should place")); let order_id = runtime.summary().personal_projection.orders.list.rows[0].order_id; runtime @@ -6934,11 +6869,9 @@ mod tests { ) .expect("product should archive"); - assert!( - runtime - .open_personal_order_detail(order_id) - .expect("buyer order detail should reopen") - ); + assert!(runtime + .open_personal_order_detail(order_id) + .expect("buyer order detail should reopen")); let detail_summary = runtime.summary(); let repeat_demand = detail_summary .personal_projection @@ -6951,11 +6884,9 @@ mod tests { assert_eq!(repeat_demand.available_item_count, 1); assert_eq!(repeat_demand.unavailable_item_count, 1); - assert!( - runtime - .repeat_personal_order(order_id, false) - .expect("repeat demand should add available items to cart") - ); + assert!(runtime + .repeat_personal_order(order_id, false) + .expect("repeat demand should add available items to cart")); let summary = runtime.summary(); assert_eq!( @@ -6968,25 +6899,21 @@ mod tests { available_product_id ); assert_eq!(summary.personal_projection.cart.cart.lines[0].quantity, 1); - assert!( - summary - .personal_projection - .cart - .cart - .replace_confirmation - .is_none() - ); + assert!(summary + .personal_projection + .cart + .cart + .replace_confirmation + .is_none()); } #[test] fn runtime_products_queries_refresh_the_repository_backed_projection() { let runtime = memory_runtime(); - assert!( - runtime - .generate_local_account(Some("Farmer".to_owned())) - .expect("account should generate") - ); + assert!(runtime + .generate_local_account(Some("Farmer".to_owned())) + .expect("account should generate")); let account_id = runtime .summary() .settings_account_projection @@ -7041,11 +6968,9 @@ mod tests { "2026-04-18T09:00:00Z", ); - assert!( - runtime - .select_local_account(account_id.as_str()) - .expect("account should select") - ); + assert!(runtime + .select_local_account(account_id.as_str()) + .expect("account should select")); let summary = runtime.summary(); assert_eq!(summary.products_projection.list.summary.total_products, 2); @@ -7059,18 +6984,14 @@ mod tests { ProductsSort::default() ); - assert!( - runtime - .select_products_filter(ProductsFilter::NeedAttention) - .expect("filter should apply") - ); + assert!(runtime + .select_products_filter(ProductsFilter::NeedAttention) + .expect("filter should apply")); assert_eq!(runtime.summary().products_projection.list.rows.len(), 2); - assert!( - runtime - .set_products_search_query("pea") - .expect("search should apply") - ); + assert!(runtime + .set_products_search_query("pea") + .expect("search should apply")); let searched = runtime.summary(); assert_eq!(searched.products_projection.list.rows.len(), 1); assert_eq!( @@ -7078,11 +6999,9 @@ mod tests { "Pea shoots" ); - assert!( - runtime - .select_products_sort(ProductsSort::Name) - .expect("sort should apply") - ); + assert!(runtime + .select_products_sort(ProductsSort::Name) + .expect("sort should apply")); assert_eq!( runtime.summary().products_projection.query.sort, ProductsSort::Name @@ -7093,11 +7012,9 @@ mod tests { fn runtime_open_products_filter_routes_today_follow_ons_into_products() { let runtime = memory_runtime(); - assert!( - runtime - .generate_local_account(Some("Farmer".to_owned())) - .expect("account should generate") - ); + assert!(runtime + .generate_local_account(Some("Farmer".to_owned())) + .expect("account should generate")); let account_id = runtime .summary() .settings_account_projection @@ -7134,21 +7051,17 @@ mod tests { .save_farm_setup(account_id.as_str(), &farm_setup_projection) .expect("farm setup should save"); - assert!( - runtime - .select_local_account(account_id.as_str()) - .expect("account should select") - ); + assert!(runtime + .select_local_account(account_id.as_str()) + .expect("account should select")); assert_eq!( runtime.summary().shell_projection.selected_section, ShellSection::Farmer(FarmerSection::Today) ); - assert!( - runtime - .open_products_filter(ProductsFilter::Drafts) - .expect("products follow-on should route") - ); + assert!(runtime + .open_products_filter(ProductsFilter::Drafts) + .expect("products follow-on should route")); let summary = runtime.summary(); assert_eq!( @@ -7185,11 +7098,9 @@ mod tests { ); assert!(orders_summary.orders_projection.detail.is_none()); - assert!( - runtime - .open_order_detail(order_id) - .expect("order detail should open") - ); + assert!(runtime + .open_order_detail(order_id) + .expect("order detail should open")); let detail_summary = runtime.summary(); assert_eq!( detail_summary.shell_projection.selected_section, @@ -7235,11 +7146,9 @@ mod tests { let (runtime, paths) = bootstrapped_runtime("pack_day_export_requires_context"); let (_, _farm_id) = provision_ready_farmer_account(&runtime); - assert!( - !runtime - .export_pack_day() - .expect("missing pack day context should no-op") - ); + assert!(!runtime + .export_pack_day() + .expect("missing pack day context should no-op")); assert_eq!( runtime.summary().pack_day_projection.export.status, PackDayExportStatus::Idle @@ -7282,11 +7191,9 @@ mod tests { }), ); - assert!( - runtime - .export_pack_day() - .expect("pack day export should succeed") - ); + assert!(runtime + .export_pack_day() + .expect("pack day export should succeed")); let summary = runtime.summary(); let export = &summary.pack_day_projection.export; @@ -7328,17 +7235,51 @@ mod tests { } #[test] + fn runtime_bootstrap_sweeps_prepared_pack_day_print_assets() { + let paths = temp_desktop_runtime_paths("pack_day_print_bootstrap_sweep"); + let stale_root = prepared_customer_label_asset_root(); + let stale_directory = stale_root.join(PackDayExportInstanceId::new().to_string()); + let _ = fs::remove_file(&stale_root); + let _ = fs::remove_dir_all(&stale_root); + fs::create_dir_all(&stale_directory).expect("stale prepared directory should create"); + fs::write(stale_directory.join("stale.ps"), "stale").expect("stale asset should write"); + + let _ = restart_runtime(paths.clone()); + + assert!(!stale_root.exists()); + + cleanup_bootstrapped_runtime_paths(&paths); + } + + #[test] + fn runtime_bootstrap_keeps_running_when_prepared_pack_day_print_root_sweep_fails() { + let paths = temp_desktop_runtime_paths("pack_day_print_bootstrap_best_effort"); + let stale_root = prepared_customer_label_asset_root(); + let _ = fs::remove_file(&stale_root); + let _ = fs::remove_dir_all(&stale_root); + if let Some(parent) = stale_root.parent() { + fs::create_dir_all(parent).expect("prepared asset root parent should create"); + } + fs::write(&stale_root, "blocked").expect("prepared asset root blocker should write"); + + let _ = restart_runtime(paths.clone()); + + assert!(stale_root.is_file()); + + let _ = fs::remove_file(&stale_root); + cleanup_bootstrapped_runtime_paths(&paths); + } + + #[test] fn runtime_prepare_pack_day_host_handoff_uses_the_current_export_bundle_for_file_actions() { let (runtime, paths) = bootstrapped_runtime("pack_day_host_handoff_prepare"); 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") - ); + assert!(runtime + .export_pack_day() + .expect("pack day export should succeed")); for (kind, suffix) in [ (PackDayHostHandoffKind::OpenPackSheet, "pack_sheet.txt"), @@ -7379,11 +7320,9 @@ mod tests { assert_eq!(prepared.1.kind, kind); assert!(prepared.1.target_path.ends_with(suffix)); - assert!( - runtime - .finish_pack_day_host_handoff(prepared.0, Ok(())) - .expect("host handoff success should apply") - ); + assert!(runtime + .finish_pack_day_host_handoff(prepared.0, Ok(())) + .expect("host handoff success should apply")); } cleanup_bootstrapped_runtime_paths(&paths); @@ -7396,11 +7335,9 @@ mod tests { 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") - ); + assert!(runtime + .export_pack_day() + .expect("pack day export should succeed")); let (request, _) = runtime .prepare_pack_day_host_handoff(PackDayHostHandoffKind::RevealBundle) @@ -7448,11 +7385,9 @@ mod tests { 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") - ); + assert!(runtime + .export_pack_day() + .expect("pack day export should succeed")); let (request, _) = runtime .prepare_pack_day_host_handoff(PackDayHostHandoffKind::RevealBundle) @@ -7464,11 +7399,9 @@ mod tests { .state_store .apply_in_memory(AppStateCommand::reset_pack_day_host_handoff()); - assert!( - !runtime - .finish_pack_day_host_handoff(request, Ok(())) - .expect("stale completion should no-op") - ); + assert!(!runtime + .finish_pack_day_host_handoff(request, Ok(())) + .expect("stale completion should no-op")); assert_eq!( runtime.summary().pack_day_projection.host_handoff.status, PackDayHostHandoffStatus::Idle @@ -7484,11 +7417,9 @@ mod tests { 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") - ); + assert!(runtime + .export_pack_day() + .expect("pack day export should succeed")); for (kind, expected_exported_suffix) in [ (PackDayPrintKind::PrintPackSheet, Some("pack_sheet.txt")), @@ -7541,25 +7472,19 @@ mod tests { .bundle .as_ref() .expect("pack day export bundle"); - assert!( - prepared - .1 - .target_path - .ends_with("customer_labels_avery_5160_letter_30_up.ps") - ); - assert!( - !prepared - .1 - .target_path - .starts_with(PathBuf::from(&export_bundle.bundle_directory)) - ); - assert!( - prepared - .1 - .target_path - .to_string_lossy() - .contains(export_bundle.export_instance_id.to_string().as_str()) - ); + assert!(prepared + .1 + .target_path + .ends_with("customer_labels_avery_5160_letter_30_up.ps")); + assert!(!prepared + .1 + .target_path + .starts_with(PathBuf::from(&export_bundle.bundle_directory))); + assert!(prepared + .1 + .target_path + .to_string_lossy() + .contains(export_bundle.export_instance_id.to_string().as_str())); assert_eq!( prepared.1.command_args, vec![ @@ -7571,11 +7496,9 @@ mod tests { } } - assert!( - runtime - .finish_pack_day_print(prepared.0, Ok(())) - .expect("print success should apply") - ); + assert!(runtime + .finish_pack_day_print(prepared.0, Ok(())) + .expect("print success should apply")); if let PackDayPrintKind::PrintCustomerLabels = kind { if let Some(parent) = prepared.1.target_path.parent() { @@ -7594,11 +7517,9 @@ mod tests { 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") - ); + assert!(runtime + .export_pack_day() + .expect("pack day export should succeed")); let (request, _) = runtime .prepare_pack_day_print(PackDayPrintKind::PrintPackSheet) @@ -7624,17 +7545,183 @@ mod tests { } #[test] + fn runtime_finish_pack_day_print_cleans_customer_label_assets_and_keeps_cleanup_failures_best_effort( + ) { + let (runtime, paths) = bootstrapped_runtime("pack_day_print_cleanup"); + 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 (success_request, success_plan) = runtime + .prepare_pack_day_print(PackDayPrintKind::PrintCustomerLabels) + .expect("customer labels should prepare") + .expect("customer labels plan should exist"); + let success_directory = success_plan + .target_path + .parent() + .expect("prepared asset parent") + .to_path_buf(); + assert!(success_directory.is_dir()); + + assert!(runtime + .finish_pack_day_print(success_request, Ok(())) + .expect("print success should apply")); + assert!(!success_directory.exists()); + + let (failure_request, failure_plan) = runtime + .prepare_pack_day_print(PackDayPrintKind::PrintCustomerLabels) + .expect("customer labels should prepare again") + .expect("customer labels plan should exist again"); + let failure_directory = failure_plan + .target_path + .parent() + .expect("prepared asset parent") + .to_path_buf(); + fs::remove_file(&failure_plan.target_path).expect("prepared asset should remove"); + fs::remove_dir_all(&failure_directory).expect("prepared asset directory should remove"); + fs::write(&failure_directory, "blocked").expect("cleanup blocker should write"); + + let error = runtime + .finish_pack_day_print( + failure_request.clone(), + Err(PackDayPrintError::UnsupportedPlatform), + ) + .expect_err("print failure should surface"); + assert!(matches!( + error, + DesktopAppRuntimeCommandError::PackDayPrint(PackDayPrintError::UnsupportedPlatform) + )); + assert!(failure_directory.is_file()); + + let summary = runtime.summary(); + assert_eq!( + summary.pack_day_projection.print.status, + PackDayPrintStatus::Failed + ); + assert_eq!( + summary.pack_day_projection.print.request, + Some(failure_request) + ); + + let _ = fs::remove_file(&failure_directory); + cleanup_bootstrapped_runtime_paths(&paths); + } + + #[test] + fn runtime_reexport_pack_day_cleans_previous_customer_label_prepared_assets() { + let (runtime, paths) = bootstrapped_runtime("pack_day_print_reexport_cleanup"); + 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("initial pack day export should succeed")); + let first_bundle = runtime + .summary() + .pack_day_projection + .export + .bundle + .clone() + .expect("initial export bundle"); + + let (_request, plan) = runtime + .prepare_pack_day_print(PackDayPrintKind::PrintCustomerLabels) + .expect("customer labels should prepare") + .expect("customer labels plan should exist"); + let prepared_directory = plan + .target_path + .parent() + .expect("prepared asset parent") + .to_path_buf(); + assert!(prepared_directory.is_dir()); + let _ = runtime + .lock_state_mut() + .state_store + .apply_in_memory(AppStateCommand::reset_pack_day_print()); + + assert!(runtime + .export_pack_day() + .expect("replacement pack day export should succeed")); + + let summary = runtime.summary(); + let replacement_bundle = summary + .pack_day_projection + .export + .bundle + .as_ref() + .expect("replacement export bundle"); + assert_ne!( + replacement_bundle.export_instance_id, + first_bundle.export_instance_id + ); + assert!(!prepared_directory.exists()); + + cleanup_bootstrapped_runtime_paths(&paths); + } + + #[test] + fn runtime_pack_day_window_change_cleans_previous_customer_label_prepared_assets() { + let (runtime, paths) = bootstrapped_runtime("pack_day_print_window_cleanup"); + let (_, farm_id) = provision_ready_farmer_account(&runtime); + let (fulfillment_window_id, _) = seed_order_workspace(&runtime, farm_id); + let (other_fulfillment_window_id, _) = + seed_second_order_workspace(&runtime, farm_id, fulfillment_window_id); + + assert!(runtime + .open_pack_day(Some(fulfillment_window_id)) + .expect("first pack day window should open")); + assert!(runtime + .export_pack_day() + .expect("initial pack day export should succeed")); + + let (_request, plan) = runtime + .prepare_pack_day_print(PackDayPrintKind::PrintCustomerLabels) + .expect("customer labels should prepare") + .expect("customer labels plan should exist"); + let prepared_directory = plan + .target_path + .parent() + .expect("prepared asset parent") + .to_path_buf(); + assert!(prepared_directory.is_dir()); + let _ = runtime + .lock_state_mut() + .state_store + .apply_in_memory(AppStateCommand::reset_pack_day_print()); + + assert!(runtime + .open_pack_day(Some(other_fulfillment_window_id)) + .expect("second pack day window should open")); + + let summary = runtime.summary(); + assert_eq!( + summary.pack_day_projection.query.fulfillment_window_id, + Some(other_fulfillment_window_id) + ); + assert_eq!( + summary.pack_day_projection.export.status, + PackDayExportStatus::Idle + ); + assert!(!prepared_directory.exists()); + + cleanup_bootstrapped_runtime_paths(&paths); + } + + #[test] fn runtime_finish_pack_day_print_ignores_stale_background_completion() { let (runtime, paths) = bootstrapped_runtime("pack_day_print_stale"); 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") - ); + assert!(runtime + .export_pack_day() + .expect("pack day export should succeed")); let (request, _) = runtime .prepare_pack_day_print(PackDayPrintKind::PrintPickupRoster) @@ -7646,11 +7733,9 @@ mod tests { .state_store .apply_in_memory(AppStateCommand::reset_pack_day_print()); - assert!( - !runtime - .finish_pack_day_print(request, Ok(())) - .expect("stale completion should no-op") - ); + assert!(!runtime + .finish_pack_day_print(request, Ok(())) + .expect("stale completion should no-op")); assert_eq!( runtime.summary().pack_day_projection.print.status, PackDayPrintStatus::Idle @@ -7717,23 +7802,19 @@ mod tests { .expect("order should update to scheduled"); assert!(runtime.open_orders().expect("orders should open")); - assert!( - runtime - .mark_order_packed(order_id) - .expect("mark packed should succeed") - ); + assert!(runtime + .mark_order_packed(order_id) + .expect("mark packed should succeed")); let summary = runtime.summary(); assert_eq!(summary.sync_status.pending_write_count, 1); - assert!( - summary - .orders_projection - .reminders - .items - .iter() - .any(|item| item.kind == ReminderKind::SyncImpact - && item.title == "Pending local changes") - ); + assert!(summary + .orders_projection + .reminders + .items + .iter() + .any(|item| item.kind == ReminderKind::SyncImpact + && item.title == "Pending local changes")); } #[test] @@ -7761,12 +7842,10 @@ mod tests { ) .expect("blocking conflict should save"); - assert!( - runtime - .lock_state_mut() - .refresh_selected_account_sync() - .expect("sync status should refresh") - ); + assert!(runtime + .lock_state_mut() + .refresh_selected_account_sync() + .expect("sync status should refresh")); let summary = runtime.summary(); let reminder = summary @@ -7808,12 +7887,10 @@ mod tests { }, ) .expect("blocking conflict should save"); - assert!( - runtime - .lock_state_mut() - .refresh_selected_account_sync() - .expect("sync status should refresh") - ); + assert!(runtime + .lock_state_mut() + .refresh_selected_account_sync() + .expect("sync status should refresh")); let reminder_id = runtime .summary() @@ -7824,53 +7901,43 @@ mod tests { .find(|item| item.kind == ReminderKind::SyncImpact) .expect("sync reminder") .reminder_id; - assert!( - runtime - .acknowledge_reminder(reminder_id) - .expect("reminder should acknowledge") - ); + assert!(runtime + .acknowledge_reminder(reminder_id) + .expect("reminder should acknowledge")); let acknowledged_summary = runtime.summary(); - assert!( - acknowledged_summary - .orders_projection - .reminders - .items - .iter() - .any(|item| { - item.reminder_id == reminder_id - && item.delivery_state == ReminderDeliveryState::Acknowledged - }) - ); - assert!( - acknowledged_summary - .reminder_log - .entries - .iter() - .any(|entry| { - entry.reminder_id == reminder_id - && entry.delivery_state == ReminderDeliveryState::Acknowledged - }) - ); + assert!(acknowledged_summary + .orders_projection + .reminders + .items + .iter() + .any(|item| { + item.reminder_id == reminder_id + && item.delivery_state == ReminderDeliveryState::Acknowledged + })); + assert!(acknowledged_summary + .reminder_log + .entries + .iter() + .any(|entry| { + entry.reminder_id == reminder_id + && entry.delivery_state == ReminderDeliveryState::Acknowledged + })); - assert!( - runtime - .resolve_sync_conflict( - conflict_id.as_str(), - SyncConflictResolutionStatus::AcceptedLocal, - ) - .expect("conflict resolution should succeed") - ); + assert!(runtime + .resolve_sync_conflict( + conflict_id.as_str(), + SyncConflictResolutionStatus::AcceptedLocal, + ) + .expect("conflict resolution should succeed")); let resolved_summary = runtime.summary(); - assert!( - resolved_summary - .orders_projection - .reminders - .items - .iter() - .all(|item| { item.reminder_id != reminder_id }) - ); + assert!(resolved_summary + .orders_projection + .reminders + .items + .iter() + .all(|item| { item.reminder_id != reminder_id })); assert!(resolved_summary.reminder_log.entries.iter().any(|entry| { entry.reminder_id == reminder_id && entry.delivery_state == ReminderDeliveryState::Resolved @@ -7923,11 +7990,9 @@ mod tests { .execute_batch(&sql) .expect("recovery record should seed"); - assert!( - runtime - .open_order_detail(order_id) - .expect("order detail should open") - ); + assert!(runtime + .open_order_detail(order_id) + .expect("order detail should open")); let summary = runtime.summary(); assert_eq!(summary.orders_projection.recovery_queue.items.len(), 1); @@ -7977,16 +8042,12 @@ mod tests { let (_, farm_id) = provision_ready_farmer_account(&runtime); let (_, order_id) = seed_order_workspace(&runtime, farm_id); - assert!( - runtime - .select_orders_filter(OrdersFilter::Packed) - .expect("orders filter should update") - ); - assert!( - runtime - .open_order_detail(order_id) - .expect("order detail should open") - ); + assert!(runtime + .select_orders_filter(OrdersFilter::Packed) + .expect("orders filter should update")); + assert!(runtime + .open_order_detail(order_id) + .expect("order detail should open")); assert!(runtime.open_orders().expect("orders should reopen")); let summary = runtime.summary(); @@ -8063,11 +8124,9 @@ mod tests { .execute_batch(&sql) .expect("second orders workspace should seed"); - assert!( - runtime - .open_orders_fulfillment_window(fulfillment_window_id) - .expect("orders window follow-on should route") - ); + assert!(runtime + .open_orders_fulfillment_window(fulfillment_window_id) + .expect("orders window follow-on should route")); let summary = runtime.summary(); assert_eq!( @@ -8104,27 +8163,21 @@ mod tests { .execute_batch(&sql) .expect("order should update to scheduled"); - assert!( - runtime - .select_orders_filter(OrdersFilter::Scheduled) - .expect("scheduled filter should apply") - ); + assert!(runtime + .select_orders_filter(OrdersFilter::Scheduled) + .expect("scheduled filter should apply")); assert_eq!(runtime.summary().orders_projection.list.rows.len(), 1); assert_eq!( runtime.summary().orders_projection.list.rows[0].status, OrderStatus::Scheduled ); - assert!( - runtime - .open_order_detail(order_id) - .expect("order detail should open") - ); - assert!( - runtime - .mark_order_packed(order_id) - .expect("order should mark packed") - ); + assert!(runtime + .open_order_detail(order_id) + .expect("order detail should open")); + assert!(runtime + .mark_order_packed(order_id) + .expect("order should mark packed")); let packed_summary = runtime.summary(); assert_eq!( packed_summary @@ -8149,27 +8202,21 @@ mod tests { 1 ); - assert!( - runtime - .select_orders_filter(OrdersFilter::Packed) - .expect("packed filter should apply") - ); + assert!(runtime + .select_orders_filter(OrdersFilter::Packed) + .expect("packed filter should apply")); assert_eq!(runtime.summary().orders_projection.list.rows.len(), 1); assert_eq!( runtime.summary().orders_projection.list.rows[0].status, OrderStatus::Packed ); - assert!( - runtime - .open_order_detail(order_id) - .expect("packed detail should open") - ); - assert!( - runtime - .mark_order_completed(order_id) - .expect("order should mark completed") - ); + assert!(runtime + .open_order_detail(order_id) + .expect("packed detail should open")); + assert!(runtime + .mark_order_completed(order_id) + .expect("order should mark completed")); let completed_summary = runtime.summary(); assert_eq!( completed_summary @@ -8181,11 +8228,9 @@ mod tests { OrderStatus::Completed ); - assert!( - runtime - .select_orders_filter(OrdersFilter::Completed) - .expect("completed filter should apply") - ); + assert!(runtime + .select_orders_filter(OrdersFilter::Completed) + .expect("completed filter should apply")); assert_eq!(runtime.summary().orders_projection.list.rows.len(), 1); assert_eq!( runtime.summary().orders_projection.list.rows[0].status, @@ -8197,11 +8242,9 @@ mod tests { fn runtime_stock_updates_refresh_today_and_products_projections() { let runtime = memory_runtime(); - assert!( - runtime - .generate_local_account(Some("Farmer".to_owned())) - .expect("account should generate") - ); + assert!(runtime + .generate_local_account(Some("Farmer".to_owned())) + .expect("account should generate")); let account_id = runtime .summary() .settings_account_projection @@ -8247,22 +8290,18 @@ mod tests { "2026-04-18T10:00:00Z", ); - assert!( - runtime - .select_local_account(account_id.as_str()) - .expect("account should select") - ); + assert!(runtime + .select_local_account(account_id.as_str()) + .expect("account should select")); let product_id = runtime.summary().products_projection.list.rows[0].product_id; assert_eq!( runtime.summary().today_projection.low_stock_products.len(), 1 ); - assert!( - runtime - .update_product_stock(product_id, 12) - .expect("stock update should succeed") - ); + assert!(runtime + .update_product_stock(product_id, 12) + .expect("stock update should succeed")); let summary = runtime.summary(); assert_eq!( @@ -8276,11 +8315,9 @@ mod tests { fn runtime_open_new_product_editor_creates_a_local_draft_and_opens_it() { let runtime = memory_runtime(); - assert!( - runtime - .generate_local_account(Some("Farmer".to_owned())) - .expect("account should generate") - ); + assert!(runtime + .generate_local_account(Some("Farmer".to_owned())) + .expect("account should generate")); let account_id = runtime .summary() .settings_account_projection @@ -8317,11 +8354,9 @@ mod tests { .save_farm_setup(account_id.as_str(), &farm_setup_projection) .expect("farm setup should save"); - assert!( - runtime - .select_local_account(account_id.as_str()) - .expect("account should select") - ); + assert!(runtime + .select_local_account(account_id.as_str()) + .expect("account should select")); assert_eq!( runtime .summary() @@ -8332,11 +8367,9 @@ mod tests { 0 ); - assert!( - runtime - .open_new_product_editor() - .expect("new product editor should open") - ); + assert!(runtime + .open_new_product_editor() + .expect("new product editor should open")); let summary = runtime.summary(); assert_eq!(summary.products_projection.list.summary.total_products, 1); @@ -8354,11 +8387,9 @@ mod tests { fn runtime_open_existing_and_save_product_editor_refreshes_products_projection() { let runtime = memory_runtime(); - assert!( - runtime - .generate_local_account(Some("Farmer".to_owned())) - .expect("account should generate") - ); + assert!(runtime + .generate_local_account(Some("Farmer".to_owned())) + .expect("account should generate")); let account_id = runtime .summary() .settings_account_projection @@ -8404,16 +8435,12 @@ mod tests { "2026-04-18T10:00:00Z", ); - assert!( - runtime - .select_local_account(account_id.as_str()) - .expect("account should select") - ); - assert!( - runtime - .open_existing_product_editor(product_id) - .expect("existing product editor should open") - ); + assert!(runtime + .select_local_account(account_id.as_str()) + .expect("account should select")); + assert!(runtime + .open_existing_product_editor(product_id) + .expect("existing product editor should open")); let saved_draft = ProductEditorDraft { title: "Salad mix".to_owned(), @@ -8426,11 +8453,9 @@ mod tests { status: radroots_app_models::ProductStatus::Published, }; - assert!( - runtime - .save_product_editor_draft(saved_draft.clone()) - .expect("product editor draft should save") - ); + assert!(runtime + .save_product_editor_draft(saved_draft.clone()) + .expect("product editor draft should save")); let summary = runtime.summary(); assert_eq!( @@ -8467,11 +8492,9 @@ mod tests { fn runtime_account_commands_refresh_identity_projection() { let runtime = memory_runtime(); - assert!( - runtime - .generate_local_account(Some("First".to_owned())) - .expect("first account should generate") - ); + assert!(runtime + .generate_local_account(Some("First".to_owned())) + .expect("first account should generate")); let first_summary = runtime.summary(); let first_account_id = first_summary .settings_account_projection @@ -8482,11 +8505,9 @@ mod tests { .account_id .clone(); - assert!( - runtime - .generate_local_account(Some("Second".to_owned())) - .expect("second account should generate") - ); + assert!(runtime + .generate_local_account(Some("Second".to_owned())) + .expect("second account should generate")); let second_summary = runtime.summary(); let second_account_id = second_summary .settings_account_projection @@ -8512,11 +8533,9 @@ mod tests { ActiveSurface::Farmer, true, ); - assert!( - runtime - .select_local_account(second_account_id.as_str()) - .expect("selection should succeed") - ); + assert!(runtime + .select_local_account(second_account_id.as_str()) + .expect("selection should succeed")); let selected_summary = runtime.summary(); assert_eq!(selected_summary.startup_gate, AppStartupGate::Farmer); assert_eq!(selected_summary.home_route, HomeRoute::FarmSetupOnboarding); @@ -8529,11 +8548,9 @@ mod tests { Some(ActiveSurface::Farmer) ); - assert!( - runtime - .remove_selected_local_key() - .expect("selected local key should remove") - ); + assert!(runtime + .remove_selected_local_key() + .expect("selected local key should remove")); let removed_summary = runtime.summary(); assert_eq!(removed_summary.settings_account_projection.roster.len(), 1); assert_eq!( @@ -8556,13 +8573,11 @@ mod tests { ); let imported_identity = RadrootsIdentity::generate(); - assert!( - runtime - .import_local_account(DesktopLocalIdentityImportRequest::raw_secret_key( - imported_identity.nsec(), - )) - .expect("raw import should succeed") - ); + assert!(runtime + .import_local_account(DesktopLocalIdentityImportRequest::raw_secret_key( + imported_identity.nsec(), + )) + .expect("raw import should succeed")); let imported_summary = runtime.summary(); assert_eq!(imported_summary.settings_account_projection.roster.len(), 2); assert_eq!( @@ -8579,11 +8594,9 @@ mod tests { fn runtime_select_active_surface_persists_selected_surface() { let runtime = memory_runtime(); - assert!( - runtime - .generate_local_account(Some("Farmer".to_owned())) - .expect("account should generate") - ); + assert!(runtime + .generate_local_account(Some("Farmer".to_owned())) + .expect("account should generate")); let account_id = runtime .summary() .settings_account_projection @@ -8594,18 +8607,14 @@ mod tests { .account_id .clone(); save_surface_activation(&runtime, account_id.as_str(), ActiveSurface::Farmer, true); - assert!( - runtime - .select_local_account(account_id.as_str()) - .expect("account should select") - ); + assert!(runtime + .select_local_account(account_id.as_str()) + .expect("account should select")); assert_eq!(runtime.summary().startup_gate, AppStartupGate::Farmer); - assert!( - runtime - .select_active_surface(ActiveSurface::Personal) - .expect("surface should select") - ); + assert!(runtime + .select_active_surface(ActiveSurface::Personal) + .expect("surface should select")); let personal_summary = runtime.summary(); assert_eq!(personal_summary.startup_gate, AppStartupGate::Personal); assert_eq!( @@ -8629,11 +8638,9 @@ mod tests { ActiveSurface::Personal ); - assert!( - runtime - .select_active_surface(ActiveSurface::Farmer) - .expect("surface should reselect") - ); + assert!(runtime + .select_active_surface(ActiveSurface::Farmer) + .expect("surface should reselect")); let farmer_summary = runtime.summary(); assert_eq!(farmer_summary.startup_gate, AppStartupGate::Farmer); assert_eq!( @@ -8662,11 +8669,9 @@ mod tests { fn selecting_farmer_account_loads_persisted_farm_setup_draft() { let runtime = memory_runtime(); - assert!( - runtime - .generate_local_account(Some("Farmer".to_owned())) - .expect("account should generate") - ); + assert!(runtime + .generate_local_account(Some("Farmer".to_owned())) + .expect("account should generate")); let account_id = runtime .summary() .settings_account_projection @@ -8690,11 +8695,9 @@ mod tests { .expect("farm setup should save"); save_surface_activation(&runtime, account_id.as_str(), ActiveSurface::Farmer, true); - assert!( - runtime - .select_local_account(account_id.as_str()) - .expect("account should select") - ); + assert!(runtime + .select_local_account(account_id.as_str()) + .expect("account should select")); let summary = runtime.summary(); assert_eq!(summary.startup_gate, AppStartupGate::Farmer); @@ -8706,11 +8709,9 @@ mod tests { fn finishing_farm_setup_persists_saved_farm_and_today_projection() { let runtime = memory_runtime(); - assert!( - runtime - .generate_local_account(Some("Farmer".to_owned())) - .expect("account should generate") - ); + assert!(runtime + .generate_local_account(Some("Farmer".to_owned())) + .expect("account should generate")); let account_id = runtime .summary() .settings_account_projection @@ -8722,11 +8723,9 @@ mod tests { .clone(); let farm_id = save_farmer_surface_activation(&runtime, account_id.as_str(), ActiveSurface::Farmer); - assert!( - runtime - .select_local_account(account_id.as_str()) - .expect("account should select") - ); + assert!(runtime + .select_local_account(account_id.as_str()) + .expect("account should select")); assert_eq!(runtime.summary().home_route, HomeRoute::FarmSetupOnboarding); let draft = FarmSetupDraft::new( @@ -8789,11 +8788,9 @@ mod tests { fn loading_farm_rules_projection_seeds_profile_from_saved_farm() { let runtime = memory_runtime(); - assert!( - runtime - .generate_local_account(Some("Farmer".to_owned())) - .expect("account should generate") - ); + assert!(runtime + .generate_local_account(Some("Farmer".to_owned())) + .expect("account should generate")); let account_id = runtime .summary() .settings_account_projection @@ -8830,11 +8827,9 @@ mod tests { .save_farm_setup(account_id.as_str(), &farm_setup_projection) .expect("farm setup should save"); - assert!( - runtime - .select_local_account(account_id.as_str()) - .expect("account should select") - ); + assert!(runtime + .select_local_account(account_id.as_str()) + .expect("account should select")); let projection = runtime .load_farm_rules_projection() @@ -8863,11 +8858,9 @@ mod tests { fn saving_farm_rules_projection_refreshes_saved_farm_summary_and_pickup_defaults() { let runtime = memory_runtime(); - assert!( - runtime - .generate_local_account(Some("Farmer".to_owned())) - .expect("account should generate") - ); + assert!(runtime + .generate_local_account(Some("Farmer".to_owned())) + .expect("account should generate")); let account_id = runtime .summary() .settings_account_projection @@ -8904,11 +8897,9 @@ mod tests { .save_farm_setup(account_id.as_str(), &farm_setup_projection) .expect("farm setup should save"); - assert!( - runtime - .select_local_account(account_id.as_str()) - .expect("account should select") - ); + assert!(runtime + .select_local_account(account_id.as_str()) + .expect("account should select")); let default_pickup_location_id = PickupLocationId::new(); let market_pickup_location_id = PickupLocationId::new(); @@ -9041,11 +9032,9 @@ mod tests { fn runtime_reset_local_device_state_clears_store_file_and_projection() { let (runtime, paths) = file_backed_runtime("reset"); - assert!( - runtime - .generate_local_account(Some("First".to_owned())) - .expect("first account should generate") - ); + assert!(runtime + .generate_local_account(Some("First".to_owned())) + .expect("first account should generate")); let first_account_id = runtime .summary() .settings_account_projection @@ -9055,11 +9044,9 @@ mod tests { .account .account_id .clone(); - assert!( - runtime - .generate_local_account(Some("Second".to_owned())) - .expect("second account should generate") - ); + assert!(runtime + .generate_local_account(Some("Second".to_owned())) + .expect("second account should generate")); let second_account_id = runtime .summary() .settings_account_projection @@ -9083,21 +9070,17 @@ mod tests { ); assert!(paths.store_path.exists()); - assert!( - runtime - .reset_local_device_state() - .expect("device state should reset") - ); + assert!(runtime + .reset_local_device_state() + .expect("device state should reset")); let summary = runtime.summary(); assert_eq!(summary.startup_gate, AppStartupGate::SetupRequired); assert!(summary.settings_account_projection.roster.is_empty()); - assert!( - summary - .settings_account_projection - .selected_account - .is_none() - ); + assert!(summary + .settings_account_projection + .selected_account + .is_none()); assert!(!paths.store_path.exists()); assert_eq!( runtime @@ -9510,11 +9493,9 @@ mod tests { } fn provision_ready_farmer_account(runtime: &DesktopAppRuntime) -> (String, FarmId) { - assert!( - runtime - .generate_local_account(Some("Farmer".to_owned())) - .expect("account should generate") - ); + assert!(runtime + .generate_local_account(Some("Farmer".to_owned())) + .expect("account should generate")); let account_id = runtime .summary() .settings_account_projection @@ -9550,11 +9531,9 @@ mod tests { .expect("sqlite store") .save_farm_setup(account_id.as_str(), &farm_setup_projection) .expect("farm setup should save"); - assert!( - runtime - .select_local_account(account_id.as_str()) - .expect("account should select") - ); + assert!(runtime + .select_local_account(account_id.as_str()) + .expect("account should select")); (account_id, farm_id) } @@ -9656,6 +9635,69 @@ mod tests { (fulfillment_window_id, order_id) } + fn seed_second_order_workspace( + runtime: &DesktopAppRuntime, + farm_id: FarmId, + source_fulfillment_window_id: FulfillmentWindowId, + ) -> (FulfillmentWindowId, OrderId) { + let fulfillment_window_id = FulfillmentWindowId::new(); + let order_id = OrderId::new(); + let sql = format!( + "insert into fulfillment_windows ( + id, + farm_id, + starts_at, + ends_at, + capacity_limit, + created_at, + updated_at, + pickup_location_id, + label, + order_cutoff_at + ) + select + '{fulfillment_window_id}', + farm_id, + '2099-04-19T16:00:00Z', + '2099-04-19T18:00:00Z', + capacity_limit, + '2099-04-19T16:00:00Z', + '2099-04-19T16:00:00Z', + pickup_location_id, + 'Saturday pickup', + '2099-04-18T18:00:00Z' + from fulfillment_windows + where id = '{source_fulfillment_window_id}' and farm_id = '{farm_id}'; + insert into orders ( + id, + farm_id, + fulfillment_window_id, + order_number, + customer_display_name, + status, + updated_at + ) values ( + '{order_id}', + '{farm_id}', + '{fulfillment_window_id}', + 'R-101', + 'Robin', + 'scheduled', + '2026-04-17T11:00:00Z' + )" + ); + runtime + .lock_state() + .sqlite_store + .as_ref() + .expect("sqlite store") + .connection() + .execute_batch(&sql) + .expect("second orders workspace should seed"); + + (fulfillment_window_id, order_id) + } + fn cleanup_paths(paths: &AppSharedAccountsPaths) { let Some(base) = paths.data_root.ancestors().nth(3).map(PathBuf::from) else { return;