From 12e61702831cb8449e2f13914bf7f673850a6009 Mon Sep 17 00:00:00 2001 From: onikytchuk Date: Thu, 10 May 2018 09:23:13 +0300 Subject: [PATCH 1/2] [#584] Added inclusion configuration 'includeFiles' that allow producers to filter common repository structure and define the list of messaging topics that would be processed during the tests autogeneration. --- docs/src/main/asciidoc/verifier_faq.adoc | 105 ++++-------------- .../converter/RecursiveFilesConverter.groovy | 2 +- .../maven/verifier/GenerateTestsMojo.java | 7 ++ .../maven/verifier/PluginUnitTest.java | 15 +++ .../pom.xml | 61 ++++++++++ .../java/com/example/services/TestBase.java | 30 +++++ .../contracts-0.0.1-SNAPSHOT.pom | 25 +++++ .../1.0.4-SNAPSHOT/maven-metadata-local.xml | 24 ++++ .../services-contracts-1.0.4-SNAPSHOT.jar | Bin 0 -> 15718 bytes .../services-contracts-1.0.4-SNAPSHOT.pom | 25 +++++ .../services-contracts/maven-metadata.xml | 28 +++++ .../contract/verifier/TestGenerator.groovy | 1 + .../ContractVerifierConfigProperties.groovy | 5 + .../verifier/file/ContractFileScanner.groovy | 7 +- .../file/ContractFileScannerSpec.groovy | 26 ++++- .../messaging/couponCollectedEventV1.groovy | 27 +++++ .../messaging/couponCollectedEventV2.groovy | 27 +++++ .../messaging/couponSentEventSm.groovy | 27 +++++ .../admin/v1/shouldReturnBetRanges.groovy | 38 +++++++ ...uldReturnEmptyFriendsWhenGetFriends.groovy | 30 +++++ .../rest/shouldUpdateUserInfo.groovy | 44 ++++++++ 21 files changed, 464 insertions(+), 90 deletions(-) create mode 100644 spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/complex-common-repo-with-messaging/pom.xml create mode 100644 spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/complex-common-repo-with-messaging/src/test/java/com/example/services/TestBase.java create mode 100644 spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/contracts/1.0.4-SNAPSHOT/contracts-0.0.1-SNAPSHOT.pom create mode 100644 spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/1.0.4-SNAPSHOT/maven-metadata-local.xml create mode 100644 spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/1.0.4-SNAPSHOT/services-contracts-1.0.4-SNAPSHOT.jar create mode 100644 spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/1.0.4-SNAPSHOT/services-contracts-1.0.4-SNAPSHOT.pom create mode 100644 spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/maven-metadata.xml create mode 100644 spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/kafka-topics/coupon-collected/src/main/resources/contracts/rule-engine-daemon/messaging/couponCollectedEventV1.groovy create mode 100644 spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/kafka-topics/coupon-collected/src/main/resources/contracts/rule-engine-daemon/messaging/couponCollectedEventV2.groovy create mode 100644 spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/kafka-topics/coupon-sent/src/main/resources/contracts/rule-engine-daemon/messaging/couponSentEventSm.groovy create mode 100644 spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/reward-rules/src/main/resources/contracts/reward_rules/rest/admin/v1/shouldReturnBetRanges.groovy create mode 100644 spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/social-service/src/main/resources/contracts/coupons_new_backend/rest/shouldReturnEmptyFriendsWhenGetFriends.groovy create mode 100644 spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/social-service/src/main/resources/contracts/facebook_client/rest/shouldUpdateUserInfo.groovy diff --git a/docs/src/main/asciidoc/verifier_faq.adoc b/docs/src/main/asciidoc/verifier_faq.adoc index a15f8f8170..a452084e34 100644 --- a/docs/src/main/asciidoc/verifier_faq.adoc +++ b/docs/src/main/asciidoc/verifier_faq.adoc @@ -344,84 +344,10 @@ contracts in the folder per topic. ===== For Maven Project -To make it possible to work on the producer side we could do the following things (all via Maven plugins): +To make it possible to work on the producer side we should specify an inclusion pattern for +filtering common repository jar by messaging topics we are interested in. ```includedFiles``` property of ```Maven Spring Cloud Contract plugin``` +allows us to do that. Also ```contractsPath``` need to be specified since the default path would be the common repository ```groupid/artifactid```. -- Add common repo dependency to your classpath: - -[source,xml,indent=0] ----- - - com.example - common-repo - ${common-repo.version} - ----- - -- Download the JAR with the contracts and unpack the JAR to target: - -[source,xml,indent=0] ----- - - org.apache.maven.plugins - maven-dependency-plugin - 3.0.0 - - - unpack-dependencies - process-resources - - unpack - - - - - com.example - common-repo - jar - false - ${project.build.directory}/contracts - - - - - - ----- - -- Rip out all the folders we're not interested in: - -[source,xml,indent=0] ----- - - org.apache.maven.plugins - maven-antrun-plugin - 1.8 - - - process-resources - - run - - - - - - - - - - - - - - - - - - ----- - -- Run the contract plugin by pointing to the contracts to the folder under target: [source,xml,indent=0] ---- @@ -429,19 +355,32 @@ To make it possible to work on the producer side we could do the following thing org.springframework.cloud spring-cloud-contract-maven-plugin ${spring-cloud-contract.version} - true - com.example + REMOTE + http://link/to/your/nexus/or/artifactory/or/sth + + com.example + common-repo-with-contracts + + + + / - .*intoxication.* - com.example.intoxication.BeerIntoxicationBase + .*messaging.* + com.example.services.MessagingBase + + + .*rest.* + com.example.services.TestBase - ${project.build.directory}/contracts + + **/${project.artifactId}/** + **/${first-topic}/** + **/${second-topic}/** + ----- ===== For Gradle Project diff --git a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverter.groovy b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverter.groovy index 043002d9c7..1dbfad196b 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverter.groovy +++ b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverter.groovy @@ -58,7 +58,7 @@ class RecursiveFilesConverter { void processFiles() { ContractFileScanner scanner = new ContractFileScanner(properties.contractsDslDir, - properties.excludedFiles as Set, [] as Set, properties.includedContracts) + properties.excludedFiles as Set, [] as Set, [] as Set, properties.includedContracts) ListMultimap contracts = scanner.findContracts() if (log.isDebugEnabled()) { log.debug("Found the following contracts $contracts") diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/GenerateTestsMojo.java b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/GenerateTestsMojo.java index 4c466b7405..61544d6ec8 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/GenerateTestsMojo.java +++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/GenerateTestsMojo.java @@ -96,6 +96,12 @@ public class GenerateTestsMojo extends AbstractMojo { @Parameter private List excludedFiles; + /** + * Patterns that should be taken into account for processing + */ + @Parameter(property = "includedFiles") + private List includedFiles; + /** * Incubating feature. You can check the size of JSON arrays. If not turned on * explicitly will be disabled. @@ -277,6 +283,7 @@ public class GenerateTestsMojo extends AbstractMojo { config.setStaticImports(this.staticImports); config.setIgnoredFiles(this.ignoredFiles); config.setExcludedFiles(this.excludedFiles); + config.setIncludedFiles(this.includedFiles); config.setAssertJsonSize(this.assertJsonSize); config.setPackageWithBaseClasses(this.packageWithBaseClasses); if (this.baseClassMappings != null) { diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/java/org/springframework/cloud/contract/maven/verifier/PluginUnitTest.java b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/java/org/springframework/cloud/contract/maven/verifier/PluginUnitTest.java index 54beac401b..70fa7c69bc 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/java/org/springframework/cloud/contract/maven/verifier/PluginUnitTest.java +++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/java/org/springframework/cloud/contract/maven/verifier/PluginUnitTest.java @@ -305,4 +305,19 @@ public class PluginUnitTest { then(this.capture.toString()).contains("Skipping pushing stubs to scm since your"); } + + @Test + public void shouldGenerateContractTestsForIncludedFilesPattern() throws Exception { + File basedir = this.resources.getBasedir("complex-common-repo-with-messaging"); + + this.maven.executeMojo(basedir, "generateTests", defaultPackageForTests(), + newParameter("contractsRepositoryUrl", + "file://" + PluginUnitTest.class.getClassLoader() + .getResource("m2repo/repository").getFile() + .replace("/", File.separator))); + assertFilesPresent(basedir, + "target/generated-test-sources/contracts/org/springframework/cloud/contract/verifier/tests/common_repo_with_inclusion/kafka_topics/coupon_sent/src/main/resources/contracts/rule_engine_daemon/MessagingTest.java"); + assertFilesPresent(basedir, + "target/generated-test-sources/contracts/org/springframework/cloud/contract/verifier/tests/common_repo_with_inclusion/reward_rules/src/main/resources/contracts/reward_rules/rest/admin/V1Test.java"); + } } diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/complex-common-repo-with-messaging/pom.xml b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/complex-common-repo-with-messaging/pom.xml new file mode 100644 index 0000000000..6c71dbfd26 --- /dev/null +++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/complex-common-repo-with-messaging/pom.xml @@ -0,0 +1,61 @@ + + + + 4.0.0 + + com.example + social-service + 0.1.BUILD-SNAPSHOT + + + + + org.springframework.cloud + spring-cloud-contract-maven-plugin + 2.0.0.BUILD-SNAPSHOT + + REMOTE + + com.example + services-contracts + + + + / + + + .*messaging.* + com.example.services.TestBase + + + .*rest.* + com.example.services.TestBase + + + + **/coupon-sent/** + **/reward-rules/** + + + + + + + \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/complex-common-repo-with-messaging/src/test/java/com/example/services/TestBase.java b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/complex-common-repo-with-messaging/src/test/java/com/example/services/TestBase.java new file mode 100644 index 0000000000..0ad45b3dcf --- /dev/null +++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/complex-common-repo-with-messaging/src/test/java/com/example/services/TestBase.java @@ -0,0 +1,30 @@ +/** + * + * Copyright 2013-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.services; + +import io.restassured.module.mockmvc.RestAssuredMockMvc; + +import org.junit.Before; + +public class TestBase { + + @Before + public void setup() { + RestAssuredMockMvc.standaloneSetup(new FraudDetectionController()); + } + +} \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/contracts/1.0.4-SNAPSHOT/contracts-0.0.1-SNAPSHOT.pom b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/contracts/1.0.4-SNAPSHOT/contracts-0.0.1-SNAPSHOT.pom new file mode 100644 index 0000000000..1369bcaf20 --- /dev/null +++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/contracts/1.0.4-SNAPSHOT/contracts-0.0.1-SNAPSHOT.pom @@ -0,0 +1,25 @@ + + + + + 4.0.0 + com.example + contracts + 0.0.1-SNAPSHOT + pom + diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/1.0.4-SNAPSHOT/maven-metadata-local.xml b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/1.0.4-SNAPSHOT/maven-metadata-local.xml new file mode 100644 index 0000000000..5b45432a6e --- /dev/null +++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/1.0.4-SNAPSHOT/maven-metadata-local.xml @@ -0,0 +1,24 @@ + + + com.example + services-contracts + 1.0.4-SNAPSHOT + + + true + + 20160916125313 + + + jar + 1.0.4-SNAPSHOT + 20160916125313 + + + pom + 1.0.4-SNAPSHOT + 20160916125313 + + + + diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/1.0.4-SNAPSHOT/services-contracts-1.0.4-SNAPSHOT.jar b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/1.0.4-SNAPSHOT/services-contracts-1.0.4-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..54c268d26c3bea4ea8dc2102758ec53352294585 GIT binary patch literal 15718 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 L(Ks%#ZT$Ctm)=;) literal 0 HcmV?d00001 diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/1.0.4-SNAPSHOT/services-contracts-1.0.4-SNAPSHOT.pom b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/1.0.4-SNAPSHOT/services-contracts-1.0.4-SNAPSHOT.pom new file mode 100644 index 0000000000..a807f11aac --- /dev/null +++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/1.0.4-SNAPSHOT/services-contracts-1.0.4-SNAPSHOT.pom @@ -0,0 +1,25 @@ + + + + + 4.0.0 + com.example + services-contracts + 1.0.4-SNAPSHOT + pom + diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/maven-metadata.xml b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/maven-metadata.xml new file mode 100644 index 0000000000..278b59b02a --- /dev/null +++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/maven-metadata.xml @@ -0,0 +1,28 @@ + + + + + com.example + services-contracts + 1.0.4-SNAPSHOT + + + 1.0.4-SNAPSHOT + + 20160409062112 + + diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy index df4ef6d63e..caa431b732 100755 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy @@ -77,6 +77,7 @@ class TestGenerator { contractFileScanner = new ContractFileScanner(configProperties.contractsDslDir, configProperties.excludedFiles as Set, configProperties.ignoredFiles as Set, + configProperties.includedFiles as Set, this.configProperties.includedContracts) } diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy index 7093690e8f..60985f17ac 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy @@ -60,6 +60,11 @@ class ContractVerifierConfigProperties { */ List excludedFiles = [] + /** + * Patterns that should be taken into account for processing + */ + List includedFiles = [] + /** * Patterns for which generated tests should be @Ignored */ diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScanner.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScanner.groovy index 8ca4be4e25..b3fa7f506c 100755 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScanner.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScanner.groovy @@ -52,12 +52,14 @@ class ContractFileScanner { private final File baseDir private final Set excludeMatchers private final Set ignoreMatchers + private final Set includeMatchers private final String includeMatcher - ContractFileScanner(File baseDir, Set excluded, Set ignored, String includeMatcher = "") { + ContractFileScanner(File baseDir, Set excluded, Set ignored, Set included, String includeMatcher = "") { this.baseDir = baseDir this.excludeMatchers = processPatterns(excluded ?: [] as Set) this.ignoreMatchers = processPatterns(ignored ?: [] as Set) + this.includeMatchers = processPatterns(included ?: [] as Set) this.includeMatcher = includeMatcher } @@ -101,7 +103,8 @@ class ContractFileScanner { boolean excluded = matchesPattern(file, excludeMatchers) if (!excluded) { boolean contractFile = isContractFile(file) - boolean included = includeMatcher ? file.absolutePath.matches(includeMatcher) : true + boolean included = includeMatcher ? file.absolutePath.matches(includeMatcher) : true + included = includeMatchers ? matchesPattern(file, includeMatchers) : included if (contractFile && included) { addContractToTestGeneration(result, files, file, i, ContractVerifierDslConverter.convertAsCollection(baseDir, file)) } else if (YamlContractConverter.INSTANCE.isAccepted(file) && included) { diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScannerSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScannerSpec.groovy index d4ee0cdf48..7e76f1d7b3 100644 --- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScannerSpec.groovy +++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScannerSpec.groovy @@ -34,7 +34,7 @@ class ContractFileScannerSpec extends Specification { File baseDir = new File(this.getClass().getResource("/directory/with/stubs").toURI()) Set excluded = ["package/**"] as Set Set ignored = ["other/different/**"] as Set - ContractFileScanner scanner = new ContractFileScanner(baseDir, excluded, ignored) + ContractFileScanner scanner = new ContractFileScanner(baseDir, excluded, ignored, [] as Set) when: ListMultimap result = scanner.findContracts() then: @@ -52,7 +52,7 @@ class ContractFileScannerSpec extends Specification { File baseDir = new File(this.getClass().getResource("/strange_[3.3.3]_directory").toURI()) Set excluded = ["foo/**"] as Set Set ignored = ["bar/**"] as Set - ContractFileScanner scanner = new ContractFileScanner(baseDir, excluded, ignored) + ContractFileScanner scanner = new ContractFileScanner(baseDir, excluded, ignored, [] as Set) when: ListMultimap result = scanner.findContracts() then: @@ -66,7 +66,7 @@ class ContractFileScannerSpec extends Specification { def "should find contracts group in scenario"() { given: File baseDir = new File(this.getClass().getResource("/directory/with/scenario").toURI()) - ContractFileScanner scanner = new ContractFileScanner(baseDir, [] as Set, [] as Set) + ContractFileScanner scanner = new ContractFileScanner(baseDir, [] as Set, [] as Set, [] as Set) when: ListMultimap contracts = scanner.findContracts() then: @@ -80,7 +80,7 @@ class ContractFileScannerSpec extends Specification { def "should find contract files with converters"() { given: File baseDir = new File(this.getClass().getResource("/directory/with/mixed").toURI()) - ContractFileScanner scanner = new ContractFileScanner(baseDir, null, null) { + ContractFileScanner scanner = new ContractFileScanner(baseDir, null, null, null) { @Override protected List converters() { return [new ContractConverter() { @@ -108,4 +108,22 @@ class ContractFileScannerSpec extends Specification { result.entries().every { it.value.convertedContract } result.entries().find { it.value.convertedContract.any { it.request.method.clientValue == "PUT" } } } + + def "should find contracts for include pattern"() { + given: + File baseDir = new File(this.getClass().getResource("/directory/with/common-messaging").toURI()) + Set included = ["social-service/**","**/coupon-collected/**/*V1*"] as Set + ContractFileScanner scanner = new ContractFileScanner(baseDir, [] as Set, [] as Set, included) + when: + ListMultimap result = scanner.findContracts() + then: + result.keySet().size() == 3 + result.values().find { (it.path.fileName.toString() == 'couponCollectedEventV1.groovy') }.groupSize==2 + result.values().find { (it.convertedContract.first().label == 'couponCollectedV1') } + result.values().findAll { (it.path.fileName.toString() == 'couponCollectedEventV2.groovy') }.isEmpty() + result.values().find { (it.path.fileName.toString() == 'shouldUpdateUserInfo.groovy') }.groupSize==1 + result.values().find { (it.path.fileName.toString() == 'shouldReturnEmptyFriendsWhenGetFriends.groovy') }.groupSize==1 + result.get(baseDir.toPath().resolve("coupon-sent")).size() == 0 + result.get(baseDir.toPath().resolve("reward-rules")).size() == 0 + } } diff --git a/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/kafka-topics/coupon-collected/src/main/resources/contracts/rule-engine-daemon/messaging/couponCollectedEventV1.groovy b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/kafka-topics/coupon-collected/src/main/resources/contracts/rule-engine-daemon/messaging/couponCollectedEventV1.groovy new file mode 100644 index 0000000000..b61731fbcf --- /dev/null +++ b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/kafka-topics/coupon-collected/src/main/resources/contracts/rule-engine-daemon/messaging/couponCollectedEventV1.groovy @@ -0,0 +1,27 @@ +import org.springframework.cloud.contract.spec.Contract + +Contract.make { + + description("""Should send a message in topic coupon_collected""") + + label 'couponCollectedV1' + + input { + triggeredBy('couponCollectedSm()') + } + + outputMessage { + sentTo('coupon_collected') + + body([ + receiverSnId: value(consumer("receiver-sn-id"), producer(regex('([^\\W]|-)+'))), + sessionId: value(consumer(7928568413097907541), producer(regex('\\d+'))), + createdTs: value(consumer(1504688949158), producer(regex('\\d+'))), + couponToken: value(consumer("440006-6-1504688949139-xyuzzrx5"), producer(regex('([^\\W]|-)+'))) + ]) + + headers { + messagingContentType(applicationJsonUtf8()) + } + } +} \ No newline at end of file diff --git a/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/kafka-topics/coupon-collected/src/main/resources/contracts/rule-engine-daemon/messaging/couponCollectedEventV2.groovy b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/kafka-topics/coupon-collected/src/main/resources/contracts/rule-engine-daemon/messaging/couponCollectedEventV2.groovy new file mode 100644 index 0000000000..529f1c93f7 --- /dev/null +++ b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/kafka-topics/coupon-collected/src/main/resources/contracts/rule-engine-daemon/messaging/couponCollectedEventV2.groovy @@ -0,0 +1,27 @@ +import org.springframework.cloud.contract.spec.Contract + +Contract.make { + + description("""Should send a message in topic coupon_collected""") + + label 'couponCollectedSm' + + input { + triggeredBy('couponCollectedSm()') + } + + outputMessage { + sentTo('coupon_collected') + + body([ + receiverSnId: value(consumer("receiver-sn-id"), producer(regex('([^\\W]|-)+'))), + sessionId: value(consumer(7928568413097907541), producer(regex('\\d+'))), + createdTs: value(consumer(1504688949158), producer(regex('\\d+'))), + couponToken: value(consumer("440006-6-1504688949139-xyuzzrx5"), producer(regex('([^\\W]|-)+'))) + ]) + + headers { + messagingContentType(applicationJsonUtf8()) + } + } +} \ No newline at end of file diff --git a/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/kafka-topics/coupon-sent/src/main/resources/contracts/rule-engine-daemon/messaging/couponSentEventSm.groovy b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/kafka-topics/coupon-sent/src/main/resources/contracts/rule-engine-daemon/messaging/couponSentEventSm.groovy new file mode 100644 index 0000000000..24772ce212 --- /dev/null +++ b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/kafka-topics/coupon-sent/src/main/resources/contracts/rule-engine-daemon/messaging/couponSentEventSm.groovy @@ -0,0 +1,27 @@ +import org.springframework.cloud.contract.spec.Contract + +Contract.make { + + description("""Should send a message in topic coupon_sent""") + + label 'couponSentSm' + + input { + triggeredBy('couponSentSm()') + } + + outputMessage { + sentTo('coupon_sent') + + body([ + senderUserId: value(consumer(123), producer(regex('\\d+'))), + sessionId: value(consumer(7928568413097907541), producer(regex('\\d+'))), + createdTs: value(consumer(1504688949158), producer(regex('\\d+'))), + couponToken: value(consumer("440006-6-1504688949139-xyuzzrx5"), producer(regex('([^\\W]|-)+'))) + ]) + + headers { + messagingContentType(applicationJsonUtf8()) + } + } +} \ No newline at end of file diff --git a/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/reward-rules/src/main/resources/contracts/reward_rules/rest/admin/v1/shouldReturnBetRanges.groovy b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/reward-rules/src/main/resources/contracts/reward_rules/rest/admin/v1/shouldReturnBetRanges.groovy new file mode 100644 index 0000000000..f70af82308 --- /dev/null +++ b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/reward-rules/src/main/resources/contracts/reward_rules/rest/admin/v1/shouldReturnBetRanges.groovy @@ -0,0 +1,38 @@ +import org.springframework.cloud.contract.spec.Contract + +Contract.make { + description('Should return bet ranges array') + request { + method 'GET' + url('/admin/v1/spin/betRanges') + } + + response { + status 200 + body( + betRanges: [ + [ + betRangeId : 3, + fromBetPercent: -1 + ], + [ + betRangeId : 4, + fromBetPercent: 0 + ], + [ + betRangeId : 1, + fromBetPercent: 90 + ], + [ + betRangeId : 2, + fromBetPercent: 130 + ] + ] + ) + + headers { + contentType(applicationJsonUtf8()) + } + } +} + diff --git a/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/social-service/src/main/resources/contracts/coupons_new_backend/rest/shouldReturnEmptyFriendsWhenGetFriends.groovy b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/social-service/src/main/resources/contracts/coupons_new_backend/rest/shouldReturnEmptyFriendsWhenGetFriends.groovy new file mode 100644 index 0000000000..5c33f16f4f --- /dev/null +++ b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/social-service/src/main/resources/contracts/coupons_new_backend/rest/shouldReturnEmptyFriendsWhenGetFriends.groovy @@ -0,0 +1,30 @@ +import org.springframework.cloud.contract.spec.Contract + +Contract.make { + description(""" +Should return empty array if user has no friends +""") + request { + method 'GET' + urlPath('/SocialServer/social/getFriends') + url('/social/getFriends') { + queryParameters { + parameter 'snId': $(consumer(regex('([^\\W]|-)+')), producer('12345')) + parameter 'snType': $(consumer(regex('\\d+')), producer(2)) + } + } + } + + response { + status 200 + body( + """ + {"friends" : []} + """) + + headers { + contentType(applicationJsonUtf8()) + } + } +} + diff --git a/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/social-service/src/main/resources/contracts/facebook_client/rest/shouldUpdateUserInfo.groovy b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/social-service/src/main/resources/contracts/facebook_client/rest/shouldUpdateUserInfo.groovy new file mode 100644 index 0000000000..411bbe2496 --- /dev/null +++ b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/social-service/src/main/resources/contracts/facebook_client/rest/shouldUpdateUserInfo.groovy @@ -0,0 +1,44 @@ +import org.springframework.cloud.contract.spec.Contract + +Contract.make { + description(""" +User's information should be update if has appropriate age +""") + request { + method 'POST' + url '/test/updateUserInfo' + body([ + userId: 123, + age: 25, + firstName: "asd", + lastName: "asd" + ]) + stubMatchers { + jsonPath('$.userId', byRegex("[1-9]{1}([0-9]{7})")) + jsonPath('$.age', byRegex("(1[89]|[2-9][0-9])")) + jsonPath('$.firstName', byRegex("[a-zA-Z]{2,20}")) + jsonPath('$.lastName', byRegex("[a-zA-Z]{2,20}")) + } + headers { + contentType(applicationJson()) + } + } + response { + status 200 + body([ + userId: fromRequest().body("userId"), + age: fromRequest().body("age"), + firstName: fromRequest().body("firstName"), + lastName: fromRequest().body("lastName") + ]) + testMatchers { + jsonPath('$.userId', byEquality()) + jsonPath('$.age', byEquality()) + jsonPath('$.firstName', byEquality()) + jsonPath('$.lastName', byEquality()) + } + headers { + contentType(applicationJson()) + } + } +} \ No newline at end of file From 544c1d8a42c70819c6a1879ecee1deacb7155b8b Mon Sep 17 00:00:00 2001 From: onikytchuk Date: Thu, 10 May 2018 11:24:01 +0300 Subject: [PATCH 2/2] Fixed docs issue --- docs/src/main/asciidoc/verifier_faq.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/src/main/asciidoc/verifier_faq.adoc b/docs/src/main/asciidoc/verifier_faq.adoc index a452084e34..8a1ca14d3e 100644 --- a/docs/src/main/asciidoc/verifier_faq.adoc +++ b/docs/src/main/asciidoc/verifier_faq.adoc @@ -381,6 +381,7 @@ allows us to do that. Also ```contractsPath``` need to be specified since the de +---- ===== For Gradle Project