mirror of
https://github.com/wneessen/go-mail.git
synced 2024-11-22 22:00:49 +01:00
Compare commits
No commits in common. "9834c6508d39b985fa8faf9b5d432883ec7aa40c" and "28dc629674d86a0618064503dbbdd02c0baffac8" have entirely different histories.
9834c6508d
...
28dc629674
9 changed files with 2016 additions and 1967 deletions
16
client.go
16
client.go
|
@ -1094,6 +1094,10 @@ func (c *Client) DialAndSendWithContext(ctx context.Context, messages ...*Msg) e
|
||||||
// - An error if the connection check fails, if no supported authentication method is found,
|
// - An error if the connection check fails, if no supported authentication method is found,
|
||||||
// or if the authentication process fails.
|
// or if the authentication process fails.
|
||||||
func (c *Client) auth() error {
|
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 {
|
if c.smtpAuth == nil && c.smtpAuthType != SMTPAuthNoAuth {
|
||||||
hasSMTPAuth, smtpAuthType := c.smtpClient.Extension("AUTH")
|
hasSMTPAuth, smtpAuthType := c.smtpClient.Extension("AUTH")
|
||||||
if !hasSMTPAuth {
|
if !hasSMTPAuth {
|
||||||
|
@ -1276,6 +1280,12 @@ func (c *Client) sendSingleMsg(message *Msg) error {
|
||||||
affectedMsg: message,
|
affectedMsg: message,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if err = c.checkConn(); err != nil {
|
||||||
|
return &SendError{
|
||||||
|
Reason: ErrConnCheck, errlist: []error{err}, isTemp: isTempError(err),
|
||||||
|
affectedMsg: message,
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1292,9 +1302,6 @@ func (c *Client) sendSingleMsg(message *Msg) error {
|
||||||
// - An error if there is no active connection, if the NOOP command fails, or if extending
|
// - An error if there is no active connection, if the NOOP command fails, or if extending
|
||||||
// the deadline fails; otherwise, returns nil.
|
// the deadline fails; otherwise, returns nil.
|
||||||
func (c *Client) checkConn() error {
|
func (c *Client) checkConn() error {
|
||||||
if c.smtpClient == nil {
|
|
||||||
return ErrNoActiveConnection
|
|
||||||
}
|
|
||||||
if !c.smtpClient.HasConnection() {
|
if !c.smtpClient.HasConnection() {
|
||||||
return ErrNoActiveConnection
|
return ErrNoActiveConnection
|
||||||
}
|
}
|
||||||
|
@ -1353,6 +1360,9 @@ func (c *Client) setDefaultHelo() error {
|
||||||
// - An error if there is no active connection, if STARTTLS is required but not supported,
|
// - 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.
|
// or if there are issues during the TLS handshake; otherwise, returns nil.
|
||||||
func (c *Client) tls() error {
|
func (c *Client) tls() error {
|
||||||
|
if !c.smtpClient.HasConnection() {
|
||||||
|
return ErrNoActiveConnection
|
||||||
|
}
|
||||||
if !c.useSSL && c.tlspolicy != NoTLS {
|
if !c.useSSL && c.tlspolicy != NoTLS {
|
||||||
hasStartTLS := false
|
hasStartTLS := false
|
||||||
extension, _ := c.smtpClient.Extension("STARTTLS")
|
extension, _ := c.smtpClient.Extension("STARTTLS")
|
||||||
|
|
2733
client_test.go
2733
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)
|
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)
|
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)
|
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)
|
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 {
|
for _, addr := range parsedAddrs {
|
||||||
addrStrings = append(addrStrings, addr.String())
|
addrStrings = append(addrStrings, addr.String())
|
||||||
}
|
}
|
||||||
// We can skip the error checking here since netmail.ParseAddressList already performed the
|
if err = addrFunc(addrStrings...); err != nil {
|
||||||
// same address checking that the msg methods do.
|
return fmt.Errorf(`failed to parse %q header: %w`, addrHeader, err)
|
||||||
_ = addrFunc(addrStrings...)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,8 +600,6 @@ func parseEMLAttachmentEmbed(contentDisposition []string, multiPart *multipart.P
|
||||||
if err := msg.EmbedReader(filename, dataReader); err != nil {
|
if err := msg.EmbedReader(filename, dataReader); err != nil {
|
||||||
return fmt.Errorf("failed to embed multipart body: %w", err)
|
return fmt.Errorf("failed to embed multipart body: %w", err)
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
return errors.New("unsupported content disposition type")
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
588
eml_test.go
588
eml_test.go
|
@ -6,8 +6,11 @@ package mail
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -19,23 +22,6 @@ Subject: Saying Hello
|
||||||
Date: Fri, 21 Nov 1997 09:55:06 -0600
|
Date: Fri, 21 Nov 1997 09:55:06 -0600
|
||||||
Message-ID: <1234@local.machine.example>
|
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.
|
This is a message just to say hello.
|
||||||
So, "Hello".`
|
So, "Hello".`
|
||||||
exampleMailPlainNoEnc = `Date: Wed, 01 Nov 2023 00:00:00 +0000
|
exampleMailPlainNoEnc = `Date: Wed, 01 Nov 2023 00:00:00 +0000
|
||||||
|
@ -56,52 +42,6 @@ This is a test mail. Please do not reply to this. Also this line is very long so
|
||||||
should be wrapped.
|
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!
|
Thank your for your business!
|
||||||
The go-mail team
|
The go-mail team
|
||||||
|
|
||||||
|
@ -364,128 +304,6 @@ VGhpcyBpcyBhIHNpbXBsZSB0ZXN0IHRleHQgZmlsZSBhdHRhY2htZW50LgoKSXQgCiAgaGFzCiAg
|
||||||
ICAgc2V2ZXJhbAogICAgICAgICAgICBuZXdsaW5lcwoJICAgICAgICAgICAgYW5kCgkgICAgc3Bh
|
ICAgc2V2ZXJhbAogICAgICAgICAgICBuZXdsaW5lcwoJICAgICAgICAgICAgYW5kCgkgICAgc3Bh
|
||||||
Y2VzCiAgICAgaW4KICBpdAouCgpBcyB3ZWxsIGFzIGFuIGVtb2ppOiDwn5mCCg==
|
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--`
|
--45c75ff528359022eb03679fbe91877d75343f2e1f8193e349deffa33ff7--`
|
||||||
exampleMailPlainB64WithAttachmentNoBoundary = `Date: Wed, 01 Nov 2023 00:00:00 +0000
|
exampleMailPlainB64WithAttachmentNoBoundary = `Date: Wed, 01 Nov 2023 00:00:00 +0000
|
||||||
MIME-Version: 1.0
|
MIME-Version: 1.0
|
||||||
|
@ -760,39 +578,6 @@ Content-Disposition: attachment;
|
||||||
filename="testfile.txt"
|
filename="testfile.txt"
|
||||||
|
|
||||||
VGhpcyBpcyBhIHRlc3QgaW4gQmFzZTY0
|
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--`
|
--------------26A45336F6C6196BD8BBA2A2--`
|
||||||
exampleMultiPart8BitBase64 = `Date: Wed, 01 Nov 2023 00:00:00 +0000
|
exampleMultiPart8BitBase64 = `Date: Wed, 01 Nov 2023 00:00:00 +0000
|
||||||
MIME-Version: 1.0
|
MIME-Version: 1.0
|
||||||
|
@ -827,352 +612,8 @@ Content-Disposition: attachment;
|
||||||
|
|
||||||
VGhpcyBpcyBhIHRlc3QgaW4gQmFzZTY0
|
VGhpcyBpcyBhIHRlc3QgaW4gQmFzZTY0
|
||||||
--------------26A45336F6C6196BD8BBA2A2--`
|
--------------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) {
|
func TestEMLToMsgFromString(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -1180,6 +621,26 @@ func TestEMLToMsgFromString(t *testing.T) {
|
||||||
enc string
|
enc string
|
||||||
sub 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 {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
@ -1548,6 +1009,3 @@ func stringToTempFile(data, name string) (string, string, error) {
|
||||||
}
|
}
|
||||||
return tempDir, filePath, nil
|
return tempDir, filePath, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
162
file_test.go
162
file_test.go
|
@ -6,160 +6,109 @@ package mail
|
||||||
|
|
||||||
import "testing"
|
import "testing"
|
||||||
|
|
||||||
func TestFile(t *testing.T) {
|
// TestFile_SetGetHeader tests the set-/getHeader method of the File object
|
||||||
t.Run("setHeader", func(t *testing.T) {
|
func TestFile_SetGetHeader(t *testing.T) {
|
||||||
f := File{
|
f := File{
|
||||||
Name: "testfile.txt",
|
Name: "testfile.txt",
|
||||||
Header: make(map[string][]string),
|
Header: make(map[string][]string),
|
||||||
}
|
}
|
||||||
f.setHeader(HeaderContentType, "text/plain")
|
f.setHeader(HeaderContentType, "text/plain")
|
||||||
contentType, ok := f.Header[HeaderContentType.String()]
|
fi, ok := f.getHeader(HeaderContentType)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Fatalf("setHeader failed. Expected header %s to be set", HeaderContentType)
|
t.Errorf("getHeader method of File did not return a value")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if len(contentType) != 1 {
|
if fi != "text/plain" {
|
||||||
t.Fatalf("setHeader failed. Expected header %s to have one value, got: %d", HeaderContentType,
|
t.Errorf("getHeader returned wrong value. Expected: %s, got: %s", "text/plain", fi)
|
||||||
len(contentType))
|
|
||||||
}
|
}
|
||||||
if contentType[0] != "text/plain" {
|
fi, ok = f.getHeader(HeaderContentTransferEnc)
|
||||||
t.Fatalf("setHeader failed. Expected header %s to have value %s, got: %s",
|
if ok {
|
||||||
HeaderContentType.String(), "text/plain", contentType[0])
|
t.Errorf("getHeader method of File did return a value, but wasn't supposed to")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
})
|
if fi != "" {
|
||||||
t.Run("getHeader", func(t *testing.T) {
|
t.Errorf("getHeader returned wrong value. Expected: %s, got: %s", "", fi)
|
||||||
f := File{
|
|
||||||
Name: "testfile.txt",
|
|
||||||
Header: make(map[string][]string),
|
|
||||||
}
|
}
|
||||||
f.setHeader(HeaderContentType, "text/plain")
|
}
|
||||||
contentType, ok := f.getHeader(HeaderContentType)
|
|
||||||
if !ok {
|
// TestFile_WithFileDescription tests the WithFileDescription option
|
||||||
t.Fatalf("setHeader failed. Expected header %s to be set", HeaderContentType)
|
func TestFile_WithFileDescription(t *testing.T) {
|
||||||
}
|
|
||||||
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 {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
desc string
|
desc string
|
||||||
}{
|
}{
|
||||||
{"File description: test", "test"},
|
{"File description: test", "test"},
|
||||||
{"File description: with newline", "test\n"},
|
|
||||||
{"File description: empty", ""},
|
{"File description: empty", ""},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
m := NewMsg()
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
message := NewMsg()
|
m.AttachFile("file.go", WithFileDescription(tt.desc))
|
||||||
message.AttachFile("file.go", WithFileDescription(tt.desc))
|
al := m.GetAttachments()
|
||||||
attachments := message.GetAttachments()
|
if len(al) <= 0 {
|
||||||
if len(attachments) <= 0 {
|
t.Errorf("AttachFile() failed. Attachment list is empty")
|
||||||
t.Fatalf("failed to retrieve attachments list")
|
|
||||||
}
|
}
|
||||||
firstAttachment := attachments[0]
|
a := al[0]
|
||||||
if firstAttachment == nil {
|
if a.Desc != tt.desc {
|
||||||
t.Fatalf("failed to retrieve first attachment, got nil")
|
t.Errorf("WithFileDescription() failed. Expected: %s, got: %s", tt.desc, a.Desc)
|
||||||
}
|
|
||||||
if firstAttachment.Desc != tt.desc {
|
|
||||||
t.Errorf("WithFileDescription() failed. Expected: %s, got: %s", tt.desc,
|
|
||||||
firstAttachment.Desc)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
t.Run("WithFileContentID", func(t *testing.T) {
|
|
||||||
|
// TestFile_WithContentID tests the WithFileContentID option
|
||||||
|
func TestFile_WithContentID(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
id string
|
contentid string
|
||||||
}{
|
}{
|
||||||
{"Content-ID: test", "test"},
|
{"File Content-ID: test", "test"},
|
||||||
{"Content-ID: with newline", "test\n"},
|
{"File Content-ID: empty", ""},
|
||||||
{"Content-ID: empty", ""},
|
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
m := NewMsg()
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
message := NewMsg()
|
m.AttachFile("file.go", WithFileContentID(tt.contentid))
|
||||||
message.AttachFile("file.go", WithFileContentID(tt.id))
|
al := m.GetAttachments()
|
||||||
attachments := message.GetAttachments()
|
if len(al) <= 0 {
|
||||||
if len(attachments) <= 0 {
|
t.Errorf("AttachFile() failed. Attachment list is empty")
|
||||||
t.Fatalf("failed to retrieve attachments list")
|
|
||||||
}
|
}
|
||||||
firstAttachment := attachments[0]
|
a := al[0]
|
||||||
if firstAttachment == nil {
|
if a.Header.Get(HeaderContentID.String()) != tt.contentid {
|
||||||
t.Fatalf("failed to retrieve first attachment, got nil")
|
t.Errorf("WithFileContentID() failed. Expected: %s, got: %s", tt.contentid,
|
||||||
}
|
a.Header.Get(HeaderContentID.String()))
|
||||||
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) {
|
|
||||||
|
// TestFile_WithFileEncoding tests the WithFileEncoding option
|
||||||
|
func TestFile_WithFileEncoding(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
encoding Encoding
|
enc Encoding
|
||||||
want Encoding
|
want Encoding
|
||||||
}{
|
}{
|
||||||
{"File encoding: US-ASCII", EncodingUSASCII, EncodingUSASCII},
|
|
||||||
{"File encoding: 8bit raw", NoEncoding, NoEncoding},
|
{"File encoding: 8bit raw", NoEncoding, NoEncoding},
|
||||||
{"File encoding: Base64", EncodingB64, EncodingB64},
|
{"File encoding: Base64", EncodingB64, EncodingB64},
|
||||||
{"File encoding: quoted-printable (not allowed)", EncodingQP, ""},
|
{"File encoding: quoted-printable (not allowed)", EncodingQP, ""},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
m := NewMsg()
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
message := NewMsg()
|
m.AttachFile("file.go", WithFileEncoding(tt.enc))
|
||||||
message.AttachFile("file.go", WithFileEncoding(tt.encoding))
|
al := m.GetAttachments()
|
||||||
attachments := message.GetAttachments()
|
if len(al) <= 0 {
|
||||||
if len(attachments) <= 0 {
|
t.Errorf("AttachFile() failed. Attachment list is empty")
|
||||||
t.Fatalf("failed to retrieve attachments list")
|
|
||||||
}
|
}
|
||||||
firstAttachment := attachments[0]
|
a := al[0]
|
||||||
if firstAttachment == nil {
|
if a.Enc != tt.want {
|
||||||
t.Fatalf("failed to retrieve first attachment, got nil")
|
t.Errorf("WithFileEncoding() failed. Expected: %s, got: %s", tt.enc, a.Enc)
|
||||||
}
|
|
||||||
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_WithFileContentType tests the WithFileContentType option
|
// TestFile_WithFileContentType tests the WithFileContentType option
|
||||||
func TestFile_WithFileContentType(t *testing.T) {
|
func TestFile_WithFileContentType(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
@ -188,6 +137,3 @@ func TestFile_WithFileContentType(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
8
testdata/RFC5322-A1-1-invalid-from.eml
vendored
8
testdata/RFC5322-A1-1-invalid-from.eml
vendored
|
@ -1,8 +0,0 @@
|
||||||
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".
|
|
|
@ -1,3 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 The go-mail Authors
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
8
testdata/RFC5322-A1-1.eml
vendored
8
testdata/RFC5322-A1-1.eml
vendored
|
@ -1,8 +0,0 @@
|
||||||
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
3
testdata/RFC5322-A1-1.eml.license
vendored
|
@ -1,3 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 The go-mail Authors
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
Loading…
Reference in a new issue