diff --git a/core/matchers/src/main/kotlin/au/com/dius/pact/core/matchers/Matching.kt b/core/matchers/src/main/kotlin/au/com/dius/pact/core/matchers/Matching.kt index c9643fe75c..789db47446 100644 --- a/core/matchers/src/main/kotlin/au/com/dius/pact/core/matchers/Matching.kt +++ b/core/matchers/src/main/kotlin/au/com/dius/pact/core/matchers/Matching.kt @@ -83,7 +83,8 @@ object Matching : KLogging() { fun matchBodyContents(expected: HttpPart, actual: HttpPart): List { 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 " + diff --git a/core/matchers/src/test/groovy/au/com/dius/pact/core/matchers/MatchingSpec.groovy b/core/matchers/src/test/groovy/au/com/dius/pact/core/matchers/MatchingSpec.groovy index ab38e4f8f8..bfbb7d18e0 100644 --- a/core/matchers/src/test/groovy/au/com/dius/pact/core/matchers/MatchingSpec.groovy +++ b/core/matchers/src/test/groovy/au/com/dius/pact/core/matchers/MatchingSpec.groovy @@ -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 { @@ -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')) @@ -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'") + } } diff --git a/core/model/src/main/kotlin/au/com/dius/pact/core/model/matchingrules/MatchingRules.kt b/core/model/src/main/kotlin/au/com/dius/pact/core/model/matchingrules/MatchingRules.kt index 1ba21ff25f..3a86ff9a4f 100644 --- a/core/model/src/main/kotlin/au/com/dius/pact/core/model/matchingrules/MatchingRules.kt +++ b/core/model/src/main/kotlin/au/com/dius/pact/core/model/matchingrules/MatchingRules.kt @@ -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 @@ -16,6 +17,7 @@ enum class RuleLogic { */ interface MatchingRule { fun toMap(spec: PactSpecVersion): Map + fun canMatch(contentType: ContentType): Boolean = false } /** @@ -30,6 +32,7 @@ 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 } /** @@ -37,6 +40,7 @@ object EqualsMatcher : MatchingRule { */ 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 } /** @@ -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( @@ -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): MatchingRuleGroup { var ruleLogic = RuleLogic.AND