From 1250621a4d41739b651140a7bcbabbfcc5fcd9d4 Mon Sep 17 00:00:00 2001 From: Xavier Michelon Date: Fri, 24 Sep 2021 15:45:22 +0200 Subject: [PATCH] GODT-963 STORE removing junk or adding nojunk should move message to inbox --- internal/imap/mailbox_messages.go | 19 ++++++++++++--- .../bridge/imap/message/update_spam.feature | 19 +++++++++++++++ test/imap_actions_messages_test.go | 24 +++++++++++++++++++ 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/internal/imap/mailbox_messages.go b/internal/imap/mailbox_messages.go index ae2b50d5..5313b776 100644 --- a/internal/imap/mailbox_messages.go +++ b/internal/imap/mailbox_messages.go @@ -137,8 +137,14 @@ func (im *imapMailbox) setFlags(messageIDs, flags []string) error { //nolint return nil } -func (im *imapMailbox) addOrRemoveFlags(operation imap.FlagsOp, messageIDs, flags []string) error { +func (im *imapMailbox) addOrRemoveFlags(operation imap.FlagsOp, messageIDs, flags []string) error { //nolint[funlen] for _, f := range flags { + // Adding flag 'nojunk' is equivalent to removing flag 'junk' + if (operation == imap.AddFlags) && (f == "nojunk") { + operation = imap.RemoveFlags + f = "junk" + } + switch f { case imap.SeenFlag: switch operation { //nolint[exhaustive] imap.SetFlags is processed by im.setFlags @@ -175,12 +181,11 @@ func (im *imapMailbox) addOrRemoveFlags(operation imap.FlagsOp, messageIDs, flag } case imap.AnsweredFlag, imap.DraftFlag, imap.RecentFlag: // Not supported. - case message.AppleMailJunkFlag, message.ThunderbirdJunkFlag: + case strings.ToLower(message.AppleMailJunkFlag), strings.ToLower(message.ThunderbirdJunkFlag): storeMailbox, err := im.storeAddress.GetMailbox("Spam") if err != nil { return err } - // Handle custom junk flags for Apple Mail and Thunderbird. switch operation { //nolint[exhaustive] imap.SetFlag is processed by im.setFlags // No label removal is necessary because Spam and Inbox are both exclusive labels so the backend @@ -190,9 +195,17 @@ func (im *imapMailbox) addOrRemoveFlags(operation imap.FlagsOp, messageIDs, flag return err } case imap.RemoveFlags: + // when removing junk flag, the message should be moved to the INBOX folder. if err := storeMailbox.UnlabelMessages(messageIDs); err != nil { return err } + inboxMailbox, err := im.storeAddress.GetMailbox("INBOX") + if err != nil { + return err + } + if err := inboxMailbox.LabelMessages(messageIDs); err != nil { + return err + } } } } diff --git a/test/features/bridge/imap/message/update_spam.feature b/test/features/bridge/imap/message/update_spam.feature index e9ab61b1..a6a3b04e 100644 --- a/test/features/bridge/imap/message/update_spam.feature +++ b/test/features/bridge/imap/message/update_spam.feature @@ -19,3 +19,22 @@ Feature: IMAP update messages in Spam folder | from | to | subject | | john.doe@mail.com | user@pm.me | foo | | jane.doe@mail.com | name@pm.me | bar | + + Scenario Outline: Removing flag "junk" or adding flags "nojunk" moves message to INBOX + When IMAP client flags "" message seq "1" + Then IMAP response is "OK" + And mailbox "INBOX" for "user" has 1 messages + And mailbox "INBOX" for "user" has messages + | from | to | subject | + | john.doe@mail.com | user@pm.me | foo | + And mailbox "Spam" for "user" has 1 messages + And mailbox "Spam" for "user" has messages + | from | to | subject | + | jane.doe@mail.com | name@pm.me | bar | + Examples: + | operation | suffix | flag | + | adds | to | nojunk | + | adds | to | NoJunk | + | removes | from | junk | + | removes | from | Junk | + | removes | from | $Junk | diff --git a/test/imap_actions_messages_test.go b/test/imap_actions_messages_test.go index 02d88d83..191d05ec 100644 --- a/test/imap_actions_messages_test.go +++ b/test/imap_actions_messages_test.go @@ -48,6 +48,10 @@ func IMAPActionsMessagesFeatureContext(s *godog.ScenarioContext) { s.Step(`^IMAP client creates message "([^"]*)" from address "([^"]*)" of "([^"]*)" to "([^"]*)" with body "([^"]*)" in "([^"]*)"$`, imapClientCreatesMessageFromAddressOfUserToWithBody) s.Step(`^IMAP client marks message seq "([^"]*)" with "([^"]*)"$`, imapClientMarksMessageSeqWithFlags) s.Step(`^IMAP client "([^"]*)" marks message seq "([^"]*)" with "([^"]*)"$`, imapClientNamedMarksMessageSeqWithFlags) + s.Step(`^IMAP client adds flags "([^"]*)" to message seq "([^"]*)"$`, imapClientAddsFlagsToMessageSeq) + s.Step(`^IMAP client "([^"]*)" adds flags "([^"]*)" to message seq "([^"]*)"$`, imapClientNamedAddsFlagsToMessageSeq) + s.Step(`^IMAP client removes flags "([^"]*)" from message seq "([^"]*)"$`, imapClientRemovesFlagsFromMessageSeq) + s.Step(`^IMAP client "([^"]*)" removes flags "([^"]*)" from message seq "([^"]*)"$`, imapClientNamedRemovesFlagsFromMessageSeq) s.Step(`^IMAP client marks message seq "([^"]*)" as read$`, imapClientMarksMessageSeqAsRead) s.Step(`^IMAP client "([^"]*)" marks message seq "([^"]*)" as read$`, imapClientNamedMarksMessageSeqAsRead) s.Step(`^IMAP client marks message seq "([^"]*)" as unread$`, imapClientMarksMessageSeqAsUnread) @@ -266,6 +270,26 @@ func imapClientNamedMarksMessageSeqWithFlags(imapClient, messageSeq, flags strin return nil } +func imapClientAddsFlagsToMessageSeq(flags, messageSeq string) error { + return imapClientNamedAddsFlagsToMessageSeq("imap", flags, messageSeq) +} + +func imapClientNamedAddsFlagsToMessageSeq(imapClient, flags, messageSeq string) error { + res := ctx.GetIMAPClient(imapClient).AddFlags(messageSeq, flags) + ctx.SetIMAPLastResponse(imapClient, res) + return nil +} + +func imapClientRemovesFlagsFromMessageSeq(flags, messageSeq string) error { + return imapClientNamedRemovesFlagsFromMessageSeq("imap", flags, messageSeq) +} + +func imapClientNamedRemovesFlagsFromMessageSeq(imapClient, flags, messageSeq string) error { + res := ctx.GetIMAPClient(imapClient).RemoveFlags(messageSeq, flags) + ctx.SetIMAPLastResponse(imapClient, res) + return nil +} + func imapClientMarksMessageSeqAsRead(messageSeq string) error { return imapClientNamedMarksMessageSeqAsRead("imap", messageSeq) }