diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0f53b93c7..48acb8e82 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -112,6 +112,24 @@ jobs: env: PACTFLOW_PACT_FOUNDATION_TOKEN: ${{ secrets.PACTFLOW_PACT_FOUNDATION_TOKEN }} + pact-v2-verify: + runs-on: "ubuntu-latest" + strategy: + matrix: + pact_url: + - "https://raw.githubusercontent.com/pact-foundation/pact_broker-client/refs/heads/master/spec/pacts/Pact%20Broker%20Client%20V2-Pact%20Broker.json" + - "https://raw.githubusercontent.com/pact-foundation/pact_broker-client/refs/heads/master/spec/pacts/pact_broker_client-pact_broker.json" + steps: + - uses: actions/checkout@v4 + - uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + - run: bundle install + - name: Verify pacts + env: + PACT_URL: ${{ matrix.pact_url }} + run: "PACT_URL=${PACT_URL} bundle exec rake pact:v2:verify" + bundle-audit: runs-on: "ubuntu-latest" steps: diff --git a/Gemfile b/Gemfile index 621572a08..d27d1bd36 100644 --- a/Gemfile +++ b/Gemfile @@ -21,7 +21,13 @@ end group :test do gem "simplecov", :require => false - gem "pact", "~>1.14" + if ENV["X_PACT_DEVELOPMENT"] == "true" + gem "pact", path: "../pact-ruby" + gem "pact-ffi", path: "../pact-ruby-ffi" + else + gem "pact", "~>1.14" + gem "pact-ffi", "~>0.4.28" + end gem "rspec-pact-matchers", "~>0.1" gem "bundler-audit", "~>0.4" gem "webmock", "~>3.9" diff --git a/spec/fixtures/approvals/get_provider_pacts_for_verification.approved.json b/spec/fixtures/approvals/get_provider_pacts_for_verification.approved.json index 9681ce180..19c04d79d 100644 --- a/spec/fixtures/approvals/get_provider_pacts_for_verification.approved.json +++ b/spec/fixtures/approvals/get_provider_pacts_for_verification.approved.json @@ -22,7 +22,7 @@ "status": 200, "headers": { "content-type": "application/hal+json;charset=utf-8", - "content-length": "840", + "content-length": "842", "date": "", "server": "Webmachine-Ruby/2.0.1 Rack/3.2" }, @@ -41,7 +41,7 @@ }, "_links": { "self": { - "href": "http://example.org/pacts/provider/Provider/consumer/Consumer%202/pact-version/0f22f551a422b027066db7635cad8bd8a59ac869/metadata/cyU1QiU1RCU1QnQlNUQ9cHJvZCZzJTVCJTVEJTVCbCU1RD10cnVlJnMlNUIlNUQlNUJjdiU1RD0y", + "href": "http://example.org/pacts/provider/Provider/consumer/Consumer%202/pact-version/0f22f551a422b027066db7635cad8bd8a59ac869/metadata/cyU1QiU1RCU1QnQlNUQ9cHJvZCZzJTVCJTVEJTVCbCU1RD10cnVlJnMlNUIlNUQlNUJjdiU1RD0xMA", "name": "Pact between Consumer 2 (4.5.6) and Provider" } } diff --git a/spec/pact/consumers/http_spec.rb b/spec/pact/consumers/http_spec.rb new file mode 100644 index 000000000..6c7df60d5 --- /dev/null +++ b/spec/pact/consumers/http_spec.rb @@ -0,0 +1,98 @@ +# frozen_string_literal: true + +require "pact_broker" +require "pact_broker/app" +require "rspec/mocks" +include RSpec::Mocks::ExampleMethods +require_relative "../../service_consumers/hal_relation_proxy_app" + +PactBroker.configuration.base_urls = ["http://example.org"] + +pact_broker = PactBroker::App.new { |c| c.database_connection = PactBroker::TestDatabase.connection_for_test_database } +app_to_verify = HalRelationProxyApp.new(pact_broker) + +require "pact" +require "pact/v2/rspec" +require_relative "../../service_consumers/shared_provider_states" +RSpec.describe "Verify consumers for Pact Broker", :pact_v2 do + + http_pact_provider "Pact Broker", opts: { + + # rails apps should be automatically detected + # if you need to configure your own app, you can do so here + + app: app_to_verify, + # start rackup with a different port. Useful if you already have something + # running on the default port *9292* + http_port: 9393, + + # Set the log level, default is :info + + log_level: :info, + logger: Logger.new(File.expand_path("../../../pact_verification.log", __dir__)), + + fail_if_no_pacts_found: true, + + # Pact Sources + + # 1. Local pacts from a directory + + # Default is pacts directory in the current working directory + # pact_dir: File.expand_path('../../../../consumer/spec/internal/pacts', __dir__), + + # 2. Broker based pacts + + # Broker credentials + + # broker_username: "pact_workshop", # can be set via PACT_BROKER_USERNAME env var + # broker_password: "pact_workshop", # can be set via PACT_BROKER_PASSWORD env var + # broker_token: "pact_workshop", # can be set via PACT_BROKER_TOKEN env var + + # Remote pact via a uri, traditionally triggered via webhooks + # when a pact that requires verification is published + + # 2a. Webhook triggered pacts + # Can be a local file or a remote URL + # Most used via webhooks + # Can be set via PACT_URL env var + # pact_uri: File.expand_path("../../../pacts/pact.json", __dir__), + pact_uri: "https://raw.githubusercontent.com/pact-foundation/pact_broker-client/refs/heads/master/spec/pacts/Pact%20Broker%20Client%20V2-Pact%20Broker.json", + + # 2b. Dynamically fetched pacts from broker + + # i. Set the broker url + # broker_url: "http://localhost:9292", # can be set via PACT_BROKER_URL env var + + # ii. Set the consumer version selectors + # Consumer version selectors + # The pact broker will return the following pacts by default, if no selectors are specified + # For the recommended setup, you dont _actually_ need to specify these selectors in ruby + # consumer_version_selectors: [{"deployedOrReleased" => true},{"mainBranch" => true},{"matchingBranch" => true}], + + # iii. Set additional dynamic selection verification options + # additional dynamic selection verification options + enable_pending: true, + include_wip_pacts_since: "2021-01-01", + + # Publish verification results to the broker + publish_verification_results: ENV["PACT_PUBLISH_VERIFICATION_RESULTS"] == "true", + provider_version: `git rev-parse HEAD`.strip, + provider_version_branch: `git rev-parse --abbrev-ref HEAD`.strip, + provider_version_tags: [`git rev-parse --abbrev-ref HEAD`.strip], + # provider_build_uri: "YOUR CI URL HERE - must be a valid url", + + } + + before_state_setup do + PactBroker::TestDatabase.truncate + end + + after_state_teardown do + PactBroker::TestDatabase.truncate + end + + shared_provider_states + +end + + diff --git a/spec/service_consumers/hal_relation_proxy_app.rb b/spec/service_consumers/hal_relation_proxy_app.rb index bca43e3d2..d32b7702a 100644 --- a/spec/service_consumers/hal_relation_proxy_app.rb +++ b/spec/service_consumers/hal_relation_proxy_app.rb @@ -35,12 +35,72 @@ class HalRelationProxyApp RESPONSE_BODY_REPLACEMENTS = { } + # query strings sent from the v2 ruby pact, is re-ordered by the rust app? + # so we need to re-order them here to match the expected query string + # PASS + # curl 'localhost:9292/matrix?ignore%5B%5D%5Bpacticipant%5D=Foo&ignore%5B%5D%5Bversion%5D=3.4.5&latestby=cvpv&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Bversion%5D=4.5.6&q%5B%5D%5Bpacticipant%5D=Foo&q%5B%5D%5Btag%5D=prod' | jq . + # FAIL + # curl 'localhost:9292/matrix?ignore%5B%5D%5Bpacticipant%5D=Foo&ignore%5B%5D%5Bversion%5D=3.4.5&latestby=cvpv&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Bpacticipant%5D=Foo&q%5B%5D%5Btag%5D=prod&q%5B%5D%5Bversion%5D=4.5.6' | jq . + QUERY_STRING_REPLACEMENTS = { + # pact-ruby-v2 pact (as v2) verified by pact-ruby-v2 + "ignore%5B%5D%5Bpacticipant%5D=Foo&ignore%5B%5D%5Bversion%5D=3.4.5&latestby=cvpv&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Bpacticipant%5D=Foo&q%5B%5D%5Btag%5D=prod&q%5B%5D%5Bversion%5D=4.5.6" => + "q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Bversion%5D=4.5.6&q%5B%5D%5Bpacticipant%5D=Foo&q%5B%5D%5Btag%5D=prod&latestby=cvpv&ignore%5B%5D%5Bpacticipant%5D=Foo&ignore%5B%5D%5Bversion%5D=3.4.5", + # pact-ruby-v2 pact (as v2) verified by pact-ruby-v1 + "ignore[][pacticipant]=Foo&ignore[][version]=3%2e4%2e5&latestby=cvpv&q[][pacticipant]=Bar&q[][pacticipant]=Foo&q[][tag]=prod&q[][version]=4%2e5%2e6" => + "q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Bversion%5D=4.5.6&q%5B%5D%5Bpacticipant%5D=Foo&q%5B%5D%5Btag%5D=prod&latestby=cvpv&ignore%5B%5D%5Bpacticipant%5D=Foo&ignore%5B%5D%5Bversion%5D=3.4.5", + + # pact-ruby-v2 pact (as v2) verified by pact-ruby-v2 + "latestby=cvpv&q%5B%5D%5Bpacticipant%5D=Foo&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Bversion%5D=1.2.3&q%5B%5D%5Bversion%5D=4.5.6" => + "q%5B%5D%5Bpacticipant%5D=Foo&q%5B%5D%5Bversion%5D=1.2.3&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Bversion%5D=4.5.6&latestby=cvpv", + # pact-ruby-v2 pact (as v2) verified by pact-ruby-v1 + "latestby=cvpv&q[][pacticipant]=Foo&q[][pacticipant]=Bar&q[][version]=1%2e2%2e3&q[][version]=4%2e5%2e6" => + "q%5B%5D%5Bpacticipant%5D=Foo&q%5B%5D%5Bversion%5D=1.2.3&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Bversion%5D=4.5.6&latestby=cvpv", + + # pact-ruby-v2 pact (as v2) verified by pact-ruby-v2 + "latestby=cvpv&q%5B%5D%5Bpacticipant%5D=Foo+Thing&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Bversion%5D=1.2.3&q%5B%5D%5Bversion%5D=4.5.6" => + "q%5B%5D%5Bpacticipant%5D=Foo%20Thing&q%5B%5D%5Bversion%5D=1.2.3&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Bversion%5D=4.5.6&latestby=cvpv", + # pact-ruby-v2 pact (as v2) verified by pact-ruby-v1 + "latestby=cvpv&q[][pacticipant]=Foo+Thing&q[][pacticipant]=Bar&q[][version]=1%2e2%2e3&q[][version]=4%2e5%2e6" => + "q%5B%5D%5Bpacticipant%5D=Foo%20Thing&q%5B%5D%5Bversion%5D=1.2.3&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Bversion%5D=4.5.6&latestby=cvpv", + + # pact-ruby-v2 pact (as v2) verified by pact-ruby-v2 + "latestby=cvpv&q%5B%5D%5Bpacticipant%5D=Foo&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Bversion%5D=1.2.3&q%5B%5D%5Bversion%5D=9.9.9" => + "q%5B%5D%5Bpacticipant%5D=Foo&q%5B%5D%5Bversion%5D=1.2.3&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Bversion%5D=9.9.9&latestby=cvpv", + # pact-ruby-v2 pact (as v2) verified by pact-ruby-v1 + "latestby=cvpv&q[][pacticipant]=Foo&q[][pacticipant]=Bar&q[][version]=1%2e2%2e3&q[][version]=9%2e9%2e9" => + "q%5B%5D%5Bpacticipant%5D=Foo&q%5B%5D%5Bversion%5D=1.2.3&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Bversion%5D=9.9.9&latestby=cvpv", + + # pact-ruby-v2 pact (as v2) verified by pact-ruby-v2 + "latestby=cvpv&q%5B%5D%5Blatest%5D=true&q%5B%5D%5Bpacticipant%5D=Foo&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Btag%5D=prod&q%5B%5D%5Bversion%5D=1.2.3" => + "q%5B%5D%5Bpacticipant%5D=Foo&q%5B%5D%5Bversion%5D=1.2.3&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Blatest%5D=true&q%5B%5D%5Btag%5D=prod&latestby=cvpv", + # pact-ruby-v2 pact (as v2) verified by pact-ruby-v1 + "latestby=cvpv&q[][latest]=true&q[][pacticipant]=Foo&q[][pacticipant]=Bar&q[][tag]=prod&q[][version]=1%2e2%2e3" => + "q%5B%5D%5Bpacticipant%5D=Foo&q%5B%5D%5Bversion%5D=1.2.3&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Blatest%5D=true&q%5B%5D%5Btag%5D=prod&latestby=cvpv", + + # pact-ruby-v2 pact (as v2) verified by pact-ruby-v2 + "latestby=cvpv&q%5B%5D%5Blatest%5D=true&q%5B%5D%5Bpacticipant%5D=Foo&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Bversion%5D=1.2.4" => + "q%5B%5D%5Bpacticipant%5D=Foo&q%5B%5D%5Bversion%5D=1.2.4&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Blatest%5D=true&latestby=cvpv", + # pact-ruby-v2 pact (as v2) verified by pact-ruby-v1 + "latestby=cvpv&q[][latest]=true&q[][pacticipant]=Foo&q[][pacticipant]=Bar&q[][version]=1%2e2%2e4" => + "q%5B%5D%5Bpacticipant%5D=Foo&q%5B%5D%5Bversion%5D=1.2.4&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Blatest%5D=true&latestby=cvpv", + } + def initialize(app) @app = app end def call env original_path = env["PATH_INFO"] + original_query = env["QUERY_STRING"] + + QUERY_STRING_REPLACEMENTS.each do | (find, replace) | + env["QUERY_STRING"] = env["QUERY_STRING"].gsub(find, replace) + end + + if env["QUERY_STRING"] != original_query + puts "Modified query string: #{env["QUERY_STRING"]}" + end + env_with_modified_path = env PATH_REPLACEMENTS.each do | (find, replace) | env_with_modified_path["PATH_INFO"] = env_with_modified_path["PATH_INFO"].gsub(find, replace) diff --git a/spec/service_consumers/pact_helper.rb b/spec/service_consumers/pact_helper.rb index 15083f81b..aa17ddf6b 100644 --- a/spec/service_consumers/pact_helper.rb +++ b/spec/service_consumers/pact_helper.rb @@ -56,6 +56,6 @@ def do_not_rollback? _response end honours_pact_with "Pact Broker Client" do - pact_uri "https://raw.githubusercontent.com/pact-foundation/pact_broker-client/master/spec/pacts/pact_broker_client-pact_broker.json" + pact_uri "https://raw.githubusercontent.com/pact-foundation/pact_broker-client/refs/heads/master/spec/pacts/Pact%20Broker%20Client%20V2-Pact%20Broker.json" end end diff --git a/spec/service_consumers/provider_states_for_pact_broker_client.rb b/spec/service_consumers/provider_states_for_pact_broker_client.rb index 1c64cd917..9be9983a5 100644 --- a/spec/service_consumers/provider_states_for_pact_broker_client.rb +++ b/spec/service_consumers/provider_states_for_pact_broker_client.rb @@ -1,353 +1,6 @@ require "spec/support/test_data_builder" - +require_relative "shared_provider_states" Pact.provider_states_for "Pact Broker Client" do - - provider_state "the pb:latest-tagged-version relation exists in the index resource" do - no_op - end - - provider_state "'Condor' exists in the pact-broker with the latest tagged 'production' version 1.2.3" do - set_up do - TestDataBuilder.new - .create_consumer("Condor") - .create_consumer_version("1.2.3") - .create_consumer_version_tag("production") - .create_consumer_version("2.0.0") - end - end - - provider_state "the pb:latest-version relation exists in the index resource" do - no_op - end - - provider_state "'Condor' exists in the pact-broker with the latest version 1.2.3" do - set_up do - TestDataBuilder.new - .create_consumer("Condor") - .create_consumer_version("1.0.0") - .create_consumer_version("1.2.3") - end - end - - provider_state "the 'Pricing Service' and 'Condor' already exist in the pact-broker" do - set_up do - TestDataBuilder.new - .create_consumer("Condor") - .create_provider("Pricing Service") - end - end - - provider_state "the pact for Foo Thing version 1.2.3 has been verified by Bar version 4.5.6" do - set_up do - TestDataBuilder.new - .create_pact_with_hierarchy("Foo Thing", "1.2.3", "Bar") - .revise_pact - .create_verification(provider_version: "4.5.6") - .create_verification(provider_version: "7.8.9", number: 2) - .create_consumer_version("2.0.0") - .create_pact - .revise_pact - .create_verification(provider_version: "4.5.6") - end - end - - provider_state "the pact for Foo version 1.2.3 has been verified by Bar version 4.5.6" do - set_up do - TestDataBuilder.new - .create_pact_with_hierarchy("Foo", "1.2.3", "Bar") - .revise_pact - .create_verification(provider_version: "4.5.6") - .create_verification(provider_version: "7.8.9", number: 2) - .create_consumer_version("2.0.0") - .create_pact - .revise_pact - .create_verification(provider_version: "4.5.6") - end - end - - provider_state "the pact for Foo version 1.2.3 and 1.2.4 has been verified by Bar version 4.5.6" do - set_up do - TestDataBuilder.new - .create_pact_with_hierarchy("Foo", "1.2.3", "Bar") - .revise_pact - .create_verification(provider_version: "4.5.6") - .create_consumer_version("1.2.4") - .create_pact - .revise_pact - .create_verification(provider_version: "4.5.6") - end - end - - provider_state "the pact for Foo version 1.2.3 has been successfully verified by Bar version 4.5.6, and 1.2.4 unsuccessfully by 9.9.9" do - set_up do - TestDataBuilder.new - .create_pact_with_hierarchy("Foo", "1.2.3", "Bar") - .revise_pact - .create_verification(provider_version: "4.5.6") - .create_consumer_version("1.2.4") - .create_pact - .revise_pact - .create_verification(provider_version: "9.9.9", success: false) - end - end - - provider_state "the pact for Foo version 1.2.3 has been successfully verified by Bar version 4.5.6 with tag prod, and 1.2.4 unsuccessfully by 9.9.9" do - set_up do - TestDataBuilder.new - .create_pact_with_hierarchy("Foo", "1.2.3", "Bar") - .revise_pact - .create_verification(provider_version: "4.5.6") - .use_provider("Bar") - .use_provider_version("4.5.6") - .create_provider_version_tag("prod") - .create_consumer_version("1.2.4") - .create_pact - .revise_pact - .create_verification(provider_version: "9.9.9", success: false) - end - end - - provider_state "the pact for Foo version 1.2.3 has been verified by Bar version 4.5.6 and version 5.6.7" do - set_up do - TestDataBuilder.new - .create_pact_with_hierarchy("Foo", "1.2.3", "Bar") - .revise_pact - .create_verification(provider_version: "4.5.6") - .create_verification(provider_version: "5.6.7", number: 2) - end - end - - provider_state "the pact for Foo version 1.2.3 has been successfully verified by Bar version 4.5.6 (tagged prod) and version 5.6.7" do - set_up do - TestDataBuilder.new - .create_pact_with_hierarchy("Foo", "1.2.3", "Bar") - .create_verification(provider_version: "4.5.6") - .use_provider_version("4.5.6") - .create_provider_version_tag("prod") - .create_verification(provider_version: "5.6.7", number: 2) - end - end - - provider_state "the 'Pricing Service' does not exist in the pact-broker" do - no_op - end - - provider_state "the 'Pricing Service' already exists in the pact-broker" do - set_up do - TestDataBuilder.new.create_pricing_service.create_provider_version("1.3.0") - end - end - - provider_state "an error occurs while publishing a pact" do - set_up do - require "pact_broker/pacts/service" - allow(PactBroker::Pacts::Service).to receive(:create_or_update_pact).and_raise("an error") - end - end - - provider_state "a pact between Condor and the Pricing Service exists" do - set_up do - TestDataBuilder.new - .create_condor - .create_consumer_version("1.3.0") - .create_pricing_service - .create_pact - end - end - - provider_state "no pact between Condor and the Pricing Service exists" do - no_op - end - - provider_state "the 'Pricing Service' and 'Condor' already exist in the pact-broker, and Condor already has a pact published for version 1.3.0" do - set_up do - TestDataBuilder.new - .create_condor - .create_consumer_version("1.3.0") - .create_pricing_service - .create_pact - end - end - - provider_state "'Condor' already exist in the pact-broker, but the 'Pricing Service' does not" do - set_up do - TestDataBuilder.new.create_condor - end - end - - provider_state "'Condor' exists in the pact-broker" do - set_up do - TestDataBuilder.new.create_condor.create_consumer_version("1.3.0") - end - end - - provider_state "'Condor' exists in the pact-broker with version 1.3.0, tagged with 'prod'" do - set_up do - TestDataBuilder.new - .create_pacticipant("Condor") - .create_version("1.3.0") - .create_tag("prod") - end - end - - provider_state "'Condor' does not exist in the pact-broker" do - no_op - end - - provider_state "a pact between Condor and the Pricing Service exists for the production version of Condor" do - set_up do - TestDataBuilder.new - .create_consumer("Condor") - .create_consumer_version("1.3.0") - .create_consumer_version_tag("prod") - .create_provider("Pricing Service") - .create_pact - end - end - - provider_state "a pacticipant version with production details exists for the Pricing Service" do - set_up do - # Your set up code goes here - end - end - - provider_state "no pacticipant version exists for the Pricing Service" do - no_op - end - - provider_state "a latest pact between Condor and the Pricing Service exists" do - set_up do - TestDataBuilder.new - .create_consumer("Condor") - .create_consumer_version("1.3.0") - .create_provider("Pricing Service") - .create_pact - end - end - - provider_state "tagged as prod pact between Condor and the Pricing Service exists" do - set_up do - TestDataBuilder.new - .create_consumer("Condor") - .create_consumer_version("1.3.0") - .create_consumer_version_tag("prod") - .create_provider("Pricing Service") - .create_pact - end - end - - provider_state "a webhook with the uuid 696c5f93-1b7f-44bc-8d03-59440fcaa9a0 exists" do - set_up do - TestDataBuilder.new - .create_consumer("Condor") - .create_provider("Pricing Service") - .create_webhook(uuid: "696c5f93-1b7f-44bc-8d03-59440fcaa9a0") - end - end - - provider_state "the pacticipant relations are present" do - no_op - end - - provider_state "a pacticipant with name Foo exists" do - set_up do - TestDataBuilder.new - .create_consumer("Foo") - end - end - - provider_state "the pb:pacticipant-version relation exists in the index resource" do - no_op - end - - provider_state "version 26f353580936ad3b9baddb17b00e84f33c69e7cb of pacticipant Foo does not exist" do - no_op - end - - provider_state "version 26f353580936ad3b9baddb17b00e84f33c69e7cb of pacticipant Foo does exist" do - set_up do - TestDataBuilder.new - .create_consumer("Foo") - .create_consumer_version("26f353580936ad3b9baddb17b00e84f33c69e7cb") - end - end - - provider_state "the pb:publish-contracts relations exists in the index resource" do - no_op - end - - provider_state "the pb:environments relation exists in the index resource" do - no_op - end - - provider_state "provider Bar version 4.5.6 has a successful verification for Foo version 1.2.3 tagged prod and a failed verification for version 3.4.5 tagged prod" do - set_up do - TestDataBuilder.new - .create_consumer("Foo") - .create_provider("Bar") - .create_consumer_version("1.2.3") - .create_consumer_version_tag("prod") - .create_pact - .create_verification(provider_version: "4.5.6") - .create_consumer_version("3.4.5") - .create_consumer_version_tag("prod") - .create_pact(json_content: TestDataBuilder.new.random_json_content("Foo", "Bar")) - .create_verification(provider_version: "4.5.6", success: false) - end - end - - provider_state "an environment exists" do - set_up do - TestDataBuilder.new - .create_environment("test", contacts: [ { name: "foo", details: { emailAddress: "foo@bar.com" } }]) - end - end - - provider_state "version 5556b8149bf8bac76bc30f50a8a2dd4c22c85f30 of pacticipant Foo exists with a test environment available for release" do - set_up do - TestDataBuilder.new - .create_environment("test", uuid: "cb632df3-0a0d-4227-aac3-60114dd36479") - .create_consumer("Foo") - .create_consumer_version("5556b8149bf8bac76bc30f50a8a2dd4c22c85f30") - end - end - - provider_state "an environment with name test and UUID 16926ef3-590f-4e3f-838e-719717aa88c9 exists" do - set_up do - TestDataBuilder.new - .create_environment("test", uuid: "16926ef3-590f-4e3f-838e-719717aa88c9") - end - end - - provider_state "an version is deployed to environment with UUID 16926ef3-590f-4e3f-838e-719717aa88c9 with target customer-1" do - set_up do - TestDataBuilder.new - .create_environment("test", uuid: "16926ef3-590f-4e3f-838e-719717aa88c9") - .create_consumer("Foo") - .create_consumer_version("5556b8149bf8bac76bc30f50a8a2dd4c22c85f30") - .create_deployed_version_for_consumer_version(uuid: "ff3adecf-cfc5-4653-a4e3-f1861092f8e0", target: "customer-1") - end - end - - provider_state "a currently deployed version exists" do - set_up do - TestDataBuilder.new - .create_environment("test", uuid: "cb632df3-0a0d-4227-aac3-60114dd36479") - .create_consumer("Foo") - .create_consumer_version("5556b8149bf8bac76bc30f50a8a2dd4c22c85f30") - .create_deployed_version_for_consumer_version(uuid: "ff3adecf-cfc5-4653-a4e3-f1861092f8e0") - end - end - - provider_state "the pb:pacticipant-branch relation exists in the index resource" do - no_op - end - - provider_state "a branch named main exists for pacticipant Foo" do - set_up do - TestDataBuilder.new - .create_consumer("Foo") - .create_consumer_version("1", branch: "main") - end - end + shared_provider_states + shared_noop_provider_states end diff --git a/spec/service_consumers/provider_states_for_pact_broker_client_2.rb b/spec/service_consumers/provider_states_for_pact_broker_client_2.rb deleted file mode 100644 index 7ef20cf41..000000000 --- a/spec/service_consumers/provider_states_for_pact_broker_client_2.rb +++ /dev/null @@ -1,36 +0,0 @@ -Pact.provider_states_for "Pact Broker Client" do - - provider_state "the pb:pacticipant-version and pb:environments relations exist in the index resource" do - no_op - end - - provider_state "an environment with name test exists" do - set_up do - TestDataBuilder.new - .create_environment("test") - end - end - - provider_state "version 5556b8149bf8bac76bc30f50a8a2dd4c22c85f30 of pacticipant Foo exists with a test environment available for deployment" do - set_up do - TestDataBuilder.new - .create_consumer("Foo") - .create_consumer_version("5556b8149bf8bac76bc30f50a8a2dd4c22c85f30") - .create_environment("test", uuid: "cb632df3-0a0d-4227-aac3-60114dd36479") - end - end - - provider_state "version 5556b8149bf8bac76bc30f50a8a2dd4c22c85f30 of pacticipant Foo does not exist" do - no_op - end - - provider_state "version 5556b8149bf8bac76bc30f50a8a2dd4c22c85f30 of pacticipant Foo exists with 2 environments that aren't test available for deployment" do - set_up do - TestDataBuilder.new - .create_consumer("Foo") - .create_consumer_version("5556b8149bf8bac76bc30f50a8a2dd4c22c85f30") - .create_environment("prod") - .create_environment("dev") - end - end -end diff --git a/spec/service_consumers/provider_states_for_pact_broker_client_v2.rb b/spec/service_consumers/provider_states_for_pact_broker_client_v2.rb new file mode 100644 index 000000000..2856a0438 --- /dev/null +++ b/spec/service_consumers/provider_states_for_pact_broker_client_v2.rb @@ -0,0 +1,6 @@ +require "spec/support/test_data_builder" +require_relative "shared_provider_states" +Pact.provider_states_for "Pact Broker Client V2" do + shared_provider_states + shared_noop_provider_states +end diff --git a/spec/service_consumers/shared_provider_states.rb b/spec/service_consumers/shared_provider_states.rb new file mode 100644 index 000000000..bc3eceb52 --- /dev/null +++ b/spec/service_consumers/shared_provider_states.rb @@ -0,0 +1,403 @@ + + # rubocop:disable Metrics/MethodLength + def shared_provider_states + + provider_state "'Condor' exists in the pact-broker with the latest tagged 'production' version 1.2.3" do + set_up do + TestDataBuilder.new + .create_consumer("Condor") + .create_consumer_version("1.2.3") + .create_consumer_version_tag("production") + .create_consumer_version("2.0.0") + end + end + + + provider_state "'Condor' exists in the pact-broker with the latest version 1.2.3" do + set_up do + TestDataBuilder.new + .create_consumer("Condor") + .create_consumer_version("1.0.0") + .create_consumer_version("1.2.3") + end + end + + provider_state "the 'Pricing Service' and 'Condor' already exist in the pact-broker" do + set_up do + TestDataBuilder.new + .create_consumer("Condor") + .create_provider("Pricing Service") + end + end + + provider_state "the pact for Foo Thing version 1.2.3 has been verified by Bar version 4.5.6" do + set_up do + TestDataBuilder.new + .create_pact_with_hierarchy("Foo Thing", "1.2.3", "Bar") + .revise_pact + .create_verification(provider_version: "4.5.6") + .create_verification(provider_version: "7.8.9", number: 2) + .create_consumer_version("2.0.0") + .create_pact + .revise_pact + .create_verification(provider_version: "4.5.6") + end + end + + provider_state "the pact for Foo version 1.2.3 has been verified by Bar version 4.5.6" do + set_up do + TestDataBuilder.new + .create_pact_with_hierarchy("Foo", "1.2.3", "Bar") + .revise_pact + .create_verification(provider_version: "4.5.6") + .create_verification(provider_version: "7.8.9", number: 2) + .create_consumer_version("2.0.0") + .create_pact + .revise_pact + .create_verification(provider_version: "4.5.6") + end + end + + provider_state "the pact for Foo version 1.2.3 and 1.2.4 has been verified by Bar version 4.5.6" do + set_up do + TestDataBuilder.new + .create_pact_with_hierarchy("Foo", "1.2.3", "Bar") + .revise_pact + .create_verification(provider_version: "4.5.6") + .create_consumer_version("1.2.4") + .create_pact + .revise_pact + .create_verification(provider_version: "4.5.6") + end + end + + provider_state "the pact for Foo version 1.2.3 has been successfully verified by Bar version 4.5.6, and 1.2.4 unsuccessfully by 9.9.9" do + set_up do + TestDataBuilder.new + .create_pact_with_hierarchy("Foo", "1.2.3", "Bar") + .revise_pact + .create_verification(provider_version: "4.5.6") + .create_consumer_version("1.2.4") + .create_pact + .revise_pact + .create_verification(provider_version: "9.9.9", success: false) + end + end + + provider_state "the pact for Foo version 1.2.3 has been successfully verified by Bar version 4.5.6 with tag prod, and 1.2.4 unsuccessfully by 9.9.9" do + set_up do + TestDataBuilder.new + .create_pact_with_hierarchy("Foo", "1.2.3", "Bar") + .revise_pact + .create_verification(provider_version: "4.5.6") + .use_provider("Bar") + .use_provider_version("4.5.6") + .create_provider_version_tag("prod") + .create_consumer_version("1.2.4") + .create_pact + .revise_pact + .create_verification(provider_version: "9.9.9", success: false) + end + end + + provider_state "the pact for Foo version 1.2.3 has been verified by Bar version 4.5.6 and version 5.6.7" do + set_up do + TestDataBuilder.new + .create_pact_with_hierarchy("Foo", "1.2.3", "Bar") + .revise_pact + .create_verification(provider_version: "4.5.6") + .create_verification(provider_version: "5.6.7", number: 2) + end + end + + provider_state "the pact for Foo version 1.2.3 has been successfully verified by Bar version 4.5.6 (tagged prod) and version 5.6.7" do + set_up do + TestDataBuilder.new + .create_pact_with_hierarchy("Foo", "1.2.3", "Bar") + .create_verification(provider_version: "4.5.6") + .use_provider_version("4.5.6") + .create_provider_version_tag("prod") + .create_verification(provider_version: "5.6.7", number: 2) + end + end + + + + provider_state "the 'Pricing Service' already exists in the pact-broker" do + set_up do + TestDataBuilder.new.create_pricing_service.create_provider_version("1.3.0") + end + end + + provider_state "an error occurs while publishing a pact" do + set_up do + require "pact_broker/pacts/service" + allow(PactBroker::Pacts::Service).to receive(:create_or_update_pact).and_raise("an error") + end + tear_down do + allow(PactBroker::Pacts::Service).to receive(:create_or_update_pact).and_call_original + end + end + + provider_state "a pact between Condor and the Pricing Service exists" do + set_up do + TestDataBuilder.new + .create_condor + .create_consumer_version("1.3.0") + .create_pricing_service + .create_pact + end + end + + + provider_state "the 'Pricing Service' and 'Condor' already exist in the pact-broker, and Condor already has a pact published for version 1.3.0" do + set_up do + TestDataBuilder.new + .create_condor + .create_consumer_version("1.3.0") + .create_pricing_service + .create_pact + end + end + + provider_state "'Condor' already exist in the pact-broker, but the 'Pricing Service' does not" do + set_up do + TestDataBuilder.new.create_condor + end + end + + provider_state "'Condor' exists in the pact-broker" do + set_up do + TestDataBuilder.new.create_condor.create_consumer_version("1.3.0") + end + end + + provider_state "'Condor' exists in the pact-broker with version 1.3.0, tagged with 'prod'" do + set_up do + TestDataBuilder.new + .create_pacticipant("Condor") + .create_version("1.3.0") + .create_tag("prod") + end + end + + + provider_state "a pact between Condor and the Pricing Service exists for the production version of Condor" do + set_up do + TestDataBuilder.new + .create_consumer("Condor") + .create_consumer_version("1.3.0") + .create_consumer_version_tag("prod") + .create_provider("Pricing Service") + .create_pact + end + end + + provider_state "a pacticipant version with production details exists for the Pricing Service" do + set_up do + # Your set up code goes here + end + end + + + provider_state "a latest pact between Condor and the Pricing Service exists" do + set_up do + TestDataBuilder.new + .create_consumer("Condor") + .create_consumer_version("1.3.0") + .create_provider("Pricing Service") + .create_pact + end + end + + provider_state "tagged as prod pact between Condor and the Pricing Service exists" do + set_up do + TestDataBuilder.new + .create_consumer("Condor") + .create_consumer_version("1.3.0") + .create_consumer_version_tag("prod") + .create_provider("Pricing Service") + .create_pact + end + end + + provider_state "a webhook with the uuid 696c5f93-1b7f-44bc-8d03-59440fcaa9a0 exists" do + set_up do + TestDataBuilder.new + .create_consumer("Condor") + .create_provider("Pricing Service") + .create_webhook(uuid: "696c5f93-1b7f-44bc-8d03-59440fcaa9a0") + end + end + + + provider_state "a pacticipant with name Foo exists" do + set_up do + TestDataBuilder.new + .create_consumer("Foo") + end + end + + + + provider_state "version 26f353580936ad3b9baddb17b00e84f33c69e7cb of pacticipant Foo does exist" do + set_up do + TestDataBuilder.new + .create_consumer("Foo") + .create_consumer_version("26f353580936ad3b9baddb17b00e84f33c69e7cb") + end + end + + provider_state "provider Bar version 4.5.6 has a successful verification for Foo version 1.2.3 tagged prod and a failed verification for version 3.4.5 tagged prod" do + set_up do + TestDataBuilder.new + .create_consumer("Foo") + .create_provider("Bar") + .create_consumer_version("1.2.3") + .create_consumer_version_tag("prod") + .create_pact + .create_verification(provider_version: "4.5.6") + .create_consumer_version("3.4.5") + .create_consumer_version_tag("prod") + .create_pact(json_content: TestDataBuilder.new.random_json_content("Foo", "Bar")) + .create_verification(provider_version: "4.5.6", success: false) + end + end + + provider_state "an environment exists" do + set_up do + TestDataBuilder.new + .create_environment("test", contacts: [ { name: "foo", details: { emailAddress: "foo@bar.com" } }]) + end + end + + provider_state "version 5556b8149bf8bac76bc30f50a8a2dd4c22c85f30 of pacticipant Foo exists with a test environment available for release" do + set_up do + TestDataBuilder.new + .create_environment("test", uuid: "cb632df3-0a0d-4227-aac3-60114dd36479") + .create_consumer("Foo") + .create_consumer_version("5556b8149bf8bac76bc30f50a8a2dd4c22c85f30") + end + end + + provider_state "an environment with name test and UUID 16926ef3-590f-4e3f-838e-719717aa88c9 exists" do + set_up do + TestDataBuilder.new + .create_environment("test", uuid: "16926ef3-590f-4e3f-838e-719717aa88c9") + end + end + + provider_state "an version is deployed to environment with UUID 16926ef3-590f-4e3f-838e-719717aa88c9 with target customer-1" do + set_up do + TestDataBuilder.new + .create_environment("test", uuid: "16926ef3-590f-4e3f-838e-719717aa88c9") + .create_consumer("Foo") + .create_consumer_version("5556b8149bf8bac76bc30f50a8a2dd4c22c85f30") + .create_deployed_version_for_consumer_version(uuid: "ff3adecf-cfc5-4653-a4e3-f1861092f8e0", target: "customer-1") + end + end + + provider_state "a currently deployed version exists" do + set_up do + TestDataBuilder.new + .create_environment("test", uuid: "cb632df3-0a0d-4227-aac3-60114dd36479") + .create_consumer("Foo") + .create_consumer_version("5556b8149bf8bac76bc30f50a8a2dd4c22c85f30") + .create_deployed_version_for_consumer_version(uuid: "ff3adecf-cfc5-4653-a4e3-f1861092f8e0") + end + end + + provider_state "a branch named main exists for pacticipant Foo" do + set_up do + TestDataBuilder.new + .create_consumer("Foo") + .create_consumer_version("1", branch: "main") + end + end + + provider_state "an environment with name test exists" do + set_up do + TestDataBuilder.new + .create_environment("test") + end + end + + provider_state "version 5556b8149bf8bac76bc30f50a8a2dd4c22c85f30 of pacticipant Foo exists with a test environment available for deployment" do + set_up do + TestDataBuilder.new + .create_consumer("Foo") + .create_consumer_version("5556b8149bf8bac76bc30f50a8a2dd4c22c85f30") + .create_environment("test", uuid: "cb632df3-0a0d-4227-aac3-60114dd36479") + end + end + + + provider_state "version 5556b8149bf8bac76bc30f50a8a2dd4c22c85f30 of pacticipant Foo exists with 2 environments that aren't test available for deployment" do + set_up do + TestDataBuilder.new + .create_consumer("Foo") + .create_consumer_version("5556b8149bf8bac76bc30f50a8a2dd4c22c85f30") + .create_environment("prod") + .create_environment("dev") + end + end + end + + def shared_noop_provider_states + provider_state "the pb:latest-tagged-version relation exists in the index resource" do + no_op + end + + provider_state "the pb:latest-version relation exists in the index resource" do + no_op + end + + provider_state "version 5556b8149bf8bac76bc30f50a8a2dd4c22c85f30 of pacticipant Foo does not exist" do + no_op + end + + provider_state "the 'Pricing Service' does not exist in the pact-broker" do + no_op + end + + provider_state "no pact between Condor and the Pricing Service exists" do + no_op + end + + provider_state "'Condor' does not exist in the pact-broker" do + no_op + end + + provider_state "no pacticipant version exists for the Pricing Service" do + no_op + end + + provider_state "the pacticipant relations are present" do + no_op + end + + provider_state "the pb:pacticipant-version relation exists in the index resource" do + no_op + end + + provider_state "version 26f353580936ad3b9baddb17b00e84f33c69e7cb of pacticipant Foo does not exist" do + no_op + end + + provider_state "the pb:publish-contracts relations exists in the index resource" do + no_op + end + + provider_state "the pb:environments relation exists in the index resource" do + no_op + end + + provider_state "the pb:pacticipant-branch relation exists in the index resource" do + no_op + end + + provider_state "the pb:pacticipant-version and pb:environments relations exist in the index resource" do + no_op + end + + end \ No newline at end of file diff --git a/spec/support/simplecov.rb b/spec/support/simplecov.rb index 8ec90a114..ec82f1e22 100644 --- a/spec/support/simplecov.rb +++ b/spec/support/simplecov.rb @@ -11,6 +11,8 @@ SimpleCov.minimum_coverage 92 when "pact:verify" SimpleCov.minimum_coverage 62 + when "pact:v2:verify" + SimpleCov.minimum_coverage 62 end end diff --git a/tasks/pact.rake b/tasks/pact.rake index adbccac3f..5e232e984 100644 --- a/tasks/pact.rake +++ b/tasks/pact.rake @@ -14,3 +14,10 @@ namespace :pact do task "verify:at" => :prepare task "verify:dev" => :prepare end + +require "rspec/core/rake_task" +RSpec::Core::RakeTask.new("pact:v2:verify") do |task| + ENV["SIMPLECOV_COMMAND_NAME"] = "pact:v2:verify" + task.pattern = "spec/pact/consumers/*_spec.rb" + task.rspec_opts = ["-t pact_v2"] +end