Add profile download policy
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use ely_domain::{
|
||||
ArchivedTab, BrowserTab, DomainError, DownloadEntry, HistoryEntry, Profile, ProfileId,
|
||||
ProfileKind, Space, SpaceId, TabId, UrlText,
|
||||
ArchivedTab, BrowserTab, DomainError, DownloadEntry, DownloadPolicy, HistoryEntry, Profile,
|
||||
ProfileId, ProfileKind, Space, SpaceId, TabId, UrlText,
|
||||
};
|
||||
|
||||
use crate::CoreError;
|
||||
@@ -45,6 +45,7 @@ pub struct BrowserSnapshot {
|
||||
pub active_space_id: SpaceId,
|
||||
pub active_space_name: String,
|
||||
pub active_profile_name: String,
|
||||
pub active_download_policy: DownloadPolicy,
|
||||
pub command_query: String,
|
||||
}
|
||||
|
||||
@@ -191,10 +192,18 @@ impl BrowserCore {
|
||||
active_space_id: self.active_space_id.clone(),
|
||||
active_space_name: active_space.name().to_string(),
|
||||
active_profile_name: active_profile.name().to_string(),
|
||||
active_download_policy: active_profile.download_policy().clone(),
|
||||
command_query: self.command_query.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn active_profile(&self) -> Result<&Profile, CoreError> {
|
||||
self.profiles
|
||||
.iter()
|
||||
.find(|profile| profile.id() == &self.active_profile_id)
|
||||
.ok_or(CoreError::MissingActiveTab)
|
||||
}
|
||||
|
||||
fn favorites(&self) -> Vec<BrowserTab> {
|
||||
self.tabs.iter().filter(|tab| tab.flags().favorite).cloned().collect()
|
||||
}
|
||||
|
||||
@@ -13,10 +13,12 @@ impl BrowserCore {
|
||||
file_name: impl Into<String>,
|
||||
total_bytes: Option<u64>,
|
||||
) -> Result<DownloadId, CoreError> {
|
||||
let destination = self.active_profile()?.download_policy().destination().clone();
|
||||
let entry = DownloadEntry::started(
|
||||
self.active_profile_id.clone(),
|
||||
source_url,
|
||||
file_name,
|
||||
destination,
|
||||
total_bytes,
|
||||
SystemTime::now(),
|
||||
)?;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use ely_domain::{Profile, ProfileId, ProfileKind, TabId};
|
||||
use ely_domain::{DownloadPolicy, Profile, ProfileId, ProfileKind, TabId};
|
||||
|
||||
use crate::CoreError;
|
||||
|
||||
@@ -66,4 +66,19 @@ impl BrowserCore {
|
||||
self.select_tab(&tab_id)?;
|
||||
Ok(tab_id)
|
||||
}
|
||||
|
||||
pub fn set_profile_download_policy(
|
||||
&mut self,
|
||||
profile_id: &ProfileId,
|
||||
download_policy: DownloadPolicy,
|
||||
) -> Result<(), CoreError> {
|
||||
let profile = self
|
||||
.profiles
|
||||
.iter_mut()
|
||||
.find(|profile| profile.id() == profile_id)
|
||||
.ok_or_else(|| CoreError::ProfileNotFound { id: profile_id.clone() })?;
|
||||
|
||||
profile.set_download_policy(download_policy);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
use std::error::Error;
|
||||
|
||||
use ely_browser_core::{BrowserCore, CoreError, InitialBrowserConfig};
|
||||
use ely_domain::{DomainError, DownloadId, DownloadState, ProfileKind, UrlText};
|
||||
use ely_domain::{
|
||||
DomainError, DownloadDestination, DownloadId, DownloadPolicy, DownloadSecurity, DownloadState,
|
||||
ProfileKind, UrlText,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn download_entries_stay_with_active_profile() -> Result<(), Box<dyn Error>> {
|
||||
@@ -62,6 +65,79 @@ fn controls_download_lifecycle() -> Result<(), Box<dyn Error>> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn records_active_profile_download_policy_on_started_entry() -> Result<(), Box<dyn Error>> {
|
||||
let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?;
|
||||
let profile_id = core.active_tab()?.profile_id().clone();
|
||||
let policy = DownloadPolicy::fixed_directory("/tmp/ely-work-downloads")?;
|
||||
core.set_profile_download_policy(&profile_id, policy.clone())?;
|
||||
|
||||
core.record_download_started(
|
||||
UrlText::parse("https://example.com/installer.dmg")?,
|
||||
"installer.dmg",
|
||||
Some(4096),
|
||||
)?;
|
||||
|
||||
let snapshot = core.snapshot()?;
|
||||
let entry = active_download(&core)?;
|
||||
assert_eq!(snapshot.active_download_policy, policy);
|
||||
assert_eq!(entry.destination(), policy.destination());
|
||||
assert_eq!(entry.security(), &DownloadSecurity::DangerousExtension);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn download_policies_stay_with_profile() -> Result<(), Box<dyn Error>> {
|
||||
let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?;
|
||||
let default_profile_id = core.active_tab()?.profile_id().clone();
|
||||
let default_policy = DownloadPolicy::fixed_directory("/tmp/ely-default-downloads")?;
|
||||
core.set_profile_download_policy(&default_profile_id, default_policy.clone())?;
|
||||
|
||||
let personal_profile_id = core.create_profile("Personal", 0xf54e00, ProfileKind::Standard)?;
|
||||
assert_eq!(
|
||||
core.snapshot()?.active_download_policy.destination(),
|
||||
&DownloadDestination::AskEveryTime
|
||||
);
|
||||
|
||||
let personal_policy = DownloadPolicy::fixed_directory("/tmp/ely-personal-downloads")?;
|
||||
core.set_profile_download_policy(&personal_profile_id, personal_policy.clone())?;
|
||||
assert_eq!(core.snapshot()?.active_download_policy, personal_policy);
|
||||
|
||||
core.select_profile(&default_profile_id)?;
|
||||
assert_eq!(core.snapshot()?.active_download_policy, default_policy);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_relative_download_directory() -> Result<(), Box<dyn Error>> {
|
||||
let error = match DownloadPolicy::fixed_directory("downloads") {
|
||||
Ok(_) => return Err("relative download directory should be rejected".into()),
|
||||
Err(error) => error,
|
||||
};
|
||||
|
||||
assert_eq!(error, DomainError::InvalidDownloadDirectory { path: "downloads".to_string() });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_path_like_download_file_name() -> Result<(), Box<dyn Error>> {
|
||||
let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?;
|
||||
let error = match core.record_download_started(
|
||||
UrlText::parse("https://example.com/evil.sh")?,
|
||||
"../evil.sh",
|
||||
None,
|
||||
) {
|
||||
Ok(_) => return Err("path-like download file name should be rejected".into()),
|
||||
Err(error) => error,
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
error,
|
||||
CoreError::Domain(DomainError::InvalidFileName { value: "../evil.sh".to_string() })
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn retries_cancelled_download_from_zero_bytes() -> Result<(), Box<dyn Error>> {
|
||||
let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?;
|
||||
|
||||
Reference in New Issue
Block a user