mirror of
https://github.com/zhom/donutbrowser.git
synced 2026-07-18 02:17:23 +02:00
refactor: fully deprecate camoufox
This commit is contained in:
@@ -1,12 +1,10 @@
|
||||
use crate::api_client::{sort_versions, ApiClient, BrowserRelease};
|
||||
use crate::browser::GithubRelease;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct BrowserVersionInfo {
|
||||
pub version: String,
|
||||
pub is_prerelease: bool,
|
||||
pub date: String,
|
||||
}
|
||||
|
||||
@@ -20,7 +18,6 @@ pub struct BrowserVersionsResult {
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct BrowserReleaseTypes {
|
||||
pub stable: Option<String>,
|
||||
pub nightly: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
@@ -53,33 +50,8 @@ impl BrowserVersionManager {
|
||||
let (os, arch) = Self::get_platform_info();
|
||||
|
||||
match browser {
|
||||
"firefox" | "firefox-developer" => Ok(true),
|
||||
"zen" => {
|
||||
// Zen supports all platforms and architectures
|
||||
Ok(true)
|
||||
}
|
||||
"brave" => {
|
||||
// Brave supports all platforms and architectures
|
||||
Ok(true)
|
||||
}
|
||||
"chromium" => {
|
||||
// Chromium doesn't support ARM64 on Linux
|
||||
if arch == "arm64" && os == "linux" {
|
||||
Ok(false)
|
||||
} else {
|
||||
Ok(true)
|
||||
}
|
||||
}
|
||||
"camoufox" => {
|
||||
// Camoufox supports all platforms and architectures according to the JS code
|
||||
Ok(true)
|
||||
}
|
||||
"wayfern" => {
|
||||
// Wayfern support depends on version.json downloads availability
|
||||
// Currently supports macos-arm64 and linux-x64
|
||||
let platform_key = format!("{os}-{arch}");
|
||||
// Check dynamically, but allow the browser to appear even if platform not available yet
|
||||
// The actual download will fail gracefully if not supported
|
||||
Ok(matches!(
|
||||
platform_key.as_str(),
|
||||
"macos-arm64"
|
||||
@@ -96,15 +68,7 @@ impl BrowserVersionManager {
|
||||
|
||||
/// Get list of browsers supported on the current platform
|
||||
pub fn get_supported_browsers(&self) -> Vec<String> {
|
||||
let all_browsers = vec![
|
||||
"firefox",
|
||||
"firefox-developer",
|
||||
"zen",
|
||||
"brave",
|
||||
"chromium",
|
||||
"camoufox",
|
||||
"wayfern",
|
||||
];
|
||||
let all_browsers = vec!["wayfern"];
|
||||
|
||||
all_browsers
|
||||
.into_iter()
|
||||
@@ -115,13 +79,6 @@ impl BrowserVersionManager {
|
||||
|
||||
/// Get cached browser versions immediately (returns None if no cache exists)
|
||||
pub fn get_cached_browser_versions(&self, browser: &str) -> Option<Vec<String>> {
|
||||
if browser == "brave" {
|
||||
return self
|
||||
.api_client
|
||||
.get_cached_github_releases("brave")
|
||||
.map(|releases| releases.into_iter().map(|r| r.tag_name).collect());
|
||||
}
|
||||
|
||||
self
|
||||
.api_client
|
||||
.load_cached_versions(browser)
|
||||
@@ -133,20 +90,6 @@ impl BrowserVersionManager {
|
||||
&self,
|
||||
browser: &str,
|
||||
) -> Option<Vec<BrowserVersionInfo>> {
|
||||
if browser == "brave" {
|
||||
if let Some(releases) = self.api_client.get_cached_github_releases("brave") {
|
||||
let detailed_info: Vec<BrowserVersionInfo> = releases
|
||||
.into_iter()
|
||||
.map(|r| BrowserVersionInfo {
|
||||
version: r.tag_name,
|
||||
is_prerelease: r.is_nightly,
|
||||
date: r.published_at,
|
||||
})
|
||||
.collect();
|
||||
return Some(detailed_info);
|
||||
}
|
||||
}
|
||||
|
||||
let cached_releases = self.api_client.load_cached_versions(browser)?;
|
||||
|
||||
// Convert cached versions to detailed info (without dates since cache doesn't store them)
|
||||
@@ -154,7 +97,6 @@ impl BrowserVersionManager {
|
||||
.into_iter()
|
||||
.map(|r| BrowserVersionInfo {
|
||||
version: r.version,
|
||||
is_prerelease: r.is_prerelease,
|
||||
date: r.date,
|
||||
})
|
||||
.collect();
|
||||
@@ -167,44 +109,25 @@ impl BrowserVersionManager {
|
||||
self.api_client.is_cache_expired(browser)
|
||||
}
|
||||
|
||||
/// Get latest stable and nightly versions for a browser (cached first)
|
||||
/// Get the latest Wayfern version (cached first)
|
||||
pub async fn get_browser_release_types(
|
||||
&self,
|
||||
browser: &str,
|
||||
) -> Result<BrowserReleaseTypes, Box<dyn std::error::Error + Send + Sync>> {
|
||||
// Try to get from cache first
|
||||
if browser != "wayfern" {
|
||||
return Err(format!("Unsupported browser: {browser}").into());
|
||||
}
|
||||
|
||||
if let Some(cached_versions) = self.get_cached_browser_versions_detailed(browser) {
|
||||
let latest_stable = cached_versions
|
||||
.iter()
|
||||
.find(|v| !v.is_prerelease)
|
||||
.map(|v| v.version.clone());
|
||||
|
||||
let latest_nightly = cached_versions
|
||||
.iter()
|
||||
.find(|v| v.is_prerelease)
|
||||
.map(|v| v.version.clone());
|
||||
|
||||
return Ok(BrowserReleaseTypes {
|
||||
stable: latest_stable,
|
||||
nightly: latest_nightly,
|
||||
stable: cached_versions.first().map(|v| v.version.clone()),
|
||||
});
|
||||
}
|
||||
|
||||
let detailed_versions = self.fetch_browser_versions_detailed(browser, false).await?;
|
||||
|
||||
let latest_stable = detailed_versions
|
||||
.iter()
|
||||
.find(|v| !v.is_prerelease)
|
||||
.map(|v| v.version.clone());
|
||||
|
||||
let latest_nightly = detailed_versions
|
||||
.iter()
|
||||
.find(|v| v.is_prerelease)
|
||||
.map(|v| v.version.clone());
|
||||
|
||||
Ok(BrowserReleaseTypes {
|
||||
stable: latest_stable,
|
||||
nightly: latest_nightly,
|
||||
stable: detailed_versions.first().map(|v| v.version.clone()),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -235,12 +158,6 @@ impl BrowserVersionManager {
|
||||
|
||||
// Fetch fresh versions from API
|
||||
let fresh_versions = match browser {
|
||||
"firefox" => self.fetch_firefox_versions(true).await?, // Always fetch fresh for merging
|
||||
"firefox-developer" => self.fetch_firefox_developer_versions(true).await?,
|
||||
"zen" => self.fetch_zen_versions(true).await?,
|
||||
"brave" => self.fetch_brave_versions(true).await?,
|
||||
"chromium" => self.fetch_chromium_versions(true).await?,
|
||||
"camoufox" => self.fetch_camoufox_versions(true).await?,
|
||||
"wayfern" => self.fetch_wayfern_versions(true).await?,
|
||||
_ => return Err(format!("Unsupported browser: {browser}").into()),
|
||||
};
|
||||
@@ -262,13 +179,12 @@ impl BrowserVersionManager {
|
||||
crate::api_client::sort_versions(&mut merged_versions);
|
||||
|
||||
// Save the merged cache (unless explicitly bypassing cache)
|
||||
if !no_caching && browser != "brave" {
|
||||
if !no_caching {
|
||||
let merged_releases: Vec<BrowserRelease> = merged_versions
|
||||
.iter()
|
||||
.map(|v| BrowserRelease {
|
||||
version: v.clone(),
|
||||
date: "".to_string(),
|
||||
is_prerelease: crate::api_client::is_browser_version_nightly(browser, v, None),
|
||||
})
|
||||
.collect();
|
||||
if let Err(e) = self
|
||||
@@ -305,157 +221,14 @@ impl BrowserVersionManager {
|
||||
// Since we don't have detailed date/prerelease info for cached versions,
|
||||
// we'll fetch fresh detailed info and map it to our merged versions
|
||||
let detailed_info: Vec<BrowserVersionInfo> = match browser {
|
||||
"firefox" => {
|
||||
let releases = self.fetch_firefox_releases_detailed(true).await?;
|
||||
merged_versions
|
||||
.into_iter()
|
||||
.map(|version| {
|
||||
// Try to find matching release info, otherwise create basic info
|
||||
if let Some(release) = releases.iter().find(|r| r.version == version) {
|
||||
BrowserVersionInfo {
|
||||
version: release.version.clone(),
|
||||
is_prerelease: release.is_prerelease,
|
||||
date: release.date.clone(),
|
||||
}
|
||||
} else {
|
||||
BrowserVersionInfo {
|
||||
version: version.clone(),
|
||||
is_prerelease: crate::api_client::is_browser_version_nightly(
|
||||
"firefox", &version, None,
|
||||
),
|
||||
date: "".to_string(),
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
"firefox-developer" => {
|
||||
let releases = self.fetch_firefox_developer_releases_detailed(true).await?;
|
||||
merged_versions
|
||||
.into_iter()
|
||||
.map(|version| {
|
||||
if let Some(release) = releases.iter().find(|r| r.version == version) {
|
||||
BrowserVersionInfo {
|
||||
version: release.version.clone(),
|
||||
is_prerelease: release.is_prerelease,
|
||||
date: release.date.clone(),
|
||||
}
|
||||
} else {
|
||||
BrowserVersionInfo {
|
||||
version: version.clone(),
|
||||
is_prerelease: crate::api_client::is_browser_version_nightly(
|
||||
"firefox-developer",
|
||||
&version,
|
||||
None,
|
||||
),
|
||||
date: "".to_string(),
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
"zen" => {
|
||||
let releases = self.fetch_zen_releases_detailed(true).await?;
|
||||
merged_versions
|
||||
.into_iter()
|
||||
// Filter out twilight releases at the detailed level too
|
||||
.filter(|version| version.to_lowercase() != "twilight")
|
||||
.map(|version| {
|
||||
if let Some(release) = releases.iter().find(|r| r.tag_name == version) {
|
||||
BrowserVersionInfo {
|
||||
version: release.tag_name.clone(),
|
||||
is_prerelease: release.is_nightly,
|
||||
date: release.published_at.clone(),
|
||||
}
|
||||
} else {
|
||||
BrowserVersionInfo {
|
||||
version: version.clone(),
|
||||
is_prerelease: crate::api_client::is_browser_version_nightly("zen", &version, None),
|
||||
date: "".to_string(),
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
"brave" => {
|
||||
let releases = self.fetch_brave_releases_detailed(true).await?;
|
||||
merged_versions
|
||||
.into_iter()
|
||||
.map(|version| {
|
||||
if let Some(release) = releases.iter().find(|r| r.tag_name == version) {
|
||||
BrowserVersionInfo {
|
||||
version: release.tag_name.clone(),
|
||||
is_prerelease: release.is_nightly,
|
||||
date: release.published_at.clone(),
|
||||
}
|
||||
} else {
|
||||
BrowserVersionInfo {
|
||||
version: version.clone(),
|
||||
is_prerelease: crate::api_client::is_browser_version_nightly(
|
||||
"brave", &version, None,
|
||||
),
|
||||
date: "".to_string(),
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
"chromium" => {
|
||||
let releases = self.fetch_chromium_releases_detailed(true).await?;
|
||||
merged_versions
|
||||
.into_iter()
|
||||
.map(|version| {
|
||||
if let Some(release) = releases.iter().find(|r| r.version == version) {
|
||||
BrowserVersionInfo {
|
||||
version: release.version.clone(),
|
||||
is_prerelease: release.is_prerelease,
|
||||
date: release.date.clone(),
|
||||
}
|
||||
} else {
|
||||
BrowserVersionInfo {
|
||||
version: version.clone(),
|
||||
is_prerelease: false, // Chromium usually stable releases
|
||||
date: "".to_string(),
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
"camoufox" => {
|
||||
let releases = self.fetch_camoufox_releases_detailed(true).await?;
|
||||
merged_versions
|
||||
.into_iter()
|
||||
.map(|version| {
|
||||
if let Some(release) = releases.iter().find(|r| r.tag_name == version) {
|
||||
BrowserVersionInfo {
|
||||
version: release.tag_name.clone(),
|
||||
is_prerelease: release.is_nightly,
|
||||
date: release.published_at.clone(),
|
||||
}
|
||||
} else {
|
||||
BrowserVersionInfo {
|
||||
version: version.clone(),
|
||||
is_prerelease: false, // Camoufox usually stable releases
|
||||
date: "".to_string(),
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
"wayfern" => {
|
||||
// Wayfern only has one version from version.json
|
||||
merged_versions
|
||||
.into_iter()
|
||||
.map(|version| BrowserVersionInfo {
|
||||
version: version.clone(),
|
||||
is_prerelease: false, // Wayfern releases are always stable
|
||||
date: "".to_string(),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
_ => {
|
||||
return Err(format!("Unsupported browser: {browser}").into());
|
||||
}
|
||||
"wayfern" => merged_versions
|
||||
.into_iter()
|
||||
.map(|version| BrowserVersionInfo {
|
||||
version: version.clone(),
|
||||
date: "".to_string(),
|
||||
})
|
||||
.collect(),
|
||||
_ => return Err(format!("Unsupported browser: {browser}").into()),
|
||||
};
|
||||
|
||||
Ok(detailed_info)
|
||||
@@ -493,7 +266,6 @@ impl BrowserVersionManager {
|
||||
.map(|v| BrowserRelease {
|
||||
version: v.clone(),
|
||||
date: "".to_string(),
|
||||
is_prerelease: crate::api_client::is_browser_version_nightly(browser, v, None),
|
||||
})
|
||||
.collect();
|
||||
if let Err(e) = self.api_client.save_cached_versions(browser, &releases) {
|
||||
@@ -512,170 +284,6 @@ impl BrowserVersionManager {
|
||||
let (os, arch) = Self::get_platform_info();
|
||||
|
||||
match browser {
|
||||
"firefox" => {
|
||||
let (platform_path, filename, is_archive) = match (&os[..], &arch[..]) {
|
||||
("windows", "x64") => ("win64", format!("Firefox Setup {version}.exe"), false),
|
||||
("windows", "arm64") => (
|
||||
"win64-aarch64",
|
||||
format!("Firefox Setup {version}.exe"),
|
||||
false,
|
||||
),
|
||||
("linux", "x64") => ("linux-x86_64", format!("firefox-{version}.tar.xz"), true),
|
||||
("linux", "arm64") => ("linux-aarch64", format!("firefox-{version}.tar.xz"), true),
|
||||
("macos", _) => ("mac", format!("Firefox {version}.dmg"), true),
|
||||
_ => {
|
||||
return Err(
|
||||
format!("Unsupported platform/architecture for Firefox: {os}/{arch}").into(),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
Ok(DownloadInfo {
|
||||
url: format!(
|
||||
"https://download-installer.cdn.mozilla.net/pub/firefox/releases/{version}/{platform_path}/en-US/{filename}"
|
||||
),
|
||||
filename,
|
||||
is_archive,
|
||||
})
|
||||
}
|
||||
"firefox-developer" => {
|
||||
let (platform_path, filename, is_archive) = match (&os[..], &arch[..]) {
|
||||
("windows", "x64") => ("win64", format!("Firefox Setup {version}.exe"), false),
|
||||
("windows", "arm64") => (
|
||||
"win64-aarch64",
|
||||
format!("Firefox Setup {version}.exe"),
|
||||
false,
|
||||
),
|
||||
("linux", "x64") => ("linux-x86_64", format!("firefox-{version}.tar.xz"), true),
|
||||
("linux", "arm64") => ("linux-aarch64", format!("firefox-{version}.tar.xz"), true),
|
||||
("macos", _) => ("mac", format!("Firefox {version}.dmg"), true),
|
||||
_ => {
|
||||
return Err(
|
||||
format!("Unsupported platform/architecture for Firefox Developer: {os}/{arch}")
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
Ok(DownloadInfo {
|
||||
url: format!(
|
||||
"https://download-installer.cdn.mozilla.net/pub/devedition/releases/{version}/{platform_path}/en-US/{filename}"
|
||||
),
|
||||
filename,
|
||||
is_archive,
|
||||
})
|
||||
}
|
||||
"zen" => {
|
||||
let (asset_name, filename, is_archive) = match (&os[..], &arch[..]) {
|
||||
("windows", "x64") => ("zen.installer.exe", format!("zen-{version}.exe"), false),
|
||||
("windows", "arm64") => (
|
||||
"zen.installer-arm64.exe",
|
||||
format!("zen-{version}-arm64.exe"),
|
||||
false,
|
||||
),
|
||||
("linux", "x64") => (
|
||||
"zen.linux-x86_64.tar.xz",
|
||||
format!("zen-{version}-x86_64.tar.xz"),
|
||||
true,
|
||||
),
|
||||
("linux", "arm64") => (
|
||||
"zen.linux-aarch64.tar.xz",
|
||||
format!("zen-{version}-aarch64.tar.xz"),
|
||||
true,
|
||||
),
|
||||
("macos", _) => (
|
||||
"zen.macos-universal.dmg",
|
||||
format!("zen-{version}.dmg"),
|
||||
true,
|
||||
),
|
||||
_ => {
|
||||
return Err(format!("Unsupported platform/architecture for Zen: {os}/{arch}").into())
|
||||
}
|
||||
};
|
||||
|
||||
Ok(DownloadInfo {
|
||||
url: format!(
|
||||
"https://github.com/zen-browser/desktop/releases/download/{version}/{asset_name}"
|
||||
),
|
||||
filename,
|
||||
is_archive,
|
||||
})
|
||||
}
|
||||
"brave" => {
|
||||
let (filename, is_archive) = match (&os[..], &arch[..]) {
|
||||
("windows", _) => (format!("brave-{version}.exe"), false),
|
||||
("linux", "x64") => (format!("brave-browser-{version}-linux-amd64.zip"), true),
|
||||
("linux", "arm64") => (format!("brave-browser-{version}-linux-arm64.zip"), true),
|
||||
("macos", _) => ("Brave-Browser-universal.dmg".to_string(), true),
|
||||
_ => {
|
||||
return Err(format!("Unsupported platform/architecture for Brave: {os}/{arch}").into())
|
||||
}
|
||||
};
|
||||
|
||||
Ok(DownloadInfo {
|
||||
url: format!(
|
||||
"https://github.com/brave/brave-browser/releases/download/{version}/{filename}"
|
||||
),
|
||||
filename,
|
||||
is_archive,
|
||||
})
|
||||
}
|
||||
"chromium" => {
|
||||
let platform_str = match (&os[..], &arch[..]) {
|
||||
("windows", "x64") => "Win_x64",
|
||||
("windows", "arm64") => "Win_Arm64",
|
||||
("linux", "x64") => "Linux_x64",
|
||||
("linux", "arm64") => return Err("Chromium doesn't support ARM64 on Linux".into()),
|
||||
("macos", "x64") => "Mac",
|
||||
("macos", "arm64") => "Mac_Arm",
|
||||
_ => {
|
||||
return Err(
|
||||
format!("Unsupported platform/architecture for Chromium: {os}/{arch}").into(),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
let (archive_name, filename) = match os.as_str() {
|
||||
"windows" => ("chrome-win.zip", format!("chromium-{version}-win.zip")),
|
||||
"linux" => ("chrome-linux.zip", format!("chromium-{version}-linux.zip")),
|
||||
"macos" => ("chrome-mac.zip", format!("chromium-{version}-mac.zip")),
|
||||
_ => return Err(format!("Unsupported platform for Chromium: {os}").into()),
|
||||
};
|
||||
|
||||
Ok(DownloadInfo {
|
||||
url: format!(
|
||||
"https://commondatastorage.googleapis.com/chromium-browser-snapshots/{platform_str}/{version}/{archive_name}"
|
||||
),
|
||||
filename,
|
||||
is_archive: true,
|
||||
})
|
||||
}
|
||||
"camoufox" => {
|
||||
// Camoufox downloads from GitHub releases with pattern: camoufox-{version}-{release}-{os}.{arch}.zip
|
||||
let (os_name, arch_name) = match (&os[..], &arch[..]) {
|
||||
("windows", "x64") => ("win", "x86_64"),
|
||||
("windows", "arm64") => ("win", "arm64"),
|
||||
("linux", "x64") => ("lin", "x86_64"),
|
||||
("linux", "arm64") => ("lin", "arm64"),
|
||||
("macos", "x64") => ("mac", "x86_64"),
|
||||
("macos", "arm64") => ("mac", "arm64"),
|
||||
_ => {
|
||||
return Err(
|
||||
format!("Unsupported platform/architecture for Camoufox: {os}/{arch}").into(),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
// Note: We provide a placeholder URL here since Camoufox requires dynamic resolution
|
||||
// The actual URL will be resolved in download.rs resolve_download_url
|
||||
Ok(DownloadInfo {
|
||||
url: format!(
|
||||
"https://github.com/daijro/camoufox/releases/download/{version}/camoufox-{{version}}-{{release}}-{os_name}.{arch_name}.zip"
|
||||
),
|
||||
filename: format!("camoufox-{version}-{os_name}.{arch_name}.zip"),
|
||||
is_archive: true,
|
||||
})
|
||||
}
|
||||
"wayfern" => {
|
||||
// Wayfern downloads from https://download.wayfern.com/
|
||||
// File naming: wayfern-{chromium_version}-{platform}-{arch}.{ext}
|
||||
@@ -728,153 +336,6 @@ impl BrowserVersionManager {
|
||||
(os.to_string(), arch.to_string())
|
||||
}
|
||||
|
||||
// Private helper methods for each browser type
|
||||
|
||||
async fn fetch_firefox_versions(
|
||||
&self,
|
||||
no_caching: bool,
|
||||
) -> Result<Vec<String>, Box<dyn std::error::Error + Send + Sync>> {
|
||||
let releases = self.fetch_firefox_releases_detailed(no_caching).await?;
|
||||
Ok(releases.into_iter().map(|r| r.version).collect())
|
||||
}
|
||||
|
||||
async fn fetch_firefox_releases_detailed(
|
||||
&self,
|
||||
no_caching: bool,
|
||||
) -> Result<Vec<BrowserRelease>, Box<dyn std::error::Error + Send + Sync>> {
|
||||
self
|
||||
.api_client
|
||||
.fetch_firefox_releases_with_caching(no_caching)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn fetch_firefox_developer_versions(
|
||||
&self,
|
||||
no_caching: bool,
|
||||
) -> Result<Vec<String>, Box<dyn std::error::Error + Send + Sync>> {
|
||||
let releases = self
|
||||
.fetch_firefox_developer_releases_detailed(no_caching)
|
||||
.await?;
|
||||
Ok(releases.into_iter().map(|r| r.version).collect())
|
||||
}
|
||||
|
||||
async fn fetch_firefox_developer_releases_detailed(
|
||||
&self,
|
||||
no_caching: bool,
|
||||
) -> Result<Vec<BrowserRelease>, Box<dyn std::error::Error + Send + Sync>> {
|
||||
self
|
||||
.api_client
|
||||
.fetch_firefox_developer_releases_with_caching(no_caching)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn fetch_zen_versions(
|
||||
&self,
|
||||
no_caching: bool,
|
||||
) -> Result<Vec<String>, Box<dyn std::error::Error + Send + Sync>> {
|
||||
let releases = self.fetch_zen_releases_detailed(no_caching).await?;
|
||||
Ok(
|
||||
releases
|
||||
.into_iter()
|
||||
.filter(|r| r.tag_name.to_lowercase() != "twilight")
|
||||
.map(|r| r.tag_name)
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
||||
async fn fetch_zen_releases_detailed(
|
||||
&self,
|
||||
no_caching: bool,
|
||||
) -> Result<Vec<GithubRelease>, Box<dyn std::error::Error + Send + Sync>> {
|
||||
self
|
||||
.api_client
|
||||
.fetch_zen_releases_with_caching(no_caching)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn fetch_brave_versions(
|
||||
&self,
|
||||
no_caching: bool,
|
||||
) -> Result<Vec<String>, Box<dyn std::error::Error + Send + Sync>> {
|
||||
let releases = self.fetch_brave_releases_detailed(no_caching).await?;
|
||||
// Persist a lightweight versions cache with accurate prerelease info for Brave
|
||||
let converted: Vec<BrowserRelease> = releases
|
||||
.iter()
|
||||
.map(|r| BrowserRelease {
|
||||
version: r.tag_name.clone(),
|
||||
date: r.published_at.clone(),
|
||||
is_prerelease: r.is_nightly,
|
||||
})
|
||||
.collect();
|
||||
// Always save so that other callers without release_name can classify correctly
|
||||
if let Err(e) = self.api_client.save_cached_versions("brave", &converted) {
|
||||
log::error!("Failed to persist Brave versions cache: {e}");
|
||||
}
|
||||
|
||||
Ok(releases.into_iter().map(|r| r.tag_name).collect())
|
||||
}
|
||||
|
||||
async fn fetch_brave_releases_detailed(
|
||||
&self,
|
||||
no_caching: bool,
|
||||
) -> Result<Vec<GithubRelease>, Box<dyn std::error::Error + Send + Sync>> {
|
||||
let releases = self
|
||||
.api_client
|
||||
.fetch_brave_releases_with_caching(no_caching)
|
||||
.await?;
|
||||
|
||||
// Save a parallel versions cache for Brave with accurate prerelease flags
|
||||
let converted: Vec<BrowserRelease> = releases
|
||||
.iter()
|
||||
.map(|r| BrowserRelease {
|
||||
version: r.tag_name.clone(),
|
||||
date: r.published_at.clone(),
|
||||
is_prerelease: r.is_nightly,
|
||||
})
|
||||
.collect();
|
||||
if let Err(e) = self.api_client.save_cached_versions("brave", &converted) {
|
||||
log::error!("Failed to persist Brave versions cache: {e}");
|
||||
}
|
||||
|
||||
Ok(releases)
|
||||
}
|
||||
|
||||
async fn fetch_chromium_versions(
|
||||
&self,
|
||||
no_caching: bool,
|
||||
) -> Result<Vec<String>, Box<dyn std::error::Error + Send + Sync>> {
|
||||
let releases = self.fetch_chromium_releases_detailed(no_caching).await?;
|
||||
Ok(releases.into_iter().map(|r| r.version).collect())
|
||||
}
|
||||
|
||||
async fn fetch_chromium_releases_detailed(
|
||||
&self,
|
||||
no_caching: bool,
|
||||
) -> Result<Vec<BrowserRelease>, Box<dyn std::error::Error + Send + Sync>> {
|
||||
self
|
||||
.api_client
|
||||
.fetch_chromium_releases_with_caching(no_caching)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn fetch_camoufox_versions(
|
||||
&self,
|
||||
no_caching: bool,
|
||||
) -> Result<Vec<String>, Box<dyn std::error::Error + Send + Sync>> {
|
||||
let releases = self.fetch_camoufox_releases_detailed(no_caching).await?;
|
||||
Ok(releases.into_iter().map(|r| r.tag_name).collect())
|
||||
}
|
||||
|
||||
async fn fetch_camoufox_releases_detailed(
|
||||
&self,
|
||||
no_caching: bool,
|
||||
) -> Result<Vec<GithubRelease>, Box<dyn std::error::Error + Send + Sync>> {
|
||||
self
|
||||
.api_client
|
||||
.fetch_camoufox_releases_with_caching(no_caching)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn fetch_wayfern_versions(
|
||||
&self,
|
||||
no_caching: bool,
|
||||
@@ -912,37 +373,14 @@ pub async fn get_browser_release_types(
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use wiremock::MockServer;
|
||||
|
||||
async fn setup_mock_server() -> MockServer {
|
||||
MockServer::start().await
|
||||
}
|
||||
|
||||
fn create_test_api_client(server: &MockServer) -> ApiClient {
|
||||
let base_url = server.uri();
|
||||
ApiClient::new_with_base_urls(
|
||||
base_url.clone(), // firefox_api_base
|
||||
base_url.clone(), // firefox_dev_api_base
|
||||
base_url.clone(), // github_api_base
|
||||
base_url.clone(), // chromium_api_base
|
||||
)
|
||||
}
|
||||
|
||||
fn create_test_service(_api_client: ApiClient) -> &'static BrowserVersionManager {
|
||||
BrowserVersionManager::instance()
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_browser_version_manager_creation() {
|
||||
let _ = BrowserVersionManager::instance();
|
||||
// Test passes if we can create the service without panicking
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_unsupported_browser() {
|
||||
let server = setup_mock_server().await;
|
||||
let api_client = create_test_api_client(&server);
|
||||
let service = create_test_service(api_client);
|
||||
let service = BrowserVersionManager::instance();
|
||||
|
||||
let result = service.fetch_browser_versions("unsupported", false).await;
|
||||
assert!(
|
||||
@@ -962,141 +400,48 @@ mod tests {
|
||||
fn test_get_download_info() {
|
||||
let service = BrowserVersionManager::instance();
|
||||
|
||||
// Test Firefox - platform-specific expectations
|
||||
let firefox_info = service.get_download_info("firefox", "139.0").unwrap();
|
||||
let wayfern_info = service.get_download_info("wayfern", "1.0.0").unwrap();
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(all(target_os = "macos", target_arch = "aarch64"))]
|
||||
{
|
||||
assert_eq!(firefox_info.filename, "Firefox 139.0.dmg");
|
||||
assert!(firefox_info.is_archive);
|
||||
assert_eq!(wayfern_info.filename, "wayfern-1.0.0-macos-arm64.dmg");
|
||||
assert!(wayfern_info.is_archive);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(all(target_os = "macos", target_arch = "x86_64"))]
|
||||
{
|
||||
assert_eq!(firefox_info.filename, "firefox-139.0.tar.xz");
|
||||
assert!(firefox_info.is_archive);
|
||||
assert_eq!(wayfern_info.filename, "wayfern-1.0.0-macos-x64.dmg");
|
||||
assert!(wayfern_info.is_archive);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
|
||||
{
|
||||
assert_eq!(firefox_info.filename, "Firefox Setup 139.0.exe");
|
||||
assert!(!firefox_info.is_archive);
|
||||
assert_eq!(wayfern_info.filename, "wayfern-1.0.0-linux-x64.tar.xz");
|
||||
assert!(wayfern_info.is_archive);
|
||||
}
|
||||
|
||||
assert!(firefox_info
|
||||
.url
|
||||
.contains("download-installer.cdn.mozilla.net"));
|
||||
assert!(firefox_info.url.contains("/pub/firefox/releases/139.0/"));
|
||||
|
||||
// Test Firefox Developer
|
||||
let firefox_dev_info = service
|
||||
.get_download_info("firefox-developer", "139.0b1")
|
||||
.unwrap();
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(all(target_os = "linux", target_arch = "aarch64"))]
|
||||
{
|
||||
assert_eq!(firefox_dev_info.filename, "Firefox 139.0b1.dmg");
|
||||
assert!(firefox_dev_info.is_archive);
|
||||
assert_eq!(wayfern_info.filename, "wayfern-1.0.0-linux-arm64.tar.xz");
|
||||
assert!(wayfern_info.is_archive);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(all(target_os = "windows", target_arch = "x86_64"))]
|
||||
{
|
||||
assert_eq!(firefox_dev_info.filename, "firefox-139.0b1.tar.xz");
|
||||
assert!(firefox_dev_info.is_archive);
|
||||
assert_eq!(wayfern_info.filename, "wayfern-1.0.0-windows-x64.zip");
|
||||
assert!(wayfern_info.is_archive);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
#[cfg(all(target_os = "windows", target_arch = "aarch64"))]
|
||||
{
|
||||
assert_eq!(firefox_dev_info.filename, "Firefox Setup 139.0b1.exe");
|
||||
assert!(!firefox_dev_info.is_archive);
|
||||
assert_eq!(wayfern_info.filename, "wayfern-1.0.0-windows-arm64.zip");
|
||||
assert!(wayfern_info.is_archive);
|
||||
}
|
||||
|
||||
assert!(firefox_dev_info
|
||||
.url
|
||||
.contains("download-installer.cdn.mozilla.net"));
|
||||
assert!(firefox_dev_info
|
||||
.url
|
||||
.contains("/pub/devedition/releases/139.0b1/"));
|
||||
assert!(wayfern_info.url.contains("download.wayfern.com"));
|
||||
|
||||
// Test Zen Browser
|
||||
let zen_info = service.get_download_info("zen", "1.11b").unwrap();
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
assert_eq!(zen_info.filename, "zen-1.11b.dmg");
|
||||
assert!(zen_info.url.contains("zen.macos-universal.dmg"));
|
||||
assert!(zen_info.is_archive);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
assert_eq!(zen_info.filename, "zen-1.11b-x86_64.tar.xz");
|
||||
assert!(zen_info.url.contains("zen.linux-x86_64.tar.xz"));
|
||||
assert!(zen_info.is_archive);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
assert_eq!(zen_info.filename, "zen-1.11b.exe");
|
||||
assert!(zen_info.url.contains("zen.installer.exe"));
|
||||
assert!(!zen_info.is_archive);
|
||||
}
|
||||
|
||||
// Test Chromium
|
||||
let chromium_info = service.get_download_info("chromium", "1465660").unwrap();
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
assert_eq!(chromium_info.filename, "chromium-1465660-mac.zip");
|
||||
assert!(chromium_info.url.contains("chrome-mac.zip"));
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
assert_eq!(chromium_info.filename, "chromium-1465660-linux.zip");
|
||||
assert!(chromium_info.url.contains("chrome-linux.zip"));
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
assert_eq!(chromium_info.filename, "chromium-1465660-win.zip");
|
||||
assert!(chromium_info.url.contains("chrome-win.zip"));
|
||||
}
|
||||
|
||||
assert!(chromium_info.is_archive);
|
||||
|
||||
// Test Brave - Note: Brave uses dynamic URL resolution, so get_download_info provides a template URL
|
||||
let brave_info = service.get_download_info("brave", "v1.81.9").unwrap();
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
assert_eq!(brave_info.filename, "Brave-Browser-universal.dmg");
|
||||
assert_eq!(brave_info.url, "https://github.com/brave/brave-browser/releases/download/v1.81.9/Brave-Browser-universal.dmg");
|
||||
assert!(brave_info.is_archive);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
assert_eq!(brave_info.filename, "brave-browser-v1.81.9-linux-amd64.zip");
|
||||
assert_eq!(brave_info.url, "https://github.com/brave/brave-browser/releases/download/v1.81.9/brave-browser-v1.81.9-linux-amd64.zip");
|
||||
assert!(brave_info.is_archive);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
assert_eq!(brave_info.filename, "brave-v1.81.9.exe");
|
||||
assert_eq!(
|
||||
brave_info.url,
|
||||
"https://github.com/brave/brave-browser/releases/download/v1.81.9/brave-v1.81.9.exe"
|
||||
);
|
||||
assert!(!brave_info.is_archive);
|
||||
}
|
||||
|
||||
// Test unsupported browser
|
||||
let unsupported_result = service.get_download_info("unsupported", "1.0.0");
|
||||
let unsupported_result = service.get_download_info("firefox", "1.0.0");
|
||||
assert!(unsupported_result.is_err());
|
||||
|
||||
log::info!("Download info test passed for all browsers");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user