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.
This commit is contained in:
Winni Neessen 2024-10-26 21:33:43 +02:00
parent 9e51dba82a
commit 4f97cd8261
Signed by: wneessen
GPG key ID: 385AC9889632126E
2 changed files with 74 additions and 3 deletions

7
msg.go
View file

@ -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
}

View file

@ -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, "<toni.tester@example.com>")
})
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, "<toni.tester@example.com>")
})
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, "<toni.tester@example.com>")
checkGenHeader(t, message, HeaderDispositionNotificationTo, "RequestMDNTo", 1, 2, "<tina.tester@example.com>")
})
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,