Skip to content

Commit 855aefa

Browse files
authored
fix: stop false manual-download update prompts (#78)
* fix: stop false manual-download update prompts * refactor: reuse updater result mapping * refactor: clarify manual-download update mapping
1 parent f27a6a7 commit 855aefa

File tree

2 files changed

+127
-64
lines changed

2 files changed

+127
-64
lines changed

src-tauri/src/bridge/commands.rs

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ use crate::bridge::updater_messages::{
88
};
99
use crate::bridge::updater_mode::{resolve_desktop_update_mode, DesktopUpdateMode};
1010
use crate::bridge::updater_types::{
11-
map_manual_download_result, map_no_update_result, map_update_available_result,
12-
map_update_channel_error, map_update_channel_ok, map_update_check_error,
13-
map_update_install_error, map_update_install_ok, DesktopAppUpdateChannelResult,
14-
DesktopAppUpdateCheckResult, DesktopAppUpdateResult,
11+
map_manual_download_no_update_result, map_manual_download_update_available_result,
12+
map_no_update_result, map_update_available_result, map_update_channel_error,
13+
map_update_channel_ok, map_update_check_error, map_update_install_error, map_update_install_ok,
14+
DesktopAppUpdateChannelResult, DesktopAppUpdateCheckResult, DesktopAppUpdateResult,
1515
};
1616
use crate::{
1717
append_desktop_log, restart_backend_flow, runtime_paths, shell_locale, tray, update_channel,
@@ -61,16 +61,13 @@ fn build_channel_aware_updater(
6161
.map_err(|error| format!("Failed to initialize updater: {error}"))
6262
}
6363

64-
fn short_circuit_update_check(
64+
fn update_check_short_circuit_result(
6565
mode: DesktopUpdateMode,
6666
current_version: &str,
6767
) -> Option<(&'static str, DesktopAppUpdateCheckResult)> {
6868
match mode {
6969
DesktopUpdateMode::NativeUpdater => None,
70-
DesktopUpdateMode::ManualDownload => Some((
71-
"desktop updater check routed to manual-download mode for current Linux install",
72-
map_manual_download_result(current_version, desktop_manual_download_reason()),
73-
)),
70+
DesktopUpdateMode::ManualDownload => None,
7471
DesktopUpdateMode::Unsupported => Some((
7572
"desktop updater check is unsupported on the current platform/runtime mode",
7673
map_update_check_error(
@@ -302,8 +299,9 @@ pub(crate) async fn desktop_bridge_check_app_update(
302299
app_handle: AppHandle,
303300
) -> DesktopAppUpdateCheckResult {
304301
let current_version = app_handle.package_info().version.to_string();
302+
let update_mode = resolve_desktop_update_mode();
305303
if let Some((log_message, result)) =
306-
short_circuit_update_check(resolve_desktop_update_mode(), &current_version)
304+
update_check_short_circuit_result(update_mode, &current_version)
307305
{
308306
append_desktop_log(log_message);
309307
return result;
@@ -315,10 +313,21 @@ pub(crate) async fn desktop_bridge_check_app_update(
315313
};
316314

317315
match updater.check().await {
318-
Ok(Some(update)) => {
319-
map_update_available_result(current_version, update.version.clone().to_string())
320-
}
321-
Ok(None) => map_no_update_result(current_version),
316+
Ok(Some(update)) => match update_mode {
317+
DesktopUpdateMode::ManualDownload => map_manual_download_update_available_result(
318+
&current_version,
319+
&update.version,
320+
desktop_manual_download_reason(),
321+
),
322+
_ => map_update_available_result(&current_version, &update.version),
323+
},
324+
Ok(None) => match update_mode {
325+
DesktopUpdateMode::ManualDownload => map_manual_download_no_update_result(
326+
&current_version,
327+
desktop_manual_download_reason(),
328+
),
329+
_ => map_no_update_result(&current_version),
330+
},
322331
Err(error) => map_update_check_error(
323332
Some(current_version),
324333
format!("Failed to check updates: {error}"),
@@ -361,32 +370,38 @@ mod tests {
361370
use super::*;
362371

363372
#[test]
364-
fn updater_check_mode_returns_manual_download_result() {
365-
let (log_message, result) =
366-
short_circuit_update_check(DesktopUpdateMode::ManualDownload, "4.19.2")
367-
.expect("manual-download mode should short-circuit update checks");
373+
fn update_check_short_circuit_only_applies_to_unsupported_mode() {
374+
assert!(
375+
update_check_short_circuit_result(DesktopUpdateMode::ManualDownload, "4.19.2")
376+
.is_none(),
377+
"manual-download mode should keep running the update check"
378+
);
379+
}
368380

369-
assert_eq!(
370-
log_message,
371-
"desktop updater check routed to manual-download mode for current Linux install"
381+
#[test]
382+
fn updater_check_manual_download_mode_only_reports_reason_without_forced_update_flag() {
383+
let result = crate::bridge::updater_types::map_manual_download_no_update_result(
384+
"4.19.2",
385+
crate::bridge::updater_messages::desktop_manual_download_reason(),
372386
);
387+
373388
assert_eq!(
374389
result,
375390
crate::bridge::updater_types::DesktopAppUpdateCheckResult {
376391
ok: true,
377392
reason: Some(crate::bridge::updater_messages::desktop_manual_download_reason()),
378393
current_version: Some("4.19.2".to_string()),
379-
latest_version: None,
380-
has_update: true,
381-
manual_download_required: true,
394+
latest_version: Some("4.19.2".to_string()),
395+
has_update: false,
396+
manual_download_required: false,
382397
}
383398
);
384399
}
385400

386401
#[test]
387402
fn updater_check_mode_returns_unsupported_result() {
388403
let (log_message, result) =
389-
short_circuit_update_check(DesktopUpdateMode::Unsupported, "4.19.2")
404+
update_check_short_circuit_result(DesktopUpdateMode::Unsupported, "4.19.2")
390405
.expect("unsupported mode should short-circuit update checks");
391406

392407
assert_eq!(

src-tauri/src/bridge/updater_types.rs

Lines changed: 87 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -28,29 +28,61 @@ pub(crate) struct DesktopAppUpdateChannelResult {
2828
pub channel: Option<UpdateChannel>,
2929
}
3030

31-
pub(crate) fn map_no_update_result(current_version: String) -> DesktopAppUpdateCheckResult {
31+
fn map_update_result(
32+
current_version: &str,
33+
latest_version: &str,
34+
reason: Option<String>,
35+
has_update: bool,
36+
manual_download_required: bool,
37+
) -> DesktopAppUpdateCheckResult {
3238
DesktopAppUpdateCheckResult {
3339
ok: true,
34-
reason: None,
35-
current_version: Some(current_version.clone()),
36-
latest_version: Some(current_version),
37-
has_update: false,
38-
manual_download_required: false,
40+
reason,
41+
current_version: Some(current_version.to_string()),
42+
latest_version: Some(latest_version.to_string()),
43+
has_update,
44+
manual_download_required,
3945
}
4046
}
4147

48+
pub(crate) fn map_no_update_result(current_version: &str) -> DesktopAppUpdateCheckResult {
49+
map_update_result(current_version, current_version, None, false, false)
50+
}
51+
4252
pub(crate) fn map_update_available_result(
43-
current_version: String,
44-
latest_version: String,
53+
current_version: &str,
54+
latest_version: &str,
4555
) -> DesktopAppUpdateCheckResult {
46-
DesktopAppUpdateCheckResult {
47-
ok: true,
48-
reason: None,
49-
current_version: Some(current_version),
50-
latest_version: Some(latest_version),
51-
has_update: true,
52-
manual_download_required: false,
53-
}
56+
map_update_result(current_version, latest_version, None, true, false)
57+
}
58+
59+
/// Maps a manual-download install that did find a newer remote release.
60+
pub(crate) fn map_manual_download_update_available_result(
61+
current_version: &str,
62+
latest_version: &str,
63+
reason: impl Into<String>,
64+
) -> DesktopAppUpdateCheckResult {
65+
map_update_result(
66+
current_version,
67+
latest_version,
68+
Some(reason.into()),
69+
true,
70+
true,
71+
)
72+
}
73+
74+
/// Maps a manual-download install that checked successfully but found no newer release.
75+
pub(crate) fn map_manual_download_no_update_result(
76+
current_version: &str,
77+
reason: impl Into<String>,
78+
) -> DesktopAppUpdateCheckResult {
79+
map_update_result(
80+
current_version,
81+
current_version,
82+
Some(reason.into()),
83+
false,
84+
false,
85+
)
5486
}
5587

5688
pub(crate) fn map_update_check_error(
@@ -97,29 +129,13 @@ pub(crate) fn map_update_channel_error(reason: impl Into<String>) -> DesktopAppU
97129
}
98130
}
99131

100-
pub(crate) fn map_manual_download_result(
101-
current_version: &str,
102-
reason: impl Into<String>,
103-
) -> DesktopAppUpdateCheckResult {
104-
DesktopAppUpdateCheckResult {
105-
ok: true,
106-
reason: Some(reason.into()),
107-
current_version: Some(current_version.to_string()),
108-
latest_version: None,
109-
// Manual-download mode should still trigger update UI even though
110-
// we cannot determine an exact remote latest version here.
111-
has_update: true,
112-
manual_download_required: true,
113-
}
114-
}
115-
116132
#[cfg(test)]
117133
mod tests {
118134
use super::*;
119135

120136
#[test]
121137
fn map_no_update_result_keeps_current_version() {
122-
let result = map_no_update_result("4.19.2".to_string());
138+
let result = map_no_update_result("4.19.2");
123139
assert!(result.ok);
124140
assert_eq!(result.current_version.as_deref(), Some("4.19.2"));
125141
assert_eq!(result.latest_version.as_deref(), Some("4.19.2"));
@@ -129,14 +145,28 @@ mod tests {
129145

130146
#[test]
131147
fn map_update_available_result_marks_update_available() {
132-
let result = map_update_available_result("4.19.2".to_string(), "4.20.0".to_string());
148+
let result = map_update_available_result("4.19.2", "4.20.0");
133149
assert!(result.ok);
134150
assert_eq!(result.current_version.as_deref(), Some("4.19.2"));
135151
assert_eq!(result.latest_version.as_deref(), Some("4.20.0"));
136152
assert!(result.has_update);
137153
assert!(!result.manual_download_required);
138154
}
139155

156+
#[test]
157+
fn map_manual_download_update_available_result_marks_manual_download_upgrade() {
158+
let result = map_manual_download_update_available_result(
159+
"4.19.2",
160+
"4.20.0",
161+
crate::bridge::updater_messages::DESKTOP_UPDATER_MANUAL_DOWNLOAD_REASON,
162+
);
163+
assert!(result.ok);
164+
assert_eq!(result.current_version.as_deref(), Some("4.19.2"));
165+
assert_eq!(result.latest_version.as_deref(), Some("4.20.0"));
166+
assert!(result.has_update);
167+
assert!(result.manual_download_required);
168+
}
169+
140170
#[test]
141171
fn map_update_check_error_keeps_known_current_version() {
142172
let result = map_update_check_error(Some("4.19.2".to_string()), "network error");
@@ -163,19 +193,37 @@ mod tests {
163193
}
164194

165195
#[test]
166-
fn map_manual_download_result_keeps_current_version_and_reason() {
167-
let result = map_manual_download_result(
196+
fn map_manual_download_no_update_result_keeps_current_version_and_reason() {
197+
let result = map_manual_download_no_update_result(
168198
"4.19.2",
169199
crate::bridge::updater_messages::DESKTOP_UPDATER_MANUAL_DOWNLOAD_REASON,
170200
);
171201
assert!(result.ok);
172202
assert_eq!(result.current_version.as_deref(), Some("4.19.2"));
173-
assert_eq!(result.latest_version, None);
174-
assert!(result.has_update);
175-
assert!(result.manual_download_required);
203+
assert_eq!(result.latest_version.as_deref(), Some("4.19.2"));
204+
assert!(!result.has_update);
205+
assert!(!result.manual_download_required);
176206
assert_eq!(
177207
result.reason.as_deref(),
178208
Some(crate::bridge::updater_messages::DESKTOP_UPDATER_MANUAL_DOWNLOAD_REASON)
179209
);
180210
}
211+
212+
#[test]
213+
fn map_manual_download_no_update_result_keeps_manual_download_message_without_update_flag() {
214+
let result = map_manual_download_no_update_result(
215+
"4.19.2",
216+
crate::bridge::updater_messages::desktop_manual_download_reason(),
217+
);
218+
219+
assert!(result.ok);
220+
assert_eq!(result.current_version.as_deref(), Some("4.19.2"));
221+
assert_eq!(result.latest_version.as_deref(), Some("4.19.2"));
222+
assert_eq!(
223+
result.reason.as_deref(),
224+
Some(crate::bridge::updater_messages::desktop_manual_download_reason().as_str())
225+
);
226+
assert!(!result.has_update);
227+
assert!(!result.manual_download_required);
228+
}
181229
}

0 commit comments

Comments
 (0)