diff --git a/core/model/src/main/kotlin/au/com/dius/pact/core/model/Plugins.kt b/core/model/src/main/kotlin/au/com/dius/pact/core/model/Plugins.kt index c2ea7b21d1..fa67ff65b7 100644 --- a/core/model/src/main/kotlin/au/com/dius/pact/core/model/Plugins.kt +++ b/core/model/src/main/kotlin/au/com/dius/pact/core/model/Plugins.kt @@ -14,6 +14,10 @@ data class PluginData( /** Any configuration supplied by the plugin */ val configuration: Map ) { + fun configAsJsonMap(): Map { + return configuration.mapValues { Json.toJson(it.value) } + } + companion object { fun fromJson(json: JsonValue): PluginData { val configuration = when (val config = json["configuration"]) { diff --git a/core/model/src/main/kotlin/au/com/dius/pact/core/model/messaging/Message.kt b/core/model/src/main/kotlin/au/com/dius/pact/core/model/messaging/Message.kt index 6af040fed4..b885b25ccc 100644 --- a/core/model/src/main/kotlin/au/com/dius/pact/core/model/messaging/Message.kt +++ b/core/model/src/main/kotlin/au/com/dius/pact/core/model/messaging/Message.kt @@ -68,6 +68,11 @@ interface MessageInteraction { * Returns the message content as a String. This will convert the contents if necessary. */ fun contentsAsString(): String? + + /** + * Any configuration provided by plugins + */ + val pluginConfiguration: Map> } /** @@ -98,6 +103,9 @@ class Message @JvmOverloads constructor( else -> contents.valueAsString() } + override val pluginConfiguration: Map> + get() = emptyMap() + @Suppress("NestedBlockDepth") override fun toMap(pactSpecVersion: PactSpecVersion): Map { val map: MutableMap = mutableMapOf( diff --git a/pact-specification-test/src/test/groovy/specification/MessageSpecificationSpec.groovy b/pact-specification-test/src/test/groovy/specification/MessageSpecificationSpec.groovy index d054d5749b..c02f29bb01 100644 --- a/pact-specification-test/src/test/groovy/specification/MessageSpecificationSpec.groovy +++ b/pact-specification-test/src/test/groovy/specification/MessageSpecificationSpec.groovy @@ -15,7 +15,8 @@ class MessageSpecificationSpec extends Specification { @SuppressWarnings('UnnecessaryGetter') def '#test #matchDesc'() { expect: - ResponseComparison.compareMessage(expected, actual).bodyMismatches.value.mismatches.isEmpty() == match + ResponseComparison.Companion.newInstance().compareMessage(expected, actual, null, [:]) + .bodyMismatches.value.mismatches.isEmpty() == match where: [test, match, matchDesc, expected, actual] << loadTestCases() @@ -38,5 +39,4 @@ class MessageSpecificationSpec extends Specification { } result } - } diff --git a/provider/junit/src/main/kotlin/au/com/dius/pact/provider/junit/target/MessageTarget.kt b/provider/junit/src/main/kotlin/au/com/dius/pact/provider/junit/target/MessageTarget.kt index b4d4919e3d..7ce62613b3 100644 --- a/provider/junit/src/main/kotlin/au/com/dius/pact/provider/junit/target/MessageTarget.kt +++ b/provider/junit/src/main/kotlin/au/com/dius/pact/provider/junit/target/MessageTarget.kt @@ -41,6 +41,7 @@ open class MessageTarget @JvmOverloads constructor( context: MutableMap, pending: Boolean ) { + // TODO: Require the plugin config here val result = verifier.verifyResponseByInvokingProviderMethods(provider, consumer, interaction, interaction.description, mutableMapOf(), false) reportTestResult(result, verifier) diff --git a/provider/junit5/src/main/kotlin/au/com/dius/pact/provider/junit5/PactVerificationContext.kt b/provider/junit5/src/main/kotlin/au/com/dius/pact/provider/junit5/PactVerificationContext.kt index 29091edaee..10010c7f26 100644 --- a/provider/junit5/src/main/kotlin/au/com/dius/pact/provider/junit5/PactVerificationContext.kt +++ b/provider/junit5/src/main/kotlin/au/com/dius/pact/provider/junit5/PactVerificationContext.kt @@ -18,6 +18,7 @@ import au.com.dius.pact.provider.IConsumerInfo import au.com.dius.pact.provider.IProviderInfo import au.com.dius.pact.provider.IProviderVerifier import au.com.dius.pact.provider.PactVerification +import au.com.dius.pact.provider.ProviderUtils.pluginConfigForInteraction import au.com.dius.pact.provider.ProviderVerifier import au.com.dius.pact.provider.VerificationFailureType import au.com.dius.pact.provider.VerificationResult @@ -104,18 +105,12 @@ data class PactVerificationContext @JvmOverloads constructor( val expectedResponse = DefaultResponseGenerator.generateResponse(reqResInteraction.response, context, GeneratorTestMode.Provider, pactPluginData, pluginData) val actualResponse = target.executeInteraction(client, request) - val pluginContext = pactPluginData.associate { - it.name to PluginConfiguration( - pluginData[it.name].orEmpty().toMutableMap(), - it.configuration.mapValues { (_, v) -> Json.toJson(v) }.toMutableMap() - ) - } listOf( verifier!!.verifyRequestResponsePact( expectedResponse, actualResponse, interactionMessage, mutableMapOf(), reqResInteraction.interactionId.orEmpty(), consumer.pending, - pluginContext + pluginConfigForInteraction(pact, interaction) ) ) } catch (e: Exception) { @@ -156,7 +151,7 @@ data class PactVerificationContext @JvmOverloads constructor( } else -> { return listOf(verifier!!.verifyResponseByInvokingProviderMethods(providerInfo, consumer, interaction, - interaction.description, mutableMapOf(), consumer.pending)) + interaction.description, mutableMapOf(), consumer.pending, pluginConfigForInteraction(pact, interaction))) } } } diff --git a/provider/junit5/src/test/groovy/au/com/dius/pact/provider/junit5/PactVerificationContextSpec.groovy b/provider/junit5/src/test/groovy/au/com/dius/pact/provider/junit5/PactVerificationContextSpec.groovy index a355bf5f8e..327bb54417 100644 --- a/provider/junit5/src/test/groovy/au/com/dius/pact/provider/junit5/PactVerificationContextSpec.groovy +++ b/provider/junit5/src/test/groovy/au/com/dius/pact/provider/junit5/PactVerificationContextSpec.groovy @@ -148,6 +148,6 @@ class PactVerificationContextSpec extends Specification { then: 1 * verifier.verifyResponseByInvokingProviderMethods(provider, consumer, interaction, - interaction.description, [:], true) >> new VerificationResult.Ok() + interaction.description, [:], true, _) >> new VerificationResult.Ok() } } diff --git a/provider/src/main/kotlin/au/com/dius/pact/provider/ProviderUtils.kt b/provider/src/main/kotlin/au/com/dius/pact/provider/ProviderUtils.kt index 171d032fb3..79c60f03c1 100644 --- a/provider/src/main/kotlin/au/com/dius/pact/provider/ProviderUtils.kt +++ b/provider/src/main/kotlin/au/com/dius/pact/provider/ProviderUtils.kt @@ -3,8 +3,11 @@ package au.com.dius.pact.provider import au.com.dius.pact.core.model.DefaultPactReader import au.com.dius.pact.core.model.FileSource import au.com.dius.pact.core.model.Interaction +import au.com.dius.pact.core.model.Pact +import au.com.dius.pact.core.support.Json import au.com.dius.pact.provider.junitsupport.loader.PactLoader import au.com.dius.pact.provider.junitsupport.loader.PactSource +import io.pact.plugins.jvm.core.PluginConfiguration import mu.KLogging import org.apache.commons.io.FilenameUtils import java.io.File @@ -178,4 +181,22 @@ object ProviderUtils : KLogging() { pactLoader.initLoader(testClass, testInstance) return pactLoader } + + @JvmStatic + fun pluginConfigForInteraction(pact: Pact?, interaction: Interaction): Map { + return if (pact != null && pact.isV4Pact()) { + val v4Pact = pact.asV4Pact().unwrap() + val v4Interaction = interaction.asV4Interaction() + val pactPluginData = v4Pact.pluginData() + val interactionPluginData = v4Interaction.pluginConfiguration.toMap() + pactPluginData.associate { + it.name to PluginConfiguration( + interactionPluginData[it.name].orEmpty().toMutableMap(), + it.configuration.mapValues { (_, v) -> Json.toJson(v) }.toMutableMap() + ) + } + } else { + emptyMap() + } + } } diff --git a/provider/src/main/kotlin/au/com/dius/pact/provider/ProviderVerifier.kt b/provider/src/main/kotlin/au/com/dius/pact/provider/ProviderVerifier.kt index 1684e35111..73557dfe83 100644 --- a/provider/src/main/kotlin/au/com/dius/pact/provider/ProviderVerifier.kt +++ b/provider/src/main/kotlin/au/com/dius/pact/provider/ProviderVerifier.kt @@ -30,6 +30,7 @@ import au.com.dius.pact.core.model.messaging.Message import au.com.dius.pact.core.model.messaging.MessageInteraction import au.com.dius.pact.core.pactbroker.IPactBrokerClient import au.com.dius.pact.core.support.Auth +import au.com.dius.pact.core.support.Json import au.com.dius.pact.core.support.MetricEvent import au.com.dius.pact.core.support.Metrics import au.com.dius.pact.core.support.Result @@ -38,6 +39,7 @@ import au.com.dius.pact.core.support.Result.Ok import au.com.dius.pact.core.support.expressions.SystemPropertyResolver import au.com.dius.pact.core.support.hasProperty import au.com.dius.pact.core.support.ifNullOrEmpty +import au.com.dius.pact.core.support.json.JsonValue import au.com.dius.pact.core.support.property import au.com.dius.pact.provider.reporters.AnsiConsoleReporter import au.com.dius.pact.provider.reporters.Event @@ -248,6 +250,7 @@ interface IProviderVerifier { * Verifies the interaction by invoking a method on a provider test class */ @Suppress("LongParameterList") + @Deprecated("Use the version that passes in any plugin configuration") fun verifyResponseByInvokingProviderMethods( providerInfo: IProviderInfo, consumer: IConsumerInfo, @@ -257,6 +260,21 @@ interface IProviderVerifier { pending: Boolean ): VerificationResult + /** + * Verifies the interaction by invoking a method on a provider test class + */ + @Suppress("LongParameterList") + fun verifyResponseByInvokingProviderMethods( + providerInfo: IProviderInfo, + consumer: IConsumerInfo, + interaction: Interaction, + interactionMessage: String, + failures: MutableMap, + pending: Boolean, + pluginConfiguration: Map + ): VerificationResult + + @Deprecated("Use the version that passes in any plugin configuration") @Suppress("LongParameterList") fun verifyResponseByFactory( providerInfo: IProviderInfo, @@ -267,6 +285,17 @@ interface IProviderVerifier { pending: Boolean ): VerificationResult + @Suppress("LongParameterList") + fun verifyResponseByFactory( + providerInfo: IProviderInfo, + consumer: IConsumerInfo, + interaction: Interaction, + interactionMessage: String, + failures: MutableMap, + pending: Boolean, + pluginConfiguration: Map + ): VerificationResult + /** * Compares the expected and actual responses */ @@ -377,6 +406,7 @@ open class ProviderVerifier @JvmOverloads constructor ( var pactReader: PactReader = DefaultPactReader override var verificationSource: String? = null var pluginManager: PluginManager = DefaultPluginManager + var responseComparer: IResponseComparison = ResponseComparison.Companion /** * This will return true unless the pact.verifier.publishResults property has the value of "true" @@ -389,7 +419,8 @@ open class ProviderVerifier @JvmOverloads constructor ( } } - @Suppress("TooGenericExceptionCaught", "TooGenericExceptionThrown", "SpreadOperator", "LongParameterList") + @Deprecated("Use the version that passes in any plugin configuration") + @Suppress("LongParameterList") override fun verifyResponseByInvokingProviderMethods( providerInfo: IProviderInfo, consumer: IConsumerInfo, @@ -397,6 +428,18 @@ open class ProviderVerifier @JvmOverloads constructor ( interactionMessage: String, failures: MutableMap, pending: Boolean + ) = verifyResponseByInvokingProviderMethods(providerInfo, consumer, interaction, interactionMessage, failures, + pending, emptyMap()) + + @Suppress("TooGenericExceptionCaught", "TooGenericExceptionThrown", "SpreadOperator", "LongParameterList") + override fun verifyResponseByInvokingProviderMethods( + providerInfo: IProviderInfo, + consumer: IConsumerInfo, + interaction: Interaction, + interactionMessage: String, + failures: MutableMap, + pending: Boolean, + pluginConfiguration: Map ): VerificationResult { val interactionId = interaction.interactionId try { @@ -426,7 +469,7 @@ open class ProviderVerifier @JvmOverloads constructor ( } else { return if (interaction.isAsynchronousMessage()) { verifyMessage(methodsAnnotatedWith.toHashSet(), interaction as MessageInteraction, interactionMessage, - failures, pending) + failures, pending, pluginConfiguration) } else { val expectedResponse = (interaction as SynchronousRequestResponse).response var result: VerificationResult = VerificationResult.Ok(interactionId, emptyList()) @@ -443,7 +486,7 @@ open class ProviderVerifier @JvmOverloads constructor ( failures, interactionId.orEmpty(), pending, - emptyMap() // TODO: pass any plugin config here + pluginConfiguration )) } result @@ -461,7 +504,7 @@ open class ProviderVerifier @JvmOverloads constructor ( } } - @Suppress("TooGenericExceptionCaught") + @Deprecated("Use the version that passes in any plugin configuration") override fun verifyResponseByFactory( providerInfo: IProviderInfo, consumer: IConsumerInfo, @@ -469,6 +512,17 @@ open class ProviderVerifier @JvmOverloads constructor ( interactionMessage: String, failures: MutableMap, pending: Boolean + ) = verifyResponseByFactory(providerInfo, consumer, interaction, interactionMessage, failures, pending, emptyMap()) + + @Suppress("TooGenericExceptionCaught") + override fun verifyResponseByFactory( + providerInfo: IProviderInfo, + consumer: IConsumerInfo, + interaction: Interaction, + interactionMessage: String, + failures: MutableMap, + pending: Boolean, + pluginConfiguration: Map ): VerificationResult { val interactionId = interaction.interactionId.orEmpty() try { @@ -480,7 +534,8 @@ open class ProviderVerifier @JvmOverloads constructor ( interactionId, interactionMessage, failures, - pending + pending, + pluginConfiguration ) } else { val expectedResponse = (interaction as SynchronousRequestResponse).response @@ -500,7 +555,7 @@ open class ProviderVerifier @JvmOverloads constructor ( failures, interactionId, pending, - emptyMap() // TODO: Pass in any plugin config here + pluginConfiguration ) } } catch (e: Exception) { @@ -572,12 +627,24 @@ open class ProviderVerifier @JvmOverloads constructor ( } } + @Deprecated("Use version that takes the Plugin Config as a parameter", + ReplaceWith("verifyMessage(methods, message, interactionMessage, failures, pending, pluginConfiguration)") + ) fun verifyMessage( methods: Set, message: MessageInteraction, interactionMessage: String, failures: MutableMap, pending: Boolean + ) = verifyMessage(methods, message, interactionMessage, failures, pending, emptyMap()) + + fun verifyMessage( + methods: Set, + message: MessageInteraction, + interactionMessage: String, + failures: MutableMap, + pending: Boolean, + pluginConfiguration: Map ): VerificationResult { val interactionId = message.interactionId var result: VerificationResult = VerificationResult.Ok(interactionId, emptyList()) @@ -590,19 +657,35 @@ open class ProviderVerifier @JvmOverloads constructor ( interactionId.orEmpty(), interactionMessage, failures, - pending + pending, + pluginConfiguration )) } return result } - private fun verifyMessage( + @Deprecated("Use version that takes the Plugin Config as a parameter", + ReplaceWith( + "verifyMessage(messageFactory, message, interactionId, interactionMessage, failures, pending, pluginConfig)" + ) + ) + fun verifyMessage( messageFactory: Function, message: MessageInteraction, interactionId: String, interactionMessage: String, failures: MutableMap, pending: Boolean + ) = verifyMessage(messageFactory, message, interactionId, interactionMessage, failures, pending, emptyMap()) + + fun verifyMessage( + messageFactory: Function, + message: MessageInteraction, + interactionId: String, + interactionMessage: String, + failures: MutableMap, + pending: Boolean, + pluginConfiguration: Map ): VerificationResult { emitEvent(Event.GeneratesAMessageWhich) val messageResult = messageFactory.apply(message.description) @@ -629,8 +712,8 @@ open class ProviderVerifier @JvmOverloads constructor ( actualMessage = messageResult.toString().toByteArray() } } - val comparison = ResponseComparison.compareMessage(message, - OptionalBody.body(actualMessage, contentType), messageMetadata) + val comparison = responseComparer.compareMessage(message, OptionalBody.body(actualMessage, contentType), + messageMetadata, pluginConfiguration) val s = ": generates a message which" return displayBodyResult( failures, @@ -747,7 +830,9 @@ open class ProviderVerifier @JvmOverloads constructor ( } PactVerification.RESPONSE_FACTORY -> { logger.debug { "Verifying via response factory function" } - verifyResponseByFactory(provider, consumer, interaction, interactionMessage, failures, pending) + verifyResponseByFactory(provider, consumer, interaction, interactionMessage, failures, pending, + ProviderUtils.pluginConfigForInteraction(pact, interaction) + ) } PactVerification.PLUGIN -> { logger.debug { "Verifying via plugin" } @@ -777,7 +862,9 @@ open class ProviderVerifier @JvmOverloads constructor ( else -> { logger.debug { "Verifying via provider methods" } verifyResponseByInvokingProviderMethods( - provider, consumer, interaction, interactionMessage, failures, pending) + provider, consumer, interaction, interactionMessage, failures, pending, + ProviderUtils.pluginConfigForInteraction(pact, interaction) + ) } } @@ -821,7 +908,7 @@ open class ProviderVerifier @JvmOverloads constructor ( pending: Boolean, pluginConfiguration: Map ): VerificationResult { - val comparison = ResponseComparison.compareResponse(expectedResponse, actualResponse, pluginConfiguration) + val comparison = responseComparer.compareResponse(expectedResponse, actualResponse, pluginConfiguration) reporters.forEach { it.returnsAResponseWhich() } diff --git a/provider/src/main/kotlin/au/com/dius/pact/provider/ResponseComparison.kt b/provider/src/main/kotlin/au/com/dius/pact/provider/ResponseComparison.kt index 32e6ebff29..12780e9680 100755 --- a/provider/src/main/kotlin/au/com/dius/pact/provider/ResponseComparison.kt +++ b/provider/src/main/kotlin/au/com/dius/pact/provider/ResponseComparison.kt @@ -49,6 +49,43 @@ data class ComparisonResult( val metadataMismatches: Map> = emptyMap() ) +/** + * Interface to the utility class that provides the logic to compare responses + */ +interface IResponseComparison { + @Deprecated("Use version that takes pluginConfiguration parameter") + fun compareResponse( + response: IResponse, + actualResponse: ProviderResponse + ): ComparisonResult + + fun compareResponse( + response: IResponse, + actualResponse: ProviderResponse, + pluginConfiguration: Map + ): ComparisonResult + + @Deprecated("Use version that takes pluginConfiguration parameter") + fun compareMessage( + message: MessageInteraction, + actual: OptionalBody + ): ComparisonResult + + @Deprecated("Use version that takes pluginConfiguration parameter") + fun compareMessage( + message: MessageInteraction, + actual: OptionalBody, + metadata: Map? + ): ComparisonResult + + fun compareMessage( + message: MessageInteraction, + actual: OptionalBody, + metadata: Map?, + pluginConfiguration: Map + ): ComparisonResult +} + /** * Utility class to compare responses */ @@ -104,7 +141,7 @@ class ResponseComparison( } } - companion object : KLogging() { + companion object : KLogging(), IResponseComparison { private fun generateFullDiff( actual: String, contentType: ContentType, @@ -149,12 +186,19 @@ class ResponseComparison( } } - @JvmStatic - @JvmOverloads - fun compareResponse( + @Deprecated("Use version that takes pluginConfiguration parameter", ReplaceWith( + "compareResponse(response, actualResponse, emptyMap())", + "au.com.dius.pact.provider.ResponseComparison.Companion.compareResponse") + ) + override fun compareResponse( + response: IResponse, + actualResponse: ProviderResponse + ) = compareResponse(response, actualResponse, emptyMap()) + + override fun compareResponse( response: IResponse, actualResponse: ProviderResponse, - pluginConfiguration: Map = mapOf() + pluginConfiguration: Map ): ComparisonResult { val actualResponseContentType = actualResponse.contentType val comparison = ResponseComparison(response.headers, response.body, response.asHttpPart().jsonBody(), @@ -166,13 +210,26 @@ class ResponseComparison( comparison.bodyResult(mismatches, SystemPropertyResolver)) } - @JvmStatic - @JvmOverloads - fun compareMessage( + + @Deprecated("Use version that takes pluginConfiguration parameter", ReplaceWith( + "compareMessage(message, actual, null, pluginConfiguration)", + "au.com.dius.pact.provider.ResponseComparison.Companion.compareMessage") + ) + override fun compareMessage(message: MessageInteraction, actual: OptionalBody) = + compareMessage(message, actual, null, emptyMap()) + + @Deprecated("Use version that takes pluginConfiguration parameter", ReplaceWith( + "compareMessage(message, actual, metadata, pluginConfiguration)", + "au.com.dius.pact.provider.ResponseComparison.Companion.compareMessage") + ) + override fun compareMessage(message: MessageInteraction, actual: OptionalBody, metadata: Map?) = + compareMessage(message, actual, metadata, emptyMap()) + + override fun compareMessage( message: MessageInteraction, actual: OptionalBody, - metadata: Map? = null, - pluginConfiguration: Map = mapOf() + metadata: Map?, + pluginConfiguration: Map ): ComparisonResult { val (bodyMismatches, metadataMismatches) = when (message) { is V4Interaction.AsynchronousMessage -> { diff --git a/provider/src/test/groovy/au/com/dius/pact/provider/MessageComparisonSpec.groovy b/provider/src/test/groovy/au/com/dius/pact/provider/MessageComparisonSpec.groovy index 73419d00bd..2836b6d1b4 100644 --- a/provider/src/test/groovy/au/com/dius/pact/provider/MessageComparisonSpec.groovy +++ b/provider/src/test/groovy/au/com/dius/pact/provider/MessageComparisonSpec.groovy @@ -10,13 +10,15 @@ import spock.lang.Specification @SuppressWarnings('LineLength') class MessageComparisonSpec extends Specification { + def responseComparison = ResponseComparison.Companion.newInstance() + def 'compares the message contents as JSON'() { given: def message = new Message('test', [], OptionalBody.body('{"a":1,"b":"2"}'.bytes)) def actual = OptionalBody.body('{"a":1,"b":"3"}'.bytes) when: - def result = ResponseComparison.compareMessage(message, actual).bodyMismatches + def result = responseComparison.compareMessage(message, actual, null, [:]).bodyMismatches then: result instanceof Result.Ok @@ -32,7 +34,7 @@ class MessageComparisonSpec extends Specification { def actual = OptionalBody.body('{"a":1,"b":"3"}'.bytes) when: - def result = ResponseComparison.compareMessage(message, actual).bodyMismatches + def result = responseComparison.compareMessage(message, actual, null, [:]).bodyMismatches then: result instanceof Result.Ok @@ -54,7 +56,7 @@ class MessageComparisonSpec extends Specification { def actualMetadata = [destination: 'X002'] when: - def result = ResponseComparison.compareMessage(message, actual, actualMetadata).metadataMismatches.collectEntries { + def result = responseComparison.compareMessage(message, actual, actualMetadata, [:]).metadataMismatches.collectEntries { [ it.key, it.value*.description() ] } diff --git a/provider/src/test/groovy/au/com/dius/pact/provider/ProviderVerifierSpec.groovy b/provider/src/test/groovy/au/com/dius/pact/provider/ProviderVerifierSpec.groovy index 3a45661598..5dffa65e51 100644 --- a/provider/src/test/groovy/au/com/dius/pact/provider/ProviderVerifierSpec.groovy +++ b/provider/src/test/groovy/au/com/dius/pact/provider/ProviderVerifierSpec.groovy @@ -27,20 +27,25 @@ import au.com.dius.pact.core.model.matchingrules.MatchingRules import au.com.dius.pact.core.model.matchingrules.MatchingRulesImpl import au.com.dius.pact.core.model.matchingrules.RegexMatcher import au.com.dius.pact.core.model.messaging.Message +import au.com.dius.pact.core.model.messaging.MessageInteraction import au.com.dius.pact.core.model.v4.MessageContents import au.com.dius.pact.core.pactbroker.IPactBrokerClient import au.com.dius.pact.core.pactbroker.PactBrokerClient import au.com.dius.pact.core.pactbroker.TestResult import au.com.dius.pact.core.support.Result import au.com.dius.pact.core.support.expressions.SystemPropertyResolver +import au.com.dius.pact.core.support.json.JsonValue import au.com.dius.pact.provider.reporters.Event import au.com.dius.pact.provider.reporters.VerifierReporter import groovy.json.JsonOutput +import io.pact.plugins.jvm.core.PluginConfiguration import io.pact.plugins.jvm.core.PluginManager import spock.lang.Specification import spock.lang.Unroll import spock.util.environment.RestoreSystemProperties +import java.util.function.Function + @SuppressWarnings('UnnecessaryGetter') class ProviderVerifierSpec extends Specification { @@ -623,7 +628,7 @@ class ProviderVerifierSpec extends Specification { then: 1 * verifier.pactReader.loadPact(_) >> pact 1 * statechange.executeStateChange(_, _, _, _, _, _, _) >> new StateChangeResult(new Result.Ok([:]), '') - 1 * verifier.verifyResponseByInvokingProviderMethods(providerInfo, consumerInfo, interaction, _, _, false) >> new VerificationResult.Ok() + 1 * verifier.verifyResponseByInvokingProviderMethods(providerInfo, consumerInfo, interaction, _, _, false, _) >> new VerificationResult.Ok() 0 * client.publishVerificationResults(_, new TestResult.Ok(), _, _) } @@ -918,4 +923,31 @@ class ProviderVerifierSpec extends Specification { 1 * verifier.pluginManager.loadPlugin('a', '1.0') >> new Result.Ok(null) 1 * verifier.pluginManager.loadPlugin('b', '2.0') >> new Result.Ok(null) } + + def 'verifyMessage must pass through any plugin config to the content matcher'() { + given: + def failures = [:] + def pluginConfiguration = new PluginConfiguration( + [a: new JsonValue.Integer(100)], + [b: new JsonValue.Integer(100)] + ) + def config = [ + b: [a: new JsonValue.Integer(100)] + ] + def interaction = new V4Interaction.AsynchronousMessage(null, 'verifyMessage Test Message', + new MessageContents(), null, [], [:], false, config) + def interactionMessage = 'Test' + verifier.responseComparer = Mock(IResponseComparison) + def actual = OptionalBody.body('"Message Data"', ContentType.JSON) + Function messageFactory = { String desc -> '"Message Data"' } + + when: + def result = verifier.verifyMessage(messageFactory, interaction as MessageInteraction, + '', interactionMessage, failures, false, [b: pluginConfiguration]) + + then: + 1 * verifier.responseComparer.compareMessage(interaction, actual, null, [b: pluginConfiguration]) >> + new ComparisonResult() + result instanceof VerificationResult.Ok + } } diff --git a/provider/src/test/groovy/au/com/dius/pact/provider/ResponseComparisonSpec.groovy b/provider/src/test/groovy/au/com/dius/pact/provider/ResponseComparisonSpec.groovy index dfc33c9495..d6d6842ae6 100644 --- a/provider/src/test/groovy/au/com/dius/pact/provider/ResponseComparisonSpec.groovy +++ b/provider/src/test/groovy/au/com/dius/pact/provider/ResponseComparisonSpec.groovy @@ -34,8 +34,10 @@ class ResponseComparisonSpec extends Specification { def status = opts.actualStatus ?: actualStatus def response = opts.response ?: response def actualHeaders = opts.actualHeaders ?: actualHeaders - ResponseComparison.compareResponse(response, - new ProviderResponse(status, actualHeaders, ContentType.JSON, OptionalBody.body(actualBody.toString(), ContentType.JSON))) + ResponseComparison.Companion.newInstance().compareResponse(response, + new ProviderResponse(status, actualHeaders, ContentType.JSON, OptionalBody.body(actualBody.toString(), ContentType.JSON)), + [:] + ) } }