mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-10 04:36:43 +00:00
415 lines
9.3 KiB
Go
415 lines
9.3 KiB
Go
// Copyright (c) 2020 Proton Technologies AG
|
|
//
|
|
// This file is part of ProtonMail Bridge.
|
|
//
|
|
// ProtonMail Bridge is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// ProtonMail Bridge is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
package smtp
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net/mail"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
type testSendRecorderGetMessageMock struct {
|
|
message *pmapi.Message
|
|
err error
|
|
}
|
|
|
|
func (m *testSendRecorderGetMessageMock) GetMessage(messageID string) (*pmapi.Message, error) {
|
|
return m.message, m.err
|
|
}
|
|
|
|
func TestSendRecorder_getMessageHash(t *testing.T) {
|
|
q := newSendRecorder()
|
|
|
|
message := &pmapi.Message{
|
|
AddressID: "address123",
|
|
Subject: "Subject #1",
|
|
Sender: &mail.Address{
|
|
Address: "from@pm.me",
|
|
},
|
|
ToList: []*mail.Address{
|
|
{Address: "to@pm.me"},
|
|
},
|
|
CCList: []*mail.Address{},
|
|
BCCList: []*mail.Address{},
|
|
Body: "body",
|
|
Attachments: []*pmapi.Attachment{
|
|
{
|
|
Name: "att1",
|
|
MIMEType: "image/png",
|
|
Size: 12345,
|
|
},
|
|
},
|
|
}
|
|
hash := q.getMessageHash(message)
|
|
|
|
testCases := []struct {
|
|
message *pmapi.Message
|
|
expectEqual bool
|
|
}{
|
|
{
|
|
message,
|
|
true,
|
|
},
|
|
{
|
|
&pmapi.Message{},
|
|
false,
|
|
},
|
|
{ // Different AddressID
|
|
&pmapi.Message{
|
|
AddressID: "...",
|
|
Subject: "Subject #1",
|
|
Sender: &mail.Address{
|
|
Address: "from@pm.me",
|
|
},
|
|
ToList: []*mail.Address{
|
|
{Address: "to@pm.me"},
|
|
},
|
|
CCList: []*mail.Address{},
|
|
BCCList: []*mail.Address{},
|
|
Body: "body",
|
|
Attachments: []*pmapi.Attachment{
|
|
{
|
|
Name: "att1",
|
|
MIMEType: "image/png",
|
|
Size: 12345,
|
|
},
|
|
},
|
|
},
|
|
false,
|
|
},
|
|
{ // Different subject
|
|
&pmapi.Message{
|
|
AddressID: "address123",
|
|
Subject: "Subject #1.",
|
|
Sender: &mail.Address{
|
|
Address: "from@pm.me",
|
|
},
|
|
ToList: []*mail.Address{
|
|
{Address: "to@pm.me"},
|
|
},
|
|
CCList: []*mail.Address{},
|
|
BCCList: []*mail.Address{},
|
|
Body: "body",
|
|
Attachments: []*pmapi.Attachment{
|
|
{
|
|
Name: "att1",
|
|
MIMEType: "image/png",
|
|
Size: 12345,
|
|
},
|
|
},
|
|
},
|
|
false,
|
|
},
|
|
{ // Different sender
|
|
&pmapi.Message{
|
|
AddressID: "address123",
|
|
Subject: "Subject #1",
|
|
Sender: &mail.Address{
|
|
Address: "sender@pm.me",
|
|
},
|
|
ToList: []*mail.Address{
|
|
{Address: "to@pm.me"},
|
|
},
|
|
CCList: []*mail.Address{},
|
|
BCCList: []*mail.Address{},
|
|
Body: "body",
|
|
Attachments: []*pmapi.Attachment{
|
|
{
|
|
Name: "att1",
|
|
MIMEType: "image/png",
|
|
Size: 12345,
|
|
},
|
|
},
|
|
},
|
|
false,
|
|
},
|
|
{ // Different ToList - changed address
|
|
&pmapi.Message{
|
|
AddressID: "address123",
|
|
Subject: "Subject #1",
|
|
Sender: &mail.Address{
|
|
Address: "from@pm.me",
|
|
},
|
|
ToList: []*mail.Address{
|
|
{Address: "other@pm.me"},
|
|
},
|
|
CCList: []*mail.Address{},
|
|
BCCList: []*mail.Address{},
|
|
Body: "body",
|
|
Attachments: []*pmapi.Attachment{
|
|
{
|
|
Name: "att1",
|
|
MIMEType: "image/png",
|
|
Size: 12345,
|
|
},
|
|
},
|
|
},
|
|
false,
|
|
},
|
|
{ // Different ToList - more addresses
|
|
&pmapi.Message{
|
|
AddressID: "address123",
|
|
Subject: "Subject #1",
|
|
Sender: &mail.Address{
|
|
Address: "from@pm.me",
|
|
},
|
|
ToList: []*mail.Address{
|
|
{Address: "to@pm.me"},
|
|
{Address: "another@pm.me"},
|
|
},
|
|
CCList: []*mail.Address{},
|
|
BCCList: []*mail.Address{},
|
|
Body: "body",
|
|
Attachments: []*pmapi.Attachment{
|
|
{
|
|
Name: "att1",
|
|
MIMEType: "image/png",
|
|
Size: 12345,
|
|
},
|
|
},
|
|
},
|
|
false,
|
|
},
|
|
{ // Different CCList
|
|
&pmapi.Message{
|
|
AddressID: "address123",
|
|
Subject: "Subject #1",
|
|
Sender: &mail.Address{
|
|
Address: "from@pm.me",
|
|
},
|
|
ToList: []*mail.Address{
|
|
{Address: "to@pm.me"},
|
|
},
|
|
CCList: []*mail.Address{
|
|
{Address: "to@pm.me"},
|
|
},
|
|
BCCList: []*mail.Address{},
|
|
Body: "body",
|
|
Attachments: []*pmapi.Attachment{
|
|
{
|
|
Name: "att1",
|
|
MIMEType: "image/png",
|
|
Size: 12345,
|
|
},
|
|
},
|
|
},
|
|
false,
|
|
},
|
|
{ // Different BCCList
|
|
&pmapi.Message{
|
|
AddressID: "address123",
|
|
Subject: "Subject #1",
|
|
Sender: &mail.Address{
|
|
Address: "from@pm.me",
|
|
},
|
|
ToList: []*mail.Address{
|
|
{Address: "to@pm.me"},
|
|
},
|
|
CCList: []*mail.Address{},
|
|
BCCList: []*mail.Address{
|
|
{Address: "to@pm.me"},
|
|
},
|
|
Body: "body",
|
|
Attachments: []*pmapi.Attachment{
|
|
{
|
|
Name: "att1",
|
|
MIMEType: "image/png",
|
|
Size: 12345,
|
|
},
|
|
},
|
|
},
|
|
false,
|
|
},
|
|
{ // Different body
|
|
&pmapi.Message{
|
|
AddressID: "address123",
|
|
Subject: "Subject #1",
|
|
Sender: &mail.Address{
|
|
Address: "from@pm.me",
|
|
},
|
|
ToList: []*mail.Address{
|
|
{Address: "to@pm.me"},
|
|
},
|
|
CCList: []*mail.Address{},
|
|
BCCList: []*mail.Address{},
|
|
Body: "body.",
|
|
Attachments: []*pmapi.Attachment{
|
|
{
|
|
Name: "att1",
|
|
MIMEType: "image/png",
|
|
Size: 12345,
|
|
},
|
|
},
|
|
},
|
|
false,
|
|
},
|
|
{ // Different attachment - no attachment
|
|
&pmapi.Message{
|
|
AddressID: "address123",
|
|
Subject: "Subject #1",
|
|
Sender: &mail.Address{
|
|
Address: "from@pm.me",
|
|
},
|
|
ToList: []*mail.Address{
|
|
{Address: "to@pm.me"},
|
|
},
|
|
CCList: []*mail.Address{},
|
|
BCCList: []*mail.Address{},
|
|
Body: "body",
|
|
Attachments: []*pmapi.Attachment{},
|
|
},
|
|
false,
|
|
},
|
|
{ // Different attachment - name
|
|
&pmapi.Message{
|
|
AddressID: "address123",
|
|
Subject: "Subject #1",
|
|
Sender: &mail.Address{
|
|
Address: "from@pm.me",
|
|
},
|
|
ToList: []*mail.Address{
|
|
{Address: "to@pm.me"},
|
|
},
|
|
CCList: []*mail.Address{},
|
|
BCCList: []*mail.Address{},
|
|
Body: "body",
|
|
Attachments: []*pmapi.Attachment{
|
|
{
|
|
Name: "...",
|
|
MIMEType: "image/png",
|
|
Size: 12345,
|
|
},
|
|
},
|
|
},
|
|
false,
|
|
},
|
|
{ // Different attachment - MIMEType
|
|
&pmapi.Message{
|
|
AddressID: "address123",
|
|
Subject: "Subject #1",
|
|
Sender: &mail.Address{
|
|
Address: "from@pm.me",
|
|
},
|
|
ToList: []*mail.Address{
|
|
{Address: "to@pm.me"},
|
|
},
|
|
CCList: []*mail.Address{},
|
|
BCCList: []*mail.Address{},
|
|
Body: "body",
|
|
Attachments: []*pmapi.Attachment{
|
|
{
|
|
Name: "att1",
|
|
MIMEType: "image/jpeg",
|
|
Size: 12345,
|
|
},
|
|
},
|
|
},
|
|
false,
|
|
},
|
|
{ // Different attachment - Size
|
|
&pmapi.Message{
|
|
AddressID: "address123",
|
|
Subject: "Subject #1",
|
|
Sender: &mail.Address{
|
|
Address: "from@pm.me",
|
|
},
|
|
ToList: []*mail.Address{
|
|
{Address: "to@pm.me"},
|
|
},
|
|
CCList: []*mail.Address{},
|
|
BCCList: []*mail.Address{},
|
|
Body: "body",
|
|
Attachments: []*pmapi.Attachment{
|
|
{
|
|
Name: "att1",
|
|
MIMEType: "image/png",
|
|
Size: 42,
|
|
},
|
|
},
|
|
},
|
|
false,
|
|
},
|
|
}
|
|
for i, tc := range testCases {
|
|
tc := tc // bind
|
|
t.Run(fmt.Sprintf("%d / %v", i, tc.message), func(t *testing.T) {
|
|
newHash := q.getMessageHash(tc.message)
|
|
if tc.expectEqual {
|
|
assert.Equal(t, hash, newHash)
|
|
} else {
|
|
assert.NotEqual(t, hash, newHash)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSendRecorder_isSendingOrSent(t *testing.T) {
|
|
q := newSendRecorder()
|
|
q.addMessage("hash", "messageID")
|
|
|
|
testCases := []struct {
|
|
hash string
|
|
message *pmapi.Message
|
|
err error
|
|
wantIsSending bool
|
|
wantWasSent bool
|
|
}{
|
|
{"badhash", &pmapi.Message{Type: pmapi.MessageTypeDraft}, nil, false, false},
|
|
{"hash", nil, errors.New("message not found"), false, false},
|
|
{"hash", &pmapi.Message{Type: pmapi.MessageTypeInbox}, nil, false, false},
|
|
{"hash", &pmapi.Message{Type: pmapi.MessageTypeDraft, Time: time.Now().Add(-20 * time.Minute).Unix()}, nil, false, false},
|
|
{"hash", &pmapi.Message{Type: pmapi.MessageTypeDraft, Time: time.Now().Unix()}, nil, true, false},
|
|
{"hash", &pmapi.Message{Type: pmapi.MessageTypeSent}, nil, false, true},
|
|
{"hash", &pmapi.Message{Type: pmapi.MessageTypeInboxAndSent}, nil, false, true},
|
|
}
|
|
for i, tc := range testCases {
|
|
tc := tc // bind
|
|
t.Run(fmt.Sprintf("%d / %v / %v / %v", i, tc.hash, tc.message, tc.err), func(t *testing.T) {
|
|
messageGetter := &testSendRecorderGetMessageMock{message: tc.message, err: tc.err}
|
|
isSending, wasSent := q.isSendingOrSent(messageGetter, "hash")
|
|
assert.Equal(t, tc.wantIsSending, isSending, "isSending does not match")
|
|
assert.Equal(t, tc.wantWasSent, wasSent, "wasSent does not match")
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSendRecorder_deleteExpiredKeys(t *testing.T) {
|
|
q := newSendRecorder()
|
|
|
|
q.hashes["hash1"] = sendRecorderValue{
|
|
messageID: "msg1",
|
|
time: time.Now(),
|
|
}
|
|
q.hashes["hash2"] = sendRecorderValue{
|
|
messageID: "msg2",
|
|
time: time.Now().Add(-31 * time.Minute),
|
|
}
|
|
|
|
q.deleteExpiredKeys()
|
|
|
|
_, ok := q.hashes["hash1"]
|
|
assert.True(t, ok)
|
|
_, ok = q.hashes["hash2"]
|
|
assert.False(t, ok)
|
|
}
|