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,