package pages
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func postForm(body string) *http.Request {
r := httptest.NewRequest(http.MethodPost, "/tokens?grants=%2A&revoke=all", strings.NewReader(body))
r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
return r
}
// TestFormValuesIgnoresTheQueryString is the reason this function is shared.
// A mutation must not be drivable from a URL a viewer was linked to, which the
// same-origin guard would happily let through.
func TestFormValuesIgnoresTheQueryString(t *testing.T) {
r := postForm("grants=bench%3Aupload")
got, err := FormValues(httptest.NewRecorder(), r, 0)
require.NoError(t, err)
assert.Equal(t, "bench:upload", got.Get("grants"), "the body's value, not the URL's")
assert.Empty(t, got.Get("revoke"), "a field present only in the query is not this form's")
// r.Form, the wrong one, would have carried it — that merge is the hole.
assert.Equal(t, "all", r.Form.Get("revoke"), "the merge is what we are avoiding")
assert.Equal(t, []string{"bench:upload", "*"}, r.Form["grants"],
"and it would have appended the URL's value to the body's")
}
func TestFormValuesRefusesAnOversizedBody(t *testing.T) {
r := postForm("grants=" + strings.Repeat("x", 4096))
_, err := FormValues(httptest.NewRecorder(), r, 128)
require.Error(t, err)
assert.ErrorIs(t, err, ErrInvalidForm)
// The same body inside the limit reads fine, so the refusal is the limit
// and not the shape.
got, err := FormValues(httptest.NewRecorder(), postForm("grants=ok"), 128)
require.NoError(t, err)
assert.Equal(t, "ok", got.Get("grants"))
}
func TestFormValuesDefaultsTheLimit(t *testing.T) {
r := postForm("grants=" + strings.Repeat("x", DefaultMaxFormBytes+1))
_, err := FormValues(httptest.NewRecorder(), r, 0)
require.Error(t, err, "max <= 0 means the default, not unbounded")
assert.ErrorIs(t, err, ErrInvalidForm)
}