Skip to content

Commit

Permalink
feat: correct provider state matching for merging
Browse files Browse the repository at this point in the history
Correct dealing with various forms of provider state. There are 3 options:

- provider_state (was supported until now) but it is part of v1 specification
- providerState wasn't supported, which is part of v2 specification
- providerStates with array of objects containing at least name attribute. This is part of specification v3 and also is used by pact-message-ruby extensively.

Without this submission any submit of two contracts with merge-mode and same version when the description is same but provider state vary would fail.
  • Loading branch information
RaVbaker committed Apr 19, 2019
1 parent 3229e17 commit 41ff6e5
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 1 deletion.
6 changes: 5 additions & 1 deletion lib/pact_broker/pacts/merger.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ def merge_pacts original_json, additional_json

def same_description_and_state? original, additional
original["description"] == additional["description"] &&
original["provider_state"] == additional["provider_state"]
normalized_provider_states(original) == normalized_provider_states(additional)
end

def normalized_provider_states(interaction)
interaction.values_at("provider_state", "providerState", "providerStates").compact.first
end

def same_request_properties? original, additional
Expand Down
33 changes: 33 additions & 0 deletions spec/lib/pact_broker/pacts/merger_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,39 @@ module Pacts
expect(result["interactions"].length).to eq example_pact["interactions"].length + 1
end

it "matches same provider state when is in v2 format" do
example_pact["interactions"][0]["providerState"] = "something in the way"
pact_to_merge["interactions"][0]["providerState"] = "something in the way"
pact_to_merge["interactions"][0]["response"]["body"] = "changed!"

result = merge_pacts(example_pact, pact_to_merge)

expect(result["interactions"].length).to eq example_pact["interactions"].length
expect(result["interactions"].first["response"]["body"]).to eq "changed!"
end

it "supports merging when provider state is in either v2 or v1 format" do
example_pact["interactions"][0]["provider_state"] = "system must resist"
pact_to_merge["interactions"][0]["providerState"] = "system must resist"
pact_to_merge["interactions"][0]["response"]["body"] = "changed!"

result = merge_pacts(example_pact, pact_to_merge)

expect(result["interactions"].length).to eq example_pact["interactions"].length
expect(result["interactions"].first["response"]["body"]).to eq "changed!"
end

it "supports merging when provider state is in v3 format with providerStates" do
example_pact["interactions"][0]["providerStates"] = [{ name: "a state" }]
pact_to_merge["interactions"][0]["providerStates"] = [{ name: "a state" }]
pact_to_merge["interactions"][0]["response"]["body"] = "changed!"

result = merge_pacts(example_pact, pact_to_merge)

expect(result["interactions"].length).to eq example_pact["interactions"].length
expect(result["interactions"].first["response"]["body"]).to eq "changed!"
end

# helper that lets these specs deal with hashes instead of JSON strings
def merge_pacts(a, b, return_hash = true)
result = PactBroker::Pacts::Merger.merge_pacts(a.to_json, b.to_json)
Expand Down

0 comments on commit 41ff6e5

Please sign in to comment.