Skip to content

Commit

Permalink
fix: only apply valid matchers for binary bodies
Browse files Browse the repository at this point in the history
  • Loading branch information
Ronald Holshausen committed Jun 19, 2020
1 parent 9f21d62 commit 755a968
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 2 deletions.
Expand Up @@ -83,7 +83,8 @@ object Matching : KLogging() {
fun matchBodyContents(expected: HttpPart, actual: HttpPart): List<BodyMismatch> {
val matcher = expected.matchingRules.rulesForCategory("body").matchingRules["$"]
return when {
matcher != null -> domatch(matcher, listOf("$"), expected.body.unwrap(), actual.body.unwrap(), BodyMismatchFactory)
matcher != null && matcher.canMatch(expected.determineContentType()) ->
domatch(matcher, listOf("$"), expected.body.unwrap(), actual.body.unwrap(), BodyMismatchFactory)
expected.body.unwrap().contentEquals(actual.body.unwrap()) -> emptyList()
else -> listOf(BodyMismatch(expected.body.unwrap(), actual.body.unwrap(),
"Actual body '${actual.body.valueAsString()}' is not equal to the expected body " +
Expand Down
Expand Up @@ -6,6 +6,7 @@ import au.com.dius.pact.core.model.Request
import au.com.dius.pact.core.model.Response
import au.com.dius.pact.core.model.matchingrules.ContentTypeMatcher
import au.com.dius.pact.core.model.matchingrules.MatchingRulesImpl
import au.com.dius.pact.core.model.matchingrules.TypeMatcher
import spock.lang.Specification

class MatchingSpec extends Specification {
Expand Down Expand Up @@ -115,7 +116,7 @@ class MatchingSpec extends Specification {
actual = new Response(200, [:], OptionalBody.body('hello'.bytes))
}

def 'Body Matching - compares the body with aby defined matcher'() {
def 'Body Matching - compares the body with any defined matcher'() {
given:
def matchingRulesImpl = new MatchingRulesImpl()
matchingRulesImpl.addCategory('body').addRule('$', new ContentTypeMatcher('image/jpeg'))
Expand All @@ -129,4 +130,20 @@ class MatchingSpec extends Specification {
then:
result.empty
}

def 'Body Matching - only use a matcher that can handle the body type'() {
given:
def matchingRulesImpl = new MatchingRulesImpl()
matchingRulesImpl.addCategory('body').addRule('$', TypeMatcher.INSTANCE)
def expected = new Response(200, ['Content-Type': ['image/jpeg']], OptionalBody.body('hello'.bytes),
matchingRulesImpl)
def actual = new Response(200, [:], OptionalBody.body(MatchingSpec.getResourceAsStream('/RAT.JPG').bytes))

when:
def result = Matching.INSTANCE.matchBody(expected, actual, false)

then:
!result.empty
result[0].mismatch.endsWith("is not equal to the expected body 'hello'")
}
}
@@ -1,5 +1,6 @@
package au.com.dius.pact.core.model.matchingrules

import au.com.dius.pact.core.model.ContentType
import au.com.dius.pact.core.model.PactSpecVersion
import mu.KLogging
import java.lang.IllegalArgumentException
Expand All @@ -16,6 +17,7 @@ enum class RuleLogic {
*/
interface MatchingRule {
fun toMap(spec: PactSpecVersion): Map<String, Any?>
fun canMatch(contentType: ContentType): Boolean = false
}

/**
Expand All @@ -30,13 +32,15 @@ data class DateMatcher @JvmOverloads constructor(val format: String = "yyyy-MM-d
*/
object EqualsMatcher : MatchingRule {
override fun toMap(spec: PactSpecVersion) = mapOf("match" to "equality")
override fun canMatch(contentType: ContentType) = true
}

/**
* Matcher for a substring in a string
*/
data class IncludeMatcher(val value: String) : MatchingRule {
override fun toMap(spec: PactSpecVersion) = mapOf("match" to "include", "value" to value)
override fun canMatch(contentType: ContentType) = true
}

/**
Expand Down Expand Up @@ -124,6 +128,7 @@ object ValuesMatcher : MatchingRule {
*/
data class ContentTypeMatcher @JvmOverloads constructor (val contentType: String) : MatchingRule {
override fun toMap(spec: PactSpecVersion) = mapOf("match" to "contentType", "value" to contentType)
override fun canMatch(contentType: ContentType) = true
}

data class MatchingRuleGroup @JvmOverloads constructor(
Expand All @@ -138,6 +143,8 @@ data class MatchingRuleGroup @JvmOverloads constructor(
}
}

fun canMatch(contentType: ContentType) = rules.all { it.canMatch(contentType) }

companion object : KLogging() {
fun fromMap(map: Map<String, Any?>): MatchingRuleGroup {
var ruleLogic = RuleLogic.AND
Expand Down

0 comments on commit 755a968

Please sign in to comment.