pact_broker 2.55.0 → 2.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -0
- data/lib/pact_broker/api/decorators/reason_decorator.rb +17 -0
- data/lib/pact_broker/app.rb +13 -4
- data/lib/pact_broker/db.rb +9 -1
- data/lib/pact_broker/doc/controllers/app.rb +5 -1
- data/lib/pact_broker/domain/verification.rb +13 -0
- data/lib/pact_broker/integrations/service.rb +2 -2
- data/lib/pact_broker/logging.rb +3 -1
- data/lib/pact_broker/matrix/deployment_status_summary.rb +23 -1
- data/lib/pact_broker/matrix/reason.rb +9 -0
- data/lib/pact_broker/pacts/content.rb +26 -2
- data/lib/pact_broker/pacts/repository.rb +2 -2
- data/lib/pact_broker/tasks/migration_task.rb +20 -1
- data/lib/pact_broker/ui/controllers/base_controller.rb +1 -1
- data/lib/pact_broker/ui/views/index/_navbar.haml +1 -1
- data/lib/pact_broker/verifications/repository.rb +2 -2
- data/lib/pact_broker/version.rb +1 -1
- data/script/foo-bar-verification.json +3 -1
- data/script/foo-bar.json +11 -0
- data/spec/features/delete_integration_spec.rb +2 -2
- data/spec/integration/ui/index_spec.rb +16 -0
- data/spec/integration/ui/matrix_spec.rb +1 -1
- data/spec/lib/pact_broker/api/decorators/reason_decorator_spec.rb +18 -1
- data/spec/lib/pact_broker/doc/controllers/app_spec.rb +16 -0
- data/spec/lib/pact_broker/integrations/service_spec.rb +6 -0
- data/spec/lib/pact_broker/matrix/deployment_status_summary_spec.rb +6 -2
- data/spec/lib/pact_broker/matrix/integration_spec.rb +43 -0
- data/spec/lib/pact_broker/pacts/content_spec.rb +125 -0
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: f4391656ae9cddad910749af5c6bb4c3c94644cf605122e31a40ce8891feb49d
         | 
| 4 | 
            +
              data.tar.gz: db46a7cdf21674996ed6271dac6c13e2238771004d76693fea6bc11e18fdd146
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 77ebcb58e85910f527b5750b4a484d856cb7a84369e4d6dc89097e3cc706c8077e1f2cc83ff8f7c5e1e079eb55b686680cacccb52c79a20a6b42b903d98e8784
         | 
| 7 | 
            +
              data.tar.gz: c151197191dab0a0b35dd08f7ec0df10a280f28f372a5d72365052a813b67265a2cd1e3d602927641169b5e72fd9e1b6547c0e04a260895693c6a65415fcace0
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,25 @@ | |
| 1 | 
            +
            <a name="v2.56.0"></a>
         | 
| 2 | 
            +
            ### v2.56.0 (2020-06-01)
         | 
| 3 | 
            +
             | 
| 4 | 
            +
             | 
| 5 | 
            +
            #### Features
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            * **database**
         | 
| 8 | 
            +
              * log schema versions and migration info on startup	 ([b385e535](/../../commit/b385e535))
         | 
| 9 | 
            +
              * allow options to be passed to Sequel migrate via the MigrationTask	 ([143613e7](/../../commit/143613e7))
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            * allow Pactflow messages in logs to be hidden by setting PACT_BROKER_HIDE_PACTFLOW_MESSAGES=true	 ([a7550105](/../../commit/a7550105))
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            * **can-i-deploy**
         | 
| 14 | 
            +
              * experimental - add a warning message if there are interactions missing verification test results.	 ([f7ab8cc5](/../../commit/f7ab8cc5))
         | 
| 15 | 
            +
             | 
| 16 | 
            +
             | 
| 17 | 
            +
            #### Bug Fixes
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            * use relative URLs when base_url not explictly set to ensure app is not vulnerable to host header attacks	 ([92c45a0a](/../../commit/92c45a0a))
         | 
| 20 | 
            +
            * raise PactBroker::Error when either pacticipant is not found in the business layer while attempting to delete an integration	 ([3c209a46](/../../commit/3c209a46))
         | 
| 21 | 
            +
             | 
| 22 | 
            +
             | 
| 1 23 | 
             
            <a name="v2.55.0"></a>
         | 
| 2 24 | 
             
            ### v2.55.0 (2020-05-22)
         | 
| 3 25 |  | 
| @@ -22,6 +22,11 @@ module PactBroker | |
| 22 22 | 
             
                        "There are no missing dependencies"
         | 
| 23 23 | 
             
                      when PactBroker::Matrix::Successful
         | 
| 24 24 | 
             
                        "All required verification results are published and successful"
         | 
| 25 | 
            +
                      when PactBroker::Matrix::InteractionsMissingVerifications
         | 
| 26 | 
            +
                        descriptions = reason.interactions.collect do | interaction |
         | 
| 27 | 
            +
                          interaction_description(interaction)
         | 
| 28 | 
            +
                        end.join('; ')
         | 
| 29 | 
            +
                        "WARNING: Although the verification was reported as successful, the results for #{reason.consumer_selector.description} and #{reason.provider_selector.description} may be missing tests for the following interactions: #{descriptions}"
         | 
| 25 30 | 
             
                      else
         | 
| 26 31 | 
             
                        reason
         | 
| 27 32 | 
             
                      end
         | 
| @@ -44,6 +49,18 @@ module PactBroker | |
| 44 49 | 
             
                        ""
         | 
| 45 50 | 
             
                      end
         | 
| 46 51 | 
             
                    end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                    # TODO move this somewhere else
         | 
| 54 | 
            +
                    def interaction_description(interaction)
         | 
| 55 | 
            +
                      if interaction['providerState'] && interaction['providerState'] != ''
         | 
| 56 | 
            +
                        "#{interaction['description']} given #{interaction['providerState']}"
         | 
| 57 | 
            +
                      elsif interaction['providerStates'] && interaction['providerStates'].is_a?(Array) && interaction['providerStates'].any?
         | 
| 58 | 
            +
                        provider_states = interaction['providerStates'].collect{ |ps| ps['name'] }.compact.join(', ')
         | 
| 59 | 
            +
                        "#{interaction['description']} given #{provider_states}"
         | 
| 60 | 
            +
                      else
         | 
| 61 | 
            +
                        interaction['description']
         | 
| 62 | 
            +
                      end
         | 
| 63 | 
            +
                    end
         | 
| 47 64 | 
             
                  end
         | 
| 48 65 | 
             
                end
         | 
| 49 66 | 
             
              end
         | 
    
        data/lib/pact_broker/app.rb
    CHANGED
    
    | @@ -81,11 +81,18 @@ module PactBroker | |
| 81 81 | 
             
                end
         | 
| 82 82 |  | 
| 83 83 | 
             
                def prepare_database
         | 
| 84 | 
            +
                  logger.info "Database schema version is #{PactBroker::DB.version(configuration.database_connection)}"
         | 
| 84 85 | 
             
                  if configuration.auto_migrate_db
         | 
| 85 | 
            -
                     | 
| 86 | 
            -
                    PactBroker::DB. | 
| 86 | 
            +
                    migration_options = { allow_missing_migration_files: configuration.allow_missing_migration_files }
         | 
| 87 | 
            +
                    if PactBroker::DB.is_current?(configuration.database_connection, migration_options)
         | 
| 88 | 
            +
                      logger.info "Skipping database migrations as the latest migration has already been applied"
         | 
| 89 | 
            +
                    else
         | 
| 90 | 
            +
                      logger.info "Migrating database schema"
         | 
| 91 | 
            +
                      PactBroker::DB.run_migrations configuration.database_connection, migration_options
         | 
| 92 | 
            +
                      logger.info "Database schema version is now #{PactBroker::DB.version(configuration.database_connection)}"
         | 
| 93 | 
            +
                    end
         | 
| 87 94 | 
             
                  else
         | 
| 88 | 
            -
                    logger.info "Skipping database migrations"
         | 
| 95 | 
            +
                    logger.info "Skipping database schema migrations as database auto migrate is disabled"
         | 
| 89 96 | 
             
                  end
         | 
| 90 97 |  | 
| 91 98 | 
             
                  if configuration.auto_migrate_db_data
         | 
| @@ -232,7 +239,9 @@ module PactBroker | |
| 232 239 | 
             
                end
         | 
| 233 240 |  | 
| 234 241 | 
             
                def print_startup_message
         | 
| 235 | 
            -
                   | 
| 242 | 
            +
                  if ENV['PACT_BROKER_HIDE_PACTFLOW_MESSAGES'] != 'true'
         | 
| 243 | 
            +
                    logger.info "\n\n#{'*' * 80}\n\nWant someone to manage your Pact Broker for you? Check out https://pactflow.io/oss for a hardened, fully supported SaaS version of the Pact Broker with an improved UI + more.\n\n#{'*' * 80}\n"
         | 
| 244 | 
            +
                  end
         | 
| 236 245 | 
             
                end
         | 
| 237 246 | 
             
              end
         | 
| 238 247 | 
             
            end
         | 
    
        data/lib/pact_broker/db.rb
    CHANGED
    
    | @@ -2,12 +2,12 @@ require 'sequel' | |
| 2 2 | 
             
            require 'pact_broker/db/validate_encoding'
         | 
| 3 3 | 
             
            require 'pact_broker/db/migrate'
         | 
| 4 4 | 
             
            require 'pact_broker/db/migrate_data'
         | 
| 5 | 
            +
            require 'pact_broker/db/version'
         | 
| 5 6 |  | 
| 6 7 | 
             
            Sequel.datetime_class = DateTime
         | 
| 7 8 |  | 
| 8 9 | 
             
            module PactBroker
         | 
| 9 10 | 
             
              module DB
         | 
| 10 | 
            -
             | 
| 11 11 | 
             
                MIGRATIONS_DIR = File.expand_path("../../../db/migrations", __FILE__)
         | 
| 12 12 |  | 
| 13 13 | 
             
                def self.connection= connection
         | 
| @@ -27,6 +27,14 @@ module PactBroker | |
| 27 27 | 
             
                  PactBroker::DB::MigrateData.(database_connection)
         | 
| 28 28 | 
             
                end
         | 
| 29 29 |  | 
| 30 | 
            +
                def self.is_current? database_connection, options = {}
         | 
| 31 | 
            +
                  Sequel::TimestampMigrator.is_current?(database_connection, PactBroker::DB::MIGRATIONS_DIR, options)
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                def self.version database_connection
         | 
| 35 | 
            +
                  PactBroker::DB::Version.call(database_connection)
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 30 38 | 
             
                def self.validate_connection_config
         | 
| 31 39 | 
             
                  PactBroker::DB::ValidateEncoding.(connection)
         | 
| 32 40 | 
             
                end
         | 
| @@ -46,7 +46,11 @@ module PactBroker | |
| 46 46 | 
             
                    private
         | 
| 47 47 |  | 
| 48 48 | 
             
                    def base_url
         | 
| 49 | 
            -
                       | 
| 49 | 
            +
                      # Using the X-Forwarded headers in the UI can leave the app vulnerable
         | 
| 50 | 
            +
                      # https://www.acunetix.com/blog/articles/automated-detection-of-host-header-attacks/
         | 
| 51 | 
            +
                      # Either use the explicitly configured base url or an empty string,
         | 
| 52 | 
            +
                      # rather than request.base_url, which uses the X-Forwarded headers.
         | 
| 53 | 
            +
                      PactBroker.configuration.base_url || ''
         | 
| 50 54 | 
             
                    end
         | 
| 51 55 | 
             
                  end
         | 
| 52 56 | 
             
                end
         | 
| @@ -2,6 +2,7 @@ require 'json' | |
| 2 2 | 
             
            require 'sequel'
         | 
| 3 3 | 
             
            require 'pact_broker/repositories/helpers'
         | 
| 4 4 | 
             
            require 'pact_broker/tags/tag_with_latest_flag'
         | 
| 5 | 
            +
            require 'pact_broker/pacts/content'
         | 
| 5 6 |  | 
| 6 7 |  | 
| 7 8 | 
             
            module PactBroker
         | 
| @@ -83,6 +84,18 @@ module PactBroker | |
| 83 84 | 
             
                  def latest_pact_publication
         | 
| 84 85 | 
             
                    pact_version.latest_pact_publication
         | 
| 85 86 | 
             
                  end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                  def interactions_missing_test_results
         | 
| 89 | 
            +
                    @interactions_missing_test_results ||= pact_content_with_test_results.interactions_missing_test_results
         | 
| 90 | 
            +
                  end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                  def all_interactions_missing_test_results?
         | 
| 93 | 
            +
                    pact_content_with_test_results.interactions.count == pact_content_with_test_results.interactions_missing_test_results.count
         | 
| 94 | 
            +
                  end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                  def pact_content_with_test_results
         | 
| 97 | 
            +
                    @pact_content_with_test_results = PactBroker::Pacts::Content.from_json(pact_version.content).with_test_results(test_results)
         | 
| 98 | 
            +
                  end
         | 
| 86 99 | 
             
                end
         | 
| 87 100 |  | 
| 88 101 | 
             
                Verification.plugin :timestamps
         | 
| @@ -31,8 +31,8 @@ module PactBroker | |
| 31 31 | 
             
                  end
         | 
| 32 32 |  | 
| 33 33 | 
             
                  def self.delete(consumer_name, provider_name)
         | 
| 34 | 
            -
                    consumer = pacticipant_service.find_pacticipant_by_name(consumer_name)
         | 
| 35 | 
            -
                    provider = pacticipant_service.find_pacticipant_by_name(provider_name)
         | 
| 34 | 
            +
                    consumer = pacticipant_service.find_pacticipant_by_name!(consumer_name)
         | 
| 35 | 
            +
                    provider = pacticipant_service.find_pacticipant_by_name!(provider_name)
         | 
| 36 36 | 
             
                    # this takes care of the triggered webhooks and webhook executions
         | 
| 37 37 | 
             
                    pact_service.delete_all_pact_publications_between(consumer_name, and: provider_name)
         | 
| 38 38 | 
             
                    verification_service.delete_all_verifications_between(consumer_name, and: provider_name)
         | 
    
        data/lib/pact_broker/logging.rb
    CHANGED
    
    | @@ -34,7 +34,9 @@ module PactBroker | |
| 34 34 | 
             
                  message = "#{e.class} #{e.message}\n#{e.backtrace.join("\n")}"
         | 
| 35 35 | 
             
                  message = "#{description} - #{message}" if description
         | 
| 36 36 | 
             
                  logger.error message
         | 
| 37 | 
            -
                   | 
| 37 | 
            +
                  if ENV['PACT_BROKER_HIDE_PACTFLOW_MESSAGES'] != 'true'
         | 
| 38 | 
            +
                    logger.info "\n\n#{'*' * 80}\n\nPrefer it was someone else's job to deal with this error? Check out https://pactflow.io/oss for a hardened, fully supported SaaS version of the Pact Broker with an improved UI  + more.\n\n#{'*' * 80}\n"
         | 
| 39 | 
            +
                  end
         | 
| 38 40 | 
             
                end
         | 
| 39 41 | 
             
              end
         | 
| 40 42 |  | 
| @@ -31,7 +31,7 @@ module PactBroker | |
| 31 31 | 
             
                  end
         | 
| 32 32 |  | 
| 33 33 | 
             
                  def reasons
         | 
| 34 | 
            -
                    error_messages.any? ? error_messages : success_messages
         | 
| 34 | 
            +
                    error_messages.any? ? error_messages + warning_messages : success_messages + warning_messages
         | 
| 35 35 | 
             
                  end
         | 
| 36 36 |  | 
| 37 37 | 
             
                  private
         | 
| @@ -51,6 +51,10 @@ module PactBroker | |
| 51 51 | 
             
                    end
         | 
| 52 52 | 
             
                  end
         | 
| 53 53 |  | 
| 54 | 
            +
                  def warning_messages
         | 
| 55 | 
            +
                    warnings_for_missing_interactions
         | 
| 56 | 
            +
                  end
         | 
| 57 | 
            +
             | 
| 54 58 | 
             
                  def specified_selectors_that_do_not_exist
         | 
| 55 59 | 
             
                    resolved_selectors.select(&:specified_version_that_does_not_exist?)
         | 
| 56 60 | 
             
                  end
         | 
| @@ -182,6 +186,24 @@ module PactBroker | |
| 182 186 | 
             
                      [dummy_consumer_selector, dummy_provider_selector]
         | 
| 183 187 | 
             
                    end.flatten
         | 
| 184 188 | 
             
                  end
         | 
| 189 | 
            +
             | 
| 190 | 
            +
                  # experimental
         | 
| 191 | 
            +
                  def warnings_for_missing_interactions
         | 
| 192 | 
            +
                    rows.select(&:success).collect do | row |
         | 
| 193 | 
            +
                      begin
         | 
| 194 | 
            +
                        if row.verification.interactions_missing_test_results.any? && !row.verification.all_interactions_missing_test_results?
         | 
| 195 | 
            +
                          InteractionsMissingVerifications.new(selector_for(row.consumer_name), selector_for(row.provider_name), row.verification.interactions_missing_test_results)
         | 
| 196 | 
            +
                        end
         | 
| 197 | 
            +
                      rescue StandardError => e
         | 
| 198 | 
            +
                        log_error(e, "Error determining if there were missing interaction verifications")
         | 
| 199 | 
            +
                        nil
         | 
| 200 | 
            +
                      end
         | 
| 201 | 
            +
                    end.compact.tap { |it| report_missing_interaction_verifications(it) if it.any? }
         | 
| 202 | 
            +
                  end
         | 
| 203 | 
            +
             | 
| 204 | 
            +
                  def report_missing_interaction_verifications(messages)
         | 
| 205 | 
            +
                    logger.warn("Interactions missing verifications", messages)
         | 
| 206 | 
            +
                  end
         | 
| 185 207 | 
             
                end
         | 
| 186 208 | 
             
              end
         | 
| 187 209 | 
             
            end
         | 
| @@ -73,5 +73,14 @@ module PactBroker | |
| 73 73 | 
             
                # provider verifications.
         | 
| 74 74 | 
             
                class NoDependenciesMissing < Reason
         | 
| 75 75 | 
             
                end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                class InteractionsMissingVerifications < ErrorReasonWithTwoSelectors
         | 
| 78 | 
            +
                  attr_reader :interactions
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                  def initialize(consumer_selector, provider_selector, interactions)
         | 
| 81 | 
            +
                    super(consumer_selector, provider_selector)
         | 
| 82 | 
            +
                    @interactions = interactions
         | 
| 83 | 
            +
                  end
         | 
| 84 | 
            +
                end
         | 
| 76 85 | 
             
              end
         | 
| 77 86 | 
             
            end
         | 
| @@ -31,14 +31,25 @@ module PactBroker | |
| 31 31 | 
             
                    Content.from_hash(SortContent.call(pact_hash))
         | 
| 32 32 | 
             
                  end
         | 
| 33 33 |  | 
| 34 | 
            +
                  def interactions_missing_test_results
         | 
| 35 | 
            +
                    interactions.reject do | interaction |
         | 
| 36 | 
            +
                      interaction['tests']&.any?
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
             | 
| 34 40 | 
             
                  def with_test_results(test_results)
         | 
| 41 | 
            +
                    tests = test_results && test_results['tests']
         | 
| 42 | 
            +
                    if tests.nil? || !tests.is_a?(Array) || tests.empty?
         | 
| 43 | 
            +
                      tests = []
         | 
| 44 | 
            +
                    end
         | 
| 45 | 
            +
             | 
| 35 46 | 
             
                    new_pact_hash = pact_hash.dup
         | 
| 36 47 | 
             
                    if interactions && interactions.is_a?(Array)
         | 
| 37 | 
            -
                      new_pact_hash['interactions'] = merge_verification_results(interactions,  | 
| 48 | 
            +
                      new_pact_hash['interactions'] = merge_verification_results(interactions, tests)
         | 
| 38 49 | 
             
                    end
         | 
| 39 50 |  | 
| 40 51 | 
             
                    if messages && messages.is_a?(Array)
         | 
| 41 | 
            -
                      new_pact_hash['messages'] = merge_verification_results(messages,  | 
| 52 | 
            +
                      new_pact_hash['messages'] = merge_verification_results(messages, tests)
         | 
| 42 53 | 
             
                    end
         | 
| 43 54 | 
             
                    Content.from_hash(new_pact_hash)
         | 
| 44 55 | 
             
                  end
         | 
| @@ -107,6 +118,19 @@ module PactBroker | |
| 107 118 | 
             
                      end
         | 
| 108 119 | 
             
                    end
         | 
| 109 120 | 
             
                  end
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                  def merge_verification_results(interactions, tests)
         | 
| 123 | 
            +
                    interactions.collect(&:dup).collect do | interaction |
         | 
| 124 | 
            +
                      interaction['tests'] = tests.select do | test |
         | 
| 125 | 
            +
                        test_is_for_interaction(interaction, test)
         | 
| 126 | 
            +
                      end
         | 
| 127 | 
            +
                      interaction
         | 
| 128 | 
            +
                    end
         | 
| 129 | 
            +
                  end
         | 
| 130 | 
            +
             | 
| 131 | 
            +
                  def test_is_for_interaction(interaction, test)
         | 
| 132 | 
            +
                    test.is_a?(Hash) && interaction.is_a?(Hash) && test['interactionDescription'] == interaction['description'] && test['interactionProviderState'] == interaction['providerState']
         | 
| 133 | 
            +
                  end
         | 
| 110 134 | 
             
                end
         | 
| 111 135 | 
             
              end
         | 
| 112 136 | 
             
            end
         | 
| @@ -107,8 +107,8 @@ module PactBroker | |
| 107 107 | 
             
                  end
         | 
| 108 108 |  | 
| 109 109 | 
             
                  def delete_all_pact_publications_between consumer_name, options
         | 
| 110 | 
            -
                    consumer = pacticipant_repository.find_by_name(consumer_name)
         | 
| 111 | 
            -
                    provider = pacticipant_repository.find_by_name(options.fetch(:and))
         | 
| 110 | 
            +
                    consumer = pacticipant_repository.find_by_name!(consumer_name)
         | 
| 111 | 
            +
                    provider = pacticipant_repository.find_by_name!(options.fetch(:and))
         | 
| 112 112 | 
             
                    query = PactPublication.where(consumer: consumer, provider: provider)
         | 
| 113 113 | 
             
                    query = query.tag(options[:tag]) if options[:tag]
         | 
| 114 114 |  | 
| @@ -16,8 +16,10 @@ module PactBroker | |
| 16 16 | 
             
                class MigrationTask < ::Rake::TaskLib
         | 
| 17 17 |  | 
| 18 18 | 
             
                  attr_accessor :database_connection
         | 
| 19 | 
            +
                  attr_accessor :options
         | 
| 19 20 |  | 
| 20 21 | 
             
                  def initialize &block
         | 
| 22 | 
            +
                    @options = {}
         | 
| 21 23 | 
             
                    rake_task &block
         | 
| 22 24 | 
             
                  end
         | 
| 23 25 |  | 
| @@ -27,12 +29,29 @@ module PactBroker | |
| 27 29 | 
             
                        desc "Run sequel migrations for pact broker database"
         | 
| 28 30 | 
             
                        task :migrate, [:target] do | t, args |
         | 
| 29 31 | 
             
                          require 'pact_broker/db/migrate'
         | 
| 32 | 
            +
                          require 'pact_broker/db/version'
         | 
| 33 | 
            +
             | 
| 30 34 | 
             
                          instance_eval(&block)
         | 
| 31 | 
            -
             | 
| 35 | 
            +
             | 
| 32 36 | 
             
                          if args[:target]
         | 
| 33 37 | 
             
                            options[:target] = args[:target].to_i
         | 
| 34 38 | 
             
                          end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                          if (logger = database_connection.loggers.first)
         | 
| 41 | 
            +
                            current_version = PactBroker::DB::Version.call(database_connection)
         | 
| 42 | 
            +
                            if options[:target]
         | 
| 43 | 
            +
                              logger.info "Migrating from schema version #{current_version} to #{options[:target]}"
         | 
| 44 | 
            +
                            else
         | 
| 45 | 
            +
                              logger.info "Migrating from schema version #{current_version} to latest"
         | 
| 46 | 
            +
                            end
         | 
| 47 | 
            +
                          end
         | 
| 48 | 
            +
             | 
| 35 49 | 
             
                          PactBroker::DB::Migrate.call(database_connection, options)
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                          if logger
         | 
| 52 | 
            +
                            current_version = PactBroker::DB::Version.call(database_connection)
         | 
| 53 | 
            +
                            logger.info "Current schema version is now #{current_version}"
         | 
| 54 | 
            +
                          end
         | 
| 36 55 | 
             
                        end
         | 
| 37 56 | 
             
                      end
         | 
| 38 57 | 
             
                    end
         | 
| @@ -12,7 +12,7 @@ module PactBroker | |
| 12 12 | 
             
                    set :dump_errors, false # The padrino logger logs these for us. If this is enabled we get duplicate logging.
         | 
| 13 13 |  | 
| 14 14 | 
             
                    def base_url
         | 
| 15 | 
            -
                      PactBroker.configuration.base_url ||  | 
| 15 | 
            +
                      PactBroker.configuration.base_url || ''
         | 
| 16 16 | 
             
                    end
         | 
| 17 17 | 
             
                  end
         | 
| 18 18 | 
             
                end
         | 
| @@ -136,8 +136,8 @@ module PactBroker | |
| 136 136 | 
             
                  end
         | 
| 137 137 |  | 
| 138 138 | 
             
                  def delete_all_verifications_between(consumer_name, options)
         | 
| 139 | 
            -
                    consumer = pacticipant_repository.find_by_name(consumer_name)
         | 
| 140 | 
            -
                    provider = pacticipant_repository.find_by_name(options.fetch(:and))
         | 
| 139 | 
            +
                    consumer = pacticipant_repository.find_by_name!(consumer_name)
         | 
| 140 | 
            +
                    provider = pacticipant_repository.find_by_name!(options.fetch(:and))
         | 
| 141 141 | 
             
                    PactBroker::Domain::Verification.where(provider: provider, consumer: consumer).delete
         | 
| 142 142 | 
             
                  end
         | 
| 143 143 |  | 
    
        data/lib/pact_broker/version.rb
    CHANGED
    
    
| @@ -2,8 +2,10 @@ | |
| 2 2 | 
             
              "success": true,
         | 
| 3 3 | 
             
              "providerApplicationVersion": "1.0.0",
         | 
| 4 4 | 
             
              "testResults": {
         | 
| 5 | 
            -
                " | 
| 5 | 
            +
                "tests": [
         | 
| 6 6 | 
             
                  {
         | 
| 7 | 
            +
                    "interactionDescription": "a request for something",
         | 
| 8 | 
            +
                    "interactionProviderState": null,
         | 
| 7 9 | 
             
                    "description": "has status code 200",
         | 
| 8 10 | 
             
                    "file_path": "/redacted/.gem/ruby/2.4.1/gems/pact-1.17.0/lib/pact/provider/rspec.rb",
         | 
| 9 11 | 
             
                    "full_description": "Verifying a pact between me and they Greeting with GET / returns a response which has status code 200",
         | 
    
        data/script/foo-bar.json
    CHANGED
    
    | @@ -17,6 +17,17 @@ | |
| 17 17 | 
             
                    "status": 200,
         | 
| 18 18 | 
             
                    "body" : "something"
         | 
| 19 19 | 
             
                  }
         | 
| 20 | 
            +
                },{
         | 
| 21 | 
            +
                  "description" : "a request for something else",
         | 
| 22 | 
            +
                  "providerState": null,
         | 
| 23 | 
            +
                  "request": {
         | 
| 24 | 
            +
                    "method": "get",
         | 
| 25 | 
            +
                    "path" : "/something"
         | 
| 26 | 
            +
                  },
         | 
| 27 | 
            +
                  "response": {
         | 
| 28 | 
            +
                    "status": 200,
         | 
| 29 | 
            +
                    "body" : "something"
         | 
| 30 | 
            +
                  }
         | 
| 20 31 | 
             
                }
         | 
| 21 32 | 
             
              ]
         | 
| 22 33 | 
             
            }
         | 
| @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            describe "Deleting  | 
| 1 | 
            +
            describe "Deleting an integration" do
         | 
| 2 2 |  | 
| 3 3 | 
             
              let(:path) { "/integrations/provider/Bar/consumer/Foo" }
         | 
| 4 4 |  | 
| @@ -19,7 +19,7 @@ describe "Deleting pact versions" do | |
| 19 19 | 
             
                end
         | 
| 20 20 | 
             
              end
         | 
| 21 21 |  | 
| 22 | 
            -
              context "when the  | 
| 22 | 
            +
              context "when the integration does not exist" do
         | 
| 23 23 | 
             
                it "returns a 404 Not Found" do
         | 
| 24 24 | 
             
                  expect(subject.status).to be 404
         | 
| 25 25 | 
             
                end
         | 
| @@ -32,5 +32,21 @@ describe "UI index" do | |
| 32 32 | 
             
                    expect(subject.body.scan('<tr').to_a.count).to eq 3
         | 
| 33 33 | 
             
                  end
         | 
| 34 34 | 
             
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                context "with the base_url not set" do
         | 
| 37 | 
            +
                  it "returns relative links" do
         | 
| 38 | 
            +
                    expect(subject.body).to include "href='/stylesheets"
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                context "with the base_url set" do
         | 
| 43 | 
            +
                  before do
         | 
| 44 | 
            +
                    allow(PactBroker.configuration).to receive(:base_url).and_return('http://example.org/pact-broker')
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  it "returns absolute links" do
         | 
| 48 | 
            +
                    expect(subject.body).to include "href='http://example.org/pact-broker/stylesheets"
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                end
         | 
| 35 51 | 
             
              end
         | 
| 36 52 | 
             
            end
         | 
| @@ -31,7 +31,7 @@ describe "UI matrix" do | |
| 31 31 | 
             
                subject { get("/matrix?q%5B%5Dpacticipant=Foo&q%5B%5Dtag=ctag&q%5B%5Dlatest=true&q%5B%5Dpacticipant=Bar&q%5B%5Dtag=ptag&q%5B%5Dlatest=true&latestby=cvpv&limit=100") }
         | 
| 32 32 |  | 
| 33 33 | 
             
                it "returns a page with a badge" do
         | 
| 34 | 
            -
                  expect(subject.body).to include " | 
| 34 | 
            +
                  expect(subject.body).to include "/matrix/provider/Bar/latest/ptag/consumer/Foo/latest/ctag/badge.svg"
         | 
| 35 35 | 
             
                end
         | 
| 36 36 | 
             
              end
         | 
| 37 37 | 
             
            end
         | 
| @@ -10,7 +10,7 @@ module PactBroker | |
| 10 10 |  | 
| 11 11 | 
             
                    describe "the number of Reason classes" do
         | 
| 12 12 | 
             
                      it "is 9 - add another spec here if a new Reason is added" do
         | 
| 13 | 
            -
                        expect(REASON_CLASSES.size).to eq  | 
| 13 | 
            +
                        expect(REASON_CLASSES.size).to eq 10
         | 
| 14 14 | 
             
                      end
         | 
| 15 15 | 
             
                    end
         | 
| 16 16 |  | 
| @@ -52,6 +52,23 @@ module PactBroker | |
| 52 52 |  | 
| 53 53 | 
             
                        its(:to_s) { is_expected.to eq "All required verification results are published and successful" }
         | 
| 54 54 | 
             
                      end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                      context "when the reason is PactBroker::Matrix::InteractionsMissingVerifications" do
         | 
| 57 | 
            +
                        let(:reason) { PactBroker::Matrix::InteractionsMissingVerifications.new(consumer_selector, provider_selector, interactions) }
         | 
| 58 | 
            +
                        let(:interactions) do
         | 
| 59 | 
            +
                          [
         | 
| 60 | 
            +
                            {
         | 
| 61 | 
            +
                              "description" => "desc1",
         | 
| 62 | 
            +
                              "providerState" => "p2"
         | 
| 63 | 
            +
                            },{
         | 
| 64 | 
            +
                              "description" => "desc1",
         | 
| 65 | 
            +
                              "providerStates" => [ { "name" => "desc3"}, { "name" => "desc4"} ]
         | 
| 66 | 
            +
                            }
         | 
| 67 | 
            +
                          ]
         | 
| 68 | 
            +
                        end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                        its(:to_s) { is_expected.to eq "WARNING: Although the verification was reported as successful, the results for version 2 of Foo and version 6 of Bar may be missing tests for the following interactions: desc1 given p2; desc1 given desc3, desc4" }
         | 
| 71 | 
            +
                      end
         | 
| 55 72 | 
             
                    end
         | 
| 56 73 | 
             
                  end
         | 
| 57 74 | 
             
                end
         | 
| @@ -26,6 +26,22 @@ module PactBroker | |
| 26 26 | 
             
                          subject
         | 
| 27 27 | 
             
                          expect(last_response.body).to include "<html>"
         | 
| 28 28 | 
             
                        end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                        context "with the base_url not set" do
         | 
| 31 | 
            +
                          it "returns relative links" do
         | 
| 32 | 
            +
                            expect(subject.body).to include "href='/css"
         | 
| 33 | 
            +
                          end
         | 
| 34 | 
            +
                        end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                        context "with the base_url set" do
         | 
| 37 | 
            +
                          before do
         | 
| 38 | 
            +
                            allow(PactBroker.configuration).to receive(:base_url).and_return('http://example.org/pact-broker')
         | 
| 39 | 
            +
                          end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                          it "returns absolute links" do
         | 
| 42 | 
            +
                            expect(subject.body).to include "href='http://example.org/pact-broker/css"
         | 
| 43 | 
            +
                          end
         | 
| 44 | 
            +
                        end
         | 
| 29 45 | 
             
                      end
         | 
| 30 46 |  | 
| 31 47 | 
             
                      context "when the resource does not exist" do
         | 
| @@ -248,6 +248,12 @@ module PactBroker | |
| 248 248 | 
             
                        Service.delete("Foo", "Foo")
         | 
| 249 249 | 
             
                      end
         | 
| 250 250 | 
             
                    end
         | 
| 251 | 
            +
             | 
| 252 | 
            +
                    context "when the pacticipants are not found for some bizarre reason (I can't see how this can happen, but it has)" do
         | 
| 253 | 
            +
                      it "raises an error" do
         | 
| 254 | 
            +
                        expect { Service.delete("Foo", "Bar") }.to raise_error(PactBroker::Error, /found/)
         | 
| 255 | 
            +
                      end
         | 
| 256 | 
            +
                    end
         | 
| 251 257 | 
             
                  end
         | 
| 252 258 |  | 
| 253 259 | 
             
                  describe "delete_all" do
         | 
| @@ -29,7 +29,8 @@ module PactBroker | |
| 29 29 | 
             
                        provider_name: bar.name,
         | 
| 30 30 | 
             
                        provider_id: bar.id,
         | 
| 31 31 | 
             
                        success: row_1_success,
         | 
| 32 | 
            -
                        pacticipant_names: [foo.name, bar.name]
         | 
| 32 | 
            +
                        pacticipant_names: [foo.name, bar.name],
         | 
| 33 | 
            +
                        verification: verification_1
         | 
| 33 34 | 
             
                      )
         | 
| 34 35 | 
             
                    end
         | 
| 35 36 |  | 
| @@ -46,7 +47,8 @@ module PactBroker | |
| 46 47 | 
             
                        provider_name: baz.name,
         | 
| 47 48 | 
             
                        provider_id: baz.id,
         | 
| 48 49 | 
             
                        success: true,
         | 
| 49 | 
            -
                        pacticipant_names: [foo.name, baz.name]
         | 
| 50 | 
            +
                        pacticipant_names: [foo.name, baz.name],
         | 
| 51 | 
            +
                        verification: verification_2
         | 
| 50 52 | 
             
                      )
         | 
| 51 53 | 
             
                    end
         | 
| 52 54 |  | 
| @@ -65,6 +67,8 @@ module PactBroker | |
| 65 67 | 
             
                    let(:foo_version) { double('foo version', number: "ddec8101dabf4edf9125a69f9a161f0f294af43c", id: 10)}
         | 
| 66 68 | 
             
                    let(:bar_version) { double('bar version', number: "14131c5da3abf323ccf410b1b619edac76231243", id: 11)}
         | 
| 67 69 | 
             
                    let(:baz_version) { double('baz version', number: "4ee06460f10e8207ad904fa9fa6c4842e462ab59", id: 12)}
         | 
| 70 | 
            +
                    let(:verification_1) { double('verification 1', interactions_missing_test_results: []) }
         | 
| 71 | 
            +
                    let(:verification_2) { double('verification 2', interactions_missing_test_results: []) }
         | 
| 68 72 |  | 
| 69 73 | 
             
                    let(:resolved_selectors) do
         | 
| 70 74 | 
             
                      [
         | 
| @@ -416,6 +416,49 @@ module PactBroker | |
| 416 416 | 
             
                        expect(subject.deployment_status_summary).to be_deployable
         | 
| 417 417 | 
             
                      end
         | 
| 418 418 | 
             
                    end
         | 
| 419 | 
            +
             | 
| 420 | 
            +
                    describe "when verification results are published missing tests for some interactions" do
         | 
| 421 | 
            +
                      let(:pact_content) do
         | 
| 422 | 
            +
                        {
         | 
| 423 | 
            +
                          "interactions" => [
         | 
| 424 | 
            +
                            {
         | 
| 425 | 
            +
                              "description" => "desc1"
         | 
| 426 | 
            +
                            },{
         | 
| 427 | 
            +
                              "description" => "desc2"
         | 
| 428 | 
            +
                            }
         | 
| 429 | 
            +
                          ]
         | 
| 430 | 
            +
                        }
         | 
| 431 | 
            +
                      end
         | 
| 432 | 
            +
             | 
| 433 | 
            +
                      let(:verification_tests) do
         | 
| 434 | 
            +
                        [
         | 
| 435 | 
            +
                          {
         | 
| 436 | 
            +
                            "interactionDescription" => "desc1"
         | 
| 437 | 
            +
                          }
         | 
| 438 | 
            +
                        ]
         | 
| 439 | 
            +
                      end
         | 
| 440 | 
            +
             | 
| 441 | 
            +
                      before do
         | 
| 442 | 
            +
                        td.create_consumer("Foo")
         | 
| 443 | 
            +
                          .create_provider("Bar")
         | 
| 444 | 
            +
                          .create_consumer_version
         | 
| 445 | 
            +
                          .create_pact(json_content: pact_content.to_json)
         | 
| 446 | 
            +
                          .create_verification(provider_version: "1", test_results: { tests: verification_tests })
         | 
| 447 | 
            +
                      end
         | 
| 448 | 
            +
             | 
| 449 | 
            +
                      let(:selectors) do
         | 
| 450 | 
            +
                        [
         | 
| 451 | 
            +
                          UnresolvedSelector.new(pacticipant_name: "Foo", latest: true),
         | 
| 452 | 
            +
                          UnresolvedSelector.new(pacticipant_name: "Bar", latest: true)
         | 
| 453 | 
            +
                        ]
         | 
| 454 | 
            +
                      end
         | 
| 455 | 
            +
             | 
| 456 | 
            +
                      let(:options) { { latestby: "cvpv"} }
         | 
| 457 | 
            +
             | 
| 458 | 
            +
                      it "should include a warning" do
         | 
| 459 | 
            +
                        expect(subject.deployment_status_summary.reasons.last).to be_a(PactBroker::Matrix::InteractionsMissingVerifications)
         | 
| 460 | 
            +
                      end
         | 
| 461 | 
            +
                    end
         | 
| 419 462 | 
             
                  end
         | 
| 420 463 | 
             
                end
         | 
| 421 464 | 
             
              end
         | 
| @@ -227,6 +227,131 @@ module PactBroker | |
| 227 227 | 
             
                      its(:pact_specification_version) { is_expected.to eq nil }
         | 
| 228 228 | 
             
                    end
         | 
| 229 229 | 
             
                  end
         | 
| 230 | 
            +
             | 
| 231 | 
            +
                  describe "with_test_results" do
         | 
| 232 | 
            +
                    let(:test_results) do
         | 
| 233 | 
            +
                      {
         | 
| 234 | 
            +
                        "tests" => [
         | 
| 235 | 
            +
                          {
         | 
| 236 | 
            +
                            "interactionProviderState" => "ps1",
         | 
| 237 | 
            +
                            "interactionDescription" => "desc1"
         | 
| 238 | 
            +
                          },{
         | 
| 239 | 
            +
                            "interactionProviderState" => "ps1",
         | 
| 240 | 
            +
                            "interactionDescription" => "desc1"
         | 
| 241 | 
            +
                          }
         | 
| 242 | 
            +
                        ]
         | 
| 243 | 
            +
                      }
         | 
| 244 | 
            +
                    end
         | 
| 245 | 
            +
             | 
| 246 | 
            +
                    let(:pact_content) do
         | 
| 247 | 
            +
                      {
         | 
| 248 | 
            +
                        "interactions" => [
         | 
| 249 | 
            +
                          {
         | 
| 250 | 
            +
                           "providerState" => "ps1",
         | 
| 251 | 
            +
                           "description" => "desc1",
         | 
| 252 | 
            +
                          },
         | 
| 253 | 
            +
                          {
         | 
| 254 | 
            +
                           "providerState" => "ps2",
         | 
| 255 | 
            +
                           "description" => "desc2",
         | 
| 256 | 
            +
                          }
         | 
| 257 | 
            +
                        ]
         | 
| 258 | 
            +
                      }
         | 
| 259 | 
            +
                    end
         | 
| 260 | 
            +
             | 
| 261 | 
            +
                    subject { Content.from_hash(pact_content).with_test_results(test_results) }
         | 
| 262 | 
            +
             | 
| 263 | 
            +
                    let(:merged) do
         | 
| 264 | 
            +
                      {
         | 
| 265 | 
            +
                        "interactions" => [
         | 
| 266 | 
            +
                          {
         | 
| 267 | 
            +
                           "providerState" => "ps1",
         | 
| 268 | 
            +
                           "description" => "desc1",
         | 
| 269 | 
            +
                           "tests" => [
         | 
| 270 | 
            +
                            {
         | 
| 271 | 
            +
                              "interactionProviderState" => "ps1",
         | 
| 272 | 
            +
                              "interactionDescription" => "desc1",
         | 
| 273 | 
            +
                            },{
         | 
| 274 | 
            +
                              "interactionProviderState" => "ps1",
         | 
| 275 | 
            +
                              "interactionDescription" => "desc1",
         | 
| 276 | 
            +
                            }
         | 
| 277 | 
            +
                           ]
         | 
| 278 | 
            +
                          },{
         | 
| 279 | 
            +
                           "providerState" => "ps2",
         | 
| 280 | 
            +
                           "description" => "desc2",
         | 
| 281 | 
            +
                           "tests" => []
         | 
| 282 | 
            +
                          }
         | 
| 283 | 
            +
                        ]
         | 
| 284 | 
            +
                      }
         | 
| 285 | 
            +
                    end
         | 
| 286 | 
            +
             | 
| 287 | 
            +
                    let(:merged_with_empty_tests) do
         | 
| 288 | 
            +
                      {
         | 
| 289 | 
            +
                        "interactions" => [
         | 
| 290 | 
            +
                          {
         | 
| 291 | 
            +
                           "providerState" => "ps1",
         | 
| 292 | 
            +
                           "description" => "desc1",
         | 
| 293 | 
            +
                           "tests" => []
         | 
| 294 | 
            +
                          },{
         | 
| 295 | 
            +
                           "providerState" => "ps2",
         | 
| 296 | 
            +
                           "description" => "desc2",
         | 
| 297 | 
            +
                           "tests" => []
         | 
| 298 | 
            +
                          }
         | 
| 299 | 
            +
                        ]
         | 
| 300 | 
            +
                      }
         | 
| 301 | 
            +
                    end
         | 
| 302 | 
            +
             | 
| 303 | 
            +
                    it "merges the contents with the results" do
         | 
| 304 | 
            +
                      expect(subject.to_hash).to eq merged
         | 
| 305 | 
            +
                    end
         | 
| 306 | 
            +
             | 
| 307 | 
            +
                    it "returns interactions without test results" do
         | 
| 308 | 
            +
                      expect(subject.interactions_missing_test_results.count).to eq 1
         | 
| 309 | 
            +
                    end
         | 
| 310 | 
            +
             | 
| 311 | 
            +
                    context "with nil test results" do
         | 
| 312 | 
            +
                      let(:test_results) { nil }
         | 
| 313 | 
            +
             | 
| 314 | 
            +
                      it "does not blow up" do
         | 
| 315 | 
            +
                        expect(subject.to_hash).to eq merged_with_empty_tests
         | 
| 316 | 
            +
                      end
         | 
| 317 | 
            +
             | 
| 318 | 
            +
                      it "returns interactions without test results" do
         | 
| 319 | 
            +
                        expect(subject.interactions_missing_test_results.count).to eq 2
         | 
| 320 | 
            +
                      end
         | 
| 321 | 
            +
                    end
         | 
| 322 | 
            +
             | 
| 323 | 
            +
                    context "with nil tests" do
         | 
| 324 | 
            +
                      let(:test_results) { {} }
         | 
| 325 | 
            +
             | 
| 326 | 
            +
                      it "does not blow up" do
         | 
| 327 | 
            +
                        expect(subject.to_hash).to eq merged_with_empty_tests
         | 
| 328 | 
            +
                      end
         | 
| 329 | 
            +
                    end
         | 
| 330 | 
            +
             | 
| 331 | 
            +
                    context "with empty tests" do
         | 
| 332 | 
            +
                      let(:test_results) { { "tests" => [] } }
         | 
| 333 | 
            +
             | 
| 334 | 
            +
                      it "does not blow up" do
         | 
| 335 | 
            +
                        expect(subject.to_hash).to eq merged_with_empty_tests
         | 
| 336 | 
            +
                      end
         | 
| 337 | 
            +
                    end
         | 
| 338 | 
            +
             | 
| 339 | 
            +
                    context "with tests not an array" do
         | 
| 340 | 
            +
                      let(:test_results) { { "tests" => {} } }
         | 
| 341 | 
            +
             | 
| 342 | 
            +
                      it "does not blow up" do
         | 
| 343 | 
            +
                        expect(subject.to_hash).to eq merged_with_empty_tests
         | 
| 344 | 
            +
                      end
         | 
| 345 | 
            +
                    end
         | 
| 346 | 
            +
             | 
| 347 | 
            +
                    context "with tests an array of not hashes" do
         | 
| 348 | 
            +
                      let(:test_results) { { "tests" => [1] } }
         | 
| 349 | 
            +
             | 
| 350 | 
            +
                      it "does not blow up" do
         | 
| 351 | 
            +
                        expect(subject.to_hash).to eq merged_with_empty_tests
         | 
| 352 | 
            +
                      end
         | 
| 353 | 
            +
                    end
         | 
| 354 | 
            +
                  end
         | 
| 230 355 | 
             
                end
         | 
| 231 356 | 
             
              end
         | 
| 232 357 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: pact_broker
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2. | 
| 4 | 
            +
              version: 2.56.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Bethany Skurrie
         | 
| @@ -10,7 +10,7 @@ authors: | |
| 10 10 | 
             
            autorequire: 
         | 
| 11 11 | 
             
            bindir: bin
         | 
| 12 12 | 
             
            cert_chain: []
         | 
| 13 | 
            -
            date: 2020- | 
| 13 | 
            +
            date: 2020-06-01 00:00:00.000000000 Z
         | 
| 14 14 | 
             
            dependencies:
         | 
| 15 15 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 16 16 | 
             
              name: httparty
         |