blob: b002a2859b753b2a944aeda2fe49b55e845c3d89 [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 },
Maya Rashishbae116e2019-06-10 12:15:25 +0300248 8: {
249 mailData: data3,
250 subject: "Re: kern/54143 (virtualbox)",
251 from: []mail.Address{
252 {
253 Name: "Rares",
254 Address: "rares@example.com",
255 },
256 },
257 to: []mail.Address{
258 {
259 Name: "",
260 Address: "bugs@example.com",
261 },
262 },
263 date: parseDate("Fri, 02 May 2019 11:25:35 +0300"),
264 textBody: `plain text part`,
265 },
Dusan Kasan17e497e2017-04-10 22:44:22 +0200266 }
267
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200268 for index, td := range testData {
Antonio331b1182019-01-15 09:58:52 +0100269 m, err := mail.ReadMessage(strings.NewReader(td.mailData))
270 if err != nil {
271 t.Error(err)
272 }
273 e, err := Parse(m)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200274 if err != nil {
275 t.Error(err)
276 }
277
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200278 if td.subject != e.Subject {
279 t.Errorf("[Test Case %v] Wrong subject. Expected: %s, Got: %s", index, td.subject, e.Subject)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200280 }
281
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200282 if td.messageID != e.MessageID {
283 t.Errorf("[Test Case %v] Wrong messageID. Expected: '%s', Got: '%s'", index, td.messageID, e.MessageID)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200284 }
285
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200286 if !td.date.Equal(e.Date) {
287 t.Errorf("[Test Case %v] Wrong date. Expected: %v, Got: %v", index, td.date, e.Date)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200288 }
289
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200290 d := dereferenceAddressList(e.From)
291 if !assertAddressListEq(td.from, d) {
292 t.Errorf("[Test Case %v] Wrong from. Expected: %s, Got: %s", index, td.from, d)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200293 }
294
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200295 var sender mail.Address
296 if e.Sender != nil {
297 sender = *e.Sender
298 }
299 if td.sender != sender {
300 t.Errorf("[Test Case %v] Wrong sender. Expected: %s, Got: %s", index, td.sender, sender)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200301 }
302
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200303 d = dereferenceAddressList(e.To)
304 if !assertAddressListEq(td.to, d) {
305 t.Errorf("[Test Case %v] Wrong to. Expected: %s, Got: %s", index, td.to, d)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200306 }
307
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200308 d = dereferenceAddressList(e.Cc)
309 if !assertAddressListEq(td.cc, d) {
310 t.Errorf("[Test Case %v] Wrong cc. Expected: %s, Got: %s", index, td.cc, d)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200311 }
312
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200313 d = dereferenceAddressList(e.Bcc)
314 if !assertAddressListEq(td.bcc, d) {
315 t.Errorf("[Test Case %v] Wrong bcc. Expected: %s, Got: %s", index, td.bcc, d)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200316 }
317
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200318 if td.resentMessageID != e.ResentMessageID {
319 t.Errorf("[Test Case %v] Wrong resent messageID. Expected: '%s', Got: '%s'", index, td.resentMessageID, e.ResentMessageID)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200320 }
321
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200322 if !td.resentDate.Equal(e.ResentDate) && !td.resentDate.IsZero() && !e.ResentDate.IsZero() {
323 t.Errorf("[Test Case %v] Wrong resent date. Expected: %v, Got: %v", index, td.resentDate, e.ResentDate)
324 }
325
326 d = dereferenceAddressList(e.ResentFrom)
327 if !assertAddressListEq(td.resentFrom, d) {
328 t.Errorf("[Test Case %v] Wrong resent from. Expected: %s, Got: %s", index, td.resentFrom, d)
329 }
330
331 var resentSender mail.Address
332 if e.ResentSender != nil {
333 resentSender = *e.ResentSender
334 }
335 if td.resentSender != resentSender {
336 t.Errorf("[Test Case %v] Wrong resent sender. Expected: %s, Got: %s", index, td.resentSender, resentSender)
337 }
338
339 d = dereferenceAddressList(e.ResentTo)
340 if !assertAddressListEq(td.resentTo, d) {
341 t.Errorf("[Test Case %v] Wrong resent to. Expected: %s, Got: %s", index, td.resentTo, d)
342 }
343
344 d = dereferenceAddressList(e.ResentCc)
345 if !assertAddressListEq(td.resentCc, d) {
346 t.Errorf("[Test Case %v] Wrong resent cc. Expected: %s, Got: %s", index, td.resentCc, d)
347 }
348
349 d = dereferenceAddressList(e.ResentBcc)
350 if !assertAddressListEq(td.resentBcc, d) {
351 t.Errorf("[Test Case %v] Wrong resent bcc. Expected: %s, Got: %s", index, td.resentBcc, d)
352 }
353
354 if !assertSliceEq(td.inReplyTo, e.InReplyTo) {
355 t.Errorf("[Test Case %v] Wrong in reply to. Expected: %s, Got: %s", index, td.inReplyTo, e.InReplyTo)
356 }
357
358 if !assertSliceEq(td.references, e.References) {
359 t.Errorf("[Test Case %v] Wrong references. Expected: %s, Got: %s", index, td.references, e.References)
360 }
361
362 d = dereferenceAddressList(e.ReplyTo)
363 if !assertAddressListEq(td.replyTo, d) {
364 t.Errorf("[Test Case %v] Wrong reply to. Expected: %s, Got: %s", index, td.replyTo, d)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200365 }
366
367 if td.htmlBody != e.HTMLBody {
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200368 t.Errorf("[Test Case %v] Wrong html body. Expected: '%s', Got: '%s'", index, td.htmlBody, e.HTMLBody)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200369 }
370
371 if td.textBody != e.TextBody {
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200372 t.Errorf("[Test Case %v] Wrong text body. Expected: '%s', Got: '%s'", index, td.textBody, e.TextBody)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200373 }
374
Dusan Kasan17e497e2017-04-10 22:44:22 +0200375 if len(td.attachments) != len(e.Attachments) {
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200376 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 +0200377 } else {
378 attachs := e.Attachments[:]
379
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200380 for _, ad := range td.attachments {
Dusan Kasan17e497e2017-04-10 22:44:22 +0200381 found := false
382
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200383 for i, ra := range attachs {
Dusan Kasan17e497e2017-04-10 22:44:22 +0200384 b, err := ioutil.ReadAll(ra.Data)
385 if err != nil {
386 t.Error(err)
387 }
388
389 encoded := base64.StdEncoding.EncodeToString(b)
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200390 if ra.Filename == ad.filename && encoded == ad.base64data && ra.ContentType == ad.contentType {
Dusan Kasan17e497e2017-04-10 22:44:22 +0200391 found = true
392 attachs = append(attachs[:i], attachs[i+1:]...)
393 }
394 }
395
396 if !found {
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200397 t.Errorf("[Test Case %v] Attachment not found: %s", index, ad.filename)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200398 }
399 }
400
401 if len(attachs) != 0 {
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200402 t.Errorf("[Test Case %v] Email contains %v unexpected attachments: %v", index, len(attachs), attachs)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200403 }
404 }
405
406 if len(td.embeddedFiles) != len(e.EmbeddedFiles) {
Dusan Kasan1a966482017-04-18 10:45:25 +0200407 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 +0200408 } else {
409 embeds := e.EmbeddedFiles[:]
410
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200411 for _, ad := range td.embeddedFiles {
Dusan Kasan17e497e2017-04-10 22:44:22 +0200412 found := false
413
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200414 for i, ra := range embeds {
Dusan Kasan17e497e2017-04-10 22:44:22 +0200415 b, err := ioutil.ReadAll(ra.Data)
416 if err != nil {
417 t.Error(err)
418 }
419
420 encoded := base64.StdEncoding.EncodeToString(b)
421
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200422 if ra.CID == ad.cid && encoded == ad.base64data && ra.ContentType == ad.contentType {
Dusan Kasan17e497e2017-04-10 22:44:22 +0200423 found = true
424 embeds = append(embeds[:i], embeds[i+1:]...)
425 }
426 }
427
428 if !found {
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200429 t.Errorf("[Test Case %v] Embedded file not found: %s", index, ad.cid)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200430 }
431 }
432
433 if len(embeds) != 0 {
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200434 t.Errorf("[Test Case %v] Email contains %v unexpected embedded files: %v", index, len(embeds), embeds)
Dusan Kasan17e497e2017-04-10 22:44:22 +0200435 }
436 }
437 }
438}
439
440func parseDate(in string) time.Time {
441 out, err := time.Parse(time.RFC1123Z, in)
442 if err != nil {
443 panic(err)
444 }
445
446 return out
447}
448
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200449type attachmentData struct {
450 filename string
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200451 contentType string
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200452 base64data string
Dusan Kasan17e497e2017-04-10 22:44:22 +0200453}
454
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200455type embeddedFileData struct {
456 cid string
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200457 contentType string
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200458 base64data string
Dusan Kasan17e497e2017-04-10 22:44:22 +0200459}
460
461func assertSliceEq(a, b []string) bool {
462 if len(a) == len(b) && len(a) == 0 {
463 return true
464 }
465
466 if a == nil && b == nil {
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200467 return true
Dusan Kasan17e497e2017-04-10 22:44:22 +0200468 }
469
470 if a == nil || b == nil {
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200471 return false
Dusan Kasan17e497e2017-04-10 22:44:22 +0200472 }
473
474 if len(a) != len(b) {
475 return false
476 }
477
478 for i := range a {
479 if a[i] != b[i] {
480 return false
481 }
482 }
483
484 return true
485}
486
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200487func assertAddressListEq(a, b []mail.Address) bool {
488 if len(a) == len(b) && len(a) == 0 {
489 return true
490 }
491
492 if a == nil && b == nil {
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200493 return true
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200494 }
495
496 if a == nil || b == nil {
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200497 return false
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200498 }
499
500 if len(a) != len(b) {
501 return false
502 }
503
504 for i := range a {
505 if a[i] != b[i] {
506 return false
507 }
508 }
509
510 return true
511}
512
513func dereferenceAddressList(al []*mail.Address) (result []mail.Address) {
Dusan Kasan4595dfe2017-04-13 00:38:24 +0200514 for _, a := range al {
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200515 result = append(result, *a)
516 }
517
518 return
519}
520
Dusan Kasan45ca2642017-04-18 10:39:35 +0200521var data1 = `From: =?UTF-8?Q?Peter_Pahol=C3=ADk?= <peter.paholik@gmail.com>
Dusan Kasan17e497e2017-04-10 22:44:22 +0200522Date: Fri, 7 Apr 2017 09:17:26 +0200
523Message-ID: <CACtgX4kNXE7T5XKSKeH_zEcfUUmf2vXVASxYjaaK9cCn-3zb_g@mail.gmail.com>
Dusan Kasanf4376a62017-05-23 21:03:55 +0200524Subject: =?UTF-8?Q?Peter_Pahol=C3=ADk?=
Dusan Kasan17e497e2017-04-10 22:44:22 +0200525To: dusan@kasan.sk
526Content-Type: multipart/mixed; boundary=f403045f1dcc043a44054c8e6bbf
527
528--f403045f1dcc043a44054c8e6bbf
529Content-Type: multipart/alternative; boundary=f403045f1dcc043a3f054c8e6bbd
530
531--f403045f1dcc043a3f054c8e6bbd
532Content-Type: text/plain; charset=UTF-8
533
534
535
536--f403045f1dcc043a3f054c8e6bbd
537Content-Type: text/html; charset=UTF-8
538
539<div dir="ltr"><br></div>
540
541--f403045f1dcc043a3f054c8e6bbd--
542--f403045f1dcc043a44054c8e6bbf
543Content-Type: application/pdf;
544 name="=?UTF-8?Q?Peter_Paholi=CC=81k_1?=
545 =?UTF-8?Q?_4_2017_2017=2D04=2D07=2Epdf?="
546Content-Disposition: attachment;
547 filename="=?UTF-8?Q?Peter_Paholi=CC=81k_1?=
548 =?UTF-8?Q?_4_2017_2017=2D04=2D07=2Epdf?="
549Content-Transfer-Encoding: base64
550X-Attachment-Id: f_j17i0f0d0
551
552JVBERi0xLjQNCiW1tbW1DQoxIDAgb2JqDQo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFIvTGFu
553Zyhlbi1VUykgL1N0cnVjdFRyZWVSb290IDY3IDAgUi9NYXJrSW5mbzw8L01hcmtlZCB0cnVlPj4v
554T3V0cHV0SW50ZW50c1s8PC9UeXBlL091dHB1dEludGVudC9TL0dUU19QREZBMS9PdXRwdXRDb25k
555ZXYgMzk1MzYyDQo+Pg0Kc3RhcnR4cmVmDQo0MTk4ODUNCiUlRU9GDQo=
556--f403045f1dcc043a44054c8e6bbf--
557`
558
Dusan Kasan45ca2642017-04-18 10:39:35 +0200559var data2 = `Subject: Re: Test Subject 2
Dusan Kasan17e497e2017-04-10 22:44:22 +0200560To: info@receiver.com
561References: <2f6b7595-c01e-46e5-42bc-f263e1c4282d@receiver.com>
562 <9ff38d03-c4ab-89b7-9328-e99d5e24e3ba@domain.com>
563Cc: Cc Man <ccman@gmail.com>
564From: Sender Man <sender@domain.com>
565Message-ID: <0e9a21b4-01dc-e5c1-dcd6-58ce5aa61f4f@receiver.com>
566Date: Fri, 7 Apr 2017 12:59:55 +0200
567User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:45.0)
568 Gecko/20100101 Thunderbird/45.8.0
569MIME-Version: 1.0
570In-Reply-To: <9ff38d03-c4ab-89b7-9328-e99d5e24e3ba@receiver.eu>
571Content-Type: multipart/alternative;
572 boundary="------------C70C0458A558E585ACB75FB4"
573
574This is a multi-part message in MIME format.
575--------------C70C0458A558E585ACB75FB4
576Content-Type: text/plain; charset=utf-8; format=flowed
577Content-Transfer-Encoding: 8bit
578
579First level
580> Second level
581>> Third level
582>
583
584
585--------------C70C0458A558E585ACB75FB4
586Content-Type: multipart/related;
587 boundary="------------5DB4A1356834BB602A5F88B2"
588
589
590--------------5DB4A1356834BB602A5F88B2
591Content-Type: text/html; charset=utf-8
592Content-Transfer-Encoding: 8bit
593
594<html>data<img src="part2.9599C449.04E5EC81@develhell.com"/></html>
595
596--------------5DB4A1356834BB602A5F88B2
597Content-Type: image/png
598Content-Transfer-Encoding: base64
599Content-ID: <part2.9599C449.04E5EC81@develhell.com>
600
601iVBORw0KGgoAAAANSUhEUgAAAQEAAAAYCAIAAAB1IN9NAAAACXBIWXMAAAsTAAALEwEAmpwY
602YKUKF+Os3baUndC0pDnwNAmLy1SUr2Gw0luxQuV/AwC6cEhVV5VRrwAAAABJRU5ErkJggg==
603--------------5DB4A1356834BB602A5F88B2
604
605--------------C70C0458A558E585ACB75FB4--
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200606`
607
Maya Rashishbae116e2019-06-10 12:15:25 +0300608var data3 = `From: Rares <rares@example.com>
609Date: Thu, 2 May 2019 11:25:35 +0300
610Subject: Re: kern/54143 (virtualbox)
611To: bugs@example.com
612Content-Type: multipart/mixed; boundary="0000000000007e2bb40587e36196"
613
614--0000000000007e2bb40587e36196
615Content-Type: text/plain; charset="UTF-8"
616
617plain text part
618--0000000000007e2bb40587e36196--
619`
620
Dusan Kasan45ca2642017-04-18 10:39:35 +0200621var rfc5322exampleA11 = `From: John Doe <jdoe@machine.example>
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200622Sender: Michael Jones <mjones@machine.example>
623To: Mary Smith <mary@example.net>
624Subject: Saying Hello
625Date: Fri, 21 Nov 1997 09:55:06 -0600
626Message-ID: <1234@local.machine.example>
627
628This is a message just to say hello.
629So, "Hello".
630`
631
Dusan Kasan45ca2642017-04-18 10:39:35 +0200632var rfc5322exampleA12 = `From: "Joe Q. Public" <john.q.public@example.com>
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200633To: Mary Smith <mary@x.test>, jdoe@example.org, Who? <one@y.test>
634Cc: <boss@nil.test>, "Giant; \"Big\" Box" <sysservices@example.net>
635Date: Tue, 1 Jul 2003 10:52:37 +0200
636Message-ID: <5678.21-Nov-1997@example.com>
637
638Hi everyone.
639`
640
641//todo: not yet implemented in net/mail
642//once there is support for this, add it
Dusan Kasan45ca2642017-04-18 10:39:35 +0200643var rfc5322exampleA13 = `From: Pete <pete@silly.example>
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200644To: A Group:Ed Jones <c@a.test>,joe@where.test,John <jdoe@one.test>;
645Cc: Undisclosed recipients:;
646Date: Thu, 13 Feb 1969 23:32:54 -0330
647Message-ID: <testabcd.1234@silly.example>
648
649Testing.
650`
651
652//we skipped the first message bcause it's the same as A 1.1
Dusan Kasan45ca2642017-04-18 10:39:35 +0200653var rfc5322exampleA2a = `From: Mary Smith <mary@example.net>
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200654To: John Doe <jdoe@machine.example>
655Reply-To: "Mary Smith: Personal Account" <smith@home.example>
656Subject: Re: Saying Hello
657Date: Fri, 21 Nov 1997 10:01:10 -0600
658Message-ID: <3456@example.net>
659In-Reply-To: <1234@local.machine.example>
660References: <1234@local.machine.example>
661
662This is a reply to your hello.
663`
664
Dusan Kasan45ca2642017-04-18 10:39:35 +0200665var rfc5322exampleA2b = `To: "Mary Smith: Personal Account" <smith@home.example>
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200666From: John Doe <jdoe@machine.example>
667Subject: Re: Saying Hello
668Date: Fri, 21 Nov 1997 11:00:00 -0600
669Message-ID: <abcd.1234@local.machine.test>
670In-Reply-To: <3456@example.net>
671References: <1234@local.machine.example> <3456@example.net>
672
673This is a reply to your reply.
674`
675
Dusan Kasan45ca2642017-04-18 10:39:35 +0200676var rfc5322exampleA3 = `Resent-From: Mary Smith <mary@example.net>
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200677Resent-To: Jane Brown <j-brown@other.example>
678Resent-Date: Mon, 24 Nov 1997 14:22:01 -0800
679Resent-Message-ID: <78910@example.net>
680From: John Doe <jdoe@machine.example>
681To: Mary Smith <mary@example.net>
682Subject: Saying Hello
683Date: Fri, 21 Nov 1997 09:55:06 -0600
684Message-ID: <1234@local.machine.example>
685
686This is a message just to say hello.
687So, "Hello".`
688
Dusan Kasan45ca2642017-04-18 10:39:35 +0200689var rfc5322exampleA4 = `Received: from x.y.test
Dusan Kasanb49ceb62017-04-13 00:00:36 +0200690 by example.net
691 via TCP
692 with ESMTP
693 id ABC12345
694 for <mary@example.net>; 21 Nov 1997 10:05:43 -0600
695Received: from node.example by x.y.test; 21 Nov 1997 10:01:22 -0600
696From: John Doe <jdoe@node.example>
697To: Mary Smith <mary@example.net>
698Subject: Saying Hello
699Date: Fri, 21 Nov 1997 09:55:06 -0600
700Message-ID: <1234@local.node.example>
701
702This is a message just to say hello.
703So, "Hello".`