GODT-1433 Adding first integration test for drafts.

This commit is contained in:
Jakub
2021-11-30 13:53:49 +01:00
parent 6ed97a0347
commit 55beb9227f
8 changed files with 89 additions and 15 deletions

View File

@ -370,7 +370,7 @@ func (storeMailbox *Mailbox) txCreateOrUpdateMessages(tx *bolt.Tx, msgs []*pmapi
// Draft bodies can change and bodies are not re-fetched by IMAP clients. // Draft bodies can change and bodies are not re-fetched by IMAP clients.
// Every change has to be a new message; we need to delete the old one and always recreate it. // Every change has to be a new message; we need to delete the old one and always recreate it.
if msg.Type == pmapi.MessageTypeDraft { if msg.Type == pmapi.MessageTypeDraft || msg.IsDraft() {
if err := storeMailbox.txDeleteMessage(tx, msg.ID); err != nil { if err := storeMailbox.txDeleteMessage(tx, msg.ID); err != nil {
return errors.Wrap(err, "cannot delete old draft") return errors.Wrap(err, "cannot delete old draft")
} }

View File

@ -27,6 +27,7 @@ func APIActionsFeatureContext(s *godog.ScenarioContext) {
s.Step(`^the internet connection is lost$`, theInternetConnectionIsLost) s.Step(`^the internet connection is lost$`, theInternetConnectionIsLost)
s.Step(`^the internet connection is restored$`, theInternetConnectionIsRestored) s.Step(`^the internet connection is restored$`, theInternetConnectionIsRestored)
s.Step(`^(\d+) second[s]? pass$`, secondsPass) s.Step(`^(\d+) second[s]? pass$`, secondsPass)
s.Step(`^the body of draft "([^"]*)" for "([^"]*)" has changed to "([^"]*)"$`, draftBodyChanged)
} }
func theInternetConnectionIsLost() error { func theInternetConnectionIsLost() error {
@ -43,3 +44,22 @@ func secondsPass(seconds int) error {
time.Sleep(time.Duration(seconds) * time.Second) time.Sleep(time.Duration(seconds) * time.Second)
return nil return nil
} }
func draftBodyChanged(bddMessageID, bddUserID, body string) error {
account := ctx.GetTestAccount(bddUserID)
if account == nil {
return godog.ErrPending
}
messageID, err := ctx.GetAPIMessageID(account.Username(), bddMessageID)
if err != nil {
return internalError(err, "getting apiID for %s", bddMessageID)
}
err = ctx.GetPMAPIController().SetDraftBody(account.Username(), messageID, body)
if err != nil {
return internalError(err, "cannot set body of %s", messageID)
}
return nil
}

View File

@ -36,6 +36,7 @@ type PMAPIController interface {
AddUserLabel(username string, label *pmapi.Label) error AddUserLabel(username string, label *pmapi.Label) error
GetLabelIDs(username string, labelNames []string) ([]string, error) GetLabelIDs(username string, labelNames []string) ([]string, error)
AddUserMessage(username string, message *pmapi.Message) (string, error) AddUserMessage(username string, message *pmapi.Message) (string, error)
SetDraftBody(username string, messageID string, body string) error
GetMessages(username, labelID string) ([]*pmapi.Message, error) GetMessages(username, labelID string) ([]*pmapi.Message, error)
ReorderAddresses(user *pmapi.User, addressIDs []string) error ReorderAddresses(user *pmapi.User, addressIDs []string) error
PrintCalls() PrintCalls()

View File

@ -157,6 +157,39 @@ func (ctl *Controller) AddUserMessage(username string, message *pmapi.Message) (
return message.ID, nil return message.ID, nil
} }
func (ctl *Controller) SetDraftBody(username string, messageID string, body string) error {
// change the body in fakeAPI
fakeUser, ok := ctl.usersByUsername[username]
if !ok {
return fmt.Errorf("user %s not found", username)
}
fakeAPI := ctl.getFakeAPIForUser(fakeUser.user.ID)
if fakeAPI == nil {
return fmt.Errorf("fakeAPI %s not found", fakeUser.user.ID)
}
message := fakeAPI.getMessage(messageID)
if message == nil {
return fmt.Errorf("fake message %s not found", messageID)
}
message.Body = body
// assuming this is draft we set following
// - Draft type (NOTE: Type is not part of pmapi.MessageEvent, but it's there on API)
// - It must not have FlagReceived and FlagSent
// - Standard labelsIDs NOTE:wrong behaviour once we will have edge case tests for drafts outside draft folder
message.Type = pmapi.MessageTypeDraft
message.Flags = pmapi.FlagE2E | pmapi.FlagInternal
message.LabelIDs = []string{pmapi.AllDraftsLabel, pmapi.AllMailLabel, pmapi.DraftLabel}
// send draft update
fakeAPI.addEventMessage(pmapi.EventUpdate, message)
return nil
}
func (ctl *Controller) getFakeAPIForUser(userID string) *FakePMAPI { func (ctl *Controller) getFakeAPIForUser(userID string) *FakePMAPI {
for _, fakeAPI := range ctl.fakeAPIs { for _, fakeAPI := range ctl.fakeAPIs {
if fakeAPI.userID == userID { if fakeAPI.userID == userID {

View File

@ -1,25 +1,18 @@
Feature: IMAP operations with Drafts Feature: IMAP operations with Drafts
Background: Background:
Given there is connected user "user" Given there is connected user "user"
And there are messages in mailbox "Drafts" for "user"
| id | from | subject | body |
| msg1 | Lionel Richie <lionel@richie.com> | RE: Hello, is it me you looking for? | Nope |
And there is IMAP client logged in as "user" And there is IMAP client logged in as "user"
And there is IMAP client selected in "Drafts" And there is IMAP client selected in "Drafts"
And IMAP client imports message to "Drafts"
"""
To: Lionel Richie <lionel@richie.com>
Subject: RE: Hello, is it me you looking for?
Nope.
"""
And IMAP response is "OK"
And API mailbox "<mailbox>" for "user" has 1 message
Scenario: Draft subject updated on locally Scenario: Draft subject updated locally
Scenario: Draft recipient updated on locally Scenario: Draft recipient updated locally
Scenario: Draft body updated on locally Scenario: Draft body updated locally
@ignore-live @ignore-live
Scenario: Draft subject updated on server side Scenario: Draft subject updated on server side
@ -29,4 +22,14 @@ Feature: IMAP operations with Drafts
@ignore-live @ignore-live
Scenario: Draft body and size updated on server side Scenario: Draft body and size updated on server side
When IMAP client fetches body of UID "1"
Then IMAP response is "OK"
Then IMAP response contains "Nope"
Given the body of draft "msg1" for "user" has changed to "Yes I am"
And the event loop of "user" loops once
And mailbox "Drafts" for "user" has 1 messages
When IMAP client fetches body of UID "2"
Then IMAP response is "OK"
Then IMAP response contains "Yes I am"
Then IMAP response does not contain "Nope"

View File

@ -34,7 +34,8 @@ func IMAPActionsMessagesFeatureContext(s *godog.ScenarioContext) {
s.Step(`^IMAP client sends command "([^"]*)"$`, imapClientSendsCommand) s.Step(`^IMAP client sends command "([^"]*)"$`, imapClientSendsCommand)
s.Step(`^IMAP client fetches "([^"]*)"$`, imapClientFetches) s.Step(`^IMAP client fetches "([^"]*)"$`, imapClientFetches)
s.Step(`^IMAP client fetches header(?:s)? of "([^"]*)"$`, imapClientFetchesHeader) s.Step(`^IMAP client fetches header(?:s)? of "([^"]*)"$`, imapClientFetchesHeader)
s.Step(`^IMAP client fetches body "([^"]*)"$`, imapClientFetchesBody) s.Step(`^IMAP client fetches bod(?:y|ies) "([^"]*)"$`, imapClientFetchesBody)
s.Step(`^IMAP client fetches bod(?:y|ies) of UID "([^"]*)"$`, imapClientFetchesUIDBody)
s.Step(`^IMAP client fetches by UID "([^"]*)"$`, imapClientFetchesByUID) s.Step(`^IMAP client fetches by UID "([^"]*)"$`, imapClientFetchesByUID)
s.Step(`^IMAP client searches for "([^"]*)"$`, imapClientSearchesFor) s.Step(`^IMAP client searches for "([^"]*)"$`, imapClientSearchesFor)
s.Step(`^IMAP client copies message seq "([^"]*)" to "([^"]*)"$`, imapClientCopiesMessagesTo) s.Step(`^IMAP client copies message seq "([^"]*)" to "([^"]*)"$`, imapClientCopiesMessagesTo)
@ -98,6 +99,12 @@ func imapClientFetchesBody(fetchRange string) error {
return nil return nil
} }
func imapClientFetchesUIDBody(fetchRange string) error {
res := ctx.GetIMAPClient("imap").FetchUID(fetchRange, "BODY.PEEK[]")
ctx.SetIMAPLastResponse("imap", res)
return nil
}
func imapClientFetchesByUID(fetchRange string) error { func imapClientFetchesByUID(fetchRange string) error {
res := ctx.GetIMAPClient("imap").FetchUID(fetchRange, "UID") res := ctx.GetIMAPClient("imap").FetchUID(fetchRange, "UID")
ctx.SetIMAPLastResponse("imap", res) ctx.SetIMAPLastResponse("imap", res)

View File

@ -73,6 +73,10 @@ func (ctl *Controller) AddUserMessage(username string, message *pmapi.Message) (
return result.MessageID, nil return result.MessageID, nil
} }
func (ctl *Controller) SetDraftBody(username string, messageID string, body string) error {
return errors.New("set draft body is not implemented for live")
}
func (ctl *Controller) GetMessages(username, labelID string) ([]*pmapi.Message, error) { func (ctl *Controller) GetMessages(username, labelID string) ([]*pmapi.Message, error) {
client, err := getPersistentClient(username) client, err := getPersistentClient(username)
if err != nil { if err != nil {

View File

@ -108,6 +108,7 @@ func thereAreMessagesInMailboxesForAddressOfUser(mailboxNames, bddAddressID, bdd
if message.HasLabelID(pmapi.SentLabel) { if message.HasLabelID(pmapi.SentLabel) {
message.Flags |= pmapi.FlagSent message.Flags |= pmapi.FlagSent
message.Type = pmapi.MessageTypeSent
} else { } else {
// some tests (Outlook move by DELETE EXPUNGE APPEND) imply creating hard copies of emails, // some tests (Outlook move by DELETE EXPUNGE APPEND) imply creating hard copies of emails,
// and the importMessage() function flags the email as Sent if the 'Received' key in not present in the // and the importMessage() function flags the email as Sent if the 'Received' key in not present in the
@ -115,6 +116,11 @@ func thereAreMessagesInMailboxesForAddressOfUser(mailboxNames, bddAddressID, bdd
header.Add("Received", "from dummy.protonmail.com") header.Add("Received", "from dummy.protonmail.com")
} }
if message.HasLabelID(pmapi.DraftLabel) {
message.Type = pmapi.MessageTypeDraft
message.Flags = pmapi.FlagInternal | pmapi.FlagE2E
}
bddMessageID := "" bddMessageID := ""
hasDeletedFlag := false hasDeletedFlag := false