package notify import ( "encoding/json" "io" "log/slog" "net/http" "net/http/httptest" "os" "testing" ) func TestWebhookNotifier_Success(t *testing.T) { var received Event server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { body, _ := io.ReadAll(r.Body) json.Unmarshal(body, &received) w.WriteHeader(http.StatusOK) })) defer server.Close() logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})) notifier := NewWebhookNotifier(server.URL, logger) event := Event{ TaskID: "t-1", TaskName: "Test", Status: "COMPLETED", CostUSD: 0.50, Duration: "2m30s", } if err := notifier.Notify(event); err != nil { t.Fatalf("unexpected error: %v", err) } if received.TaskID != "t-1" { t.Errorf("task_id: want 't-1', got %q", received.TaskID) } if received.CostUSD != 0.50 { t.Errorf("cost: want 0.50, got %f", received.CostUSD) } } func TestWebhookNotifier_ServerError(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) })) defer server.Close() logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})) notifier := NewWebhookNotifier(server.URL, logger) err := notifier.Notify(Event{TaskID: "t-1", Status: "COMPLETED"}) if err == nil { t.Fatal("expected error for 500 response") } } func TestMultiNotifier_FansOut(t *testing.T) { var count int counter := &countingNotifier{count: &count} logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})) multi := NewMultiNotifier(logger, counter, counter, counter) multi.Notify(Event{TaskID: "t-1"}) if count != 3 { t.Errorf("want 3 notifications, got %d", count) } } func TestLogNotifier_NoError(t *testing.T) { logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})) notifier := &LogNotifier{Logger: logger} if err := notifier.Notify(Event{TaskID: "t-1", Status: "COMPLETED"}); err != nil { t.Errorf("unexpected error: %v", err) } } type countingNotifier struct { count *int } func (c *countingNotifier) Notify(_ Event) error { *c.count++ return nil }