mirror of https://github.com/usememos/memos.git
140 lines
2.9 KiB
Go
140 lines
2.9 KiB
Go
package email
|
|
|
|
import (
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestSend(t *testing.T) {
|
|
config := &Config{
|
|
SMTPHost: "smtp.example.com",
|
|
SMTPPort: 587,
|
|
FromEmail: "test@example.com",
|
|
}
|
|
|
|
message := &Message{
|
|
To: []string{"recipient@example.com"},
|
|
Subject: "Test",
|
|
Body: "Test body",
|
|
}
|
|
|
|
// This will fail to connect (no real server), but should validate inputs
|
|
err := Send(config, message)
|
|
// We expect an error because there's no real SMTP server
|
|
// But it should be a connection error, not a validation error
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "dial")
|
|
}
|
|
|
|
func TestSendValidation(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
config *Config
|
|
message *Message
|
|
wantErr bool
|
|
errMsg string
|
|
}{
|
|
{
|
|
name: "nil config",
|
|
config: nil,
|
|
message: &Message{To: []string{"test@example.com"}, Subject: "Test", Body: "Test"},
|
|
wantErr: true,
|
|
errMsg: "configuration is required",
|
|
},
|
|
{
|
|
name: "nil message",
|
|
config: &Config{SMTPHost: "smtp.example.com", SMTPPort: 587, FromEmail: "from@example.com"},
|
|
message: nil,
|
|
wantErr: true,
|
|
errMsg: "message is required",
|
|
},
|
|
{
|
|
name: "invalid config",
|
|
config: &Config{
|
|
SMTPHost: "",
|
|
SMTPPort: 587,
|
|
},
|
|
message: &Message{To: []string{"test@example.com"}, Subject: "Test", Body: "Test"},
|
|
wantErr: true,
|
|
errMsg: "invalid email configuration",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
err := Send(tt.config, tt.message)
|
|
if tt.wantErr {
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), tt.errMsg)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSendAsync(t *testing.T) {
|
|
config := &Config{
|
|
SMTPHost: "smtp.example.com",
|
|
SMTPPort: 587,
|
|
FromEmail: "test@example.com",
|
|
}
|
|
|
|
message := &Message{
|
|
To: []string{"recipient@example.com"},
|
|
Subject: "Test Async",
|
|
Body: "Test async body",
|
|
}
|
|
|
|
// SendAsync should not block
|
|
start := time.Now()
|
|
SendAsync(config, message)
|
|
duration := time.Since(start)
|
|
|
|
// Should return almost immediately (< 100ms)
|
|
assert.Less(t, duration, 100*time.Millisecond)
|
|
|
|
// Give goroutine time to start
|
|
time.Sleep(50 * time.Millisecond)
|
|
}
|
|
|
|
func TestSendAsyncConcurrent(t *testing.T) {
|
|
config := &Config{
|
|
SMTPHost: "smtp.example.com",
|
|
SMTPPort: 587,
|
|
FromEmail: "test@example.com",
|
|
}
|
|
|
|
// Send multiple emails concurrently
|
|
var wg sync.WaitGroup
|
|
count := 5
|
|
|
|
for i := 0; i < count; i++ {
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
message := &Message{
|
|
To: []string{"recipient@example.com"},
|
|
Subject: "Concurrent Test",
|
|
Body: "Test body",
|
|
}
|
|
SendAsync(config, message)
|
|
}()
|
|
}
|
|
|
|
// Should complete without deadlock
|
|
done := make(chan bool)
|
|
go func() {
|
|
wg.Wait()
|
|
done <- true
|
|
}()
|
|
|
|
select {
|
|
case <-done:
|
|
// Success
|
|
case <-time.After(1 * time.Second):
|
|
t.Fatal("SendAsync calls did not complete in time")
|
|
}
|
|
}
|