mirror of
https://github.com/zhom/donutbrowser.git
synced 2026-04-29 15:26:05 +02:00
fix: prevent version downgrade for camoufox
This commit is contained in:
+84
-16
@@ -9,21 +9,21 @@ use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use crate::browser::GithubRelease;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
struct VersionComponent {
|
||||
major: u32,
|
||||
minor: u32,
|
||||
patch: u32,
|
||||
pre_release: Option<PreRelease>,
|
||||
pub struct VersionComponent {
|
||||
pub major: u32,
|
||||
pub minor: u32,
|
||||
pub patch: u32,
|
||||
pub pre_release: Option<PreRelease>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
struct PreRelease {
|
||||
kind: PreReleaseKind,
|
||||
number: Option<u32>,
|
||||
pub struct PreRelease {
|
||||
pub kind: PreReleaseKind,
|
||||
pub number: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
enum PreReleaseKind {
|
||||
pub enum PreReleaseKind {
|
||||
Alpha,
|
||||
Beta,
|
||||
RC,
|
||||
@@ -32,7 +32,7 @@ enum PreReleaseKind {
|
||||
}
|
||||
|
||||
impl VersionComponent {
|
||||
fn parse(version: &str) -> Self {
|
||||
pub fn parse(version: &str) -> Self {
|
||||
let version = version.trim();
|
||||
|
||||
// Handle special case for Zen Browser twilight releases
|
||||
@@ -260,12 +260,8 @@ pub fn is_browser_version_nightly(
|
||||
false
|
||||
}
|
||||
"camoufox" => {
|
||||
// For Camoufox, all releases are generally stable unless marked as prerelease
|
||||
if let Some(name) = release_name {
|
||||
name.to_lowercase().contains("alpha")
|
||||
} else {
|
||||
false
|
||||
}
|
||||
// For Camoufox, beta versions are actually the stable releases
|
||||
false
|
||||
}
|
||||
_ => {
|
||||
// Default fallback
|
||||
@@ -1992,4 +1988,76 @@ mod tests {
|
||||
assert_eq!(versions[2], "135.0.5beta22");
|
||||
assert_eq!(versions[3], "135.0.5beta21");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_camoufox_user_reported_versions() {
|
||||
// Test the exact versions reported by the user: 135.0.1beta24 vs 135.0beta22
|
||||
let v22 = VersionComponent::parse("135.0beta22");
|
||||
let v24 = VersionComponent::parse("135.0.1beta24");
|
||||
|
||||
println!("User reported v22: {v22:?}");
|
||||
println!("User reported v24: {v24:?}");
|
||||
|
||||
// 135.0.1beta24 should be greater than 135.0beta22 (newer patch version)
|
||||
assert!(
|
||||
v24 > v22,
|
||||
"135.0.1beta24 should be greater than 135.0beta22, but got: v24={v24:?} vs v22={v22:?}"
|
||||
);
|
||||
|
||||
// Test sorting of the exact user-reported versions
|
||||
let mut versions = vec!["135.0beta22".to_string(), "135.0.1beta24".to_string()];
|
||||
|
||||
sort_versions(&mut versions);
|
||||
|
||||
println!("User reported sorted versions: {versions:?}");
|
||||
|
||||
// Should be sorted from newest to oldest
|
||||
assert_eq!(
|
||||
versions[0], "135.0.1beta24",
|
||||
"135.0.1beta24 should be first (newest)"
|
||||
);
|
||||
assert_eq!(
|
||||
versions[1], "135.0beta22",
|
||||
"135.0beta22 should be second (older)"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_camoufox_version_classification() {
|
||||
// Test that Camoufox beta versions are now correctly classified as stable (not nightly)
|
||||
assert!(
|
||||
!is_browser_version_nightly("camoufox", "135.0beta22", None),
|
||||
"135.0beta22 should be classified as stable for Camoufox"
|
||||
);
|
||||
assert!(
|
||||
!is_browser_version_nightly("camoufox", "135.0.1beta24", None),
|
||||
"135.0.1beta24 should be classified as stable for Camoufox"
|
||||
);
|
||||
|
||||
// Test with release names too - beta releases should be stable
|
||||
assert!(
|
||||
!is_browser_version_nightly("camoufox", "135.0beta22", Some("Release Beta 22")),
|
||||
"Release with 'Beta' in name should be classified as stable for Camoufox"
|
||||
);
|
||||
|
||||
// Test that stable versions are not classified as nightly
|
||||
assert!(
|
||||
!is_browser_version_nightly("camoufox", "135.0", None),
|
||||
"135.0 should be classified as stable"
|
||||
);
|
||||
assert!(
|
||||
!is_browser_version_nightly("camoufox", "135.0.1", None),
|
||||
"135.0.1 should be classified as stable"
|
||||
);
|
||||
|
||||
// Test alpha and RC versions are still considered nightly
|
||||
assert!(
|
||||
is_browser_version_nightly("camoufox", "136.0alpha1", None),
|
||||
"136.0alpha1 should be classified as nightly/prerelease"
|
||||
);
|
||||
assert!(
|
||||
is_browser_version_nightly("camoufox", "136.0rc1", None),
|
||||
"136.0rc1 should be classified as nightly/prerelease"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,22 +407,17 @@ impl AutoUpdater {
|
||||
}
|
||||
|
||||
fn is_version_newer(&self, version1: &str, version2: &str) -> bool {
|
||||
self.compare_versions(version1, version2) == std::cmp::Ordering::Greater
|
||||
// Use the proper VersionComponent comparison from api_client.rs
|
||||
let version_a = crate::api_client::VersionComponent::parse(version1);
|
||||
let version_b = crate::api_client::VersionComponent::parse(version2);
|
||||
version_a > version_b
|
||||
}
|
||||
|
||||
fn compare_versions(&self, version1: &str, version2: &str) -> std::cmp::Ordering {
|
||||
// Basic semantic version comparison
|
||||
let v1_parts = self.parse_version(version1);
|
||||
let v2_parts = self.parse_version(version2);
|
||||
|
||||
v1_parts.cmp(&v2_parts)
|
||||
}
|
||||
|
||||
fn parse_version(&self, version: &str) -> Vec<u32> {
|
||||
version
|
||||
.split(&['.', 'a', 'b', '-', '_'][..])
|
||||
.filter_map(|part| part.parse::<u32>().ok())
|
||||
.collect()
|
||||
// Use the proper VersionComponent comparison from api_client.rs
|
||||
let version_a = crate::api_client::VersionComponent::parse(version1);
|
||||
let version_b = crate::api_client::VersionComponent::parse(version2);
|
||||
version_a.cmp(&version_b)
|
||||
}
|
||||
|
||||
fn get_auto_update_state_file(&self) -> PathBuf {
|
||||
@@ -570,6 +565,68 @@ mod tests {
|
||||
assert!(!updater.is_version_newer("1.0.0", "1.0.0"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_camoufox_beta_version_comparison() {
|
||||
let updater = AutoUpdater::new();
|
||||
|
||||
// Test the exact user-reported scenario: 135.0.1beta24 vs 135.0beta22
|
||||
assert!(
|
||||
updater.is_version_newer("135.0.1beta24", "135.0beta22"),
|
||||
"135.0.1beta24 should be newer than 135.0beta22"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
updater.compare_versions("135.0.1beta24", "135.0beta22"),
|
||||
std::cmp::Ordering::Greater,
|
||||
"135.0.1beta24 should compare as greater than 135.0beta22"
|
||||
);
|
||||
|
||||
// Test other camoufox beta version combinations
|
||||
assert!(
|
||||
updater.is_version_newer("135.0.5beta24", "135.0.5beta22"),
|
||||
"135.0.5beta24 should be newer than 135.0.5beta22"
|
||||
);
|
||||
|
||||
assert!(
|
||||
updater.is_version_newer("135.0.1beta1", "135.0beta1"),
|
||||
"135.0.1beta1 should be newer than 135.0beta1 due to patch version"
|
||||
);
|
||||
|
||||
// Test that older versions are not considered newer
|
||||
assert!(
|
||||
!updater.is_version_newer("135.0beta22", "135.0.1beta24"),
|
||||
"135.0beta22 should NOT be newer than 135.0.1beta24"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_beta_version_ordering_comprehensive() {
|
||||
let updater = AutoUpdater::new();
|
||||
|
||||
// Test various beta version patterns that could appear in camoufox
|
||||
let test_cases = vec![
|
||||
("135.0.1beta24", "135.0beta22", true), // User reported case
|
||||
("135.0.5beta24", "135.0.5beta22", true), // Same patch, different beta
|
||||
("135.1beta1", "135.0beta99", true), // Higher minor beats beta number
|
||||
("136.0beta1", "135.9.9beta99", true), // Higher major beats everything
|
||||
("135.0.1beta1", "135.0beta1", true), // Patch version matters
|
||||
("135.0beta22", "135.0.1beta24", false), // Reverse of user case
|
||||
];
|
||||
|
||||
for (newer, older, should_be_newer) in test_cases {
|
||||
let result = updater.is_version_newer(newer, older);
|
||||
assert_eq!(
|
||||
result,
|
||||
should_be_newer,
|
||||
"Expected {} {} {} but got {}",
|
||||
newer,
|
||||
if should_be_newer { ">" } else { "<=" },
|
||||
older,
|
||||
if result { "true" } else { "false" }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_check_profile_update_stable_to_stable() {
|
||||
let updater = AutoUpdater::new();
|
||||
@@ -854,15 +911,4 @@ mod tests {
|
||||
let loaded_state: AutoUpdateState = serde_json::from_str(&content).unwrap();
|
||||
assert_eq!(loaded_state.pending_updates.len(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_version() {
|
||||
let updater = AutoUpdater::new();
|
||||
|
||||
assert_eq!(updater.parse_version("1.2.3"), vec![1, 2, 3]);
|
||||
assert_eq!(updater.parse_version("1.2.3-alpha"), vec![1, 2, 3]);
|
||||
assert_eq!(updater.parse_version("1.2.3a1"), vec![1, 2, 3, 1]);
|
||||
assert_eq!(updater.parse_version("1.2.3b2"), vec![1, 2, 3, 2]);
|
||||
assert_eq!(updater.parse_version("10.0.0"), vec![10, 0, 0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,13 +327,6 @@ export function CreateProfileDialog({
|
||||
|
||||
<ScrollArea className="flex-1 pr-6 h-[350px]">
|
||||
<div className="py-4 space-y-6">
|
||||
{/* Anti-Detect Description */}
|
||||
<div className="p-3 text-center bg-blue-50 rounded-md border border-blue-200 dark:bg-blue-950 dark:border-blue-800">
|
||||
<p className="text-sm text-blue-800 dark:text-blue-200">
|
||||
Powered by Camoufox
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Profile Name - Common to both tabs */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="profile-name">Profile Name</Label>
|
||||
@@ -403,6 +396,13 @@ export function CreateProfileDialog({
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="anti-detect" className="mt-0 space-y-6">
|
||||
{/* Anti-Detect Description */}
|
||||
<div className="p-3 text-center bg-blue-50 rounded-md border border-blue-200 dark:bg-blue-950 dark:border-blue-800">
|
||||
<p className="text-sm text-blue-800 dark:text-blue-200">
|
||||
Powered by Camoufox
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-6">
|
||||
{/* Camoufox Download Status */}
|
||||
{!isBrowserVersionAvailable("camoufox") &&
|
||||
|
||||
Reference in New Issue
Block a user