mirror of
https://github.com/wneessen/go-mail.git
synced 2024-11-25 23:15:08 +01:00
Compare commits
22 commits
e7e0fe03bb
...
c28bd7e331
Author | SHA1 | Date | |
---|---|---|---|
c28bd7e331 | |||
1c6b9faf15 | |||
7d670a1f24 | |||
2f3809f33e | |||
4ecc6f2b0c | |||
a59173fae0 | |||
d39953c837 | |||
6cbb6745bb | |||
4506472319 | |||
759452f346 | |||
4eb9d8a1fa | |||
afa65585a0 | |||
4a519a3b1f | |||
ae44d37d03 | |||
80bf7240b4 | |||
f48ff6e150 | |||
c395c83a06 | |||
ae7b6a68c5 | |||
d02f469658 | |||
e779777c9b | |||
f576b92ce2 | |||
466c2892bf |
6 changed files with 1583 additions and 1200 deletions
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
|
@ -31,8 +31,8 @@ jobs:
|
||||||
go: ['1.23']
|
go: ['1.23']
|
||||||
env:
|
env:
|
||||||
PERFORM_ONLINE_TEST: ${{ vars.PERFORM_ONLINE_TEST }}
|
PERFORM_ONLINE_TEST: ${{ vars.PERFORM_ONLINE_TEST }}
|
||||||
PERFORM_UNIX_OPEN_WRITE_TESTS: "true"
|
PERFORM_UNIX_OPEN_WRITE_TESTS: ${{ vars.PERFORM_UNIX_OPEN_WRITE_TESTS }}
|
||||||
TEST_SENDMAIL: ${{ vars.TEST_SENDMAIL }}
|
PERFORM_SENDMAIL_TESTS: ${{ vars.PERFORM_SENDMAIL_TESTS }}
|
||||||
TEST_HOST: ${{ secrets.TEST_HOST }}
|
TEST_HOST: ${{ secrets.TEST_HOST }}
|
||||||
TEST_USER: ${{ secrets.TEST_USER }}
|
TEST_USER: ${{ secrets.TEST_USER }}
|
||||||
TEST_PASS: ${{ secrets.TEST_PASS }}
|
TEST_PASS: ${{ secrets.TEST_PASS }}
|
||||||
|
|
|
@ -3559,6 +3559,7 @@ type serverProps struct {
|
||||||
FailOnQuit bool
|
FailOnQuit bool
|
||||||
FailOnReset bool
|
FailOnReset bool
|
||||||
FailOnSTARTTLS bool
|
FailOnSTARTTLS bool
|
||||||
|
FailTemp bool
|
||||||
FeatureSet string
|
FeatureSet string
|
||||||
ListenPort int
|
ListenPort int
|
||||||
SSLListener bool
|
SSLListener bool
|
||||||
|
@ -3720,6 +3721,10 @@ func handleTestServerConnection(connection net.Conn, t *testing.T, props *server
|
||||||
writeLine("500 5.0.0 Error during DATA transmission")
|
writeLine("500 5.0.0 Error during DATA transmission")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if props.FailTemp {
|
||||||
|
writeLine("451 4.3.0 Error: fail on DATA close")
|
||||||
|
break
|
||||||
|
}
|
||||||
writeLine("250 2.0.0 Ok: queued as 1234567890")
|
writeLine("250 2.0.0 Ok: queued as 1234567890")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,17 +6,17 @@ coverage:
|
||||||
status:
|
status:
|
||||||
project:
|
project:
|
||||||
default:
|
default:
|
||||||
target: 85%
|
target: 90%
|
||||||
threshold: 5%
|
threshold: 2%
|
||||||
base: auto
|
base: auto
|
||||||
if_ci_failed: error
|
if_ci_failed: error
|
||||||
only_pulls: false
|
only_pulls: false
|
||||||
patch:
|
patch:
|
||||||
default:
|
default:
|
||||||
target: 80%
|
target: 90%
|
||||||
base: auto
|
base: auto
|
||||||
if_ci_failed: error
|
if_ci_failed: error
|
||||||
threshold: 5%
|
threshold: 2%
|
||||||
|
|
||||||
comment:
|
comment:
|
||||||
require_changes: true
|
require_changes: true
|
||||||
|
|
4
msg.go
4
msg.go
|
@ -2371,8 +2371,8 @@ func (m *Msg) WriteToSendmailWithContext(ctx context.Context, sendmailPath strin
|
||||||
// - https://datatracker.ietf.org/doc/html/rfc5322
|
// - https://datatracker.ietf.org/doc/html/rfc5322
|
||||||
func (m *Msg) NewReader() *Reader {
|
func (m *Msg) NewReader() *Reader {
|
||||||
reader := &Reader{}
|
reader := &Reader{}
|
||||||
buffer := bytes.Buffer{}
|
buffer := bytes.NewBuffer(nil)
|
||||||
_, err := m.Write(&buffer)
|
_, err := m.Write(buffer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reader.err = fmt.Errorf("failed to write Msg to Reader buffer: %w", err)
|
reader.err = fmt.Errorf("failed to write Msg to Reader buffer: %w", err)
|
||||||
}
|
}
|
||||||
|
|
2615
msg_test.go
2615
msg_test.go
File diff suppressed because it is too large
Load diff
147
msg_unix_test.go
147
msg_unix_test.go
|
@ -9,11 +9,9 @@ package mail
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
|
||||||
"errors"
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMsg_AttachFile_unixOnly(t *testing.T) {
|
func TestMsg_AttachFile_unixOnly(t *testing.T) {
|
||||||
|
@ -22,7 +20,7 @@ func TestMsg_AttachFile_unixOnly(t *testing.T) {
|
||||||
t.Skipf("PERFORM_UNIX_OPEN_WRITE_TESTS variable is not set. Skipping unix open/write tests")
|
t.Skipf("PERFORM_UNIX_OPEN_WRITE_TESTS variable is not set. Skipping unix open/write tests")
|
||||||
}
|
}
|
||||||
|
|
||||||
tempFile, err := os.CreateTemp("testdata/tmp", "attachfile-open-write-test.*.txt")
|
tempFile, err := os.CreateTemp("", "attachfile-open-write-test.*.txt")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create temp file: %s", err)
|
t.Fatalf("failed to create temp file: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -53,134 +51,76 @@ func TestMsg_AttachFile_unixOnly(t *testing.T) {
|
||||||
t.Errorf("expected error to be %s, got: %s", os.ErrPermission, err)
|
t.Errorf("expected error to be %s, got: %s", os.ErrPermission, err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
t.Run("AttachFile with fileFromFS fails on copy", func(t *testing.T) {
|
}
|
||||||
tempfile, err := os.CreateTemp("testdata/tmp", "attachfile-close-early.*.txt")
|
|
||||||
|
func TestMsg_EmbedFile_unixOnly(t *testing.T) {
|
||||||
|
t.Run("EmbedFile with fileFromFS fails on open", func(t *testing.T) {
|
||||||
|
if os.Getenv("PERFORM_UNIX_OPEN_WRITE_TESTS") != "true" {
|
||||||
|
t.Skipf("PERFORM_UNIX_OPEN_WRITE_TESTS variable is not set. Skipping unix open/write tests")
|
||||||
|
}
|
||||||
|
|
||||||
|
tempFile, err := os.CreateTemp("", "embedfile-open-write-test.*.txt")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create temp file: %s", err)
|
t.Fatalf("failed to create temp file: %s", err)
|
||||||
}
|
}
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
if err := os.Remove(tempfile.Name()); err != nil {
|
if err := os.Remove(tempFile.Name()); err != nil {
|
||||||
t.Errorf("failed to remove temp file: %s", err)
|
t.Errorf("failed to remove temp file: %s", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
if err = os.Chmod(tempFile.Name(), 0o000); err != nil {
|
||||||
|
t.Fatalf("failed to chmod temp file: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
message := NewMsg()
|
message := NewMsg()
|
||||||
if message == nil {
|
if message == nil {
|
||||||
t.Fatal("message is nil")
|
t.Fatal("message is nil")
|
||||||
}
|
}
|
||||||
message.AttachFile("testdata/attachment.txt")
|
message.EmbedFile(tempFile.Name())
|
||||||
attachments := message.GetAttachments()
|
embeds := message.GetEmbeds()
|
||||||
if len(attachments) != 1 {
|
if len(embeds) != 1 {
|
||||||
t.Fatalf("failed to get attachments, expected 1, got: %d", len(attachments))
|
t.Fatalf("failed to get embeds, expected 1, got: %d", len(embeds))
|
||||||
}
|
}
|
||||||
messageBuf, err := os.Open(tempfile.Name())
|
messageBuf := bytes.NewBuffer(nil)
|
||||||
if err != nil {
|
_, err = embeds[0].Writer(messageBuf)
|
||||||
t.Fatalf("failed to open temp file: %s", err)
|
|
||||||
}
|
|
||||||
// We close early to cause an error during io.Copy
|
|
||||||
if err = messageBuf.Close(); err != nil {
|
|
||||||
t.Fatalf("failed to close temp file: %s", err)
|
|
||||||
}
|
|
||||||
_, err = attachments[0].Writer(messageBuf)
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("writer func expected to fail, but didn't")
|
t.Error("writer func expected to fail, but didn't")
|
||||||
}
|
}
|
||||||
|
if !errors.Is(err, os.ErrPermission) {
|
||||||
|
t.Errorf("expected error to be %s, got: %s", os.ErrPermission, err)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMsg_AttachReader_unixOnly(t *testing.T) {
|
func TestMsg_WriteToFile_unixOnly(t *testing.T) {
|
||||||
t.Run("AttachReader with fileFromReader fails on copy", func(t *testing.T) {
|
t.Run("WriteToFile fails on create", func(t *testing.T) {
|
||||||
tempfile, err := os.CreateTemp("", "attachfile-close-early.*.txt")
|
if os.Getenv("PERFORM_UNIX_OPEN_WRITE_TESTS") != "true" {
|
||||||
|
t.Skipf("PERFORM_UNIX_OPEN_WRITE_TESTS variable is not set. Skipping unix open/write tests")
|
||||||
|
}
|
||||||
|
|
||||||
|
tempfile, err := os.CreateTemp("", "testmail-create.*.eml")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create temp file: %s", err)
|
t.Fatalf("failed to create temp file: %s", err)
|
||||||
}
|
}
|
||||||
t.Cleanup(func() {
|
if err = os.Chmod(tempfile.Name(), 0o000); err != nil {
|
||||||
if err := os.Remove(tempfile.Name()); err != nil {
|
t.Fatalf("failed to chmod temp file: %s", err)
|
||||||
t.Errorf("failed to remove temp file: %s", err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
message := NewMsg()
|
|
||||||
if message == nil {
|
|
||||||
t.Fatal("message is nil")
|
|
||||||
}
|
|
||||||
file, err := os.Open("testdata/attachment.txt")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to open file: %s", err)
|
|
||||||
}
|
}
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
if err := file.Close(); err != nil {
|
if err = tempfile.Close(); err != nil {
|
||||||
t.Errorf("failed to close file: %s", err)
|
t.Fatalf("failed to close temp file: %s", err)
|
||||||
|
}
|
||||||
|
if err = os.Remove(tempfile.Name()); err != nil {
|
||||||
|
t.Fatalf("failed to remove temp file: %s", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if err = message.AttachReader("attachment.txt", file); err != nil {
|
message := testMessage(t)
|
||||||
t.Fatalf("failed to attach reader: %s", err)
|
if err = message.WriteToFile(tempfile.Name()); err == nil {
|
||||||
}
|
t.Errorf("expected error, got nil")
|
||||||
attachments := message.GetAttachments()
|
|
||||||
if len(attachments) != 1 {
|
|
||||||
t.Fatalf("failed to get attachments, expected 1, got: %d", len(attachments))
|
|
||||||
}
|
|
||||||
messageBuf, err := os.Open(tempfile.Name())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to open temp file: %s", err)
|
|
||||||
}
|
|
||||||
// We close early to cause an error during io.Copy
|
|
||||||
if err = messageBuf.Close(); err != nil {
|
|
||||||
t.Fatalf("failed to close temp file: %s", err)
|
|
||||||
}
|
|
||||||
_, err = attachments[0].Writer(messageBuf)
|
|
||||||
if err == nil {
|
|
||||||
t.Error("writer func expected to fail, but didn't")
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestMsg_WriteToSendmailWithContext tests the WriteToSendmailWithContext() method of the Msg
|
/*
|
||||||
func TestMsg_WriteToSendmailWithContext(t *testing.T) {
|
|
||||||
if os.Getenv("TEST_SENDMAIL") != "true" {
|
|
||||||
t.Skipf("TEST_SENDMAIL variable is not set. Skipping sendmail test")
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
sp string
|
|
||||||
sf bool
|
|
||||||
}{
|
|
||||||
{"Sendmail path: /dev/null", "/dev/null", true},
|
|
||||||
{"Sendmail path: /bin/cat", "/bin/cat", true},
|
|
||||||
{"Sendmail path: /is/invalid", "/is/invalid", true},
|
|
||||||
{"Sendmail path: /bin/echo", "/bin/echo", false},
|
|
||||||
}
|
|
||||||
m := NewMsg()
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
ctx, cfn := context.WithTimeout(context.Background(), time.Second*10)
|
|
||||||
defer cfn()
|
|
||||||
m.SetBodyString(TypeTextPlain, "Plain")
|
|
||||||
if err := m.WriteToSendmailWithContext(ctx, tt.sp); err != nil && !tt.sf {
|
|
||||||
t.Errorf("WriteToSendmailWithCommand() failed: %s", err)
|
|
||||||
}
|
|
||||||
m.Reset()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestMsg_WriteToSendmail will test the output to the local sendmail command
|
|
||||||
func TestMsg_WriteToSendmail(t *testing.T) {
|
|
||||||
if os.Getenv("TEST_SENDMAIL") != "true" {
|
|
||||||
t.Skipf("TEST_SENDMAIL variable is not set. Skipping sendmail test")
|
|
||||||
}
|
|
||||||
_, err := os.Stat(SendmailPath)
|
|
||||||
if err != nil {
|
|
||||||
t.Skipf("local sendmail command not found in expected path. Skipping")
|
|
||||||
}
|
|
||||||
|
|
||||||
m := NewMsg()
|
|
||||||
_ = m.From("Toni Tester <tester@example.com>")
|
|
||||||
_ = m.To(TestRcpt)
|
|
||||||
m.SetBodyString(TypeTextPlain, "This is a test")
|
|
||||||
if err := m.WriteToSendmail(); err != nil {
|
|
||||||
t.Errorf("WriteToSendmail failed: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMsg_WriteToTempFileFailed(t *testing.T) {
|
func TestMsg_WriteToTempFileFailed(t *testing.T) {
|
||||||
m := NewMsg()
|
m := NewMsg()
|
||||||
_ = m.From("Toni Tester <tester@example.com>")
|
_ = m.From("Toni Tester <tester@example.com>")
|
||||||
|
@ -202,3 +142,6 @@ func TestMsg_WriteToTempFileFailed(t *testing.T) {
|
||||||
t.Errorf("WriteToTempFile() did not fail as expected")
|
t.Errorf("WriteToTempFile() did not fail as expected")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
Loading…
Reference in a new issue