api: Contact::get_all(): Support listing address-contacts

Also test-cover `DC_GCL_ADD_SELF`.
This commit is contained in:
iequidoo
2025-06-29 17:24:06 -03:00
committed by iequidoo
parent 0a73c2b7ab
commit 7e4d4cf680
6 changed files with 62 additions and 16 deletions

View File

@@ -89,6 +89,7 @@ pub const DC_GCL_ADD_ALLDONE_HINT: usize = 0x04;
pub const DC_GCL_FOR_FORWARDING: usize = 0x08;
pub const DC_GCL_ADD_SELF: u32 = 0x02;
pub const DC_GCL_ADDRESS: u32 = 0x04;
// unchanged user avatars are resent to the recipients every some days
pub(crate) const DC_RESEND_USER_AVATAR_DAYS: i64 = 14;

View File

@@ -24,7 +24,7 @@ use crate::blob::BlobObject;
use crate::chat::{ChatId, ChatIdBlocked, ProtectionStatus};
use crate::color::str_to_color;
use crate::config::Config;
use crate::constants::{Blocked, Chattype, DC_GCL_ADD_SELF};
use crate::constants::{self, Blocked, Chattype};
use crate::context::Context;
use crate::events::EventType;
use crate::key::{
@@ -1063,11 +1063,12 @@ impl Contact {
/// Returns known and unblocked contacts.
///
/// To get information about a single contact, see get_contact().
/// By default, key-contacts are listed.
///
/// `listflags` is a combination of flags:
/// - if the flag DC_GCL_ADD_SELF is set, SELF is added to the list unless filtered by other parameters
///
/// `query` is a string to filter the list.
/// * `listflags` - A combination of flags:
/// - `DC_GCL_ADD_SELF` - Add SELF unless filtered by other parameters.
/// - `DC_GCL_ADDRESS` - List address-contacts instead of key-contacts.
/// * `query` - A string to filter the list.
pub async fn get_all(
context: &Context,
listflags: u32,
@@ -1080,7 +1081,8 @@ impl Contact {
.collect::<HashSet<_>>();
let mut add_self = false;
let mut ret = Vec::new();
let flag_add_self = (listflags & DC_GCL_ADD_SELF) != 0;
let flag_add_self = (listflags & constants::DC_GCL_ADD_SELF) != 0;
let flag_address = (listflags & constants::DC_GCL_ADDRESS) != 0;
let minimal_origin = if context.get_config_bool(Config::Bot).await? {
Origin::Unknown
} else {
@@ -1093,13 +1095,14 @@ impl Contact {
.query_map(
"SELECT c.id, c.addr FROM contacts c
WHERE c.id>?
AND c.fingerprint!='' \
AND (c.fingerprint='')=?
AND c.origin>=? \
AND c.blocked=0 \
AND (iif(c.name='',c.authname,c.name) LIKE ? OR c.addr LIKE ?) \
ORDER BY c.last_seen DESC, c.id DESC;",
(
ContactId::LAST_SPECIAL,
flag_address,
minimal_origin,
&s3str_like_cmd,
&s3str_like_cmd,
@@ -1149,11 +1152,11 @@ impl Contact {
.query_map(
"SELECT id, addr FROM contacts
WHERE id>?
AND fingerprint!=''
AND (fingerprint='')=?
AND origin>=?
AND blocked=0
ORDER BY last_seen DESC, id DESC;",
(ContactId::LAST_SPECIAL, minimal_origin),
(ContactId::LAST_SPECIAL, flag_address, minimal_origin),
|row| {
let id: ContactId = row.get(0)?;
let addr: String = row.get(1)?;

View File

@@ -69,6 +69,9 @@ async fn test_get_contacts() -> Result<()> {
let contacts = Contact::get_all(&context.ctx, 0, Some("MyName")).await?;
assert_eq!(contacts.len(), 0);
let claire_id = Contact::create(&context, "someone", "claire@example.org").await?;
let dave_id = Contact::create(&context, "", "dave@example.org").await?;
let id = context.add_or_lookup_contact_id(&alice).await;
assert_ne!(id, ContactId::UNDEFINED);
@@ -101,10 +104,35 @@ async fn test_get_contacts() -> Result<()> {
let contacts = Contact::get_all(&context, 0, Some("MyName")).await?;
assert_eq!(contacts.len(), 0);
// Search by display name (same as manually set name).
let contacts = Contact::get_all(&context.ctx, 0, Some("someone")).await?;
assert_eq!(contacts.len(), 1);
assert_eq!(contacts.first(), Some(&id));
for add_self in [0, constants::DC_GCL_ADD_SELF] {
info!(&context, "add_self={add_self}");
// Search key-contacts by display name (same as manually set name).
let contacts = Contact::get_all(&context.ctx, add_self, Some("someone")).await?;
assert_eq!(contacts, vec![id]);
// Get all key-contacts.
let contacts = Contact::get_all(&context, add_self, None).await?;
match add_self {
0 => assert_eq!(contacts, vec![id]),
_ => assert_eq!(contacts, vec![id, ContactId::SELF]),
}
}
// Search address-contacts by display name.
let contacts = Contact::get_all(&context, constants::DC_GCL_ADDRESS, Some("someone")).await?;
assert_eq!(contacts, vec![claire_id]);
// Get all address-contacts. Newer contacts go first.
let contacts = Contact::get_all(&context, constants::DC_GCL_ADDRESS, None).await?;
assert_eq!(contacts, vec![dave_id, claire_id]);
let contacts = Contact::get_all(
&context,
constants::DC_GCL_ADDRESS | constants::DC_GCL_ADD_SELF,
None,
)
.await?;
assert_eq!(contacts, vec![dave_id, claire_id, ContactId::SELF]);
Ok(())
}