mirror of
https://github.com/chatmail/core.git
synced 2026-05-09 01:46:30 +03:00
feat: sort past members by the timestamp of removal
This commit is contained in:
@@ -3493,6 +3493,8 @@ pub async fn get_chat_contacts(context: &Context, chat_id: ChatId) -> Result<Vec
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a vector of contact IDs for given chat ID that are no longer part of the group.
|
/// Returns a vector of contact IDs for given chat ID that are no longer part of the group.
|
||||||
|
///
|
||||||
|
/// Members that have been removed recently are in the beginning of the list.
|
||||||
pub async fn get_past_chat_contacts(context: &Context, chat_id: ChatId) -> Result<Vec<ContactId>> {
|
pub async fn get_past_chat_contacts(context: &Context, chat_id: ChatId) -> Result<Vec<ContactId>> {
|
||||||
let now = time();
|
let now = time();
|
||||||
let list = context
|
let list = context
|
||||||
@@ -3505,7 +3507,7 @@ pub async fn get_past_chat_contacts(context: &Context, chat_id: ChatId) -> Resul
|
|||||||
WHERE cc.chat_id=?
|
WHERE cc.chat_id=?
|
||||||
AND cc.add_timestamp < cc.remove_timestamp
|
AND cc.add_timestamp < cc.remove_timestamp
|
||||||
AND ? < cc.remove_timestamp
|
AND ? < cc.remove_timestamp
|
||||||
ORDER BY c.id=1, c.last_seen DESC, c.id DESC",
|
ORDER BY c.id=1, cc.remove_timestamp DESC, c.id DESC",
|
||||||
(chat_id, now.saturating_sub(60 * 24 * 3600)),
|
(chat_id, now.saturating_sub(60 * 24 * 3600)),
|
||||||
|row| row.get::<_, ContactId>(0),
|
|row| row.get::<_, ContactId>(0),
|
||||||
|ids| ids.collect::<Result<Vec<_>, _>>().map_err(Into::into),
|
|ids| ids.collect::<Result<Vec<_>, _>>().map_err(Into::into),
|
||||||
|
|||||||
@@ -3418,6 +3418,61 @@ async fn test_expire_past_members_after_60_days() -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Test that past members are ordered by the timestamp of their removal.
|
||||||
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
|
async fn test_past_members_order() -> Result<()> {
|
||||||
|
let t = &TestContext::new_alice().await;
|
||||||
|
|
||||||
|
let bob_contact_id = Contact::create(t, "Bob", "bob@example.net").await?;
|
||||||
|
let charlie_contact_id = Contact::create(t, "Charlie", "charlie@example.org").await?;
|
||||||
|
let fiona_contact_id = Contact::create(t, "Fiona", "fiona@example.net").await?;
|
||||||
|
|
||||||
|
let chat_id = create_group_chat(t, ProtectionStatus::Unprotected, "Group chat").await?;
|
||||||
|
add_contact_to_chat(t, chat_id, bob_contact_id).await?;
|
||||||
|
add_contact_to_chat(t, chat_id, charlie_contact_id).await?;
|
||||||
|
add_contact_to_chat(t, chat_id, fiona_contact_id).await?;
|
||||||
|
t.send_text(chat_id, "Hi! I created a group.").await;
|
||||||
|
|
||||||
|
assert_eq!(get_past_chat_contacts(t, chat_id).await?.len(), 0);
|
||||||
|
|
||||||
|
remove_contact_from_chat(t, chat_id, charlie_contact_id).await?;
|
||||||
|
|
||||||
|
let past_contacts = get_past_chat_contacts(t, chat_id).await?;
|
||||||
|
assert_eq!(past_contacts.len(), 1);
|
||||||
|
assert_eq!(past_contacts[0], charlie_contact_id);
|
||||||
|
|
||||||
|
SystemTime::shift(Duration::from_secs(5));
|
||||||
|
remove_contact_from_chat(t, chat_id, bob_contact_id).await?;
|
||||||
|
|
||||||
|
let past_contacts = get_past_chat_contacts(t, chat_id).await?;
|
||||||
|
assert_eq!(past_contacts.len(), 2);
|
||||||
|
assert_eq!(past_contacts[0], bob_contact_id);
|
||||||
|
assert_eq!(past_contacts[1], charlie_contact_id);
|
||||||
|
|
||||||
|
SystemTime::shift(Duration::from_secs(5));
|
||||||
|
remove_contact_from_chat(t, chat_id, fiona_contact_id).await?;
|
||||||
|
|
||||||
|
let past_contacts = get_past_chat_contacts(t, chat_id).await?;
|
||||||
|
assert_eq!(past_contacts.len(), 3);
|
||||||
|
assert_eq!(past_contacts[0], fiona_contact_id);
|
||||||
|
assert_eq!(past_contacts[1], bob_contact_id);
|
||||||
|
assert_eq!(past_contacts[2], charlie_contact_id);
|
||||||
|
|
||||||
|
// Adding and removing Bob
|
||||||
|
// moves him to the top of past member list.
|
||||||
|
SystemTime::shift(Duration::from_secs(5));
|
||||||
|
add_contact_to_chat(t, chat_id, bob_contact_id).await?;
|
||||||
|
remove_contact_from_chat(t, chat_id, bob_contact_id).await?;
|
||||||
|
|
||||||
|
let past_contacts = get_past_chat_contacts(t, chat_id).await?;
|
||||||
|
assert_eq!(past_contacts.len(), 3);
|
||||||
|
assert_eq!(past_contacts[0], bob_contact_id);
|
||||||
|
assert_eq!(past_contacts[1], fiona_contact_id);
|
||||||
|
assert_eq!(past_contacts[2], charlie_contact_id);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Test the case when Alice restores a backup older than 60 days
|
/// Test the case when Alice restores a backup older than 60 days
|
||||||
/// with outdated member list.
|
/// with outdated member list.
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
|
|||||||
Reference in New Issue
Block a user