diff --git a/crates/ely_browser_core/src/navigation.rs b/crates/ely_browser_core/src/navigation.rs index 4f3d210..55dd641 100644 --- a/crates/ely_browser_core/src/navigation.rs +++ b/crates/ely_browser_core/src/navigation.rs @@ -60,6 +60,10 @@ pub(crate) fn new_profile_name(command: &str) -> Option<&str> { command_argument(command, &["new-profile ", "new profile "]) } +pub(crate) fn new_private_profile_name(command: &str) -> Option<&str> { + command_argument(command, &["new-private-profile ", "new private profile "]) +} + pub(crate) fn switch_profile_name(command: &str) -> Option<&str> { command_argument(command, &["switch-profile ", "switch profile "]) } diff --git a/crates/ely_browser_core/src/state/commands.rs b/crates/ely_browser_core/src/state/commands.rs index 63a0fc8..04347fc 100644 --- a/crates/ely_browser_core/src/state/commands.rs +++ b/crates/ely_browser_core/src/state/commands.rs @@ -4,9 +4,9 @@ use crate::{ CoreError, navigation::{ about_url, bookmarks_url, downloads_url, history_url, move_tab_space_name, - new_profile_name, new_space_name, plugin_detail_url, plugins_url, reading_list_url, - search_url, settings_page_url, settings_url, space_icon, switch_profile_name, - sync_status_url, task_manager_url, + new_private_profile_name, new_profile_name, new_space_name, plugin_detail_url, plugins_url, + reading_list_url, search_url, settings_page_url, settings_url, space_icon, + switch_profile_name, sync_status_url, task_manager_url, }, }; @@ -97,6 +97,10 @@ impl BrowserCore { self.create_profile(name.to_string(), 0xf54e00, ProfileKind::Standard)?; return Ok(true); } + if let Some(name) = new_private_profile_name(command) { + self.create_profile(name.to_string(), 0x807d72, ProfileKind::Private)?; + return Ok(true); + } if let Some(name) = move_tab_space_name(command) { let Some(space_id) = self.find_space_match(name) else { return Ok(false); diff --git a/crates/ely_browser_core/src/state/history.rs b/crates/ely_browser_core/src/state/history.rs index d4cde72..8133a43 100644 --- a/crates/ely_browser_core/src/state/history.rs +++ b/crates/ely_browser_core/src/state/history.rs @@ -1,6 +1,6 @@ use std::time::SystemTime; -use ely_domain::{BrowserTab, HistoryEntry, UrlText}; +use ely_domain::{BrowserTab, HistoryEntry, ProfileId, ProfileKind, UrlText}; use crate::navigation::records_history; @@ -8,7 +8,7 @@ use super::BrowserCore; impl BrowserCore { pub(super) fn record_history_entry(&mut self, tab: &BrowserTab) { - if !records_history(tab.url()) { + if !records_history(tab.url()) || !self.profile_records_history(tab.profile_id()) { return; } @@ -46,6 +46,13 @@ impl BrowserCore { .cloned() .collect() } + + fn profile_records_history(&self, profile_id: &ProfileId) -> bool { + match self.profiles.iter().find(|profile| profile.id() == profile_id) { + Some(profile) => profile.kind() == &ProfileKind::Standard, + None => false, + } + } } fn history_entry_matches_query(entry: &HistoryEntry, normalized_query: &str) -> bool { diff --git a/crates/ely_browser_core/tests/profiles.rs b/crates/ely_browser_core/tests/profiles.rs new file mode 100644 index 0000000..4d73413 --- /dev/null +++ b/crates/ely_browser_core/tests/profiles.rs @@ -0,0 +1,47 @@ +use std::error::Error; + +use ely_browser_core::{BrowserCore, InitialBrowserConfig}; +use ely_domain::{CommandIntent, ProfileKind, UrlText}; + +#[test] +fn new_private_profile_command_creates_private_profile() -> Result<(), Box> { + let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?; + + core.set_command_query(">new-private-profile Private"); + let intent = core.submit_command()?; + + assert_eq!(intent, Some(CommandIntent::Command("new-private-profile Private".to_string())),); + let snapshot = core.snapshot()?; + let Some(profile) = snapshot.profiles.iter().find(|profile| profile.name() == "Private") else { + return Err("missing private profile".into()); + }; + + assert_eq!(profile.kind(), &ProfileKind::Private); + assert_eq!(&snapshot.active_profile_id, profile.id()); + assert_eq!(snapshot.active_profile_name, "Private"); + assert_eq!(snapshot.command_query, ""); + Ok(()) +} + +#[test] +fn private_profiles_do_not_record_history() -> Result<(), Box> { + let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?; + let default_profile_id = core.snapshot()?.active_profile_id; + let private_profile_id = core.create_profile("Private", 0x807d72, ProfileKind::Private)?; + + core.open_tab(UrlText::parse("https://example.com/private")?); + let private_snapshot = core.snapshot()?; + assert_eq!(private_snapshot.active_profile_id, private_profile_id); + assert!(private_snapshot.history_entries.is_empty()); + + core.select_profile(&default_profile_id)?; + core.open_tab(UrlText::parse("https://example.com/standard")?); + let default_snapshot = core.snapshot()?; + assert_eq!(default_snapshot.active_profile_id, default_profile_id); + assert_eq!(default_snapshot.history_entries.len(), 1); + + core.select_profile(&private_profile_id)?; + let private_snapshot = core.snapshot()?; + assert!(private_snapshot.history_entries.is_empty()); + Ok(()) +}