You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
4.4 KiB
Go
140 lines
4.4 KiB
Go
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)
|
|
}
|
|
}
|