in components/places/src/bookmark_sync/engine.rs [3598:3814]
fn test_wipe() -> Result<()> {
let api = new_mem_api();
let writer = api.open_connection(ConnectionType::ReadWrite)?;
let records = vec![
json!({
"id": "toolbar",
"type": "folder",
"parentid": "places",
"parentName": "",
"dateAdded": 0,
"title": "toolbar",
"children": ["folderAAAAAA"],
}),
json!({
"id": "folderAAAAAA",
"type": "folder",
"parentid": "toolbar",
"parentName": "toolbar",
"dateAdded": 0,
"title": "A",
"children": ["bookmarkBBBB"],
}),
json!({
"id": "bookmarkBBBB",
"type": "bookmark",
"parentid": "folderAAAAAA",
"parentName": "A",
"dateAdded": 0,
"title": "A",
"bmkUri": "http://example.com/a",
}),
json!({
"id": "menu",
"type": "folder",
"parentid": "places",
"parentName": "",
"dateAdded": 0,
"title": "menu",
"children": ["folderCCCCCC"],
}),
json!({
"id": "folderCCCCCC",
"type": "folder",
"parentid": "menu",
"parentName": "menu",
"dateAdded": 0,
"title": "A",
"children": ["bookmarkDDDD", "folderEEEEEE"],
}),
json!({
"id": "bookmarkDDDD",
"type": "bookmark",
"parentid": "folderCCCCCC",
"parentName": "C",
"dateAdded": 0,
"title": "D",
"bmkUri": "http://example.com/d",
}),
json!({
"id": "folderEEEEEE",
"type": "folder",
"parentid": "folderCCCCCC",
"parentName": "C",
"dateAdded": 0,
"title": "E",
"children": ["bookmarkFFFF"],
}),
json!({
"id": "bookmarkFFFF",
"type": "bookmark",
"parentid": "folderEEEEEE",
"parentName": "E",
"dateAdded": 0,
"title": "F",
"bmkUri": "http://example.com/f",
}),
];
let engine = create_sync_engine(&api);
let incoming = records
.into_iter()
.map(IncomingBso::from_test_content)
.collect();
let outgoing = engine_apply_incoming(&engine, incoming);
let mut outgoing_ids = outgoing
.iter()
.map(|p| p.envelope.id.clone())
.collect::<Vec<_>>();
outgoing_ids.sort();
assert_eq!(outgoing_ids, &["menu", "mobile", "toolbar", "unfiled"],);
engine
.set_uploaded(ServerTimestamp(0), outgoing_ids)
.expect("Should push synced changes back to the engine");
engine.sync_finished().expect("should work");
engine.wipe().expect("Should wipe the store");
// Wiping the store should delete all items except for the roots.
assert_local_json_tree(
&writer,
&BookmarkRootGuid::Root.as_guid(),
json!({
"guid": &BookmarkRootGuid::Root.as_guid(),
"children": [
{
"guid": &BookmarkRootGuid::Menu.as_guid(),
"children": [],
},
{
"guid": &BookmarkRootGuid::Toolbar.as_guid(),
"children": [],
},
{
"guid": &BookmarkRootGuid::Unfiled.as_guid(),
"children": [],
},
{
"guid": &BookmarkRootGuid::Mobile.as_guid(),
"children": [],
},
],
}),
);
// Now pretend that F changed remotely between the time we called `wipe`
// and the next sync.
let record_for_f = json!({
"id": "bookmarkFFFF",
"type": "bookmark",
"parentid": "folderEEEEEE",
"parentName": "E",
"dateAdded": 0,
"title": "F (remote)",
"bmkUri": "http://example.com/f-remote",
});
let incoming = vec![IncomingBso::from_test_content_ts(
record_for_f,
ServerTimestamp(1000),
)];
let outgoing = engine_apply_incoming(&engine, incoming);
let (outgoing_tombstones, outgoing_records): (Vec<_>, Vec<_>) =
outgoing.iter().partition(|record| {
matches!(
record
.to_test_incoming()
.into_content::<BookmarkRecord>()
.kind,
IncomingKind::Tombstone
)
});
let mut outgoing_record_ids = outgoing_records
.iter()
.map(|p| p.envelope.id.as_str())
.collect::<Vec<_>>();
outgoing_record_ids.sort_unstable();
assert_eq!(
outgoing_record_ids,
&["bookmarkFFFF", "menu", "mobile", "toolbar", "unfiled"],
);
let mut outgoing_tombstone_ids = outgoing_tombstones
.iter()
.map(|p| p.envelope.id.clone())
.collect::<Vec<_>>();
outgoing_tombstone_ids.sort();
assert_eq!(
outgoing_tombstone_ids,
&[
"bookmarkBBBB",
"bookmarkDDDD",
"folderAAAAAA",
"folderCCCCCC",
"folderEEEEEE"
]
);
// F should move to the closest surviving ancestor, which, in this case,
// is the menu.
assert_local_json_tree(
&writer,
&BookmarkRootGuid::Root.as_guid(),
json!({
"guid": &BookmarkRootGuid::Root.as_guid(),
"children": [
{
"guid": &BookmarkRootGuid::Menu.as_guid(),
"children": [
{
"guid": "bookmarkFFFF",
"title": "F (remote)",
"url": "http://example.com/f-remote",
},
],
},
{
"guid": &BookmarkRootGuid::Toolbar.as_guid(),
"children": [],
},
{
"guid": &BookmarkRootGuid::Unfiled.as_guid(),
"children": [],
},
{
"guid": &BookmarkRootGuid::Mobile.as_guid(),
"children": [],
},
],
}),
);
Ok(())
}