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) }