This is an automated email from the ASF dual-hosted git repository. matrei pushed a commit to branch feat/http-client-form-post in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit 5aff68c53859c65e7e49a2dd4af6fe14dd684a31 Author: Mattias Reichel <[email protected]> AuthorDate: Sun Jun 14 13:47:51 2026 +0200 docs: add info about HttpClientSupport.httpPostForm() --- grails-doc/src/en/guide/introduction/whatsNew.adoc | 7 +++++++ grails-doc/src/en/guide/testing/integrationTesting.adoc | 17 +++++++++++++++++ grails-testing-support-http-client/README.md | 10 ++++++++++ 3 files changed, 34 insertions(+) diff --git a/grails-doc/src/en/guide/introduction/whatsNew.adoc b/grails-doc/src/en/guide/introduction/whatsNew.adoc index 17f4bb42d3..cf23eba335 100644 --- a/grails-doc/src/en/guide/introduction/whatsNew.adoc +++ b/grails-doc/src/en/guide/introduction/whatsNew.adoc @@ -36,3 +36,10 @@ The Grails Gradle extension now defaults `preserveParameterNames` to `true`, so Tag library unit tests also clean up and rebuild TagLib metadata automatically between features. Tests that use `TagLibUnitTest` no longer need to manage `purgeTagLibMetaClass`, and specs that mock additional tag libraries continue to work across feature methods. + +==== Test HTTP Client Form Requests + +Integration tests that implement `HttpClientSupport` can now use `httpPostForm(...)` to send `application/x-www-form-urlencoded` +request bodies. The helper URL-encodes form fields using UTF-8, and repeated values in a `Collection` or array are encoded as +repeated keys in insertion order. + diff --git a/grails-doc/src/en/guide/testing/integrationTesting.adoc b/grails-doc/src/en/guide/testing/integrationTesting.adoc index 13eb1c14af..d5fa35c92f 100644 --- a/grails-doc/src/en/guide/testing/integrationTesting.adoc +++ b/grails-doc/src/en/guide/testing/integrationTesting.adoc @@ -403,6 +403,14 @@ class DemoSpec extends Specification implements HttpClientSupport { response.assertJsonContains([title: 'Grails in Action']) } + void 'Posting form data'() { + when: 'you post a map it is turned into an application/x-www-form-urlencoded payload' + def response = httpPostForm('/api/search', [query: 'grails core', tag: ['web', 'testing']]) + + then: + response.assertStatus(200) + } + void 'Posting and verifying XML'() { when: 'you can post XML using a builder' def response = httpPostXml('/api/books') { @@ -457,6 +465,15 @@ class DemoSpec extends Specification implements HttpClientSupport { 60 seconds and a redirect policy of always following redirects. You can use helpers `newHttpRequestWith(Closure configurer)` and `newHttpClientWith(Closure configurer)` to customize your own client and requests starting from the defaults. +`httpPostForm(...)` sends `application/x-www-form-urlencoded` request bodies. Pass a `Map` of form fields, and the +helper will URL-encode each entry using UTF-8. Scalar values are encoded once, while `Collection` and array values are +encoded as repeated keys in insertion order: + +[source,groovy] +---- +httpPostForm('/search', [query: 'grails core', tag: ['web', 'testing']]) +---- + Additional request helper methods available include `httpDelete()`, `httpHead()`, `httpOptions()`, `httpPatch()`, `httpPut()`, `httpTrace()`, and many assertion methods on responses. diff --git a/grails-testing-support-http-client/README.md b/grails-testing-support-http-client/README.md index b30fffec10..613c6a5edb 100644 --- a/grails-testing-support-http-client/README.md +++ b/grails-testing-support-http-client/README.md @@ -123,6 +123,16 @@ httpPutJson('/products/1', jsonGenerator, [ The same `JsonGenerator` overload pattern is available on `httpPostJson(...)`, `httpPutJson(...)`, and `httpPatchJson(...)`, including the variants that accept request headers and an explicit `HttpClient`. +### Form data + +`httpPostForm(...)` sends `application/x-www-form-urlencoded` request bodies. Pass a `Map` of form fields and the +helper will URL-encode each entry using UTF-8. Scalar values are encoded once, while `Collection` and array values are +encoded as repeated keys in insertion order: + +```groovy +httpPostForm('/search', [query: 'grails core', tag: ['web', 'testing']]) +``` + ### XML formatting XML request bodies can be generated with Groovy MarkupBuilder DSL. For the `http[Post|Patch|Put]Xml` methods,
