mirror of
https://github.com/wneessen/go-mail.git
synced 2024-11-22 13:50:49 +01:00
Compare commits
17 commits
28dc629674
...
9834c6508d
Author | SHA1 | Date | |
---|---|---|---|
9834c6508d | |||
75e035c783 | |||
769783f037 | |||
9f1e1976fe | |||
887e3cd768 | |||
127cfdf2bc | |||
7ed23bf01b | |||
0310527eb5 | |||
1399a3331a | |||
45ebcb95b3 | |||
1519522e5d | |||
3bf1992cab | |||
4a8ac76636 | |||
5e3ebcc1a6 | |||
040289cea4 | |||
2a2176d700 | |||
e442419c18 |
9 changed files with 1929 additions and 1978 deletions
16
client.go
16
client.go
|
@ -1094,10 +1094,6 @@ func (c *Client) DialAndSendWithContext(ctx context.Context, messages ...*Msg) e
|
|||
// - An error if the connection check fails, if no supported authentication method is found,
|
||||
// or if the authentication process fails.
|
||||
func (c *Client) auth() error {
|
||||
if err := c.checkConn(); err != nil {
|
||||
return fmt.Errorf("failed to authenticate: %w", err)
|
||||
}
|
||||
|
||||
if c.smtpAuth == nil && c.smtpAuthType != SMTPAuthNoAuth {
|
||||
hasSMTPAuth, smtpAuthType := c.smtpClient.Extension("AUTH")
|
||||
if !hasSMTPAuth {
|
||||
|
@ -1280,12 +1276,6 @@ func (c *Client) sendSingleMsg(message *Msg) error {
|
|||
affectedMsg: message,
|
||||
}
|
||||
}
|
||||
if err = c.checkConn(); err != nil {
|
||||
return &SendError{
|
||||
Reason: ErrConnCheck, errlist: []error{err}, isTemp: isTempError(err),
|
||||
affectedMsg: message,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -1302,6 +1292,9 @@ func (c *Client) sendSingleMsg(message *Msg) error {
|
|||
// - An error if there is no active connection, if the NOOP command fails, or if extending
|
||||
// the deadline fails; otherwise, returns nil.
|
||||
func (c *Client) checkConn() error {
|
||||
if c.smtpClient == nil {
|
||||
return ErrNoActiveConnection
|
||||
}
|
||||
if !c.smtpClient.HasConnection() {
|
||||
return ErrNoActiveConnection
|
||||
}
|
||||
|
@ -1360,9 +1353,6 @@ func (c *Client) setDefaultHelo() error {
|
|||
// - An error if there is no active connection, if STARTTLS is required but not supported,
|
||||
// or if there are issues during the TLS handshake; otherwise, returns nil.
|
||||
func (c *Client) tls() error {
|
||||
if !c.smtpClient.HasConnection() {
|
||||
return ErrNoActiveConnection
|
||||
}
|
||||
if !c.useSSL && c.tlspolicy != NoTLS {
|
||||
hasStartTLS := false
|
||||
extension, _ := c.smtpClient.Extension("STARTTLS")
|
||||
|
|
3017
client_test.go
3017
client_test.go
File diff suppressed because it is too large
Load diff
12
eml.go
12
eml.go
|
@ -60,7 +60,7 @@ func EMLToMsgFromReader(reader io.Reader) (*Msg, error) {
|
|||
return msg, fmt.Errorf("failed to parse EML from reader: %w", err)
|
||||
}
|
||||
|
||||
if err := parseEML(parsedMsg, bodybuf, msg); err != nil {
|
||||
if err = parseEML(parsedMsg, bodybuf, msg); err != nil {
|
||||
return msg, fmt.Errorf("failed to parse EML contents: %w", err)
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ func EMLToMsgFromFile(filePath string) (*Msg, error) {
|
|||
return msg, fmt.Errorf("failed to parse EML file: %w", err)
|
||||
}
|
||||
|
||||
if err := parseEML(parsedMsg, bodybuf, msg); err != nil {
|
||||
if err = parseEML(parsedMsg, bodybuf, msg); err != nil {
|
||||
return msg, fmt.Errorf("failed to parse EML contents: %w", err)
|
||||
}
|
||||
|
||||
|
@ -218,9 +218,9 @@ func parseEMLHeaders(mailHeader *netmail.Header, msg *Msg) error {
|
|||
for _, addr := range parsedAddrs {
|
||||
addrStrings = append(addrStrings, addr.String())
|
||||
}
|
||||
if err = addrFunc(addrStrings...); err != nil {
|
||||
return fmt.Errorf(`failed to parse %q header: %w`, addrHeader, err)
|
||||
}
|
||||
// We can skip the error checking here since netmail.ParseAddressList already performed the
|
||||
// same address checking that the msg methods do.
|
||||
_ = addrFunc(addrStrings...)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -600,6 +600,8 @@ func parseEMLAttachmentEmbed(contentDisposition []string, multiPart *multipart.P
|
|||
if err := msg.EmbedReader(filename, dataReader); err != nil {
|
||||
return fmt.Errorf("failed to embed multipart body: %w", err)
|
||||
}
|
||||
default:
|
||||
return errors.New("unsupported content disposition type")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
588
eml_test.go
588
eml_test.go
|
@ -6,11 +6,8 @@ package mail
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -22,6 +19,23 @@ 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".`
|
||||
exampleMailRFC5322A11InvalidFrom = `From: §§§§§§§§§
|
||||
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".`
|
||||
exampleMailInvalidHeader = `From: John Doe <jdoe@machine.example>
|
||||
To: Mary Smith <mary@example.net>
|
||||
Inva@id*Header; This is a header
|
||||
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
|
||||
|
@ -42,6 +56,52 @@ This is a test mail. Please do not reply to this. Also this line is very long so
|
|||
should be wrapped.
|
||||
|
||||
|
||||
Thank your for your business!
|
||||
The go-mail team
|
||||
|
||||
--
|
||||
This is a signature`
|
||||
exampleMailPlainInvalidCTE = `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: invalid
|
||||
|
||||
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`
|
||||
exampleMailInvalidContentType = `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; $foo; bar; --invalid--
|
||||
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
|
||||
|
||||
|
@ -304,6 +364,128 @@ VGhpcyBpcyBhIHNpbXBsZSB0ZXN0IHRleHQgZmlsZSBhdHRhY2htZW50LgoKSXQgCiAgaGFzCiAg
|
|||
ICAgc2V2ZXJhbAogICAgICAgICAgICBuZXdsaW5lcwoJICAgICAgICAgICAgYW5kCgkgICAgc3Bh
|
||||
Y2VzCiAgICAgaW4KICBpdAouCgpBcyB3ZWxsIGFzIGFuIGVtb2ppOiDwn5mCCg==
|
||||
|
||||
--45c75ff528359022eb03679fbe91877d75343f2e1f8193e349deffa33ff7--`
|
||||
exampleMailPlainB64WithAttachmentNoContentType = `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
|
||||
|
||||
RGVhciBDdXN0b21lciwKClRoaXMgaXMgYSB0ZXN0IG1haWwuIFBsZWFzZSBkbyBub3QgcmVwbHkg
|
||||
dG8gdGhpcy4gQWxzbyB0aGlzIGxpbmUgaXMgdmVyeSBsb25nIHNvIGl0CnNob3VsZCBiZSB3cmFw
|
||||
cGVkLgoKClRoYW5rIHlvdXIgZm9yIHlvdXIgYnVzaW5lc3MhClRoZSBnby1tYWlsIHRlYW0KCi0t
|
||||
ClRoaXMgaXMgYSBzaWduYXR1cmU=
|
||||
|
||||
--45c75ff528359022eb03679fbe91877d75343f2e1f8193e349deffa33ff7
|
||||
Content-Disposition: attachment; filename="test.attachment"
|
||||
Content-Transfer-Encoding: base64
|
||||
|
||||
VGhpcyBpcyBhIHNpbXBsZSB0ZXN0IHRleHQgZmlsZSBhdHRhY2htZW50LgoKSXQgCiAgaGFzCiAg
|
||||
ICAgc2V2ZXJhbAogICAgICAgICAgICBuZXdsaW5lcwoJICAgICAgICAgICAgYW5kCgkgICAgc3Bh
|
||||
Y2VzCiAgICAgaW4KICBpdAouCgpBcyB3ZWxsIGFzIGFuIGVtb2ppOiDwn5mCCg==
|
||||
|
||||
--45c75ff528359022eb03679fbe91877d75343f2e1f8193e349deffa33ff7--`
|
||||
exampleMailPlainB64WithAttachmentBrokenB64 = `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
|
||||
dG8gdGhpcy4gQWxzbyB0aGl§§§§§@@@@@XMgdmVyeSBsb25nIHNvIGl0CnNob3VsZCBiZSB3cmFw
|
||||
cGVkLgoKClRoYW5rIHlvdXIgZm9yIHlvdXIgYnVzaW5lc3MhClRoZSBnby1tYWlsIHRlYW0KCi0t
|
||||
ClRoaXMgaXMgYSBzaWduYXR1cmU=
|
||||
|
||||
--45c75ff528359022eb03679fbe91877d75343f2e1f8193e349deffa33ff7
|
||||
Content-Disposition: attachment; filename="test.attachment"
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-Type: application/octet-stream; name="test.attachment"
|
||||
|
||||
VGhpcyBpcyBhIHNpbXBsZSB0ZXN0IHRleHQgZmlsZSBhdHRhY2htZW50LgoKSXQgCiAgaGFzCiAg
|
||||
ICAgc2V2ZXJhbAogICAg§§§§§@@@@@BuZXdsaW5lcwoJICAgICAgICAgICAgYW5kCgkgICAgc3Bh
|
||||
Y2VzCiAgICAgaW4KICBpdAouCgpBcyB3ZWxsIGFzIGFuIGVtb2ppOiDwn5mCCg==
|
||||
|
||||
--45c75ff528359022eb03679fbe91877d75343f2e1f8193e349deffa33ff7--`
|
||||
exampleMailPlainB64WithAttachmentInvalidCTE = `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: invalid
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
|
||||
RGVhciBDdXN0b21lciwKClRoaXMgaXMgYSB0ZXN0IG1haWwuIFBsZWFzZSBkbyBub3QgcmVwbHkg
|
||||
dG8gdGhpcy4gQWxzbyB0aGlzIGxpbmUgaXMgdmVyeSBsb25nIHNvIGl0CnNob3VsZCBiZSB3cmFw
|
||||
cGVkLgoKClRoYW5rIHlvdXIgZm9yIHlvdXIgYnVzaW5lc3MhClRoZSBnby1tYWlsIHRlYW0KCi0t
|
||||
ClRoaXMgaXMgYSBzaWduYXR1cmU=
|
||||
|
||||
--45c75ff528359022eb03679fbe91877d75343f2e1f8193e349deffa33ff7
|
||||
Content-Disposition: attachment; filename="test.attachment"
|
||||
Content-Transfer-Encoding: invalid
|
||||
Content-Type: application/octet-stream; name="test.attachment"
|
||||
|
||||
VGhpcyBpcyBhIHNpbXBsZSB0ZXN0IHRleHQgZmlsZSBhdHRhY2htZW50LgoKSXQgCiAgaGFzCiAg
|
||||
ICAgc2V2ZXJhbAogICAgICAgICAgICBuZXdsaW5lcwoJICAgICAgICAgICAgYW5kCgkgICAgc3Bh
|
||||
Y2VzCiAgICAgaW4KICBpdAouCgpBcyB3ZWxsIGFzIGFuIGVtb2ppOiDwn5mCCg==
|
||||
|
||||
--45c75ff528359022eb03679fbe91877d75343f2e1f8193e349deffa33ff7--`
|
||||
exampleMailPlainB64WithAttachmentInvalidContentType = `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; text/plain @ charset=UTF-8; $foo; bar; --invalid--
|
||||
|
||||
VGhpcyBpcyBhIHNpbXBsZSB0ZXN0IHRleHQgZmlsZSBhdHRhY2htZW50LgoKSXQgCiAgaGFzCiAg
|
||||
ICAgc2V2ZXJhbAogICAgICAgICAgICBuZXdsaW5lcwoJICAgICAgICAgICAgYW5kCgkgICAgc3Bh
|
||||
Y2VzCiAgICAgaW4KICBpdAouCgpBcyB3ZWxsIGFzIGFuIGVtb2ppOiDwn5mCCg==
|
||||
|
||||
--45c75ff528359022eb03679fbe91877d75343f2e1f8193e349deffa33ff7--`
|
||||
exampleMailPlainB64WithAttachmentNoBoundary = `Date: Wed, 01 Nov 2023 00:00:00 +0000
|
||||
MIME-Version: 1.0
|
||||
|
@ -578,6 +760,39 @@ Content-Disposition: attachment;
|
|||
filename="testfile.txt"
|
||||
|
||||
VGhpcyBpcyBhIHRlc3QgaW4gQmFzZTY0
|
||||
--------------26A45336F6C6196BD8BBA2A2--`
|
||||
exampleMultiPart7BitBase64BrokenB64 = `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"
|
||||
|
||||
VGh@@@@§§§§hIHRlc3QgaW4gQmFzZTY0
|
||||
--------------26A45336F6C6196BD8BBA2A2--`
|
||||
exampleMultiPart8BitBase64 = `Date: Wed, 01 Nov 2023 00:00:00 +0000
|
||||
MIME-Version: 1.0
|
||||
|
@ -612,8 +827,352 @@ Content-Disposition: attachment;
|
|||
|
||||
VGhpcyBpcyBhIHRlc3QgaW4gQmFzZTY0
|
||||
--------------26A45336F6C6196BD8BBA2A2--`
|
||||
exampleMailWithInlineEmbed = `Date: Wed, 01 Nov 2023 00:00:00 +0000
|
||||
MIME-Version: 1.0
|
||||
Message-ID: <1305604950.683004066175.AAAAAAAAaaaaaaaaB@go-mail.dev>
|
||||
Subject: Example mail with inline 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>
|
||||
Content-Type: multipart/related; boundary="abc123"
|
||||
|
||||
--abc123
|
||||
Content-Type: text/html; charset=UTF-8
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>Hello,</p>
|
||||
<p>This is an example email with an inline image:</p>
|
||||
<img src="cid:12345@go-mail.dev" alt="Inline Image">
|
||||
<p>Best regards,<br>The go-mail team</p>
|
||||
</body>
|
||||
</html>
|
||||
--abc123
|
||||
Content-Type: image/png
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-ID: <12345@go-mail.dev>
|
||||
Content-Disposition: inline; filename="test.png"
|
||||
|
||||
iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIW2NgYGD4DwABBAEAwS2O
|
||||
UAAAAABJRU5ErkJggg==
|
||||
--abc123--`
|
||||
exampleMailWithInlineEmbedWrongDisposition = `Date: Wed, 01 Nov 2023 00:00:00 +0000
|
||||
MIME-Version: 1.0
|
||||
Message-ID: <1305604950.683004066175.AAAAAAAAaaaaaaaaB@go-mail.dev>
|
||||
Subject: Example mail with inline 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>
|
||||
Content-Type: multipart/related; boundary="abc123"
|
||||
|
||||
--abc123
|
||||
Content-Type: text/html; charset=UTF-8
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>Hello,</p>
|
||||
<p>This is an example email with an inline image:</p>
|
||||
<img src="cid:12345@go-mail.dev" alt="Inline Image">
|
||||
<p>Best regards,<br>The go-mail team</p>
|
||||
</body>
|
||||
</html>
|
||||
--abc123
|
||||
Content-Type: image/png
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-ID: <12345@go-mail.dev>
|
||||
Content-Disposition: broken; filename="test.png"
|
||||
|
||||
iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIW2NgYGD4DwABBAEAwS2O
|
||||
UAAAAABJRU5ErkJggg==
|
||||
--abc123--`
|
||||
)
|
||||
|
||||
func TestEMLToMsgFromReader(t *testing.T) {
|
||||
t.Run("EMLToMsgFromReader via EMLToMsgFromString, check subject and encoding", func(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
emlString string
|
||||
wantEncoding Encoding
|
||||
wantSubject string
|
||||
}{
|
||||
{
|
||||
"RFC5322 A1.1 example mail", exampleMailRFC5322A11, EncodingUSASCII,
|
||||
"Saying Hello"},
|
||||
{
|
||||
"Plain text no encoding (7bit)", exampleMailPlain7Bit, EncodingUSASCII,
|
||||
"Example mail // plain text without encoding",
|
||||
},
|
||||
{
|
||||
"Plain text no encoding", exampleMailPlainNoEnc, NoEncoding,
|
||||
"Example mail // plain text without encoding",
|
||||
},
|
||||
{
|
||||
"Plain text quoted-printable", exampleMailPlainQP, EncodingQP,
|
||||
"Example mail // plain text quoted-printable",
|
||||
},
|
||||
{
|
||||
"Plain text base64", exampleMailPlainB64, EncodingB64,
|
||||
"Example mail // plain text base64",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
parsed, err := EMLToMsgFromString(tt.emlString)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse EML string: %s", err)
|
||||
}
|
||||
if parsed.Encoding() != tt.wantEncoding.String() {
|
||||
t.Errorf("failed to parse EML string: want encoding %s, got %s", tt.wantEncoding,
|
||||
parsed.Encoding())
|
||||
}
|
||||
gotSubject, ok := parsed.genHeader[HeaderSubject]
|
||||
if !ok {
|
||||
t.Fatalf("failed to parse EML string. No subject header found")
|
||||
}
|
||||
if len(gotSubject) != 1 {
|
||||
t.Fatalf("failed to parse EML string, more than one subject header found")
|
||||
}
|
||||
if !strings.EqualFold(gotSubject[0], tt.wantSubject) {
|
||||
t.Errorf("failed to parse EML string: want subject %s, got %s", tt.wantSubject,
|
||||
gotSubject[0])
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
t.Run("EMLToMsgFromReader fails on reader", func(t *testing.T) {
|
||||
emlReader := bytes.NewBufferString("invalid")
|
||||
if _, err := EMLToMsgFromReader(emlReader); err == nil {
|
||||
t.Errorf("EML parsing with invalid EML string should fail")
|
||||
}
|
||||
})
|
||||
t.Run("EMLToMsgFromReader fails on parseEML", func(t *testing.T) {
|
||||
emlReader := bytes.NewBufferString(exampleMailRFC5322A11InvalidFrom)
|
||||
if _, err := EMLToMsgFromReader(emlReader); err == nil {
|
||||
t.Errorf("EML parsing with invalid EML string should fail")
|
||||
}
|
||||
})
|
||||
t.Run("EMLToMsgFromReader via EMLToMsgFromString on different examples", func(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
emlString string
|
||||
shouldFail bool
|
||||
}{
|
||||
{
|
||||
name: "Valid RFC 5322 Example",
|
||||
emlString: exampleMailRFC5322A11,
|
||||
shouldFail: false,
|
||||
},
|
||||
{
|
||||
name: "Invalid From Header (RFC 5322)",
|
||||
emlString: exampleMailRFC5322A11InvalidFrom,
|
||||
shouldFail: true,
|
||||
},
|
||||
{
|
||||
name: "Invalid Header",
|
||||
emlString: exampleMailInvalidHeader,
|
||||
shouldFail: true,
|
||||
},
|
||||
{
|
||||
name: "Plain broken Content-Type",
|
||||
emlString: exampleMailInvalidContentType,
|
||||
shouldFail: true,
|
||||
},
|
||||
{
|
||||
name: "Plain No Encoding",
|
||||
emlString: exampleMailPlainNoEnc,
|
||||
shouldFail: false,
|
||||
},
|
||||
{
|
||||
name: "Plain invalid CTE",
|
||||
emlString: exampleMailPlainInvalidCTE,
|
||||
shouldFail: true,
|
||||
},
|
||||
{
|
||||
name: "Plain 7bit",
|
||||
emlString: exampleMailPlain7Bit,
|
||||
shouldFail: false,
|
||||
},
|
||||
{
|
||||
name: "Broken Body Base64",
|
||||
emlString: exampleMailPlainBrokenBody,
|
||||
shouldFail: true,
|
||||
},
|
||||
{
|
||||
name: "Unknown Content Type",
|
||||
emlString: exampleMailPlainUnknownContentType,
|
||||
shouldFail: true,
|
||||
},
|
||||
{
|
||||
name: "Broken Header",
|
||||
emlString: exampleMailPlainBrokenHeader,
|
||||
shouldFail: true,
|
||||
},
|
||||
{
|
||||
name: "Broken From Header",
|
||||
emlString: exampleMailPlainBrokenFrom,
|
||||
shouldFail: true,
|
||||
},
|
||||
{
|
||||
name: "Broken To Header",
|
||||
emlString: exampleMailPlainBrokenTo,
|
||||
shouldFail: true,
|
||||
},
|
||||
{
|
||||
name: "Invalid Date",
|
||||
emlString: exampleMailPlainNoEncInvalidDate,
|
||||
shouldFail: true,
|
||||
},
|
||||
{
|
||||
name: "No Date Header",
|
||||
emlString: exampleMailPlainNoEncNoDate,
|
||||
shouldFail: false,
|
||||
},
|
||||
{
|
||||
name: "Quoted Printable Encoding",
|
||||
emlString: exampleMailPlainQP,
|
||||
shouldFail: false,
|
||||
},
|
||||
{
|
||||
name: "Unsupported Transfer Encoding",
|
||||
emlString: exampleMailPlainUnsupportedTransferEnc,
|
||||
shouldFail: true,
|
||||
},
|
||||
{
|
||||
name: "Base64 Encoding",
|
||||
emlString: exampleMailPlainB64,
|
||||
shouldFail: false,
|
||||
},
|
||||
{
|
||||
name: "Base64 with Attachment",
|
||||
emlString: exampleMailPlainB64WithAttachment,
|
||||
shouldFail: false,
|
||||
},
|
||||
{
|
||||
name: "Base64 with Attachment no content types",
|
||||
emlString: exampleMailPlainB64WithAttachmentNoContentType,
|
||||
shouldFail: true,
|
||||
},
|
||||
{
|
||||
name: "Multipart Base64 with Attachment broken Base64",
|
||||
emlString: exampleMailPlainB64WithAttachmentBrokenB64,
|
||||
shouldFail: true,
|
||||
},
|
||||
{
|
||||
name: "Base64 with Attachment with invalid content type in attachment",
|
||||
emlString: exampleMailPlainB64WithAttachmentInvalidContentType,
|
||||
shouldFail: true,
|
||||
},
|
||||
{
|
||||
name: "Base64 with Attachment with invalid CTE in attachment",
|
||||
emlString: exampleMailPlainB64WithAttachmentInvalidCTE,
|
||||
shouldFail: true,
|
||||
},
|
||||
{
|
||||
name: "Base64 with Attachment No Boundary",
|
||||
emlString: exampleMailPlainB64WithAttachmentNoBoundary,
|
||||
shouldFail: true,
|
||||
},
|
||||
{
|
||||
name: "Broken Body Base64",
|
||||
emlString: exampleMailPlainB64BrokenBody,
|
||||
shouldFail: true,
|
||||
},
|
||||
{
|
||||
name: "Base64 with Embedded Image",
|
||||
emlString: exampleMailPlainB64WithEmbed,
|
||||
shouldFail: false,
|
||||
},
|
||||
{
|
||||
name: "Base64 with Embed No Content-ID",
|
||||
emlString: exampleMailPlainB64WithEmbedNoContentID,
|
||||
shouldFail: false,
|
||||
},
|
||||
{
|
||||
name: "Multipart Mixed with Attachment, Embed, and Alternative Part",
|
||||
emlString: exampleMailMultipartMixedAlternativeRelated,
|
||||
shouldFail: false,
|
||||
},
|
||||
{
|
||||
name: "Multipart 7bit Base64",
|
||||
emlString: exampleMultiPart7BitBase64,
|
||||
shouldFail: false,
|
||||
},
|
||||
{
|
||||
name: "Multipart 7bit Base64 with broken Base64",
|
||||
emlString: exampleMultiPart7BitBase64BrokenB64,
|
||||
shouldFail: true,
|
||||
},
|
||||
{
|
||||
name: "Multipart 8bit Base64",
|
||||
emlString: exampleMultiPart8BitBase64,
|
||||
shouldFail: false,
|
||||
},
|
||||
{
|
||||
name: "Multipart with inline embed",
|
||||
emlString: exampleMailWithInlineEmbed,
|
||||
shouldFail: false,
|
||||
},
|
||||
{
|
||||
name: "Multipart with inline embed disposition broken",
|
||||
emlString: exampleMailWithInlineEmbedWrongDisposition,
|
||||
shouldFail: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, err := EMLToMsgFromString(tt.emlString)
|
||||
if tt.shouldFail && err == nil {
|
||||
t.Errorf("parsing of EML was supposed to fail, but it did not")
|
||||
}
|
||||
if !tt.shouldFail && err != nil {
|
||||
t.Errorf("parsing of EML failed: %s", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestEMLToMsgFromFile(t *testing.T) {
|
||||
t.Run("EMLToMsgFromFile succeeds", func(t *testing.T) {
|
||||
parsed, err := EMLToMsgFromFile("testdata/RFC5322-A1-1.eml")
|
||||
if err != nil {
|
||||
t.Fatalf("EMLToMsgFromFile failed: %s ", err)
|
||||
}
|
||||
if parsed.Encoding() != EncodingUSASCII.String() {
|
||||
t.Errorf("EMLToMsgFromFile failed: want encoding %s, got %s", EncodingUSASCII,
|
||||
parsed.Encoding())
|
||||
}
|
||||
gotSubject, ok := parsed.genHeader[HeaderSubject]
|
||||
if !ok {
|
||||
t.Fatalf("failed to parse EML string. No subject header found")
|
||||
}
|
||||
if len(gotSubject) != 1 {
|
||||
t.Fatalf("failed to parse EML string, more than one subject header found")
|
||||
}
|
||||
if !strings.EqualFold(gotSubject[0], "Saying Hello") {
|
||||
t.Errorf("failed to parse EML string: want subject %s, got %s", "Saying Hello",
|
||||
gotSubject[0])
|
||||
}
|
||||
|
||||
})
|
||||
t.Run("EMLToMsgFromFile fails on file not found", func(t *testing.T) {
|
||||
if _, err := EMLToMsgFromFile("testdata/not-existing.eml"); err == nil {
|
||||
t.Errorf("EMLToMsgFromFile with invalid file should fail")
|
||||
}
|
||||
})
|
||||
t.Run("EMLToMsgFromFile fails on parseEML", func(t *testing.T) {
|
||||
if _, err := EMLToMsgFromFile("testdata/RFC5322-A1-1-invalid-from.eml"); err == nil {
|
||||
t.Errorf("EMLToMsgFromFile with invalid EML message should fail")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
func TestEMLToMsgFromString(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
@ -621,26 +1180,6 @@ func TestEMLToMsgFromString(t *testing.T) {
|
|||
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) {
|
||||
|
@ -1009,3 +1548,6 @@ func stringToTempFile(data, name string) (string, string, error) {
|
|||
}
|
||||
return tempDir, filePath, nil
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
|
|
252
file_test.go
252
file_test.go
|
@ -6,108 +6,159 @@ package mail
|
|||
|
||||
import "testing"
|
||||
|
||||
// TestFile_SetGetHeader tests the set-/getHeader method of the File object
|
||||
func TestFile_SetGetHeader(t *testing.T) {
|
||||
f := File{
|
||||
Name: "testfile.txt",
|
||||
Header: make(map[string][]string),
|
||||
}
|
||||
f.setHeader(HeaderContentType, "text/plain")
|
||||
fi, ok := f.getHeader(HeaderContentType)
|
||||
if !ok {
|
||||
t.Errorf("getHeader method of File did not return a value")
|
||||
return
|
||||
}
|
||||
if fi != "text/plain" {
|
||||
t.Errorf("getHeader returned wrong value. Expected: %s, got: %s", "text/plain", fi)
|
||||
}
|
||||
fi, ok = f.getHeader(HeaderContentTransferEnc)
|
||||
if ok {
|
||||
t.Errorf("getHeader method of File did return a value, but wasn't supposed to")
|
||||
return
|
||||
}
|
||||
if fi != "" {
|
||||
t.Errorf("getHeader returned wrong value. Expected: %s, got: %s", "", fi)
|
||||
}
|
||||
func TestFile(t *testing.T) {
|
||||
t.Run("setHeader", func(t *testing.T) {
|
||||
f := File{
|
||||
Name: "testfile.txt",
|
||||
Header: make(map[string][]string),
|
||||
}
|
||||
f.setHeader(HeaderContentType, "text/plain")
|
||||
contentType, ok := f.Header[HeaderContentType.String()]
|
||||
if !ok {
|
||||
t.Fatalf("setHeader failed. Expected header %s to be set", HeaderContentType)
|
||||
}
|
||||
if len(contentType) != 1 {
|
||||
t.Fatalf("setHeader failed. Expected header %s to have one value, got: %d", HeaderContentType,
|
||||
len(contentType))
|
||||
}
|
||||
if contentType[0] != "text/plain" {
|
||||
t.Fatalf("setHeader failed. Expected header %s to have value %s, got: %s",
|
||||
HeaderContentType.String(), "text/plain", contentType[0])
|
||||
}
|
||||
})
|
||||
t.Run("getHeader", func(t *testing.T) {
|
||||
f := File{
|
||||
Name: "testfile.txt",
|
||||
Header: make(map[string][]string),
|
||||
}
|
||||
f.setHeader(HeaderContentType, "text/plain")
|
||||
contentType, ok := f.getHeader(HeaderContentType)
|
||||
if !ok {
|
||||
t.Fatalf("setHeader failed. Expected header %s to be set", HeaderContentType)
|
||||
}
|
||||
if contentType != "text/plain" {
|
||||
t.Fatalf("setHeader failed. Expected header %s to have value %s, got: %s",
|
||||
HeaderContentType.String(), "text/plain", contentType)
|
||||
}
|
||||
})
|
||||
t.Run("WithFileDescription", func(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
desc string
|
||||
}{
|
||||
{"File description: test", "test"},
|
||||
{"File description: with newline", "test\n"},
|
||||
{"File description: empty", ""},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
message := NewMsg()
|
||||
message.AttachFile("file.go", WithFileDescription(tt.desc))
|
||||
attachments := message.GetAttachments()
|
||||
if len(attachments) <= 0 {
|
||||
t.Fatalf("failed to retrieve attachments list")
|
||||
}
|
||||
firstAttachment := attachments[0]
|
||||
if firstAttachment == nil {
|
||||
t.Fatalf("failed to retrieve first attachment, got nil")
|
||||
}
|
||||
if firstAttachment.Desc != tt.desc {
|
||||
t.Errorf("WithFileDescription() failed. Expected: %s, got: %s", tt.desc,
|
||||
firstAttachment.Desc)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
t.Run("WithFileContentID", func(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
id string
|
||||
}{
|
||||
{"Content-ID: test", "test"},
|
||||
{"Content-ID: with newline", "test\n"},
|
||||
{"Content-ID: empty", ""},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
message := NewMsg()
|
||||
message.AttachFile("file.go", WithFileContentID(tt.id))
|
||||
attachments := message.GetAttachments()
|
||||
if len(attachments) <= 0 {
|
||||
t.Fatalf("failed to retrieve attachments list")
|
||||
}
|
||||
firstAttachment := attachments[0]
|
||||
if firstAttachment == nil {
|
||||
t.Fatalf("failed to retrieve first attachment, got nil")
|
||||
}
|
||||
contentID := firstAttachment.Header.Get(HeaderContentID.String())
|
||||
if contentID != tt.id {
|
||||
t.Errorf("WithFileContentID() failed. Expected: %s, got: %s", tt.id,
|
||||
contentID)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
t.Run("WithFileEncoding", func(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
encoding Encoding
|
||||
want Encoding
|
||||
}{
|
||||
{"File encoding: US-ASCII", EncodingUSASCII, EncodingUSASCII},
|
||||
{"File encoding: 8bit raw", NoEncoding, NoEncoding},
|
||||
{"File encoding: Base64", EncodingB64, EncodingB64},
|
||||
{"File encoding: quoted-printable (not allowed)", EncodingQP, ""},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
message := NewMsg()
|
||||
message.AttachFile("file.go", WithFileEncoding(tt.encoding))
|
||||
attachments := message.GetAttachments()
|
||||
if len(attachments) <= 0 {
|
||||
t.Fatalf("failed to retrieve attachments list")
|
||||
}
|
||||
firstAttachment := attachments[0]
|
||||
if firstAttachment == nil {
|
||||
t.Fatalf("failed to retrieve first attachment, got nil")
|
||||
}
|
||||
if firstAttachment.Enc != tt.want {
|
||||
t.Errorf("WithFileEncoding() failed. Expected: %s, got: %s", tt.want, firstAttachment.Enc)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
t.Run("WithFileName", func(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
fileName string
|
||||
}{
|
||||
{"File name: test", "test"},
|
||||
{"File name: with newline", "test\n"},
|
||||
{"File name: empty", ""},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
message := NewMsg()
|
||||
message.AttachFile("file.go", WithFileName(tt.fileName))
|
||||
attachments := message.GetAttachments()
|
||||
if len(attachments) <= 0 {
|
||||
t.Fatalf("failed to retrieve attachments list")
|
||||
}
|
||||
firstAttachment := attachments[0]
|
||||
if firstAttachment == nil {
|
||||
t.Fatalf("failed to retrieve first attachment, got nil")
|
||||
}
|
||||
if firstAttachment.Name != tt.fileName {
|
||||
t.Errorf("WithFileName() failed. Expected: %s, got: %s", tt.fileName,
|
||||
firstAttachment.Name)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TestFile_WithFileDescription tests the WithFileDescription option
|
||||
func TestFile_WithFileDescription(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
desc string
|
||||
}{
|
||||
{"File description: test", "test"},
|
||||
{"File description: empty", ""},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
m := NewMsg()
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m.AttachFile("file.go", WithFileDescription(tt.desc))
|
||||
al := m.GetAttachments()
|
||||
if len(al) <= 0 {
|
||||
t.Errorf("AttachFile() failed. Attachment list is empty")
|
||||
}
|
||||
a := al[0]
|
||||
if a.Desc != tt.desc {
|
||||
t.Errorf("WithFileDescription() failed. Expected: %s, got: %s", tt.desc, a.Desc)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
// TestFile_WithContentID tests the WithFileContentID option
|
||||
func TestFile_WithContentID(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
contentid string
|
||||
}{
|
||||
{"File Content-ID: test", "test"},
|
||||
{"File Content-ID: empty", ""},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
m := NewMsg()
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m.AttachFile("file.go", WithFileContentID(tt.contentid))
|
||||
al := m.GetAttachments()
|
||||
if len(al) <= 0 {
|
||||
t.Errorf("AttachFile() failed. Attachment list is empty")
|
||||
}
|
||||
a := al[0]
|
||||
if a.Header.Get(HeaderContentID.String()) != tt.contentid {
|
||||
t.Errorf("WithFileContentID() failed. Expected: %s, got: %s", tt.contentid,
|
||||
a.Header.Get(HeaderContentID.String()))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestFile_WithFileEncoding tests the WithFileEncoding option
|
||||
func TestFile_WithFileEncoding(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
enc Encoding
|
||||
want Encoding
|
||||
}{
|
||||
{"File encoding: 8bit raw", NoEncoding, NoEncoding},
|
||||
{"File encoding: Base64", EncodingB64, EncodingB64},
|
||||
{"File encoding: quoted-printable (not allowed)", EncodingQP, ""},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
m := NewMsg()
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m.AttachFile("file.go", WithFileEncoding(tt.enc))
|
||||
al := m.GetAttachments()
|
||||
if len(al) <= 0 {
|
||||
t.Errorf("AttachFile() failed. Attachment list is empty")
|
||||
}
|
||||
a := al[0]
|
||||
if a.Enc != tt.want {
|
||||
t.Errorf("WithFileEncoding() failed. Expected: %s, got: %s", tt.enc, a.Enc)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestFile_WithFileContentType tests the WithFileContentType option
|
||||
func TestFile_WithFileContentType(t *testing.T) {
|
||||
|
@ -137,3 +188,6 @@ func TestFile_WithFileContentType(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
|
|
8
testdata/RFC5322-A1-1-invalid-from.eml
vendored
Normal file
8
testdata/RFC5322-A1-1-invalid-from.eml
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
From: §§§§§§§§
|
||||
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".
|
3
testdata/RFC5322-A1-1-invalid-from.eml.license
vendored
Normal file
3
testdata/RFC5322-A1-1-invalid-from.eml.license
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 The go-mail Authors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
8
testdata/RFC5322-A1-1.eml
vendored
Normal file
8
testdata/RFC5322-A1-1.eml
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
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".
|
3
testdata/RFC5322-A1-1.eml.license
vendored
Normal file
3
testdata/RFC5322-A1-1.eml.license
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 The go-mail Authors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
Loading…
Reference in a new issue