From 4f97cd8261ab28be5abf07e5db1326e66537ac25 Mon Sep 17 00:00:00 2001 From: Winni Neessen Date: Sat, 26 Oct 2024 21:33:43 +0200 Subject: [PATCH] Initialize `genHeader` in RequestMDNTo method Add checks to initialize `genHeader` if it is nil in the RequestMDNTo method to prevent potential nil map assignment errors. The newly implemented tests showed that this method was never actually working and the old test was inefficient to identify this. --- msg.go | 7 +++--- msg_test.go | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/msg.go b/msg.go index e19f8e5..8ce7a91 100644 --- a/msg.go +++ b/msg.go @@ -1187,6 +1187,9 @@ func (m *Msg) IsDelivered() bool { // References: // - https://datatracker.ietf.org/doc/html/rfc8098 func (m *Msg) RequestMDNTo(rcpts ...string) error { + if m.genHeader == nil { + m.genHeader = make(map[Header][]string) + } var addresses []string for _, addrVal := range rcpts { address, err := mail.ParseAddress(addrVal) @@ -1195,9 +1198,7 @@ func (m *Msg) RequestMDNTo(rcpts ...string) error { } addresses = append(addresses, address.String()) } - if _, ok := m.genHeader[HeaderDispositionNotificationTo]; ok { - m.genHeader[HeaderDispositionNotificationTo] = addresses - } + m.genHeader[HeaderDispositionNotificationTo] = addresses return nil } diff --git a/msg_test.go b/msg_test.go index d085713..31a7565 100644 --- a/msg_test.go +++ b/msg_test.go @@ -1915,6 +1915,76 @@ func TestMsg_IsDelivered(t *testing.T) { }) } +func TestMsg_RequestMDNTo(t *testing.T) { + t.Run("RequestMDNTo with valid address", func(t *testing.T) { + message := NewMsg() + if message == nil { + t.Fatal("message is nil") + } + if err := message.RequestMDNTo("toni.tester@example.com"); err != nil { + t.Fatalf("failed to set RequestMDNTo: %s", err) + } + checkGenHeader(t, message, HeaderDispositionNotificationTo, "RequestMDNTo", 0, 1, "") + }) + t.Run("RequestMDNTo with valid address and nil-genHeader", func(t *testing.T) { + message := NewMsg() + if message == nil { + t.Fatal("message is nil") + } + message.genHeader = nil + if err := message.RequestMDNTo("toni.tester@example.com"); err != nil { + t.Fatalf("failed to set RequestMDNTo: %s", err) + } + checkGenHeader(t, message, HeaderDispositionNotificationTo, "RequestMDNTo", 0, 1, "") + }) + t.Run("RequestMDNTo with multiple valid addresses", func(t *testing.T) { + message := NewMsg() + if message == nil { + t.Fatal("message is nil") + } + if err := message.RequestMDNTo("toni.tester@example.com", "tina.tester@example.com"); err != nil { + t.Fatalf("failed to set RequestMDNTo: %s", err) + } + checkGenHeader(t, message, HeaderDispositionNotificationTo, "RequestMDNTo", 0, 2, "") + checkGenHeader(t, message, HeaderDispositionNotificationTo, "RequestMDNTo", 1, 2, "") + }) + t.Run("RequestMDNTo with invalid address", func(t *testing.T) { + message := NewMsg() + if message == nil { + t.Fatal("message is nil") + } + if err := message.RequestMDNTo("invalid"); err == nil { + t.Fatalf("RequestMDNTo should fail with invalid address") + } + }) + t.Run("RequestMDNTo with empty string should fail", func(t *testing.T) { + message := NewMsg() + if message == nil { + t.Fatal("message is nil") + } + if err := message.RequestMDNTo(""); err == nil { + t.Fatalf("RequestMDNTo should fail with invalid address") + } + }) + t.Run("RequestMDNTo with different RFC5322 addresses", func(t *testing.T) { + message := NewMsg() + if message == nil { + t.Fatal("message is nil") + } + for _, tt := range rfc5322Test { + t.Run(tt.value, func(t *testing.T) { + err := message.RequestMDNTo(tt.value) + if err != nil && tt.valid { + t.Errorf("RequestMDNTo on address %s should succeed, but failed with: %s", tt.value, err) + } + if err == nil && !tt.valid { + t.Errorf("RequestMDNTo on address %s should fail, but succeeded", tt.value) + } + }) + } + }) +} + // checkAddrHeader verifies the correctness of an AddrHeader in a Msg based on the provided criteria. // It checks whether the AddrHeader contains the correct address, name, and number of fields. func checkAddrHeader(t *testing.T, message *Msg, header AddrHeader, fn string, field, wantFields int,