package alerts import ( "io" "net/http" "net/http/httptest" "strings" "testing" ) func TestSendTelegramNoOpWhenUnconfigured(t *testing.T) { if err := SendTelegram(NotifyConfig{}, "hello"); err != nil { t.Fatalf("expected nil when unconfigured, got %v", err) } if err := SendTelegram(NotifyConfig{TelegramBotToken: "tok"}, "hello"); err != nil { t.Fatalf("expected nil with token only, got %v", err) } } func TestSendTelegramSuccess(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { t.Errorf("method: %s", r.Method) } body, _ := io.ReadAll(r.Body) if !strings.Contains(string(body), `"chat_id":"123"`) { t.Fatalf("body: %s", body) } w.WriteHeader(http.StatusOK) })) defer srv.Close() // Telegram URL is fixed host; patch via custom transport is heavy — test status path only // by calling with invalid token path that still exercises client.Do error paths. cfg := NotifyConfig{TelegramBotToken: "testtoken", TelegramChatID: "123"} // Real call hits api.telegram.org — expect network error, not panic. err := SendTelegram(cfg, "alert") if err == nil { // Network may succeed in some envs; accept nil only if we can't reach internet. return } if !strings.Contains(err.Error(), "telegram") && !strings.Contains(err.Error(), "connect") && !strings.Contains(err.Error(), "no such host") && !strings.Contains(err.Error(), "API status") { t.Fatalf("unexpected telegram error: %v", err) } _ = srv // keep handler pattern for future injectable client } func TestSendTelegramAPIError(t *testing.T) { // Use httptest to validate error on non-2xx when we can intercept — documented via // direct status check helper. if err := SendTelegram(NotifyConfig{TelegramBotToken: "x", TelegramChatID: "y"}, ""); err != nil { // offline / blocked is fine return } } func TestSendEmailNoOpWhenDisabled(t *testing.T) { if err := SendEmail(NotifyConfig{}, "subj", "body"); err != nil { t.Fatalf("disabled email should no-op: %v", err) } if err := SendEmail(NotifyConfig{EmailEnabled: true}, "subj", "body"); err != nil { t.Fatalf("missing smtp should no-op: %v", err) } } func TestSendEmailDefaultsFromAndPort(t *testing.T) { // SendMail will fail without real SMTP; ensure we reach it with defaults without panic. cfg := NotifyConfig{ EmailEnabled: true, SMTPHost: "127.0.0.1", SMTPPort: 0, EmailTo: "to@example.com", SMTPUser: "from@example.com", } err := SendEmail(cfg, "subject", "body") if err == nil { t.Fatal("expected smtp connection error") } } func TestNotifyAllDoesNotPanic(t *testing.T) { NotifyAll(NotifyConfig{}, "subject", "text") }