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.6 KiB
Go
126 lines
3.6 KiB
Go
package http
|
|
|
|
// handler_unit_test.go contains tests for backend behavior.
|
|
|
|
import (
|
|
"bytes"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/gofiber/fiber/v3"
|
|
|
|
"knowfoolery/backend/shared/infra/utils/validation"
|
|
)
|
|
|
|
// TestUpdateAuthAndValidationBranches verifies expected behavior.
|
|
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 verifies expected behavior.
|
|
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 verifies expected behavior.
|
|
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")
|
|
}
|
|
}
|