-
-
Notifications
You must be signed in to change notification settings - Fork 174
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add 'pacts for verification' endpoint (#308)
* feat: add endpoint for "verifiable pacts" which returns a list of pacts to be verified and marks which ones should be considered "pending" and not fail the build * feat: add beta:provider-pacts-for-verification rel to index * feat: squash pacts with the same pact version sha into one 'pact' * feat: compose messages to explain why pacts are in pending/non pending state, and why they have been included in the verification step * feat: use pending and inclusion messages in the pacts for verification response * feat: add 'read more' link to pending reason * feat: add feature flag to turn on pact for verifications relation
- Loading branch information
Showing
35 changed files
with
1,200 additions
and
171 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
lib/pact_broker/api/contracts/verifiable_pacts_query_schema.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
require 'dry-validation' | ||
|
||
module PactBroker | ||
module Api | ||
module Contracts | ||
class VerifiablePactsQuerySchema | ||
SCHEMA = Dry::Validation.Schema do | ||
optional(:provider_version_tags).maybe(:array?) | ||
# optional(:exclude_other_pending).filled(included_in?: ["true", "false"]) | ||
optional(:consumer_version_selectors).each do | ||
schema do | ||
required(:tag).filled(:str?) | ||
optional(:latest).filled(included_in?: ["true", "false"]) | ||
end | ||
end | ||
end | ||
|
||
def self.call(params) | ||
select_first_message(flatten_index_messages(SCHEMA.call(params).messages(full: true))) | ||
end | ||
|
||
def self.select_first_message(messages) | ||
messages.each_with_object({}) do | (key, value), new_messages | | ||
new_messages[key] = [value.first] | ||
end | ||
end | ||
|
||
def self.flatten_index_messages(messages) | ||
if messages[:consumer_version_selectors] | ||
new_messages = messages[:consumer_version_selectors].collect do | index, value | | ||
value.values.flatten.collect { | text | "#{text} at index #{index}"} | ||
end.flatten | ||
messages.merge(consumer_version_selectors: new_messages) | ||
else | ||
messages | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
34 changes: 34 additions & 0 deletions
34
lib/pact_broker/api/decorators/verifiable_pact_decorator.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
lib/pact_broker/api/decorators/verifiable_pacts_query_decorator.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
require_relative 'base_decorator' | ||
require_relative 'verifiable_pact_decorator' | ||
require 'pact_broker/api/pact_broker_urls' | ||
|
||
module PactBroker | ||
module Api | ||
module Decorators | ||
class VerifiablePactsQueryDecorator < BaseDecorator | ||
collection :provider_version_tags | ||
|
||
collection :consumer_version_selectors, class: OpenStruct do | ||
property :tag | ||
property :latest, setter: ->(fragment:, represented:, **) { represented.latest = (fragment == 'true') } | ||
end | ||
|
||
|
||
def from_hash(*args) | ||
# Should remember how to do this via Representable... | ||
result = super | ||
result.consumer_version_selectors = [] if result.consumer_version_selectors.nil? | ||
result.provider_version_tags = [] if result.provider_version_tags.nil? | ||
result | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
54 changes: 54 additions & 0 deletions
54
lib/pact_broker/api/resources/provider_pacts_for_verification.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
require 'pact_broker/api/resources/provider_pacts' | ||
require 'pact_broker/api/decorators/verifiable_pacts_decorator' | ||
require 'pact_broker/api/contracts/verifiable_pacts_query_schema' | ||
require 'pact_broker/api/decorators/verifiable_pacts_query_decorator' | ||
|
||
module PactBroker | ||
module Api | ||
module Resources | ||
class ProviderPactsForVerification < ProviderPacts | ||
def initialize | ||
@query = Rack::Utils.parse_nested_query(request.uri.query) | ||
end | ||
|
||
def malformed_request? | ||
if (errors = query_schema.call(query)).any? | ||
set_json_validation_error_messages(errors) | ||
true | ||
else | ||
false | ||
end | ||
end | ||
|
||
private | ||
|
||
attr_reader :query | ||
|
||
def pacts | ||
pact_service.find_for_verification( | ||
provider_name, | ||
parsed_query_params.provider_version_tags, | ||
parsed_query_params.consumer_version_selectors | ||
) | ||
end | ||
|
||
def resource_title | ||
"Pacts to be verified by provider #{provider_name}" | ||
end | ||
|
||
def to_json | ||
PactBroker::Api::Decorators::VerifiablePactsDecorator.new(pacts).to_json(to_json_options) | ||
end | ||
|
||
|
||
def query_schema | ||
PactBroker::Api::Contracts::VerifiablePactsQuerySchema | ||
end | ||
|
||
def parsed_query_params | ||
@parsed_query_params ||= PactBroker::Api::Decorators::VerifiablePactsQueryDecorator.new(OpenStruct.new).from_hash(query) | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
require 'delegate' | ||
|
||
# A head pact is the pact for the latest consumer version with the specified tag | ||
# (ignoring later versions that might have the specified tag but no pact) | ||
|
||
module PactBroker | ||
module Pacts | ||
class HeadPact < SimpleDelegator | ||
attr_reader :tag, :consumer_version_number | ||
|
||
def initialize(pact, consumer_version_number, tag) | ||
super(pact) | ||
@consumer_version_number = consumer_version_number | ||
@tag = tag | ||
end | ||
|
||
# The underlying pact publication may well be the overall latest as well, but | ||
# this row does not know that, as there will be a row with a nil tag | ||
# if it is the overall latest as well as a row with the | ||
# tag set, as the data is denormalised in the LatestTaggedPactPublications table. | ||
def overall_latest? | ||
tag.nil? | ||
end | ||
|
||
def pact | ||
__getobj__() | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.