8d2cd97e17
New adminalert worker polls for feedback + word complaints arriving since the last check and coalesces a burst into one digest email per interval (5 min), inert unless a distinct admin sender (BACKEND_SMTP_ADMIN_FROM) and recipient (BACKEND_ADMIN_EMAIL, comma-separated allowed) are configured. The mailer gains a per-message From override and splits a comma-separated To into separate recipients (go-mail needs them as a list). Feedback/game stores gain CountSince/CountComplaintsSince. Unit tests cover the digest, the skip-when- empty, and the recipient split.
56 lines
1.7 KiB
Go
56 lines
1.7 KiB
Go
package adminalert
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"scrabble/backend/internal/account"
|
|
)
|
|
|
|
// The fakes ignore the watermark and return a fixed count, which is all the digest logic
|
|
// needs.
|
|
type fbCounter struct{ n int }
|
|
|
|
func (f fbCounter) CountSince(context.Context, time.Time) (int, error) { return f.n, nil }
|
|
|
|
type cpCounter struct{ n int }
|
|
|
|
func (c cpCounter) CountComplaintsSince(context.Context, time.Time) (int, error) { return c.n, nil }
|
|
|
|
type recordingMailer struct{ sent []account.Message }
|
|
|
|
func (m *recordingMailer) Send(_ context.Context, msg account.Message) error {
|
|
m.sent = append(m.sent, msg)
|
|
return nil
|
|
}
|
|
|
|
func TestNotifierSkipsWhenNothingNew(t *testing.T) {
|
|
mailer := &recordingMailer{}
|
|
n := New(mailer, fbCounter{0}, cpCounter{0}, "alerts@erudit-game.ru", "op@x.ru", "", nil)
|
|
n.tick(context.Background())
|
|
if len(mailer.sent) != 0 {
|
|
t.Fatalf("sent %d emails, want 0 when nothing is new", len(mailer.sent))
|
|
}
|
|
}
|
|
|
|
func TestNotifierDigestsNewItems(t *testing.T) {
|
|
mailer := &recordingMailer{}
|
|
n := New(mailer, fbCounter{2}, cpCounter{1}, "alerts@erudit-game.ru", "op@x.ru, two@x.ru", "https://erudit-game.ru/_gm", nil)
|
|
n.tick(context.Background())
|
|
if len(mailer.sent) != 1 {
|
|
t.Fatalf("sent %d emails, want 1 digest", len(mailer.sent))
|
|
}
|
|
msg := mailer.sent[0]
|
|
if msg.From != "alerts@erudit-game.ru" || msg.To != "op@x.ru, two@x.ru" {
|
|
t.Errorf("digest addressing = From %q To %q", msg.From, msg.To)
|
|
}
|
|
if !strings.Contains(msg.Subject, "2 new feedback") || !strings.Contains(msg.Subject, "1 new word complaint") {
|
|
t.Errorf("digest subject = %q, want the feedback + complaint counts", msg.Subject)
|
|
}
|
|
if !strings.Contains(msg.Text, "/_gm") {
|
|
t.Errorf("digest body = %q, want the console link", msg.Text)
|
|
}
|
|
}
|