Compare commits

..

21 commits

Author SHA1 Message Date
8b6a7927ef
Add dummy test function in msg_test.go
Introduce a new, empty test function `TestMsg_ToIgnoreInvalid` in `msg_test.go` to accommodate future test cases. This commit also aligns a comment for better readability.
2024-10-25 17:43:59 +02:00
1ea7b173c6
Add tests for Msg.AddToFormat
Introduced new test cases to validate Msg.AddToFormat functionality with both valid and invalid email addresses. Ensured proper error handling and address formatting in the message headers.
2024-10-25 17:16:46 +02:00
a7f81baa4b
Fix address references in tests and add AddTo functionality
Corrected incorrect address references in the `msg_test.go` file. Added new tests to validate the AddTo functionality, ensuring multiple addresses can be added and validated properly.
2024-10-25 17:13:22 +02:00
cb85a136c3
Add Goland noinspection comments to suppress deprecation warnings
This change adds `//goland:noinspection GoDeprecation` comments in the `msg_test.go` file. These comments suppress deprecation warnings for the `SetHeader` and `SetHeaderPreformatted` methods during test execution.
2024-10-25 17:05:22 +02:00
aa46b408ad
Add additional tests for From and To address handling
Refactor "From" related tests to improve error messages and add tests for the new "FromFormat" function. Introduce new tests to validate the "To" address handling, covering various valid and invalid address scenarios.
2024-10-25 17:03:57 +02:00
5d85be068d
Add comprehensive tests for email "From" field validation
Implemented extensive test cases for the "From" field in email messages, covering various valid and invalid email formats according to RFC5322. Verified correct handling for each scenario to ensure robustness of email address validation.
2024-10-25 16:36:34 +02:00
1caa2cfb92
Add tests for EnvelopeFrom and EnvelopeFromFormat methods
Implemented comprehensive tests for the EnvelopeFrom and EnvelopeFromFormat methods to ensure proper handling of valid and invalid email addresses. This includes validation of both address and format for the "EnvelopeFrom" header.
2024-10-25 15:14:06 +02:00
c8dbc9a735
Update tests for SetAddrHeader and add new test cases
Renamed existing test cases for clarity and added new test cases for SetAddrHeaderIgnoreInvalid function. The new tests cover multiple scenarios including valid/invalid addresses, and edge cases such as nil addrHeader map.
2024-10-25 15:00:53 +02:00
08fe44c051
Initialize address header map and enforce single 'From' address.
This commit ensures that the address header map is properly initialized before assigning addresses to it. Additionally, it enforces the rule that only a single 'From' address is allowed, preventing multiple addresses from being set for the 'From' header. These misses were found while working on the enhanced testing suite
2024-10-25 14:57:36 +02:00
7d352bc58e
Add comprehensive tests for header and address methods
Implemented extensive unit tests for setting various headers and address fields in the `Msg` struct, including setting general headers, preformatted headers, and address headers with various scenarios to ensure correctness and robustness.
2024-10-25 12:18:26 +02:00
9505f94e3d
Refactor header test structure and improve readability
Simplify test structure by renaming fields for clarity and brevity. AddressHeader tests and importance tests now use more concise and consistent naming conventions. This enhances readability and maintainability of the test code.
2024-10-25 12:18:12 +02:00
143e3b5b4f
Fix context in tests and improve error handling
Updated test cases to use a predefined context instead of creating new backgrounds. Additionally, improved error handling by checking for client creation failures and adding appropriate fatal log messages. These changes enhance test reliability and debugging clarity.
2024-10-25 11:46:48 +02:00
a2e9dbae11
Add unit tests for charset and header setting in messages
This commit introduces two new unit tests: `TestMsg_Charset` and `TestMsg_SetHeader`. These tests cover the functionality of setting and retrieving the character set and headers for messages, ensuring correctness and robustness.
2024-10-25 11:36:26 +02:00
69c5f43cbf
Refactor test cases in header_test.go
Consolidate repetitive test case definitions into separate slices for readability and maintainability. This change simplifies the addition of new test cases and reduces redundancy.
2024-10-25 11:36:17 +02:00
425a190eb1
fumpt'ed formatting 2024-10-25 11:36:05 +02:00
64aeb683ba
Format test cases for consistency
Reformat test cases in `client_test.go` for better readability and consistency by converting single-line struct definitions into multi-line blocks. This change improves code maintainability and aligns the formatting across similar tests.
2024-10-25 11:35:25 +02:00
1dba76948f
Simplify test descriptions in msg_test.go
Shortened the test case descriptions for better clarity and readability. Added a new test function 'TestMsg_Encoding' to verify encoding outputs.
2024-10-25 11:24:35 +02:00
120c2efd08
Refactor test cases with shared test data
Consolidated repetitive test data into shared variables to improve code maintainability and readability. This modification also helps in reducing redundancy and streamlining future updates to test data.
2024-10-25 11:18:09 +02:00
c4946af3ab
Refactor msg_test.go to streamline tests and reduce redundancy
Reorganized and condensed test cases for the NewMsg method by merging individual tests and removing obsolete functions. This improves maintainability and reduces duplication in the test suite.
2024-10-25 11:08:11 +02:00
64cfbf9e46
Rename test functions and add new header cases.
Renamed test functions from `TestHeader_String` to `TestHeader_Stringer` and `TestAddrHeader_String` to `TestAddrHeader_Stringer` for consistency. Additionally, added new header cases such as "Content-Description" and "X-Auto-Response-Suppress" to improve test coverage.
2024-10-25 09:53:49 +02:00
c58d52e49a
Refactor TestImportance_StringFuncs in header_test.go
Separated test cases for String, NumString, and XPrioString methods of the Importance object into distinct sub-tests. Improved readability and maintainability by grouping similar assertions together.
2024-10-25 09:48:00 +02:00
5 changed files with 4569 additions and 3293 deletions

View file

@ -1448,20 +1448,32 @@ func TestClient_SetSMTPAuthCustom(t *testing.T) {
want string want string
}{ }{
{"CRAM-MD5", smtp.CRAMMD5Auth("", ""), "*smtp.cramMD5Auth"}, {"CRAM-MD5", smtp.CRAMMD5Auth("", ""), "*smtp.cramMD5Auth"},
{"LOGIN", smtp.LoginAuth("", "", "", false), {
"*smtp.loginAuth"}, "LOGIN", smtp.LoginAuth("", "", "", false),
{"LOGIN-NOENC", smtp.LoginAuth("", "", "", true), "*smtp.loginAuth",
"*smtp.loginAuth"}, },
{"PLAIN", smtp.PlainAuth("", "", "", "", false), {
"*smtp.plainAuth"}, "LOGIN-NOENC", smtp.LoginAuth("", "", "", true),
{"PLAIN-NOENC", smtp.PlainAuth("", "", "", "", true), "*smtp.loginAuth",
"*smtp.plainAuth"}, },
{
"PLAIN", smtp.PlainAuth("", "", "", "", false),
"*smtp.plainAuth",
},
{
"PLAIN-NOENC", smtp.PlainAuth("", "", "", "", true),
"*smtp.plainAuth",
},
{"SCRAM-SHA-1", smtp.ScramSHA1Auth("", ""), "*smtp.scramAuth"}, {"SCRAM-SHA-1", smtp.ScramSHA1Auth("", ""), "*smtp.scramAuth"},
{"SCRAM-SHA-1-PLUS", smtp.ScramSHA1PlusAuth("", "", nil), {
"*smtp.scramAuth"}, "SCRAM-SHA-1-PLUS", smtp.ScramSHA1PlusAuth("", "", nil),
"*smtp.scramAuth",
},
{"SCRAM-SHA-256", smtp.ScramSHA256Auth("", ""), "*smtp.scramAuth"}, {"SCRAM-SHA-256", smtp.ScramSHA256Auth("", ""), "*smtp.scramAuth"},
{"SCRAM-SHA-256-PLUS", smtp.ScramSHA256PlusAuth("", "", nil), {
"*smtp.scramAuth"}, "SCRAM-SHA-256-PLUS", smtp.ScramSHA256PlusAuth("", "", nil),
"*smtp.scramAuth",
},
{"XOAUTH2", smtp.XOAuth2Auth("", ""), "*smtp.xoauth2Auth"}, {"XOAUTH2", smtp.XOAuth2Auth("", ""), "*smtp.xoauth2Auth"},
} }
for _, tt := range tests { for _, tt := range tests {
@ -1483,7 +1495,6 @@ func TestClient_SetSMTPAuthCustom(t *testing.T) {
t.Errorf("failed to set custom SMTP auth, expected auth method type: %s, got: %s", t.Errorf("failed to set custom SMTP auth, expected auth method type: %s, got: %s",
tt.want, authType) tt.want, authType)
} }
}) })
} }
}) })
@ -1785,7 +1796,7 @@ func TestClient_DialWithContext(t *testing.T) {
} }
}) })
t.Run("connect should fail on HELO", func(t *testing.T) { t.Run("connect should fail on HELO", func(t *testing.T) {
ctxFail, cancelFail := context.WithCancel(context.Background()) ctxFail, cancelFail := context.WithCancel(ctx)
defer cancelFail() defer cancelFail()
PortAdder.Add(1) PortAdder.Add(1)
failServerPort := int(TestServerPortBase + PortAdder.Load()) failServerPort := int(TestServerPortBase + PortAdder.Load())
@ -1820,7 +1831,7 @@ func TestClient_DialWithContext(t *testing.T) {
} }
}) })
t.Run("connect with failing auth", func(t *testing.T) { t.Run("connect with failing auth", func(t *testing.T) {
ctxAuth, cancelAuth := context.WithCancel(context.Background()) ctxAuth, cancelAuth := context.WithCancel(ctx)
defer cancelAuth() defer cancelAuth()
PortAdder.Add(1) PortAdder.Add(1)
authServerPort := int(TestServerPortBase + PortAdder.Load()) authServerPort := int(TestServerPortBase + PortAdder.Load())
@ -1850,7 +1861,7 @@ func TestClient_DialWithContext(t *testing.T) {
} }
}) })
t.Run("connect with STARTTLS", func(t *testing.T) { t.Run("connect with STARTTLS", func(t *testing.T) {
ctxTLS, cancelTLS := context.WithCancel(context.Background()) ctxTLS, cancelTLS := context.WithCancel(ctx)
defer cancelTLS() defer cancelTLS()
PortAdder.Add(1) PortAdder.Add(1)
tlsServerPort := int(TestServerPortBase + PortAdder.Load()) tlsServerPort := int(TestServerPortBase + PortAdder.Load())
@ -1880,7 +1891,7 @@ func TestClient_DialWithContext(t *testing.T) {
} }
}) })
t.Run("connect with STARTTLS Opportunisticly", func(t *testing.T) { t.Run("connect with STARTTLS Opportunisticly", func(t *testing.T) {
ctxTLS, cancelTLS := context.WithCancel(context.Background()) ctxTLS, cancelTLS := context.WithCancel(ctx)
defer cancelTLS() defer cancelTLS()
PortAdder.Add(1) PortAdder.Add(1)
tlsServerPort := int(TestServerPortBase + PortAdder.Load()) tlsServerPort := int(TestServerPortBase + PortAdder.Load())
@ -1910,7 +1921,7 @@ func TestClient_DialWithContext(t *testing.T) {
} }
}) })
t.Run("connect with STARTTLS but fail", func(t *testing.T) { t.Run("connect with STARTTLS but fail", func(t *testing.T) {
ctxTLS, cancelTLS := context.WithCancel(context.Background()) ctxTLS, cancelTLS := context.WithCancel(ctx)
defer cancelTLS() defer cancelTLS()
PortAdder.Add(1) PortAdder.Add(1)
tlsServerPort := int(TestServerPortBase + PortAdder.Load()) tlsServerPort := int(TestServerPortBase + PortAdder.Load())
@ -1941,7 +1952,7 @@ func TestClient_DialWithContext(t *testing.T) {
} }
}) })
t.Run("want STARTTLS, but server does not support it", func(t *testing.T) { t.Run("want STARTTLS, but server does not support it", func(t *testing.T) {
ctxTLS, cancelTLS := context.WithCancel(context.Background()) ctxTLS, cancelTLS := context.WithCancel(ctx)
defer cancelTLS() defer cancelTLS()
PortAdder.Add(1) PortAdder.Add(1)
tlsServerPort := int(TestServerPortBase + PortAdder.Load()) tlsServerPort := int(TestServerPortBase + PortAdder.Load())
@ -1971,7 +1982,7 @@ func TestClient_DialWithContext(t *testing.T) {
} }
}) })
t.Run("connect with SSL", func(t *testing.T) { t.Run("connect with SSL", func(t *testing.T) {
ctxSSL, cancelSSL := context.WithCancel(context.Background()) ctxSSL, cancelSSL := context.WithCancel(ctx)
defer cancelSSL() defer cancelSSL()
PortAdder.Add(1) PortAdder.Add(1)
sslServerPort := int(TestServerPortBase + PortAdder.Load()) sslServerPort := int(TestServerPortBase + PortAdder.Load())
@ -2305,7 +2316,6 @@ func TestClient_auth(t *testing.T) {
if err := client.Close(); err != nil { if err := client.Close(); err != nil {
t.Errorf("failed to close client connection: %s", err) t.Errorf("failed to close client connection: %s", err)
} }
}) })
t.Run(tt.name+" should fail", func(t *testing.T) { t.Run(tt.name+" should fail", func(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
@ -2484,6 +2494,9 @@ func TestClient_Send(t *testing.T) {
t.Cleanup(cancelDial) t.Cleanup(cancelDial)
client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS)) client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS))
if err != nil {
t.Fatalf("failed to create new client: %s", err)
}
if err = client.DialWithContext(ctxDial); err != nil { if err = client.DialWithContext(ctxDial); err != nil {
t.Fatalf("failed to connect to test server: %s", err) t.Fatalf("failed to connect to test server: %s", err)
} }
@ -2498,6 +2511,9 @@ func TestClient_Send(t *testing.T) {
}) })
t.Run("send with no connection should fail", func(t *testing.T) { t.Run("send with no connection should fail", func(t *testing.T) {
client, err := NewClient(DefaultHost) client, err := NewClient(DefaultHost)
if err != nil {
t.Fatalf("failed to create new client: %s", err)
}
if err = client.Send(message); err == nil { if err = client.Send(message); err == nil {
t.Errorf("client should have failed to send email with no connection") t.Errorf("client should have failed to send email with no connection")
} }
@ -2530,6 +2546,9 @@ func TestClient_Send(t *testing.T) {
t.Cleanup(cancelDial) t.Cleanup(cancelDial)
client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS)) client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS))
if err != nil {
t.Fatalf("failed to create new client: %s", err)
}
if err = client.DialWithContext(ctxDial); err != nil { if err = client.DialWithContext(ctxDial); err != nil {
t.Fatalf("failed to connect to test server: %s", err) t.Fatalf("failed to connect to test server: %s", err)
} }
@ -2584,6 +2603,9 @@ func TestClient_sendSingleMsg(t *testing.T) {
t.Cleanup(cancelDial) t.Cleanup(cancelDial)
client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS)) client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS))
if err != nil {
t.Fatalf("failed to create new client: %s", err)
}
if err = client.DialWithContext(ctxDial); err != nil { if err = client.DialWithContext(ctxDial); err != nil {
t.Fatalf("failed to connect to test server: %s", err) t.Fatalf("failed to connect to test server: %s", err)
} }
@ -2620,6 +2642,9 @@ func TestClient_sendSingleMsg(t *testing.T) {
t.Cleanup(cancelDial) t.Cleanup(cancelDial)
client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS)) client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS))
if err != nil {
t.Fatalf("failed to create new client: %s", err)
}
if err = client.DialWithContext(ctxDial); err != nil { if err = client.DialWithContext(ctxDial); err != nil {
t.Fatalf("failed to connect to test server: %s", err) t.Fatalf("failed to connect to test server: %s", err)
} }
@ -2658,6 +2683,9 @@ func TestClient_sendSingleMsg(t *testing.T) {
t.Cleanup(cancelDial) t.Cleanup(cancelDial)
client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS)) client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS))
if err != nil {
t.Fatalf("failed to create new client: %s", err)
}
if err = client.DialWithContext(ctxDial); err != nil { if err = client.DialWithContext(ctxDial); err != nil {
t.Fatalf("failed to connect to test server: %s", err) t.Fatalf("failed to connect to test server: %s", err)
} }
@ -2701,6 +2729,9 @@ func TestClient_sendSingleMsg(t *testing.T) {
t.Cleanup(cancelDial) t.Cleanup(cancelDial)
client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS)) client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS))
if err != nil {
t.Fatalf("failed to create new client: %s", err)
}
if err = client.DialWithContext(ctxDial); err != nil { if err = client.DialWithContext(ctxDial); err != nil {
t.Fatalf("failed to connect to test server: %s", err) t.Fatalf("failed to connect to test server: %s", err)
} }
@ -2744,6 +2775,9 @@ func TestClient_sendSingleMsg(t *testing.T) {
t.Cleanup(cancelDial) t.Cleanup(cancelDial)
client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS)) client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS))
if err != nil {
t.Fatalf("failed to create new client: %s", err)
}
if err = client.DialWithContext(ctxDial); err != nil { if err = client.DialWithContext(ctxDial); err != nil {
t.Fatalf("failed to connect to test server: %s", err) t.Fatalf("failed to connect to test server: %s", err)
} }
@ -2787,6 +2821,9 @@ func TestClient_sendSingleMsg(t *testing.T) {
t.Cleanup(cancelDial) t.Cleanup(cancelDial)
client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS), WithDSN()) client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS), WithDSN())
if err != nil {
t.Fatalf("failed to create new client: %s", err)
}
if err = client.DialWithContext(ctxDial); err != nil { if err = client.DialWithContext(ctxDial); err != nil {
t.Fatalf("failed to connect to test server: %s", err) t.Fatalf("failed to connect to test server: %s", err)
} }
@ -2823,6 +2860,9 @@ func TestClient_sendSingleMsg(t *testing.T) {
t.Cleanup(cancelDial) t.Cleanup(cancelDial)
client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS)) client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS))
if err != nil {
t.Fatalf("failed to create new client: %s", err)
}
if err = client.DialWithContext(ctxDial); err != nil { if err = client.DialWithContext(ctxDial); err != nil {
t.Fatalf("failed to connect to test server: %s", err) t.Fatalf("failed to connect to test server: %s", err)
} }
@ -2867,6 +2907,9 @@ func TestClient_sendSingleMsg(t *testing.T) {
t.Cleanup(cancelDial) t.Cleanup(cancelDial)
client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS)) client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS))
if err != nil {
t.Fatalf("failed to create new client: %s", err)
}
if err = client.DialWithContext(ctxDial); err != nil { if err = client.DialWithContext(ctxDial); err != nil {
t.Fatalf("failed to connect to test server: %s", err) t.Fatalf("failed to connect to test server: %s", err)
} }
@ -2911,6 +2954,9 @@ func TestClient_sendSingleMsg(t *testing.T) {
t.Cleanup(cancelDial) t.Cleanup(cancelDial)
client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS)) client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS))
if err != nil {
t.Fatalf("failed to create new client: %s", err)
}
if err = client.DialWithContext(ctxDial); err != nil { if err = client.DialWithContext(ctxDial); err != nil {
t.Fatalf("failed to connect to test server: %s", err) t.Fatalf("failed to connect to test server: %s", err)
} }
@ -2954,6 +3000,9 @@ func TestClient_sendSingleMsg(t *testing.T) {
t.Cleanup(cancelDial) t.Cleanup(cancelDial)
client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS)) client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS))
if err != nil {
t.Fatalf("failed to create new client: %s", err)
}
if err = client.DialWithContext(ctxDial); err != nil { if err = client.DialWithContext(ctxDial); err != nil {
t.Fatalf("failed to connect to test server: %s", err) t.Fatalf("failed to connect to test server: %s", err)
} }
@ -2997,6 +3046,9 @@ func TestClient_sendSingleMsg(t *testing.T) {
t.Cleanup(cancelDial) t.Cleanup(cancelDial)
client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS)) client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS))
if err != nil {
t.Fatalf("failed to create new client: %s", err)
}
if err = client.DialWithContext(ctxDial); err != nil { if err = client.DialWithContext(ctxDial); err != nil {
t.Fatalf("failed to connect to test server: %s", err) t.Fatalf("failed to connect to test server: %s", err)
} }
@ -3040,6 +3092,9 @@ func TestClient_checkConn(t *testing.T) {
t.Cleanup(cancelDial) t.Cleanup(cancelDial)
client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS)) client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS))
if err != nil {
t.Fatalf("failed to create new client: %s", err)
}
if err = client.DialWithContext(ctxDial); err != nil { if err = client.DialWithContext(ctxDial); err != nil {
t.Fatalf("failed to connect to test server: %s", err) t.Fatalf("failed to connect to test server: %s", err)
} }
@ -3074,6 +3129,9 @@ func TestClient_checkConn(t *testing.T) {
t.Cleanup(cancelDial) t.Cleanup(cancelDial)
client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS)) client, err := NewClient(DefaultHost, WithPort(serverPort), WithTLSPolicy(NoTLS))
if err != nil {
t.Fatalf("failed to create new client: %s", err)
}
if err = client.DialWithContext(ctxDial); err != nil { if err = client.DialWithContext(ctxDial); err != nil {
t.Fatalf("failed to connect to test server: %s", err) t.Fatalf("failed to connect to test server: %s", err)
} }
@ -3091,6 +3149,9 @@ func TestClient_checkConn(t *testing.T) {
}) })
t.Run("connection should fail on no connection", func(t *testing.T) { t.Run("connection should fail on no connection", func(t *testing.T) {
client, err := NewClient(DefaultHost) client, err := NewClient(DefaultHost)
if err != nil {
t.Fatalf("failed to create new client: %s", err)
}
if err = client.checkConn(); err == nil { if err = client.checkConn(); err == nil {
t.Errorf("client should have failed on connection check") t.Errorf("client should have failed on connection check")
} }
@ -3419,11 +3480,14 @@ func simpleSMTPServer(ctx context.Context, t *testing.T, props *serverProps) err
if props.SSLListener { if props.SSLListener {
keypair, err := tls.X509KeyPair(localhostCert, localhostKey) keypair, err := tls.X509KeyPair(localhostCert, localhostKey)
if err != nil { if err != nil {
return fmt.Errorf("failed to read TLS keypair: %s", err) return fmt.Errorf("failed to read TLS keypair: %w", err)
} }
tlsConfig := &tls.Config{Certificates: []tls.Certificate{keypair}} tlsConfig := &tls.Config{Certificates: []tls.Certificate{keypair}}
listener, err = tls.Listen(TestServerProto, fmt.Sprintf("%s:%d", TestServerAddr, props.ListenPort), listener, err = tls.Listen(TestServerProto, fmt.Sprintf("%s:%d", TestServerAddr, props.ListenPort),
tlsConfig) tlsConfig)
if err != nil {
t.Fatalf("failed to create TLS listener: %s", err)
}
} else { } else {
listener, err = net.Listen(TestServerProto, fmt.Sprintf("%s:%d", TestServerAddr, props.ListenPort)) listener, err = net.Listen(TestServerProto, fmt.Sprintf("%s:%d", TestServerAddr, props.ListenPort))
} }
@ -3504,7 +3568,6 @@ func handleTestServerConnection(connection net.Conn, t *testing.T, props *server
break break
} }
writeLine("250-localhost.localdomain\r\n" + props.FeatureSet) writeLine("250-localhost.localdomain\r\n" + props.FeatureSet)
break
case strings.HasPrefix(data, "MAIL FROM:"): case strings.HasPrefix(data, "MAIL FROM:"):
if props.FailOnMailFrom { if props.FailOnMailFrom {
writeLine("500 5.5.2 Error: fail on MAIL FROM") writeLine("500 5.5.2 Error: fail on MAIL FROM")

View file

@ -901,7 +901,8 @@ func TestEMLToMsgFromReader(t *testing.T) {
}{ }{
{ {
"RFC5322 A1.1 example mail", exampleMailRFC5322A11, EncodingUSASCII, "RFC5322 A1.1 example mail", exampleMailRFC5322A11, EncodingUSASCII,
"Saying Hello"}, "Saying Hello",
},
{ {
"Plain text no encoding (7bit)", exampleMailPlain7Bit, EncodingUSASCII, "Plain text no encoding (7bit)", exampleMailPlain7Bit, EncodingUSASCII,
"Example mail // plain text without encoding", "Example mail // plain text without encoding",
@ -1158,7 +1159,6 @@ func TestEMLToMsgFromFile(t *testing.T) {
t.Errorf("failed to parse EML string: want subject %s, got %s", "Saying Hello", t.Errorf("failed to parse EML string: want subject %s, got %s", "Saying Hello",
gotSubject[0]) gotSubject[0])
} }
}) })
t.Run("EMLToMsgFromFile fails on file not found", func(t *testing.T) { t.Run("EMLToMsgFromFile fails on file not found", func(t *testing.T) {
if _, err := EMLToMsgFromFile("testdata/not-existing.eml"); err == nil { if _, err := EMLToMsgFromFile("testdata/not-existing.eml"); err == nil {

View file

@ -8,69 +8,13 @@ import (
"testing" "testing"
) )
// TestImportance_StringFuncs tests the different string method of the Importance object var (
func TestImportance_StringFuncs(t *testing.T) { genHeaderTests = []struct {
tests := []struct {
name string name string
imp Importance header Header
wantns string
xprio string
want string
}{
{"Importance: Non-Urgent", ImportanceNonUrgent, "0", "5", "non-urgent"},
{"Importance: Low", ImportanceLow, "0", "5", "low"},
{"Importance: Normal", ImportanceNormal, "", "", ""},
{"Importance: High", ImportanceHigh, "1", "1", "high"},
{"Importance: Urgent", ImportanceUrgent, "1", "1", "urgent"},
{"Importance: Unknown", 9, "", "", ""},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.imp.NumString() != tt.wantns {
t.Errorf("wrong number string for Importance returned. Expected: %s, got: %s",
tt.wantns, tt.imp.NumString())
}
if tt.imp.XPrioString() != tt.xprio {
t.Errorf("wrong x-prio string for Importance returned. Expected: %s, got: %s",
tt.xprio, tt.imp.XPrioString())
}
if tt.imp.String() != tt.want {
t.Errorf("wrong string for Importance returned. Expected: %s, got: %s",
tt.want, tt.imp.String())
}
})
}
}
// TestAddrHeader_String tests the string method of the AddrHeader object
func TestAddrHeader_String(t *testing.T) {
tests := []struct {
name string
ah AddrHeader
want string
}{
{"Address header: From", HeaderFrom, "From"},
{"Address header: To", HeaderTo, "To"},
{"Address header: Cc", HeaderCc, "Cc"},
{"Address header: Bcc", HeaderBcc, "Bcc"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.ah.String() != tt.want {
t.Errorf("wrong string for AddrHeader returned. Expected: %s, got: %s",
tt.want, tt.ah.String())
}
})
}
}
// TestHeader_String tests the string method of the Header object
func TestHeader_String(t *testing.T) {
tests := []struct {
name string
h Header
want string want string
}{ }{
{"Header: Content-Description", HeaderContentDescription, "Content-Description"},
{"Header: Content-Disposition", HeaderContentDisposition, "Content-Disposition"}, {"Header: Content-Disposition", HeaderContentDisposition, "Content-Disposition"},
{"Header: Content-ID", HeaderContentID, "Content-ID"}, {"Header: Content-ID", HeaderContentID, "Content-ID"},
{"Header: Content-Language", HeaderContentLang, "Content-Language"}, {"Header: Content-Language", HeaderContentLang, "Content-Language"},
@ -78,6 +22,10 @@ func TestHeader_String(t *testing.T) {
{"Header: Content-Transfer-Encoding", HeaderContentTransferEnc, "Content-Transfer-Encoding"}, {"Header: Content-Transfer-Encoding", HeaderContentTransferEnc, "Content-Transfer-Encoding"},
{"Header: Content-Type", HeaderContentType, "Content-Type"}, {"Header: Content-Type", HeaderContentType, "Content-Type"},
{"Header: Date", HeaderDate, "Date"}, {"Header: Date", HeaderDate, "Date"},
{
"Header: Disposition-Notification-To", HeaderDispositionNotificationTo,
"Disposition-Notification-To",
},
{"Header: Importance", HeaderImportance, "Importance"}, {"Header: Importance", HeaderImportance, "Importance"},
{"Header: In-Reply-To", HeaderInReplyTo, "In-Reply-To"}, {"Header: In-Reply-To", HeaderInReplyTo, "In-Reply-To"},
{"Header: List-Unsubscribe", HeaderListUnsubscribe, "List-Unsubscribe"}, {"Header: List-Unsubscribe", HeaderListUnsubscribe, "List-Unsubscribe"},
@ -87,19 +35,90 @@ func TestHeader_String(t *testing.T) {
{"Header: Organization", HeaderOrganization, "Organization"}, {"Header: Organization", HeaderOrganization, "Organization"},
{"Header: Precedence", HeaderPrecedence, "Precedence"}, {"Header: Precedence", HeaderPrecedence, "Precedence"},
{"Header: Priority", HeaderPriority, "Priority"}, {"Header: Priority", HeaderPriority, "Priority"},
{"Header: HeaderReferences", HeaderReferences, "References"}, {"Header: References", HeaderReferences, "References"},
{"Header: Reply-To", HeaderReplyTo, "Reply-To"}, {"Header: Reply-To", HeaderReplyTo, "Reply-To"},
{"Header: Subject", HeaderSubject, "Subject"}, {"Header: Subject", HeaderSubject, "Subject"},
{"Header: User-Agent", HeaderUserAgent, "User-Agent"}, {"Header: User-Agent", HeaderUserAgent, "User-Agent"},
{"Header: X-Auto-Response-Suppress", HeaderXAutoResponseSuppress, "X-Auto-Response-Suppress"},
{"Header: X-Mailer", HeaderXMailer, "X-Mailer"}, {"Header: X-Mailer", HeaderXMailer, "X-Mailer"},
{"Header: X-MSMail-Priority", HeaderXMSMailPriority, "X-MSMail-Priority"}, {"Header: X-MSMail-Priority", HeaderXMSMailPriority, "X-MSMail-Priority"},
{"Header: X-Priority", HeaderXPriority, "X-Priority"}, {"Header: X-Priority", HeaderXPriority, "X-Priority"},
} }
addrHeaderTests = []struct {
name string
header AddrHeader
want string
}{
{"From", HeaderFrom, "From"},
{"To", HeaderTo, "To"},
{"Cc", HeaderCc, "Cc"},
{"Bcc", HeaderBcc, "Bcc"},
}
)
func TestImportance_Stringer(t *testing.T) {
tests := []struct {
name string
imp Importance
wantnum string
xprio string
want string
}{
{"Non-Urgent", ImportanceNonUrgent, "0", "5", "non-urgent"},
{"Low", ImportanceLow, "0", "5", "low"},
{"Normal", ImportanceNormal, "", "", ""},
{"High", ImportanceHigh, "1", "1", "high"},
{"Urgent", ImportanceUrgent, "1", "1", "urgent"},
{"Unknown", 9, "", "", ""},
}
t.Run("String", func(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
if tt.h.String() != tt.want { if tt.imp.String() != tt.want {
t.Errorf("wrong string for Header returned. Expected: %s, got: %s", t.Errorf("wrong string for Importance returned. Expected: %s, got: %s", tt.want, tt.imp.String())
tt.want, tt.h.String()) }
})
}
})
t.Run("NumString", func(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.imp.NumString() != tt.wantnum {
t.Errorf("wrong number string for Importance returned. Expected: %s, got: %s", tt.wantnum,
tt.imp.NumString())
}
})
}
})
t.Run("XPrioString", func(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.imp.XPrioString() != tt.xprio {
t.Errorf("wrong x-prio string for Importance returned. Expected: %s, got: %s", tt.xprio,
tt.imp.XPrioString())
}
})
}
})
}
func TestAddrHeader_Stringer(t *testing.T) {
for _, tt := range addrHeaderTests {
t.Run(tt.name, func(t *testing.T) {
if tt.header.String() != tt.want {
t.Errorf("wrong string for AddrHeader returned. Expected: %s, got: %s",
tt.want, tt.header.String())
}
})
}
}
func TestHeader_Stringer(t *testing.T) {
for _, tt := range genHeaderTests {
t.Run(tt.name, func(t *testing.T) {
if tt.header.String() != tt.want {
t.Errorf("wrong string for Header returned. Expected: %s, got: %s",
tt.want, tt.header.String())
} }
}) })
} }

10
msg.go
View file

@ -583,6 +583,9 @@ func (m *Msg) SetAddrHeader(header AddrHeader, values ...string) error {
// References: // References:
// - https://datatracker.ietf.org/doc/html/rfc5322#section-3.4 // - https://datatracker.ietf.org/doc/html/rfc5322#section-3.4
func (m *Msg) SetAddrHeaderIgnoreInvalid(header AddrHeader, values ...string) { func (m *Msg) SetAddrHeaderIgnoreInvalid(header AddrHeader, values ...string) {
if m.addrHeader == nil {
m.addrHeader = make(map[AddrHeader][]*mail.Address)
}
var addresses []*mail.Address var addresses []*mail.Address
for _, addrVal := range values { for _, addrVal := range values {
address, err := mail.ParseAddress(m.encodeString(addrVal)) address, err := mail.ParseAddress(m.encodeString(addrVal))
@ -591,7 +594,14 @@ func (m *Msg) SetAddrHeaderIgnoreInvalid(header AddrHeader, values ...string) {
} }
addresses = append(addresses, address) addresses = append(addresses, address)
} }
switch header {
case HeaderFrom:
if len(addresses) > 0 {
m.addrHeader[header] = []*mail.Address{addresses[0]}
}
default:
m.addrHeader[header] = addresses m.addrHeader[header] = addresses
}
} }
// EnvelopeFrom sets the envelope from address for the Msg. // EnvelopeFrom sets the envelope from address for the Msg.

File diff suppressed because it is too large Load diff