go-mail/eml_test.go

1012 lines
38 KiB
Go
Raw Normal View History

// SPDX-FileCopyrightText: 2022-2023 The go-mail Authors
//
// SPDX-License-Identifier: MIT
package mail
import (
"bytes"
"fmt"
"os"
"strings"
"testing"
"time"
)
const (
// RFC 5322 example mail
// See: https://datatracker.ietf.org/doc/html/rfc5322#appendix-A.1.1
exampleMailRFC5322A11 = `From: John Doe <jdoe@machine.example>
To: Mary Smith <mary@example.net>
Subject: Saying Hello
Date: Fri, 21 Nov 1997 09:55:06 -0600
Message-ID: <1234@local.machine.example>
This is a message just to say hello.
So, "Hello".`
exampleMailPlainNoEnc = `Date: Wed, 01 Nov 2023 00:00:00 +0000
MIME-Version: 1.0
Message-ID: <1305604950.683004066175.AAAAAAAAaaaaaaaaB@go-mail.dev>
Subject: Example mail // plain text without encoding
User-Agent: go-mail v0.4.0 // https://github.com/wneessen/go-mail
X-Mailer: go-mail v0.4.0 // https://github.com/wneessen/go-mail
From: "Toni Tester" <go-mail@go-mail.dev>
To: <go-mail+test@go-mail.dev>
Cc: <go-mail+cc@go-mail.dev>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Dear Customer,
This is a test mail. Please do not reply to this. Also this line is very long so it
should be wrapped.
Thank your for your business!
The go-mail team
--
This is a signature`
exampleMailPlain7Bit = `Date: Wed, 01 Nov 2023 00:00:00 +0000
MIME-Version: 1.0
Message-ID: <1305604950.683004066175.AAAAAAAAaaaaaaaaB@go-mail.dev>
Subject: Example mail // plain text without encoding
User-Agent: go-mail v0.4.0 // https://github.com/wneessen/go-mail
X-Mailer: go-mail v0.4.0 // https://github.com/wneessen/go-mail
From: "Toni Tester" <go-mail@go-mail.dev>
To: <go-mail+test@go-mail.dev>
Cc: <go-mail+cc@go-mail.dev>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
Dear Customer,
This is a test mail. Please do not reply to this. Also this line is very long so it
should be wrapped.
Thank your for your business!
The go-mail team
--
This is a signature`
exampleMailPlainBrokenBody = `Date: Wed, 01 Nov 2023 00:00:00 +0000
MIME-Version: 1.0
Message-ID: <1305604950.683004066175.AAAAAAAAaaaaaaaaB@go-mail.dev>
Subject: Example mail // plain text without encoding
User-Agent: go-mail v0.4.0 // https://github.com/wneessen/go-mail
X-Mailer: go-mail v0.4.0 // https://github.com/wneessen/go-mail
From: "Toni Tester" <go-mail@go-mail.dev>
To: <go-mail+test@go-mail.dev>
Cc: <go-mail+cc@go-mail.dev>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: base64
This plain text body should not be parsed as Base64.
`
exampleMailPlainUnknownContentType = `Date: Wed, 01 Nov 2023 00:00:00 +0000
MIME-Version: 1.0
Message-ID: <1305604950.683004066175.AAAAAAAAaaaaaaaaB@go-mail.dev>
Subject: Example mail // plain text without encoding
User-Agent: go-mail v0.4.0 // https://github.com/wneessen/go-mail
X-Mailer: go-mail v0.4.0 // https://github.com/wneessen/go-mail
From: "Toni Tester" <go-mail@go-mail.dev>
To: <go-mail+test@go-mail.dev>
Cc: <go-mail+cc@go-mail.dev>
Content-Type: application/unknown; charset=UTF-8
Content-Transfer-Encoding: base64
This plain text body should not be parsed as Base64.
`
exampleMailPlainBrokenHeader = `Date: Wed, 01 Nov 2023 00:00:00 +0000
MIME-Version = 1.0
Message-ID: <1305604950.683004066175.AAAAAAAAaaaaaaaaB@go-mail.dev>
Subject: Example mail // plain text without encoding
User-Agent = go-mail v0.4.0 // https://github.com/wneessen/go-mail
X-Mailer: go-mail v0.4.0 // https://github.com/wneessen/go-mail
From = "Toni Tester" <go-mail@go-mail.dev>
To: <go-mail+test@go-mail.dev>
Cc: <go-mail+cc@go-mail.dev>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding = 8bit
Dear Customer,
This is a test mail. Please do not reply to this. Also this line is very long so it
should be wrapped.
Thank your for your business!
The go-mail team
--
This is a signature`
exampleMailPlainBrokenFrom = `Date: Wed, 01 Nov 2023 00:00:00 +0000
MIME-Version: 1.0
Message-ID: <1305604950.683004066175.AAAAAAAAaaaaaaaaB@go-mail.dev>
Subject: Example mail // plain text without encoding
User-Agent: go-mail v0.4.0 // https://github.com/wneessen/go-mail
X-Mailer: go-mail v0.4.0 // https://github.com/wneessen/go-mail
From: Toni Tester" go-mail@go-mail.dev>
To: <go-mail+test@go-mail.dev>
Cc: <go-mail+cc@go-mail.dev>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Dear Customer,
This is a test mail. Please do not reply to this. Also this line is very long so it
should be wrapped.
Thank your for your business!
The go-mail team
--
This is a signature`
exampleMailPlainBrokenTo = `Date: Wed, 01 Nov 2023 00:00:00 +0000
MIME-Version: 1.0
Message-ID: <1305604950.683004066175.AAAAAAAAaaaaaaaaB@go-mail.dev>
Subject: Example mail // plain text without encoding
User-Agent: go-mail v0.4.0 // https://github.com/wneessen/go-mail
X-Mailer: go-mail v0.4.0 // https://github.com/wneessen/go-mail
From: "Toni Tester" <go-mail@go-mail.dev>
To: go-mail+test.go-mail.dev>
Cc: <go-mail+cc@go-mail.dev>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Dear Customer,
This is a test mail. Please do not reply to this. Also this line is very long so it
should be wrapped.
Thank your for your business!
The go-mail team
--
This is a signature`
exampleMailPlainNoEncInvalidDate = `Date: Inv, 99 Nov 9999 99:99:00 +0000
MIME-Version: 1.0
Message-ID: <1305604950.683004066175.AAAAAAAAaaaaaaaaB@go-mail.dev>
Subject: Example mail // plain text without encoding
User-Agent: go-mail v0.4.0 // https://github.com/wneessen/go-mail
X-Mailer: go-mail v0.4.0 // https://github.com/wneessen/go-mail
From: "Toni Tester" <go-mail@go-mail.dev>
To: <go-mail+test@go-mail.dev>
Cc: <go-mail+cc@go-mail.dev>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Dear Customer,
This is a test mail. Please do not reply to this. Also this line is very long so it
should be wrapped.
Thank your for your business!
The go-mail team
--
This is a signature`
exampleMailPlainNoEncNoDate = `MIME-Version: 1.0
Message-ID: <1305604950.683004066175.AAAAAAAAaaaaaaaaB@go-mail.dev>
Subject: Example mail // plain text without encoding
User-Agent: go-mail v0.4.0 // https://github.com/wneessen/go-mail
X-Mailer: go-mail v0.4.0 // https://github.com/wneessen/go-mail
From: "Toni Tester" <go-mail@go-mail.dev>
To: <go-mail+test@go-mail.dev>
Cc: <go-mail+cc@go-mail.dev>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Dear Customer,
This is a test mail. Please do not reply to this. Also this line is very long so it
should be wrapped.
Thank your for your business!
The go-mail team
--
This is a signature`
exampleMailPlainQP = `Date: Wed, 01 Nov 2023 00:00:00 +0000
MIME-Version: 1.0
Message-ID: <1305604950.683004066175.AAAAAAAAaaaaaaaaB@go-mail.dev>
Subject: Example mail // plain text quoted-printable
User-Agent: go-mail v0.4.0 // https://github.com/wneessen/go-mail
X-Mailer: go-mail v0.4.0 // https://github.com/wneessen/go-mail
From: "Toni Tester" <go-mail@go-mail.dev>
To: <go-mail+test@go-mail.dev>
Cc: <go-mail+cc@go-mail.dev>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Dear Customer,
This is a test mail. Please do not reply to this. Also this line is very lo=
ng so it
should be wrapped.
Thank your for your business!
The go-mail team
--
This is a signature`
exampleMailPlainUnsupportedTransferEnc = `Date: Wed, 01 Nov 2023 00:00:00 +0000
MIME-Version: 1.0
Message-ID: <1305604950.683004066175.AAAAAAAAaaaaaaaaB@go-mail.dev>
Subject: Example mail // plain text quoted-printable
User-Agent: go-mail v0.4.0 // https://github.com/wneessen/go-mail
X-Mailer: go-mail v0.4.0 // https://github.com/wneessen/go-mail
From: "Toni Tester" <go-mail@go-mail.dev>
To: <go-mail+test@go-mail.dev>
Cc: <go-mail+cc@go-mail.dev>
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: unknown
Dear Customer,
This is a test mail. Please do not reply to this. Also this line is very long so it should be wrapped.
This is not ==D3
Thank your for your business!
The go-mail team
--
This is a signature`
exampleMailPlainB64 = `Date: Wed, 01 Nov 2023 00:00:00 +0000
MIME-Version: 1.0
Message-ID: <1305604950.683004066175.AAAAAAAAaaaaaaaaB@go-mail.dev>
Subject: Example mail // plain text base64
User-Agent: go-mail v0.4.0 // https://github.com/wneessen/go-mail
X-Mailer: go-mail v0.4.0 // https://github.com/wneessen/go-mail
From: "Toni Tester" <go-mail@go-mail.dev>
To: <go-mail+test@go-mail.dev>
Cc: <go-mail+cc@go-mail.dev>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: base64
RGVhciBDdXN0b21lciwKClRoaXMgaXMgYSB0ZXN0IG1haWwuIFBsZWFzZSBkbyBub3QgcmVwbHkg
dG8gdGhpcy4gQWxzbyB0aGlzIGxpbmUgaXMgdmVyeSBsb25nIHNvIGl0CnNob3VsZCBiZSB3cmFw
cGVkLgoKClRoYW5rIHlvdXIgZm9yIHlvdXIgYnVzaW5lc3MhClRoZSBnby1tYWlsIHRlYW0KCi0t
ClRoaXMgaXMgYSBzaWduYXR1cmU=`
exampleMailPlainB64WithAttachment = `Date: Wed, 01 Nov 2023 00:00:00 +0000
MIME-Version: 1.0
Message-ID: <1305604950.683004066175.AAAAAAAAaaaaaaaaB@go-mail.dev>
Subject: Example mail // plain text base64 with attachment
User-Agent: go-mail v0.4.1 // https://github.com/wneessen/go-mail
X-Mailer: go-mail v0.4.1 // https://github.com/wneessen/go-mail
From: "Toni Tester" <go-mail@go-mail.dev>
To: <go-mail+test@go-mail.dev>
Cc: <go-mail+cc@go-mail.dev>
Content-Type: multipart/mixed;
boundary=45c75ff528359022eb03679fbe91877d75343f2e1f8193e349deffa33ff7
--45c75ff528359022eb03679fbe91877d75343f2e1f8193e349deffa33ff7
Content-Transfer-Encoding: base64
Content-Type: text/plain; charset=UTF-8
RGVhciBDdXN0b21lciwKClRoaXMgaXMgYSB0ZXN0IG1haWwuIFBsZWFzZSBkbyBub3QgcmVwbHkg
dG8gdGhpcy4gQWxzbyB0aGlzIGxpbmUgaXMgdmVyeSBsb25nIHNvIGl0CnNob3VsZCBiZSB3cmFw
cGVkLgoKClRoYW5rIHlvdXIgZm9yIHlvdXIgYnVzaW5lc3MhClRoZSBnby1tYWlsIHRlYW0KCi0t
ClRoaXMgaXMgYSBzaWduYXR1cmU=
--45c75ff528359022eb03679fbe91877d75343f2e1f8193e349deffa33ff7
Content-Disposition: attachment; filename="test.attachment"
Content-Transfer-Encoding: base64
Content-Type: application/octet-stream; name="test.attachment"
VGhpcyBpcyBhIHNpbXBsZSB0ZXN0IHRleHQgZmlsZSBhdHRhY2htZW50LgoKSXQgCiAgaGFzCiAg
ICAgc2V2ZXJhbAogICAgICAgICAgICBuZXdsaW5lcwoJICAgICAgICAgICAgYW5kCgkgICAgc3Bh
Y2VzCiAgICAgaW4KICBpdAouCgpBcyB3ZWxsIGFzIGFuIGVtb2ppOiDwn5mCCg==
--45c75ff528359022eb03679fbe91877d75343f2e1f8193e349deffa33ff7--`
exampleMailPlainB64WithAttachmentNoBoundary = `Date: Wed, 01 Nov 2023 00:00:00 +0000
MIME-Version: 1.0
Message-ID: <1305604950.683004066175.AAAAAAAAaaaaaaaaB@go-mail.dev>
Subject: Example mail // plain text base64 with attachment
User-Agent: go-mail v0.4.1 // https://github.com/wneessen/go-mail
X-Mailer: go-mail v0.4.1 // https://github.com/wneessen/go-mail
From: "Toni Tester" <go-mail@go-mail.dev>
To: <go-mail+test@go-mail.dev>
Cc: <go-mail+cc@go-mail.dev>
Content-Type: multipart/mixed;
--45c75ff528359022eb03679fbe91877d75343f2e1f8193e349deffa33ff7
Content-Transfer-Encoding: base64
Content-Type: text/plain; charset=UTF-8
RGVhciBDdXN0b21lciwKClRoaXMgaXMgYSB0ZXN0IG1haWwuIFBsZWFzZSBkbyBub3QgcmVwbHkg
dG8gdGhpcy4gQWxzbyB0aGlzIGxpbmUgaXMgdmVyeSBsb25nIHNvIGl0CnNob3VsZCBiZSB3cmFw
cGVkLgoKClRoYW5rIHlvdXIgZm9yIHlvdXIgYnVzaW5lc3MhClRoZSBnby1tYWlsIHRlYW0KCi0t
ClRoaXMgaXMgYSBzaWduYXR1cmU=
--45c75ff528359022eb03679fbe91877d75343f2e1f8193e349deffa33ff7
Content-Disposition: attachment; filename="test.attachment"
Content-Transfer-Encoding: base64
Content-Type: application/octet-stream; name="test.attachment"
VGhpcyBpcyBhIHNpbXBsZSB0ZXN0IHRleHQgZmlsZSBhdHRhY2htZW50LgoKSXQgCiAgaGFzCiAg
ICAgc2V2ZXJhbAogICAgICAgICAgICBuZXdsaW5lcwoJICAgICAgICAgICAgYW5kCgkgICAgc3Bh
Y2VzCiAgICAgaW4KICBpdAouCgpBcyB3ZWxsIGFzIGFuIGVtb2ppOiDwn5mCCg==
--45c75ff528359022eb03679fbe91877d75343f2e1f8193e349deffa33ff7--`
exampleMailPlainB64BrokenBody = `Date: Wed, 01 Nov 2023 00:00:00 +0000
MIME-Version: 1.0
Message-ID: <1305604950.683004066175.AAAAAAAAaaaaaaaaB@go-mail.dev>
Subject: Example mail // plain text base64 with attachment
User-Agent: go-mail v0.4.1 // https://github.com/wneessen/go-mail
X-Mailer: go-mail v0.4.1 // https://github.com/wneessen/go-mail
From: "Toni Tester" <go-mail@go-mail.dev>
To: <go-mail+test@go-mail.dev>
Cc: <go-mail+cc@go-mail.dev>
Content-Type: multipart/mixed;
boundary=45c75ff528359022eb03679fbe91877d75343f2e1f8193e349deffa33ff7
--45c75ff528359022eb03679fbe91877d75343f2e1f8193e349deffa33ff7
Content-Transfer-Encoding = base64
Content-Type = text/plain; charset=UTF-8
RGVhciBDdXN0b21lciwKClRoaXMgaXMgYSB0ZXN0IG1haWwuIFBsZWFzZSBkbyBub3QgcmVwbHkg
dG8gdGhpcy4gQWxzbyB0aGlzIGxpbmUgaXMgdmVyeSBsb25nIHNvIGl0CnNob3VsZCBiZSB3cmFw
cGVkLgoKClRoYW5rIHlvdXIgZm9yIHlvdXIgYnVzaW5lc3MhClRoZSBnby1tYWlsIHRlYW0KCi0t
ClRoaXMgaXMgYSBzaWduYXR1cmU=
--45c75ff528359022eb03679fbe91877d75343f2e1f8193e349deffa33ff7
Content-Disposition: attachment; filename="test.attachment"
Content-Transfer-Encoding: base64
Content-Type: application/octet-stream; name="test.attachment"
VGhpcyBpcyBhIHNpbXBsZSB0ZXN0IHRleHQgZmlsZSBhdHRhY2htZW50LgoKSXQgCiAgaGFzCiAg
ICAgc2V2ZXJhbAogICAgICAgICAgICBuZXdsaW5lcwoJICAgICAgICAgICAgYW5kCgkgICAgc3Bh
Y2VzCiAgICAgaW4KICBpdAouCgpBcyB3ZWxsIGFzIGFuIGVtb2ppOiDwn5mCCg==
--45c75ff528359022eb03679fbe91877d75343f2e1f8193e349deffa33ff7--`
exampleMailPlainB64WithEmbed = `Date: Wed, 01 Nov 2023 00:00:00 +0000
MIME-Version: 1.0
Message-ID: <1305604950.683004066175.AAAAAAAAaaaaaaaaB@go-mail.dev>
Subject: Example mail // plain text base64 with embed
User-Agent: go-mail v0.4.1 // https://github.com/wneessen/go-mail
X-Mailer: go-mail v0.4.1 // https://github.com/wneessen/go-mail
From: "Toni Tester" <go-mail@go-mail.dev>
To: <go-mail+test@go-mail.dev>
Cc: <go-mail+cc@go-mail.dev>
Content-Type: multipart/related;
boundary=ffbcfb94b44e5297325102f6ced05b3b37f1d70fc38a5e78dc73c1a8434b
--ffbcfb94b44e5297325102f6ced05b3b37f1d70fc38a5e78dc73c1a8434b
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
This is a test body string
--ffbcfb94b44e5297325102f6ced05b3b37f1d70fc38a5e78dc73c1a8434b
Content-Disposition: inline; filename="pixel.png"
Content-Id: <pixel.png>
Content-Transfer-Encoding: base64
Content-Type: image/png; name="pixel.png"
iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIW2NgYGD4DwABBAEAwS2O
UAAAAABJRU5ErkJggg==
--ffbcfb94b44e5297325102f6ced05b3b37f1d70fc38a5e78dc73c1a8434b--`
exampleMailPlainB64WithEmbedNoContentID = `Date: Wed, 01 Nov 2023 00:00:00 +0000
MIME-Version: 1.0
Message-ID: <1305604950.683004066175.AAAAAAAAaaaaaaaaB@go-mail.dev>
Subject: Example mail // plain text base64 with embed
User-Agent: go-mail v0.4.1 // https://github.com/wneessen/go-mail
X-Mailer: go-mail v0.4.1 // https://github.com/wneessen/go-mail
From: "Toni Tester" <go-mail@go-mail.dev>
To: <go-mail+test@go-mail.dev>
Cc: <go-mail+cc@go-mail.dev>
Content-Type: multipart/related;
boundary=ffbcfb94b44e5297325102f6ced05b3b37f1d70fc38a5e78dc73c1a8434b
--ffbcfb94b44e5297325102f6ced05b3b37f1d70fc38a5e78dc73c1a8434b
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
This is a test body string
--ffbcfb94b44e5297325102f6ced05b3b37f1d70fc38a5e78dc73c1a8434b
Content-Disposition: inline; filename="pixel.png"
Content-Transfer-Encoding: base64
Content-Type: image/png; name="pixel.png"
iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIW2NgYGD4DwABBAEAwS2O
UAAAAABJRU5ErkJggg==
--ffbcfb94b44e5297325102f6ced05b3b37f1d70fc38a5e78dc73c1a8434b--`
exampleMailMultipartMixedAlternativeRelated = `Date: Wed, 01 Nov 2023 00:00:00 +0000
MIME-Version: 1.0
Message-ID: <1305604950.683004066175.AAAAAAAAaaaaaaaaB@go-mail.dev>
Subject: Example mail // plain text base64 with attachment, embed and alternative part
User-Agent: go-mail v0.4.1 // https://github.com/wneessen/go-mail
X-Mailer: go-mail v0.4.1 // https://github.com/wneessen/go-mail
From: "Toni Tester" <go-mail@go-mail.dev>
To: <go-mail+test@go-mail.dev>
Cc: <go-mail+cc@go-mail.dev>
Content-Type: multipart/mixed;
boundary=fe785e0384e2607697cc2ecb17cce003003bb7ca9112104f3e8ce727edb5
--fe785e0384e2607697cc2ecb17cce003003bb7ca9112104f3e8ce727edb5
Content-Type: multipart/related;
boundary=5897e40a22c608e252cfab849e966112fcbd5a1c291208026b3ca2bfab8a
--5897e40a22c608e252cfab849e966112fcbd5a1c291208026b3ca2bfab8a
Content-Type: multipart/alternative;
boundary=cbace12de35ef4eae53fd974ccd41cb2aee4f9c9c76057ec8bfdd0c97813
--cbace12de35ef4eae53fd974ccd41cb2aee4f9c9c76057ec8bfdd0c97813
Content-Transfer-Encoding: base64
Content-Type: text/plain; charset=UTF-8
RGVhciBDdXN0b21lciwKCkdvb2QgbmV3cyEgWW91ciBvcmRlciBpcyBvbiB0aGUgd2F5IGFuZCBp
bnZvaWNlIGlzIGF0dGFjaGVkIQoKWW91IHdpbGwgZmluZCB5b3VyIHRyYWNraW5nIG51bWJlciBv
biB0aGUgaW52b2ljZS4gVHJhY2tpbmcgZGF0YSBtYXkgdGFrZQp1cCB0byAyNCBob3VycyB0byBi
ZSBhY2Nlc3NpYmxlIG9ubGluZS4KCuKAoiBQbGVhc2UgcmVtaXQgcGF5bWVudCBhdCB5b3VyIGVh
cmxpZXN0IGNvbnZlbmllbmNlIHVubGVzcyBpbnZvaWNlIGlzCm1hcmtlZCDigJxQQUlE4oCdLgri
gKIgU29tZSBpdGVtcyBtYXkgc2hpcCBzZXBhcmF0ZWx5IGZyb20gbXVsdGlwbGUgbG9jYXRpb25z
LiBTZXBhcmF0ZQppbnZvaWNlcyB3aWxsIGJlIGlzc3VlZCB3aGVuIGFwcGxpY2FibGUuCuKAoiBQ
TEVBU0UgSU5TUEVDVCBVUE9OIFJFQ0VJUFQgRk9SIFBBVFRFUk4sIENPTE9SLCBERUZFQ1RTLCBE
QU1BR0UgRlJPTQpTSElQUElORywgQ09SUkVDVCBZQVJEQUdFLCBFVEMhIE9uY2UgYW4gb3JkZXIg
aXMgY3V0IG9yIHNld24sIG5vIHJldHVybnMKd2lsbCBiZSBhY2NlcHRlZCBmb3IgYW55IHJlYXNv
biwgbm8gbWF0dGVyIHRoZSBwYXJ0eSBpbiBlcnJvci4gTm8gcmV0dXJucwp3aWxsIGJlIGF1dGhv
cml6ZWQgYWZ0ZXIgMzAgZGF5cyBvZiBpbnZvaWNlIGRhdGUuIE5vIGV4Y2VwdGlvbnMgd2lsbCBi
ZQptYWRlLgoKVGhhbmsgeW91ciBmb3IgeW91ciBidXNpbmVzcyEKCk5haWxkb2N0b3IgRmFicmlj
cw==
--cbace12de35ef4eae53fd974ccd41cb2aee4f9c9c76057ec8bfdd0c97813
Content-Transfer-Encoding: base64
Content-Type: text/html; charset=UTF-8
PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KPGJvZHk+CjxwPlRoaXMgaXMgSFRNTCA8
c3Ryb25nPmluIEJPTEQ8L3N0cm9uZz4KPHA+ClRoaXMgaXMgYW4gZW1iZWRkZWQgcGljdHVyZTog
CjxpbWcgYWx0PSJwaXhlbC5wbmciIHNyYz0iY2lkOmltYWdlMS5wbmciPgo8YnI+Rm9vPC9wPg==
--cbace12de35ef4eae53fd974ccd41cb2aee4f9c9c76057ec8bfdd0c97813--
--5897e40a22c608e252cfab849e966112fcbd5a1c291208026b3ca2bfab8a
Content-Disposition: inline; filename="pixel.png"
Content-Id: image1.png
Content-Transfer-Encoding: base64
Content-Type: image/png; name="pixel.png"
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAAAAACoWZBhAAAFEmlUWHRYTUw6Y29tLmFkb2JlLnht
cAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQi
Pz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUg
NS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIy
LXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1s
bnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgeG1sbnM6cGhvdG9zaG9w
PSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6ZXhpZj0iaHR0
cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iCiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRv
YmUuY29tL3RpZmYvMS4wLyIKICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hh
cC8xLjAvbW0vIgogICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9z
VHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgeG1wOkNyZWF0ZURhdGU9IjIwMjQtMDYtMjhUMTM6MjY6
MDYrMDIwMCIKICAgeG1wOk1vZGlmeURhdGU9IjIwMjQtMDYtMjhUMTM6Mjc6MDgrMDI6MDAiCiAg
IHhtcDpNZXRhZGF0YURhdGU9IjIwMjQtMDYtMjhUMTM6Mjc6MDgrMDI6MDAiCiAgIHBob3Rvc2hv
cDpEYXRlQ3JlYXRlZD0iMjAyNC0wNi0yOFQxMzoyNjowNiswMjAwIgogICBwaG90b3Nob3A6Q29s
b3JNb2RlPSIxIgogICBwaG90b3Nob3A6SUNDUHJvZmlsZT0iR3JleXNjYWxlIEQ1MCIKICAgZXhp
ZjpQaXhlbFhEaW1lbnNpb249IjEwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTAiCiAgIGV4
aWY6Q29sb3JTcGFjZT0iNjU1MzUiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMTAiCiAgIHRpZmY6SW1h
Z2VMZW5ndGg9IjEwIgogICB0aWZmOlJlc29sdXRpb25Vbml0PSIyIgogICB0aWZmOlhSZXNvbHV0
aW9uPSI3Mi8xIgogICB0aWZmOllSZXNvbHV0aW9uPSI3Mi8xIj4KICAgPHhtcE1NOkhpc3Rvcnk+
CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0icHJvZHVjZWQi
CiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFmZmluaXR5IFBob3RvIDIgMi4zLjAiCiAgICAg
IHN0RXZ0OndoZW49IjIwMjQtMDYtMjhUMTM6Mjc6MDgrMDI6MDAiLz4KICAgIDwvcmRmOlNlcT4K
ICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6
eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/PpwIGG4AAADdaUNDUEdyZXlzY2FsZSBENTAAABiV
dVC9CsJAGEul6KCDg4vSoQ+gIIjiKoou6qAVrLiUs/5gq8e1In0v30TwGRycnc0VcRD9IJdwfMmR
A4xlIMLIrAPhIVaDSceduws7d0cWFvIow/JEJEfTvoO/87zB0Hyt6az/ez/HXPmRIF+IlpAqJj+I
4TmW1EaburR3Jl3qIXUxDE7i7dWvFvzDbEquEBYGUPCRIIKAh4DaRg9N6H6/ffXUN8aRm4KnpFth
hw22iFHl7YlpOmedZvtMTfQffXeXnvI+rTKNxguyvDKvB7U4qQAAAAlwSFlzAAALEwAACxMBAJqc
GAAAABFJREFUCJljnMoAA0wMNGcCAEQrAKk9oHKhAAAAAElFTkSuQmCC
--5897e40a22c608e252cfab849e966112fcbd5a1c291208026b3ca2bfab8a--
--fe785e0384e2607697cc2ecb17cce003003bb7ca9112104f3e8ce727edb5
Content-Disposition: attachment; filename="attachment.png"
Content-Transfer-Encoding: base64
Content-Type: image/png; name="attachment.png"
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAAAAACoWZBhAAAFEmlUWHRYTUw6Y29tLmFkb2JlLnht
cAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQi
Pz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUg
NS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIy
LXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1s
bnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgeG1sbnM6cGhvdG9zaG9w
PSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6ZXhpZj0iaHR0
cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iCiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRv
YmUuY29tL3RpZmYvMS4wLyIKICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hh
cC8xLjAvbW0vIgogICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9z
VHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgeG1wOkNyZWF0ZURhdGU9IjIwMjQtMDYtMjhUMTM6MjY6
MDYrMDIwMCIKICAgeG1wOk1vZGlmeURhdGU9IjIwMjQtMDYtMjhUMTM6Mjc6MDgrMDI6MDAiCiAg
IHhtcDpNZXRhZGF0YURhdGU9IjIwMjQtMDYtMjhUMTM6Mjc6MDgrMDI6MDAiCiAgIHBob3Rvc2hv
cDpEYXRlQ3JlYXRlZD0iMjAyNC0wNi0yOFQxMzoyNjowNiswMjAwIgogICBwaG90b3Nob3A6Q29s
b3JNb2RlPSIxIgogICBwaG90b3Nob3A6SUNDUHJvZmlsZT0iR3JleXNjYWxlIEQ1MCIKICAgZXhp
ZjpQaXhlbFhEaW1lbnNpb249IjEwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTAiCiAgIGV4
aWY6Q29sb3JTcGFjZT0iNjU1MzUiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMTAiCiAgIHRpZmY6SW1h
Z2VMZW5ndGg9IjEwIgogICB0aWZmOlJlc29sdXRpb25Vbml0PSIyIgogICB0aWZmOlhSZXNvbHV0
aW9uPSI3Mi8xIgogICB0aWZmOllSZXNvbHV0aW9uPSI3Mi8xIj4KICAgPHhtcE1NOkhpc3Rvcnk+
CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0icHJvZHVjZWQi
CiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFmZmluaXR5IFBob3RvIDIgMi4zLjAiCiAgICAg
IHN0RXZ0OndoZW49IjIwMjQtMDYtMjhUMTM6Mjc6MDgrMDI6MDAiLz4KICAgIDwvcmRmOlNlcT4K
ICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6
eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/PpwIGG4AAADdaUNDUEdyZXlzY2FsZSBENTAAABiV
dVC9CsJAGEul6KCDg4vSoQ+gIIjiKoou6qAVrLiUs/5gq8e1In0v30TwGRycnc0VcRD9IJdwfMmR
A4xlIMLIrAPhIVaDSceduws7d0cWFvIow/JEJEfTvoO/87zB0Hyt6az/ez/HXPmRIF+IlpAqJj+I
4TmW1EaburR3Jl3qIXUxDE7i7dWvFvzDbEquEBYGUPCRIIKAh4DaRg9N6H6/ffXUN8aRm4KnpFth
hw22iFHl7YlpOmedZvtMTfQffXeXnvI+rTKNxguyvDKvB7U4qQAAAAlwSFlzAAALEwAACxMBAJqc
GAAAABFJREFUCJljnMoAA0wMNGcCAEQrAKk9oHKhAAAAAElFTkSuQmCC
--fe785e0384e2607697cc2ecb17cce003003bb7ca9112104f3e8ce727edb5--`
exampleMultiPart7BitBase64 = `Date: Wed, 01 Nov 2023 00:00:00 +0000
MIME-Version: 1.0
Message-ID: <1305604950.683004066175.AAAAAAAAaaaaaaaaB@go-mail.dev>
Subject: Example mail // 7bit with base64 attachment
User-Agent: go-mail v0.4.1 // https://github.com/wneessen/go-mail
X-Mailer: go-mail v0.4.1 // https://github.com/wneessen/go-mail
From: "Toni Tester" <go-mail@go-mail.dev>
To: <go-mail+test@go-mail.dev>
Cc: <go-mail+cc@go-mail.dev>
Content-Type: multipart/mixed;
boundary="------------26A45336F6C6196BD8BBA2A2"
This is a multi-part message in MIME format.
--------------26A45336F6C6196BD8BBA2A2
Content-Type: text/plain; charset=US-ASCII; format=flowed
Content-Transfer-Encoding: 7bit
testtest
testtest
testtest
testtest
testtest
testtest
--------------26A45336F6C6196BD8BBA2A2
Content-Type: text/plain; charset=UTF-8;
name="testfile.txt"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="testfile.txt"
VGhpcyBpcyBhIHRlc3QgaW4gQmFzZTY0
--------------26A45336F6C6196BD8BBA2A2--`
exampleMultiPart8BitBase64 = `Date: Wed, 01 Nov 2023 00:00:00 +0000
MIME-Version: 1.0
Message-ID: <1305604950.683004066175.AAAAAAAAaaaaaaaaB@go-mail.dev>
Subject: Example mail // 8bit with base64 attachment
User-Agent: go-mail v0.4.1 // https://github.com/wneessen/go-mail
X-Mailer: go-mail v0.4.1 // https://github.com/wneessen/go-mail
From: "Toni Tester" <go-mail@go-mail.dev>
To: <go-mail+test@go-mail.dev>
Cc: <go-mail+cc@go-mail.dev>
Content-Type: multipart/mixed;
boundary="------------26A45336F6C6196BD8BBA2A2"
This is a multi-part message in MIME format.
--------------26A45336F6C6196BD8BBA2A2
Content-Type: text/plain; charset=US-ASCII; format=flowed
Content-Transfer-Encoding: 8bit
testtest
testtest
testtest
testtest
testtest
testtest
--------------26A45336F6C6196BD8BBA2A2
Content-Type: text/plain; charset=UTF-8;
name="testfile.txt"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="testfile.txt"
VGhpcyBpcyBhIHRlc3QgaW4gQmFzZTY0
--------------26A45336F6C6196BD8BBA2A2--`
)
func TestEMLToMsgFromString(t *testing.T) {
tests := []struct {
name string
eml string
enc string
sub string
}{
{
"RFC5322 A1.1", exampleMailRFC5322A11, "7bit",
"Saying Hello",
},
{
"Plain text no encoding (7bit)", exampleMailPlain7Bit, "7bit",
"Example mail // plain text without encoding",
},
{
"Plain text no encoding", exampleMailPlainNoEnc, "8bit",
"Example mail // plain text without encoding",
},
{
"Plain text quoted-printable", exampleMailPlainQP, "quoted-printable",
"Example mail // plain text quoted-printable",
},
{
"Plain text base64", exampleMailPlainB64, "base64",
"Example mail // plain text base64",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
msg, err := EMLToMsgFromString(tt.eml)
if err != nil {
t.Errorf("failed to parse EML: %s", err)
}
if msg.Encoding() != tt.enc {
t.Errorf("EMLToMsgFromString failed: expected encoding: %s, but got: %s", tt.enc, msg.Encoding())
}
if subject := msg.GetGenHeader(HeaderSubject); len(subject) > 0 && !strings.EqualFold(subject[0], tt.sub) {
t.Errorf("EMLToMsgFromString failed: expected subject: %s, but got: %s",
tt.sub, subject[0])
}
})
}
}
func TestEMLToMsgFromFile(t *testing.T) {
tests := []struct {
name string
eml string
enc string
sub string
}{
{
"Plain text no encoding", exampleMailPlainNoEnc, "8bit",
"Example mail // plain text without encoding",
},
{
"Plain text quoted-printable", exampleMailPlainQP, "quoted-printable",
"Example mail // plain text quoted-printable",
},
{
"Plain text base64", exampleMailPlainB64, "base64",
"Example mail // plain text base64",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tempDir, tempFile, err := stringToTempFile(tt.eml, tt.name)
defer func() {
if err = os.RemoveAll(tempDir); err != nil {
t.Error("failed to remove temp dir:", err)
}
}()
msg, err := EMLToMsgFromFile(tempFile)
if err != nil {
t.Errorf("failed to parse EML: %s", err)
}
if msg.Encoding() != tt.enc {
t.Errorf("EMLToMsgFromString failed: expected encoding: %s, but got: %s", tt.enc, msg.Encoding())
}
if subject := msg.GetGenHeader(HeaderSubject); len(subject) > 0 && !strings.EqualFold(subject[0], tt.sub) {
t.Errorf("EMLToMsgFromString failed: expected subject: %s, but got: %s",
tt.sub, subject[0])
}
})
}
}
func TestEMLToMsgFromReaderFailing(t *testing.T) {
mailbuf := bytes.NewBufferString(exampleMailPlainBrokenFrom)
_, err := EMLToMsgFromReader(mailbuf)
if err == nil {
t.Error("EML from Reader with broken FROM was supposed to fail, but didn't")
}
mailbuf.Reset()
mailbuf.WriteString(exampleMailPlainBrokenHeader)
_, err = EMLToMsgFromReader(mailbuf)
if err == nil {
t.Error("EML from Reader with broken header was supposed to fail, but didn't")
}
mailbuf.Reset()
mailbuf.WriteString(exampleMailPlainB64BrokenBody)
_, err = EMLToMsgFromReader(mailbuf)
if err == nil {
t.Error("EML from Reader with broken body was supposed to fail, but didn't")
}
mailbuf.Reset()
mailbuf.WriteString(exampleMailPlainBrokenBody)
_, err = EMLToMsgFromReader(mailbuf)
if err == nil {
t.Error("EML from Reader with broken body was supposed to fail, but didn't")
}
mailbuf.Reset()
mailbuf.WriteString(exampleMailPlainUnknownContentType)
_, err = EMLToMsgFromReader(mailbuf)
if err == nil {
t.Error("EML from Reader with unknown content type was supposed to fail, but didn't")
}
mailbuf.Reset()
mailbuf.WriteString(exampleMailPlainUnsupportedTransferEnc)
_, err = EMLToMsgFromReader(mailbuf)
if err == nil {
t.Error("EML from Reader with unsupported Transer-Encoding was supposed to fail, but didn't")
}
}
func TestEMLToMsgFromFileFailing(t *testing.T) {
tempDir, tempFile, err := stringToTempFile(exampleMailPlainBrokenFrom, "testmail")
if err != nil {
t.Errorf("failed to write EML string to temp file: %s", err)
}
_, err = EMLToMsgFromFile(tempFile)
if err == nil {
t.Error("EML from Reader with broken FROM was supposed to fail, but didn't")
}
if err = os.RemoveAll(tempDir); err != nil {
t.Error("failed to remove temp dir:", err)
}
tempDir, tempFile, err = stringToTempFile(exampleMailPlainBrokenHeader, "testmail")
if err != nil {
t.Errorf("failed to write EML string to temp file: %s", err)
}
_, err = EMLToMsgFromFile(tempFile)
if err == nil {
t.Error("EML from Reader with broken header was supposed to fail, but didn't")
}
if err = os.RemoveAll(tempDir); err != nil {
t.Error("failed to remove temp dir:", err)
}
tempDir, tempFile, err = stringToTempFile(exampleMailPlainB64BrokenBody, "testmail")
if err != nil {
t.Errorf("failed to write EML string to temp file: %s", err)
}
_, err = EMLToMsgFromFile(tempFile)
if err == nil {
t.Error("EML from Reader with broken body was supposed to fail, but didn't")
}
if err = os.RemoveAll(tempDir); err != nil {
t.Error("failed to remove temp dir:", err)
}
tempDir, tempFile, err = stringToTempFile(exampleMailPlainBrokenBody, "testmail")
if err != nil {
t.Errorf("failed to write EML string to temp file: %s", err)
}
_, err = EMLToMsgFromFile(tempFile)
if err == nil {
t.Error("EML from Reader with broken body was supposed to fail, but didn't")
}
if err = os.RemoveAll(tempDir); err != nil {
t.Error("failed to remove temp dir:", err)
}
tempDir, tempFile, err = stringToTempFile(exampleMailPlainUnknownContentType, "testmail")
if err != nil {
t.Errorf("failed to write EML string to temp file: %s", err)
}
_, err = EMLToMsgFromFile(tempFile)
if err == nil {
t.Error("EML from Reader with unknown content type was supposed to fail, but didn't")
}
if err = os.RemoveAll(tempDir); err != nil {
t.Error("failed to remove temp dir:", err)
}
tempDir, tempFile, err = stringToTempFile(exampleMailPlainUnsupportedTransferEnc, "testmail")
if err != nil {
t.Errorf("failed to write EML string to temp file: %s", err)
}
_, err = EMLToMsgFromFile(tempFile)
if err == nil {
t.Error("EML from Reader with unsupported Transer-Encoding was supposed to fail, but didn't")
}
if err = os.RemoveAll(tempDir); err != nil {
t.Error("failed to remove temp dir:", err)
}
}
func TestEMLToMsgFromStringBrokenDate(t *testing.T) {
_, err := EMLToMsgFromString(exampleMailPlainNoEncInvalidDate)
if err == nil {
t.Error("EML with invalid date was supposed to fail, but didn't")
}
now := time.Now()
m, err := EMLToMsgFromString(exampleMailPlainNoEncNoDate)
if err != nil {
t.Errorf("EML with no date parsing failed: %s", err)
}
da := m.GetGenHeader(HeaderDate)
if len(da) < 1 {
t.Error("EML with no date expected current date, but got nothing")
return
}
d := da[0]
if d != now.Format(time.RFC1123Z) {
t.Errorf("EML with no date expected: %s, got: %s", now.Format(time.RFC1123Z), d)
}
}
func TestEMLToMsgFromStringBrokenFrom(t *testing.T) {
_, err := EMLToMsgFromString(exampleMailPlainBrokenFrom)
if err == nil {
t.Error("EML with broken FROM was supposed to fail, but didn't")
}
}
func TestEMLToMsgFromStringBrokenTo(t *testing.T) {
_, err := EMLToMsgFromString(exampleMailPlainBrokenTo)
if err == nil {
t.Error("EML with broken TO was supposed to fail, but didn't")
}
}
func TestEMLToMsgFromStringNoBoundary(t *testing.T) {
_, err := EMLToMsgFromString(exampleMailPlainB64WithAttachmentNoBoundary)
if err == nil {
t.Error("EML with no boundary was supposed to fail, but didn't")
}
}
func TestEMLToMsgFromStringWithAttachment(t *testing.T) {
wantSubject := "Example mail // plain text base64 with attachment"
msg, err := EMLToMsgFromString(exampleMailPlainB64WithAttachment)
if err != nil {
t.Errorf("EML with attachment failed: %s", err)
}
if subject := msg.GetGenHeader(HeaderSubject); len(subject) > 0 && !strings.EqualFold(subject[0], wantSubject) {
t.Errorf("EMLToMsgFromString of EML with attachment failed: expected subject: %s, but got: %s",
wantSubject, subject[0])
}
if len(msg.attachments) != 1 {
t.Errorf("EMLToMsgFromString of EML with attachment failed: expected no. of attachments: %d, but got: %d",
1, len(msg.attachments))
}
}
func TestEMLToMsgFromStringWithEmbed(t *testing.T) {
wantSubject := "Example mail // plain text base64 with embed"
msg, err := EMLToMsgFromString(exampleMailPlainB64WithEmbed)
if err != nil {
t.Errorf("EML with embed failed: %s", err)
}
if subject := msg.GetGenHeader(HeaderSubject); len(subject) > 0 && !strings.EqualFold(subject[0], wantSubject) {
t.Errorf("EMLToMsgFromString of EML with embed failed: expected subject: %s, but got: %s",
wantSubject, subject[0])
}
if len(msg.embeds) != 1 {
t.Errorf("EMLToMsgFromString of EML with embed failed: expected no. of embeds: %d, but got: %d",
1, len(msg.embeds))
}
msg, err = EMLToMsgFromString(exampleMailPlainB64WithEmbedNoContentID)
if err != nil {
t.Errorf("EML with embed failed: %s", err)
}
if subject := msg.GetGenHeader(HeaderSubject); len(subject) > 0 && !strings.EqualFold(subject[0], wantSubject) {
t.Errorf("EMLToMsgFromString of EML with embed failed: expected subject: %s, but got: %s",
wantSubject, subject[0])
}
if len(msg.embeds) != 1 {
t.Errorf("EMLToMsgFromString of EML with embed failed: expected no. of embeds: %d, but got: %d",
1, len(msg.embeds))
}
}
func TestEMLToMsgFromStringMultipartMixedAlternativeRelated(t *testing.T) {
wantSubject := "Example mail // plain text base64 with attachment, embed and alternative part"
msg, err := EMLToMsgFromString(exampleMailMultipartMixedAlternativeRelated)
if err != nil {
t.Errorf("EML multipart mixed, related, alternative failed: %s", err)
}
if subject := msg.GetGenHeader(HeaderSubject); len(subject) > 0 && !strings.EqualFold(subject[0], wantSubject) {
t.Errorf("EMLToMsgFromString of EML multipart mixed, related, alternative failed: expected subject: %s,"+
" but got: %s", wantSubject, subject[0])
}
if len(msg.embeds) != 1 {
t.Errorf("EMLToMsgFromString of EML multipart mixed, related, alternative failed: expected no. of "+
"embeds: %d, but got: %d", 1, len(msg.embeds))
}
if len(msg.attachments) != 1 {
t.Errorf("EMLToMsgFromString of EML multipart mixed, related, alternative failed: expected no. of "+
"attachments: %d, but got: %d", 1, len(msg.attachments))
}
if len(msg.parts) != 3 {
t.Errorf("EMLToMsgFromString of EML multipart mixed, related, alternative failed: expected no. of "+
"parts: %d, but got: %d", 3, len(msg.parts))
}
var hasPlain, hasHTML, hasAlternative bool
for _, part := range msg.parts {
if strings.EqualFold(part.contentType.String(), TypeMultipartAlternative.String()) {
hasAlternative = true
}
if strings.EqualFold(part.contentType.String(), TypeTextPlain.String()) {
hasPlain = true
}
if strings.EqualFold(part.contentType.String(), TypeTextHTML.String()) {
hasHTML = true
}
}
if !hasPlain {
t.Error("EMLToMsgFromString of EML multipart mixed, related, alternative failed: expected PLAIN " +
"but got none")
}
if !hasHTML {
t.Error("EMLToMsgFromString of EML multipart mixed, related, alternative failed: expected HTML " +
"but got none")
}
if !hasAlternative {
t.Error("EMLToMsgFromString of EML multipart mixed, related, alternative failed: expected Alternative " +
"but got none")
}
}
func TestEMLToMsgFromStringMultipartMixedWith7Bit(t *testing.T) {
wantSubject := "Example mail // 7bit with base64 attachment"
msg, err := EMLToMsgFromString(exampleMultiPart7BitBase64)
if err != nil {
t.Errorf("EML multipart mixed with 7bit: %s", err)
}
if subject := msg.GetGenHeader(HeaderSubject); len(subject) > 0 && !strings.EqualFold(subject[0], wantSubject) {
t.Errorf("EMLToMsgFromString of EML multipart mixed with 7bit: expected subject: %s,"+
" but got: %s", wantSubject, subject[0])
}
if len(msg.parts) != 1 {
t.Errorf("EMLToMsgFromString of EML multipart mixed with 7bit failed: expected 1 part, got: %d",
len(msg.parts))
return
}
if !strings.EqualFold(msg.parts[0].GetEncoding().String(), EncodingUSASCII.String()) {
t.Errorf("EMLToMsgFromString of EML multipart mixed with 7bit failed: expected encoding: %s, got %s",
EncodingUSASCII.String(), msg.parts[0].GetEncoding().String())
}
if len(msg.attachments) != 1 {
t.Errorf("EMLToMsgFromString of EML multipart mixed with 7bit failed: expected 1 attachment, got: %d",
len(msg.attachments))
return
}
}
func TestEMLToMsgFromStringMultipartMixedWith8Bit(t *testing.T) {
wantSubject := "Example mail // 8bit with base64 attachment"
msg, err := EMLToMsgFromString(exampleMultiPart8BitBase64)
if err != nil {
t.Errorf("EML multipart mixed with 8bit: %s", err)
}
if subject := msg.GetGenHeader(HeaderSubject); len(subject) > 0 && !strings.EqualFold(subject[0], wantSubject) {
t.Errorf("EMLToMsgFromString of EML multipart mixed with 8bit: expected subject: %s,"+
" but got: %s", wantSubject, subject[0])
}
if len(msg.parts) != 1 {
t.Errorf("EMLToMsgFromString of EML multipart mixed with 8bit failed: expected 1 part, got: %d",
len(msg.parts))
return
}
if !strings.EqualFold(msg.parts[0].GetEncoding().String(), NoEncoding.String()) {
t.Errorf("EMLToMsgFromString of EML multipart mixed with 8bit failed: expected encoding: %s, got %s",
NoEncoding.String(), msg.parts[0].GetEncoding().String())
}
if len(msg.attachments) != 1 {
t.Errorf("EMLToMsgFromString of EML multipart mixed with 8bit failed: expected 1 attachment, got: %d",
len(msg.attachments))
return
}
}
// stringToTempFile is a helper method that will create a temporary file form a give data string
func stringToTempFile(data, name string) (string, string, error) {
tempDir, err := os.MkdirTemp("", fmt.Sprintf("*-%s", name))
if err != nil {
return tempDir, "", fmt.Errorf("failed to create temp dir: %w", err)
}
filePath := fmt.Sprintf("%s/%s", tempDir, name)
err = os.WriteFile(filePath, []byte(data), 0o666)
if err != nil {
return tempDir, "", fmt.Errorf("failed to write data to temp file: %w", err)
}
return tempDir, filePath, nil
}