Skip to content

Commit

Permalink
fix: ConnectorUpdate CreateMessage
Browse files Browse the repository at this point in the history
Fix connector updates for create message. There was a bug in them related
to messages with the same ID.
  • Loading branch information
LBeernaertProton committed Sep 13, 2022
1 parent 449783e commit ec2d0e4
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 15 deletions.
39 changes: 38 additions & 1 deletion connector/dummy_simulate.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package connector

import "github.com/ProtonMail/gluon/imap"
import (
"github.com/ProtonMail/gluon/imap"
)

func (conn *Dummy) SetFolderPrefix(pfx string) {
defer conn.Flush()
Expand Down Expand Up @@ -86,6 +88,41 @@ func (conn *Dummy) MessageCreated(message imap.Message, literal []byte, mboxIDs
return nil
}

func (conn *Dummy) MessagesCreated(messages []imap.Message, literals [][]byte, mboxIDs [][]imap.LabelID) error {
conn.state.lock.Lock()
defer conn.state.lock.Unlock()

update := imap.NewMessagesCreated()

for i := 0; i < len(messages); i++ {
parsedMessage, err := imap.NewParsedMessage(literals[i])
if err != nil {
return err
}

labelIDs := make(map[imap.LabelID]struct{})

for _, mboxID := range mboxIDs[i] {
labelIDs[mboxID] = struct{}{}
}

conn.state.messages[messages[i].ID] = &dummyMessage{
literal: literals[i],
seen: messages[i].Flags.Contains(imap.FlagSeen),
flagged: messages[i].Flags.Contains(imap.FlagFlagged),
parsedMessage: parsedMessage,
date: messages[i].Date,
labelIDs: labelIDs,
}

update.Add(messages[i], literals[i], parsedMessage, mboxIDs[i]...)
}

conn.pushUpdate(update)

return nil
}

func (conn *Dummy) MessageAdded(messageID imap.MessageID, labelID imap.LabelID) error {
conn.state.labelMessage(messageID, labelID)

Expand Down
2 changes: 1 addition & 1 deletion internal/backend/connector_updates.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ func (user *user) applyMessagesCreated(ctx context.Context, update *imap.Message
InternalID: imap.InternalMessageID(internalID),
}

remoteMessageRequestsMap[update.Message.ID] = req
remoteMessageRequestsMap[update.Message.ID] = request
}

for _, mbox := range update.MailboxIDs {
Expand Down
45 changes: 32 additions & 13 deletions tests/session_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type Connector interface {
MailboxDeleted(imap.LabelID) error

MessageCreated(imap.Message, []byte, []imap.LabelID) error
MessagesCreated([]imap.Message, [][]byte, [][]imap.LabelID) error
MessageAdded(imap.MessageID, imap.LabelID) error
MessageRemoved(imap.MessageID, imap.LabelID) error
MessageSeen(imap.MessageID, bool) error
Expand Down Expand Up @@ -173,6 +174,12 @@ func (s *testSession) mailboxCreatedCustom(user string, name []string, flags, pe
func (s *testSession) messageCreated(user string, mailboxID imap.LabelID, literal []byte, flags ...string) imap.MessageID {
messageID := imap.MessageID(utils.NewRandomMessageID())

s.messageCreatedWithID(user, messageID, mailboxID, literal, flags...)

return messageID
}

func (s *testSession) messageCreatedWithID(user string, messageID imap.MessageID, mailboxID imap.LabelID, literal []byte, flags ...string) {
require.NoError(s.tb, s.conns[s.userIDs[user]].MessageCreated(
imap.Message{
ID: messageID,
Expand All @@ -184,30 +191,42 @@ func (s *testSession) messageCreated(user string, mailboxID imap.LabelID, litera
))

s.conns[s.userIDs[user]].Flush()

return messageID
}

func (s *testSession) batchMessageCreated(user string, mailboxID imap.LabelID, count int, createMessage func(int) ([]byte, []string)) []imap.MessageID {
return s.batchMessageCreatedWithID(user, mailboxID, count, func(i int) (imap.MessageID, []byte, []string) {
messageID := imap.MessageID(utils.NewRandomMessageID())
literal, flags := createMessage(i)

return messageID, literal, flags
})
}

func (s *testSession) batchMessageCreatedWithID(user string, mailboxID imap.LabelID, count int, createMessage func(int) (imap.MessageID, []byte, []string)) []imap.MessageID {
var messageIDs []imap.MessageID

messages := make([]imap.Message, 0, count)
literals := make([][]byte, 0, count)
mailboxes := make([][]imap.LabelID, 0, count)

for i := 0; i < count; i++ {
messageID := imap.MessageID(utils.NewRandomMessageID())
messageID, literal, flags := createMessage(i)

literal, flags := createMessage(i)
messages = append(messages, imap.Message{
ID: messageID,
Flags: imap.NewFlagSetFromSlice(flags),
Date: time.Now(),
})

literals = append(literals, literal)

require.NoError(s.tb, s.conns[s.userIDs[user]].MessageCreated(
imap.Message{
ID: messageID,
Flags: imap.NewFlagSetFromSlice(flags),
Date: time.Now(),
},
literal,
[]imap.LabelID{mailboxID},
))
mailboxes = append(mailboxes, []imap.LabelID{mailboxID})

messageIDs = append(messageIDs, messageID)
}

require.NoError(s.tb, s.conns[s.userIDs[user]].MessagesCreated(messages, literals, mailboxes))

s.conns[s.userIDs[user]].Flush()

return messageIDs
Expand Down
21 changes: 21 additions & 0 deletions tests/updates_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package tests

import (
"github.com/ProtonMail/gluon/imap"
"github.com/ProtonMail/gluon/internal/utils"
"testing"
)

Expand Down Expand Up @@ -269,3 +271,22 @@ func TestMessageFlaggedUpdate(t *testing.T) {
c.OK("A004")
})
}

func TestMessageAddWithSameID(t *testing.T) {
runOneToOneTestWithAuth(t, defaultServerOptions(t), func(c *testConnection, s *testSession) {
mailboxID := s.mailboxCreated("user", []string{"mbox"})
flags := []string{imap.FlagFlagged, imap.FlagDraft, "\\foo", "\\bar", imap.AttrMarked}
messageID := imap.MessageID(utils.NewRandomMessageID())
s.batchMessageCreatedWithID("user", mailboxID, 2, func(i int) (imap.MessageID, []byte, []string) {
return messageID, []byte("to: [email protected]"), flags
})

s.flush("user")

c.C("A001 SELECT mbox").OK("A001")

c.C("A003 FETCH 1 (FLAGS)")
c.S(`* 1 FETCH (FLAGS (\Draft \Flagged \Marked \Recent \bar \foo)`)
c.OK("A003")
})
}

0 comments on commit ec2d0e4

Please sign in to comment.