diff --git a/deltachat-rpc-client/tests/test_multitransport.py b/deltachat-rpc-client/tests/test_multitransport.py index d3a3be992..245fdc003 100644 --- a/deltachat-rpc-client/tests/test_multitransport.py +++ b/deltachat-rpc-client/tests/test_multitransport.py @@ -201,3 +201,19 @@ def test_transport_synchronization(acfactory, log) -> None: assert ac1.wait_for_incoming_msg().get_snapshot().text == "Hello!" assert ac1_clone.wait_for_incoming_msg().get_snapshot().text == "Hello!" + + +def test_recognize_self_address(acfactory) -> None: + alice, bob = acfactory.get_online_accounts(2) + + bob_chat = bob.create_chat(alice) + + qr = acfactory.get_account_qr() + alice.add_transport_from_qr(qr) + + new_alice_addr = alice.list_transports()[1]["addr"] + alice.set_config("configured_addr", new_alice_addr) + + bob_chat.send_text("Hello!") + msg = alice.wait_for_incoming_msg().get_snapshot() + assert msg.chat == alice.create_chat(bob) diff --git a/src/config.rs b/src/config.rs index 13c245718..bdb5ca2b1 100644 --- a/src/config.rs +++ b/src/config.rs @@ -13,7 +13,6 @@ use strum_macros::{AsRefStr, Display, EnumIter, EnumString}; use tokio::fs; use crate::blob::BlobObject; -use crate::configure::EnteredLoginParam; use crate::context::Context; use crate::events::EventType; use crate::log::LogExt; @@ -21,7 +20,7 @@ use crate::mimefactory::RECOMMENDED_FILE_SIZE; use crate::provider::Provider; use crate::sync::{self, Sync::*, SyncData}; use crate::tools::get_abs_path; -use crate::transport::ConfiguredLoginParam; +use crate::transport::{ConfiguredLoginParam, add_pseudo_transport}; use crate::{constants, stats}; /// The available configuration keys. @@ -204,7 +203,7 @@ pub enum Config { /// `ProviderOptions::delete_to_trash`. DeleteToTrash, - /// The primary email address. Also see `SecondaryAddrs`. + /// The primary email address. ConfiguredAddr, /// List of configured IMAP servers as a JSON array. @@ -306,10 +305,6 @@ pub enum Config { /// Meant to help profile owner to differ between profiles with similar names. PrivateTag, - /// All secondary self addresses separated by spaces - /// (`addr1@example.org addr2@example.org addr3@example.org`) - SecondaryAddrs, - /// Read-only core version string. #[strum(serialize = "sys.version")] SysVersion, @@ -819,16 +814,7 @@ impl Context { self, "Creating a pseudo configured account which will not be able to send or receive messages. Only meant for tests!" ); - self.sql - .execute( - "INSERT INTO transports (addr, entered_param, configured_param) VALUES (?, ?, ?)", - ( - addr, - serde_json::to_string(&EnteredLoginParam::default())?, - format!(r#"{{"addr":"{addr}","imap":[],"imap_user":"","imap_password":"","smtp":[],"smtp_user":"","smtp_password":"","certificate_checks":"Automatic","oauth2":false}}"#) - ), - ) - .await?; + add_pseudo_transport(self, addr).await?; self.sql .set_raw_config(Config::ConfiguredAddr.as_ref(), Some(addr)) .await?; @@ -958,16 +944,6 @@ impl Context { pub(crate) async fn set_primary_self_addr(&self, primary_new: &str) -> Result<()> { self.quota.write().await.take(); - // add old primary address (if exists) to secondary addresses - let mut secondary_addrs = self.get_all_self_addrs().await?; - // never store a primary address also as a secondary - secondary_addrs.retain(|a| !addr_cmp(a, primary_new)); - self.set_config_internal( - Config::SecondaryAddrs, - Some(secondary_addrs.join(" ").as_str()), - ) - .await?; - self.sql .set_raw_config(Config::ConfiguredAddr.as_ref(), Some(primary_new)) .await?; @@ -985,14 +961,10 @@ impl Context { /// Returns all secondary self addresses. pub(crate) async fn get_secondary_self_addrs(&self) -> Result> { - let secondary_addrs = self - .get_config(Config::SecondaryAddrs) - .await? - .unwrap_or_default(); - Ok(secondary_addrs - .split_ascii_whitespace() - .map(|s| s.to_string()) - .collect()) + self.sql.query_map_vec("SELECT addr FROM transports WHERE addr NOT IN (SELECT value FROM config WHERE keyname='configured_addr')", (), |row| { + let addr: String = row.get(0)?; + Ok(addr) + }).await } /// Returns the primary self address. diff --git a/src/config/config_tests.rs b/src/config/config_tests.rs index bec0fa2f7..aabe0e7f5 100644 --- a/src/config/config_tests.rs +++ b/src/config/config_tests.rs @@ -94,59 +94,6 @@ async fn test_set_config_bool() -> Result<()> { Ok(()) } -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_self_addrs() -> Result<()> { - let alice = TestContext::new_alice().await; - - assert!(alice.is_self_addr("alice@example.org").await?); - assert_eq!(alice.get_all_self_addrs().await?, vec!["alice@example.org"]); - assert!(!alice.is_self_addr("alice@alice.com").await?); - - // Test adding the same primary address - alice.set_primary_self_addr("alice@example.org").await?; - alice.set_primary_self_addr("Alice@Example.Org").await?; - assert_eq!(alice.get_all_self_addrs().await?, vec!["Alice@Example.Org"]); - - // Test adding a new (primary) self address - // The address is trimmed during configure by `LoginParam::from_database()`, - // so `set_primary_self_addr()` doesn't have to trim it. - alice.set_primary_self_addr("Alice@alice.com").await?; - assert!(alice.is_self_addr("aliCe@example.org").await?); - assert!(alice.is_self_addr("alice@alice.com").await?); - assert_eq!( - alice.get_all_self_addrs().await?, - vec!["Alice@alice.com", "Alice@Example.Org"] - ); - - // Check that the entry is not duplicated - alice.set_primary_self_addr("alice@alice.com").await?; - alice.set_primary_self_addr("alice@alice.com").await?; - assert_eq!( - alice.get_all_self_addrs().await?, - vec!["alice@alice.com", "Alice@Example.Org"] - ); - - // Test switching back - alice.set_primary_self_addr("alice@example.org").await?; - assert_eq!( - alice.get_all_self_addrs().await?, - vec!["alice@example.org", "alice@alice.com"] - ); - - // Test setting a new primary self address, the previous self address - // should be kept as a secondary self address - alice.set_primary_self_addr("alice@alice.xyz").await?; - assert_eq!( - alice.get_all_self_addrs().await?, - vec!["alice@alice.xyz", "alice@example.org", "alice@alice.com"] - ); - assert!(alice.is_self_addr("alice@example.org").await?); - assert!(alice.is_self_addr("alice@alice.com").await?); - assert!(alice.is_self_addr("Alice@alice.xyz").await?); - - Ok(()) -} - #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_mdns_default_behaviour() -> Result<()> { let t = &TestContext::new_alice().await; diff --git a/src/imap/imap_tests.rs b/src/imap/imap_tests.rs index 88d0ac057..ccc5853a7 100644 --- a/src/imap/imap_tests.rs +++ b/src/imap/imap_tests.rs @@ -1,5 +1,6 @@ use super::*; use crate::test_utils::TestContext; +use crate::transport::add_pseudo_transport; #[test] fn test_get_folder_meaning_by_name() { @@ -271,12 +272,14 @@ async fn test_get_imap_search_command() -> Result<()> { r#"FROM "alice@example.org""# ); + add_pseudo_transport(&t, "alice@another.com").await?; t.ctx.set_primary_self_addr("alice@another.com").await?; assert_eq!( get_imap_self_sent_search_command(&t.ctx).await?, r#"OR (FROM "alice@another.com") (FROM "alice@example.org")"# ); + add_pseudo_transport(&t, "alice@third.com").await?; t.ctx.set_primary_self_addr("alice@third.com").await?; assert_eq!( get_imap_self_sent_search_command(&t.ctx).await?, diff --git a/src/transport.rs b/src/transport.rs index 90e679c9f..a5c05874e 100644 --- a/src/transport.rs +++ b/src/transport.rs @@ -756,6 +756,21 @@ pub(crate) async fn sync_transports( Ok(()) } +/// Adds transport entry to the `transports` table with empty configuration. +pub(crate) async fn add_pseudo_transport(context: &Context, addr: &str) -> Result<()> { + context.sql + .execute( + "INSERT INTO transports (addr, entered_param, configured_param) VALUES (?, ?, ?)", + ( + addr, + serde_json::to_string(&EnteredLoginParam::default())?, + format!(r#"{{"addr":"{addr}","imap":[],"imap_user":"","imap_password":"","smtp":[],"smtp_user":"","smtp_password":"","certificate_checks":"Automatic","oauth2":false}}"#) + ), + ) + .await?; + Ok(()) +} + #[cfg(test)] mod tests { use super::*;