diff --git a/src/config.rs b/src/config.rs index 7cb7617f1..f8e3c8ed9 100644 --- a/src/config.rs +++ b/src/config.rs @@ -438,6 +438,11 @@ pub enum Config { /// storing the same token multiple times on the server. EncryptedDeviceToken, + /// Enables running test hooks, e.g. see `InnerContext::pre_encrypt_mime_hook`. + /// This way is better than conditional compilation, i.e. `#[cfg(test)]`, because tests not + /// using this still run unmodified code. + TestHooks, + /// Return an error from `receive_imf_inner()` for a fully downloaded message. For tests. FailOnReceivingFullMsg, } diff --git a/src/context.rs b/src/context.rs index 9287777c9..8574ceb5c 100644 --- a/src/context.rs +++ b/src/context.rs @@ -303,6 +303,17 @@ pub struct InnerContext { /// `Connectivity` values for mailboxes, unordered. Used to compute the aggregate connectivity, /// see [`Context::get_connectivity()`]. pub(crate) connectivities: parking_lot::Mutex>, + + #[expect(clippy::type_complexity)] + /// Transforms the root of the cryptographic payload before encryption. + pub(crate) pre_encrypt_mime_hook: parking_lot::Mutex< + Option< + for<'a> fn( + &Context, + mail_builder::mime::MimePart<'a>, + ) -> mail_builder::mime::MimePart<'a>, + >, + >, } /// The state of ongoing process. @@ -467,6 +478,7 @@ impl Context { iroh: Arc::new(RwLock::new(None)), self_fingerprint: OnceLock::new(), connectivities: parking_lot::Mutex::new(Vec::new()), + pre_encrypt_mime_hook: None.into(), }; let ctx = Context { @@ -1051,6 +1063,13 @@ impl Context { .await? .to_string(), ); + res.insert( + "test_hooks", + self.sql + .get_raw_config("test_hooks") + .await? + .unwrap_or_default(), + ); res.insert( "fail_on_receiving_full_msg", self.sql diff --git a/src/dehtml.rs b/src/dehtml.rs index a6d70b1f7..12cd4e609 100644 --- a/src/dehtml.rs +++ b/src/dehtml.rs @@ -13,6 +13,7 @@ use quick_xml::{ use crate::simplify::{SimplifiedText, simplify_quote}; +#[derive(Default)] struct Dehtml { strbuilder: String, quote: String, @@ -25,6 +26,9 @@ struct Dehtml { /// Everything between `
` and `
` is usually metadata /// If this is > `0`, then we are inside a `
`. divs_since_quoted_content_div: u32, + /// `
` elements should be omitted, see + /// . + divs_since_hp_legacy_display: u32, /// All-Inkl just puts the quote into `
`. This count is /// increased at each `
` and decreased at each `
`. blockquotes_since_blockquote: u32, @@ -48,20 +52,25 @@ impl Dehtml { } fn get_add_text(&self) -> AddText { - if self.divs_since_quote_div > 0 && self.divs_since_quoted_content_div == 0 { - AddText::No // Everything between `
` and `
` is metadata which we don't want + // Everything between `
` and `
` is + // metadata which we don't want. + if self.divs_since_quote_div > 0 && self.divs_since_quoted_content_div == 0 + || self.divs_since_hp_legacy_display > 0 + { + AddText::No } else { self.add_text } } } -#[derive(Debug, PartialEq, Clone, Copy)] +#[derive(Debug, Default, PartialEq, Clone, Copy)] enum AddText { /// Inside `