blob: 402ff1180ad052e0b8fc210bd98e0832968d8e59 [file] [log] [blame]
package parsemail_test
import (
"testing"
"github.com/DusanKasan/parsemail"
"strings"
"time"
"net/mail"
"encoding/base64"
"io/ioutil"
)
func TestParseEmail(t *testing.T) {
var testData = []struct{
mailData string
subject string
from []string
sender string
to []string
replyTo []string
cc []string
bcc []string
messageID string
inReplyTo []string
references []string
date time.Time
htmlBody string
textBody string
attachments []attachmentData
embeddedFiles []embeddedFileData
headerCheck func (mail.Header, *testing.T)
}{
{
mailData: Data1,
subject: "Test Subject 1",
from: []string{"Peter Paholík <peter.paholik@gmail.com>"},
to: []string{"dusan@kasan.sk"},
messageID: "CACtgX4kNXE7T5XKSKeH_zEcfUUmf2vXVASxYjaaK9cCn-3zb_g@mail.gmail.com",
date: parseDate("Fri, 07 Apr 2017 09:17:26 +0200"),
htmlBody: "<div dir=\"ltr\"><br></div>",
attachments: []attachmentData{
{
filename: "Peter Paholík 1 4 2017 2017-04-07.pdf",
base64data: "JVBERi0xLjQNCiW1tbW1DQoxIDAgb2JqDQo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFIvTGFuZyhlbi1VUykgL1N0cnVjdFRyZWVSb290IDY3IDAgUi9NYXJrSW5mbzw8L01hcmtlZCB0cnVlPj4vT3V0cHV0SW50ZW50c1s8PC9UeXBlL091dHB1dEludGVudC9TL0dUU19QREZBMS9PdXRwdXRDb25kZXYgMzk1MzYyDQo+Pg0Kc3RhcnR4cmVmDQo0MTk4ODUNCiUlRU9GDQo=",
},
},
},
{
mailData: Data2,
subject: "Re: Test Subject 2",
from: []string{"Sender Man <sender@domain.com>"},
to: []string{"info@receiver.com"},
cc: []string{"Cc Man <ccman@gmail.com>"},
messageID: "0e9a21b4-01dc-e5c1-dcd6-58ce5aa61f4f@receiver.com",
inReplyTo: []string{"9ff38d03-c4ab-89b7-9328-e99d5e24e3ba@receiver.eu"},
references: []string{"2f6b7595-c01e-46e5-42bc-f263e1c4282d@receiver.com", "9ff38d03-c4ab-89b7-9328-e99d5e24e3ba@domain.com"},
date: parseDate("Fri, 07 Apr 2017 12:59:55 +0200"),
htmlBody: `<html>data<img src="part2.9599C449.04E5EC81@develhell.com"/></html>`,
textBody: `First level
> Second level
>> Third level
>
`,
embeddedFiles: []embeddedFileData{
{
cid: "part2.9599C449.04E5EC81@develhell.com",
base64data: "iVBORw0KGgoAAAANSUhEUgAAAQEAAAAYCAIAAAB1IN9NAAAACXBIWXMAAAsTAAALEwEAmpwYYKUKF+Os3baUndC0pDnwNAmLy1SUr2Gw0luxQuV/AwC6cEhVV5VRrwAAAABJRU5ErkJggg==",
},
},
},
}
for _, td := range testData {
e, err := parsemail.Parse(strings.NewReader(td.mailData))
if err != nil {
t.Error(err)
}
if td.subject != e.Subject() {
t.Errorf("Wrong subject. Expected: %s, Got: %s", td.subject, e.Subject())
}
if td.sender != e.Sender() {
t.Errorf("Wrong sender. Expected: %s, Got: %s", td.sender, e.Sender())
}
if !assertSliceEq(td.from, e.From()) {
t.Errorf("Wrong from. Expected: %s, Got: %s", td.from, e.From())
}
if !assertSliceEq(td.inReplyTo, e.InReplyTo()) {
t.Errorf("Wrong in reply to. Expected: %s, Got: %s", td.inReplyTo, e.InReplyTo())
}
if !assertSliceEq(td.references, e.References()) {
t.Errorf("Wrong references. Expected: %s, Got: %s", td.references, e.References())
}
if !assertSliceEq(td.to, e.To()) {
t.Errorf("Wrong to. Expected: %s, Got: %s", td.to, e.To())
}
if !assertSliceEq(td.replyTo, e.ReplyTo()) {
t.Errorf("Wrong reply to. Expected: %s, Got: %s", td.replyTo, e.ReplyTo())
}
if !assertSliceEq(td.cc, e.Cc()) {
t.Errorf("Wrong cc. Expected: %s, Got: %s", td.cc, e.Cc())
}
if !assertSliceEq(td.bcc, e.Bcc()) {
t.Errorf("Wrong cc. Expected: %s, Got: %s", td.cc, e.Cc())
}
date, err := e.Date()
if err != nil {
t.Error(err)
} else if td.date != date {
t.Errorf("Wrong date. Expected: %v, Got: %v", td.date, date)
}
if td.htmlBody != e.HTMLBody {
t.Errorf("Wrong html body. Expected: '%s', Got: '%s'", td.htmlBody, e.HTMLBody)
}
if td.textBody != e.TextBody {
t.Errorf("Wrong text body. Expected: '%s', Got: '%s'", td.textBody, e.TextBody)
}
if td.messageID != e.MessageID() {
t.Errorf("Wrong messageID. Expected: '%s', Got: '%s'", td.messageID, e.MessageID())
}
if len(td.attachments) != len(e.Attachments) {
t.Errorf("Incorrect number of attachments! Expected: %v, Got: %v.", len(td.attachments), len(e.Attachments))
} else {
attachs := e.Attachments[:]
for _, ad := range(td.attachments) {
found := false
for i, ra := range(attachs) {
b, err := ioutil.ReadAll(ra.Data)
if err != nil {
t.Error(err)
}
encoded := base64.StdEncoding.EncodeToString(b)
if ra.Filename == ad.filename && encoded == ad.base64data {
found = true
attachs = append(attachs[:i], attachs[i+1:]...)
}
}
if !found {
t.Errorf("Attachment not found: %s", ad.filename)
}
}
if len(attachs) != 0 {
t.Errorf("Email contains %v unexpected attachments: %v", len(attachs), attachs)
}
}
if len(td.embeddedFiles) != len(e.EmbeddedFiles) {
t.Errorf("Incorrect number of embedded files! Expected: %s, Got: %s.", len(td.embeddedFiles), len(e.EmbeddedFiles))
} else {
embeds := e.EmbeddedFiles[:]
for _, ad := range(td.embeddedFiles) {
found := false
for i, ra := range(embeds) {
b, err := ioutil.ReadAll(ra.Data)
if err != nil {
t.Error(err)
}
encoded := base64.StdEncoding.EncodeToString(b)
if ra.CID == ad.cid && encoded == ad.base64data {
found = true
embeds = append(embeds[:i], embeds[i+1:]...)
}
}
if !found {
t.Errorf("Embedded file not found: %s", ad.cid)
}
}
if len(embeds) != 0 {
t.Errorf("Email contains %v unexpected embedded files: %v", len(embeds), embeds)
}
}
}
}
func parseDate(in string) time.Time {
out, err := time.Parse(time.RFC1123Z, in)
if err != nil {
panic(err)
}
return out
}
type attachmentData struct{
filename string
base64data string
}
type embeddedFileData struct{
cid string
base64data string
}
func assertSliceEq(a, b []string) bool {
if len(a) == len(b) && len(a) == 0 {
return true
}
if a == nil && b == nil {
return true;
}
if a == nil || b == nil {
return false;
}
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}
var Data1 = `From: =?UTF-8?Q?Peter_Pahol=C3=ADk?= <peter.paholik@gmail.com>
Date: Fri, 7 Apr 2017 09:17:26 +0200
Message-ID: <CACtgX4kNXE7T5XKSKeH_zEcfUUmf2vXVASxYjaaK9cCn-3zb_g@mail.gmail.com>
Subject: Test Subject 1
To: dusan@kasan.sk
Content-Type: multipart/mixed; boundary=f403045f1dcc043a44054c8e6bbf
--f403045f1dcc043a44054c8e6bbf
Content-Type: multipart/alternative; boundary=f403045f1dcc043a3f054c8e6bbd
--f403045f1dcc043a3f054c8e6bbd
Content-Type: text/plain; charset=UTF-8
--f403045f1dcc043a3f054c8e6bbd
Content-Type: text/html; charset=UTF-8
<div dir="ltr"><br></div>
--f403045f1dcc043a3f054c8e6bbd--
--f403045f1dcc043a44054c8e6bbf
Content-Type: application/pdf;
name="=?UTF-8?Q?Peter_Paholi=CC=81k_1?=
=?UTF-8?Q?_4_2017_2017=2D04=2D07=2Epdf?="
Content-Disposition: attachment;
filename="=?UTF-8?Q?Peter_Paholi=CC=81k_1?=
=?UTF-8?Q?_4_2017_2017=2D04=2D07=2Epdf?="
Content-Transfer-Encoding: base64
X-Attachment-Id: f_j17i0f0d0
JVBERi0xLjQNCiW1tbW1DQoxIDAgb2JqDQo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFIvTGFu
Zyhlbi1VUykgL1N0cnVjdFRyZWVSb290IDY3IDAgUi9NYXJrSW5mbzw8L01hcmtlZCB0cnVlPj4v
T3V0cHV0SW50ZW50c1s8PC9UeXBlL091dHB1dEludGVudC9TL0dUU19QREZBMS9PdXRwdXRDb25k
ZXYgMzk1MzYyDQo+Pg0Kc3RhcnR4cmVmDQo0MTk4ODUNCiUlRU9GDQo=
--f403045f1dcc043a44054c8e6bbf--
`
var Data2 = `Subject: Re: Test Subject 2
To: info@receiver.com
References: <2f6b7595-c01e-46e5-42bc-f263e1c4282d@receiver.com>
<9ff38d03-c4ab-89b7-9328-e99d5e24e3ba@domain.com>
Cc: Cc Man <ccman@gmail.com>
From: Sender Man <sender@domain.com>
Message-ID: <0e9a21b4-01dc-e5c1-dcd6-58ce5aa61f4f@receiver.com>
Date: Fri, 7 Apr 2017 12:59:55 +0200
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:45.0)
Gecko/20100101 Thunderbird/45.8.0
MIME-Version: 1.0
In-Reply-To: <9ff38d03-c4ab-89b7-9328-e99d5e24e3ba@receiver.eu>
Content-Type: multipart/alternative;
boundary="------------C70C0458A558E585ACB75FB4"
This is a multi-part message in MIME format.
--------------C70C0458A558E585ACB75FB4
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit
First level
> Second level
>> Third level
>
--------------C70C0458A558E585ACB75FB4
Content-Type: multipart/related;
boundary="------------5DB4A1356834BB602A5F88B2"
--------------5DB4A1356834BB602A5F88B2
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 8bit
<html>data<img src="part2.9599C449.04E5EC81@develhell.com"/></html>
--------------5DB4A1356834BB602A5F88B2
Content-Type: image/png
Content-Transfer-Encoding: base64
Content-ID: <part2.9599C449.04E5EC81@develhell.com>
iVBORw0KGgoAAAANSUhEUgAAAQEAAAAYCAIAAAB1IN9NAAAACXBIWXMAAAsTAAALEwEAmpwY
YKUKF+Os3baUndC0pDnwNAmLy1SUr2Gw0luxQuV/AwC6cEhVV5VRrwAAAABJRU5ErkJggg==
--------------5DB4A1356834BB602A5F88B2
--------------C70C0458A558E585ACB75FB4--
`