claude-failover/internal/notify/notifier_test.go
Ubuntu 46c49d0f2f feat(notify): Phase 2.5 — Notifier Telegram + Resend email
- internal/notify: Telegram (POST /sendMessage) et Resend email (POST /emails)
- Credentials lus depuis env vars (telegramBaseURL/resendBaseURL overridables en test)
- No-op gracieux quand token/key absents
- 5 tests unitaires avec httptest.Server

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 20:28:46 +00:00

123 lines
3.4 KiB
Go

package notify
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"forge.secuaas.ovh/olivier/claude-failover/internal/config"
)
// TestTelegramNoop verifies that an unconfigured notifier is a safe no-op.
func TestTelegramNoop(t *testing.T) {
n := &Notifier{}
if err := n.Telegram("hello"); err != nil {
t.Errorf("expected nil error for empty token, got %v", err)
}
}
// TestEmailNoop verifies that an unconfigured notifier is a safe no-op.
func TestEmailNoop(t *testing.T) {
n := &Notifier{}
if err := n.Email("subject", "<p>body</p>"); err != nil {
t.Errorf("expected nil error for empty API key, got %v", err)
}
}
// TestNewFromConfig verifies that New reads credentials from env vars.
func TestNewFromConfig(t *testing.T) {
t.Setenv("TEST_TG_TOKEN", "my-token")
t.Setenv("TEST_TG_CHAT", "9999")
t.Setenv("TEST_EMAIL", "ops@example.com")
cfg := &config.Config{
Notifications: config.NotificationsConfig{
TelegramTokenEnv: "TEST_TG_TOKEN",
TelegramChatIDEnv: "TEST_TG_CHAT",
NotifyEmailEnv: "TEST_EMAIL",
},
}
n := New(cfg)
if n.telegramToken != "my-token" {
t.Errorf("expected token my-token, got %q", n.telegramToken)
}
if n.telegramChatID != "9999" {
t.Errorf("expected chatID 9999, got %q", n.telegramChatID)
}
if n.notifyEmail != "ops@example.com" {
t.Errorf("expected email ops@example.com, got %q", n.notifyEmail)
}
}
// TestTelegramHTTP verifies the actual HTTP body sent to Telegram.
func TestTelegramHTTP(t *testing.T) {
var gotBody map[string]string
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
json.NewDecoder(r.Body).Decode(&gotBody)
w.WriteHeader(200)
w.Write([]byte(`{"ok":true}`))
}))
defer srv.Close()
n := &Notifier{
telegramToken: "tok",
telegramChatID: "42",
httpClient: srv.Client(),
telegramBaseURL: srv.URL,
}
if err := n.Telegram("test message"); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if gotBody["text"] != "test message" {
t.Errorf("expected text 'test message', got %q", gotBody["text"])
}
if gotBody["chat_id"] != "42" {
t.Errorf("expected chat_id 42, got %q", gotBody["chat_id"])
}
}
// TestEmailHTTP verifies the HTTP body sent to Resend.
func TestEmailHTTP(t *testing.T) {
var gotBody map[string]interface{}
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
json.NewDecoder(r.Body).Decode(&gotBody)
if r.Header.Get("Authorization") != "Bearer test-key" {
t.Errorf("unexpected Authorization header: %q", r.Header.Get("Authorization"))
}
w.WriteHeader(201)
w.Write([]byte(`{"id":"msg-123"}`))
}))
defer srv.Close()
n := &Notifier{
resendAPIKey: "test-key",
notifyEmail: "user@example.com",
httpClient: srv.Client(),
resendBaseURL: srv.URL,
}
if err := n.Email("Alert", "<p>something happened</p>"); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if gotBody["subject"] != "Alert" {
t.Errorf("expected subject Alert, got %v", gotBody["subject"])
}
}
// TestTelegramHTTPError propagates non-2xx status as error.
func TestTelegramHTTPError(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(429)
}))
defer srv.Close()
n := &Notifier{
telegramToken: "tok",
telegramChatID: "1",
httpClient: srv.Client(),
telegramBaseURL: srv.URL,
}
if err := n.Telegram("msg"); err == nil {
t.Error("expected error on HTTP 429, got nil")
}
}