Skip to content

fix: Make pre-messages w/o text want MDNs (#8004)#8008

Merged
iequidoo merged 1 commit into
mainfrom
iequidoo/test_markseen_pre_msg
Jun 17, 2026
Merged

fix: Make pre-messages w/o text want MDNs (#8004)#8008
iequidoo merged 1 commit into
mainfrom
iequidoo/test_markseen_pre_msg

Conversation

@iequidoo

@iequidoo iequidoo commented Mar 18, 2026

Copy link
Copy Markdown
Collaborator

This fixes #8004 . Maybe it's even good that MDNs will
be sent for pre-messages only having placeholder text with the viewtype and size, at least this way
we notify the contact that we've noticed the message. Anyway, with adding message previews the
problem will be solved for the corresponding viewtypes.

@iequidoo iequidoo force-pushed the iequidoo/test_markseen_pre_msg branch from 4fdd476 to 9afce7d Compare March 18, 2026 14:01
@iequidoo iequidoo requested review from Hocuri and link2xt March 18, 2026 14:06
@iequidoo

Copy link
Copy Markdown
Collaborator Author

I made a bug in the test -- bob doesn't accept the chat -- and this looks suspicious to me:

alice WARN: src/mimeparser.rs:435: decryption failed: decrypt_with_keys: missing key
alice INFO: src/receive_imf.rs:520: Receiving message "ffc78f9e-5ca0-4ab0-8379-8b9150fedfac@localhost", seen=false...
alice INFO: src/contact.rs:1094: Added contact id=1002 addr=bob@example.net.
alice INFO: src/receive_imf.rs:1442: Non-group message, no parent. num_recipients=1. from_id=Contact#1002. Chat assignment = OneOneChat.
alice INFO: src/receive_imf.rs:1771: No chat id for message (TRASH).
alice INFO: src/receive_imf.rs:2356: Message has 1 parts and is assigned to chat #Chat#Trash.
test tests::pre_messages::receiving::test_pre_msg_mdn ... FAILED

Why is bob's self-MDN being processed after the decryption failure? It should go to the trash just because of that and no message should be tried to be added.

@iequidoo iequidoo force-pushed the iequidoo/test_markseen_pre_msg branch from 9afce7d to d3370d5 Compare March 18, 2026 15:14
Comment thread src/test_utils.rs Outdated

pub async fn pop_sent_msg_opt(&self, timeout: Duration) -> Option<SentMessage<'_>> {
let from_head = self
.get_config_bool(Config::PopSentMsgFromHead)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we instead have a new function shift_sent_msg_opt that does this and not a global config that is only used for tests? Otherwise we will have to add this config to all tests over time.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise we will have to add this config to all tests over time.

Why? Only to those where sending messages from head is needed to reproduce some regression. Anyway, do you mean adding a function that moves an smtp job from head to tail?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean creating a function shift_sent_msg_opt that takes message from the beginning of the queue rather than the end, so we can use it in new tests.

@iequidoo iequidoo Mar 20, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first i wanted to do is to create unqueue_sent_msg_opt() which does the same as pop_sent_msg_opt(), but takes the first queued message. But there are other functions calling pop_sent_msg_opt(), so we should forward some flag everywhere. E.g. in the new test it's send_msg() returning SentMessage. Note sure you mean the same, what does shift_ mean? Anyway, i'd avoid adding a flag everywhere, better we add a new Config key or some flag (maybe one-shot) to Context.

I also don't expect many tests needing this, so a config key doesn't look like a problem.

@iequidoo iequidoo Mar 20, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also it appeared that not the sending order is a problem, but absence of message text, so i can drop this part at all. But as it's already done, maybe let it remain?

EDIT: The discussion here is a bit outdated because pop_sent_msg_ex() was added meanwhile, but we still need a way to revert the order for messages popped from the SMTP queue indirectly.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed this Config::PopSentMsgFromHead, chat::send_msg() can be used in tests directly, which doesn't pop any message from smtp, then sent messages can be popped by calling TestContext::pop_sent_msg_ex() which pops from head by default.

@iequidoo iequidoo force-pushed the iequidoo/test_markseen_pre_msg branch from d3370d5 to d2f33f5 Compare March 20, 2026 16:01
@iequidoo iequidoo changed the title test: MDN on pre-message has effect if received before sending full message (#8004) fix: Make pre-messages w/o text want MDNs (#8004) Mar 21, 2026
@iequidoo iequidoo requested review from link2xt and r10s March 21, 2026 12:37
@iequidoo iequidoo force-pushed the iequidoo/test_markseen_pre_msg branch 2 times, most recently from 40058de to 7d5c3f3 Compare March 24, 2026 15:52
@iequidoo iequidoo force-pushed the iequidoo/test_markseen_pre_msg branch from 7d5c3f3 to c70705d Compare March 30, 2026 01:33
@iequidoo iequidoo force-pushed the iequidoo/test_markseen_pre_msg branch from c70705d to d3c0bb0 Compare April 16, 2026 17:28
@iequidoo iequidoo force-pushed the iequidoo/test_markseen_pre_msg branch from d3c0bb0 to 77edcea Compare April 27, 2026 06:14
Comment thread src/smtp.rs Outdated
SendResult::Success => {
if !recipients.is_empty() {
info!(context, "Successfully sent MDN for {rfc724_mid}.");
#[cfg(not(test))]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't like conditional compilation and generally changing the code just for a single test, like adding hooks, options and code paths that are only needed to make the tests pass. If every test adds this, we will end up with unmaintainable code because every time a change to such function is needed someone will have to make sure that the code added for the test does not break as well.

If the function is too large to be usable in a test, e.g. because it makes SMTP connections, it can be refactored first into smaller functions to make it possible to call relevant parts from the test.

@link2xt link2xt May 23, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For a similar discussion, previously: #8019
Also we have pre_encrypt_mime_hook used only in a single test: #8271

@iequidoo iequidoo May 25, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a commit removing conditional compilation by passing different callbacks for MDN sending from the release and test code. Not sure this resolves your comment however, but the idea isn't that every test adds a new conditional compilation block or a new callback, but all tests pass the same callback to send_mdn() so that we only have two: the real and the test ("mock") ones. We anyway cannot test in Rust the same code that we really run.

At least now, with callbacks instead of conditional compilation, code isolation is better, e.g. the test code can't be affected by local vars.

@iequidoo iequidoo May 25, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more way to refactor this is to add another set of smtp functions (namely, send_mdn_rfc724_mid() and send_mdn()) for tests and extract common code blocks into separate functions shared with the release code, but i afraid this will worsen readability and it'll be even difficult to name those common functions meaningfully.

@iequidoo iequidoo Jun 11, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have made send_fn impl AsyncFnOnce and removed extra parameters from it, they are now bound to closures.

@link2xt is this callback approach enough? I'm not sure that breaking everything into smaller functions will improve maintainability

@iequidoo iequidoo marked this pull request as draft May 23, 2026 23:59
@iequidoo iequidoo force-pushed the iequidoo/test_markseen_pre_msg branch 2 times, most recently from 98d91da to 94a895f Compare May 25, 2026 22:09
@iequidoo iequidoo marked this pull request as ready for review May 25, 2026 22:13
@iequidoo iequidoo force-pushed the iequidoo/test_markseen_pre_msg branch from 94a895f to e15b366 Compare May 27, 2026 05:25
@iequidoo iequidoo marked this pull request as draft May 27, 2026 05:47
@iequidoo iequidoo force-pushed the iequidoo/test_markseen_pre_msg branch from e15b366 to 136b6e4 Compare May 27, 2026 07:23
@iequidoo iequidoo marked this pull request as ready for review May 27, 2026 07:23
Comment thread src/smtp.rs Outdated
@iequidoo iequidoo force-pushed the iequidoo/test_markseen_pre_msg branch from 136b6e4 to 9b7e7f0 Compare May 31, 2026 05:26
@iequidoo iequidoo force-pushed the iequidoo/test_markseen_pre_msg branch from 9b7e7f0 to e88940e Compare June 11, 2026 17:18
Comment thread src/tests/pre_messages/receiving.rs Outdated
.await?,
1
);
smtp::queue_mdn(bob).await;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid complicating send_mdn_rfc724_mid with hooks and test code: it is enough to check that the message WantsMdn and smtp_mdns has an entry, as already checked above.

It indeed looks bad that send_mdn_rfc724_mid does SMTP sending itself rather than just queueing a message and interrupting SMTP loop and probably should be refactored, but it's better not to do any refactoring of this function in this PR.

@iequidoo iequidoo Jun 14, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it actually that bad (less readable?) that send_mdn_rfc724_mid() now accepts send_fn instead of smtp: &mut Smtp? It's not a test hook like we had before and have already removed. Rather a way to abstract parts of the code.

In this test it's ok to just check for presence of the smtp_mdns entry, fortunately. But what to do in tests actually needing to receive MDNs we send, like e.g. 67a75a4? If we never refactor this MDN sending pipeline, the only way to test receiving MDNs is to put them into test-data/ which is really harder to maintain. Testing receiving Detlta Chat -generated MDNs in Python tests isn't always helpful because of timings. Sometimes an MDN needs to be received at an exact moment.

...

It indeed looks bad that send_mdn_rfc724_mid does SMTP sending itself rather than just queueing a message and interrupting SMTP loop and probably should be refactored, but it's better not to do any refactoring of this function in this PR.

Agree, that would be a quite big refactoring for this PR. In the current state the PR only moves a part of the code into AsyncFnOnce(&str, String, Vec<String>) -> Result<bool>, this is all the refactoring.

@iequidoo iequidoo force-pushed the iequidoo/test_markseen_pre_msg branch from 886d6c4 to 9d6c7e5 Compare June 14, 2026 00:40
@iequidoo iequidoo marked this pull request as draft June 14, 2026 00:40
@iequidoo iequidoo force-pushed the iequidoo/test_markseen_pre_msg branch 4 times, most recently from 6c69d4c to 6bb6622 Compare June 16, 2026 03:55
@iequidoo

Copy link
Copy Markdown
Collaborator Author

I've removed the refactoring of smtp and corresponding parts of the tests. It's unfortunate that MDNs can't be fully tested w/o it. Here's a branch for the removed refactoring, but i'm not going to create more discussions or PRs: https://github.com/chatmail/core/tree/iequidoo/queue_mdn

@iequidoo iequidoo marked this pull request as ready for review June 16, 2026 03:59
@iequidoo iequidoo requested a review from link2xt June 16, 2026 03:59
Comment thread src/context.rs Outdated
@iequidoo iequidoo force-pushed the iequidoo/test_markseen_pre_msg branch from 6bb6622 to 0787ca2 Compare June 17, 2026 01:06
@iequidoo iequidoo marked this pull request as draft June 17, 2026 01:12
@iequidoo iequidoo force-pushed the iequidoo/test_markseen_pre_msg branch from 0787ca2 to 1eb772e Compare June 17, 2026 01:17
@iequidoo iequidoo marked this pull request as ready for review June 17, 2026 01:17
@iequidoo iequidoo force-pushed the iequidoo/test_markseen_pre_msg branch from 1eb772e to 7633022 Compare June 17, 2026 01:21
@iequidoo iequidoo requested a review from link2xt June 17, 2026 01:26
Comment thread src/mimeparser.rs Outdated
.sql
.query_row_optional(
// MDN on a pre-message references the post-message, see `receive_imf`. So we can't tell
// which one was seen, but this is on purpose.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure I understand this comment. "we can't tell which one was seen" means that we cannot tell if pre-message or fully downloaded message was seen?

Also not clear which part of receive_imf "see receive_imf" refers to.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"we can't tell which one was seen" means that we cannot tell if pre-message or fully downloaded message was seen?

Yes. I've already forgotten which part of receive_imf i meant and why, but i tried to improve the comment.

Maybe it's even good that MDNs will be sent for pre-messages only having placeholder text with the
viewtype and size, at least this way we notify the contact that we've noticed the message. Anyway,
with adding message previews the problem will be solved for the corresponding viewtypes.
@iequidoo iequidoo force-pushed the iequidoo/test_markseen_pre_msg branch from 7633022 to d5b6488 Compare June 17, 2026 03:00
@iequidoo iequidoo merged commit 58b3f0e into main Jun 17, 2026
19 checks passed
@iequidoo iequidoo deleted the iequidoo/test_markseen_pre_msg branch June 17, 2026 03:02
@link2xt

link2xt commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

I've removed the refactoring of smtp and corresponding parts of the tests. It's unfortunate that MDNs can't be fully tested w/o it. Here's a branch for the removed refactoring, but i'm not going to create more discussions or PRs: https://github.com/chatmail/core/tree/iequidoo/queue_mdn

I have looked at it, but still think we don't want to have code that converts smtp_mdns into smtp just for tests. The code related to smtp table handling will need to be changed for failover as we will need to store the messages differently to make it possible to update the From header. I'm currently looking into possibility of updating the Date header for #8112 as it will also make it possible to do failover and try sending the same message from different relays. Having more code depending on smtp will make it more difficult and storing MDNs in smtp table is not what happens in the actually running code.

@iequidoo

Copy link
Copy Markdown
Collaborator Author

I have looked at it, but still think we don't want to have code that converts smtp_mdns into smtp just for tests. [...]

Got it. Maybe then it should be not queue_mdn() but get_sent_mdn() -> SentMessage<'_> in test_utils module? However, this can be done later after #8112 and implementing SMTP failover.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

read-receipts not always displayed

3 participants