-
-
Notifications
You must be signed in to change notification settings - Fork 481
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Support generators with URI FORM encoded bodies #1610
- Loading branch information
1 parent
79d2174
commit 870a999
Showing
9 changed files
with
310 additions
and
37 deletions.
There are no files selected for viewing
47 changes: 47 additions & 0 deletions
47
.../junit5/src/test/java/au/com/dius/pact/consumer/junit5/FormPostWithProviderStateTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package au.com.dius.pact.consumer.junit5; | ||
|
||
import au.com.dius.pact.consumer.MockServer; | ||
import au.com.dius.pact.consumer.dsl.FormPostBuilder; | ||
import au.com.dius.pact.consumer.dsl.PactDslWithProvider; | ||
import au.com.dius.pact.core.model.PactSpecVersion; | ||
import au.com.dius.pact.core.model.RequestResponsePact; | ||
import au.com.dius.pact.core.model.annotations.Pact; | ||
import org.apache.hc.client5.http.fluent.Request; | ||
import org.apache.hc.core5.http.HttpResponse; | ||
import org.apache.hc.core5.http.message.BasicNameValuePair; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.ExtendWith; | ||
|
||
import java.io.IOException; | ||
import java.util.UUID; | ||
|
||
import static org.hamcrest.MatcherAssert.assertThat; | ||
import static org.hamcrest.Matchers.equalTo; | ||
import static org.hamcrest.Matchers.is; | ||
|
||
@ExtendWith(PactConsumerTestExt.class) | ||
@PactTestFor(providerName = "FormPostProvider", pactVersion = PactSpecVersion.V3) | ||
public class FormPostWithProviderStateTest { | ||
@Pact(consumer = "FormPostConsumer") | ||
public RequestResponsePact formpost(PactDslWithProvider builder) { | ||
return builder | ||
.given("provider state 1") | ||
.uponReceiving("FORM POST request with provider state") | ||
.path("/form") | ||
.method("POST") | ||
.body( | ||
new FormPostBuilder() | ||
.parameterFromProviderState("value", "value", "1000")) | ||
.willRespondWith() | ||
.status(200) | ||
.toPact(); | ||
} | ||
|
||
@Test | ||
void testFormPost(MockServer mockServer) throws IOException { | ||
HttpResponse httpResponse = Request.post(mockServer.getUrl() + "/form") | ||
.bodyForm( | ||
new BasicNameValuePair("value", "1000")).execute().returnResponse(); | ||
assertThat(httpResponse.getCode(), is(equalTo(200))); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
...rc/main/kotlin/au/com/dius/pact/core/model/generators/FormUrlEncodedContentTypeHandler.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package au.com.dius.pact.core.model.generators | ||
|
||
import au.com.dius.pact.core.model.OptionalBody | ||
import au.com.dius.pact.core.model.PathToken | ||
import au.com.dius.pact.core.model.parsePath | ||
import org.apache.hc.core5.http.NameValuePair | ||
import org.apache.hc.core5.http.message.BasicNameValuePair | ||
import org.apache.hc.core5.net.WWWFormCodec | ||
import java.nio.charset.Charset | ||
|
||
object FormUrlEncodedContentTypeHandler : ContentTypeHandler { | ||
override fun processBody(value: OptionalBody, fn: (QueryResult) -> Unit): OptionalBody { | ||
val charset = value.contentType.asCharset() | ||
val body = FormQueryResult(WWWFormCodec.parse(value.valueAsString(), charset)) | ||
fn.invoke(body) | ||
return OptionalBody.body(WWWFormCodec.format(body.body, charset).toByteArray(charset), value.contentType) | ||
} | ||
|
||
override fun applyKey(body: QueryResult, key: String, generator: Generator, context: MutableMap<String, Any>) { | ||
val values = (body as FormQueryResult).body | ||
val pathExp = parsePath(key) | ||
values.forEachIndexed { index, entry -> | ||
if (pathMatches(pathExp, entry.name.orEmpty())) { | ||
values[index] = BasicNameValuePair(entry.name, generator.generate(context, entry.value)?.toString()) | ||
} | ||
} | ||
} | ||
|
||
private fun pathMatches(pathExp: List<PathToken>, name: String): Boolean { | ||
val root = pathExp[0] | ||
val levelOne = pathExp[1] | ||
return pathExp.size == 2 && root is PathToken.Root && | ||
(levelOne is PathToken.Star || (levelOne is PathToken.Field && levelOne.name == name)) | ||
} | ||
} | ||
|
||
class FormQueryResult(var body: MutableList<NameValuePair>, override val key: Any? = null) : QueryResult { | ||
override var value: Any? | ||
get() = body | ||
set(value) { | ||
body = if (value is List<*>) { | ||
(value as List<NameValuePair>).toMutableList() | ||
} else { | ||
WWWFormCodec.parse(value.toString(), Charset.defaultCharset()) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
...groovy/au/com/dius/pact/core/model/generators/FormUrlEncodedContentTypeHandlerSpec.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package au.com.dius.pact.core.model.generators | ||
|
||
import org.apache.hc.core5.net.WWWFormCodec | ||
import spock.lang.Specification | ||
|
||
import java.nio.charset.Charset | ||
|
||
class FormUrlEncodedContentTypeHandlerSpec extends Specification { | ||
def 'applies the generator to the field in the body'() { | ||
given: | ||
def body = 'a=A&b=B&c=C' | ||
def charset = Charset.defaultCharset() | ||
def queryResult = new FormQueryResult(WWWFormCodec.parse(body, charset), null) | ||
def key = '$.b' | ||
def generator = Mock(Generator) { | ||
generate(_, _) >> 'X' | ||
} | ||
|
||
when: | ||
FormUrlEncodedContentTypeHandler.INSTANCE.applyKey(queryResult, key, generator, [:]) | ||
|
||
then: | ||
WWWFormCodec.format(queryResult.body, charset) == 'a=A&b=X&c=C' | ||
} | ||
|
||
def 'does not apply the generator when field is not in the body'() { | ||
def body = 'a=A&b=B&c=C' | ||
def charset = Charset.defaultCharset() | ||
def queryResult = new FormQueryResult(WWWFormCodec.parse(body, charset), null) | ||
def key = '$.d' | ||
def generator = Mock(Generator) { | ||
generate(_, _) >> 'X' | ||
} | ||
|
||
when: | ||
FormUrlEncodedContentTypeHandler.INSTANCE.applyKey(queryResult, key, generator, [:]) | ||
|
||
then: | ||
WWWFormCodec.format(queryResult.body, charset) == 'a=A&b=B&c=C' | ||
} | ||
|
||
def 'does not apply the generator to empty body'() { | ||
given: | ||
def body = new FormQueryResult([], null) | ||
def key = '$.d' | ||
def generator = Mock(Generator) { | ||
generate(_, _) >> 'X' | ||
} | ||
|
||
when: | ||
FormUrlEncodedContentTypeHandler.INSTANCE.applyKey(body, key, generator, [:]) | ||
|
||
then: | ||
WWWFormCodec.format(body.body, Charset.defaultCharset()) == '' | ||
} | ||
|
||
def 'applies the generator to all map entries'() { | ||
given: | ||
def body = 'a=A&b=B&c=C' | ||
def charset = Charset.defaultCharset() | ||
def queryResult = new FormQueryResult(WWWFormCodec.parse(body, charset), null) | ||
def key = '$.*' | ||
def generator = Mock(Generator) { | ||
generate(_, _) >> 'X' | ||
} | ||
|
||
when: | ||
FormUrlEncodedContentTypeHandler.INSTANCE.applyKey(queryResult, key, generator, [:]) | ||
|
||
then: | ||
WWWFormCodec.format(queryResult.body, charset) == 'a=X&b=X&c=X' | ||
} | ||
} |
Oops, something went wrong.