From f66974f943da2500eaae02c834a0c39a3b6fd961 Mon Sep 17 00:00:00 2001 From: Marc Scholten Date: Sat, 13 Jun 2026 11:21:59 +0200 Subject: [PATCH] Add regression test for Office365/Exchange trailing FETCH fields (#15) Office365 and Exchange append "UID nn FLAGS (\Seen)" after the BODY[] literal, before the closing ')'. The old Parsec FETCH parser rejected this with "expected space or )". The streaming parser introduced in #111 already tolerates it; this locks the behaviour in with a test feeding the exact wire shape from #15 through IMAP.fetch. Also fixes the stale "append preserves raw crlf message bytes" expectation: APPEND now quotes the mailbox name ("INBOX") since the mailbox-quoting change, so the test expectation is updated to match. The suite is green again (48/48). Co-Authored-By: Claude Opus 4.8 --- test/IMAPParsersTest.hs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/test/IMAPParsersTest.hs b/test/IMAPParsersTest.hs index b4e60c1..281102d 100644 --- a/test/IMAPParsersTest.hs +++ b/test/IMAPParsersTest.hs @@ -298,7 +298,7 @@ imapCommandTest = commandBytes "000000 STATUS \"foo bar\" (MESSAGES)" @=? actual , "append preserves raw crlf message bytes" ~: TestCase $ do let mailData = BS.pack "Subject: x\r\n\r\nBody\r\n" - expectedCommand = "000000 APPEND INBOX {" ++ show (BS.length mailData) ++ "}" + expectedCommand = "000000 APPEND \"INBOX\" {" ++ show (BS.length mailData) ++ "}" (conn, written) <- scriptedConnection [ line "+ Ready for literal" , okLine "APPEND completed" @@ -365,6 +365,19 @@ imapFetchTest = ] fetched <- IMAP.fetch conn 42 body @=? fetched + , "fetch tolerates trailing UID/FLAGS after body literal (Office365/Exchange, #15)" ~: TestCase $ do + -- Office365 and Exchange append "UID nn FLAGS (\\Seen)" after the + -- BODY[] literal, before the closing ')'. The old Parsec parser + -- rejected this with "expected space or )". + let body = BS.pack "Content-Transfer-Encoding: quoted-printable\r\n\r\n" + (conn, _) <- scriptedConnection + [ line ("* 12 FETCH (BODY[] {" ++ show (BS.length body) ++ "}") + , ReadBytes body + , line " UID 12 FLAGS (\\Seen))" + , okLine "FETCH completed" + ] + fetched <- IMAP.fetch conn 12 + body @=? fetched , "fetchPeek reads body response without setting Seen" ~: TestCase $ do let body = BS.pack "peeked" (conn, _) <- scriptedConnection