GODT-1817: Restore move related feature tests
Gluon updated to latest dev commit, required for feature. Checks from move_local_folder.feature are implemented in Gluon.
This commit is contained in:
parent
d720feaa6d
commit
9390cb64b4
|
@ -132,7 +132,6 @@ Proton Mail Bridge includes the following 3rd party software:
|
||||||
gopkg.in/yaml.v2
|
gopkg.in/yaml.v2
|
||||||
gopkg.in/yaml.v3
|
gopkg.in/yaml.v3
|
||||||
* [docker-credential-helpers](https://github.com/ProtonMail/docker-credential-helpers) available under [license](https://github.com/ProtonMail/docker-credential-helpers/blob/master/LICENSE)
|
* [docker-credential-helpers](https://github.com/ProtonMail/docker-credential-helpers) available under [license](https://github.com/ProtonMail/docker-credential-helpers/blob/master/LICENSE)
|
||||||
* [go-imap](https://github.com/ProtonMail/go-imap) available under [license](https://github.com/ProtonMail/go-imap/blob/master/LICENSE)
|
|
||||||
* [go-message](https://github.com/ProtonMail/go-message) available under [license](https://github.com/ProtonMail/go-message/blob/master/LICENSE)
|
* [go-message](https://github.com/ProtonMail/go-message) available under [license](https://github.com/ProtonMail/go-message/blob/master/LICENSE)
|
||||||
* [go-keychain](https://github.com/cuthix/go-keychain) available under [license](https://github.com/cuthix/go-keychain/blob/master/LICENSE)
|
* [go-keychain](https://github.com/cuthix/go-keychain) available under [license](https://github.com/cuthix/go-keychain/blob/master/LICENSE)
|
||||||
<!-- END AUTOGEN -->
|
<!-- END AUTOGEN -->
|
||||||
|
|
3
go.mod
3
go.mod
|
@ -5,7 +5,7 @@ go 1.18
|
||||||
require (
|
require (
|
||||||
github.com/0xAX/notificator v0.0.0-20220220101646-ee9b8921e557
|
github.com/0xAX/notificator v0.0.0-20220220101646-ee9b8921e557
|
||||||
github.com/Masterminds/semver/v3 v3.1.1
|
github.com/Masterminds/semver/v3 v3.1.1
|
||||||
github.com/ProtonMail/gluon v0.14.2-0.20221220184532-b04fb948e367
|
github.com/ProtonMail/gluon v0.14.2-0.20230106095250-7e99ea4da61e
|
||||||
github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a
|
github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a
|
||||||
github.com/ProtonMail/go-proton-api v0.2.4-0.20230103140323-680d85d1c3f0
|
github.com/ProtonMail/go-proton-api v0.2.4-0.20230103140323-680d85d1c3f0
|
||||||
github.com/ProtonMail/go-rfc5322 v0.11.0
|
github.com/ProtonMail/go-rfc5322 v0.11.0
|
||||||
|
@ -120,7 +120,6 @@ require (
|
||||||
|
|
||||||
replace (
|
replace (
|
||||||
github.com/docker/docker-credential-helpers => github.com/ProtonMail/docker-credential-helpers v1.1.0
|
github.com/docker/docker-credential-helpers => github.com/ProtonMail/docker-credential-helpers v1.1.0
|
||||||
github.com/emersion/go-imap => github.com/ProtonMail/go-imap v0.0.0-20201228133358-4db68cea0cac
|
|
||||||
github.com/emersion/go-message => github.com/ProtonMail/go-message v0.0.0-20210611055058-fabeff2ec753
|
github.com/emersion/go-message => github.com/ProtonMail/go-message v0.0.0-20210611055058-fabeff2ec753
|
||||||
github.com/keybase/go-keychain => github.com/cuthix/go-keychain v0.0.0-20220405075754-31e7cee908fe
|
github.com/keybase/go-keychain => github.com/cuthix/go-keychain v0.0.0-20220405075754-31e7cee908fe
|
||||||
)
|
)
|
||||||
|
|
11
go.sum
11
go.sum
|
@ -28,16 +28,16 @@ github.com/ProtonMail/bcrypt v0.0.0-20211005172633-e235017c1baf h1:yc9daCCYUefEs
|
||||||
github.com/ProtonMail/bcrypt v0.0.0-20211005172633-e235017c1baf/go.mod h1:o0ESU9p83twszAU8LBeJKFAAMX14tISa0yk4Oo5TOqo=
|
github.com/ProtonMail/bcrypt v0.0.0-20211005172633-e235017c1baf/go.mod h1:o0ESU9p83twszAU8LBeJKFAAMX14tISa0yk4Oo5TOqo=
|
||||||
github.com/ProtonMail/docker-credential-helpers v1.1.0 h1:+kvUIpwWcbtP3WFv5sSvkFn/XLzSqPOB5AAthuk9xPk=
|
github.com/ProtonMail/docker-credential-helpers v1.1.0 h1:+kvUIpwWcbtP3WFv5sSvkFn/XLzSqPOB5AAthuk9xPk=
|
||||||
github.com/ProtonMail/docker-credential-helpers v1.1.0/go.mod h1:mK0aBveCxhnQ756AmaTfXMZDeULvheYVhF/MWMErN5g=
|
github.com/ProtonMail/docker-credential-helpers v1.1.0/go.mod h1:mK0aBveCxhnQ756AmaTfXMZDeULvheYVhF/MWMErN5g=
|
||||||
github.com/ProtonMail/gluon v0.14.2-0.20221220184532-b04fb948e367 h1:oYEXHIRCqK3RG0nErhhZ6cpqRTCZmd1QYtmHastjWB8=
|
github.com/ProtonMail/gluon v0.14.2-0.20230105101243-675bf5daf3e6 h1:pGom2w5ncRNZf8+Z3IL4DQyTCI2UK8jhb6zkQVbVrLg=
|
||||||
github.com/ProtonMail/gluon v0.14.2-0.20221220184532-b04fb948e367/go.mod h1:z2AxLIiBCT1K+0OBHyaDI7AEaO5qI6/BEC2TE42vs4Q=
|
github.com/ProtonMail/gluon v0.14.2-0.20230105101243-675bf5daf3e6/go.mod h1:z2AxLIiBCT1K+0OBHyaDI7AEaO5qI6/BEC2TE42vs4Q=
|
||||||
|
github.com/ProtonMail/gluon v0.14.2-0.20230106095250-7e99ea4da61e h1://xRNjGTAMXw2U91MtqPc4krUtxQmt2+4z1oYrBaOWU=
|
||||||
|
github.com/ProtonMail/gluon v0.14.2-0.20230106095250-7e99ea4da61e/go.mod h1:z2AxLIiBCT1K+0OBHyaDI7AEaO5qI6/BEC2TE42vs4Q=
|
||||||
github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a h1:D+aZah+k14Gn6kmL7eKxoo/4Dr/lK3ChBcwce2+SQP4=
|
github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a h1:D+aZah+k14Gn6kmL7eKxoo/4Dr/lK3ChBcwce2+SQP4=
|
||||||
github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a/go.mod h1:oTGdE7/DlWIr23G0IKW3OXK9wZ5Hw1GGiaJFccTvZi4=
|
github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a/go.mod h1:oTGdE7/DlWIr23G0IKW3OXK9wZ5Hw1GGiaJFccTvZi4=
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
|
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20220822140716-1678d6eb0cbe/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
|
github.com/ProtonMail/go-crypto v0.0.0-20220822140716-1678d6eb0cbe/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895 h1:NsReiLpErIPzRrnogAXYwSoU7txA977LjDGrbkewJbg=
|
github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895 h1:NsReiLpErIPzRrnogAXYwSoU7txA977LjDGrbkewJbg=
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
|
github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
|
||||||
github.com/ProtonMail/go-imap v0.0.0-20201228133358-4db68cea0cac h1:2xU3QncAiS/W3UlWZTkbNKW5WkLzk6Egl1T0xX+sbjs=
|
|
||||||
github.com/ProtonMail/go-imap v0.0.0-20201228133358-4db68cea0cac/go.mod h1:yKASt+C3ZiDAiCSssxg9caIckWF/JG7ZQTO7GAmvicU=
|
|
||||||
github.com/ProtonMail/go-message v0.0.0-20210611055058-fabeff2ec753 h1:I8IsYA297x0QLU80G5I6aLYUu3JYNSpo8j5fkXtFDW0=
|
github.com/ProtonMail/go-message v0.0.0-20210611055058-fabeff2ec753 h1:I8IsYA297x0QLU80G5I6aLYUu3JYNSpo8j5fkXtFDW0=
|
||||||
github.com/ProtonMail/go-message v0.0.0-20210611055058-fabeff2ec753/go.mod h1:NBAn21zgCJ/52WLDyed18YvYFm5tEoeDauubFqLokM4=
|
github.com/ProtonMail/go-message v0.0.0-20210611055058-fabeff2ec753/go.mod h1:NBAn21zgCJ/52WLDyed18YvYFm5tEoeDauubFqLokM4=
|
||||||
github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f/go.mod h1:NYt+V3/4rEeDuaev/zw1zCq8uqVEuPHzDPo3OZrlGJ4=
|
github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f/go.mod h1:NYt+V3/4rEeDuaev/zw1zCq8uqVEuPHzDPo3OZrlGJ4=
|
||||||
|
@ -122,9 +122,10 @@ github.com/elastic/go-sysinfo v1.8.1 h1:4Yhj+HdV6WjbCRgGdZpPJ8lZQlXZLKDAeIkmQ/VR
|
||||||
github.com/elastic/go-sysinfo v1.8.1/go.mod h1:JfllUnzoQV/JRYymbH3dO1yggI3mV2oTKSXsDHM+uIM=
|
github.com/elastic/go-sysinfo v1.8.1/go.mod h1:JfllUnzoQV/JRYymbH3dO1yggI3mV2oTKSXsDHM+uIM=
|
||||||
github.com/elastic/go-windows v1.0.1 h1:AlYZOldA+UJ0/2nBuqWdo90GFCgG9xuyw9SYzGUtJm0=
|
github.com/elastic/go-windows v1.0.1 h1:AlYZOldA+UJ0/2nBuqWdo90GFCgG9xuyw9SYzGUtJm0=
|
||||||
github.com/elastic/go-windows v1.0.1/go.mod h1:FoVvqWSun28vaDQPbj2Elfc0JahhPB7WQEGa3c814Ss=
|
github.com/elastic/go-windows v1.0.1/go.mod h1:FoVvqWSun28vaDQPbj2Elfc0JahhPB7WQEGa3c814Ss=
|
||||||
|
github.com/emersion/go-imap v1.2.1-0.20220429085312-746087b7a317 h1:i0cBrdFLm8A/3hWEjn/BwdXLBplFJoZtu63p7bjrmaI=
|
||||||
|
github.com/emersion/go-imap v1.2.1-0.20220429085312-746087b7a317/go.mod h1:Qlx1FSx2FTxjnjWpIlVNEuX+ylerZQNFE5NsmKFSejY=
|
||||||
github.com/emersion/go-imap-id v0.0.0-20190926060100-f94a56b9ecde h1:43mBoVwooyLm1+1YVf5nvn1pSFWhw7rOpcrp1Jg/qk0=
|
github.com/emersion/go-imap-id v0.0.0-20190926060100-f94a56b9ecde h1:43mBoVwooyLm1+1YVf5nvn1pSFWhw7rOpcrp1Jg/qk0=
|
||||||
github.com/emersion/go-imap-id v0.0.0-20190926060100-f94a56b9ecde/go.mod h1:sPwp0FFboaK/bxsrUz1lNrDMUCsZUsKC5YuM4uRVRVs=
|
github.com/emersion/go-imap-id v0.0.0-20190926060100-f94a56b9ecde/go.mod h1:sPwp0FFboaK/bxsrUz1lNrDMUCsZUsKC5YuM4uRVRVs=
|
||||||
github.com/emersion/go-sasl v0.0.0-20191210011802-430746ea8b9b/go.mod h1:G/dpzLu16WtQpBfQ/z3LYiYJn3ZhKSGWn83fyoyQe/k=
|
|
||||||
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
|
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
|
||||||
github.com/emersion/go-sasl v0.0.0-20220912192320-0145f2c60ead h1:fI1Jck0vUrXT8bnphprS1EoVRe2Q5CKCX8iDlpqjQ/Y=
|
github.com/emersion/go-sasl v0.0.0-20220912192320-0145f2c60ead h1:fI1Jck0vUrXT8bnphprS1EoVRe2Q5CKCX8iDlpqjQ/Y=
|
||||||
github.com/emersion/go-sasl v0.0.0-20220912192320-0145f2c60ead/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
|
github.com/emersion/go-sasl v0.0.0-20220912192320-0145f2c60ead/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
|
||||||
|
|
|
@ -112,16 +112,20 @@ func (conn *imapConnector) createLabel(ctx context.Context, name []string) (imap
|
||||||
return imap.Mailbox{}, fmt.Errorf("a label cannot have children")
|
return imap.Mailbox{}, fmt.Errorf("a label cannot have children")
|
||||||
}
|
}
|
||||||
|
|
||||||
label, err := conn.client.CreateLabel(ctx, proton.CreateLabelReq{
|
return safe.LockRetErr(func() (imap.Mailbox, error) {
|
||||||
Name: name[0],
|
label, err := conn.client.CreateLabel(ctx, proton.CreateLabelReq{
|
||||||
Color: "#f66",
|
Name: name[0],
|
||||||
Type: proton.LabelTypeLabel,
|
Color: "#f66",
|
||||||
})
|
Type: proton.LabelTypeLabel,
|
||||||
if err != nil {
|
})
|
||||||
return imap.Mailbox{}, err
|
if err != nil {
|
||||||
}
|
return imap.Mailbox{}, err
|
||||||
|
}
|
||||||
|
|
||||||
return toIMAPMailbox(label, conn.flags, conn.permFlags, conn.attrs), nil
|
conn.apiLabels[label.ID] = label
|
||||||
|
|
||||||
|
return toIMAPMailbox(label, conn.flags, conn.permFlags, conn.attrs), nil
|
||||||
|
}, conn.apiLabelsLock)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (conn *imapConnector) createFolder(ctx context.Context, name []string) (imap.Mailbox, error) {
|
func (conn *imapConnector) createFolder(ctx context.Context, name []string) (imap.Mailbox, error) {
|
||||||
|
@ -368,18 +372,42 @@ func (conn *imapConnector) RemoveMessagesFromMailbox(ctx context.Context, messag
|
||||||
}
|
}
|
||||||
|
|
||||||
// MoveMessages removes the given messages from one label and adds them to the other label.
|
// MoveMessages removes the given messages from one label and adds them to the other label.
|
||||||
func (conn *imapConnector) MoveMessages(ctx context.Context, messageIDs []imap.MessageID, labelFromID imap.MailboxID, labelToID imap.MailboxID) error {
|
func (conn *imapConnector) MoveMessages(ctx context.Context, messageIDs []imap.MessageID, labelFromID imap.MailboxID, labelToID imap.MailboxID) (bool, error) {
|
||||||
defer conn.goPollAPIEvents(false)
|
defer conn.goPollAPIEvents(false)
|
||||||
|
|
||||||
|
if (labelFromID == proton.InboxLabel && labelToID == proton.SentLabel) ||
|
||||||
|
(labelFromID == proton.SentLabel && labelToID == proton.InboxLabel) {
|
||||||
|
return false, fmt.Errorf("not allowed")
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldExpungeOldLocation := func() bool {
|
||||||
|
conn.apiLabelsLock.RLock()
|
||||||
|
defer conn.apiLabelsLock.RUnlock()
|
||||||
|
|
||||||
|
var result bool
|
||||||
|
|
||||||
|
if v, ok := conn.apiLabels[string(labelFromID)]; ok && v.Type == proton.LabelTypeLabel {
|
||||||
|
result = result || true
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, ok := conn.apiLabels[string(labelToID)]; ok && v.Type == proton.LabelTypeFolder {
|
||||||
|
result = result || true
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}()
|
||||||
|
|
||||||
if err := conn.client.LabelMessages(ctx, mapTo[imap.MessageID, string](messageIDs), string(labelToID)); err != nil {
|
if err := conn.client.LabelMessages(ctx, mapTo[imap.MessageID, string](messageIDs), string(labelToID)); err != nil {
|
||||||
return fmt.Errorf("labeling messages: %w", err)
|
return false, fmt.Errorf("labeling messages: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := conn.client.UnlabelMessages(ctx, mapTo[imap.MessageID, string](messageIDs), string(labelFromID)); err != nil {
|
if shouldExpungeOldLocation {
|
||||||
return fmt.Errorf("unlabeling messages: %w", err)
|
if err := conn.client.UnlabelMessages(ctx, mapTo[imap.MessageID, string](messageIDs), string(labelFromID)); err != nil {
|
||||||
|
return false, fmt.Errorf("unlabeling messages: %w", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return shouldExpungeOldLocation, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarkMessagesSeen sets the seen value of the given messages.
|
// MarkMessagesSeen sets the seen value of the given messages.
|
||||||
|
|
|
@ -1,98 +0,0 @@
|
||||||
Feature: IMAP move messages
|
|
||||||
Background:
|
|
||||||
Given there is connected user "user"
|
|
||||||
And there is "user" with mailbox "Folders/folder"
|
|
||||||
And there is "user" with mailbox "Labels/label"
|
|
||||||
And there is "user" with mailbox "Labels/label2"
|
|
||||||
And there are messages in mailbox "INBOX" 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 are messages in mailbox "Sent" for "user"
|
|
||||||
| from | to | subject | body |
|
|
||||||
| john.doe@mail.com | user@pm.me | response | hello |
|
|
||||||
And there are messages in mailbox "Labels/label2" for "user"
|
|
||||||
| from | to | subject | body |
|
|
||||||
| john.doe@mail.com | user@pm.me | baz | hello |
|
|
||||||
And there is IMAP client logged in as "user"
|
|
||||||
|
|
||||||
Scenario: Move message from inbox (folder) to folder
|
|
||||||
Given there is IMAP client selected in "INBOX"
|
|
||||||
When IMAP client moves message seq "1" to "Folders/folder"
|
|
||||||
Then IMAP response is "OK"
|
|
||||||
And mailbox "INBOX" for "user" has messages
|
|
||||||
| from | to | subject |
|
|
||||||
| jane.doe@mail.com | name@pm.me | bar |
|
|
||||||
And mailbox "Folders/folder" for "user" has messages
|
|
||||||
| from | to | subject |
|
|
||||||
| john.doe@mail.com | user@pm.me | foo |
|
|
||||||
And API endpoint "PUT /mail/v4/messages/label" is called
|
|
||||||
And API endpoint "PUT /mail/v4/messages/unlabel" is not called
|
|
||||||
|
|
||||||
Scenario: Move all messages from inbox to folder
|
|
||||||
Given there is IMAP client selected in "INBOX"
|
|
||||||
When IMAP client moves message seq "1:*" to "Folders/folder"
|
|
||||||
Then IMAP response is "OK"
|
|
||||||
And mailbox "INBOX" for "user" has 0 messages
|
|
||||||
And mailbox "Folders/folder" for "user" has messages
|
|
||||||
| from | to | subject |
|
|
||||||
| john.doe@mail.com | user@pm.me | foo |
|
|
||||||
| jane.doe@mail.com | name@pm.me | bar |
|
|
||||||
And API endpoint "PUT /mail/v4/messages/label" is called
|
|
||||||
And API endpoint "PUT /mail/v4/messages/unlabel" is not called
|
|
||||||
|
|
||||||
Scenario: Move message from folder to label (keeps in folder)
|
|
||||||
Given there is IMAP client selected in "INBOX"
|
|
||||||
When IMAP client moves message seq "1" to "Labels/label"
|
|
||||||
Then IMAP response is "OK"
|
|
||||||
And mailbox "INBOX" for "user" has messages
|
|
||||||
| from | to | subject |
|
|
||||||
| john.doe@mail.com | user@pm.me | foo |
|
|
||||||
| jane.doe@mail.com | name@pm.me | bar |
|
|
||||||
And mailbox "Labels/label" for "user" has messages
|
|
||||||
| from | to | subject |
|
|
||||||
| john.doe@mail.com | user@pm.me | foo |
|
|
||||||
And API endpoint "PUT /mail/v4/messages/label" is called
|
|
||||||
And API endpoint "PUT /mail/v4/messages/unlabel" is not called
|
|
||||||
|
|
||||||
Scenario: Move message from label to folder
|
|
||||||
Given there is IMAP client selected in "Labels/label2"
|
|
||||||
When IMAP client moves message seq "1" to "Folders/folder"
|
|
||||||
Then IMAP response is "OK"
|
|
||||||
And mailbox "Labels/label2" for "user" has 0 messages
|
|
||||||
And mailbox "Folders/folder" for "user" has messages
|
|
||||||
| from | to | subject |
|
|
||||||
| john.doe@mail.com | user@pm.me | baz |
|
|
||||||
And API endpoint "PUT /mail/v4/messages/label" is called
|
|
||||||
And API endpoint "PUT /mail/v4/messages/unlabel" is called
|
|
||||||
|
|
||||||
Scenario: Move message from label to label
|
|
||||||
Given there is IMAP client selected in "Labels/label2"
|
|
||||||
When IMAP client moves message seq "1" to "Labels/label"
|
|
||||||
Then IMAP response is "OK"
|
|
||||||
And mailbox "Labels/label2" for "user" has 0 messages
|
|
||||||
And mailbox "Labels/label" for "user" has messages
|
|
||||||
| from | to | subject |
|
|
||||||
| john.doe@mail.com | user@pm.me | baz |
|
|
||||||
And API endpoint "PUT /mail/v4/messages/label" is called
|
|
||||||
And API endpoint "PUT /mail/v4/messages/unlabel" is called
|
|
||||||
|
|
||||||
Scenario: Move message from All Mail is not possible
|
|
||||||
Given there is IMAP client selected in "All Mail"
|
|
||||||
When IMAP client moves message seq "1" to "Folders/folder"
|
|
||||||
Then IMAP response is "NO move from All Mail is not allowed"
|
|
||||||
And mailbox "All Mail" for "user" has messages
|
|
||||||
| from | to | subject |
|
|
||||||
| john.doe@mail.com | user@pm.me | foo |
|
|
||||||
| jane.doe@mail.com | name@pm.me | bar |
|
|
||||||
And mailbox "Folders/folder" for "user" has 0 messages
|
|
||||||
|
|
||||||
Scenario: Move message from Inbox to Sent is not possible
|
|
||||||
Given there is IMAP client selected in "INBOX"
|
|
||||||
When IMAP client moves message seq "1" to "Sent"
|
|
||||||
Then IMAP response is "move from Inbox to Sent is not allowed"
|
|
||||||
|
|
||||||
Scenario: Move message from Sent to Inbox is not possible
|
|
||||||
Given there is IMAP client selected in "Sent"
|
|
||||||
When IMAP client moves message seq "1" to "INBOX"
|
|
||||||
Then IMAP response is "move from Sent to Inbox is not allowed"
|
|
|
@ -1,80 +0,0 @@
|
||||||
# IMAP clients can move message to local folder (setting \Deleted flag)
|
|
||||||
# and then move it back (IMAP client does not remember the message,
|
|
||||||
# so instead removing the flag it imports duplicate message).
|
|
||||||
# Regular IMAP server would keep the message twice and later EXPUNGE would
|
|
||||||
# not delete the message (EXPUNGE would delete the original message and
|
|
||||||
# the new duplicate one would stay). Both Bridge and API detects duplicates;
|
|
||||||
# therefore we need to remove \Deleted flag if IMAP client re-imports.
|
|
||||||
Feature: IMAP move message out to and back from local folder
|
|
||||||
Background:
|
|
||||||
Given there is connected user "user"
|
|
||||||
Given there is IMAP client logged in as "user"
|
|
||||||
And there is IMAP client selected in "INBOX"
|
|
||||||
|
|
||||||
Scenario: Mark message as deleted and re-append again
|
|
||||||
When IMAP client imports message to "INBOX"
|
|
||||||
"""
|
|
||||||
From: <john.doe@mail.com>
|
|
||||||
To: <user@pm.me>
|
|
||||||
Subject: foo
|
|
||||||
Date: Mon, 02 Jan 2006 15:04:05 +0000
|
|
||||||
Message-Id: <msgID>
|
|
||||||
Received: by 2002:0:0:0:0:0:0:0 with SMTP id 0123456789abcdef; Wed, 30 Dec 2020 01:23:45 0000
|
|
||||||
|
|
||||||
hello
|
|
||||||
"""
|
|
||||||
Then IMAP response is "OK"
|
|
||||||
When IMAP client marks message seq "1" as deleted
|
|
||||||
Then IMAP response is "OK"
|
|
||||||
When IMAP client imports message to "INBOX"
|
|
||||||
"""
|
|
||||||
From: <john.doe@mail.com>
|
|
||||||
To: <user@pm.me>
|
|
||||||
Subject: foo
|
|
||||||
Date: Mon, 02 Jan 2006 15:04:05 +0000
|
|
||||||
Message-Id: <msgID>
|
|
||||||
Received: by 2002:0:0:0:0:0:0:0 with SMTP id 0123456789abcdef; Wed, 30 Dec 2020 01:23:45 0000
|
|
||||||
|
|
||||||
hello
|
|
||||||
"""
|
|
||||||
Then IMAP response is "OK"
|
|
||||||
And mailbox "INBOX" for "user" has 1 message
|
|
||||||
And mailbox "INBOX" for "user" has messages
|
|
||||||
| from | to | subject | deleted |
|
|
||||||
| john.doe@mail.com | user@pm.me | foo | false |
|
|
||||||
|
|
||||||
# We cannot control ID generation on API.
|
|
||||||
@ignore-live
|
|
||||||
Scenario: Mark internal message as deleted and re-append again
|
|
||||||
# Each message has different subject so if the ID generations on fake API
|
|
||||||
# changes, test will fail because not even external ID mechanism will work.
|
|
||||||
When IMAP client imports message to "INBOX"
|
|
||||||
"""
|
|
||||||
From: <john.doe@mail.com>
|
|
||||||
To: <user@pm.me>
|
|
||||||
Subject: foo
|
|
||||||
Date: Mon, 02 Jan 2006 15:04:05 +0000
|
|
||||||
Received: by 2002:0:0:0:0:0:0:0 with SMTP id 0123456789abcdef; Wed, 30 Dec 2020 01:23:45 0000
|
|
||||||
|
|
||||||
hello
|
|
||||||
"""
|
|
||||||
Then IMAP response is "OK"
|
|
||||||
When IMAP client marks message seq "1" as deleted
|
|
||||||
Then IMAP response is "OK"
|
|
||||||
# Fake API generates for the first message simple ID 1.
|
|
||||||
When IMAP client imports message to "INBOX"
|
|
||||||
"""
|
|
||||||
From: <john.doe@mail.com>
|
|
||||||
To: <user@pm.me>
|
|
||||||
Subject: bar
|
|
||||||
Date: Mon, 02 Jan 2006 15:04:05 +0000
|
|
||||||
X-Pm-Internal-Id: 1
|
|
||||||
Received: by 2002:0:0:0:0:0:0:0 with SMTP id 0123456789abcdef; Wed, 30 Dec 2020 01:23:45 0000
|
|
||||||
|
|
||||||
hello
|
|
||||||
"""
|
|
||||||
Then IMAP response is "OK"
|
|
||||||
And mailbox "INBOX" for "user" has 1 message
|
|
||||||
And mailbox "INBOX" for "user" has messages
|
|
||||||
| from | to | subject | deleted |
|
|
||||||
| john.doe@mail.com | user@pm.me | foo | false |
|
|
|
@ -1,77 +0,0 @@
|
||||||
Feature: IMAP move messages by append and delete (without MOVE support, e.g., Outlook)
|
|
||||||
Background:
|
|
||||||
Given there is connected user "user"
|
|
||||||
And there is "user" with mailbox "Folders/mbox"
|
|
||||||
And there is IMAP client "source" logged in as "user"
|
|
||||||
And there is IMAP client "target" logged in as "user"
|
|
||||||
|
|
||||||
Scenario Outline: Move message from <srcMailbox> to <dstMailbox> by <order>
|
|
||||||
Given there are messages in mailbox "<srcMailbox>" for "user"
|
|
||||||
| id | from | to | subject | body |
|
|
||||||
| 1 | sndr1@pm.me | rcvr1@pm.me | subj1 | body1 |
|
|
||||||
| 2 | sndr2@pm.me | rcvr2@pm.me | subj2 | body2 |
|
|
||||||
And there is IMAP client "source" selected in "<srcMailbox>"
|
|
||||||
And there is IMAP client "target" selected in "<dstMailbox>"
|
|
||||||
When IMAP clients "source" and "target" move message seq "2" of "user" to "<dstMailbox>" by <order>
|
|
||||||
Then IMAP response to "source" is "OK"
|
|
||||||
Then IMAP response to "target" is "OK"
|
|
||||||
And mailbox "<dstMailbox>" for "user" has 1 messages
|
|
||||||
And mailbox "<dstMailbox>" for "user" has messages
|
|
||||||
| from | to | subject |
|
|
||||||
| sndr2@pm.me | rcvr2@pm.me | subj2 |
|
|
||||||
And mailbox "<srcMailbox>" for "user" has 1 messages
|
|
||||||
And mailbox "<srcMailbox>" for "user" has messages
|
|
||||||
| from | to | subject |
|
|
||||||
| sndr1@pm.me | rcvr1@pm.me | subj1 |
|
|
||||||
Examples:
|
|
||||||
| srcMailbox | dstMailbox | order |
|
|
||||||
| Trash | INBOX | APPEND DELETE EXPUNGE |
|
|
||||||
| Spam | INBOX | APPEND DELETE EXPUNGE |
|
|
||||||
| INBOX | Archive | APPEND DELETE EXPUNGE |
|
|
||||||
| INBOX | Folders/mbox | APPEND DELETE EXPUNGE |
|
|
||||||
| INBOX | Spam | APPEND DELETE EXPUNGE |
|
|
||||||
| INBOX | Trash | APPEND DELETE EXPUNGE |
|
|
||||||
| Trash | INBOX | DELETE APPEND EXPUNGE |
|
|
||||||
| Spam | INBOX | DELETE APPEND EXPUNGE |
|
|
||||||
| INBOX | Archive | DELETE APPEND EXPUNGE |
|
|
||||||
| INBOX | Folders/mbox | DELETE APPEND EXPUNGE |
|
|
||||||
| INBOX | Spam | DELETE APPEND EXPUNGE |
|
|
||||||
| INBOX | Trash | DELETE APPEND EXPUNGE |
|
|
||||||
| Trash | INBOX | DELETE EXPUNGE APPEND |
|
|
||||||
| Spam | INBOX | DELETE EXPUNGE APPEND |
|
|
||||||
| INBOX | Archive | DELETE EXPUNGE APPEND |
|
|
||||||
| INBOX | Folders/mbox | DELETE EXPUNGE APPEND |
|
|
||||||
| INBOX | Spam | DELETE EXPUNGE APPEND |
|
|
||||||
| INBOX | Trash | DELETE EXPUNGE APPEND |
|
|
||||||
|
|
||||||
Scenario Outline: Move message from <mailbox> to All Mail by <order>
|
|
||||||
Given there are messages in mailbox "<mailbox>" for "user"
|
|
||||||
| id | from | to | subject | body |
|
|
||||||
| 1 | john.doe@mail.com | user@pm.me | subj1 | body1 |
|
|
||||||
| 2 | john.doe@mail.com | name@pm.me | subj2 | body2 |
|
|
||||||
And there is IMAP client "source" selected in "<mailbox>"
|
|
||||||
And there is IMAP client "target" selected in "All Mail"
|
|
||||||
When IMAP clients "source" and "target" move message seq "2" of "user" to "All Mail" by <order>
|
|
||||||
Then IMAP response to "source" is "OK"
|
|
||||||
Then IMAP response to "target" is "OK"
|
|
||||||
And mailbox "<mailbox>" for "user" has messages
|
|
||||||
| from | to | subject |
|
|
||||||
| john.doe@mail.com | user@pm.me | subj1 |
|
|
||||||
And mailbox "All Mail" for "user" has messages
|
|
||||||
| from | to | subject |
|
|
||||||
| john.doe@mail.com | user@pm.me | subj1 |
|
|
||||||
| john.doe@mail.com | name@pm.me | subj2 |
|
|
||||||
Examples:
|
|
||||||
| mailbox | order |
|
|
||||||
| INBOX | APPEND DELETE EXPUNGE |
|
|
||||||
| Archive | APPEND DELETE EXPUNGE |
|
|
||||||
| Trash | APPEND DELETE EXPUNGE |
|
|
||||||
| Spam | APPEND DELETE EXPUNGE |
|
|
||||||
| INBOX | DELETE APPEND EXPUNGE |
|
|
||||||
| Archive | DELETE APPEND EXPUNGE |
|
|
||||||
| Trash | DELETE APPEND EXPUNGE |
|
|
||||||
| Spam | DELETE APPEND EXPUNGE |
|
|
||||||
| INBOX | DELETE EXPUNGE APPEND |
|
|
||||||
| Archive | DELETE EXPUNGE APPEND |
|
|
||||||
| Trash | DELETE EXPUNGE APPEND |
|
|
||||||
| Spam | DELETE EXPUNGE APPEND |
|
|
|
@ -188,6 +188,8 @@ func TestFeatures(testingT *testing.T) {
|
||||||
ctx.Step(`^IMAP client "([^"]*)" selects "([^"]*)"$`, s.imapClientSelectsMailbox)
|
ctx.Step(`^IMAP client "([^"]*)" selects "([^"]*)"$`, s.imapClientSelectsMailbox)
|
||||||
ctx.Step(`^IMAP client "([^"]*)" copies the message with subject "([^"]*)" from "([^"]*)" to "([^"]*)"$`, s.imapClientCopiesTheMessageWithSubjectFromTo)
|
ctx.Step(`^IMAP client "([^"]*)" copies the message with subject "([^"]*)" from "([^"]*)" to "([^"]*)"$`, s.imapClientCopiesTheMessageWithSubjectFromTo)
|
||||||
ctx.Step(`^IMAP client "([^"]*)" copies all messages from "([^"]*)" to "([^"]*)"$`, s.imapClientCopiesAllMessagesFromTo)
|
ctx.Step(`^IMAP client "([^"]*)" copies all messages from "([^"]*)" to "([^"]*)"$`, s.imapClientCopiesAllMessagesFromTo)
|
||||||
|
ctx.Step(`^IMAP client "([^"]*)" moves the message with subject "([^"]*)" from "([^"]*)" to "([^"]*)"$`, s.imapClientMovesTheMessageWithSubjectFromTo)
|
||||||
|
ctx.Step(`^IMAP client "([^"]*)" moves all messages from "([^"]*)" to "([^"]*)"$`, s.imapClientMovesAllMessagesFromTo)
|
||||||
ctx.Step(`^IMAP client "([^"]*)" sees the following messages in "([^"]*)":$`, s.imapClientSeesTheFollowingMessagesInMailbox)
|
ctx.Step(`^IMAP client "([^"]*)" sees the following messages in "([^"]*)":$`, s.imapClientSeesTheFollowingMessagesInMailbox)
|
||||||
ctx.Step(`^IMAP client "([^"]*)" eventually sees the following messages in "([^"]*)":$`, s.imapClientEventuallySeesTheFollowingMessagesInMailbox)
|
ctx.Step(`^IMAP client "([^"]*)" eventually sees the following messages in "([^"]*)":$`, s.imapClientEventuallySeesTheFollowingMessagesInMailbox)
|
||||||
ctx.Step(`^IMAP client "([^"]*)" sees (\d+) messages in "([^"]*)"$`, s.imapClientSeesMessagesInMailbox)
|
ctx.Step(`^IMAP client "([^"]*)" sees (\d+) messages in "([^"]*)"$`, s.imapClientSeesMessagesInMailbox)
|
||||||
|
@ -201,7 +203,7 @@ func TestFeatures(testingT *testing.T) {
|
||||||
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)
|
||||||
ctx.Step(`^IMAP clients "([^"]*)" and "([^"]*)" move message seq "([^"]*)" of "([^"]*)" to "([^"]*)" by ([^"]*) ([^"]*) ([^"]*)`, s.imapClientsMoveMessageSeqOfUserFromToByOrderedOperations)
|
ctx.Step(`^IMAP clients "([^"]*)" and "([^"]*)" move message with subject "([^"]*)" of "([^"]*)" to "([^"]*)" by ([^"]*) ([^"]*) ([^"]*)`, s.imapClientsMoveMessageWithSubjectUserFromToByOrderedOperations)
|
||||||
ctx.Step(`^IMAP client "([^"]*)" sees header "([^"]*)" in message with subject "([^"]*)" in "([^"]*)"$`, s.imapClientSeesHeaderInMessageWithSubject)
|
ctx.Step(`^IMAP client "([^"]*)" sees header "([^"]*)" in message with subject "([^"]*)" in "([^"]*)"$`, s.imapClientSeesHeaderInMessageWithSubject)
|
||||||
|
|
||||||
// ==== SMTP ====
|
// ==== SMTP ====
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
Feature: IMAP move messages
|
||||||
|
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 |
|
||||||
|
| mbox | folder |
|
||||||
|
| label | label |
|
||||||
|
| label2 | label |
|
||||||
|
And the address "[user:user]@[domain]" of account "[user:user]" has the following messages in "Inbox":
|
||||||
|
| from | to | subject | unread |
|
||||||
|
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
||||||
|
| jane.doe@mail.com | name@[domain] | bar | true |
|
||||||
|
And the address "[user:user]@[domain]" of account "[user:user]" has the following messages in "Labels/label2":
|
||||||
|
| from | to | subject | unread |
|
||||||
|
| john.doe@mail.com | [user:user]@[domain] | baz | false |
|
||||||
|
And the address "[user:user]@[domain]" of account "[user:user]" has the following messages in "Sent":
|
||||||
|
| from | to | subject | unread |
|
||||||
|
| john.doe@mail.com | [user:user]@[domain] | bax | 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: Move message from folder to label (keeps in folder)
|
||||||
|
When IMAP client "1" moves the message with subject "foo" from "INBOX" to "Labels/label"
|
||||||
|
And it succeeds
|
||||||
|
And IMAP client "1" sees the following messages in "INBOX":
|
||||||
|
| from | to | subject | unread |
|
||||||
|
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
||||||
|
| jane.doe@mail.com | name@[domain] | bar | true |
|
||||||
|
And IMAP client "1" sees the following messages in "Labels/label":
|
||||||
|
| from | to | subject | unread |
|
||||||
|
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
||||||
|
|
||||||
|
# This test covers a limitation of Gluon where we are not able to ensure the messages moved to a label via append
|
||||||
|
# expunge are preserved in the original folder.
|
||||||
|
Scenario: Move message from folder to label with append expunge does not keep message in origin folder
|
||||||
|
When user "[user:user]" connects and authenticates IMAP client "source"
|
||||||
|
And user "[user:user]" connects and authenticates IMAP client "target"
|
||||||
|
And IMAP client "source" selects "INBOX"
|
||||||
|
And IMAP client "target" selects "Labels/label"
|
||||||
|
And IMAP clients "source" and "target" move message with subject "foo" of "[user:user]" to "Labels/label" by APPEND DELETE EXPUNGE
|
||||||
|
And it succeeds
|
||||||
|
Then IMAP client "source" sees the following messages in "INBOX":
|
||||||
|
| from | to | subject | unread |
|
||||||
|
| jane.doe@mail.com | name@[domain] | bar | true |
|
||||||
|
And IMAP client "target" sees the following messages in "Labels/label":
|
||||||
|
| from | to | subject | unread |
|
||||||
|
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
||||||
|
|
||||||
|
Scenario: Move message from label to folder
|
||||||
|
When IMAP client "1" moves the message with subject "baz" from "Labels/label2" to "Folders/mbox"
|
||||||
|
And it succeeds
|
||||||
|
And IMAP client "1" sees the following messages in "Folders/mbox":
|
||||||
|
| from | to | subject | unread |
|
||||||
|
| john.doe@mail.com | [user:user]@[domain] | baz | false |
|
||||||
|
And IMAP client "1" sees 0 messages in "Labels/label2"
|
||||||
|
|
||||||
|
Scenario: Move message from label to label
|
||||||
|
When IMAP client "1" moves the message with subject "baz" from "Labels/label2" to "Labels/label"
|
||||||
|
And it succeeds
|
||||||
|
And IMAP client "1" sees the following messages in "Labels/label":
|
||||||
|
| from | to | subject | unread |
|
||||||
|
| john.doe@mail.com | [user:user]@[domain] | baz | false |
|
||||||
|
And IMAP client "1" sees 0 messages in "Labels/label2"
|
||||||
|
|
||||||
|
Scenario: Move message from All Mail is not possible
|
||||||
|
When IMAP client "1" moves the message with subject "baz" from "All Mail" to "Folders/folder"
|
||||||
|
Then it fails
|
||||||
|
And IMAP client "1" sees the following messages in "All Mail":
|
||||||
|
| from | to | subject | unread |
|
||||||
|
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
||||||
|
| jane.doe@mail.com | name@[domain] | bar | true |
|
||||||
|
| john.doe@mail.com | [user:user]@[domain] | baz | false |
|
||||||
|
| john.doe@mail.com | [user:user]@[domain] | bax | false |
|
||||||
|
|
||||||
|
Scenario: Move message from Inbox to Sent is not possible
|
||||||
|
Given test skips reporter checks
|
||||||
|
When IMAP client "1" moves the message with subject "bar" from "Inbox" to "Sent"
|
||||||
|
Then it fails
|
||||||
|
|
||||||
|
Scenario: Move message from Sent to Inbox is not possible
|
||||||
|
Given test skips reporter checks
|
||||||
|
When IMAP client "1" moves the message with subject "bax" from "Sent" to "Inbox"
|
||||||
|
Then it fails
|
|
@ -33,13 +33,13 @@ Feature: IMAP move messages by append and delete (without MOVE support, e.g., Ou
|
||||||
Then it succeeds
|
Then it succeeds
|
||||||
And IMAP client "source" selects "<srcMailbox>"
|
And IMAP client "source" selects "<srcMailbox>"
|
||||||
And IMAP client "target" selects "<dstMailbox>"
|
And IMAP client "target" selects "<dstMailbox>"
|
||||||
When IMAP clients "source" and "target" move message seq "2" of "[user:user]" to "<dstMailbox>" by <order>
|
When IMAP clients "source" and "target" move message with subject "subj2" of "[user:user]" to "<dstMailbox>" by <order>
|
||||||
And IMAP client "source" sees 1 messages in "<srcMailbox>"
|
And IMAP client "source" sees 1 messages in "<srcMailbox>"
|
||||||
And IMAP client "source" sees the following messages in "<srcMailbox>":
|
And IMAP client "source" sees the following messages in "<srcMailbox>":
|
||||||
| from | to | subject |
|
| from | to | subject |
|
||||||
| sndr1@[domain] | rcvr1@[domain] | subj1 |
|
| sndr1@[domain] | rcvr1@[domain] | subj1 |
|
||||||
And IMAP client "target" sees 1 messages in "<dstMailbox>"
|
And IMAP client "target" eventually sees 1 messages in "<dstMailbox>"
|
||||||
And IMAP client "target" sees the following messages in "<dstMailbox>":
|
And IMAP client "target" eventually sees the following messages in "<dstMailbox>":
|
||||||
| from | to | subject |
|
| from | to | subject |
|
||||||
| sndr2@[domain] | rcvr2@[domain] | subj2 |
|
| sndr2@[domain] | rcvr2@[domain] | subj2 |
|
||||||
Examples:
|
Examples:
|
||||||
|
|
|
@ -23,7 +23,6 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -288,6 +287,31 @@ func (s *scenario) imapClientSeesTheFollowingMessagesInMailbox(clientID, mailbox
|
||||||
return matchMessages(haveMessages, wantMessages)
|
return matchMessages(haveMessages, wantMessages)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *scenario) imapClientMovesTheMessageWithSubjectFromTo(clientID, subject, from, to string) error {
|
||||||
|
_, client := s.t.getIMAPClient(clientID)
|
||||||
|
|
||||||
|
uid, err := clientGetUIDBySubject(client, from, subject)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := clientMove(client, from, to, uid); err != nil {
|
||||||
|
s.t.pushError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *scenario) imapClientMovesAllMessagesFromTo(clientID, from, to string) error {
|
||||||
|
_, client := s.t.getIMAPClient(clientID)
|
||||||
|
|
||||||
|
if err := clientMove(client, from, to); err != nil {
|
||||||
|
s.t.pushError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *scenario) imapClientEventuallySeesTheFollowingMessagesInMailbox(clientID, mailbox string, table *godog.Table) error {
|
func (s *scenario) imapClientEventuallySeesTheFollowingMessagesInMailbox(clientID, mailbox string, table *godog.Table) error {
|
||||||
return eventually(func() error {
|
return eventually(func() error {
|
||||||
err := s.imapClientSeesTheFollowingMessagesInMailbox(clientID, mailbox, table)
|
err := s.imapClientSeesTheFollowingMessagesInMailbox(clientID, mailbox, table)
|
||||||
|
@ -433,16 +457,11 @@ func (s *scenario) imapClientAppendsToMailbox(clientID string, file, mailbox str
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *scenario) imapClientsMoveMessageSeqOfUserFromToByOrderedOperations(sourceIMAPClient, targetIMAPClient, messageSeq, bddUserID, targetMailboxName, op1, op2, op3 string) error {
|
func (s *scenario) imapClientsMoveMessageWithSubjectUserFromToByOrderedOperations(sourceIMAPClient, targetIMAPClient, messageSubject, bddUserID, targetMailboxName, op1, op2, op3 string) error {
|
||||||
// call NOOP to prevent unilateral updates in following FETCH
|
// call NOOP to prevent unilateral updates in following FETCH
|
||||||
_, sourceClient := s.t.getIMAPClient(sourceIMAPClient)
|
_, sourceClient := s.t.getIMAPClient(sourceIMAPClient)
|
||||||
_, targetClient := s.t.getIMAPClient(targetIMAPClient)
|
_, targetClient := s.t.getIMAPClient(targetIMAPClient)
|
||||||
|
|
||||||
sequenceID, err := strconv.Atoi(messageSeq)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := sourceClient.Noop(); err != nil {
|
if err := sourceClient.Noop(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -451,8 +470,13 @@ func (s *scenario) imapClientsMoveMessageSeqOfUserFromToByOrderedOperations(sour
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uid, err := clientGetUIDBySubject(sourceClient, sourceClient.Mailbox().Name, messageSubject)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// get the original message
|
// get the original message
|
||||||
messages, err := clientFetchSequence(sourceClient, messageSeq)
|
messages, err := clientFetchSequence(sourceClient, fmt.Sprintf("%v", uid), true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -486,7 +510,7 @@ func (s *scenario) imapClientsMoveMessageSeqOfUserFromToByOrderedOperations(sour
|
||||||
|
|
||||||
targetErr = targetClient.Append(targetMailboxName, flags, time.Now(), bytes.NewReader(literal))
|
targetErr = targetClient.Append(targetMailboxName, flags, time.Now(), bytes.NewReader(literal))
|
||||||
case "DELETE":
|
case "DELETE":
|
||||||
if _, err := clientStore(sourceClient, sequenceID, sequenceID, false, imap.FormatFlagsOp(imap.AddFlags, true), imap.DeletedFlag); err != nil {
|
if _, err := clientStore(sourceClient, int(uid), int(uid), true, imap.FormatFlagsOp(imap.AddFlags, true), imap.DeletedFlag); err != nil {
|
||||||
storeErr = err
|
storeErr = err
|
||||||
}
|
}
|
||||||
case "EXPUNGE":
|
case "EXPUNGE":
|
||||||
|
@ -606,7 +630,7 @@ func clientFetch(client *client.Client, mailbox string) ([]*imap.Message, error)
|
||||||
return iterator.Collect(iterator.Chan(resCh)), nil
|
return iterator.Collect(iterator.Chan(resCh)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func clientFetchSequence(client *client.Client, sequenceSet string) ([]*imap.Message, error) {
|
func clientFetchSequence(client *client.Client, sequenceSet string, isUID bool) ([]*imap.Message, error) {
|
||||||
seqSet, err := imap.ParseSeqSet(sequenceSet)
|
seqSet, err := imap.ParseSeqSet(sequenceSet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -615,12 +639,22 @@ func clientFetchSequence(client *client.Client, sequenceSet string) ([]*imap.Mes
|
||||||
resCh := make(chan *imap.Message)
|
resCh := make(chan *imap.Message)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
if err := client.Fetch(
|
if isUID {
|
||||||
seqSet,
|
if err := client.UidFetch(
|
||||||
[]imap.FetchItem{imap.FetchFlags, imap.FetchEnvelope, imap.FetchUid, "BODY.PEEK[]"},
|
seqSet,
|
||||||
resCh,
|
[]imap.FetchItem{imap.FetchFlags, imap.FetchEnvelope, imap.FetchUid, "BODY.PEEK[]"},
|
||||||
); err != nil {
|
resCh,
|
||||||
panic(err)
|
); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := client.Fetch(
|
||||||
|
seqSet,
|
||||||
|
[]imap.FetchItem{imap.FetchFlags, imap.FetchEnvelope, imap.FetchUid, "BODY.PEEK[]"},
|
||||||
|
resCh,
|
||||||
|
); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -652,6 +686,31 @@ func clientCopy(client *client.Client, from, to string, uid ...uint32) error {
|
||||||
return client.UidCopy(seqset, to)
|
return client.UidCopy(seqset, to)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func clientMove(client *client.Client, from, to string, uid ...uint32) error {
|
||||||
|
status, err := client.Select(from, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if status.Messages == 0 {
|
||||||
|
return fmt.Errorf("expected %v to have messages, but it doesn't", from)
|
||||||
|
}
|
||||||
|
|
||||||
|
var seqset *imap.SeqSet
|
||||||
|
|
||||||
|
if len(uid) == 0 {
|
||||||
|
seqset = &imap.SeqSet{Set: []imap.Seq{{Start: 1, Stop: status.Messages}}}
|
||||||
|
} else {
|
||||||
|
seqset = &imap.SeqSet{}
|
||||||
|
|
||||||
|
for _, uid := range uid {
|
||||||
|
seqset.AddNum(uid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return client.UidMove(seqset, to)
|
||||||
|
}
|
||||||
|
|
||||||
func clientStore(client *client.Client, from, to int, isUID bool, item imap.StoreItem, flags ...string) ([]*imap.Message, error) { //nolint:unparam
|
func clientStore(client *client.Client, from, to int, isUID bool, item imap.StoreItem, flags ...string) ([]*imap.Message, error) { //nolint:unparam
|
||||||
resCh := make(chan *imap.Message)
|
resCh := make(chan *imap.Message)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue