TestSMTPEnvelopeAndHeaders verifies that SMTP envelope addresses (used in MAIL FROM and RCPT TO commands) contain only bare email addresses, while email headers preserve the full address including display names. This is important because RFC 5321 requires envelope addresses to be bare emails, while
(t *testing.T)
| 525 | // |
| 526 | // See: https://github.com/coder/coder/issues/20727 |
| 527 | func TestSMTPEnvelopeAndHeaders(t *testing.T) { |
| 528 | t.Parallel() |
| 529 | |
| 530 | const ( |
| 531 | hello = "localhost" |
| 532 | to = "bob@bob.com" |
| 533 | |
| 534 | subject = "This is the subject" |
| 535 | body = "This is the body" |
| 536 | ) |
| 537 | |
| 538 | tests := []struct { |
| 539 | name string |
| 540 | fromConfig string // The configured From address (may include display name) |
| 541 | expectedEnvFrom string // Expected envelope MAIL FROM (bare email) |
| 542 | expectedHeaderFrom string // Expected From header (preserves display name) |
| 543 | }{ |
| 544 | { |
| 545 | name: "bare email address", |
| 546 | fromConfig: "system@coder.com", |
| 547 | expectedEnvFrom: "system@coder.com", |
| 548 | expectedHeaderFrom: "system@coder.com", |
| 549 | }, |
| 550 | { |
| 551 | name: "email with display name", |
| 552 | fromConfig: "Coder System <system@coder.com>", |
| 553 | expectedEnvFrom: "system@coder.com", |
| 554 | expectedHeaderFrom: "Coder System <system@coder.com>", |
| 555 | }, |
| 556 | { |
| 557 | name: "email with quoted display name", |
| 558 | fromConfig: `"Coder Notifications" <notifications@coder.com>`, |
| 559 | expectedEnvFrom: "notifications@coder.com", |
| 560 | expectedHeaderFrom: `"Coder Notifications" <notifications@coder.com>`, |
| 561 | }, |
| 562 | } |
| 563 | |
| 564 | for _, tc := range tests { |
| 565 | t.Run(tc.name, func(t *testing.T) { |
| 566 | t.Parallel() |
| 567 | |
| 568 | ctx := testutil.Context(t, testutil.WaitShort) |
| 569 | logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Leveled(slog.LevelDebug) |
| 570 | |
| 571 | cfg := codersdk.NotificationsEmailConfig{ |
| 572 | Hello: serpent.String(hello), |
| 573 | From: serpent.String(tc.fromConfig), |
| 574 | } |
| 575 | |
| 576 | backend := smtptest.NewBackend(smtptest.Config{ |
| 577 | AuthMechanisms: []string{}, |
| 578 | }) |
| 579 | |
| 580 | srv, listen, err := smtptest.CreateMockSMTPServer(backend, false) |
| 581 | require.NoError(t, err) |
| 582 | t.Cleanup(func() { |
| 583 | assert.ErrorIs(t, srv.Shutdown(ctx), smtp.ErrServerClosed) |
| 584 | }) |
nothing calls this directly
no test coverage detected