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.

126 lines
3.8 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"
)
// TestUpdateAuthAndValidationBranches ensures update auth and validation branches behavior is handled correctly.
func TestUpdateAuthAndValidationBranches(t *testing.T) {
h := NewHandler(nil, validation.NewValidator(), nil, nil, true, 20, 100)
app := fiber.New()
app.Post("/leaderboard/update", h.Update)
req := httptest.NewRequest(http.MethodPost, "/leaderboard/update", bytes.NewReader([]byte(`{}`)))
res, err := app.Test(req)
if err != nil {
t.Fatalf("app.Test: %v", err)
}
defer res.Body.Close()
if res.StatusCode != http.StatusForbidden {
t.Fatalf("expected forbidden without auth claims, got %d", res.StatusCode)
}
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("/leaderboard/update", h.Update)
req = httptest.NewRequest(http.MethodPost, "/leaderboard/update", bytes.NewReader([]byte(`{}`)))
res, err = app.Test(req)
if err != nil {
t.Fatalf("app.Test: %v", err)
}
defer res.Body.Close()
if res.StatusCode != http.StatusForbidden {
t.Fatalf("expected forbidden for non-service/non-admin, got %d", res.StatusCode)
}
app = fiber.New()
app.Use(func(c fiber.Ctx) error {
c.Locals("user_id", "svc-1")
c.Locals("user_roles", []string{"service"})
return c.Next()
})
app.Post("/leaderboard/update", h.Update)
req = httptest.NewRequest(http.MethodPost, "/leaderboard/update", bytes.NewReader([]byte("{")))
req.Header.Set("Content-Type", "application/json")
res, err = app.Test(req)
if err != nil {
t.Fatalf("app.Test: %v", err)
}
defer res.Body.Close()
if res.StatusCode != http.StatusBadRequest {
t.Fatalf("expected bad request for malformed json, got %d", res.StatusCode)
}
validShape := `{
"session_id":"s1",
"player_id":"u1",
"player_name":"P",
"total_score":1,
"questions_asked":1,
"questions_correct":1,
"hints_used":0,
"duration_seconds":10,
"completed_at":"not-rfc3339",
"completion_type":"completed"
}`
req = httptest.NewRequest(http.MethodPost, "/leaderboard/update", bytes.NewReader([]byte(validShape)))
req.Header.Set("Content-Type", "application/json")
res, err = app.Test(req)
if err != nil {
t.Fatalf("app.Test: %v", err)
}
defer res.Body.Close()
if res.StatusCode != http.StatusBadRequest {
t.Fatalf("expected bad request for completed_at format, got %d", res.StatusCode)
}
}
// TestGetPlayerRankingForbiddenBranch ensures get player ranking forbidden branch behavior is handled correctly.
func TestGetPlayerRankingForbiddenBranch(t *testing.T) {
h := NewHandler(nil, validation.NewValidator(), nil, nil, false, 20, 100)
app := fiber.New()
app.Use(func(c fiber.Ctx) error {
c.Locals("user_id", "user-2")
c.Locals("user_roles", []string{"player"})
return c.Next()
})
app.Get("/leaderboard/players/:id", h.GetPlayerRanking)
req := httptest.NewRequest(http.MethodGet, "/leaderboard/players/user-1?page=oops&page_size=-1", nil)
res, err := app.Test(req)
if err != nil {
t.Fatalf("app.Test: %v", err)
}
defer res.Body.Close()
if res.StatusCode != http.StatusForbidden {
t.Fatalf("expected forbidden for non-owner non-admin, got %d", res.StatusCode)
}
}
// TestHelperFunctions ensures helper functions behavior is handled correctly.
func TestHelperFunctions(t *testing.T) {
if got := atoiWithDefault("", 3); got != 3 {
t.Fatalf("expected default for empty input")
}
if got := atoiWithDefault("bad", 4); got != 4 {
t.Fatalf("expected default for invalid input")
}
if got := atoiWithDefault("7", 4); got != 7 {
t.Fatalf("expected parsed int")
}
}