test(GODT-2600): Changing state (read/unread, starred/unstarred) of a message in integration tests

This commit is contained in:
Gjorgji Slamkov
2023-06-22 05:13:53 +00:00
parent 09eef64514
commit e78cb8089b
4 changed files with 215 additions and 10 deletions

View File

@ -215,8 +215,16 @@ func TestFeatures(testingT *testing.T) {
ctx.Step(`^IMAP client "([^"]*)" marks the message with subject "([^"]*)" as deleted$`, s.imapClientMarksTheMessageWithSubjectAsDeleted) ctx.Step(`^IMAP client "([^"]*)" marks the message with subject "([^"]*)" as deleted$`, s.imapClientMarksTheMessageWithSubjectAsDeleted)
ctx.Step(`^IMAP client "([^"]*)" marks message (\d+) as not deleted$`, s.imapClientMarksMessageAsNotDeleted) ctx.Step(`^IMAP client "([^"]*)" marks message (\d+) as not deleted$`, s.imapClientMarksMessageAsNotDeleted)
ctx.Step(`^IMAP client "([^"]*)" marks all messages as deleted$`, s.imapClientMarksAllMessagesAsDeleted) ctx.Step(`^IMAP client "([^"]*)" marks all messages as deleted$`, s.imapClientMarksAllMessagesAsDeleted)
ctx.Step(`^IMAP client "([^"]*)" sees that message (\d+) has the flag "([^"]*)"$`, s.imapClientSeesThatMessageHasTheFlag)
ctx.Step(`^IMAP client "([^"]*)" expunges$`, s.imapClientExpunges) ctx.Step(`^IMAP client "([^"]*)" expunges$`, s.imapClientExpunges)
ctx.Step(`^IMAP client "([^"]*)" marks message (\d+) as "([^"]*)"$`, s.imapClientMarksMessageAsState)
ctx.Step(`^IMAP client "([^"]*)" marks the message with subject "([^"]*)" as "([^"]*)"$`, s.imapClientMarksTheMessageWithSubjectAsState)
ctx.Step(`^IMAP client "([^"]*)" marks all messages as "([^"]*)"$`, s.imapClientMarksAllMessagesAsState)
ctx.Step(`^IMAP client "([^"]*)" eventually sees that message at row (\d+) has the flag "([^"]*)"$`, s.imapClientSeesThatMessageHasTheFlag)
ctx.Step(`^IMAP client "([^"]*)" eventually sees that message at row (\d+) does not have the flag "([^"]*)"$`, s.imapClientSeesThatMessageDoesNotHaveTheFlag)
ctx.Step(`^IMAP client "([^"]*)" eventually sees that the message with subject "([^"]*)" has the flag "([^"]*)"`, s.imapClientSeesThatTheMessageWithSubjectHasTheFlag)
ctx.Step(`^IMAP client "([^"]*)" eventually sees that the message with subject "([^"]*)" does not have the flag "([^"]*)"`, s.imapClientSeesThatTheMessageWithSubjectDoesNotHaveTheFlag)
ctx.Step(`^IMAP client "([^"]*)" eventually sees that all the messages have the flag "([^"]*)"`, s.imapClientSeesThatAllTheMessagesHaveTheFlag)
ctx.Step(`^IMAP client "([^"]*)" eventually sees that all the messages do not have the flag "([^"]*)"`, s.imapClientSeesThatAllTheMessagesDoNotHaveTheFlag)
ctx.Step(`^IMAP client "([^"]*)" appends the following message to "([^"]*)":$`, s.imapClientAppendsTheFollowingMessageToMailbox) ctx.Step(`^IMAP client "([^"]*)" appends the following message to "([^"]*)":$`, s.imapClientAppendsTheFollowingMessageToMailbox)
ctx.Step(`^IMAP client "([^"]*)" appends the following messages to "([^"]*)":$`, s.imapClientAppendsTheFollowingMessagesToMailbox) ctx.Step(`^IMAP client "([^"]*)" appends the following messages to "([^"]*)":$`, s.imapClientAppendsTheFollowingMessagesToMailbox)
ctx.Step(`^IMAP client "([^"]*)" appends "([^"]*)" to "([^"]*)"$`, s.imapClientAppendsToMailbox) ctx.Step(`^IMAP client "([^"]*)" appends "([^"]*)" to "([^"]*)"$`, s.imapClientAppendsToMailbox)

View File

@ -18,7 +18,7 @@ Feature: IMAP remove messages from mailbox
When IMAP client "1" selects "Folders/mbox" When IMAP client "1" selects "Folders/mbox"
And IMAP client "1" marks message 2 as deleted And IMAP client "1" marks message 2 as deleted
And it succeeds And it succeeds
Then IMAP client "1" sees that message 2 has the flag "\Deleted" Then IMAP client "1" eventually sees that message at row 2 has the flag "\Deleted"
When IMAP client "1" expunges When IMAP client "1" expunges
And it succeeds And it succeeds
Then IMAP client "1" eventually sees 9 messages in "Folders/mbox" Then IMAP client "1" eventually sees 9 messages in "Folders/mbox"

View File

@ -0,0 +1,59 @@
Feature: IMAP change state of message in mailbox
Background:
Given there exists an account with username "[user:user]" and password "password"
And the account "[user:user]" has the following custom mailboxes:
| name | type |
| one | folder |
| two | folder |
And the address "[user:user]@[domain]" of account "[user:user]" has 5 messages in "Folders/one"
And the address "[user:user]@[domain]" of account "[user:user]" has 150 messages in "Folders/two"
And the address "[user:user]@[domain]" of account "[user:user]" has the following messages in "Inbox":
| from | to | subject | unread |
| a@example.com | b@example.com | one | true |
| c@example.com | d@example.com | two | false |
And bridge starts
And the user logs in with username "[user:user]" and password "password"
And user "[user:user]" finishes syncing
And user "[user:user]" connects and authenticates IMAP client "1"
Scenario: Mark message as read
When IMAP client "1" selects "Folders/one"
And IMAP client "1" marks message 1 as "read"
And it succeeds
Then IMAP client "1" eventually sees that message at row 1 has the flag "\Seen"
Scenario: Mark message as unread
When IMAP client "1" selects "Folders/one"
And IMAP client "1" marks message 1 as "unread"
And it succeeds
Then IMAP client "1" eventually sees that message at row 1 does not have the flag "\Seen"
Scenario: Mark message as starred
When IMAP client "1" selects "Folders/one"
And IMAP client "1" marks message 1 as "starred"
And it succeeds
Then IMAP client "1" eventually sees that message at row 1 has the flag "\Flagged"
Scenario: Mark message as unstarred
When IMAP client "1" selects "Folders/one"
And IMAP client "1" marks message 1 as "unstarred"
And it succeeds
Then IMAP client "1" eventually sees that message at row 1 does not have the flag "\Flagged"
Scenario: Mark message with subject as read/unread
When IMAP client "1" selects "Inbox"
And IMAP client "1" marks the message with subject "one" as "read"
And it succeeds
And IMAP client "1" marks the message with subject "two" as "unread"
And it succeeds
Then IMAP client "1" eventually sees that the message with subject "one" has the flag "\Seen"
And IMAP client "1" eventually sees that the message with subject "two" does not have the flag "\Seen"
Scenario: Mark all messages in folder as read/unread
When IMAP client "1" selects "Folders/two"
And IMAP client "1" marks all messages as "read"
And it succeeds
Then IMAP client "1" eventually sees that all the messages have the flag "\Seen"
When IMAP client "1" marks all messages as "unread"
And it succeeds
Then IMAP client "1" eventually sees that all the messages do not have the flag "\Seen"

View File

@ -401,25 +401,88 @@ func (s *scenario) imapClientMarksAllMessagesAsDeleted(clientID string) error {
return nil return nil
} }
func (s *scenario) imapClientSeesThatMessageHasTheFlag(clientID string, seq int, flag string) error { func (s *scenario) imapClientMarksMessageAsState(clientID string, seq int, messageState string) error {
_, client := s.t.getIMAPClient(clientID) _, client := s.t.getIMAPClient(clientID)
fetch, err := clientFetch(client, client.Mailbox().Name) err := clientChangeMessageState(client, seq, messageState, true)
if err != nil {
s.t.pushError(err)
}
return nil
}
func (s *scenario) imapClientMarksTheMessageWithSubjectAsState(clientID, subject, messageState string) error {
_, client := s.t.getIMAPClient(clientID)
uid, err := clientGetUIDBySubject(client, client.Mailbox().Name, subject)
if err != nil { if err != nil {
return err return err
} }
idx := xslices.IndexFunc(fetch, func(msg *imap.Message) bool { if err := clientChangeMessageState(client, int(uid), messageState, true); err != nil {
return msg.SeqNum == uint32(seq) s.t.pushError(err)
})
if !slices.Contains(fetch[idx].Flags, flag) {
return fmt.Errorf("expected message %v to have flag %v, got %v", seq, flag, fetch[idx].Flags)
} }
return nil return nil
} }
func (s *scenario) imapClientMarksAllMessagesAsState(clientID, messageState string) error {
_, client := s.t.getIMAPClient(clientID)
if err := clientChangeAllMessageState(client, messageState); err != nil {
s.t.pushError(err)
}
return nil
}
func (s *scenario) imapClientSeesThatMessageHasTheFlag(clientID string, seq int, flag string) error {
_, client := s.t.getIMAPClient(clientID)
return clientIsFlagApplied(client, seq, flag, true, false)
}
func (s *scenario) imapClientSeesThatMessageDoesNotHaveTheFlag(clientID string, seq int, flag string) error {
_, client := s.t.getIMAPClient(clientID)
return clientIsFlagApplied(client, seq, flag, false, false)
}
func (s *scenario) imapClientSeesThatTheMessageWithSubjectHasTheFlag(clientID, subject, flag string) error {
_, client := s.t.getIMAPClient(clientID)
uid, err := clientGetUIDBySubject(client, client.Mailbox().Name, subject)
if err != nil {
return err
}
return clientIsFlagApplied(client, int(uid), flag, true, false)
}
func (s *scenario) imapClientSeesThatTheMessageWithSubjectDoesNotHaveTheFlag(clientID, subject, flag string) error {
_, client := s.t.getIMAPClient(clientID)
uid, err := clientGetUIDBySubject(client, client.Mailbox().Name, subject)
if err != nil {
return err
}
return clientIsFlagApplied(client, int(uid), flag, false, false)
}
func (s *scenario) imapClientSeesThatAllTheMessagesHaveTheFlag(clientID string, flag string) error {
_, client := s.t.getIMAPClient(clientID)
return clientIsFlagApplied(client, 1, flag, true, true)
}
func (s *scenario) imapClientSeesThatAllTheMessagesDoNotHaveTheFlag(clientID string, flag string) error {
_, client := s.t.getIMAPClient(clientID)
return clientIsFlagApplied(client, 1, flag, false, true)
}
func (s *scenario) imapClientExpunges(clientID string) error { func (s *scenario) imapClientExpunges(clientID string) error {
_, client := s.t.getIMAPClient(clientID) _, client := s.t.getIMAPClient(clientID)
@ -767,3 +830,78 @@ func clientStore(client *client.Client, from, to int, isUID bool, item imap.Stor
func clientAppend(client *client.Client, mailbox string, literal string) error { func clientAppend(client *client.Client, mailbox string, literal string) error {
return client.Append(mailbox, []string{}, time.Now(), strings.NewReader(literal)) return client.Append(mailbox, []string{}, time.Now(), strings.NewReader(literal))
} }
func clientIsFlagApplied(client *client.Client, seq int, flag string, applied bool, wholeMailbox bool) error {
fetch, err := clientFetch(client, client.Mailbox().Name)
if err != nil {
return err
}
idx := xslices.IndexFunc(fetch, func(msg *imap.Message) bool {
return msg.SeqNum == uint32(seq)
})
if slices.Contains(fetch[idx].Flags, flag) != applied {
return fmt.Errorf("expected message %v to have flag %v set to %v, got %v", seq, flag, applied, fetch[idx].Flags)
}
if wholeMailbox {
for i := seq; i <= int(client.Mailbox().Messages); i++ {
idx := xslices.IndexFunc(fetch, func(msg *imap.Message) bool {
return msg.SeqNum == uint32(i)
})
if slices.Contains(fetch[idx].Flags, flag) != applied {
return fmt.Errorf("expected message %v to have flag %v set to %v, got %v", seq, flag, applied, fetch[idx].Flags)
}
}
}
return nil
}
func clientChangeMessageState(client *client.Client, seq int, messageState string, isUID bool) error {
switch {
case messageState == "read":
_, err := clientStore(client, seq, seq, isUID, imap.FormatFlagsOp(imap.AddFlags, true), imap.SeenFlag)
if err != nil {
return err
}
case messageState == "unread":
_, err := clientStore(client, seq, seq, isUID, imap.FormatFlagsOp(imap.RemoveFlags, true), imap.SeenFlag)
if err != nil {
return err
}
case messageState == "starred":
_, err := clientStore(client, seq, seq, isUID, imap.FormatFlagsOp(imap.AddFlags, true), imap.FlaggedFlag)
if err != nil {
return err
}
case messageState == "unstarred":
_, err := clientStore(client, seq, seq, isUID, imap.FormatFlagsOp(imap.RemoveFlags, true), imap.FlaggedFlag)
if err != nil {
return err
}
}
return nil
}
func clientChangeAllMessageState(client *client.Client, messageState string) error {
if messageState == "read" {
_, err := clientStore(client, 1, int(client.Mailbox().Messages), false, imap.FormatFlagsOp(imap.AddFlags, true), imap.SeenFlag)
if err != nil {
return err
}
} else if messageState == "unread" {
_, err := clientStore(client, 1, int(client.Mailbox().Messages), false, imap.FormatFlagsOp(imap.RemoveFlags, true), imap.SeenFlag)
if err != nil {
return err
}
}
return nil
}