diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index 602e2597c7..005905e74d 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -693,6 +693,21 @@ char* dc_get_connectivity_html (dc_context_t* context); void dc_configure (dc_context_t* context); +/** + * Add fake transport that cannot be used to connect. + * + * Used for offline tests only. + * + * To add a transport, use JSON-RPC calls `add_or_update_transport` + * and `add_transport_from_qr` instead. + * + * @memberof dc_context_t + * @param context The context object. + * @param addr The email address of the new transport. + */ +void dc_add_pseudo_transport (dc_context_t* context, const char *addr); + + /** * Check if the context is already configured. * diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index a96e4e0cb0..d133359775 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -31,6 +31,7 @@ use deltachat::key::preconfigure_keypair; use deltachat::message::MsgId; use deltachat::qr_code_generator::{create_qr_svg, generate_backup_qr, get_securejoin_qr_svg}; use deltachat::stock_str::StockMessage; +use deltachat::transport::add_pseudo_transport; use deltachat::webxdc::StatusUpdateSerial; use deltachat::*; use deltachat::{accounts::Accounts, log::LogExt}; @@ -414,6 +415,21 @@ pub unsafe extern "C" fn dc_configure(context: *mut dc_context_t) { spawn_configure(ctx.clone()); } +#[unsafe(no_mangle)] +pub unsafe extern "C" fn dc_add_pseudo_transport( + context: *mut dc_context_t, + addr: *const libc::c_char, +) { + if context.is_null() { + eprintln!("ignoring careless call to dc_add_pseudo_transport()"); + return; + } + + let ctx = unsafe { &*context }; + let addr = to_string_lossy(addr); + block_on(add_pseudo_transport(ctx, &addr)).log_err(ctx).ok(); +} + #[unsafe(no_mangle)] pub unsafe extern "C" fn dc_is_configured(context: *mut dc_context_t) -> libc::c_int { if context.is_null() { diff --git a/python/src/deltachat/testplugin.py b/python/src/deltachat/testplugin.py index 943d055010..7dab54298e 100644 --- a/python/src/deltachat/testplugin.py +++ b/python/src/deltachat/testplugin.py @@ -11,6 +11,9 @@ from queue import Queue from typing import Callable, Dict, List, Optional +from .capi import lib +from .cutil import as_dc_charpointer + import pytest from _pytest._code import Source @@ -366,6 +369,7 @@ def get_pseudo_configured_account(self, passphrase: Optional[str] = None) -> Acc ac.open(passphrase) acname = ac._logid addr = f"{acname}@offline.org" + lib.dc_add_pseudo_transport(ac._dc_context, as_dc_charpointer(addr)) ac.update_config( { "configured_addr": addr, @@ -374,6 +378,7 @@ def get_pseudo_configured_account(self, passphrase: Optional[str] = None) -> Acc ) self._preconfigure_key(ac) self._acsetup.init_logging(ac) + assert ac.is_configured(), "Pseudo configured account should look like if it is configured" return ac def new_online_configuring_account(self, cloned_from=None, **kwargs) -> Account: diff --git a/src/config.rs b/src/config.rs index 966484f7b0..12ab9f45ae 100644 --- a/src/config.rs +++ b/src/config.rs @@ -19,7 +19,7 @@ use crate::log::LogExt; use crate::mimefactory::RECOMMENDED_FILE_SIZE; use crate::sync::{self, Sync::*, SyncData}; use crate::tools::get_abs_path; -use crate::transport::{add_pseudo_transport, transport_addrs}; +use crate::transport::transport_addrs; use crate::{constants, stats}; /// The available configuration keys. @@ -753,39 +753,28 @@ impl Context { bail!("Cannot unset configured_addr"); }; - if !self.is_configured().await? { - info!( - self, - "Creating a pseudo configured account which will not be able to send or receive messages. Only meant for tests!" - ); - add_pseudo_transport(self, addr).await?; - self.sql - .set_raw_config(Config::ConfiguredAddr.as_ref(), Some(addr)) - .await?; - } else { - self.sql - .transaction(|transaction| { - if transaction.query_row( - "SELECT COUNT(*) FROM transports WHERE addr=?", - (addr,), - |row| { - let res: i64 = row.get(0)?; - Ok(res) - }, - )? == 0 - { - bail!("Address does not belong to any transport."); - } - transaction.execute( - "UPDATE config SET value=? WHERE keyname='configured_addr'", - (addr,), - )?; - - Ok(()) - }) - .await?; - self.sql.uncache_raw_config("configured_addr").await; - } + self.sql + .transaction(|transaction| { + if transaction.query_row( + "SELECT COUNT(*) FROM transports WHERE addr=?", + (addr,), + |row| { + let res: i64 = row.get(0)?; + Ok(res) + }, + )? == 0 + { + bail!("Address does not belong to any transport."); + } + transaction.execute( + "INSERT OR REPLACE INTO config (keyname, value) VALUES ('configured_addr', ?)", + (addr,), + )?; + + Ok(()) + }) + .await?; + self.sql.uncache_raw_config("configured_addr").await; } _ => { self.sql.set_raw_config(key.as_ref(), value).await?; diff --git a/src/configure.rs b/src/configure.rs index d9a83d7a8e..bb436b3cf3 100644 --- a/src/configure.rs +++ b/src/configure.rs @@ -715,7 +715,7 @@ mod tests { let mut tcm = TestContextManager::new(); let t = &tcm.unconfigured().await; - // Setting ConfiguredAddr on an unconfigured account creates a pseudo transport + add_pseudo_transport(t, "primary@example.org").await?; t.set_config(Config::ConfiguredAddr, Some("primary@example.org")) .await?; assert_eq!(t.count_transports().await?, 1); diff --git a/src/key.rs b/src/key.rs index 997fb9e6d8..e7d69eb5fe 100644 --- a/src/key.rs +++ b/src/key.rs @@ -662,6 +662,7 @@ mod tests { use crate::config::Config; use crate::test_utils::{TestContext, TestContextManager, alice_keypair}; use crate::tools::SystemTime; + use crate::transport::add_pseudo_transport; static KEYPAIR: LazyLock = LazyLock::new(alice_keypair); @@ -811,6 +812,7 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_load_self_generate_public() { let t = TestContext::new().await; + add_pseudo_transport(&t, "alice@example.org").await.unwrap(); t.set_config(Config::ConfiguredAddr, Some("alice@example.org")) .await .unwrap(); @@ -821,6 +823,7 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_load_self_generate_secret() { let t = TestContext::new().await; + add_pseudo_transport(&t, "alice@example.org").await.unwrap(); t.set_config(Config::ConfiguredAddr, Some("alice@example.org")) .await .unwrap(); @@ -833,6 +836,7 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD use std::thread; let t = TestContext::new().await; + add_pseudo_transport(&t, "alice@example.org").await.unwrap(); t.set_config(Config::ConfiguredAddr, Some("alice@example.org")) .await .unwrap(); diff --git a/src/lib.rs b/src/lib.rs index d430487f76..c4ec71e8aa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -97,7 +97,7 @@ pub mod stock_str; pub mod storage_usage; mod sync; mod token; -mod transport; +pub mod transport; mod update_helper; pub mod webxdc; #[macro_use] diff --git a/src/pgp/pgp_tests.rs b/src/pgp/pgp_tests.rs index bd2b617671..3649bc6323 100644 --- a/src/pgp/pgp_tests.rs +++ b/src/pgp/pgp_tests.rs @@ -2,6 +2,7 @@ use std::sync::LazyLock; use tokio::sync::OnceCell; use super::*; +use crate::transport::add_pseudo_transport; use crate::{ config::Config, decrypt, @@ -19,6 +20,9 @@ async fn decrypt_bytes( auth_tokens_for_decryption: &[String], ) -> Result> { let t = &TestContext::new().await; + add_pseudo_transport(t, "alice@example.org") + .await + .expect("Failed to add pseudo transport"); t.set_config(Config::ConfiguredAddr, Some("alice@example.org")) .await .expect("Failed to configure address"); diff --git a/src/test_utils.rs b/src/test_utils.rs index d31cc83218..52e7c29fbd 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -557,6 +557,9 @@ impl TestContext { /// The context will be configured but the key will not be pre-generated so if a key is /// used the fingerprint will be different every time. pub async fn configure_addr(&self, addr: &str) { + add_pseudo_transport(&self.ctx, addr) + .await + .expect("Failed to add pseudo transport"); self.ctx .set_config(Config::ConfiguredAddr, Some(addr)) .await diff --git a/src/transport.rs b/src/transport.rs index 9d07675c85..b16151f09c 100644 --- a/src/transport.rs +++ b/src/transport.rs @@ -765,7 +765,7 @@ pub(crate) fn maybe_update_sending_transport( } /// Adds transport entry to the `transports` table with empty configuration. -pub(crate) async fn add_pseudo_transport(context: &Context, addr: &str) -> Result<()> { +pub async fn add_pseudo_transport(context: &Context, addr: &str) -> Result<()> { context.sql .execute( "INSERT OR IGNORE INTO transports (addr, entered_param, configured_param) VALUES (?, ?, ?)",