package httputil // Tests for HTTP query pagination, sorting, and filtering extraction. import ( "encoding/json" "net/http" "net/http/httptest" "testing" "github.com/gofiber/fiber/v3" "github.com/stretchr/testify/require" "knowfoolery/backend/shared/domain/types" ) // TestPaginationFromQuery verifies defaulting and bounds from query parameters. func TestPaginationFromQuery(t *testing.T) { app := fiber.New() app.Get("/", func(c fiber.Ctx) error { pagination := PaginationFromQuery(c) return c.JSON(pagination) }) req := httptest.NewRequest(http.MethodGet, "/?page=0&page_size=500", nil) resp, err := app.Test(req) require.NoError(t, err) defer resp.Body.Close() var p types.Pagination require.NoError(t, json.NewDecoder(resp.Body).Decode(&p)) require.Equal(t, 1, p.Page) require.Equal(t, types.MaxPageSize, p.PageSize) } // TestSortingFromQuery verifies allowed field enforcement and direction normalization. func TestSortingFromQuery(t *testing.T) { app := fiber.New() app.Get("/", func(c fiber.Ctx) error { sorting := SortingFromQuery(c, "name", []string{"name", "created"}) return c.JSON(sorting) }) req := httptest.NewRequest(http.MethodGet, "/?sort=invalid&direction=down", nil) resp, err := app.Test(req) require.NoError(t, err) defer resp.Body.Close() var s SortingParams require.NoError(t, json.NewDecoder(resp.Body).Decode(&s)) require.Equal(t, "name", s.Field) require.Equal(t, "asc", s.Direction) } // TestFiltersFromQueryAndCustom verifies base filters and custom filter extraction. func TestFiltersFromQueryAndCustom(t *testing.T) { app := fiber.New() app.Get("/", func(c fiber.Ctx) error { filters := FiltersFromQuery(c) filters.WithCustomFilter(c, "theme") return c.JSON(filters) }) req := httptest.NewRequest(http.MethodGet, "/?search=hi&status=active&theme=scifi", nil) resp, err := app.Test(req) require.NoError(t, err) defer resp.Body.Close() var f FilterParams require.NoError(t, json.NewDecoder(resp.Body).Decode(&f)) require.Equal(t, "hi", f.Search) require.Equal(t, "active", f.Status) require.Equal(t, "scifi", f.Custom["theme"]) }