diff --git a/core/pactbroker/src/main/kotlin/au/com/dius/pact/core/pactbroker/PactBrokerClient.kt b/core/pactbroker/src/main/kotlin/au/com/dius/pact/core/pactbroker/PactBrokerClient.kt index 38c74e2b0c..b16c5ba3ea 100644 --- a/core/pactbroker/src/main/kotlin/au/com/dius/pact/core/pactbroker/PactBrokerClient.kt +++ b/core/pactbroker/src/main/kotlin/au/com/dius/pact/core/pactbroker/PactBrokerClient.kt @@ -105,7 +105,13 @@ sealed class Latest { /** * Model for a CanIDeploy result */ -data class CanIDeployResult(val ok: Boolean, val message: String, val reason: String, val unknown: Int? = null) +data class CanIDeployResult( + val ok: Boolean, + val message: String, + val reason: String, + val unknown: Int? = null, + val verificationResultUrl: String? = null +) /** * Consumer version selector. See https://docs.pact.io/pact_broker/advanced_topics/selectors @@ -806,8 +812,15 @@ open class PactBrokerClient( when (val result = halClient.getJson(path, false)) { is Ok -> { val summary: JsonValue.Object = result.value["summary"].downcast() + val verificationResultUrl = result.value["matrix"].asArray() + ?.get(0)?.asObject() + ?.get("verificationResult")?.asObject() + ?.get("_links")?.asObject() + ?.get("self")?.asObject() + ?.get("href") + ?.let{ url -> Json.toString(url) } CanIDeployResult(Json.toBoolean(summary["deployable"]), "", Json.toString(summary["reason"]), - Json.toInteger(summary["unknown"])) + Json.toInteger(summary["unknown"]), verificationResultUrl) } is Err -> { logger.error(result.error) { "Pact broker matrix query failed: ${result.error.message}" } diff --git a/core/pactbroker/src/test/groovy/au/com/dius/pact/core/pactbroker/PactBrokerClientSpec.groovy b/core/pactbroker/src/test/groovy/au/com/dius/pact/core/pactbroker/PactBrokerClientSpec.groovy index 041b6412e4..c5c70a7f6f 100644 --- a/core/pactbroker/src/test/groovy/au/com/dius/pact/core/pactbroker/PactBrokerClientSpec.groovy +++ b/core/pactbroker/src/test/groovy/au/com/dius/pact/core/pactbroker/PactBrokerClientSpec.groovy @@ -736,4 +736,39 @@ class PactBrokerClientSpec extends Specification { then: 1 * mockHalClient.postJson(PactBrokerClient.PUBLISH_CONTRACTS_LINK, [:], jsonBody) >> new Ok(new JsonValue.Object([:])) } + + @Issue('#1525') + def 'can-i-deploy - should return verificationResultUrl when there is one'() { + given: + def halClient = Mock(IHalClient) + def config = new PactBrokerClientConfig(10, 0) + PactBrokerClient client = Spy(PactBrokerClient, constructorArgs: ['baseUrl', [:], config]) { + newHalClient() >> halClient + } + def json = JsonParser.parseString(''' + |{ + | "summary": { + | "deployable": true, + | "reason": "some text", + | "unknown": 0 + | }, + | "matrix": [{ + | "verificationResult": { + | "_links": { + | "self": { + | "href": "verificationResultUrl" + | } + | } + | } + | }] + |}'''.stripMargin()) + + when: + def result = client.canIDeploy('test', '1.2.3', new Latest.UseLatest(true), '') + + then: + 1 * halClient.getJson(_, _) >> new Ok(json) + result.ok + result.verificationResultUrl == 'verificationResultUrl' + } } diff --git a/provider/gradle/src/main/groovy/au/com/dius/pact/provider/gradle/PactCanIDeployTask.groovy b/provider/gradle/src/main/groovy/au/com/dius/pact/provider/gradle/PactCanIDeployTask.groovy index 45d280a9eb..a6c18d8808 100644 --- a/provider/gradle/src/main/groovy/au/com/dius/pact/provider/gradle/PactCanIDeployTask.groovy +++ b/provider/gradle/src/main/groovy/au/com/dius/pact/provider/gradle/PactCanIDeployTask.groovy @@ -58,6 +58,10 @@ class PactCanIDeployTask extends PactCanIDeployBaseTask { println("Computer says no ¯\\_(ツ)_/¯ ${result.message}\n\n${t.red.invoke(result.reason)}") } + if (result.verificationResultUrl != null) { + println("VERIFICATION RESULTS\n--------------------\n1. ${result.verificationResultUrl}\n") + } + if (!result.ok) { throw new GradleScriptException("Can you deploy? Computer says no ¯\\_(ツ)_/¯ ${result.message}", null) } diff --git a/provider/gradle/src/test/groovy/au/com/dius/pact/provider/gradle/PactCanIDeployTaskSpec.groovy b/provider/gradle/src/test/groovy/au/com/dius/pact/provider/gradle/PactCanIDeployTaskSpec.groovy index e0e21f1e1e..9c8533e2ff 100644 --- a/provider/gradle/src/test/groovy/au/com/dius/pact/provider/gradle/PactCanIDeployTaskSpec.groovy +++ b/provider/gradle/src/test/groovy/au/com/dius/pact/provider/gradle/PactCanIDeployTaskSpec.groovy @@ -76,7 +76,7 @@ class PactCanIDeployTaskSpec extends Specification { project.evaluate() task.brokerClient = Mock(PactBrokerClient) { - canIDeploy(_, _, _, _, _) >> new CanIDeployResult(true, '', '', null) + canIDeploy(_, _, _, _, _) >> new CanIDeployResult(true, '', '', null, null) } when: @@ -105,7 +105,31 @@ class PactCanIDeployTaskSpec extends Specification { then: notThrown(GradleScriptException) 1 * task.brokerClient.canIDeploy('pacticipant', '1.0.0', _, _, _) >> - new CanIDeployResult(true, '', '', null) + new CanIDeployResult(true, '', '', null, null) + } + + def 'prints verification results url when pact broker client returns one'() { + given: + project.pact { + broker { + pactBrokerUrl = 'pactBrokerUrl' + } + } + project.ext.pacticipant = 'pacticipant' + project.ext.pacticipantVersion = '1.0.0' + project.ext.latest = 'true' + project.ext.toTag = 'prod' + project.evaluate() + + task.brokerClient = Mock(PactBrokerClient) + + when: + task.canIDeploy() + + then: + notThrown(GradleScriptException) + 1 * task.brokerClient.canIDeploy('pacticipant', '1.0.0', + new Latest.UseLatest(true), 'prod', _) >> new CanIDeployResult(true, '', '', null, 'verificationResultUrl') } def 'passes optional parameters to the pact broker client'() { @@ -129,7 +153,7 @@ class PactCanIDeployTaskSpec extends Specification { then: notThrown(GradleScriptException) 1 * task.brokerClient.canIDeploy('pacticipant', '1.0.0', - new Latest.UseLatest(true), 'prod', _) >> new CanIDeployResult(true, '', '', null) + new Latest.UseLatest(true), 'prod', _) >> new CanIDeployResult(true, '', '', null, null) } def 'throws an exception if the pact broker client says no'() { @@ -150,7 +174,7 @@ class PactCanIDeployTaskSpec extends Specification { then: 1 * task.brokerClient.canIDeploy('pacticipant', '1.0.0', _, _, _) >> - new CanIDeployResult(false, 'Bad version', 'Bad version', null) + new CanIDeployResult(false, 'Bad version', 'Bad version', null, null) def ex = thrown(GradleScriptException) ex.message == 'Can you deploy? Computer says no ¯\\_(ツ)_/¯ Bad version' } diff --git a/provider/maven/src/main/kotlin/au/com/dius/pact/provider/maven/PactCanIDeployMojo.kt b/provider/maven/src/main/kotlin/au/com/dius/pact/provider/maven/PactCanIDeployMojo.kt index 65dda8d7da..d21eff07ea 100644 --- a/provider/maven/src/main/kotlin/au/com/dius/pact/provider/maven/PactCanIDeployMojo.kt +++ b/provider/maven/src/main/kotlin/au/com/dius/pact/provider/maven/PactCanIDeployMojo.kt @@ -59,6 +59,10 @@ open class PactCanIDeployMojo : PactBaseMojo() { println("Computer says no ¯\\_(ツ)_/¯ ${result.message}\n\n${t.red(result.reason)}") } + if (result.verificationResultUrl != null) { + println("VERIFICATION RESULTS\n--------------------\n1. ${result.verificationResultUrl}\n") + } + if (!result.ok) { throw MojoExecutionException("Can you deploy? Computer says no ¯\\_(ツ)_/¯ ${result.message}", null) } diff --git a/provider/maven/src/test/groovy/au/com/dius/pact/provider/maven/PactCanIDeployMojoSpec.groovy b/provider/maven/src/test/groovy/au/com/dius/pact/provider/maven/PactCanIDeployMojoSpec.groovy index 1dfa945c2e..560cf26163 100644 --- a/provider/maven/src/test/groovy/au/com/dius/pact/provider/maven/PactCanIDeployMojoSpec.groovy +++ b/provider/maven/src/test/groovy/au/com/dius/pact/provider/maven/PactCanIDeployMojoSpec.groovy @@ -59,7 +59,7 @@ class PactCanIDeployMojoSpec extends Specification { mojo.pacticipantVersion = null mojo.latest = 'true' mojo.brokerClient = Mock(PactBrokerClient) { - canIDeploy(_, _, _, _, _) >> new CanIDeployResult(true, '', '', null) + canIDeploy(_, _, _, _, _) >> new CanIDeployResult(true, '', '', null, null) } when: @@ -79,7 +79,7 @@ class PactCanIDeployMojoSpec extends Specification { then: notThrown(MojoExecutionException) 1 * mojo.brokerClient.canIDeploy('test', '1234', _, _, _) >> - new CanIDeployResult(true, '', '', null) + new CanIDeployResult(true, '', '', null, null) } def 'passes optional parameters to the pact broker client'() { @@ -94,7 +94,7 @@ class PactCanIDeployMojoSpec extends Specification { then: notThrown(MojoExecutionException) 1 * mojo.brokerClient.canIDeploy('test', '1234', - new Latest.UseLatest(true), 'prod', _) >> new CanIDeployResult(true, '', '', null) + new Latest.UseLatest(true), 'prod', _) >> new CanIDeployResult(true, '', '', null, null) } def 'passes ignore parameters to the pact broker client'() { @@ -110,7 +110,23 @@ class PactCanIDeployMojoSpec extends Specification { then: notThrown(MojoExecutionException) 1 * mojo.brokerClient.canIDeploy('test', '1234', - new Latest.UseLatest(true), '', selectors) >> new CanIDeployResult(true, '', '', null) + new Latest.UseLatest(true), '', selectors) >> new CanIDeployResult(true, '', '', null, null) + } + + def 'prints verification results url when pact broker client returns one'() { + given: + IgnoreSelector[] selectors = [new IgnoreSelector('bob')] as IgnoreSelector[] + mojo.latest = 'true' + mojo.ignore = selectors + mojo.brokerClient = Mock(PactBrokerClient) + + when: + mojo.execute() + + then: + notThrown(MojoExecutionException) + 1 * mojo.brokerClient.canIDeploy('test', '1234', + new Latest.UseLatest(true), '', selectors) >> new CanIDeployResult(true, '', '', null, "verificationResultUrl") } def 'throws an exception if the pact broker client says no'() { @@ -122,7 +138,7 @@ class PactCanIDeployMojoSpec extends Specification { then: 1 * mojo.brokerClient.canIDeploy('test', '1234', _, _, _) >> - new CanIDeployResult(false, 'Bad version', 'Bad version', null) + new CanIDeployResult(false, 'Bad version', 'Bad version', null, null) def ex = thrown(MojoExecutionException) ex.message == 'Can you deploy? Computer says no ¯\\_(ツ)_/¯ Bad version' }