Skip to content

Commit

Permalink
feat(matrix): add validation errors to matrix resource
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Oct 9, 2017
1 parent 531e087 commit 7f91710
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 12 deletions.
22 changes: 13 additions & 9 deletions lib/pact_broker/api/resources/matrix.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,34 @@ def allowed_methods
["GET"]
end

def resource_exists?
true
def malformed_request?
error_messages = matrix_service.validate_selectors(selectors)
if error_messages.any?
set_json_validation_error_messages error_messages
true
else
false
end
end

def to_json
versions = version_service.find_versions_by_selector(version_selectors)
criteria = versions.each_with_object({}) { | version, hash | hash[version.pacticipant.name] = version.number }
criteria = selected_versions.each_with_object({}) { | version, hash | hash[version.pacticipant.name] = version.number }
lines = matrix_service.find_compatible_pacticipant_versions(criteria)
PactBroker::Api::Decorators::MatrixPactDecorator.new(lines).to_json(user_options: { base_url: base_url })
end

def selectors
@selectors ||= CGI.parse(request.uri.query)['selector[]']
@selectors ||= CGI.parse(CGI.unescape(request.uri.query))['selectors[]']
end

def version_selectors
@version_selectors ||= selectors.select{ | selector| selector.include?("/version/") }
end

def pacticipant_selectors
@pacticipant_selectors ||= selectors.select{ | selector | selectors.include?("/version/")}
def selected_versions
@selected_versions ||= version_service.find_versions_by_selector(version_selectors)
end

end
end
end
end
end
33 changes: 32 additions & 1 deletion lib/pact_broker/matrix/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
module PactBroker
module Matrix
module Service
extend self
VERSION_SELECTOR_PATTERN = %r{(^[^/]+)/version/[^/]+$}.freeze

extend self
extend PactBroker::Repositories
extend PactBroker::Services

def find params
matrix_repository.find params[:consumer_name], params[:provider_name]
Expand All @@ -14,6 +16,35 @@ def find params
def find_compatible_pacticipant_versions criteria
matrix_repository.find_compatible_pacticipant_versions criteria
end

def validate_selectors selectors
error_messages = []
selectors.each do | version_selector |
if !(version_selector =~ VERSION_SELECTOR_PATTERN)
error_messages << "Invalid version selector '#{version_selector}'. Format must be <pacticipant_name>/version/<version>"
end
end

selectors.each do | version_selector |
if match = version_selector.match(VERSION_SELECTOR_PATTERN)
pacticipant_name = match[1]
unless pacticipant_service.find_pacticipant_by_name(pacticipant_name)
error_messages << "Pacticipant '#{pacticipant_name}' not found"
end
end
end

if error_messages.empty?
selected_versions = version_service.find_versions_by_selector(selectors)
if selected_versions.any?(&:nil?)
selected_versions.each_with_index do | selected_version, i |
error_messages << "No pact or verification found for #{selectors[i]}"
end
end
end

error_messages
end
end
end
end
2 changes: 1 addition & 1 deletion spec/features/get_matrix_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
let(:path) { "/matrix" }
let(:params) do
{
selector: ['Consumer/version/1.0.0','Provider/version/4.5.6']
selectors: ['Consumer/version/1.0.0','Provider/version/4.5.6']
}
end
let(:last_response_body) { JSON.parse(subject.body, symbolize_names: true) }
Expand Down
38 changes: 38 additions & 0 deletions spec/lib/pact_broker/api/resources/matrix_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
require 'pact_broker/api/resources/matrix'
require 'pact_broker/matrix/service'

module PactBroker
module Api
module Resources
describe Matrix do
before do
allow(PactBroker::Matrix::Service).to receive(:validate_selectors).and_return(error_messages)
end

let(:td) { TestDataBuilder.new }
let(:path) { "/matrix" }
let(:json_response_body) { JSON.parse(subject.body, symbolize_names: true) }
let(:params) { { selectors: ['Foo/version/1', 'Bar/version/2'] } }
let(:error_messages) { [] }

subject { get path, params, {'Content-Type' => 'application/hal+json'}; last_response }

it "validates the selectors" do
expect(PactBroker::Matrix::Service).to receive(:validate_selectors).with(['Foo/version/1', 'Bar/version/2'])
subject
end

context "when a validation error occurs" do
let(:error_messages) { ['foo'] }
it "returns a 400 status" do
expect(subject.status).to eq 400
end

it "returns error messages" do
expect(json_response_body[:errors]).to eq ['foo']
end
end
end
end
end
end
42 changes: 42 additions & 0 deletions spec/lib/pact_broker/matrix/service_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
require 'pact_broker/matrix/service'

module PactBroker
module Matrix
describe Service do
describe "validate_selectors" do
let(:td) { TestDataBuilder.new }

subject { Service.validate_selectors(selectors) }

context "when a selector format is invalid" do
let(:selectors) { ["Foo/1"] }

it "returns error messages" do
expect(subject.first).to eq "Invalid version selector 'Foo/1'. Format must be <pacticipant_name>/version/<version>"
end
end

context "when one or more of the selectors does not match any known version" do
before do
td.create_pacticipant("Foo")
end

let(:selectors) { ["Foo/version/1"] }

it "returns error messages" do
expect(subject.first).to eq "No pact or verification found for Foo/version/1"
end
end

context "when the pacticipant does not exist" do
let(:selectors) { ["Foo/version/1"] }

it "returns error messages" do
expect(subject.first).to eq "Pacticipant 'Foo' not found"
end
end
end
end
end
end

Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

it "sets the created_at date of the new version to the created_at of the verification" do
subject
expect(PactBroker::Domain::Verification.first.provider_version.created_at).to eq now
expect(PactBroker::Domain::Verification.first.provider_version.created_at.to_datetime).to eq now
end

context "when the version already exists" do
Expand Down
12 changes: 12 additions & 0 deletions spec/service_consumers/provider_states_for_pact_broker_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@

Pact.provider_states_for "Pact Broker Client" do

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")
.create_verification(provider_version: "4.5.6")
.create_verification(provider_version: "7.8.9", number: 2)
.create_consumer_version("2.0.0")
.create_pact
.create_verification(provider_version: "4.5.6")
end
end

provider_state "the 'Pricing Service' does not exist in the pact-broker" do
no_op
end
Expand Down

0 comments on commit 7f91710

Please sign in to comment.