use pomomon_garden::features::achievement::AchievementPlugin; use pomomon_garden::features::achievement::components::{AchievementId, AchievementProgress}; use pomomon_garden::features::notification::components::Notifications; use pomomon_garden::features::phase::components::SessionTracker; use pomomon_garden::prelude::*; use strum::IntoEnumIterator; #[test] fn test_achievement_unlock_logic() { let mut app = App::new(); app.add_plugins(MinimalPlugins); app.add_plugins(AchievementPlugin); app.insert_resource(Notifications::default()); // Needs to be present because check_achievements uses it // Helper to run systems and get progress let mut run_check = |completed_focus: u32, total_berries: u32, total_withered: u32| { app.insert_resource(SessionTracker { completed_focus_phases: completed_focus, total_berries_earned: total_berries, total_plants_withered: total_withered, }); app.update(); // Runs check_achievements app.world().resource::().clone() }; // --- Initial State --- let progress = run_check(0, 0, 0); for id in AchievementId::iter() { assert!( !progress.is_unlocked(&id), "Achievement {:?} should not be unlocked initially", id ); } // --- First Steps (1 berry) --- let progress = run_check(0, 1, 0); assert!(progress.is_unlocked(&AchievementId::FirstSteps)); // --- Getting Started (1 focus phase) --- let progress = run_check(1, 1, 0); assert!(progress.is_unlocked(&AchievementId::GettingStarted)); // --- Negligent (1 withered plant) --- let progress = run_check(1, 1, 1); assert!(progress.is_unlocked(&AchievementId::Negligent)); // --- Focus Master (10 focus phases) --- let progress = run_check(10, 1, 1); assert!(progress.is_unlocked(&AchievementId::FocusMaster)); // --- Master Farmer (100 berries) --- let progress = run_check(10, 100, 1); assert!(progress.is_unlocked(&AchievementId::MasterFarmer)); // --- Zen Master (50 focus phases) --- let progress = run_check(50, 100, 1); assert!(progress.is_unlocked(&AchievementId::ZenMaster)); // --- Compost King (10 withered plants) --- let progress = run_check(50, 100, 10); assert!(progress.is_unlocked(&AchievementId::CompostKing)); // --- Berry Tycoon (1000 berries) --- let progress = run_check(50, 1000, 10); assert!(progress.is_unlocked(&AchievementId::BerryTycoon)); // --- Test idempotency: already unlocked should stay unlocked --- let initial_progress = progress.clone(); let progress = run_check(50, 1000, 10); assert_eq!(progress.unlocked.len(), initial_progress.unlocked.len()); // Same number unlocked for id in AchievementId::iter() { assert_eq!(progress.is_unlocked(&id), initial_progress.is_unlocked(&id)); } }