Add tests for Msg attachment handling

Introduce new unit tests for verifying the `AttachReader` method and enhancing error handling in attachment functions. These tests cover scenarios for success, file permissions, and early file closure errors.
This commit is contained in:
Winni Neessen 2024-10-27 15:54:39 +01:00
parent 0cf636ee9b
commit 946ad294ce
Signed by: wneessen
GPG key ID: 385AC9889632126E
2 changed files with 138 additions and 0 deletions

View file

@ -8,12 +8,83 @@
package mail
import (
"bytes"
"context"
"errors"
"os"
"testing"
"time"
)
func TestMsg_AttachFile_unixOnly(t *testing.T) {
t.Run("AttachFile with fileFromFS fails on open", func(t *testing.T) {
tempfile, err := os.CreateTemp("", "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(), 0000); 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("", "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")
}
if !errors.Is(err, os.ErrClosed) {
t.Errorf("expected error to be %s, got: %s", os.ErrClosed, err)
}
})
}
// TestMsg_WriteToSendmailWithContext tests the WriteToSendmailWithContext() method of the Msg
func TestMsg_WriteToSendmailWithContext(t *testing.T) {
if os.Getenv("TEST_SENDMAIL") != "true" {

View file

@ -12,6 +12,7 @@ import (
ht "html/template"
"io"
"net"
"os"
"reflect"
"strings"
"testing"
@ -4491,6 +4492,15 @@ func TestMsg_AttachFile(t *testing.T) {
if attachments[0].Name != "attachment.txt" {
t.Errorf("expected attachment name to be %s, got: %s", "attachment.txt", attachments[0].Name)
}
messageBuf := bytes.NewBuffer(nil)
_, err := attachments[0].Writer(messageBuf)
if err != nil {
t.Errorf("writer func failed: %s", err)
}
got := strings.TrimSpace(messageBuf.String())
if !strings.EqualFold(got, "This is a test attachment") {
t.Errorf("expected message body to be %s, got: %s", "This is a test attachment", got)
}
})
t.Run("AttachFile with non-existant file", func(t *testing.T) {
message := NewMsg()
@ -4508,6 +4518,63 @@ func TestMsg_AttachFile(t *testing.T) {
})
}
func TestMsg_AttachReader(t *testing.T) {
t.Run("AttachReader with file", func(t *testing.T) {
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 retrieve attachments list")
}
if attachments[0] == nil {
t.Fatal("expected attachment to be not nil")
}
if attachments[0].Name != "attachment.txt" {
t.Errorf("expected attachment name to be %s, got: %s", "attachment.txt", attachments[0].Name)
}
messageBuf := bytes.NewBuffer(nil)
_, err = attachments[0].Writer(messageBuf)
if err != nil {
t.Errorf("writer func failed: %s", err)
}
got := strings.TrimSpace(messageBuf.String())
if !strings.EqualFold(got, "This is a test attachment") {
t.Errorf("expected message body to be %s, got: %s", "This is a test attachment", got)
}
})
/*
t.Run("AttachReader with non-existant file", func(t *testing.T) {
message := NewMsg()
if message == nil {
t.Fatal("message is nil")
}
message.AttachReader("testdata/non-existant-file.txt")
attachments := message.GetAttachments()
if len(attachments) != 0 {
t.Fatalf("failed to retrieve attachments list")
}
})
t.Run("AttachReader with options", func(t *testing.T) {
t.Log("all options have already been tested in file_test.go")
})
*/
}
/*
// TestNewMsgWithMiddleware tests WithMiddleware