- Added rate limiting for outbound email sends to prevent abuse, implemented in `internal/api/mail/sendguard`. - Introduced idempotency key support for email sending to avoid duplicate submissions. - Enhanced attachment handling with new limits and validation in `internal/api/mail/limits`. - Updated outbox processing to include retry logic and circuit breaker for SMTP failures. - Improved HTML sanitization for email content to enhance security. - Added unit tests for new features, ensuring robust functionality and error handling. - Updated configuration options in `.env.example` for new mail settings.
43 lines
1004 B
Go
43 lines
1004 B
Go
package smtp
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestCircuitBreaker_opensAfterThreshold(t *testing.T) {
|
|
cb := NewCircuitBreaker(3, time.Minute)
|
|
account := "acc-1"
|
|
|
|
for i := 0; i < 3; i++ {
|
|
if err := cb.Allow(account); err != nil {
|
|
t.Fatalf("allow %d: %v", i, err)
|
|
}
|
|
cb.RecordFailure(account)
|
|
}
|
|
if err := cb.Allow(account); !errors.Is(err, ErrCircuitOpen) {
|
|
t.Fatalf("allow after failures = %v, want %v", err, ErrCircuitOpen)
|
|
}
|
|
}
|
|
|
|
func TestCircuitBreaker_recoversAfterCooldown(t *testing.T) {
|
|
cb := NewCircuitBreaker(1, 10*time.Millisecond)
|
|
account := "acc-2"
|
|
|
|
_ = cb.Allow(account)
|
|
cb.RecordFailure(account)
|
|
if err := cb.Allow(account); !errors.Is(err, ErrCircuitOpen) {
|
|
t.Fatalf("expected open circuit: %v", err)
|
|
}
|
|
|
|
time.Sleep(15 * time.Millisecond)
|
|
if err := cb.Allow(account); err != nil {
|
|
t.Fatalf("expected half-open allow: %v", err)
|
|
}
|
|
cb.RecordSuccess(account)
|
|
if err := cb.Allow(account); err != nil {
|
|
t.Fatalf("expected closed circuit: %v", err)
|
|
}
|
|
}
|