package http // handler_unit_test.go contains backend tests for package behavior, error paths, and regressions. import ( "bytes" "net/http" "net/http/httptest" "testing" "github.com/gofiber/fiber/v3" "knowfoolery/backend/shared/infra/utils/validation" ) // TestUnauthorizedBranches ensures unauthorized branches behavior is handled correctly. func TestUnauthorizedBranches(t *testing.T) { h := NewHandler(nil, validation.NewValidator(), nil, nil) app := fiber.New() app.Post("/sessions/start", h.StartSession) app.Post("/sessions/end", h.EndSession) app.Post("/sessions/:id/hint", h.RequestHint) app.Get("/sessions/:id", h.GetSession) app.Get("/sessions/:id/question", h.GetCurrentQuestion) cases := []struct { method string path string }{ {http.MethodPost, "/sessions/start"}, {http.MethodPost, "/sessions/end"}, {http.MethodPost, "/sessions/s1/hint"}, {http.MethodGet, "/sessions/s1"}, {http.MethodGet, "/sessions/s1/question"}, } for _, tc := range cases { req := httptest.NewRequest(tc.method, tc.path, nil) res, err := app.Test(req) if err != nil { t.Fatalf("app.Test(%s %s): %v", tc.method, tc.path, err) } if res.StatusCode != http.StatusUnauthorized { _ = res.Body.Close() t.Fatalf("expected unauthorized for %s %s, got %d", tc.method, tc.path, res.StatusCode) } _ = res.Body.Close() } } // TestStartAndEndValidationBranches ensures start and end validation branches behavior is handled correctly. func TestStartAndEndValidationBranches(t *testing.T) { h := NewHandler(nil, validation.NewValidator(), nil, nil) app := fiber.New() app.Use(func(c fiber.Ctx) error { c.Locals("user_id", "user-1") c.Locals("user_roles", []string{"player"}) return c.Next() }) app.Post("/sessions/start", h.StartSession) app.Post("/sessions/end", h.EndSession) app.Post("/sessions/:id/answer", h.SubmitAnswer) req := httptest.NewRequest(http.MethodPost, "/sessions/start", bytes.NewReader([]byte("{"))) req.Header.Set("Content-Type", "application/json") res, err := app.Test(req) if err != nil { t.Fatalf("app.Test start malformed: %v", err) } defer res.Body.Close() if res.StatusCode != http.StatusBadRequest { t.Fatalf("expected bad request for malformed start body, got %d", res.StatusCode) } req = httptest.NewRequest(http.MethodPost, "/sessions/start", bytes.NewReader([]byte(`{"preferred_theme":"a"}`))) req.Header.Set("Content-Type", "application/json") res, err = app.Test(req) if err != nil { t.Fatalf("app.Test start validation: %v", err) } defer res.Body.Close() if res.StatusCode != http.StatusBadRequest { t.Fatalf("expected bad request for start validation, got %d", res.StatusCode) } req = httptest.NewRequest(http.MethodPost, "/sessions/end", bytes.NewReader([]byte("{"))) req.Header.Set("Content-Type", "application/json") res, err = app.Test(req) if err != nil { t.Fatalf("app.Test end malformed: %v", err) } defer res.Body.Close() if res.StatusCode != http.StatusBadRequest { t.Fatalf("expected bad request for malformed end body, got %d", res.StatusCode) } req = httptest.NewRequest(http.MethodPost, "/sessions/end", bytes.NewReader([]byte(`{"session_id":""}`))) req.Header.Set("Content-Type", "application/json") res, err = app.Test(req) if err != nil { t.Fatalf("app.Test end validation: %v", err) } defer res.Body.Close() if res.StatusCode != http.StatusBadRequest { t.Fatalf("expected bad request for end validation, got %d", res.StatusCode) } } // TestBearerTokenAndClaimsHelpers ensures bearer token and claims helpers behavior is handled correctly. func TestBearerTokenAndClaimsHelpers(t *testing.T) { app := fiber.New() app.Use(func(c fiber.Ctx) error { c.Locals("user_id", "admin-1") c.Locals("user_roles", []string{"admin"}) return c.Next() }) app.Get("/token", func(c fiber.Ctx) error { if got := bearerToken(c); got != "abc" { return c.SendStatus(http.StatusInternalServerError) } claims := authClaimsFromContext(c) if !claims.IsAdmin || claims.UserID != "admin-1" { return c.SendStatus(http.StatusInternalServerError) } return c.SendStatus(http.StatusOK) }) req := httptest.NewRequest(http.MethodGet, "/token", nil) req.Header.Set("Authorization", "Bearer abc") res, err := app.Test(req) if err != nil { t.Fatalf("app.Test helper route: %v", err) } defer res.Body.Close() if res.StatusCode != http.StatusOK { t.Fatalf("expected helper route success, got %d", res.StatusCode) } }