use super::*;
#[test]
fn sharing_to_self_before_opening_a_chat_reuses_the_same_conversation() {
let dir = tempfile::tempdir().unwrap();
let owner = Keys::generate();
let mut core = logged_in_test_core_at_data_dir(
&owner,
&Keys::generate(),
dir.path().to_string_lossy().into_owned(),
);
core.rebuild_state();
let account = core.state.account.clone().unwrap();
assert!(core.state.chat_list.is_empty());
let targets = crate::share_target_chats(Some(account.clone()), vec![]);
assert_eq!(targets.len(), 1);
assert_eq!(targets[0].chat_id, owner.public_key().to_hex());
assert_eq!(targets[0].display_name, "Note to self");
assert_eq!(targets[0].subtitle.as_ref(), Some(&account.display_name));
core.handle_action(AppAction::SendMessage {
chat_id: targets[0].chat_id.clone(),
text: "Shared link".into(),
});
assert_eq!(core.state.chat_list.len(), 1);
let mut existing = core.state.chat_list[0].clone();
existing.is_request = true;
let mut other = existing.clone();
other.chat_id = "another-chat".into();
let targets = crate::share_target_chats(Some(account.clone()), vec![other.clone(), existing]);
assert_eq!(targets.len(), 2);
assert_eq!(targets[0].chat_id, account.public_key_hex);
assert!(!targets[0].is_request);
assert_eq!(
targets[0].last_message_preview.as_deref(),
Some("Shared link")
);
assert_eq!(targets[1], other);
let mut revoked = account;
revoked.authorization_state = crate::DeviceAuthorizationState::Revoked;
assert!(crate::share_target_chats(Some(revoked), targets.clone()).is_empty());
assert!(crate::share_target_chats(None, targets).is_empty());
}
#[test]
fn forwarded_content_survives_encryption_projection_and_storage_without_source_author() {
let sender_owner = Keys::generate();
let sender_device = Keys::generate();
let receiver_owner = Keys::generate();
let receiver_device = Keys::generate();
let source_owner = Keys::generate();
let mut sender = logged_in_test_core("forward-sender", &sender_owner, &sender_device);
let mut receiver = logged_in_test_core("forward-receiver", &receiver_owner, &receiver_device);
let invite = create_private_invite_for_test(&mut receiver);
prove_invite_owner(&mut sender, &receiver_owner, &receiver_device, 10);
sender.upsert_local_app_key_device_with_labels(
sender_owner.public_key(),
sender_device.public_key(),
None,
true,
);
sender.publish_local_app_keys_snapshot_only("test_forward");
sender.pending_relay_publishes.clear();
sender.handle_action(AppAction::AcceptInvite {
invite_input: invite,
});
let source = test_chat_message(
&source_owner.public_key().to_hex(),
"source-message",
"Bring a picnic blanket.",
unix_now().get(),
false,
);
let text = crate::format_forwarded_message(source.body.clone());
let target = receiver_owner.public_key().to_hex();
sender.handle_action(AppAction::SendMessage {
chat_id: target.clone(),
text: text.clone(),
});
let outgoing = sender
.state
.current_chat
.as_ref()
.unwrap()
.messages
.iter()
.find(|m| m.body == text)
.unwrap();
assert_eq!(
outgoing.author_owner_pubkey_hex,
Some(sender_owner.public_key().to_hex())
);
assert!(outgoing.is_outgoing);
for event in pending_events_with_kind(&sender, INVITE_RESPONSE_KIND)
.into_iter()
.chain(pending_events_with_kind(&sender, MESSAGE_EVENT_KIND))
{
receiver.handle_relay_event(event);
}
let chat_id = sender_owner.public_key().to_hex();
receiver.handle_action(AppAction::OpenChat {
chat_id: chat_id.clone(),
});
let received = receiver
.state
.current_chat
.as_ref()
.unwrap()
.messages
.iter()
.find(|m| m.body == text)
.expect("decrypted forward in UI projection");
assert_eq!(received.body, "Forwarded:\n\nBring a picnic blanket.");
assert_eq!(received.author_owner_pubkey_hex, Some(chat_id.clone()));
assert!(!received.is_outgoing);
assert!(!received.body.contains(&source_owner.public_key().to_hex()));
assert!(!received.body.contains(&source.id));
let received_id = received.id.clone();
let persisted = receiver.load_persisted().unwrap().unwrap();
let stored = persisted
.threads
.iter()
.find(|t| t.chat_id == chat_id)
.unwrap()
.messages
.iter()
.find(|m| m.id == received_id)
.unwrap();
assert_eq!(
crate::core::chats::chat_message_from_persisted(stored).body,
text
);
assert_eq!(
crate::format_forwarded_message(text.clone()),
text,
"forwarding again keeps one heading"
);
}
#[test]
fn forwarded_attachment_keeps_heading_in_group_timeline_and_persistence() {
let owner = Keys::generate();
let device = Keys::generate();
let mut core = logged_in_test_core("forward-group", &owner, &device);
core.handle_action(AppAction::CreateGroup {
name: "Notes".into(),
member_inputs: vec![],
});
let chat_id = core.state.current_chat.as_ref().unwrap().chat_id.clone();
let url = "htree://nhash1example/photo.jpg";
core.handle_action(AppAction::SendMessage {
chat_id: chat_id.clone(),
text: crate::format_forwarded_message(format!("A picnic\n{url}")),
});
let message = core
.state
.current_chat
.as_ref()
.unwrap()
.messages
.iter()
.find(|m| m.body.starts_with("Forwarded:"))
.unwrap()
.clone();
assert_eq!(message.body, "Forwarded:\n\nA picnic");
assert_eq!(message.attachments.len(), 1);
assert_eq!(message.attachments[0].htree_url, url);
let persisted = core.load_persisted().unwrap().unwrap();
let stored = persisted
.threads
.iter()
.find(|t| t.chat_id == chat_id)
.unwrap()
.messages
.iter()
.find(|m| m.id == message.id)
.unwrap();
let restored = crate::core::chats::chat_message_from_persisted(stored);
assert_eq!(restored.body, message.body);
assert_eq!(restored.attachments, message.attachments);
}