Skip to content

Commit

Permalink
feat(v3): parse array of provider states with params
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Oct 1, 2018
1 parent 9159e06 commit 4471df3
Show file tree
Hide file tree
Showing 10 changed files with 180 additions and 14 deletions.
20 changes: 13 additions & 7 deletions lib/pact/consumer_contract/interaction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,32 @@ module Pact
class Interaction
include ActiveSupportSupport

attr_accessor :description, :request, :response, :provider_state
attr_accessor :description, :request, :response, :provider_state, :provider_states

def initialize attributes = {}
@description = attributes[:description]
@request = attributes[:request]
@response = attributes[:response]
@provider_state = attributes[:provider_state] || attributes[:providerState]
@provider_states = attributes[:provider_states]
end

def self.from_hash hash, options = {}
InteractionParser.call(hash, options)
end

def to_hash
{
description: description,
provider_state: provider_state,
request: request.to_hash,
response: response.to_hash
}
h = { description: description }

if provider_states
h[:provider_states] = provider_states.collect(&:to_hash)
else
h[:provider_state] = provider_state
end

h[:request] = request.to_hash
h[:response] = response.to_hash
h
end

def http?
Expand Down
8 changes: 7 additions & 1 deletion lib/pact/consumer_contract/interaction_v2_parser.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'pact/consumer_contract/request'
require 'pact/consumer_contract/response'
require 'pact/consumer_contract/provider_state'
require 'pact/symbolize_keys'
require 'pact/matching_rules'
require 'pact/errors'
Expand All @@ -12,7 +13,8 @@ class InteractionV2Parser
def self.call hash, options
request = parse_request(hash['request'], options)
response = parse_response(hash['response'], options)
Interaction.new(symbolize_keys(hash).merge(request: request, response: response))
provider_states = parse_provider_states(hash['providerState'] || hash['provider_state'])
Interaction.new(symbolize_keys(hash).merge(request: request, response: response, provider_states: provider_states))
end

def self.parse_request request_hash, options
Expand All @@ -24,5 +26,9 @@ def self.parse_response response_hash, options
response_hash = Pact::MatchingRules.merge(response_hash, response_hash['matchingRules'], options)
Pact::Response.from_hash(response_hash)
end

def self.parse_provider_states provider_state_name
provider_state_name ? [Pact::ProviderState.new(provider_state_name)] : []
end
end
end
14 changes: 13 additions & 1 deletion lib/pact/consumer_contract/interaction_v3_parser.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'pact/consumer_contract/request'
require 'pact/consumer_contract/response'
require 'pact/consumer_contract/provider_state'
require 'pact/symbolize_keys'
require 'pact/matching_rules'
require 'pact/errors'
Expand All @@ -13,7 +14,12 @@ class InteractionV3Parser
def self.call hash, options
request = parse_request(hash['request'], options)
response = parse_response(hash['response'], options)
Interaction.new(symbolize_keys(hash).merge(request: request, response: response))
provider_states = parse_provider_states(hash['providerStates'])
provider_state = provider_states.any? ? provider_states.first.name : nil
if provider_states && provider_states.size > 1
Pact.configuration.error_stream.puts("WARN: Currently only 1 provider state is supported. Ignoring ")
end
Interaction.new(symbolize_keys(hash).merge(request: request, response: response, provider_states: provider_states, provider_state: provider_state))
end

def self.parse_request request_hash, options
Expand Down Expand Up @@ -57,5 +63,11 @@ def self.parse_response_with_string_body response_hash, response_matching_rules,
string_with_matching_rules = StringWithMatchingRules.new(response_hash['body'], options[:pact_specification_version], response_matching_rules)
Pact::Response.from_hash(response_hash.merge('body' => string_with_matching_rules))
end

def self.parse_provider_states provider_states
(provider_states || []).collect do | provider_state_hash |
Pact::ProviderState.new(provider_state_hash['name'], provider_state_hash['params'])
end
end
end
end
34 changes: 34 additions & 0 deletions lib/pact/consumer_contract/provider_state.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module Pact
class ProviderState

attr_reader :name, :params

def initialize name, params = {}
@name = name
@params = params
end

def self.from_hash(hash)
new(hash["name"], hash["params"])
end

def ==(other)
other.is_a?(Pact::ProviderState) && other.name == self.name && other.params == self.params
end

def to_hash
{
"name" => name,
"params" => params
}
end

def to_json(opts = {})
as_json(opts).to_json(opts)
end

def as_json(opts = {})
to_hash
end
end
end
2 changes: 0 additions & 2 deletions lib/pact/consumer_contract/query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@

module Pact
class Query

def self.create query
if query.is_a? Hash
Pact::QueryHash.new(query)
else
Pact::QueryString.new(query)
end
end

end
end
4 changes: 4 additions & 0 deletions lib/pact/consumer_contract/query_hash.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ def empty?
@hash && @hash.empty?
end

def to_hash
@hash
end

private

def convert_to_hash_of_arrays(query)
Expand Down
5 changes: 2 additions & 3 deletions spec/lib/pact/consumer_contract/interaction_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@ module Consumer

describe "matches_criteria?" do
subject { InteractionFactory.create(:description => 'a request for food') }

context "by description" do
context "when the interaction matches" do
it "returns true" do
expect(subject.matches_criteria?(:description => /request.*food/)).to be true
end
end

context "when the interaction does not match" do
it "returns false" do
expect(subject.matches_criteria?(:description => /blah/)).to be false
Expand All @@ -52,10 +54,7 @@ module Consumer
end
end



describe "request_modifies_resource_without_checking_response_body?" do

let(:interaction) { Interaction.new(request: request, response: response)}

subject { interaction.request_modifies_resource_without_checking_response_body?}
Expand Down
54 changes: 54 additions & 0 deletions spec/lib/pact/consumer_contract/interaction_v2_parser_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
require 'pact/consumer_contract/interaction_v2_parser'

module Pact
describe InteractionV2Parser do
describe ".call" do
let(:interaction_hash) do
{
"description" => "description",
"request" => { "method" => "GET", "path" => "/" },
"response" => { "status" => 200 },
"providerState" => "foo"
}
end

let(:options) do
{
pact_specification_version: Pact::SpecificationVersion.new("3.0")
}
end

subject { InteractionV2Parser.call(interaction_hash, options) }

describe "provider_states" do
it "returns an array of provider states with size 1" do
expect(subject.provider_states.size).to eq 1
end

it "sets the name of the provider state to the string provided" do
expect(subject.provider_states.first.name)
end

it "sets the params to an empty hash" do
expect(subject.provider_states.first.params).to eq({})
end

context "when the providerState is nil" do
before do
interaction_hash["providerState"] = nil
end

it "returns an empty list" do
expect(subject.provider_states).to be_empty
end
end
end

describe "provider_state" do
it "sets the name from the hash" do
expect(subject.provider_state).to eq "foo"
end
end
end
end
end
48 changes: 48 additions & 0 deletions spec/lib/pact/consumer_contract/interaction_v3_parser_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
require 'pact/consumer_contract/interaction_v3_parser'

module Pact
describe InteractionV3Parser do
describe ".call" do

let(:interaction_hash) do
{
"description" => "description",
"request" => { "method" => "GET", "path" => "/" },
"response" => { "status" => 200 },
"providerStates" => [{
"name" => "foo",
"params" => {"a" => "b"}
}]
}
end

let(:options) do
{
pact_specification_version: Pact::SpecificationVersion.new("3.0")
}
end

subject { InteractionV3Parser.call(interaction_hash, options) }

describe "provider_states" do
it "parses the array of provider states" do
expect(subject.provider_states.size).to eq 1
end

it "parses the name of each" do
expect(subject.provider_states.first.name)
end

it "parses the params of each" do
expect(subject.provider_states.first.params).to eq "a" => "b"
end
end

describe "provider_state" do
it "sets the provider_state string to the name of the first providerState for backwards compatibility while we implement v3" do
expect(subject.provider_state).to eq "foo"
end
end
end
end
end
5 changes: 5 additions & 0 deletions spec/support/factories.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ def self.create hash = {}
'body' => {a: 'response body'}
}
}

if hash.key?(:provider_states) || hash.key?('provider_states')
defaults.delete('provider_state')
end

Pact::Interaction.from_hash(stringify_keys(deep_merge(defaults, stringify_keys(hash))))
end
end
Expand Down

0 comments on commit 4471df3

Please sign in to comment.