use super::*;
#[test]
fn private_group_recipient_delivery_survives_sender_restart_while_member_offline() {
let mut farm = GroupScaleFarm::new(&[1, 1, 1]);
farm.pump();
let members = farm.owners[1..]
.iter()
.map(|owner| owner.public_key().to_hex())
.collect::<Vec<_>>();
farm.devices[0]
.core
.create_group("offline private group", &members);
let group_id = farm.devices[0].core.groups.keys().next().unwrap().clone();
let chat_id = group_chat_id(&group_id);
farm.pump();
for device in &mut farm.devices {
device.core.accept_message_request(&chat_id);
}
farm.send(0, &chat_id, "private group bootstrap");
farm.pump();
farm.devices[2].online = false;
let body = "attachment message while C is offline";
let (message_id, _) = farm.send(0, &chat_id, body);
let pending = farm.devices[0]
.core
.pending_relay_publishes
.values()
.filter(|pending| pending.inner_event_id.as_deref() == Some(message_id.as_str()))
.filter_map(|pending| serde_json::from_str::<Event>(&pending.event_json).ok())
.collect::<Vec<_>>();
assert_eq!(
pending.len(),
1,
"offline and online members read the same signed event"
);
let carrier = pending[0].clone();
assert!(farm.devices[0]
.core
.protocol_engine
.as_ref()
.unwrap()
.is_known_group_sender_event_author(carrier.pubkey));
let wire = serde_json::to_string(&carrier).unwrap();
for device in &farm.devices {
assert!(!wire.contains(&device.keys.public_key().to_hex()));
}
for owner in &farm.owners {
assert!(!wire.contains(&owner.public_key().to_hex()));
}
assert!(!wire.contains(&group_id));
assert!(!farm.devices[2].core.threads[&chat_id]
.messages
.iter()
.any(|message| message.id == message_id));
assert!(
!farm.history.iter().any(|event| event.id == carrier.id),
"restart occurs before the recipient carrier has reached any relay"
);
let owner = farm.owners[0].clone();
let keys = farm.devices[0].keys.clone();
let path = farm.devices[0].core.data_dir.to_string_lossy().into_owned();
farm.devices[0].core.preferences.nostr_relay_urls.clear();
farm.devices[0].core.preferences.nearby_lan_enabled = false;
farm.devices[0].core.preferences.nearby_bluetooth_enabled = false;
farm.devices[0].core.persist_app_state().unwrap();
farm.devices[0].core.stop_device_sync_now();
let placeholder = logged_in_test_core("private-group-restart-placeholder", &owner, &keys);
let previous = std::mem::replace(&mut farm.devices[0].core, placeholder);
drop(previous);
let mut restored = logged_in_test_core_at_data_dir(&owner, &keys, path);
restored
.start_session_inner(
owner.public_key(),
Some(owner.clone()),
keys,
true,
true,
true,
)
.unwrap();
restored.stop_device_sync_now();
let recovered = restored
.pending_relay_publishes
.get(&carrier.id.to_hex())
.expect("sender restart retains C's exact queued private carrier");
assert_eq!(
serde_json::from_str::<Event>(&recovered.event_json).unwrap(),
carrier
);
farm.devices[0].core = restored;
farm.devices[2].online = true;
farm.pump();
for _ in 0..2 {
farm.devices[2].core.handle_relay_event(carrier.clone());
}
let received = farm.devices[2].core.threads[&chat_id]
.messages
.iter()
.filter(|message| message.id == message_id)
.collect::<Vec<_>>();
assert_eq!(
received.len(),
1,
"restarted queue and duplicate delivery display exactly once"
);
assert_eq!(received[0].body, body);
assert_eq!(
received[0].source_event_id.as_deref(),
Some(carrier.id.to_hex().as_str())
);
assert_eq!(
received[0].author_owner_pubkey_hex.as_deref(),
Some(owner.public_key().to_hex().as_str())
);
assert!(!received[0].is_outgoing);
}