mirror of
https://github.com/wneessen/go-mail.git
synced 2024-11-25 07:00:49 +01:00
Compare commits
33 commits
e808e0b972
...
9682755e25
Author | SHA1 | Date | |
---|---|---|---|
9682755e25 | |||
8fb05a33ff | |||
7b9df7de47 | |||
bdffa22ad8 | |||
89f29b241e | |||
eed3dec7d6 | |||
3be41b1aea | |||
f7cfe5289a | |||
946ad294ce | |||
0cf636ee9b | |||
84f9d0583d | |||
254dc81706 | |||
e00ddda3a3 | |||
602f8a6e29 | |||
4db66696a6 | |||
f8caa5599b | |||
35ffc95102 | |||
432e21f162 | |||
0aa81d724b | |||
78ee1a2a81 | |||
b510d2654c | |||
056ec60734 | |||
cb5ac8b0e2 | |||
6376f29190 | |||
9a01629c47 | |||
2dad9d36b2 | |||
c8c7d18ba9 | |||
472a5a6454 | |||
f2619737e8 | |||
b7ca41af81 | |||
66e25d82d3 | |||
babf7b9780 | |||
43f9ffa3af |
11 changed files with 1794 additions and 514 deletions
23
.cirrus.yml
23
.cirrus.yml
|
@ -1,23 +0,0 @@
|
||||||
# SPDX-FileCopyrightText: 2022 Winni Neessen <winni@neessen.dev>
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
freebsd_task:
|
|
||||||
name: FreeBSD
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
- name: FreeBSD 13.3
|
|
||||||
freebsd_instance:
|
|
||||||
image_family: freebsd-13-3
|
|
||||||
- name: FreeBSD 14.0
|
|
||||||
freebsd_instance:
|
|
||||||
image_family: freebsd-14-0
|
|
||||||
|
|
||||||
env:
|
|
||||||
TEST_SKIP_SENDMAIL: 1
|
|
||||||
|
|
||||||
pkginstall_script:
|
|
||||||
- pkg install -y go
|
|
||||||
|
|
||||||
test_script:
|
|
||||||
- go test -race -cover -shuffle=on ./...
|
|
20
.github/workflows/ci.yml
vendored
20
.github/workflows/ci.yml
vendored
|
@ -136,6 +136,26 @@ jobs:
|
||||||
- name: Run go test
|
- name: Run go test
|
||||||
run: |
|
run: |
|
||||||
go test -race -shuffle=on ./...
|
go test -race -shuffle=on ./...
|
||||||
|
test-fbsd:
|
||||||
|
name: Test on FreeBSD ${{ matrix.osver }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
concurrency:
|
||||||
|
group: ci-test-freebsd-${{ matrix.osver }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
osver: ['13.4', '14.0', '14.1']
|
||||||
|
steps:
|
||||||
|
- name: Checkout Code
|
||||||
|
uses: actions/checkout@61b9e3751b92087fd0b06925ba6dd6314e06f089 # master
|
||||||
|
- name: Run go test on FreeBSD
|
||||||
|
uses: vmactions/freebsd-vm@v1
|
||||||
|
with:
|
||||||
|
usesh: true
|
||||||
|
prepare: |
|
||||||
|
pkg install -y go
|
||||||
|
run: |
|
||||||
|
go test -race -shuffle=on ./...
|
||||||
reuse:
|
reuse:
|
||||||
name: REUSE Compliance Check
|
name: REUSE Compliance Check
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
|
@ -2579,6 +2579,10 @@ func TestClient_Send(t *testing.T) {
|
||||||
}
|
}
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
if err := client.Close(); err != nil {
|
if err := client.Close(); err != nil {
|
||||||
|
var netErr net.Error
|
||||||
|
if errors.As(err, &netErr) && netErr.Timeout() {
|
||||||
|
t.Skip("failed to close the test server connection due to timeout")
|
||||||
|
}
|
||||||
t.Errorf("failed to close client: %s", err)
|
t.Errorf("failed to close client: %s", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
24
msg.go
24
msg.go
|
@ -1681,11 +1681,11 @@ func (m *Msg) SetBodyHTMLTemplate(tpl *ht.Template, data interface{}, opts ...Pa
|
||||||
if tpl == nil {
|
if tpl == nil {
|
||||||
return errors.New(errTplPointerNil)
|
return errors.New(errTplPointerNil)
|
||||||
}
|
}
|
||||||
buffer := bytes.Buffer{}
|
buffer := bytes.NewBuffer(nil)
|
||||||
if err := tpl.Execute(&buffer, data); err != nil {
|
if err := tpl.Execute(buffer, data); err != nil {
|
||||||
return fmt.Errorf(errTplExecuteFailed, err)
|
return fmt.Errorf(errTplExecuteFailed, err)
|
||||||
}
|
}
|
||||||
writeFunc := writeFuncFromBuffer(&buffer)
|
writeFunc := writeFuncFromBuffer(buffer)
|
||||||
m.SetBodyWriter(TypeTextHTML, writeFunc, opts...)
|
m.SetBodyWriter(TypeTextHTML, writeFunc, opts...)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1712,11 +1712,11 @@ func (m *Msg) SetBodyTextTemplate(tpl *tt.Template, data interface{}, opts ...Pa
|
||||||
if tpl == nil {
|
if tpl == nil {
|
||||||
return errors.New(errTplPointerNil)
|
return errors.New(errTplPointerNil)
|
||||||
}
|
}
|
||||||
buf := bytes.Buffer{}
|
buffer := bytes.NewBuffer(nil)
|
||||||
if err := tpl.Execute(&buf, data); err != nil {
|
if err := tpl.Execute(buffer, data); err != nil {
|
||||||
return fmt.Errorf(errTplExecuteFailed, err)
|
return fmt.Errorf(errTplExecuteFailed, err)
|
||||||
}
|
}
|
||||||
writeFunc := writeFuncFromBuffer(&buf)
|
writeFunc := writeFuncFromBuffer(buffer)
|
||||||
m.SetBodyWriter(TypeTextPlain, writeFunc, opts...)
|
m.SetBodyWriter(TypeTextPlain, writeFunc, opts...)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1786,11 +1786,11 @@ func (m *Msg) AddAlternativeHTMLTemplate(tpl *ht.Template, data interface{}, opt
|
||||||
if tpl == nil {
|
if tpl == nil {
|
||||||
return errors.New(errTplPointerNil)
|
return errors.New(errTplPointerNil)
|
||||||
}
|
}
|
||||||
buffer := bytes.Buffer{}
|
buffer := bytes.NewBuffer(nil)
|
||||||
if err := tpl.Execute(&buffer, data); err != nil {
|
if err := tpl.Execute(buffer, data); err != nil {
|
||||||
return fmt.Errorf(errTplExecuteFailed, err)
|
return fmt.Errorf(errTplExecuteFailed, err)
|
||||||
}
|
}
|
||||||
writeFunc := writeFuncFromBuffer(&buffer)
|
writeFunc := writeFuncFromBuffer(buffer)
|
||||||
m.AddAlternativeWriter(TypeTextHTML, writeFunc, opts...)
|
m.AddAlternativeWriter(TypeTextHTML, writeFunc, opts...)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1816,11 +1816,11 @@ func (m *Msg) AddAlternativeTextTemplate(tpl *tt.Template, data interface{}, opt
|
||||||
if tpl == nil {
|
if tpl == nil {
|
||||||
return errors.New(errTplPointerNil)
|
return errors.New(errTplPointerNil)
|
||||||
}
|
}
|
||||||
buffer := bytes.Buffer{}
|
buffer := bytes.NewBuffer(nil)
|
||||||
if err := tpl.Execute(&buffer, data); err != nil {
|
if err := tpl.Execute(buffer, data); err != nil {
|
||||||
return fmt.Errorf(errTplExecuteFailed, err)
|
return fmt.Errorf(errTplExecuteFailed, err)
|
||||||
}
|
}
|
||||||
writeFunc := writeFuncFromBuffer(&buffer)
|
writeFunc := writeFuncFromBuffer(buffer)
|
||||||
m.AddAlternativeWriter(TypeTextPlain, writeFunc, opts...)
|
m.AddAlternativeWriter(TypeTextPlain, writeFunc, opts...)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,126 @@
|
||||||
package mail
|
package mail
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestMsg_AttachFile_unixOnly(t *testing.T) {
|
||||||
|
t.Run("AttachFile with fileFromFS fails on open", func(t *testing.T) {
|
||||||
|
tempfile, err := os.CreateTemp("testdata/tmp", "attachfile-unable-to-open.*.txt")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create temp file: %s", err)
|
||||||
|
}
|
||||||
|
t.Cleanup(func() {
|
||||||
|
if err := os.Remove(tempfile.Name()); err != nil {
|
||||||
|
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 to 0000: %s", err)
|
||||||
|
}
|
||||||
|
message := NewMsg()
|
||||||
|
if message == nil {
|
||||||
|
t.Fatal("message is nil")
|
||||||
|
}
|
||||||
|
message.AttachFile(tempfile.Name())
|
||||||
|
attachments := message.GetAttachments()
|
||||||
|
if len(attachments) != 1 {
|
||||||
|
t.Fatalf("failed to get attachments, expected 1, got: %d", len(attachments))
|
||||||
|
}
|
||||||
|
messageBuf := bytes.NewBuffer(nil)
|
||||||
|
_, err = attachments[0].Writer(messageBuf)
|
||||||
|
if err == nil {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("AttachFile with fileFromFS fails on copy", func(t *testing.T) {
|
||||||
|
tempfile, err := os.CreateTemp("testdata/tmp", "attachfile-close-early.*.txt")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create temp file: %s", err)
|
||||||
|
}
|
||||||
|
t.Cleanup(func() {
|
||||||
|
if err := os.Remove(tempfile.Name()); err != nil {
|
||||||
|
t.Errorf("failed to remove temp file: %s", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
message := NewMsg()
|
||||||
|
if message == nil {
|
||||||
|
t.Fatal("message is nil")
|
||||||
|
}
|
||||||
|
message.AttachFile("testdata/attachment.txt")
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMsg_AttachReader_unixOnly(t *testing.T) {
|
||||||
|
t.Run("AttachReader with fileFromReader fails on copy", func(t *testing.T) {
|
||||||
|
tempfile, err := os.CreateTemp("", "attachfile-close-early.*.txt")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create temp file: %s", err)
|
||||||
|
}
|
||||||
|
t.Cleanup(func() {
|
||||||
|
if err := os.Remove(tempfile.Name()); err != nil {
|
||||||
|
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() {
|
||||||
|
if err := file.Close(); err != nil {
|
||||||
|
t.Errorf("failed to close file: %s", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if err = message.AttachReader("attachment.txt", file); err != nil {
|
||||||
|
t.Fatalf("failed to attach reader: %s", err)
|
||||||
|
}
|
||||||
|
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
|
// TestMsg_WriteToSendmailWithContext tests the WriteToSendmailWithContext() method of the Msg
|
||||||
func TestMsg_WriteToSendmailWithContext(t *testing.T) {
|
func TestMsg_WriteToSendmailWithContext(t *testing.T) {
|
||||||
if os.Getenv("TEST_SENDMAIL") != "true" {
|
if os.Getenv("TEST_SENDMAIL") != "true" {
|
||||||
|
|
2115
msg_test.go
2115
msg_test.go
File diff suppressed because it is too large
Load diff
1
testdata/attachment.txt
vendored
Normal file
1
testdata/attachment.txt
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
This is a test attachment
|
3
testdata/attachment.txt.license
vendored
Normal file
3
testdata/attachment.txt.license
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 The go-mail Authors
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: MIT
|
1
testdata/embed.txt
vendored
Normal file
1
testdata/embed.txt
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
This is a test embed
|
3
testdata/embed.txt.license
vendored
Normal file
3
testdata/embed.txt.license
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 The go-mail Authors
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: MIT
|
0
testdata/tmp/.gitkeep
vendored
Normal file
0
testdata/tmp/.gitkeep
vendored
Normal file
Loading…
Reference in a new issue