Implement deleted flag GODT-461

This commit is contained in:
Jakub
2020-08-25 07:16:13 +02:00
committed by Michal Horejsek
parent 803353e300
commit 66e04dd5ed
25 changed files with 396 additions and 135 deletions

View File

@ -34,6 +34,7 @@ type PMAPIController interface {
AddUserMessage(username string, message *pmapi.Message) error
GetMessageID(username, messageIndex string) string
GetMessages(username, labelID string) ([]*pmapi.Message, error)
GetLastMessageID(username string) string
ReorderAddresses(user *pmapi.User, addressIDs []string) error
PrintCalls()
WasCalled(method, path string, expectedRequest []byte) bool

View File

@ -172,4 +172,8 @@ func (ctl *Controller) GetMessages(username, labelID string) ([]*pmapi.Message,
}
}
return messages, nil
func (ctl *Controller) GetLastMessageID(username string) string {
msgs := ctl.messagesByUsername[username]
return msgs[len(msgs)-1].ID
}

View File

@ -277,7 +277,8 @@ func (api *FakePMAPI) deleteMessages(method method, path string, request interfa
newMessages := []*pmapi.Message{}
for _, message := range api.messages {
if shouldBeDeleted(message) {
if hasItem(message.LabelIDs, pmapi.TrashLabel) {
if hasItem(message.LabelIDs, pmapi.TrashLabel) ||
hasItem(message.LabelIDs, pmapi.SpamLabel) {
api.addEventMessage(pmapi.EventDelete, message)
continue
}

View File

@ -11,7 +11,8 @@ Feature: IMAP remove messages from mailbox
When IMAP client marks message "2" as deleted
Then IMAP response is "OK"
And mailbox "<mailbox>" for "user" has 10 messages
And message "2" in "INBOX" for "user" is marked as deleted
And message "9" in "<mailbox>" for "user" is marked as deleted
And IMAP response contains "\* 2 FETCH[ (]*FLAGS \([^)]*\\Deleted"
When IMAP client sends expunge
Then IMAP response is "OK"
And IMAP response contains "* 2 EXPUNGE"
@ -77,7 +78,7 @@ Feature: IMAP remove messages from mailbox
When IMAP client marks message "2" as deleted
Then IMAP response is "OK"
And mailbox "INBOX" for "user" has 10 messages
And message "2" in "INBOX" for "user" is marked as deleted
And message "9" in "INBOX" for "user" is marked as deleted
When IMAP client sends command "<leave>"
Then IMAP response is "OK"
And mailbox "INBOX" for "user" has <n> messages

View File

@ -57,23 +57,27 @@ Feature: IMAP update messages
And message "1" in "Spam" for "user" is marked as unstarred
Scenario: Mark message as deleted
When IMAP client marks message "2" as deleted
# Mark message as Starred so we can check that mark as Deleted is not
# tempering with Starred flag
When IMAP client marks message "1" as starred
Then IMAP response is "OK"
When IMAP client marks message "1" as deleted
Then IMAP response is "OK"
And message "2" in "INBOX" for "user" is marked as read
And message "2" in "INBOX" for "user" is marked as starred
And message "2" in "INBOX" for "user" is marked as deleted
Scenario: Mark message as undeleted
When IMAP client marks message "2" as undeleted
When IMAP client marks message "1" as undeleted
Then IMAP response is "OK"
And message "2" in "INBOX" for "user" is marked as read
And message "2" in "INBOX" for "user" is marked as starred
And message "2" in "INBOX" for "user" is marked as undeleted
Scenario: Mark message as deleted only
When IMAP client marks message "2" with "\Deleted"
When IMAP client marks message "1" with "\Deleted"
Then IMAP response is "OK"
And message "2" in "INBOX" for "user" is marked as unread
And message "2" in "INBOX" for "user" is marked as unstarred
And message "2" in "INBOX" for "user" is marked as undeleted
And message "2" in "INBOX" for "user" is marked as deleted

View File

@ -4,14 +4,15 @@ Feature: IMAP remove messages from Trash
And there is "user" with mailbox "Folders/mbox"
And there is "user" with mailbox "Labels/label"
Scenario Outline: Delete messages from Trash/Spam removes all labels first
Scenario Outline: Delete messages from Trash/Spam does not remove from All Mail
Given there are messages in mailbox "<mailbox>" for "user"
| from | to | subject | body |
| john.doe@mail.com | user@pm.me | foo | hello |
| jane.doe@mail.com | name@pm.me | bar | world |
And there is IMAP client logged in as "user"
And there is IMAP client selected in "<mailbox>"
And IMAP client copies messages "2" to "Labels/label"
When IMAP client copies messages "2" to "Labels/label"
Then IMAP response is "OK"
When IMAP client marks message "2" as deleted
Then IMAP response is "OK"
And mailbox "<mailbox>" for "user" has 2 messages
@ -19,9 +20,9 @@ Feature: IMAP remove messages from Trash
And mailbox "Labels/label" for "user" has 1 messages
When IMAP client sends expunge
Then IMAP response is "OK"
And mailbox "<mailbox>" for "user" has 2 messages
And mailbox "<mailbox>" for "user" has 1 messages
And mailbox "All Mail" for "user" has 2 messages
And mailbox "Labels/label" for "user" has 0 messages
And mailbox "Labels/label" for "user" has 1 messages
Examples:
| mailbox |
@ -29,7 +30,7 @@ Feature: IMAP remove messages from Trash
| Trash |
Scenario Outline: Delete messages from Trash/Spamm deletes from All Mail
Scenario Outline: Delete messages from Trash/Spamm removes from All Mail
Given there are messages in mailbox "<mailbox>" for "user"
| from | to | subject | body |
| john.doe@mail.com | user@pm.me | foo | hello |

View File

@ -162,4 +162,8 @@ func (ctl *Controller) GetMessages(username, labelID string) ([]*pmapi.Message,
}
return messages, nil
func (ctl *Controller) GetLastMessageID(username string) string {
ids := ctl.messageIDsByUsername[username]
return ids[len(ids)-1]
}

View File

@ -23,7 +23,7 @@ import (
"strings"
"time"
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
"github.com/ProtonMail/proton-bridge/internal/store"
"github.com/ProtonMail/proton-bridge/test/accounts"
"github.com/cucumber/godog"
"github.com/cucumber/godog/gherkin"
@ -128,13 +128,13 @@ func mailboxForAddressOfUserHasMessages(mailboxName, bddAddressID, bddUserID str
if err != nil {
return internalError(err, "getting API IDs from sequence range")
}
allMessages := []*pmapi.Message{}
allMessages := []*store.Message{}
for _, apiID := range apiIDs {
message, err := mailbox.GetMessage(apiID)
if err != nil {
return internalError(err, "getting message by ID")
}
allMessages = append(allMessages, message.Message())
allMessages = append(allMessages, message)
}
head := messages.Rows[0].Cells
@ -168,9 +168,10 @@ func mailboxForAddressOfUserHasMessages(mailboxName, bddAddressID, bddUserID str
return nil
}
func messagesContainsMessageRow(account *accounts.TestAccount, allMessages []*pmapi.Message, head []*gherkin.TableCell, row *gherkin.TableRow) (bool, error) { //nolint[funlen]
func messagesContainsMessageRow(account *accounts.TestAccount, allMessages []*store.Message, head []*gherkin.TableCell, row *gherkin.TableRow) (bool, error) { //nolint[funlen]
found := false
for _, message := range allMessages {
for _, storeMessage := range allMessages {
message := storeMessage.Message()
matches := true
for n, cell := range row.Cells {
switch head[n].Value {
@ -220,8 +221,8 @@ func messagesContainsMessageRow(account *accounts.TestAccount, allMessages []*pm
matches = false
}
case "deleted":
// TODO
matches = false
expectedDeleted := cell.Value == "true"
matches = storeMessage.IsMarkedDeleted() == expectedDeleted
default:
return false, fmt.Errorf("unexpected column name: %s", head[n].Value)
}
@ -247,56 +248,60 @@ func areAddressesSame(first, second string) bool {
}
func messagesInMailboxForUserIsMarkedAsRead(messageIDs, mailboxName, bddUserID string) error {
return checkMessages(bddUserID, mailboxName, messageIDs, func(message *pmapi.Message) error {
if message.Unread == 0 {
return checkMessages(bddUserID, mailboxName, messageIDs, func(message *store.Message) error {
if message.Message().Unread == 0 {
return nil
}
return fmt.Errorf("message %s \"%s\" is expected to be read but is not", message.ID, message.Subject)
return fmt.Errorf("message %s \"%s\" is expected to be read but is not", message.ID(), message.Message().Subject)
})
}
func messagesInMailboxForUserIsMarkedAsUnread(messageIDs, mailboxName, bddUserID string) error {
return checkMessages(bddUserID, mailboxName, messageIDs, func(message *pmapi.Message) error {
if message.Unread == 1 {
return checkMessages(bddUserID, mailboxName, messageIDs, func(message *store.Message) error {
if message.Message().Unread == 1 {
return nil
}
return fmt.Errorf("message %s \"%s\" is expected to not be read but is", message.ID, message.Subject)
return fmt.Errorf("message %s \"%s\" is expected to not be read but is", message.ID(), message.Message().Subject)
})
}
func messagesInMailboxForUserIsMarkedAsStarred(messageIDs, mailboxName, bddUserID string) error {
return checkMessages(bddUserID, mailboxName, messageIDs, func(message *pmapi.Message) error {
if hasItem(message.LabelIDs, "10") {
return checkMessages(bddUserID, mailboxName, messageIDs, func(message *store.Message) error {
if hasItem(message.Message().LabelIDs, "10") {
return nil
}
return fmt.Errorf("message %s \"%s\" is expected to be starred but is not", message.ID, message.Subject)
return fmt.Errorf("message %s \"%s\" is expected to be starred but is not", message.ID(), message.Message().Subject)
})
}
func messagesInMailboxForUserIsMarkedAsUnstarred(messageIDs, mailboxName, bddUserID string) error {
return checkMessages(bddUserID, mailboxName, messageIDs, func(message *pmapi.Message) error {
if !hasItem(message.LabelIDs, "10") {
return checkMessages(bddUserID, mailboxName, messageIDs, func(message *store.Message) error {
if !hasItem(message.Message().LabelIDs, "10") {
return nil
}
return fmt.Errorf("message %s \"%s\" is expected to not be starred but is", message.ID, message.Subject)
return fmt.Errorf("message %s \"%s\" is expected to not be starred but is", message.ID(), message.Message().Subject)
})
}
func messagesInMailboxForUserIsMarkedAsDeleted(messageIDs, mailboxName, bddUserID string) error {
return checkMessages(bddUserID, mailboxName, messageIDs, func(message *pmapi.Message) error {
// TODO
return fmt.Errorf("TODO message %s \"%s\" is expected to be deleted but is not", message.ID, message.Subject)
return checkMessages(bddUserID, mailboxName, messageIDs, func(message *store.Message) error {
if message.IsMarkedDeleted() {
return nil
}
return fmt.Errorf("message %s \"%s\" is expected to be deleted but is not", message.ID(), message.Message().Subject)
})
}
func messagesInMailboxForUserIsMarkedAsUndeleted(messageIDs, mailboxName, bddUserID string) error {
return checkMessages(bddUserID, mailboxName, messageIDs, func(message *pmapi.Message) error {
// TODO
return fmt.Errorf("TODO message %s \"%s\" is expected to not be deleted but is", message.ID, message.Subject)
return checkMessages(bddUserID, mailboxName, messageIDs, func(message *store.Message) error {
if !message.IsMarkedDeleted() {
return nil
}
return fmt.Errorf("message %s \"%s\" is expected to not be deleted but is", message.ID(), message.Message().Subject)
})
}
func checkMessages(bddUserID, mailboxName, messageIDs string, callback func(*pmapi.Message) error) error {
func checkMessages(bddUserID, mailboxName, messageIDs string, callback func(*store.Message) error) error {
account := ctx.GetTestAccount(bddUserID)
if account == nil {
return godog.ErrPending
@ -313,9 +318,9 @@ func checkMessages(bddUserID, mailboxName, messageIDs string, callback func(*pma
return nil
}
func getMessages(username, addressID, mailboxName, messageIDs string) ([]*pmapi.Message, error) {
msgs := []*pmapi.Message{}
var msg *pmapi.Message
func getMessages(username, addressID, mailboxName, messageIDs string) ([]*store.Message, error) {
msgs := []*store.Message{}
var msg *store.Message
var err error
iterateOverSeqSet(messageIDs, func(messageID string) {
messageID = ctx.GetPMAPIController().GetMessageID(username, messageID)
@ -327,16 +332,12 @@ func getMessages(username, addressID, mailboxName, messageIDs string) ([]*pmapi.
return msgs, err
}
func getMessage(username, addressID, mailboxName, messageID string) (*pmapi.Message, error) {
func getMessage(username, addressID, mailboxName, messageID string) (*store.Message, error) {
mailbox, err := ctx.GetStoreMailbox(username, addressID, mailboxName)
if err != nil {
return nil, err
}
message, err := mailbox.GetMessage(messageID)
if err != nil {
return nil, err
}
return message.Message(), nil
return mailbox.GetMessage(messageID)
}
func hasItem(items []string, value string) bool {

View File

@ -79,14 +79,16 @@ func thereAreMessagesInMailboxesForAddressOfUser(mailboxNames, bddAddressID, bdd
if account == nil {
return godog.ErrPending
}
head := messages.Rows[0].Cells
labelIDs, err := ctx.GetPMAPIController().GetLabelIDs(account.Username(), strings.Split(mailboxNames, ","))
if err != nil {
return internalError(err, "getting labels %s for %s", mailboxNames, account.Username())
}
for _, row := range messages.Rows {
var markMessageIDsDeleted []string
head := messages.Rows[0].Cells
for _, row := range messages.Rows[1:] {
message := &pmapi.Message{
MIMEType: "text/plain",
LabelIDs: labelIDs,
@ -97,6 +99,8 @@ func thereAreMessagesInMailboxesForAddressOfUser(mailboxNames, bddAddressID, bdd
message.Flags |= pmapi.FlagSent
}
hasDeletedFlag := false
for n, cell := range row.Cells {
switch head[n].Value {
case "from":
@ -134,11 +138,7 @@ func thereAreMessagesInMailboxesForAddressOfUser(mailboxNames, bddAddressID, bdd
}
message.Time = date.Unix()
case "deleted":
if cell.Value == "true" {
/* TODO
Remember that this message should be marked as deleted
*/
}
hasDeletedFlag = cell.Value == "true"
default:
return fmt.Errorf("unexpected column name: %s", head[n].Value)
}
@ -146,13 +146,28 @@ func thereAreMessagesInMailboxesForAddressOfUser(mailboxNames, bddAddressID, bdd
if err := ctx.GetPMAPIController().AddUserMessage(account.Username(), message); err != nil {
return internalError(err, "adding message")
}
if hasDeletedFlag {
lastMessageID := ctx.GetPMAPIController().GetLastMessageID(account.Username())
markMessageIDsDeleted = append(markMessageIDsDeleted, lastMessageID)
}
}
/* TODO
storeMailbox.MarkMessageAsDeleted(msgID)
*/
if err := internalError(ctx.WaitForSync(account.Username()), "waiting for sync"); err != nil {
return err
}
return internalError(ctx.WaitForSync(account.Username()), "waiting for sync")
for _, mailboxName := range strings.Split(mailboxNames, ",") {
storeMailbox, err := ctx.GetStoreMailbox(account.Username(), account.AddressID(), mailboxName)
if err != nil {
return err
}
if err := storeMailbox.MarkMessagesDeleted(markMessageIDsDeleted); err != nil {
return err
}
}
return nil
}
func thereAreSomeMessagesInMailboxesForUser(numberOfMessages int, mailboxNames, bddUserID string) error {