aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_composecontext.cpp
AgeCommit message (Collapse)AuthorFilesLines
9 hoursfeat: flag what you answered, mark what was forwarded to youDanilo M.1-0/+77
Item 68, which turned out to be three things once its premise was measured. The note asked to extend a "passed" subject rule to "Fw:"; there was no subject rule, and the correlation it rested on did not exist. What did exist was a gap nobody had reported. Reply and forward now flag their source. The Maildir R and P flags, which every other client sets and notmuch reads back as "replied" and "passed", had never been written here: measured on the developer's index, all 317 "replied" and all 6 "passed" came from other clients. ComposeWindow emits sourceMessageAnswered after a successful send and MainWindow routes it through sendMessageTagChange, message-scoped and off the undo stack, for the reason auto mark-read is: the flag records that the mail went, and the send cannot be undone. ComposeContext carries sourceMessageId rather than reusing inReplyTo, which is deliberately empty on a forward so the recipient's client does not file it under the thread it left. Keying on it made the "passed" half dead code that compiled and never fired. A resumed draft is excluded: its kind records how the file was opened, not what the user is doing, so flagging on it would set R from a guess. A received forward gets its own mark. Derived from the subject at paint time, storing nothing and reaching no server, because "passed" means "I forwarded this" and setting it from a guess would assert something false on 222 existing messages. subjectIsForwarded() shares forwardSubject()'s prefix table so the two cannot disagree, strips a Re: chain first, and takes extra locale spellings from [general] forward_prefixes, which extends the built-in table rather than replacing it. A mutation survived the first round and corrected a claim in the code: QRegularExpression::escape already makes a punctuation prefix inert, so the word guard is not about pattern validity. It stops a configured "-" matching "-: x". The comment and test say that now. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LXCZFLXbAii5n5wtovpdhh
5 daysfeat(compose): derive a reply's recipients and headers, item 123Danilo M.1-0/+1051
ComposeContext, task 7 of the compose-and-send plan. Address parsing, recipient derivation, the References chain, subject prefixing and account resolution, as free functions over values so they test without a painter. Recipient derivation was designed from the spec rather than transcribed: the plan's draft omitted it and its tests could not compile, calling QVERIFY(config.load(path)) against a void return. Six defects found in review, each pinned by a test checked against the mutation that breaks it: - Message-ids reached GMime bare, and GMime writes an EMPTY header for a bare addr-spec rather than complaining. In-Reply-To and References both shipped blank, so every reply would have arrived as an orphan thread with nothing wrong to see locally. MessageBuilder now brackets on write, in the one place that composes those headers rather than in each caller. - internet_address_to_string was called with FALSE for the encode flag, so a display name carrying a raw newline rendered with the newline intact. That is a header-injection primitive. - A reply to the user's own message addressed the user. It now goes to that message's original recipients, mirroring their To/Cc split, which is what the Sent view and a follow-up on unanswered mail need. - A From parsing to no mailbox left To empty, reachable from real mail ("From: Mailer Daemon"). MessageBuilder treats an empty recipient list as success, so the message would have been handed to the send command with nobody to deliver to and filed in Sent looking sent. - The References header was split on whitespace alone, so a client's non-conformant "<a@x>,<b@y>" became one token and the bracket strip produced the fabricated id "a@x>,<b@y". - Reply and forward prefixes were recognised in English only, doubling every AW:, SV:, WG: and Re[2]: a mixed-locale mailbox receives. Single-letter spellings are deliberately excluded: with R: recognised, "R: report on Q3" reads as a prefix and a genuine first reply threads nowhere. The mailbox-only guard in parseAddressHeader survived its first mutation check, because removing it still yields no recipients: the invalid GObject cast makes GMime's own assertion return NULL. That is undefined behaviour papered over by an assertion G_DISABLE_CHECKS compiles out, so the test now asserts on the emitted critical rather than on the count. Registering the log handler on a NULL domain catches nothing; the criticals carry "GLib-GObject" and "gmime". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LoaLBowZ6w1JNx6SEhDP1L