From f48ff6e1502e8b6e2e749ea02c7d23b0e1858683 Mon Sep 17 00:00:00 2001 From: Winni Neessen Date: Mon, 28 Oct 2024 12:17:20 +0100 Subject: [PATCH] Add tests for embedding functionalities in Msg Introduce unit tests for EmbedReadSeeker, EmbedHTMLTemplate, EmbedTextTemplate, and EmbedFromEmbedFS methods in the Msg package. These tests cover various use cases and error scenarios, ensuring the correct handling of embedded content. --- msg_test.go | 234 ++++++++++++++++++++++++++++++++++++++++++++++- msg_unix_test.go | 44 +++++++++ 2 files changed, 277 insertions(+), 1 deletion(-) diff --git a/msg_test.go b/msg_test.go index b50edf9..7b52688 100644 --- a/msg_test.go +++ b/msg_test.go @@ -136,7 +136,7 @@ var ( } ) -//go:embed testdata/attachment.txt +//go:embed testdata/attachment.txt testdata/embed.txt var efs embed.FS func TestNewMsg(t *testing.T) { @@ -4872,6 +4872,238 @@ func TestMsg_EmbedReader(t *testing.T) { }) } +func TestMsg_EmbedReadSeeker(t *testing.T) { + t.Run("EmbedReadSeeker with file", func(t *testing.T) { + message := NewMsg() + if message == nil { + t.Fatal("message is nil") + } + file, err := os.Open("testdata/embed.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) + } + }) + message.EmbedReadSeeker("embed.txt", file) + embeds := message.GetEmbeds() + if len(embeds) != 1 { + t.Fatalf("failed to retrieve embeds list") + } + if embeds[0] == nil { + t.Fatal("expected embed to be not nil") + } + if embeds[0].Name != "embed.txt" { + t.Errorf("expected embed name to be %s, got: %s", "embed.txt", embeds[0].Name) + } + messageBuf := bytes.NewBuffer(nil) + _, err = embeds[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 embed") { + t.Errorf("expected message body to be %s, got: %s", "This is a test embed", got) + } + }) +} + +func TestMsg_EmbedHTMLTemplate(t *testing.T) { + tplString := `

{{.teststring}}

` + invalidTplString := `

{{call $.invalid .teststring}}

` + data := map[string]interface{}{"teststring": "this is a test"} + htmlTpl, err := ht.New("htmltpl").Parse(tplString) + if err != nil { + t.Fatalf("failed to parse HTML template: %s", err) + } + invalidTpl, err := ht.New("htmltpl").Parse(invalidTplString) + if err != nil { + t.Fatalf("failed to parse invalid HTML template: %s", err) + } + t.Run("EmbedHTMLTemplate with valid template", func(t *testing.T) { + message := NewMsg() + if message == nil { + t.Fatal("message is nil") + } + if err = message.EmbedHTMLTemplate("embed.html", htmlTpl, data); err != nil { + t.Fatalf("failed to set body HTML template: %s", err) + } + embeds := message.GetEmbeds() + if len(embeds) != 1 { + t.Fatalf("failed to retrieve embeds list") + } + if embeds[0] == nil { + t.Fatal("expected embed to be not nil") + } + if embeds[0].Name != "embed.html" { + t.Errorf("expected embed name to be %s, got: %s", "embed.html", embeds[0].Name) + } + messageBuf := bytes.NewBuffer(nil) + _, err = embeds[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

") { + t.Errorf("expected message body to be %s, got: %s", "

this is a test

", got) + } + }) + t.Run("EmbedHTMLTemplate with invalid template", func(t *testing.T) { + message := NewMsg() + if message == nil { + t.Fatal("message is nil") + } + err = message.EmbedHTMLTemplate("embed.html", invalidTpl, data) + if err == nil { + t.Fatal("expected error, got nil") + } + expectErr := `failed to embed template: failed to execute template: template: htmltpl:1:5: executing "htmltpl" ` + + `at : error calling call: call of nil` + if !strings.EqualFold(err.Error(), expectErr) { + t.Errorf("expected error to be %s, got: %s", expectErr, err.Error()) + } + }) + t.Run("EmbedHTMLTemplate with nil template", func(t *testing.T) { + message := NewMsg() + if message == nil { + t.Fatal("message is nil") + } + err = message.EmbedHTMLTemplate("embed.html", nil, data) + if err == nil { + t.Fatal("expected error, got nil") + } + expectedErr := `failed to embed template: ` + errTplPointerNil + if !strings.EqualFold(err.Error(), expectedErr) { + t.Errorf("expected error to be %s, got: %s", expectedErr, err.Error()) + } + }) +} + +func TestMsg_EmbedTextTemplate(t *testing.T) { + tplString := `Teststring: {{.teststring}}` + invalidTplString := `Teststring: {{call $.invalid .teststring}}` + data := map[string]interface{}{"teststring": "this is a test"} + textTpl, err := ttpl.New("texttpl").Parse(tplString) + if err != nil { + t.Fatalf("failed to parse Text template: %s", err) + } + invalidTpl, err := ttpl.New("texttpl").Parse(invalidTplString) + if err != nil { + t.Fatalf("failed to parse invalid Text template: %s", err) + } + t.Run("EmbedTextTemplate with valid template", func(t *testing.T) { + message := NewMsg() + if message == nil { + t.Fatal("message is nil") + } + if err = message.EmbedTextTemplate("embed.txt", textTpl, data); err != nil { + t.Fatalf("failed to set body HTML template: %s", err) + } + embeds := message.GetEmbeds() + if len(embeds) != 1 { + t.Fatalf("failed to retrieve embeds list") + } + if embeds[0] == nil { + t.Fatal("expected embed to be not nil") + } + if embeds[0].Name != "embed.txt" { + t.Errorf("expected embed name to be %s, got: %s", "embed.txt", embeds[0].Name) + } + messageBuf := bytes.NewBuffer(nil) + _, err = embeds[0].Writer(messageBuf) + if err != nil { + t.Errorf("writer func failed: %s", err) + } + got := strings.TrimSpace(messageBuf.String()) + if !strings.EqualFold(got, "Teststring: this is a test") { + t.Errorf("expected message body to be %s, got: %s", "Teststring: this is a test", got) + } + }) + t.Run("EmbedTextTemplate with invalid template", func(t *testing.T) { + message := NewMsg() + if message == nil { + t.Fatal("message is nil") + } + err = message.EmbedTextTemplate("embed.txt", invalidTpl, data) + if err == nil { + t.Fatal("expected error, got nil") + } + expectErr := `failed to embed template: failed to execute template: template: texttpl:1:14: executing "texttpl" ` + + `at : error calling call: call of nil` + if !strings.EqualFold(err.Error(), expectErr) { + t.Errorf("expected error to be %s, got: %s", expectErr, err.Error()) + } + }) + t.Run("EmbedTextTemplate with nil template", func(t *testing.T) { + message := NewMsg() + if message == nil { + t.Fatal("message is nil") + } + err = message.EmbedTextTemplate("embed.html", nil, data) + if err == nil { + t.Fatal("expected error, got nil") + } + expectedErr := `failed to embed template: ` + errTplPointerNil + if !strings.EqualFold(err.Error(), expectedErr) { + t.Errorf("expected error to be %s, got: %s", expectedErr, err.Error()) + } + }) +} + +func TestMsg_EmbedFromEmbedFS(t *testing.T) { + t.Run("EmbedFromEmbedFS successful", func(t *testing.T) { + message := NewMsg() + if message == nil { + t.Fatal("message is nil") + } + if err := message.EmbedFromEmbedFS("testdata/embed.txt", &efs, + WithFileName("embed.txt")); err != nil { + t.Fatalf("failed to embed from embed FS: %s", err) + } + embeds := message.GetEmbeds() + if len(embeds) != 1 { + t.Fatalf("failed to retrieve embeds list") + } + if embeds[0] == nil { + t.Fatal("expected embed to be not nil") + } + if embeds[0].Name != "embed.txt" { + t.Errorf("expected embed name to be %s, got: %s", "embed.txt", embeds[0].Name) + } + messageBuf := bytes.NewBuffer(nil) + _, err := embeds[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 embed") { + t.Errorf("expected message body to be %s, got: %s", "This is a test embed", got) + } + }) + t.Run("EmbedFromEmbedFS with invalid path", func(t *testing.T) { + message := NewMsg() + if message == nil { + t.Fatal("message is nil") + } + err := message.EmbedFromEmbedFS("testdata/invalid.txt", &efs, WithFileName("embed.txt")) + if err == nil { + t.Fatal("expected error, got nil") + } + }) + t.Run("EmbedFromEmbedFS with nil embed FS", func(t *testing.T) { + message := NewMsg() + if message == nil { + t.Fatal("message is nil") + } + err := message.EmbedFromEmbedFS("testdata/invalid.txt", nil, WithFileName("embed.txt")) + if err == nil { + t.Fatal("expected error, got nil") + } + }) +} + /* // TestNewMsgWithMiddleware tests WithMiddleware diff --git a/msg_unix_test.go b/msg_unix_test.go index 0200470..eec15ff 100644 --- a/msg_unix_test.go +++ b/msg_unix_test.go @@ -315,6 +315,50 @@ func TestMsg_EmbedReader_unixOnly(t *testing.T) { }) } +func TestMsg_EmbedReadSeeker_unixOnly(t *testing.T) { + t.Run("EmbedReadSeeker with fileFromReadSeeker fails on copy", func(t *testing.T) { + tempfile, err := os.CreateTemp("", "embedfile-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/embed.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) + } + }) + message.EmbedReadSeeker("embed.txt", file) + embeds := message.GetEmbeds() + if len(embeds) != 1 { + t.Fatalf("failed to get embeds, expected 1, got: %d", len(embeds)) + } + 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 = embeds[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" {