fix(sync): preserve private profile boundaries
This commit is contained in:
@@ -24,18 +24,28 @@ impl BrowserCore {
|
|||||||
summary.record_skipped();
|
summary.record_skipped();
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
let name = record.name.trim().to_string();
|
||||||
|
|
||||||
let existing_index =
|
let existing_index = self
|
||||||
self.profiles.iter().position(|profile| profile.id() == &profile_id).or_else(|| {
|
.profiles
|
||||||
self.profiles
|
.iter()
|
||||||
.iter()
|
.position(|profile| profile.id() == &profile_id && profile.kind() == &kind)
|
||||||
.position(|profile| profile.name().eq_ignore_ascii_case(record.name.trim()))
|
.or_else(|| {
|
||||||
|
self.profiles.iter().position(|profile| {
|
||||||
|
profile.kind() == &kind && profile.name().eq_ignore_ascii_case(&name)
|
||||||
|
})
|
||||||
});
|
});
|
||||||
let id = existing_index
|
let id = existing_index
|
||||||
.and_then(|index| self.profiles.get(index).map(|profile| profile.id().clone()))
|
.and_then(|index| self.profiles.get(index).map(|profile| profile.id().clone()))
|
||||||
.unwrap_or_else(|| profile_id.clone());
|
.unwrap_or_else(|| {
|
||||||
|
if self.profiles.iter().any(|profile| profile.id() == &profile_id) {
|
||||||
|
ProfileId::new()
|
||||||
|
} else {
|
||||||
|
profile_id.clone()
|
||||||
|
}
|
||||||
|
});
|
||||||
context.register_profile_alias(profile_id, id.clone());
|
context.register_profile_alias(profile_id, id.clone());
|
||||||
let mut profile = Profile::new(record.name, record.color_hex, kind);
|
let mut profile = Profile::new(name, record.color_hex, kind);
|
||||||
profile.set_sync_policy(record.sync_policy.into());
|
profile.set_sync_policy(record.sync_policy.into());
|
||||||
let profile = Profile::restore(id, profile);
|
let profile = Profile::restore(id, profile);
|
||||||
|
|
||||||
|
|||||||
@@ -112,3 +112,68 @@ fn paused_profile_data_is_omitted_from_sync_snapshots() -> Result<(), Box<dyn Er
|
|||||||
assert!(target.snapshot()?.history_entries.is_empty());
|
assert!(target.snapshot()?.history_entries.is_empty());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn standard_profile_sync_preserves_a_same_named_private_profile() -> Result<(), Box<dyn Error>> {
|
||||||
|
let mut source_config = InitialBrowserConfig::ely_defaults()?;
|
||||||
|
source_config.profile_name = "Private".to_string();
|
||||||
|
let mut source = BrowserCore::new(source_config)?;
|
||||||
|
source.navigate_active_tab(UrlText::parse("https://example.com/remote")?)?;
|
||||||
|
let bytes = source.build_sync_snapshot_bytes()?;
|
||||||
|
|
||||||
|
let mut target = BrowserCore::new(InitialBrowserConfig::private_window()?)?;
|
||||||
|
let private_profile_id = target.snapshot()?.active_profile_id;
|
||||||
|
target.navigate_active_tab(UrlText::parse("https://private.example/secret")?)?;
|
||||||
|
target.apply_sync_snapshot_bytes(&bytes)?;
|
||||||
|
let snapshot = target.snapshot()?;
|
||||||
|
|
||||||
|
assert!(snapshot.profiles.iter().any(|profile| {
|
||||||
|
profile.id() == &private_profile_id && profile.kind() == &ProfileKind::Private
|
||||||
|
}));
|
||||||
|
assert!(snapshot.profiles.iter().any(|profile| {
|
||||||
|
profile.id() != &private_profile_id
|
||||||
|
&& profile.name() == "Private"
|
||||||
|
&& profile.kind() == &ProfileKind::Standard
|
||||||
|
}));
|
||||||
|
let outbound = String::from_utf8(target.build_sync_snapshot_bytes()?)?;
|
||||||
|
assert!(!outbound.contains("https://private.example/secret"));
|
||||||
|
assert!(outbound.contains("https://example.com/remote"));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn standard_profile_sync_remaps_a_private_profile_id_collision() -> Result<(), Box<dyn Error>> {
|
||||||
|
let mut target = BrowserCore::new(InitialBrowserConfig::private_window()?)?;
|
||||||
|
let private_profile_id = target.snapshot()?.active_profile_id;
|
||||||
|
target.navigate_active_tab(UrlText::parse("https://private.example/id-secret")?)?;
|
||||||
|
|
||||||
|
let mut source_config = InitialBrowserConfig::ely_defaults()?;
|
||||||
|
source_config.profile_id = Some(private_profile_id.clone());
|
||||||
|
source_config.profile_name = " Synced ".to_string();
|
||||||
|
let mut source = BrowserCore::new(source_config)?;
|
||||||
|
source.navigate_active_tab(UrlText::parse("https://example.com/id-remote")?)?;
|
||||||
|
let bytes = source.build_sync_snapshot_bytes()?;
|
||||||
|
target.apply_sync_snapshot_bytes(&bytes)?;
|
||||||
|
target.apply_sync_snapshot_bytes(&bytes)?;
|
||||||
|
let snapshot = target.snapshot()?;
|
||||||
|
|
||||||
|
assert!(snapshot.profiles.iter().any(|profile| {
|
||||||
|
profile.id() == &private_profile_id && profile.kind() == &ProfileKind::Private
|
||||||
|
}));
|
||||||
|
assert_eq!(
|
||||||
|
snapshot
|
||||||
|
.profiles
|
||||||
|
.iter()
|
||||||
|
.filter(|profile| {
|
||||||
|
profile.id() != &private_profile_id
|
||||||
|
&& profile.name() == "Synced"
|
||||||
|
&& profile.kind() == &ProfileKind::Standard
|
||||||
|
})
|
||||||
|
.count(),
|
||||||
|
1
|
||||||
|
);
|
||||||
|
let outbound = String::from_utf8(target.build_sync_snapshot_bytes()?)?;
|
||||||
|
assert!(!outbound.contains("https://private.example/id-secret"));
|
||||||
|
assert!(outbound.contains("https://example.com/id-remote"));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user