Skip to content

Commit

Permalink
feat(matrix): change query params for matrix to use pacticipant[]=? a…
Browse files Browse the repository at this point in the history
…nd version[]=?
  • Loading branch information
bethesque committed Oct 27, 2017
1 parent 8b630ad commit 41c20c5
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 44 deletions.
17 changes: 4 additions & 13 deletions lib/pact_broker/api/resources/matrix.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require 'pact_broker/api/resources/base_resource'
require 'pact_broker/api/decorators/matrix_decorator'
require 'cgi'
require 'pact_broker/matrix/parse_query'

module PactBroker
module Api
Expand All @@ -16,7 +16,7 @@ def allowed_methods
end

def malformed_request?
error_messages = matrix_service.validate_selectors(selectors)
error_messages = matrix_service.validate_selectors(criteria)
if error_messages.any?
set_json_validation_error_messages error_messages
true
Expand All @@ -26,21 +26,12 @@ def malformed_request?
end

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

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

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

def selected_versions
@selected_versions ||= version_service.find_versions_by_selector(version_selectors)
def criteria
@criteria ||= PactBroker::Matrix::ParseQuery.call(request.uri.query)
end
end
end
Expand Down
14 changes: 14 additions & 0 deletions lib/pact_broker/matrix/parse_query.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require 'cgi'

module PactBroker
module Matrix
class ParseQuery
def self.call query
params = CGI.parse(CGI.unescape(query))
params['pacticipant[]'].zip(params['version[]']).each_with_object({}) do | (pacticipant, version), hash |
hash[pacticipant] = version
end
end
end
end
end
23 changes: 6 additions & 17 deletions lib/pact_broker/matrix/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
module PactBroker
module Matrix
module Service
VERSION_SELECTOR_PATTERN = %r{(^[^/]+)/version/[^/]+$}.freeze

extend self
extend PactBroker::Repositories
Expand All @@ -23,27 +22,17 @@ def find_compatible_pacticipant_versions criteria

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
selectors.keys.each do | pacticipant_name |
unless pacticipant_service.find_pacticipant_by_name(pacticipant_name)
error_messages << "Pacticipant '#{pacticipant_name}' not found"
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]}" if selected_version.nil?
end
selectors.each do | pacticipant_name, version_number |
version = version_service.find_by_pacticipant_name_and_number(pacticipant_name: pacticipant_name, pacticipant_version_number: version_number)
error_messages << "No pact or verification found for #{pacticipant_name} version #{version_number}" if version.nil?
end
end

Expand Down
71 changes: 71 additions & 0 deletions script/seed-matrix.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/usr/bin/env ruby

raise "Please supply database path" unless ARGV[0]

$LOAD_PATH.unshift './lib'
$LOAD_PATH.unshift './spec'
ENV['RACK_ENV'] = 'development'
require 'sequel'
require 'logger'
DATABASE_CREDENTIALS = {logger: Logger.new($stdout), adapter: "sqlite", database: ARGV[0], :encoding => 'utf8'}
connection = Sequel.connect(DATABASE_CREDENTIALS)
connection.timezone = :utc
require 'pact_broker/db'
PactBroker::DB.connection = connection
require 'pact_broker'
require 'support/test_data_builder'


tables_to_clean = [:labels, :webhook_executions, :triggered_webhooks, :verifications, :pact_publications, :pact_versions, :pacts, :pact_version_contents, :tags, :versions, :webhook_headers, :webhooks, :pacticipants]

tables_to_clean.each do | table_name |
connection[table_name].delete if connection.table_exists?(table_name)
end

=begin
A -> B -> C
1 s 1 f 1
2 s 2
=end

# TestDataBuilder.new.create_pact_with_hierarchy("A", "1.2.3", "B")
# .use_provider("B")
# .create_version("2.0.0")
# .create_provider("C")
# .create_version("3.0.0")
# .create_pact

TestDataBuilder.new
.create_pact_with_hierarchy("A", "1", "B")
.create_verification(provider_version: '1')
.create_verification(provider_version: '2', number: 2, success: false)
.create_verification(provider_version: '4', number: 3)
.create_provider_version("5")
.use_consumer("B")
.use_consumer_version("1")
.create_provider("C")
.create_pact
.create_verification(provider_version: '1', success: false)
.use_consumer_version("2")
.create_pact
.create_verification(provider_version: '2', success: true)
.create_consumer_version("3")
.create_pact
.create_pact_with_hierarchy("the-example-application", "391c43cae8c0e83c570c191f7324fccd67e53abc", "another-example-application")
.create_verification(provider_version: '391c43cae8c0e83c570c191f7324fccd67e53abc')
.create_verification(provider_version: '57fa24e44efc4d8aa42bb855a8217f145b5b1b5b', number: 2, success: false)
.create_verification(provider_version: '4', number: 3)
.use_consumer("another-example-application")
.use_consumer_version("391c43cae8c0e83c570c191f7324fccd67e53abc")
.create_provider("a-third-example-application")
.create_pact
.create_verification(provider_version: '391c43cae8c0e83c570c191f7324fccd67e53abc', success: false)
.use_consumer_version("57fa24e44efc4d8aa42bb855a8217f145b5b1b5b")
.create_pact
.create_verification(provider_version: '57fa24e44efc4d8aa42bb855a8217f145b5b1b5b', success: true)


3 changes: 2 additions & 1 deletion spec/features/get_matrix_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
let(:path) { "/matrix" }
let(:params) do
{
selectors: ['Consumer/version/1.0.0','Provider/version/4.5.6']
pacticipant: ['Consumer', 'Provider'],
version: ['1.0.0', '4.5.6']
}
end
let(:last_response_body) { JSON.parse(subject.body, symbolize_names: true) }
Expand Down
4 changes: 2 additions & 2 deletions spec/lib/pact_broker/api/resources/matrix_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ module Resources
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(:params) { { pacticipant: ['Foo', 'Bar'], version: ['1', '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'])
expect(PactBroker::Matrix::Service).to receive(:validate_selectors).with('Foo' => '1', 'Bar' => '2')
subject
end

Expand Down
25 changes: 25 additions & 0 deletions spec/lib/pact_broker/matrix/parse_query_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require 'pact_broker/matrix/parse_query'

module PactBroker
module Matrix
describe ParseQuery do
describe ".call" do
let(:query) { "pacticipant[]=Foo&pacticipant[]=Bar&version[]=1.2.3&version[]=9.9.9" }

subject { ParseQuery.call(query) }

it "extracts the pacticipant names and respective versions" do
expect(subject).to eq "Foo" => "1.2.3", "Bar" => "9.9.9"
end

context "with spaces" do
let(:query) { "pacticipant%5B%5D=Name%20With%20Spaces&version%5B%5D=1%202" }

it "works" do
expect(subject).to eq "Name With Spaces" => "1 2"
end
end
end
end
end
end
15 changes: 4 additions & 11 deletions spec/lib/pact_broker/matrix/service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,14 @@ module Matrix

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 there is only one selector" do
before do
td.create_pacticipant("Foo")
.create_version("1")
end

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

it "returns error messages" do
expect(subject.first).to eq "Please provide 2 or more version selectors."
Expand All @@ -39,15 +32,15 @@ module Matrix

end

let(:selectors) { ["Foo/version/1", "Bar/version/1"] }
let(:selectors) { {"Foo" => "1", "Bar" => "1"} }

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

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

it "returns error messages" do
expect(subject.first).to eq "Pacticipant 'Foo' not found"
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 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")
.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 pact for Foo version 1.2.3 has been verified by Bar version 4.5.6" do
set_up do
TestDataBuilder.new
Expand Down

0 comments on commit 41c20c5

Please sign in to comment.