blob: 809aad8a3cbc1feb691f80128dd640b293a4d27f [file] [log] [blame]
Dusan Kasanc2129de2017-04-13 10:42:21 +02001package parsemail
Dusan Kasan17e497e2017-04-10 22:44:22 +02002
3import (
Dusan Kasan17e497e2017-04-10 22:44:22 +02004 "encoding/base64"
5 "io/ioutil"
Dusan Kasan4595dfe2017-04-13 00:38:24 +02006 "net/mail"
7 "strings"
8 "testing"
9 "time"
Dusan Kasan17e497e2017-04-10 22:44:22 +020010)
11
12func TestParseEmail(t *testing.T) {
Dusan Kasan4595dfe2017-04-13 00:38:24 +020013 var testData = map[int]struct {
Dusan Kasan17e497e2017-04-10 22:44:22 +020014 mailData string
15
Dusan Kasan4595dfe2017-04-13 00:38:24 +020016 subject string
17 date time.Time
18 from []mail.Address
19 sender mail.Address
20 to []mail.Address
21 replyTo []mail.Address
22 cc []mail.Address
23 bcc []mail.Address
24 messageID string
25 resentDate time.Time
26 resentFrom []mail.Address
27 resentSender mail.Address
28 resentTo []mail.Address
29 resentReplyTo []mail.Address
30 resentCc []mail.Address
31 resentBcc []mail.Address
Dusan Kasanb49ceb62017-04-13 00:00:36 +020032 resentMessageID string
Dusan Kasan4595dfe2017-04-13 00:38:24 +020033 inReplyTo []string
34 references []string
35 htmlBody string
36 textBody string
37 attachments []attachmentData
38 embeddedFiles []embeddedFileData
39 headerCheck func(mail.Header, *testing.T)
Dusan Kasan17e497e2017-04-10 22:44:22 +020040 }{
Dusan Kasanb49ceb62017-04-13 00:00:36 +020041 1: {
Dusan Kasan45ca2642017-04-18 10:39:35 +020042 mailData: rfc5322exampleA11,
Dusan Kasan4595dfe2017-04-13 00:38:24 +020043 subject: "Saying Hello",
Dusan Kasanb49ceb62017-04-13 00:00:36 +020044 from: []mail.Address{
Dusan Kasan45ca2642017-04-18 10:39:35 +020045 {
46 Name: "John Doe",
47 Address: "jdoe@machine.example",
48 },
Dusan Kasanb49ceb62017-04-13 00:00:36 +020049 },
50 to: []mail.Address{
Dusan Kasan45ca2642017-04-18 10:39:35 +020051 {
52 Name: "Mary Smith",
53 Address: "mary@example.net",
54 },
Dusan Kasanb49ceb62017-04-13 00:00:36 +020055 },
Dusan Kasan45ca2642017-04-18 10:39:35 +020056 sender: mail.Address{
57 Name: "Michael Jones",
58 Address: "mjones@machine.example",
59 },
Dusan Kasanb49ceb62017-04-13 00:00:36 +020060 messageID: "1234@local.machine.example",
Dusan Kasan4595dfe2017-04-13 00:38:24 +020061 date: parseDate("Fri, 21 Nov 1997 09:55:06 -0600"),
Dusan Kasanb49ceb62017-04-13 00:00:36 +020062 textBody: `This is a message just to say hello.
63So, "Hello".`,
64 },
65 2: {
Dusan Kasan45ca2642017-04-18 10:39:35 +020066 mailData: rfc5322exampleA12,
Dusan Kasanb49ceb62017-04-13 00:00:36 +020067 from: []mail.Address{
Dusan Kasan45ca2642017-04-18 10:39:35 +020068 {
69 Name: "Joe Q. Public",
70 Address: "john.q.public@example.com",
71 },
Dusan Kasanb49ceb62017-04-13 00:00:36 +020072 },
73 to: []mail.Address{
Dusan Kasan45ca2642017-04-18 10:39:35 +020074 {
75 Name: "Mary Smith",
76 Address: "mary@x.test",
77 },
78 {
79 Name: "",
80 Address: "jdoe@example.org",
81 },
82 {
83 Name: "Who?",
84 Address: "one@y.test",
85 },
Dusan Kasanb49ceb62017-04-13 00:00:36 +020086 },
87 cc: []mail.Address{
Dusan Kasan45ca2642017-04-18 10:39:35 +020088 {
89 Name: "",
90 Address: "boss@nil.test",
91 },
92 {
93 Name: "Giant; \"Big\" Box",
94 Address: "sysservices@example.net",
95 },
Dusan Kasanb49ceb62017-04-13 00:00:36 +020096 },
97 messageID: "5678.21-Nov-1997@example.com",
Dusan Kasan4595dfe2017-04-13 00:38:24 +020098 date: parseDate("Tue, 01 Jul 2003 10:52:37 +0200"),
99 textBody: `Hi everyone.`,
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200100 },
101 3: {
Dusan Kasan45ca2642017-04-18 10:39:35 +0200102 mailData: rfc5322exampleA2a,
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200103 subject: "Re: Saying Hello",
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200104 from: []mail.Address{
Dusan Kasan45ca2642017-04-18 10:39:35 +0200105 {
106 Name: "Mary Smith",
107 Address: "mary@example.net",
108 },
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200109 },
110 replyTo: []mail.Address{
Dusan Kasan45ca2642017-04-18 10:39:35 +0200111 {
112 Name: "Mary Smith: Personal Account",
113 Address: "smith@home.example",
114 },
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200115 },
116 to: []mail.Address{
Dusan Kasan45ca2642017-04-18 10:39:35 +0200117 {
118 Name: "John Doe",
119 Address: "jdoe@machine.example",
120 },
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200121 },
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200122 messageID: "3456@example.net",
123 inReplyTo: []string{"1234@local.machine.example"},
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200124 references: []string{"1234@local.machine.example"},
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200125 date: parseDate("Fri, 21 Nov 1997 10:01:10 -0600"),
126 textBody: `This is a reply to your hello.`,
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200127 },
128 4: {
Dusan Kasan45ca2642017-04-18 10:39:35 +0200129 mailData: rfc5322exampleA2b,
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200130 subject: "Re: Saying Hello",
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200131 from: []mail.Address{
Dusan Kasan45ca2642017-04-18 10:39:35 +0200132 {
133 Name: "John Doe",
134 Address: "jdoe@machine.example",
135 },
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200136 },
137 to: []mail.Address{
Dusan Kasan45ca2642017-04-18 10:39:35 +0200138 {
139 Name: "Mary Smith: Personal Account",
140 Address: "smith@home.example",
141 },
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200142 },
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200143 messageID: "abcd.1234@local.machine.test",
144 inReplyTo: []string{"3456@example.net"},
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200145 references: []string{"1234@local.machine.example", "3456@example.net"},
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200146 date: parseDate("Fri, 21 Nov 1997 11:00:00 -0600"),
147 textBody: `This is a reply to your reply.`,
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200148 },
149 5: {
Dusan Kasan45ca2642017-04-18 10:39:35 +0200150 mailData: rfc5322exampleA3,
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200151 subject: "Saying Hello",
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200152 from: []mail.Address{
Dusan Kasan45ca2642017-04-18 10:39:35 +0200153 {
154 Name: "John Doe",
155 Address: "jdoe@machine.example",
156 },
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200157 },
158 to: []mail.Address{
Dusan Kasan45ca2642017-04-18 10:39:35 +0200159 {
160 Name: "Mary Smith",
161 Address: "mary@example.net",
162 },
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200163 },
164 messageID: "1234@local.machine.example",
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200165 date: parseDate("Fri, 21 Nov 1997 09:55:06 -0600"),
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200166 resentFrom: []mail.Address{
Dusan Kasan45ca2642017-04-18 10:39:35 +0200167 {
168 Name: "Mary Smith",
169 Address: "mary@example.net",
170 },
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200171 },
172 resentTo: []mail.Address{
Dusan Kasan45ca2642017-04-18 10:39:35 +0200173 {
174 Name: "Jane Brown",
175 Address: "j-brown@other.example",
176 },
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200177 },
178 resentMessageID: "78910@example.net",
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200179 resentDate: parseDate("Mon, 24 Nov 1997 14:22:01 -0800"),
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200180 textBody: `This is a message just to say hello.
181So, "Hello".`,
182 },
183 6: {
Dusan Kasan45ca2642017-04-18 10:39:35 +0200184 mailData: data1,
Dusan Kasanf4376a62017-05-23 21:03:55 +0200185 subject: "Peter Paholík",
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200186 from: []mail.Address{
Dusan Kasan45ca2642017-04-18 10:39:35 +0200187 {
188 Name: "Peter Paholík",
189 Address: "peter.paholik@gmail.com",
190 },
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200191 },
192 to: []mail.Address{
Dusan Kasan45ca2642017-04-18 10:39:35 +0200193 {
194 Name: "",
195 Address: "dusan@kasan.sk",
196 },
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200197 },
Dusan Kasan17e497e2017-04-10 22:44:22 +0200198 messageID: "CACtgX4kNXE7T5XKSKeH_zEcfUUmf2vXVASxYjaaK9cCn-3zb_g@mail.gmail.com",
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200199 date: parseDate("Fri, 07 Apr 2017 09:17:26 +0200"),
200 htmlBody: "<div dir=\"ltr\"><br></div>",
Dusan Kasan17e497e2017-04-10 22:44:22 +0200201 attachments: []attachmentData{
202 {
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200203 filename: "Peter Paholík 1 4 2017 2017-04-07.pdf",
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200204 contentType: "application/pdf",
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200205 base64data: "JVBERi0xLjQNCiW1tbW1DQoxIDAgb2JqDQo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFIvTGFuZyhlbi1VUykgL1N0cnVjdFRyZWVSb290IDY3IDAgUi9NYXJrSW5mbzw8L01hcmtlZCB0cnVlPj4vT3V0cHV0SW50ZW50c1s8PC9UeXBlL091dHB1dEludGVudC9TL0dUU19QREZBMS9PdXRwdXRDb25kZXYgMzk1MzYyDQo+Pg0Kc3RhcnR4cmVmDQo0MTk4ODUNCiUlRU9GDQo=",
Dusan Kasan17e497e2017-04-10 22:44:22 +0200206 },
207 },
208 },
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200209 7: {
Dusan Kasan45ca2642017-04-18 10:39:35 +0200210 mailData: data2,
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200211 subject: "Re: Test Subject 2",
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200212 from: []mail.Address{
Dusan Kasan45ca2642017-04-18 10:39:35 +0200213 {
214 Name: "Sender Man",
215 Address: "sender@domain.com",
216 },
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200217 },
218 to: []mail.Address{
Dusan Kasan45ca2642017-04-18 10:39:35 +0200219 {
220 Name: "",
221 Address: "info@receiver.com",
222 },
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200223 },
224 cc: []mail.Address{
Dusan Kasan45ca2642017-04-18 10:39:35 +0200225 {
226 Name: "Cc Man",
227 Address: "ccman@gmail.com",
228 },
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200229 },
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200230 messageID: "0e9a21b4-01dc-e5c1-dcd6-58ce5aa61f4f@receiver.com",
231 inReplyTo: []string{"9ff38d03-c4ab-89b7-9328-e99d5e24e3ba@receiver.eu"},
Dusan Kasan17e497e2017-04-10 22:44:22 +0200232 references: []string{"2f6b7595-c01e-46e5-42bc-f263e1c4282d@receiver.com", "9ff38d03-c4ab-89b7-9328-e99d5e24e3ba@domain.com"},
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200233 date: parseDate("Fri, 07 Apr 2017 12:59:55 +0200"),
234 htmlBody: `<html>data<img src="part2.9599C449.04E5EC81@develhell.com"/></html>`,
Dusan Kasan17e497e2017-04-10 22:44:22 +0200235 textBody: `First level
236> Second level
237>> Third level
238>
239`,
240 embeddedFiles: []embeddedFileData{
241 {
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200242 cid: "part2.9599C449.04E5EC81@develhell.com",
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200243 contentType: "image/png",
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200244 base64data: "iVBORw0KGgoAAAANSUhEUgAAAQEAAAAYCAIAAAB1IN9NAAAACXBIWXMAAAsTAAALEwEAmpwYYKUKF+Os3baUndC0pDnwNAmLy1SUr2Gw0luxQuV/AwC6cEhVV5VRrwAAAABJRU5ErkJggg==",
Dusan Kasan17e497e2017-04-10 22:44:22 +0200245 },
246 },
247 },
248 }
249
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200250 for index, td := range testData {
Edwin Love0c868a42019-04-02 11:17:35 +0100251 e, err := Parse(strings.NewReader(td.mailData))
Dusan Kasan17e497e2017-04-10 22:44:22 +0200252 if err != nil {
253 t.Error(err)
254 }
255
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200256 if td.subject != e.Subject {
257 t.Errorf("[Test Case %v] Wrong subject. Expected: %s, Got: %s", index, td.subject, e.Subject)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200258 }
259
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200260 if td.messageID != e.MessageID {
261 t.Errorf("[Test Case %v] Wrong messageID. Expected: '%s', Got: '%s'", index, td.messageID, e.MessageID)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200262 }
263
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200264 if !td.date.Equal(e.Date) {
265 t.Errorf("[Test Case %v] Wrong date. Expected: %v, Got: %v", index, td.date, e.Date)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200266 }
267
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200268 d := dereferenceAddressList(e.From)
269 if !assertAddressListEq(td.from, d) {
270 t.Errorf("[Test Case %v] Wrong from. Expected: %s, Got: %s", index, td.from, d)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200271 }
272
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200273 var sender mail.Address
274 if e.Sender != nil {
275 sender = *e.Sender
276 }
277 if td.sender != sender {
278 t.Errorf("[Test Case %v] Wrong sender. Expected: %s, Got: %s", index, td.sender, sender)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200279 }
280
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200281 d = dereferenceAddressList(e.To)
282 if !assertAddressListEq(td.to, d) {
283 t.Errorf("[Test Case %v] Wrong to. Expected: %s, Got: %s", index, td.to, d)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200284 }
285
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200286 d = dereferenceAddressList(e.Cc)
287 if !assertAddressListEq(td.cc, d) {
288 t.Errorf("[Test Case %v] Wrong cc. Expected: %s, Got: %s", index, td.cc, d)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200289 }
290
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200291 d = dereferenceAddressList(e.Bcc)
292 if !assertAddressListEq(td.bcc, d) {
293 t.Errorf("[Test Case %v] Wrong bcc. Expected: %s, Got: %s", index, td.bcc, d)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200294 }
295
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200296 if td.resentMessageID != e.ResentMessageID {
297 t.Errorf("[Test Case %v] Wrong resent messageID. Expected: '%s', Got: '%s'", index, td.resentMessageID, e.ResentMessageID)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200298 }
299
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200300 if !td.resentDate.Equal(e.ResentDate) && !td.resentDate.IsZero() && !e.ResentDate.IsZero() {
301 t.Errorf("[Test Case %v] Wrong resent date. Expected: %v, Got: %v", index, td.resentDate, e.ResentDate)
302 }
303
304 d = dereferenceAddressList(e.ResentFrom)
305 if !assertAddressListEq(td.resentFrom, d) {
306 t.Errorf("[Test Case %v] Wrong resent from. Expected: %s, Got: %s", index, td.resentFrom, d)
307 }
308
309 var resentSender mail.Address
310 if e.ResentSender != nil {
311 resentSender = *e.ResentSender
312 }
313 if td.resentSender != resentSender {
314 t.Errorf("[Test Case %v] Wrong resent sender. Expected: %s, Got: %s", index, td.resentSender, resentSender)
315 }
316
317 d = dereferenceAddressList(e.ResentTo)
318 if !assertAddressListEq(td.resentTo, d) {
319 t.Errorf("[Test Case %v] Wrong resent to. Expected: %s, Got: %s", index, td.resentTo, d)
320 }
321
322 d = dereferenceAddressList(e.ResentCc)
323 if !assertAddressListEq(td.resentCc, d) {
324 t.Errorf("[Test Case %v] Wrong resent cc. Expected: %s, Got: %s", index, td.resentCc, d)
325 }
326
327 d = dereferenceAddressList(e.ResentBcc)
328 if !assertAddressListEq(td.resentBcc, d) {
329 t.Errorf("[Test Case %v] Wrong resent bcc. Expected: %s, Got: %s", index, td.resentBcc, d)
330 }
331
332 if !assertSliceEq(td.inReplyTo, e.InReplyTo) {
333 t.Errorf("[Test Case %v] Wrong in reply to. Expected: %s, Got: %s", index, td.inReplyTo, e.InReplyTo)
334 }
335
336 if !assertSliceEq(td.references, e.References) {
337 t.Errorf("[Test Case %v] Wrong references. Expected: %s, Got: %s", index, td.references, e.References)
338 }
339
340 d = dereferenceAddressList(e.ReplyTo)
341 if !assertAddressListEq(td.replyTo, d) {
342 t.Errorf("[Test Case %v] Wrong reply to. Expected: %s, Got: %s", index, td.replyTo, d)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200343 }
344
345 if td.htmlBody != e.HTMLBody {
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200346 t.Errorf("[Test Case %v] Wrong html body. Expected: '%s', Got: '%s'", index, td.htmlBody, e.HTMLBody)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200347 }
348
349 if td.textBody != e.TextBody {
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200350 t.Errorf("[Test Case %v] Wrong text body. Expected: '%s', Got: '%s'", index, td.textBody, e.TextBody)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200351 }
352
Dusan Kasan17e497e2017-04-10 22:44:22 +0200353 if len(td.attachments) != len(e.Attachments) {
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200354 t.Errorf("[Test Case %v] Incorrect number of attachments! Expected: %v, Got: %v.", index, len(td.attachments), len(e.Attachments))
Dusan Kasan17e497e2017-04-10 22:44:22 +0200355 } else {
356 attachs := e.Attachments[:]
357
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200358 for _, ad := range td.attachments {
Dusan Kasan17e497e2017-04-10 22:44:22 +0200359 found := false
360
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200361 for i, ra := range attachs {
Dusan Kasan17e497e2017-04-10 22:44:22 +0200362 b, err := ioutil.ReadAll(ra.Data)
363 if err != nil {
364 t.Error(err)
365 }
366
367 encoded := base64.StdEncoding.EncodeToString(b)
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200368 if ra.Filename == ad.filename && encoded == ad.base64data && ra.ContentType == ad.contentType {
Dusan Kasan17e497e2017-04-10 22:44:22 +0200369 found = true
370 attachs = append(attachs[:i], attachs[i+1:]...)
371 }
372 }
373
374 if !found {
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200375 t.Errorf("[Test Case %v] Attachment not found: %s", index, ad.filename)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200376 }
377 }
378
379 if len(attachs) != 0 {
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200380 t.Errorf("[Test Case %v] Email contains %v unexpected attachments: %v", index, len(attachs), attachs)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200381 }
382 }
383
384 if len(td.embeddedFiles) != len(e.EmbeddedFiles) {
Dusan Kasan1a966482017-04-18 10:45:25 +0200385 t.Errorf("[Test Case %v] Incorrect number of embedded files! Expected: %v, Got: %v.", index, len(td.embeddedFiles), len(e.EmbeddedFiles))
Dusan Kasan17e497e2017-04-10 22:44:22 +0200386 } else {
387 embeds := e.EmbeddedFiles[:]
388
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200389 for _, ad := range td.embeddedFiles {
Dusan Kasan17e497e2017-04-10 22:44:22 +0200390 found := false
391
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200392 for i, ra := range embeds {
Dusan Kasan17e497e2017-04-10 22:44:22 +0200393 b, err := ioutil.ReadAll(ra.Data)
394 if err != nil {
395 t.Error(err)
396 }
397
398 encoded := base64.StdEncoding.EncodeToString(b)
399
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200400 if ra.CID == ad.cid && encoded == ad.base64data && ra.ContentType == ad.contentType {
Dusan Kasan17e497e2017-04-10 22:44:22 +0200401 found = true
402 embeds = append(embeds[:i], embeds[i+1:]...)
403 }
404 }
405
406 if !found {
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200407 t.Errorf("[Test Case %v] Embedded file not found: %s", index, ad.cid)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200408 }
409 }
410
411 if len(embeds) != 0 {
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200412 t.Errorf("[Test Case %v] Email contains %v unexpected embedded files: %v", index, len(embeds), embeds)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200413 }
414 }
415 }
416}
417
418func parseDate(in string) time.Time {
419 out, err := time.Parse(time.RFC1123Z, in)
420 if err != nil {
421 panic(err)
422 }
423
424 return out
425}
426
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200427type attachmentData struct {
428 filename string
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200429 contentType string
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200430 base64data string
Dusan Kasan17e497e2017-04-10 22:44:22 +0200431}
432
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200433type embeddedFileData struct {
434 cid string
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200435 contentType string
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200436 base64data string
Dusan Kasan17e497e2017-04-10 22:44:22 +0200437}
438
439func assertSliceEq(a, b []string) bool {
440 if len(a) == len(b) && len(a) == 0 {
441 return true
442 }
443
444 if a == nil && b == nil {
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200445 return true
Dusan Kasan17e497e2017-04-10 22:44:22 +0200446 }
447
448 if a == nil || b == nil {
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200449 return false
Dusan Kasan17e497e2017-04-10 22:44:22 +0200450 }
451
452 if len(a) != len(b) {
453 return false
454 }
455
456 for i := range a {
457 if a[i] != b[i] {
458 return false
459 }
460 }
461
462 return true
463}
464
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200465func assertAddressListEq(a, b []mail.Address) bool {
466 if len(a) == len(b) && len(a) == 0 {
467 return true
468 }
469
470 if a == nil && b == nil {
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200471 return true
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200472 }
473
474 if a == nil || b == nil {
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200475 return false
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200476 }
477
478 if len(a) != len(b) {
479 return false
480 }
481
482 for i := range a {
483 if a[i] != b[i] {
484 return false
485 }
486 }
487
488 return true
489}
490
491func dereferenceAddressList(al []*mail.Address) (result []mail.Address) {
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200492 for _, a := range al {
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200493 result = append(result, *a)
494 }
495
496 return
497}
498
Dusan Kasan45ca2642017-04-18 10:39:35 +0200499var data1 = `From: =?UTF-8?Q?Peter_Pahol=C3=ADk?= <peter.paholik@gmail.com>
Dusan Kasan17e497e2017-04-10 22:44:22 +0200500Date: Fri, 7 Apr 2017 09:17:26 +0200
501Message-ID: <CACtgX4kNXE7T5XKSKeH_zEcfUUmf2vXVASxYjaaK9cCn-3zb_g@mail.gmail.com>
Dusan Kasanf4376a62017-05-23 21:03:55 +0200502Subject: =?UTF-8?Q?Peter_Pahol=C3=ADk?=
Dusan Kasan17e497e2017-04-10 22:44:22 +0200503To: dusan@kasan.sk
504Content-Type: multipart/mixed; boundary=f403045f1dcc043a44054c8e6bbf
505
506--f403045f1dcc043a44054c8e6bbf
507Content-Type: multipart/alternative; boundary=f403045f1dcc043a3f054c8e6bbd
508
509--f403045f1dcc043a3f054c8e6bbd
510Content-Type: text/plain; charset=UTF-8
511
512
513
514--f403045f1dcc043a3f054c8e6bbd
515Content-Type: text/html; charset=UTF-8
516
517<div dir="ltr"><br></div>
518
519--f403045f1dcc043a3f054c8e6bbd--
520--f403045f1dcc043a44054c8e6bbf
521Content-Type: application/pdf;
522 name="=?UTF-8?Q?Peter_Paholi=CC=81k_1?=
523 =?UTF-8?Q?_4_2017_2017=2D04=2D07=2Epdf?="
524Content-Disposition: attachment;
525 filename="=?UTF-8?Q?Peter_Paholi=CC=81k_1?=
526 =?UTF-8?Q?_4_2017_2017=2D04=2D07=2Epdf?="
527Content-Transfer-Encoding: base64
528X-Attachment-Id: f_j17i0f0d0
529
530JVBERi0xLjQNCiW1tbW1DQoxIDAgb2JqDQo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFIvTGFu
531Zyhlbi1VUykgL1N0cnVjdFRyZWVSb290IDY3IDAgUi9NYXJrSW5mbzw8L01hcmtlZCB0cnVlPj4v
532T3V0cHV0SW50ZW50c1s8PC9UeXBlL091dHB1dEludGVudC9TL0dUU19QREZBMS9PdXRwdXRDb25k
533ZXYgMzk1MzYyDQo+Pg0Kc3RhcnR4cmVmDQo0MTk4ODUNCiUlRU9GDQo=
534--f403045f1dcc043a44054c8e6bbf--
535`
536
Dusan Kasan45ca2642017-04-18 10:39:35 +0200537var data2 = `Subject: Re: Test Subject 2
Dusan Kasan17e497e2017-04-10 22:44:22 +0200538To: info@receiver.com
539References: <2f6b7595-c01e-46e5-42bc-f263e1c4282d@receiver.com>
540 <9ff38d03-c4ab-89b7-9328-e99d5e24e3ba@domain.com>
541Cc: Cc Man <ccman@gmail.com>
542From: Sender Man <sender@domain.com>
543Message-ID: <0e9a21b4-01dc-e5c1-dcd6-58ce5aa61f4f@receiver.com>
544Date: Fri, 7 Apr 2017 12:59:55 +0200
545User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:45.0)
546 Gecko/20100101 Thunderbird/45.8.0
547MIME-Version: 1.0
548In-Reply-To: <9ff38d03-c4ab-89b7-9328-e99d5e24e3ba@receiver.eu>
549Content-Type: multipart/alternative;
550 boundary="------------C70C0458A558E585ACB75FB4"
551
552This is a multi-part message in MIME format.
553--------------C70C0458A558E585ACB75FB4
554Content-Type: text/plain; charset=utf-8; format=flowed
555Content-Transfer-Encoding: 8bit
556
557First level
558> Second level
559>> Third level
560>
561
562
563--------------C70C0458A558E585ACB75FB4
564Content-Type: multipart/related;
565 boundary="------------5DB4A1356834BB602A5F88B2"
566
567
568--------------5DB4A1356834BB602A5F88B2
569Content-Type: text/html; charset=utf-8
570Content-Transfer-Encoding: 8bit
571
572<html>data<img src="part2.9599C449.04E5EC81@develhell.com"/></html>
573
574--------------5DB4A1356834BB602A5F88B2
575Content-Type: image/png
576Content-Transfer-Encoding: base64
577Content-ID: <part2.9599C449.04E5EC81@develhell.com>
578
579iVBORw0KGgoAAAANSUhEUgAAAQEAAAAYCAIAAAB1IN9NAAAACXBIWXMAAAsTAAALEwEAmpwY
580YKUKF+Os3baUndC0pDnwNAmLy1SUr2Gw0luxQuV/AwC6cEhVV5VRrwAAAABJRU5ErkJggg==
581--------------5DB4A1356834BB602A5F88B2
582
583--------------C70C0458A558E585ACB75FB4--
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200584`
585
Dusan Kasan45ca2642017-04-18 10:39:35 +0200586var rfc5322exampleA11 = `From: John Doe <jdoe@machine.example>
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200587Sender: Michael Jones <mjones@machine.example>
588To: Mary Smith <mary@example.net>
589Subject: Saying Hello
590Date: Fri, 21 Nov 1997 09:55:06 -0600
591Message-ID: <1234@local.machine.example>
592
593This is a message just to say hello.
594So, "Hello".
595`
596
Dusan Kasan45ca2642017-04-18 10:39:35 +0200597var rfc5322exampleA12 = `From: "Joe Q. Public" <john.q.public@example.com>
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200598To: Mary Smith <mary@x.test>, jdoe@example.org, Who? <one@y.test>
599Cc: <boss@nil.test>, "Giant; \"Big\" Box" <sysservices@example.net>
600Date: Tue, 1 Jul 2003 10:52:37 +0200
601Message-ID: <5678.21-Nov-1997@example.com>
602
603Hi everyone.
604`
605
606//todo: not yet implemented in net/mail
607//once there is support for this, add it
Dusan Kasan45ca2642017-04-18 10:39:35 +0200608var rfc5322exampleA13 = `From: Pete <pete@silly.example>
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200609To: A Group:Ed Jones <c@a.test>,joe@where.test,John <jdoe@one.test>;
610Cc: Undisclosed recipients:;
611Date: Thu, 13 Feb 1969 23:32:54 -0330
612Message-ID: <testabcd.1234@silly.example>
613
614Testing.
615`
616
617//we skipped the first message bcause it's the same as A 1.1
Dusan Kasan45ca2642017-04-18 10:39:35 +0200618var rfc5322exampleA2a = `From: Mary Smith <mary@example.net>
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200619To: John Doe <jdoe@machine.example>
620Reply-To: "Mary Smith: Personal Account" <smith@home.example>
621Subject: Re: Saying Hello
622Date: Fri, 21 Nov 1997 10:01:10 -0600
623Message-ID: <3456@example.net>
624In-Reply-To: <1234@local.machine.example>
625References: <1234@local.machine.example>
626
627This is a reply to your hello.
628`
629
Dusan Kasan45ca2642017-04-18 10:39:35 +0200630var rfc5322exampleA2b = `To: "Mary Smith: Personal Account" <smith@home.example>
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200631From: John Doe <jdoe@machine.example>
632Subject: Re: Saying Hello
633Date: Fri, 21 Nov 1997 11:00:00 -0600
634Message-ID: <abcd.1234@local.machine.test>
635In-Reply-To: <3456@example.net>
636References: <1234@local.machine.example> <3456@example.net>
637
638This is a reply to your reply.
639`
640
Dusan Kasan45ca2642017-04-18 10:39:35 +0200641var rfc5322exampleA3 = `Resent-From: Mary Smith <mary@example.net>
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200642Resent-To: Jane Brown <j-brown@other.example>
643Resent-Date: Mon, 24 Nov 1997 14:22:01 -0800
644Resent-Message-ID: <78910@example.net>
645From: John Doe <jdoe@machine.example>
646To: Mary Smith <mary@example.net>
647Subject: Saying Hello
648Date: Fri, 21 Nov 1997 09:55:06 -0600
649Message-ID: <1234@local.machine.example>
650
651This is a message just to say hello.
652So, "Hello".`
653
Dusan Kasan45ca2642017-04-18 10:39:35 +0200654var rfc5322exampleA4 = `Received: from x.y.test
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200655 by example.net
656 via TCP
657 with ESMTP
658 id ABC12345
659 for <mary@example.net>; 21 Nov 1997 10:05:43 -0600
660Received: from node.example by x.y.test; 21 Nov 1997 10:01:22 -0600
661From: John Doe <jdoe@node.example>
662To: Mary Smith <mary@example.net>
663Subject: Saying Hello
664Date: Fri, 21 Nov 1997 09:55:06 -0600
665Message-ID: <1234@local.node.example>
666
667This is a message just to say hello.
668So, "Hello".`