Skip to content

Commit

Permalink
feat(consumer-dsl): Support request body as byte array #1777
Browse files Browse the repository at this point in the history
  • Loading branch information
rholshausen committed Apr 22, 2024
1 parent 151211e commit fa6714c
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import au.com.dius.pact.core.model.ProviderState
import au.com.dius.pact.core.model.generators.Category
import au.com.dius.pact.core.model.generators.Generators
import au.com.dius.pact.core.model.generators.ProviderStateGenerator
import au.com.dius.pact.core.model.matchingrules.ContentTypeMatcher
import au.com.dius.pact.core.model.matchingrules.MatchingRules
import au.com.dius.pact.core.model.matchingrules.RegexMatcher
import au.com.dius.pact.core.model.queryStringToMap
Expand Down Expand Up @@ -367,6 +368,18 @@ open class PactDslRequestWithPath : PactDslRequestBase {
return super.bodyMatchingContentType(contentType, exampleContents) as PactDslRequestWithPath
}

/**
* Request body as a binary data. It will match any expected bodies against the content type.
* @param example Example contents to use in the consumer test
* @param contentType Content type of the data
*/
fun withBinaryData(example: ByteArray, contentType: String): PactDslRequestWithPath {
requestBody = body(example, au.com.dius.pact.core.model.ContentType.fromString(contentType))
requestHeaders["Content-Type"] = listOf(contentType)
requestMatchers.addCategory("body").addRule("$", ContentTypeMatcher(contentType))
return this
}

/**
* The path of the request
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import au.com.dius.pact.core.model.OptionalBody.Companion.body
import au.com.dius.pact.core.model.PactSpecVersion
import au.com.dius.pact.core.model.generators.Category
import au.com.dius.pact.core.model.generators.ProviderStateGenerator
import au.com.dius.pact.core.model.matchingrules.ContentTypeMatcher
import au.com.dius.pact.core.model.matchingrules.RegexMatcher
import au.com.dius.pact.core.model.queryStringToMap
import au.com.dius.pact.core.support.expressions.DataType
Expand Down Expand Up @@ -288,6 +289,18 @@ open class PactDslRequestWithoutPath @JvmOverloads constructor(
return super.bodyMatchingContentType(contentType, exampleContents) as PactDslRequestWithoutPath
}

/**
* Request body as a binary data. It will match any expected bodies against the content type.
* @param example Example contents to use in the consumer test
* @param contentType Content type of the data
*/
fun withBinaryData(example: ByteArray, contentType: String): PactDslRequestWithoutPath {
requestBody = body(example, au.com.dius.pact.core.model.ContentType.fromString(contentType))
requestHeaders["Content-Type"] = listOf(contentType)
requestMatchers.addCategory("body").addRule("$", ContentTypeMatcher(contentType))
return this
}

/**
* The path of the request
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,4 +265,28 @@ class PactDslRequestWithPathSpec extends Specification {
def ex = thrown(au.com.dius.pact.consumer.InvalidMatcherException)
ex.message == 'Example "abcd" does not match regular expression "\\d+"'
}
@Issue('#1777')
def 'supports setting binary body contents'() {
given:
def request = ConsumerPactBuilder.consumer('spec')
.hasPactWith('provider')
.uponReceiving('a PUT request with binary data')
.path('/path')
def gif1px = [
0107, 0111, 0106, 0070, 0067, 0141, 0001, 0000, 0001, 0000, 0200, 0000, 0000, 0377, 0377, 0377,
0377, 0377, 0377, 0054, 0000, 0000, 0000, 0000, 0001, 0000, 0001, 0000, 0000, 0002, 0002, 0104,
0001, 0000, 0073
] as byte[]
when:
def result = request.withBinaryData(gif1px, 'image/gif')
then:
result.requestHeaders['Content-Type'] == ['image/gif']
result.requestBody.value == gif1px
result.requestMatchers.rulesForCategory('body').toMap(PactSpecVersion.V4) == [
'$': [matchers: [[match: 'contentType', value: 'image/gif']], combine: 'AND']
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,27 @@ class PactDslRequestWithoutPathSpec extends Specification {
def ex = thrown(au.com.dius.pact.consumer.InvalidMatcherException)
ex.message == 'Example "/abcd" does not match regular expression "\\/\\d+"'
}

@Issue('#1777')
def 'supports setting binary body contents'() {
given:
def request = ConsumerPactBuilder.consumer('spec')
.hasPactWith('provider')
.uponReceiving('a PUT request with binary data')
def gif1px = [
0107, 0111, 0106, 0070, 0067, 0141, 0001, 0000, 0001, 0000, 0200, 0000, 0000, 0377, 0377, 0377,
0377, 0377, 0377, 0054, 0000, 0000, 0000, 0000, 0001, 0000, 0001, 0000, 0000, 0002, 0002, 0104,
0001, 0000, 0073
] as byte[]

when:
def result = request.withBinaryData(gif1px, 'image/gif')

then:
result.requestHeaders['Content-Type'] == ['image/gif']
result.requestBody.value == gif1px
result.requestMatchers.rulesForCategory('body').toMap(PactSpecVersion.V4) == [
'$': [matchers: [[match: 'contentType', value: 'image/gif']], combine: 'AND']
]
}
}

0 comments on commit fa6714c

Please sign in to comment.