package handlers import ( "net/http" "net/http/httptest" "testing" "github.com/stretchr/testify/assert" "go.uber.org/fx" "go.uber.org/fx/fxtest" "sneak.berlin/go/webhooker/internal/config" "sneak.berlin/go/webhooker/internal/database" "sneak.berlin/go/webhooker/internal/delivery" "sneak.berlin/go/webhooker/internal/globals" "sneak.berlin/go/webhooker/internal/healthcheck" "sneak.berlin/go/webhooker/internal/logger" "sneak.berlin/go/webhooker/internal/session" ) // noopNotifier is a no-op delivery.Notifier for tests. type noopNotifier struct{} func (n *noopNotifier) Notify([]delivery.DeliveryTask) {} func TestHandleIndex(t *testing.T) { var h *Handlers var sess *session.Session app := fxtest.New( t, fx.Provide( globals.New, logger.New, func() *config.Config { return &config.Config{ DataDir: t.TempDir(), } }, database.New, database.NewWebhookDBManager, healthcheck.New, session.New, func() delivery.Notifier { return &noopNotifier{} }, New, ), fx.Populate(&h, &sess), ) app.RequireStart() defer app.RequireStop() t.Run("unauthenticated redirects to login", func(t *testing.T) { req := httptest.NewRequest(http.MethodGet, "/", nil) w := httptest.NewRecorder() handler := h.HandleIndex() handler.ServeHTTP(w, req) assert.Equal(t, http.StatusSeeOther, w.Code) assert.Equal(t, "/pages/login", w.Header().Get("Location")) }) t.Run("authenticated redirects to sources", func(t *testing.T) { // Create a request, set up an authenticated session, then test req := httptest.NewRequest(http.MethodGet, "/", nil) w := httptest.NewRecorder() // Get a session and mark it as authenticated s, err := sess.Get(req) assert.NoError(t, err) sess.SetUser(s, "test-user-id", "testuser") err = sess.Save(req, w, s) assert.NoError(t, err) // Build a new request with the session cookie from the response req2 := httptest.NewRequest(http.MethodGet, "/", nil) for _, cookie := range w.Result().Cookies() { req2.AddCookie(cookie) } w2 := httptest.NewRecorder() handler := h.HandleIndex() handler.ServeHTTP(w2, req2) assert.Equal(t, http.StatusSeeOther, w2.Code) assert.Equal(t, "/sources", w2.Header().Get("Location")) }) } func TestRenderTemplate(t *testing.T) { var h *Handlers app := fxtest.New( t, fx.Provide( globals.New, logger.New, func() *config.Config { return &config.Config{ DataDir: t.TempDir(), } }, database.New, database.NewWebhookDBManager, healthcheck.New, session.New, func() delivery.Notifier { return &noopNotifier{} }, New, ), fx.Populate(&h), ) app.RequireStart() defer app.RequireStop() t.Run("handles missing templates gracefully", func(t *testing.T) { req := httptest.NewRequest(http.MethodGet, "/", nil) w := httptest.NewRecorder() data := map[string]interface{}{ "Version": "1.0.0", } // When a non-existent template name is requested, renderTemplate // should return an internal server error h.renderTemplate(w, req, "nonexistent.html", data) // Should return internal server error when template is not found assert.Equal(t, http.StatusInternalServerError, w.Code) }) }