Files
doormile_backend/controllers/admin_pagesize_test.go

89 lines
3.1 KiB
Go

package controllers
import (
"net/http/httptest"
"testing"
"doormile/utils"
"github.com/gofiber/fiber/v2"
)
// The page-size ceiling on the admin list endpoints.
//
// GetAdminBookings and GetAdminCustomers clamped `pagesize` to a hard-coded
// 100 while utils.ParsePage allowed 1000. The console does not read one page —
// it DRAINS the list, and it asks for 1000 a page. Being handed 100 meant ten
// times the round trips for the same rows, and because the drain has its own
// page budget (12), the list it renders stopped at 1,200 bookings. Past that
// the counts on the screen are floors presented as totals.
//
// The ceiling now comes from utils.MaxPageSize so the two cannot drift apart
// again. These tests pin the clamp arithmetic directly: exercising the handlers
// themselves needs Postgres, and this is the part that was wrong.
// clampPageSize mirrors the expression in the handlers. If the handlers change,
// this stops matching and the tests below stop meaning anything — which is why
// TestHandlersUseTheSharedCeiling reads the source instead of trusting it.
func clampPageSize(requested int) int {
return min(utils.MaxPageSize, max(1, requested))
}
func TestPageSizeCeilingComesFromTheSharedConstant(t *testing.T) {
if utils.MaxPageSize <= 100 {
t.Fatalf("utils.MaxPageSize = %d: raising the clamp to it is pointless if it "+
"is not above the old hard-coded 100", utils.MaxPageSize)
}
// The exact request the console makes on every drain page.
if got := clampPageSize(1000); got != 1000 {
t.Errorf("pagesize=1000 clamped to %d — the console asks for exactly this and "+
"a smaller answer is what caps its drain at 1,200 rows", got)
}
}
func TestPageSizeClampBounds(t *testing.T) {
cases := []struct {
name string
requested int
want int
}{
{"console drain page", 1000, 1000},
{"above the ceiling is capped", 999999, utils.MaxPageSize},
{"at the ceiling", utils.MaxPageSize, utils.MaxPageSize},
{"one below the ceiling", utils.MaxPageSize - 1, utils.MaxPageSize - 1},
{"zero floors to one", 0, 1},
{"negative floors to one", -50, 1},
{"one stays one", 1, 1},
{"the old ceiling still works", 100, 100},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
if got := clampPageSize(tc.requested); got != tc.want {
t.Errorf("clampPageSize(%d) = %d, want %d", tc.requested, got, tc.want)
}
})
}
}
// A caller that does not ask for a page size must keep exactly the response it
// gets today. Widening the ceiling must not widen the default: every client
// that never passed ?pagesize would suddenly be handed 50x the rows.
func TestDefaultPageSizeIsUnchangedByTheWiderCeiling(t *testing.T) {
app := fiber.New(fiber.Config{DisableStartupMessage: true})
app.Get("/probe", func(c *fiber.Ctx) error {
// The same default the handlers pass to QueryInt.
if got := c.QueryInt("pagesize", 20); got != 20 {
t.Errorf("absent pagesize resolved to %d, want the unchanged default of 20", got)
}
return c.SendString("ok")
})
resp, err := app.Test(httptest.NewRequest("GET", "/probe", nil), 5000)
if err != nil {
t.Fatalf("probe request: %v", err)
}
defer resp.Body.Close()
}