package logger_test import ( "bytes" "encoding/json" "errors" "log/slog" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/fx" "go.uber.org/fx/fxevent" "go.uber.org/fx/fxtest" "sneak.berlin/go/webhooker/internal/globals" "sneak.berlin/go/webhooker/internal/logger" ) var errStopHook = errors.New("stop hook failed on purpose") func testGlobals() *globals.Globals { return &globals.Globals{ Appname: "test-app", Version: "1.0.0", } } func TestNew(t *testing.T) { t.Parallel() lc := fxtest.NewLifecycle(t) params := logger.LoggerParams{ Globals: testGlobals(), } l, err := logger.New(lc, params) if err != nil { t.Fatalf("New() error = %v", err) } if l.Get() == nil { t.Error("Get() returned nil logger") } // Test that we can log without panic l.Get().Info("test message", "key", "value") } func TestEnableDebugLogging(t *testing.T) { t.Parallel() lc := fxtest.NewLifecycle(t) params := logger.LoggerParams{ Globals: testGlobals(), } l, err := logger.New(lc, params) if err != nil { t.Fatalf("New() error = %v", err) } // Enable debug logging should not panic l.EnableDebugLogging() // Test debug logging l.Get().Debug("debug message", "test", true) } // TestFxLogger_Levels starts and stops an fx app that reports its own // events through NewFxLogger, as cmd/webhooker does, and reads back // what reached the handler: the graph at DEBUG, the start at INFO and // a failed stop hook at ERROR, each as a structured record. func TestFxLogger_Levels(t *testing.T) { t.Parallel() var out bytes.Buffer log := slog.New(slog.NewJSONHandler( &out, &slog.HandlerOptions{Level: slog.LevelDebug}, )) app := fx.New( fx.WithLogger(func() fxevent.Logger { return logger.NewFxLogger(log) }), fx.Invoke(func(lc fx.Lifecycle) { lc.Append(fx.StopHook(func() error { return errStopHook })) }), ) require.NoError(t, app.Start(t.Context())) require.ErrorIs(t, app.Stop(t.Context()), errStopHook) levels := map[string]string{} decoder := json.NewDecoder(&out) for decoder.More() { var record struct { Level string `json:"level"` Msg string `json:"msg"` } require.NoError(t, decoder.Decode(&record)) levels[record.Msg] = record.Level } assert.Equal(t, "DEBUG", levels["provided"]) assert.Equal(t, "INFO", levels["started"]) assert.Equal(t, "ERROR", levels["OnStop hook failed"]) }