mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-10 04:36:43 +00:00
GODT-1650: text/html sending tests
This commit is contained in:
3
go.mod
3
go.mod
@ -38,7 +38,7 @@ require (
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/urfave/cli/v2 v2.16.3
|
||||
gitlab.protontech.ch/go/liteapi v0.32.1-0.20221004092920-6b728aed0d4d
|
||||
gitlab.protontech.ch/go/liteapi v0.32.1-0.20221004164551-596cce482fb0
|
||||
golang.org/x/exp v0.0.0-20220921164117-439092de6870
|
||||
golang.org/x/net v0.1.0
|
||||
golang.org/x/sys v0.1.0
|
||||
@ -131,4 +131,5 @@ replace (
|
||||
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/keybase/go-keychain => github.com/cuthix/go-keychain v0.0.0-20220405075754-31e7cee908fe
|
||||
gitlab.protontech.ch/go/liteapi => ../liteapi
|
||||
)
|
||||
|
||||
2
go.sum
2
go.sum
@ -463,8 +463,6 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/zclconf/go-cty v1.11.0 h1:726SxLdi2SDnjY+BStqB9J1hNp4+2WlzyXLuimibIe0=
|
||||
github.com/zclconf/go-cty v1.11.0/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeWIMfhLvA=
|
||||
gitlab.protontech.ch/go/liteapi v0.32.1-0.20221004092920-6b728aed0d4d h1:2CB6po0yWmgb0bVCylvQlQph6a6Hk/Uziq5eHg0ZCfo=
|
||||
gitlab.protontech.ch/go/liteapi v0.32.1-0.20221004092920-6b728aed0d4d/go.mod h1:SVxEeF4uYYYpSlfeAj2ZqluVEP95pbZ8LyoieSxU0pM=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
|
||||
@ -1,11 +1,27 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
|
||||
"github.com/bradenaw/juniper/xslices"
|
||||
)
|
||||
|
||||
func ToAny(v any) any {
|
||||
b, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var a any
|
||||
|
||||
if err := json.Unmarshal(b, &a); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
func IsSub(outer, inner any) bool {
|
||||
if outer == nil && inner != nil {
|
||||
return IsSub(reflect.Zero(reflect.TypeOf(inner)).Interface(), inner)
|
||||
@ -30,10 +46,6 @@ func IsSub(outer, inner any) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(inner) != len(outer) {
|
||||
return false
|
||||
}
|
||||
|
||||
return isSubSlice(outer, inner)
|
||||
|
||||
default:
|
||||
@ -69,6 +81,10 @@ func isSubMap(outer, inner map[string]any) bool {
|
||||
}
|
||||
|
||||
func isSubSlice(outer, inner []any) bool {
|
||||
if len(inner) != len(outer) {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, v := range inner {
|
||||
if xslices.IndexFunc(outer, func(outer any) bool {
|
||||
return IsSub(outer, v)
|
||||
|
||||
@ -5,7 +5,7 @@ Feature: IMAP get mailbox info
|
||||
| name | type |
|
||||
| one | folder |
|
||||
And the address "user@pm.me" of account "user@pm.me" has the following messages in "one":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| a@pm.me | a@pm.me | one | true |
|
||||
| b@pm.me | b@pm.me | two | false |
|
||||
And bridge starts
|
||||
|
||||
@ -6,7 +6,7 @@ Feature: IMAP copy messages
|
||||
| mbox | folder |
|
||||
| label | label |
|
||||
And the address "user@pm.me" of account "user@pm.me" has the following messages in "Inbox":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | user@pm.me | foo | false |
|
||||
| jane.doe@mail.com | name@pm.me | bar | true |
|
||||
And bridge starts
|
||||
@ -17,37 +17,37 @@ Feature: IMAP copy messages
|
||||
Scenario: Copy message to label
|
||||
When IMAP client "1" copies the message with subject "foo" from "INBOX" to "Labels/label"
|
||||
Then IMAP client "1" sees the following messages in "INBOX":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | user@pm.me | foo | false |
|
||||
| jane.doe@mail.com | name@pm.me | bar | true |
|
||||
And IMAP client "1" sees the following messages in "Labels/label":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | user@pm.me | foo | false |
|
||||
|
||||
Scenario: Copy all messages to label
|
||||
When IMAP client "1" copies all messages from "INBOX" to "Labels/label"
|
||||
Then IMAP client "1" sees the following messages in "INBOX":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | user@pm.me | foo | false |
|
||||
| jane.doe@mail.com | name@pm.me | bar | true |
|
||||
And IMAP client "1" sees the following messages in "Labels/label":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | user@pm.me | foo | false |
|
||||
| jane.doe@mail.com | name@pm.me | bar | true |
|
||||
|
||||
Scenario: Copy message to folder does move
|
||||
When IMAP client "1" copies the message with subject "foo" from "INBOX" to "Folders/mbox"
|
||||
Then IMAP client "1" eventually sees the following messages in "INBOX":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| jane.doe@mail.com | name@pm.me | bar | true |
|
||||
And IMAP client "1" sees the following messages in "Folders/mbox":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | user@pm.me | foo | false |
|
||||
|
||||
Scenario: Copy all messages to folder does move
|
||||
When IMAP client "1" copies all messages from "INBOX" to "Folders/mbox"
|
||||
Then IMAP client "1" sees the following messages in "Folders/mbox":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | user@pm.me | foo | false |
|
||||
| jane.doe@mail.com | name@pm.me | bar | true |
|
||||
And IMAP client "1" eventually sees 0 messages in "INBOX"
|
||||
@ -55,7 +55,7 @@ Feature: IMAP copy messages
|
||||
Scenario: Copy message from Inbox to Sent is not possible
|
||||
When IMAP client "1" copies the message with subject "foo" from "INBOX" to "Sent"
|
||||
Then IMAP client "1" eventually sees the following messages in "INBOX":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | user@pm.me | foo | false |
|
||||
| jane.doe@mail.com | name@pm.me | bar | true |
|
||||
And IMAP client "1" eventually sees 0 messages in "Sent"
|
||||
344
tests/features/smtp/send/html.feature
Normal file
344
tests/features/smtp/send/html.feature
Normal file
@ -0,0 +1,344 @@
|
||||
Feature: SMTP sending of plain messages
|
||||
Background:
|
||||
Given there exists an account with username "user@pm.me" and password "password"
|
||||
And there exists an account with username "bridgetest@protonmail.com" and password "password"
|
||||
And there exists an account with username "bridgetest2@protonmail.com" and password "password"
|
||||
And bridge starts
|
||||
And the user logs in with username "user@pm.me" and password "password"
|
||||
And user "user@pm.me" connects and authenticates SMTP client "1"
|
||||
|
||||
Scenario: HTML message to external account
|
||||
When SMTP client "1" sends the following message from "user@pm.me" to "pm.bridge.qa@gmail.com":
|
||||
"""
|
||||
From: Bridge Test <user@pm.me>
|
||||
To: External Bridge <pm.bridge.qa@gmail.com>
|
||||
Subject: HTML text external
|
||||
Content-Disposition: inline
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
Content-Type: text/html; charset=utf-8
|
||||
In-Reply-To: <base64hashOfSomeMessage@protonmail.internalid>
|
||||
|
||||
<html><body>This is body of <b>HTML mail</b> without attachment<body></html>
|
||||
|
||||
"""
|
||||
Then it succeeds
|
||||
When user "user@pm.me" connects and authenticates IMAP client "1"
|
||||
Then IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| from | to | subject |
|
||||
| user@pm.me | pm.bridge.qa@gmail.com | HTML text external |
|
||||
And the body in the "POST" request to "/mail/v4/messages" is:
|
||||
"""
|
||||
{
|
||||
"Message": {
|
||||
"Subject": "HTML text external",
|
||||
"Sender": {
|
||||
"Name": "Bridge Test"
|
||||
},
|
||||
"ToList": [
|
||||
{
|
||||
"Address": "pm.bridge.qa@gmail.com",
|
||||
"Name": "External Bridge"
|
||||
}
|
||||
],
|
||||
"CCList": [],
|
||||
"BCCList": [],
|
||||
"MIMEType": "text/html"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: HTML message with inline image to external account
|
||||
When SMTP client "1" sends the following message from "user@pm.me" to "pm.bridge.qa@gmail.com":
|
||||
"""
|
||||
From: Bridge Test <user@pm.me>
|
||||
To: External Bridge <pm.bridge.qa@gmail.com>
|
||||
Subject: Html Inline External
|
||||
Content-Disposition: inline
|
||||
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.5.0
|
||||
MIME-Version: 1.0
|
||||
Content-Language: en-US
|
||||
Content-Type: multipart/related; boundary="------------61FA22A41A3F46E8E90EF528"
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--------------61FA22A41A3F46E8E90EF528
|
||||
Content-Type: text/html; charset=utf-8
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
</head>
|
||||
<body text="#000000" bgcolor="#FFFFFF">
|
||||
<p><br>
|
||||
</p>
|
||||
<p>Behold! An inline <img moz-do-not-send="false"
|
||||
src="cid:part1.D96BFAE9.E2E1CAE3@protonmail.com" alt=""
|
||||
width="24" height="24"><br>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
--------------61FA22A41A3F46E8E90EF528
|
||||
Content-Type: image/gif; name="email-action-left.gif"
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-ID: <part1.D96BFAE9.E2E1CAE3@protonmail.com>
|
||||
Content-Disposition: inline; filename="email-action-left.gif"
|
||||
|
||||
R0lGODlhGAAYANUAACcsKOHs4kppTH6tgYWxiIq0jTVENpG5lDI/M7bRuEaJSkqOTk2RUU+P
|
||||
U16lYl+lY2iva262cXS6d3rDfYLNhWeeamKTZGSVZkNbRGqhbOPt4////+7u7qioqFZWVlNT
|
||||
UyIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAGAAYAAAG
|
||||
/8CNcLjRJAqVRqNSSGiI0GFgoKhar4NAdHioMhyRCYUyiTgY1cOWUH1ILgIDAGAQXCSPKgHa
|
||||
XUAyGCCCg4IYGRALCmpCAVUQFgiEkiAIFhBVWhtUDxmRk5IIGXkDRQoMEoGfHpIYEmhGCg4X
|
||||
nyAdHB+SFw4KRwoRArQdG7eEAhEKSAoTBoIdzs/Cw7iCBhMKSQoUAIJbQ8QgABQKStnbIN1C
|
||||
3+HjFcrMtdDO6dMg1dcFvsCfwt+CxsgJYs3a10+QLl4aTKGitYpQq1eaFHDyREtQqFGMHEGq
|
||||
SMkSJi4K/ACiZQiRIihsJL6JM6fOnTwK9kTpYgqMGDJm0JzsNuWKTw0FWdANMYJECRMnW4IA
|
||||
ADs=
|
||||
--------------61FA22A41A3F46E8E90EF528--
|
||||
|
||||
"""
|
||||
Then it succeeds
|
||||
When user "user@pm.me" connects and authenticates IMAP client "1"
|
||||
Then IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| from | to | subject |
|
||||
| user@pm.me | pm.bridge.qa@gmail.com | Html Inline External |
|
||||
And the body in the "POST" request to "/mail/v4/messages" is:
|
||||
"""
|
||||
{
|
||||
"Message": {
|
||||
"Subject": "Html Inline External",
|
||||
"Sender": {
|
||||
"Name": "Bridge Test"
|
||||
},
|
||||
"ToList": [
|
||||
{
|
||||
"Address": "pm.bridge.qa@gmail.com",
|
||||
"Name": "External Bridge"
|
||||
}
|
||||
],
|
||||
"CCList": [],
|
||||
"BCCList": [],
|
||||
"MIMEType": "text/html"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: HTML message with alternative inline to internal account
|
||||
When SMTP client "1" sends the following message from "user@pm.me" to "bridgetest@protonmail.com":
|
||||
"""
|
||||
From: Bridge Test <user@pm.me>
|
||||
To: Internal Bridge <bridgetest@protonmail.com>
|
||||
Subject: Html Inline Alternative Internal
|
||||
Content-Disposition: inline
|
||||
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.5.0
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/alternative; boundary="------------5A259F4DE164B5ADA313F644"
|
||||
Content-Language: en-US
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--------------5A259F4DE164B5ADA313F644
|
||||
Content-Type: text/plain; charset=utf-8
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
|
||||
Behold! An inline
|
||||
|
||||
|
||||
--------------5A259F4DE164B5ADA313F644
|
||||
Content-Type: multipart/related; boundary="------------61FA22A41A3F46E8E90EF528"
|
||||
|
||||
|
||||
--------------61FA22A41A3F46E8E90EF528
|
||||
Content-Type: text/html; charset=utf-8
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
</head>
|
||||
<body text="#000000" bgcolor="#FFFFFF">
|
||||
<p><br>
|
||||
</p>
|
||||
<p>Behold! An inline <img moz-do-not-send="false"
|
||||
src="cid:part1.D96BFAE9.E2E1CAE3@protonmail.com" alt=""
|
||||
width="24" height="24"><br>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
--------------61FA22A41A3F46E8E90EF528
|
||||
Content-Type: image/gif; name="email-action-left.gif"
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-ID: <part1.D96BFAE9.E2E1CAE3@protonmail.com>
|
||||
Content-Disposition: inline; filename="email-action-left.gif"
|
||||
|
||||
R0lGODlhGAAYANUAACcsKOHs4kppTH6tgYWxiIq0jTVENpG5lDI/M7bRuEaJSkqOTk2RUU+P
|
||||
U16lYl+lY2iva262cXS6d3rDfYLNhWeeamKTZGSVZkNbRGqhbOPt4////+7u7qioqFZWVlNT
|
||||
UyIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAGAAYAAAG
|
||||
/8CNcLjRJAqVRqNSSGiI0GFgoKhar4NAdHioMhyRCYUyiTgY1cOWUH1ILgIDAGAQXCSPKgHa
|
||||
XUAyGCCCg4IYGRALCmpCAVUQFgiEkiAIFhBVWhtUDxmRk5IIGXkDRQoMEoGfHpIYEmhGCg4X
|
||||
nyAdHB+SFw4KRwoRArQdG7eEAhEKSAoTBoIdzs/Cw7iCBhMKSQoUAIJbQ8QgABQKStnbIN1C
|
||||
3+HjFcrMtdDO6dMg1dcFvsCfwt+CxsgJYs3a10+QLl4aTKGitYpQq1eaFHDyREtQqFGMHEGq
|
||||
SMkSJi4K/ACiZQiRIihsJL6JM6fOnTwK9kTpYgqMGDJm0JzsNuWKTw0FWdANMYJECRMnW4IA
|
||||
ADs=
|
||||
--------------61FA22A41A3F46E8E90EF528--
|
||||
|
||||
--------------5A259F4DE164B5ADA313F644--
|
||||
|
||||
"""
|
||||
Then it succeeds
|
||||
When user "user@pm.me" connects and authenticates IMAP client "1"
|
||||
Then IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| from | to | subject |
|
||||
| user@pm.me | bridgetest@protonmail.com | Html Inline Alternative Internal |
|
||||
And the body in the "POST" request to "/mail/v4/messages" is:
|
||||
"""
|
||||
{
|
||||
"Message": {
|
||||
"Subject": "Html Inline Alternative Internal",
|
||||
"Sender": {
|
||||
"Name": "Bridge Test"
|
||||
},
|
||||
"ToList": [
|
||||
{
|
||||
"Address": "bridgetest@protonmail.com",
|
||||
"Name": "Internal Bridge"
|
||||
}
|
||||
],
|
||||
"CCList": [],
|
||||
"BCCList": [],
|
||||
"MIMEType": "text/html"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: HTML message with alternative inline to external account
|
||||
When SMTP client "1" sends the following message from "user@pm.me" to "pm.bridge.qa@gmail.com":
|
||||
"""
|
||||
From: Bridge Test <user@pm.me>
|
||||
To: External Bridge <pm.bridge.qa@gmail.com>
|
||||
Subject: Html Inline Alternative External
|
||||
Content-Disposition: inline
|
||||
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.5.0
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/alternative; boundary="------------5A259F4DE164B5ADA313F644"
|
||||
Content-Language: en-US
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--------------5A259F4DE164B5ADA313F644
|
||||
Content-Type: text/plain; charset=utf-8
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
|
||||
Behold! An inline
|
||||
|
||||
|
||||
--------------5A259F4DE164B5ADA313F644
|
||||
Content-Type: multipart/related; boundary="------------61FA22A41A3F46E8E90EF528"
|
||||
|
||||
|
||||
--------------61FA22A41A3F46E8E90EF528
|
||||
Content-Type: text/html; charset=utf-8
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
</head>
|
||||
<body text="#000000" bgcolor="#FFFFFF">
|
||||
<p><br>
|
||||
</p>
|
||||
<p>Behold! An inline <img moz-do-not-send="false"
|
||||
src="cid:part1.D96BFAE9.E2E1CAE3@protonmail.com" alt=""
|
||||
width="24" height="24"><br>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
--------------61FA22A41A3F46E8E90EF528
|
||||
Content-Type: image/gif; name="email-action-left.gif"
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-ID: <part1.D96BFAE9.E2E1CAE3@protonmail.com>
|
||||
Content-Disposition: inline; filename="email-action-left.gif"
|
||||
|
||||
R0lGODlhGAAYANUAACcsKOHs4kppTH6tgYWxiIq0jTVENpG5lDI/M7bRuEaJSkqOTk2RUU+P
|
||||
U16lYl+lY2iva262cXS6d3rDfYLNhWeeamKTZGSVZkNbRGqhbOPt4////+7u7qioqFZWVlNT
|
||||
UyIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAGAAYAAAG
|
||||
/8CNcLjRJAqVRqNSSGiI0GFgoKhar4NAdHioMhyRCYUyiTgY1cOWUH1ILgIDAGAQXCSPKgHa
|
||||
XUAyGCCCg4IYGRALCmpCAVUQFgiEkiAIFhBVWhtUDxmRk5IIGXkDRQoMEoGfHpIYEmhGCg4X
|
||||
nyAdHB+SFw4KRwoRArQdG7eEAhEKSAoTBoIdzs/Cw7iCBhMKSQoUAIJbQ8QgABQKStnbIN1C
|
||||
3+HjFcrMtdDO6dMg1dcFvsCfwt+CxsgJYs3a10+QLl4aTKGitYpQq1eaFHDyREtQqFGMHEGq
|
||||
SMkSJi4K/ACiZQiRIihsJL6JM6fOnTwK9kTpYgqMGDJm0JzsNuWKTw0FWdANMYJECRMnW4IA
|
||||
ADs=
|
||||
--------------61FA22A41A3F46E8E90EF528--
|
||||
|
||||
--------------5A259F4DE164B5ADA313F644--
|
||||
|
||||
"""
|
||||
Then it succeeds
|
||||
When user "user@pm.me" connects and authenticates IMAP client "1"
|
||||
Then IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| from | to | subject |
|
||||
| user@pm.me | pm.bridge.qa@gmail.com | Html Inline Alternative External |
|
||||
And the body in the "POST" request to "/mail/v4/messages" is:
|
||||
"""
|
||||
{
|
||||
"Message": {
|
||||
"Subject": "Html Inline Alternative External",
|
||||
"Sender": {
|
||||
"Name": "Bridge Test"
|
||||
},
|
||||
"ToList": [
|
||||
{
|
||||
"Address": "pm.bridge.qa@gmail.com",
|
||||
"Name": "External Bridge"
|
||||
}
|
||||
],
|
||||
"CCList": [],
|
||||
"BCCList": [],
|
||||
"MIMEType": "text/html"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: HTML message with extremely long line (greater than default 2000 line limit) to external account
|
||||
When SMTP client "1" sends the following message from "user@pm.me" to "pm.bridge.qa@gmail.com":
|
||||
"""
|
||||
From: Bridge Test <user@pm.me>
|
||||
To: External Bridge <pm.bridge.qa@gmail.com>
|
||||
Subject: HTML text external
|
||||
Content-Disposition: inline
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
Content-Type: text/html; charset=utf-8
|
||||
In-Reply-To: <base64hashOfSomeMessage@protonmail.internalid>
|
||||
|
||||
<html><body>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<body></html>
|
||||
|
||||
"""
|
||||
Then it succeeds
|
||||
When user "user@pm.me" connects and authenticates IMAP client "1"
|
||||
Then IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| from | to | subject |
|
||||
| user@pm.me | pm.bridge.qa@gmail.com | HTML text external |
|
||||
And the body in the "POST" request to "/mail/v4/messages" is:
|
||||
"""
|
||||
{
|
||||
"Message": {
|
||||
"Subject": "HTML text external",
|
||||
"Sender": {
|
||||
"Name": "Bridge Test"
|
||||
},
|
||||
"ToList": [
|
||||
{
|
||||
"Address": "pm.bridge.qa@gmail.com",
|
||||
"Name": "External Bridge"
|
||||
}
|
||||
],
|
||||
"CCList": [],
|
||||
"BCCList": [],
|
||||
"MIMEType": "text/html"
|
||||
}
|
||||
}
|
||||
"""
|
||||
@ -19,8 +19,8 @@ Feature: SMTP sending of plain messages
|
||||
Then it succeeds
|
||||
When user "user@pm.me" connects and authenticates IMAP client "1"
|
||||
Then IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| sender | recipient | subject | unread |
|
||||
| user@pm.me | bridgetest@protonmail.com | | false |
|
||||
| from | to | subject |
|
||||
| user@pm.me | bridgetest@protonmail.com | |
|
||||
And the body in the "POST" request to "/mail/v4/messages" is:
|
||||
"""
|
||||
{
|
||||
@ -54,8 +54,8 @@ Feature: SMTP sending of plain messages
|
||||
Then it succeeds
|
||||
When user "user@pm.me" connects and authenticates IMAP client "1"
|
||||
Then IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| sender | recipient | subject | unread |
|
||||
| user@pm.me | pm.bridge.qa@gmail.com | | false |
|
||||
| from | to | subject |
|
||||
| user@pm.me | pm.bridge.qa@gmail.com | |
|
||||
And the body in the "POST" request to "/mail/v4/messages" is:
|
||||
"""
|
||||
{
|
||||
@ -92,8 +92,8 @@ Feature: SMTP sending of plain messages
|
||||
Then it succeeds
|
||||
When user "user@pm.me" connects and authenticates IMAP client "1"
|
||||
Then IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| sender | recipient | subject | unread |
|
||||
| user@pm.me | bridgetest@protonmail.com | Plain text internal | false |
|
||||
| from | to | subject |
|
||||
| user@pm.me | bridgetest@protonmail.com | Plain text internal |
|
||||
And the body in the "POST" request to "/mail/v4/messages" is:
|
||||
"""
|
||||
{
|
||||
@ -130,8 +130,8 @@ Feature: SMTP sending of plain messages
|
||||
Then it succeeds
|
||||
When user "user@pm.me" connects and authenticates IMAP client "1"
|
||||
Then IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| sender | recipient | subject | unread |
|
||||
| user@pm.me | pm.bridge.qa@gmail.com | Plain text external | false |
|
||||
| from | to | subject |
|
||||
| user@pm.me | pm.bridge.qa@gmail.com | Plain text external |
|
||||
And the body in the "POST" request to "/mail/v4/messages" is:
|
||||
"""
|
||||
{
|
||||
@ -168,8 +168,8 @@ Feature: SMTP sending of plain messages
|
||||
Then it succeeds
|
||||
When user "user@pm.me" connects and authenticates IMAP client "1"
|
||||
Then IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| sender | recipient | subject | unread |
|
||||
| user@pm.me | pm.bridge.qa@gmail.com | Plain text no charset external | false |
|
||||
| from | to | subject |
|
||||
| user@pm.me | pm.bridge.qa@gmail.com | Plain text no charset external |
|
||||
And the body in the "POST" request to "/mail/v4/messages" is:
|
||||
"""
|
||||
{
|
||||
@ -209,8 +209,8 @@ Feature: SMTP sending of plain messages
|
||||
Then it succeeds
|
||||
When user "user@pm.me" connects and authenticates IMAP client "1"
|
||||
Then IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| sender | recipient | subject | unread |
|
||||
| user@pm.me | pm.bridge.qa@gmail.com | Plain text no charset external | false |
|
||||
| from | to | subject |
|
||||
| user@pm.me | pm.bridge.qa@gmail.com | Plain text no charset external |
|
||||
And the body in the "POST" request to "/mail/v4/messages" is:
|
||||
"""
|
||||
{
|
||||
@ -245,8 +245,8 @@ Feature: SMTP sending of plain messages
|
||||
Then it succeeds
|
||||
When user "user@pm.me" connects and authenticates IMAP client "1"
|
||||
Then IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| sender | recipient | subject | unread |
|
||||
| user@pm.me | pm.bridge.qa@gmail.com | Plain, no charset, no content, external | false |
|
||||
| from | to | subject |
|
||||
| user@pm.me | pm.bridge.qa@gmail.com | Plain, no charset, no content, external |
|
||||
And the body in the "POST" request to "/mail/v4/messages" is:
|
||||
"""
|
||||
{
|
||||
@ -285,8 +285,8 @@ Feature: SMTP sending of plain messages
|
||||
Then it succeeds
|
||||
When user "user@pm.me" connects and authenticates IMAP client "1"
|
||||
Then IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| sender | recipient | cc | subject | unread |
|
||||
| user@pm.me | bridgetest@protonmail.com | bridgetest2@protonmail.com | RCPT-CC test | false |
|
||||
| from | to | cc | subject |
|
||||
| user@pm.me | bridgetest@protonmail.com | bridgetest2@protonmail.com | RCPT-CC test |
|
||||
And the body in the "POST" request to "/mail/v4/messages" is:
|
||||
"""
|
||||
{
|
||||
|
||||
@ -7,11 +7,11 @@ Feature: Address mode
|
||||
| one | folder |
|
||||
| two | folder |
|
||||
And the address "user@pm.me" of account "user@pm.me" has the following messages in "one":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| a@pm.me | a@pm.me | one | true |
|
||||
| b@pm.me | b@pm.me | two | false |
|
||||
And the address "alias@pm.me" of account "user@pm.me" has the following messages in "two":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| c@pm.me | c@pm.me | three | true |
|
||||
| d@pm.me | d@pm.me | four | false |
|
||||
And bridge starts
|
||||
@ -21,30 +21,30 @@ Feature: Address mode
|
||||
Scenario: The user is in combined mode
|
||||
When user "user@pm.me" connects and authenticates IMAP client "1" with address "user@pm.me"
|
||||
Then IMAP client "1" sees the following messages in "Folders/one":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| a@pm.me | a@pm.me | one | true |
|
||||
| b@pm.me | b@pm.me | two | false |
|
||||
And IMAP client "1" sees the following messages in "Folders/two":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| c@pm.me | c@pm.me | three | true |
|
||||
| d@pm.me | d@pm.me | four | false |
|
||||
And IMAP client "1" sees the following messages in "All Mail":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| a@pm.me | a@pm.me | one | true |
|
||||
| b@pm.me | b@pm.me | two | false |
|
||||
| c@pm.me | c@pm.me | three | true |
|
||||
| d@pm.me | d@pm.me | four | false |
|
||||
When user "user@pm.me" connects and authenticates IMAP client "2" with address "alias@pm.me"
|
||||
Then IMAP client "2" sees the following messages in "Folders/one":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| a@pm.me | a@pm.me | one | true |
|
||||
| b@pm.me | b@pm.me | two | false |
|
||||
And IMAP client "2" sees the following messages in "Folders/two":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| c@pm.me | c@pm.me | three | true |
|
||||
| d@pm.me | d@pm.me | four | false |
|
||||
And IMAP client "2" sees the following messages in "All Mail":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| a@pm.me | a@pm.me | one | true |
|
||||
| b@pm.me | b@pm.me | two | false |
|
||||
| c@pm.me | c@pm.me | three | true |
|
||||
@ -55,22 +55,22 @@ Feature: Address mode
|
||||
And user "user@pm.me" finishes syncing
|
||||
When user "user@pm.me" connects and authenticates IMAP client "1" with address "user@pm.me"
|
||||
Then IMAP client "1" sees the following messages in "Folders/one":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| a@pm.me | a@pm.me | one | true |
|
||||
| b@pm.me | b@pm.me | two | false |
|
||||
And IMAP client "1" sees 0 messages in "Folders/two"
|
||||
And IMAP client "1" sees the following messages in "All Mail":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| a@pm.me | a@pm.me | one | true |
|
||||
| b@pm.me | b@pm.me | two | false |
|
||||
When user "user@pm.me" connects and authenticates IMAP client "2" with address "alias@pm.me"
|
||||
Then IMAP client "2" sees 0 messages in "Folders/one"
|
||||
And IMAP client "2" sees the following messages in "Folders/two":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| c@pm.me | c@pm.me | three | true |
|
||||
| d@pm.me | d@pm.me | four | false |
|
||||
And IMAP client "2" sees the following messages in "All Mail":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| c@pm.me | c@pm.me | three | true |
|
||||
| d@pm.me | d@pm.me | four | false |
|
||||
|
||||
@ -81,14 +81,14 @@ Feature: Address mode
|
||||
And user "user@pm.me" finishes syncing
|
||||
When user "user@pm.me" connects and authenticates IMAP client "1" with address "user@pm.me"
|
||||
Then IMAP client "1" sees the following messages in "All Mail":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| a@pm.me | a@pm.me | one | true |
|
||||
| b@pm.me | b@pm.me | two | false |
|
||||
| c@pm.me | c@pm.me | three | true |
|
||||
| d@pm.me | d@pm.me | four | false |
|
||||
When user "user@pm.me" connects and authenticates IMAP client "2" with address "alias@pm.me"
|
||||
Then IMAP client "2" sees the following messages in "All Mail":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| a@pm.me | a@pm.me | one | true |
|
||||
| b@pm.me | b@pm.me | two | false |
|
||||
| c@pm.me | c@pm.me | three | true |
|
||||
@ -97,14 +97,14 @@ Feature: Address mode
|
||||
Scenario: The user adds an address while in combined mode
|
||||
When user "user@pm.me" connects and authenticates IMAP client "1" with address "user@pm.me"
|
||||
Then IMAP client "1" sees the following messages in "All Mail":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| a@pm.me | a@pm.me | one | true |
|
||||
| b@pm.me | b@pm.me | two | false |
|
||||
| c@pm.me | c@pm.me | three | true |
|
||||
| d@pm.me | d@pm.me | four | false |
|
||||
When user "user@pm.me" connects and authenticates IMAP client "2" with address "alias@pm.me"
|
||||
Then IMAP client "2" sees the following messages in "All Mail":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| a@pm.me | a@pm.me | one | true |
|
||||
| b@pm.me | b@pm.me | two | false |
|
||||
| c@pm.me | c@pm.me | three | true |
|
||||
@ -113,7 +113,7 @@ Feature: Address mode
|
||||
And bridge sends an address created event for user "user@pm.me"
|
||||
When user "user@pm.me" connects and authenticates IMAP client "3" with address "other@pm.me"
|
||||
Then IMAP client "3" sees the following messages in "All Mail":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| a@pm.me | a@pm.me | one | true |
|
||||
| b@pm.me | b@pm.me | two | false |
|
||||
| c@pm.me | c@pm.me | three | true |
|
||||
@ -124,12 +124,12 @@ Feature: Address mode
|
||||
And user "user@pm.me" finishes syncing
|
||||
When user "user@pm.me" connects and authenticates IMAP client "1" with address "user@pm.me"
|
||||
And IMAP client "1" sees the following messages in "All Mail":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| a@pm.me | a@pm.me | one | true |
|
||||
| b@pm.me | b@pm.me | two | false |
|
||||
When user "user@pm.me" connects and authenticates IMAP client "2" with address "alias@pm.me"
|
||||
And IMAP client "2" sees the following messages in "All Mail":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| c@pm.me | c@pm.me | three | true |
|
||||
| d@pm.me | d@pm.me | four | false |
|
||||
Given the account "user@pm.me" has additional address "other@pm.me"
|
||||
@ -140,14 +140,14 @@ Feature: Address mode
|
||||
Scenario: The user deletes an address while in combined mode
|
||||
When user "user@pm.me" connects and authenticates IMAP client "1" with address "user@pm.me"
|
||||
Then IMAP client "1" sees the following messages in "All Mail":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| a@pm.me | a@pm.me | one | true |
|
||||
| b@pm.me | b@pm.me | two | false |
|
||||
| c@pm.me | c@pm.me | three | true |
|
||||
| d@pm.me | d@pm.me | four | false |
|
||||
When user "user@pm.me" connects and authenticates IMAP client "2" with address "alias@pm.me"
|
||||
Then IMAP client "2" sees the following messages in "All Mail":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| a@pm.me | a@pm.me | one | true |
|
||||
| b@pm.me | b@pm.me | two | false |
|
||||
| c@pm.me | c@pm.me | three | true |
|
||||
@ -162,12 +162,12 @@ Feature: Address mode
|
||||
And user "user@pm.me" finishes syncing
|
||||
When user "user@pm.me" connects and authenticates IMAP client "1" with address "user@pm.me"
|
||||
And IMAP client "1" sees the following messages in "All Mail":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| a@pm.me | a@pm.me | one | true |
|
||||
| b@pm.me | b@pm.me | two | false |
|
||||
When user "user@pm.me" connects and authenticates IMAP client "2" with address "alias@pm.me"
|
||||
And IMAP client "2" sees the following messages in "All Mail":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| c@pm.me | c@pm.me | three | true |
|
||||
| d@pm.me | d@pm.me | four | false |
|
||||
Given the account "user@pm.me" no longer has additional address "alias@pm.me"
|
||||
|
||||
@ -7,11 +7,11 @@ Feature: Bridge can fully sync an account
|
||||
| two | folder |
|
||||
| three | label |
|
||||
And the address "user@pm.me" of account "user@pm.me" has the following messages in "one":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| a@pm.me | a@pm.me | one | true |
|
||||
| b@pm.me | b@pm.me | two | false |
|
||||
And the address "user@pm.me" of account "user@pm.me" has the following messages in "two":
|
||||
| sender | recipient | subject | unread |
|
||||
| from | to | subject | unread |
|
||||
| a@pm.me | a@pm.me | one | true |
|
||||
| b@pm.me | b@pm.me | two | false |
|
||||
And bridge starts
|
||||
|
||||
@ -127,15 +127,16 @@ func (s *scenario) imapClientSeesTheFollowingMailboxInfo(clientID string, table
|
||||
return err
|
||||
}
|
||||
|
||||
haveMailboxes := xslices.Map(status, func(info *imap.MailboxStatus) Mailbox {
|
||||
return Mailbox{
|
||||
Name: info.Name,
|
||||
Total: int(info.Messages),
|
||||
Unread: int(info.Unseen),
|
||||
}
|
||||
haveMailboxes := xslices.Map(status, func(status *imap.MailboxStatus) Mailbox {
|
||||
return newMailboxFromIMAP(status)
|
||||
})
|
||||
|
||||
return matchMailboxes(haveMailboxes, table)
|
||||
wantMailboxes, err := unmarshalTable[Mailbox](table)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return matchMailboxes(haveMailboxes, wantMailboxes)
|
||||
}
|
||||
|
||||
func (s *scenario) imapClientEventuallySeesTheFollowingMailboxInfo(clientID string, table *godog.Table) error {
|
||||
@ -159,14 +160,15 @@ func (s *scenario) imapClientSeesTheFollowingMailboxInfoForMailbox(clientID, mai
|
||||
})
|
||||
|
||||
haveMailboxes := xslices.Map(status, func(info *imap.MailboxStatus) Mailbox {
|
||||
return Mailbox{
|
||||
Name: info.Name,
|
||||
Total: int(info.Messages),
|
||||
Unread: int(info.Unseen),
|
||||
}
|
||||
return newMailboxFromIMAP(info)
|
||||
})
|
||||
|
||||
return matchMailboxes(haveMailboxes, table)
|
||||
wantMailboxes, err := unmarshalTable[Mailbox](table)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return matchMailboxes(haveMailboxes, wantMailboxes)
|
||||
}
|
||||
|
||||
func (s *scenario) imapClientSeesTheFollowingMailboxes(clientID string, table *godog.Table) error {
|
||||
@ -280,31 +282,15 @@ func (s *scenario) imapClientSeesTheFollowingMessagesInMailbox(clientID, mailbox
|
||||
}
|
||||
|
||||
haveMessages := xslices.Map(fetch, func(msg *imap.Message) Message {
|
||||
message := Message{
|
||||
Subject: msg.Envelope.Subject,
|
||||
Unread: slices.Contains(msg.Flags, imap.SeenFlag),
|
||||
}
|
||||
|
||||
if len(msg.Envelope.From) > 0 {
|
||||
message.From = msg.Envelope.From[0].Address()
|
||||
}
|
||||
|
||||
if len(msg.Envelope.To) > 0 {
|
||||
message.To = msg.Envelope.To[0].Address()
|
||||
}
|
||||
|
||||
if len(msg.Envelope.Cc) > 0 {
|
||||
message.CC = msg.Envelope.Cc[0].Address()
|
||||
}
|
||||
|
||||
if len(msg.Envelope.Bcc) > 0 {
|
||||
message.BCC = msg.Envelope.Bcc[0].Address()
|
||||
}
|
||||
|
||||
return message
|
||||
return newMessageFromIMAP(msg)
|
||||
})
|
||||
|
||||
return matchMessages(haveMessages, table)
|
||||
wantMessages, err := unmarshalTable[Message](table)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return matchMessages(haveMessages, wantMessages)
|
||||
}
|
||||
|
||||
func (s *scenario) imapClientEventuallySeesTheFollowingMessagesInMailbox(clientID, mailbox string, table *godog.Table) error {
|
||||
|
||||
@ -6,82 +6,85 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/bradenaw/juniper/xslices"
|
||||
"github.com/cucumber/godog"
|
||||
"github.com/cucumber/messages-go/v16"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"github.com/emersion/go-imap"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
Subject string `bdd:"subject"`
|
||||
|
||||
From string `bdd:"sender"`
|
||||
To string `bdd:"recipient"`
|
||||
From string `bdd:"from"`
|
||||
To string `bdd:"to"`
|
||||
CC string `bdd:"cc"`
|
||||
BCC string `bdd:"bcc"`
|
||||
|
||||
Unread bool `bdd:"unread"`
|
||||
}
|
||||
|
||||
func newMessageFromRow(header, row *messages.PickleTableRow) Message {
|
||||
var msg Message
|
||||
|
||||
if err := unmarshalRow(header, row, &msg); err != nil {
|
||||
panic(err)
|
||||
func newMessageFromIMAP(msg *imap.Message) Message {
|
||||
message := Message{
|
||||
Subject: msg.Envelope.Subject,
|
||||
Unread: slices.Contains(msg.Flags, imap.SeenFlag),
|
||||
}
|
||||
|
||||
return msg
|
||||
if len(msg.Envelope.From) > 0 {
|
||||
message.From = msg.Envelope.From[0].Address()
|
||||
}
|
||||
|
||||
if len(msg.Envelope.To) > 0 {
|
||||
message.To = msg.Envelope.To[0].Address()
|
||||
}
|
||||
|
||||
if len(msg.Envelope.Cc) > 0 {
|
||||
message.CC = msg.Envelope.Cc[0].Address()
|
||||
}
|
||||
|
||||
if len(msg.Envelope.Bcc) > 0 {
|
||||
message.BCC = msg.Envelope.Bcc[0].Address()
|
||||
}
|
||||
|
||||
return message
|
||||
}
|
||||
|
||||
func matchMessages(have []Message, want *godog.Table) error {
|
||||
if want := parseMessages(want); !cmp.Equal(want, have, cmpopts.SortSlices(func(a, b Message) bool { return a.Subject < b.Subject })) {
|
||||
return fmt.Errorf("want: %v, have: %v", want, have)
|
||||
func matchMessages(have, want []Message) error {
|
||||
if !IsSub(ToAny(have), ToAny(want)) {
|
||||
return fmt.Errorf("missing messages: %v", want)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseMessages(table *godog.Table) []Message {
|
||||
header := table.Rows[0]
|
||||
|
||||
return xslices.Map(table.Rows[1:], func(row *messages.PickleTableRow) Message {
|
||||
return newMessageFromRow(header, row)
|
||||
})
|
||||
}
|
||||
|
||||
type Mailbox struct {
|
||||
Name string `bdd:"name"`
|
||||
Total int `bdd:"total"`
|
||||
Unread int `bdd:"unread"`
|
||||
}
|
||||
|
||||
func newMailboxFromRow(header, row *messages.PickleTableRow) Mailbox {
|
||||
var mbox Mailbox
|
||||
|
||||
if err := unmarshalRow(header, row, &mbox); err != nil {
|
||||
panic(err)
|
||||
func newMailboxFromIMAP(status *imap.MailboxStatus) Mailbox {
|
||||
return Mailbox{
|
||||
Name: status.Name,
|
||||
Total: int(status.Messages),
|
||||
Unread: int(status.Unseen),
|
||||
}
|
||||
|
||||
return mbox
|
||||
}
|
||||
|
||||
func matchMailboxes(have []Mailbox, want *godog.Table) error {
|
||||
if want := parseMailboxes(want); !cmp.Equal(want, have, cmpopts.SortSlices(func(a, b Mailbox) bool { return a.Name < b.Name })) {
|
||||
return fmt.Errorf("want: %v, have: %v", want, have)
|
||||
func matchMailboxes(have, want []Mailbox) error {
|
||||
slices.SortFunc(have, func(a, b Mailbox) bool {
|
||||
return a.Name < b.Name
|
||||
})
|
||||
|
||||
slices.SortFunc(want, func(a, b Mailbox) bool {
|
||||
return a.Name < b.Name
|
||||
})
|
||||
|
||||
if !IsSub(want, have) {
|
||||
return fmt.Errorf("missing messages: %v", want)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseMailboxes(table *godog.Table) []Mailbox {
|
||||
header := table.Rows[0]
|
||||
|
||||
return xslices.Map(table.Rows[1:], func(row *messages.PickleTableRow) Mailbox {
|
||||
return newMailboxFromRow(header, row)
|
||||
})
|
||||
}
|
||||
|
||||
func eventually(condition func() error, waitFor, tick time.Duration) error {
|
||||
ch := make(chan error, 1)
|
||||
|
||||
@ -111,14 +114,24 @@ func eventually(condition func() error, waitFor, tick time.Duration) error {
|
||||
}
|
||||
}
|
||||
|
||||
func getCellValue(header, row *messages.PickleTableRow, name string) (string, bool) {
|
||||
for idx, cell := range header.Cells {
|
||||
if cell.Value == name {
|
||||
return row.Cells[idx].Value, true
|
||||
}
|
||||
func unmarshalTable[T any](table *messages.PickleTable) ([]T, error) {
|
||||
if len(table.Rows) == 0 {
|
||||
return nil, fmt.Errorf("empty table")
|
||||
}
|
||||
|
||||
return "", false
|
||||
var res []T
|
||||
|
||||
for _, row := range table.Rows[1:] {
|
||||
var v T
|
||||
|
||||
if err := unmarshalRow(table.Rows[0], row, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res = append(res, v)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func unmarshalRow(header, row *messages.PickleTableRow, v any) error {
|
||||
@ -152,6 +165,16 @@ func unmarshalRow(header, row *messages.PickleTableRow, v any) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getCellValue(header, row *messages.PickleTableRow, name string) (string, bool) {
|
||||
for idx, cell := range header.Cells {
|
||||
if cell.Value == name {
|
||||
return row.Cells[idx].Value, true
|
||||
}
|
||||
}
|
||||
|
||||
return "", false
|
||||
}
|
||||
|
||||
func mustParseInt(s string) int {
|
||||
i, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
|
||||
@ -8,9 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/ProtonMail/gluon/rfc822"
|
||||
"github.com/bradenaw/juniper/xslices"
|
||||
"github.com/cucumber/godog"
|
||||
"github.com/cucumber/messages-go/v16"
|
||||
"github.com/google/uuid"
|
||||
"gitlab.protontech.ch/go/liteapi"
|
||||
"golang.org/x/exp/slices"
|
||||
@ -82,29 +80,28 @@ func (s *scenario) theAccountHasCustomLabels(username string, count int) error {
|
||||
}
|
||||
|
||||
func (s *scenario) theAccountHasTheFollowingCustomMailboxes(username string, table *godog.Table) error {
|
||||
type mailbox struct {
|
||||
name string
|
||||
typ liteapi.LabelType
|
||||
type CustomMailbox struct {
|
||||
Name string `bdd:"name"`
|
||||
Type string `bdd:"type"`
|
||||
}
|
||||
|
||||
wantMailboxes := xslices.Map(table.Rows[1:], func(row *messages.PickleTableRow) mailbox {
|
||||
var mailboxType liteapi.LabelType
|
||||
|
||||
switch row.Cells[1].Value {
|
||||
case "folder":
|
||||
mailboxType = liteapi.LabelTypeFolder
|
||||
case "label":
|
||||
mailboxType = liteapi.LabelTypeLabel
|
||||
wantMailboxes, err := unmarshalTable[CustomMailbox](table)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return mailbox{
|
||||
name: row.Cells[0].Value,
|
||||
typ: mailboxType,
|
||||
}
|
||||
})
|
||||
|
||||
for _, wantMailbox := range wantMailboxes {
|
||||
if _, err := s.t.api.CreateLabel(s.t.getUserID(username), wantMailbox.name, wantMailbox.typ); err != nil {
|
||||
var labelType liteapi.LabelType
|
||||
|
||||
switch wantMailbox.Type {
|
||||
case "folder":
|
||||
labelType = liteapi.LabelTypeFolder
|
||||
|
||||
case "label":
|
||||
labelType = liteapi.LabelTypeLabel
|
||||
}
|
||||
|
||||
if _, err := s.t.api.CreateLabel(s.t.getUserID(username), wantMailbox.Name, labelType); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -117,7 +114,12 @@ func (s *scenario) theAddressOfAccountHasTheFollowingMessagesInMailbox(address,
|
||||
addrID := s.t.getUserAddrID(userID, address)
|
||||
mboxID := s.t.getMBoxID(userID, mailbox)
|
||||
|
||||
for _, wantMessage := range parseMessages(table) {
|
||||
wantMessages, err := unmarshalTable[Message](table)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, wantMessage := range wantMessages {
|
||||
if _, err := s.t.api.CreateMessage(
|
||||
userID,
|
||||
addrID,
|
||||
@ -125,8 +127,8 @@ func (s *scenario) theAddressOfAccountHasTheFollowingMessagesInMailbox(address,
|
||||
wantMessage.Subject,
|
||||
&mail.Address{Address: wantMessage.From},
|
||||
[]*mail.Address{{Address: wantMessage.To}},
|
||||
[]*mail.Address{},
|
||||
[]*mail.Address{},
|
||||
[]*mail.Address{{Address: wantMessage.CC}},
|
||||
[]*mail.Address{{Address: wantMessage.BCC}},
|
||||
"some body goes here",
|
||||
rfc822.TextPlain,
|
||||
wantMessage.Unread,
|
||||
|
||||
Reference in New Issue
Block a user