diff --git a/crates/update/src/updater.rs b/crates/update/src/updater.rs index 607356d4..c6f22c6b 100644 --- a/crates/update/src/updater.rs +++ b/crates/update/src/updater.rs @@ -200,8 +200,10 @@ impl Updater { let requested = std::mem::take(&mut self.requested); match answer { Ok(Some(release)) => { - self.status = Status::Idle; - if self.prompt.is_none() && self.install.is_none() && !self.installed && self.managed.is_none() { + // The launcher may have pinned the app while the check ran. + let managed = self.read_choice(); + self.status = if managed && requested { Status::UpToDate } else { Status::Idle }; + if self.prompt.is_none() && self.install.is_none() && !self.installed && !managed { self.prompt = Some(StartupPrompt::new(self.app, release, self.version.clone())); } } diff --git a/crates/update/src/updater_pin_tests.rs b/crates/update/src/updater_pin_tests.rs index 593665fa..b32a4fbd 100644 --- a/crates/update/src/updater_pin_tests.rs +++ b/crates/update/src/updater_pin_tests.rs @@ -122,3 +122,23 @@ fn a_running_install_keeps_its_prompt_when_the_app_is_pinned() { assert!(u.read_choice()); assert!(u.prompt_open(), "tick reports the running install through the prompt"); } + +#[test] +fn a_pin_made_while_the_check_runs_still_holds_its_answer() { + let ctx = egui::Context::default(); + let dir = tempfile::tempdir().unwrap(); + let path = dir.path().join("versions.json"); + let during = path.clone(); + // The check itself pins the app before answering, as the launcher could mid-check. + let source: CheckSource = Arc::new(move || { + let mut pins = Pins::default(); + pins.set(PHOTOCRAFT.id, &crate::pins::VersionTrack::Pinned("v0.13.0".into())); + pins.save(&during)?; + Ok(Some(newer())) + }); + let mut u = Updater::new(&PHOTOCRAFT, "0.13.0").with_source(source).with_pins_path(&path); + u.check_now(&ctx); + settle(&mut u, &ctx); + assert!(!u.prompt_open()); + assert_eq!(u.status(), &Status::UpToDate); +}