pact-support 1.4.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +143 -0
- data/lib/pact/configuration.rb +4 -0
- data/lib/pact/consumer_contract/consumer_contract.rb +19 -8
- data/lib/pact/consumer_contract/http_consumer_contract_parser.rb +37 -0
- data/lib/pact/consumer_contract/interaction.rb +57 -56
- data/lib/pact/consumer_contract/interaction_parser.rb +23 -0
- data/lib/pact/consumer_contract/interaction_v2_parser.rb +34 -0
- data/lib/pact/consumer_contract/interaction_v3_parser.rb +73 -0
- data/lib/pact/consumer_contract/pact_file.rb +24 -24
- data/lib/pact/consumer_contract/provider_state.rb +34 -0
- data/lib/pact/consumer_contract/query.rb +0 -2
- data/lib/pact/consumer_contract/query_hash.rb +6 -0
- data/lib/pact/consumer_contract/query_string.rb +2 -2
- data/lib/pact/consumer_contract/request.rb +1 -5
- data/lib/pact/consumer_contract/string_with_matching_rules.rb +17 -0
- data/lib/pact/matchers/multipart_form_diff_formatter.rb +41 -0
- data/lib/pact/matching_rules/merge.rb +43 -28
- data/lib/pact/matching_rules/v3/extract.rb +94 -0
- data/lib/pact/matching_rules/v3/merge.rb +135 -0
- data/lib/pact/matching_rules.rb +19 -6
- data/lib/pact/reification.rb +6 -3
- data/lib/pact/shared/multipart_form_differ.rb +14 -0
- data/lib/pact/specification_version.rb +18 -0
- data/lib/pact/support/version.rb +1 -1
- data/script/release.sh +1 -1
- data/spec/fixtures/multipart-form-diff.txt +9 -0
- data/spec/fixtures/not-a-pact.json +3 -0
- data/spec/fixtures/pact-http-v2.json +36 -0
- data/spec/fixtures/pact-http-v3.json +36 -0
- data/spec/integration/matching_rules_extract_and_merge_spec.rb +41 -4
- data/spec/lib/pact/consumer_contract/consumer_contract_spec.rb +54 -31
- data/spec/lib/pact/consumer_contract/http_consumer_contract_parser_spec.rb +25 -0
- data/spec/lib/pact/consumer_contract/interaction_parser_spec.rb +62 -0
- data/spec/lib/pact/consumer_contract/interaction_spec.rb +2 -26
- data/spec/lib/pact/consumer_contract/interaction_v2_parser_spec.rb +54 -0
- data/spec/lib/pact/consumer_contract/interaction_v3_parser_spec.rb +48 -0
- data/spec/lib/pact/consumer_contract/pact_file_spec.rb +9 -0
- data/spec/lib/pact/consumer_contract/query_hash_spec.rb +23 -0
- data/spec/lib/pact/matchers/multipart_form_diff_formatter_spec.rb +36 -0
- data/spec/lib/pact/matching_rules/merge_spec.rb +198 -110
- data/spec/lib/pact/matching_rules/v3/extract_spec.rb +238 -0
- data/spec/lib/pact/matching_rules/v3/merge_spec.rb +462 -0
- data/spec/lib/pact/matching_rules_spec.rb +82 -0
- data/spec/lib/pact/reification_spec.rb +18 -5
- data/spec/lib/pact/shared/multipart_form_differ_spec.rb +39 -0
- data/spec/support/factories.rb +5 -0
- data/tasks/spec.rake +0 -1
- metadata +40 -3
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"consumer": {
|
|
3
|
+
"name": "consumer"
|
|
4
|
+
},
|
|
5
|
+
"interactions": [
|
|
6
|
+
{
|
|
7
|
+
"description": "a test request",
|
|
8
|
+
"providerState": "the weather is sunny",
|
|
9
|
+
"request": {
|
|
10
|
+
"method": "get",
|
|
11
|
+
"path": "/foo"
|
|
12
|
+
},
|
|
13
|
+
"response": {
|
|
14
|
+
"body": {
|
|
15
|
+
"foo": "bar"
|
|
16
|
+
},
|
|
17
|
+
"matchingRules": {
|
|
18
|
+
"body": {
|
|
19
|
+
"$.foo": {
|
|
20
|
+
"matchers": [{ "match": "type" }]
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"status": 200
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"provider": {
|
|
29
|
+
"name": "provider"
|
|
30
|
+
},
|
|
31
|
+
"metadata": {
|
|
32
|
+
"pactSpecification": {
|
|
33
|
+
"version": "3.0"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
require 'pact/term'
|
|
2
2
|
require 'pact/something_like'
|
|
3
3
|
require 'pact/matching_rules/extract'
|
|
4
|
+
require 'pact/matching_rules/v3/extract'
|
|
4
5
|
require 'pact/matching_rules/merge'
|
|
6
|
+
require 'pact/matching_rules/v3/merge'
|
|
5
7
|
require 'pact/reification'
|
|
6
8
|
|
|
7
9
|
describe "converting Pact::Term and Pact::SomethingLike to matching rules and back again" do
|
|
@@ -10,6 +12,9 @@ describe "converting Pact::Term and Pact::SomethingLike to matching rules and ba
|
|
|
10
12
|
let(:matching_rules) { Pact::MatchingRules::Extract.(expected) }
|
|
11
13
|
let(:recreated_expected) { Pact::MatchingRules::Merge.(example, matching_rules)}
|
|
12
14
|
|
|
15
|
+
let(:recreated_expected_v3) { Pact::MatchingRules::V3::Merge.(example, matching_rules_v3) }
|
|
16
|
+
let(:matching_rules_v3) { Pact::MatchingRules::V3::Extract.(expected) }
|
|
17
|
+
|
|
13
18
|
context "with a Pact::Term" do
|
|
14
19
|
let(:expected) do
|
|
15
20
|
{
|
|
@@ -21,9 +26,29 @@ describe "converting Pact::Term and Pact::SomethingLike to matching rules and ba
|
|
|
21
26
|
}
|
|
22
27
|
end
|
|
23
28
|
|
|
24
|
-
it "recreates the same object hierarchy" do
|
|
29
|
+
it "recreates the same object hierarchy with v2 matching" do
|
|
30
|
+
expect(recreated_expected).to eq expected
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "recreates the same object hierarchy with v3 matching" do
|
|
34
|
+
expect(recreated_expected_v3).to eq expected
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
context "with a Pact::SomethingLike containing a Pact::ArrayLike" do
|
|
39
|
+
let(:expected) do
|
|
40
|
+
{
|
|
41
|
+
body: Pact::SomethingLike.new(children: Pact::ArrayLike.new("foo", min: 2))
|
|
42
|
+
}
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "recreates the same object hierarchy with v2 matching" do
|
|
25
46
|
expect(recreated_expected).to eq expected
|
|
26
47
|
end
|
|
48
|
+
|
|
49
|
+
it "recreates the same object hierarchy with v3 matching" do
|
|
50
|
+
expect(recreated_expected_v3).to eq expected
|
|
51
|
+
end
|
|
27
52
|
end
|
|
28
53
|
|
|
29
54
|
context "with a Pact::SomethingLike" do
|
|
@@ -37,9 +62,13 @@ describe "converting Pact::Term and Pact::SomethingLike to matching rules and ba
|
|
|
37
62
|
}
|
|
38
63
|
end
|
|
39
64
|
|
|
40
|
-
it "recreates the same object hierarchy" do
|
|
65
|
+
it "recreates the same object hierarchy with v2 matching" do
|
|
41
66
|
expect(recreated_expected).to eq expected
|
|
42
67
|
end
|
|
68
|
+
|
|
69
|
+
it "recreates the same object hierarchy with v3 matching" do
|
|
70
|
+
expect(recreated_expected_v3).to eq expected
|
|
71
|
+
end
|
|
43
72
|
end
|
|
44
73
|
|
|
45
74
|
context "with a Pact::SomethingLike containing a Hash" do
|
|
@@ -61,9 +90,13 @@ describe "converting Pact::Term and Pact::SomethingLike to matching rules and ba
|
|
|
61
90
|
}
|
|
62
91
|
end
|
|
63
92
|
|
|
64
|
-
it "recreates the same object hierarchy" do
|
|
93
|
+
it "recreates the same object hierarchy with v2 matching" do
|
|
65
94
|
expect(recreated_expected).to eq expected
|
|
66
95
|
end
|
|
96
|
+
|
|
97
|
+
it "recreates the same object hierarchy with v3 matching" do
|
|
98
|
+
expect(recreated_expected_v3).to eq expected
|
|
99
|
+
end
|
|
67
100
|
end
|
|
68
101
|
|
|
69
102
|
context "with a Pact::SomethingLike containing an Array" do
|
|
@@ -83,8 +116,12 @@ describe "converting Pact::Term and Pact::SomethingLike to matching rules and ba
|
|
|
83
116
|
}
|
|
84
117
|
end
|
|
85
118
|
|
|
86
|
-
it "recreates the same object hierarchy" do
|
|
119
|
+
it "recreates the same object hierarchy with v2 matching" do
|
|
87
120
|
expect(recreated_expected).to eq expected
|
|
88
121
|
end
|
|
122
|
+
|
|
123
|
+
it "recreates the same object hierarchy with v3 matching" do
|
|
124
|
+
expect(recreated_expected_v3).to eq expected
|
|
125
|
+
end
|
|
89
126
|
end
|
|
90
127
|
end
|
|
@@ -3,50 +3,73 @@ require 'pact/consumer_contract'
|
|
|
3
3
|
|
|
4
4
|
module Pact
|
|
5
5
|
describe ConsumerContract do
|
|
6
|
+
describe "from_uri" do
|
|
7
|
+
context "when the URL does not point to a valid pact" do
|
|
8
|
+
subject { ConsumerContract.from_uri('spec/fixtures/not-a-pact.json') }
|
|
9
|
+
|
|
10
|
+
it "raises a helpful error" do
|
|
11
|
+
expect { subject }.to raise_error UnrecognizePactFormatError, /Please check that spec/
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe "from_hash" do
|
|
17
|
+
context "when the hash is not a valid pact" do
|
|
18
|
+
subject { ConsumerContract.from_hash({'foo' => 'bar'}) }
|
|
19
|
+
|
|
20
|
+
it "raises a helpful error" do
|
|
21
|
+
expect { subject }.to raise_error UnrecognizePactFormatError, 'This document does not use a recognised Pact format: {"foo"=>"bar"}'
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
6
25
|
|
|
7
26
|
describe ".from_json" do
|
|
27
|
+
|
|
8
28
|
let(:loaded_pact) { ConsumerContract.from_json(string) }
|
|
9
|
-
context "when the top level object is a ConsumerContract" do
|
|
10
|
-
let(:string) { '{"interactions":[{"request": {"path":"/path", "method" : "get"}, "response": {"status" : 200}}], "consumer": {"name" : "Bob"} , "provider": {"name" : "Mary"} }' }
|
|
11
29
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
30
|
+
context "with an HTTP contract" do
|
|
31
|
+
context "when the top level object is a ConsumerContract" do
|
|
32
|
+
let(:string) { '{"interactions":[{"request": {"path":"/path", "method" : "get"}, "response": {"status" : 200}}], "consumer": {"name" : "Bob"} , "provider": {"name" : "Mary"} }' }
|
|
15
33
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
34
|
+
it "should create a Pact" do
|
|
35
|
+
expect(loaded_pact).to be_instance_of ConsumerContract
|
|
36
|
+
end
|
|
19
37
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
38
|
+
it "should have interactions" do
|
|
39
|
+
expect(loaded_pact.interactions).to be_instance_of Array
|
|
40
|
+
end
|
|
23
41
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
end
|
|
42
|
+
it "should have a consumer" do
|
|
43
|
+
expect(loaded_pact.consumer).to be_instance_of Pact::ServiceConsumer
|
|
44
|
+
end
|
|
28
45
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
expect(loaded_pact).to be_instance_of ConsumerContract
|
|
46
|
+
it "should have a provider" do
|
|
47
|
+
expect(loaded_pact.provider).to be_instance_of Pact::ServiceProvider
|
|
48
|
+
end
|
|
33
49
|
end
|
|
34
50
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
51
|
+
context "with old 'producer' key" do
|
|
52
|
+
let(:string) { File.read('./spec/support/a_consumer-a_producer.json')}
|
|
53
|
+
it "should create a Pact" do
|
|
54
|
+
expect(loaded_pact).to be_instance_of ConsumerContract
|
|
55
|
+
end
|
|
38
56
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
57
|
+
it "should have interactions" do
|
|
58
|
+
expect(loaded_pact.interactions).to be_instance_of Array
|
|
59
|
+
end
|
|
42
60
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
end
|
|
61
|
+
it "should have a consumer" do
|
|
62
|
+
expect(loaded_pact.consumer).to be_instance_of Pact::ServiceConsumer
|
|
63
|
+
end
|
|
47
64
|
|
|
48
|
-
|
|
49
|
-
|
|
65
|
+
it "should have a provider" do
|
|
66
|
+
expect(loaded_pact.provider).to be_instance_of Pact::ServiceProvider
|
|
67
|
+
expect(loaded_pact.provider.name).to eq "an old producer"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "should have a provider_state" do
|
|
71
|
+
expect(loaded_pact.interactions.first.provider_state).to eq 'state one'
|
|
72
|
+
end
|
|
50
73
|
end
|
|
51
74
|
end
|
|
52
75
|
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'pact/consumer_contract/http_consumer_contract_parser'
|
|
2
|
+
|
|
3
|
+
module Pact
|
|
4
|
+
describe HttpConsumerContractParser do
|
|
5
|
+
describe "#call integration test" do
|
|
6
|
+
subject { HttpConsumerContractParser.new.call(pact_hash) }
|
|
7
|
+
|
|
8
|
+
context "with a v2 pact" do
|
|
9
|
+
let(:pact_hash) { load_json_fixture('pact-http-v2.json') }
|
|
10
|
+
|
|
11
|
+
it "correctly parses the pact" do
|
|
12
|
+
expect(subject.interactions.first.response.headers['Content-Type']).to be_a(Pact::Term)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
context "with a v3 pact" do
|
|
17
|
+
let(:pact_hash) { load_json_fixture('pact-http-v3.json') }
|
|
18
|
+
|
|
19
|
+
it "correctly parses the pact" do
|
|
20
|
+
expect(subject.interactions.first.response.body['foo']).to be_a(Pact::SomethingLike)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require 'pact/consumer_contract/interaction_parser'
|
|
2
|
+
|
|
3
|
+
module Pact
|
|
4
|
+
describe InteractionParser do
|
|
5
|
+
describe ".call" do
|
|
6
|
+
|
|
7
|
+
let(:request) { {method: 'get', path: 'path'} }
|
|
8
|
+
let(:response) { {} }
|
|
9
|
+
|
|
10
|
+
context "when providerState has been used instead of provider_state" do
|
|
11
|
+
|
|
12
|
+
subject { InteractionParser.call('response' => response, 'request' => request, 'providerState' => 'some state') }
|
|
13
|
+
|
|
14
|
+
it "recognises the provider state" do
|
|
15
|
+
expect(subject.provider_state).to eq 'some state'
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
context "when there are matching rules" do
|
|
20
|
+
let(:hash) { load_json_fixture 'interaction-with-matching-rules.json' }
|
|
21
|
+
|
|
22
|
+
subject { InteractionParser.call(hash, pact_specification_version: Pact::SpecificationVersion.new("2")) }
|
|
23
|
+
|
|
24
|
+
it "merges the rules with the example for the request" do
|
|
25
|
+
expect(subject.request.body['name']).to be_instance_of(Pact::Term)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "merges the rules with the example for the response" do
|
|
29
|
+
expect(subject.response.body['_links']['self']['href']).to be_instance_of(Pact::Term)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context "when the request body is a String" do
|
|
34
|
+
let(:hash) { { 'request' => request, 'response' => response } }
|
|
35
|
+
subject { InteractionParser.call(hash, pact_specification_version: Pact::SpecificationVersion.new("3")) }
|
|
36
|
+
|
|
37
|
+
let(:request) { { 'method' => 'get', 'path' => 'path' , 'body' => "<xml></xml>", 'matchingRules' => {"body" => {"foo" => "bar"} } } }
|
|
38
|
+
|
|
39
|
+
it "returns an interaction with an StringWithMatchingRules in the request" do
|
|
40
|
+
expect(subject.request.body).to be_a(Pact::StringWithMatchingRules)
|
|
41
|
+
expect(subject.request.body).to eq "<xml></xml>"
|
|
42
|
+
expect(subject.request.body.matching_rules).to eq "foo" => "bar"
|
|
43
|
+
expect(subject.request.body.pact_specification_version).to eq Pact::SpecificationVersion.new("3")
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
context "when the response body is a String" do
|
|
48
|
+
let(:hash) { { 'request' => request, 'response' => response } }
|
|
49
|
+
subject { InteractionParser.call(hash, pact_specification_version: Pact::SpecificationVersion.new("3")) }
|
|
50
|
+
|
|
51
|
+
let(:response) { { 'status' => '200', 'body' => "<xml></xml>", 'matchingRules' => {"body" => {"foo" => "bar"} } } }
|
|
52
|
+
|
|
53
|
+
it "returns an interaction with an StringWithMatchingRules in the response" do
|
|
54
|
+
expect(subject.response.body).to be_a(Pact::StringWithMatchingRules)
|
|
55
|
+
expect(subject.response.body).to eq "<xml></xml>"
|
|
56
|
+
expect(subject.response.body.matching_rules).to eq "foo" => "bar"
|
|
57
|
+
expect(subject.response.body.pact_specification_version).to eq Pact::SpecificationVersion.new("3")
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -38,12 +38,14 @@ module Pact
|
|
|
38
38
|
|
|
39
39
|
describe "matches_criteria?" do
|
|
40
40
|
subject { InteractionFactory.create(:description => 'a request for food') }
|
|
41
|
+
|
|
41
42
|
context "by description" do
|
|
42
43
|
context "when the interaction matches" do
|
|
43
44
|
it "returns true" do
|
|
44
45
|
expect(subject.matches_criteria?(:description => /request.*food/)).to be true
|
|
45
46
|
end
|
|
46
47
|
end
|
|
48
|
+
|
|
47
49
|
context "when the interaction does not match" do
|
|
48
50
|
it "returns false" do
|
|
49
51
|
expect(subject.matches_criteria?(:description => /blah/)).to be false
|
|
@@ -52,33 +54,7 @@ module Pact
|
|
|
52
54
|
end
|
|
53
55
|
end
|
|
54
56
|
|
|
55
|
-
describe "from_hash" do
|
|
56
|
-
context "when providerState has been used instead of provider_state" do
|
|
57
|
-
|
|
58
|
-
subject { Interaction.from_hash('response' => response, 'request' => request, 'providerState' => 'some state') }
|
|
59
|
-
|
|
60
|
-
it "recognises the provider state" do
|
|
61
|
-
expect(subject.provider_state).to eq 'some state'
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
context "when there are matching rules" do
|
|
66
|
-
let(:hash) { load_json_fixture 'interaction-with-matching-rules.json' }
|
|
67
|
-
|
|
68
|
-
subject { Interaction.from_hash hash }
|
|
69
|
-
|
|
70
|
-
it "merges the rules with the example for the request" do
|
|
71
|
-
expect(subject.request.body['name']).to be_instance_of(Pact::Term)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
it "merges the rules with the example for the response" do
|
|
75
|
-
expect(subject.response.body['_links']['self']['href']).to be_instance_of(Pact::Term)
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
57
|
describe "request_modifies_resource_without_checking_response_body?" do
|
|
81
|
-
|
|
82
58
|
let(:interaction) { Interaction.new(request: request, response: response)}
|
|
83
59
|
|
|
84
60
|
subject { interaction.request_modifies_resource_without_checking_response_body?}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'pact/consumer_contract/interaction_v2_parser'
|
|
2
|
+
|
|
3
|
+
module Pact
|
|
4
|
+
describe InteractionV2Parser do
|
|
5
|
+
describe ".call" do
|
|
6
|
+
let(:interaction_hash) do
|
|
7
|
+
{
|
|
8
|
+
"description" => "description",
|
|
9
|
+
"request" => { "method" => "GET", "path" => "/" },
|
|
10
|
+
"response" => { "status" => 200 },
|
|
11
|
+
"providerState" => "foo"
|
|
12
|
+
}
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
let(:options) do
|
|
16
|
+
{
|
|
17
|
+
pact_specification_version: Pact::SpecificationVersion.new("3.0")
|
|
18
|
+
}
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
subject { InteractionV2Parser.call(interaction_hash, options) }
|
|
22
|
+
|
|
23
|
+
describe "provider_states" do
|
|
24
|
+
it "returns an array of provider states with size 1" do
|
|
25
|
+
expect(subject.provider_states.size).to eq 1
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "sets the name of the provider state to the string provided" do
|
|
29
|
+
expect(subject.provider_states.first.name)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "sets the params to an empty hash" do
|
|
33
|
+
expect(subject.provider_states.first.params).to eq({})
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
context "when the providerState is nil" do
|
|
37
|
+
before do
|
|
38
|
+
interaction_hash["providerState"] = nil
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "returns an empty list" do
|
|
42
|
+
expect(subject.provider_states).to be_empty
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe "provider_state" do
|
|
48
|
+
it "sets the name from the hash" do
|
|
49
|
+
expect(subject.provider_state).to eq "foo"
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'pact/consumer_contract/interaction_v3_parser'
|
|
2
|
+
|
|
3
|
+
module Pact
|
|
4
|
+
describe InteractionV3Parser do
|
|
5
|
+
describe ".call" do
|
|
6
|
+
|
|
7
|
+
let(:interaction_hash) do
|
|
8
|
+
{
|
|
9
|
+
"description" => "description",
|
|
10
|
+
"request" => { "method" => "GET", "path" => "/" },
|
|
11
|
+
"response" => { "status" => 200 },
|
|
12
|
+
"providerStates" => [{
|
|
13
|
+
"name" => "foo",
|
|
14
|
+
"params" => {"a" => "b"}
|
|
15
|
+
}]
|
|
16
|
+
}
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
let(:options) do
|
|
20
|
+
{
|
|
21
|
+
pact_specification_version: Pact::SpecificationVersion.new("3.0")
|
|
22
|
+
}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
subject { InteractionV3Parser.call(interaction_hash, options) }
|
|
26
|
+
|
|
27
|
+
describe "provider_states" do
|
|
28
|
+
it "parses the array of provider states" do
|
|
29
|
+
expect(subject.provider_states.size).to eq 1
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "parses the name of each" do
|
|
33
|
+
expect(subject.provider_states.first.name)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "parses the params of each" do
|
|
37
|
+
expect(subject.provider_states.first.params).to eq "a" => "b"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
describe "provider_state" do
|
|
42
|
+
it "sets the provider_state string to the name of the first providerState for backwards compatibility while we implement v3" do
|
|
43
|
+
expect(subject.provider_state).to eq "foo"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -25,6 +25,15 @@ module Pact
|
|
|
25
25
|
end
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
+
describe 'with backslashes to a local path' do
|
|
29
|
+
let(:windows_path) { 'spec\support\a_consumer-a_provider.json' }
|
|
30
|
+
let(:unix_path) { 'spec/support/a_consumer-a_provider.json' }
|
|
31
|
+
|
|
32
|
+
it 'transforms them to forward slashes' do
|
|
33
|
+
expect(PactFile.read(windows_path)).to eq PactFile.read(unix_path)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
28
37
|
context 'without basic authentication' do
|
|
29
38
|
before do
|
|
30
39
|
stub_request(:get, uri_without_userinfo).to_return(body: pact_content)
|
|
@@ -72,6 +72,15 @@ module Pact
|
|
|
72
72
|
expect(subject.difference(other).keys).to contain_exactly(:"param[a]", :"param[a][aa]", :"param[a][bb]")
|
|
73
73
|
end
|
|
74
74
|
end
|
|
75
|
+
|
|
76
|
+
context "when there is an ArrayLike" do
|
|
77
|
+
let(:query) { { param: Pact.each_like("1") } }
|
|
78
|
+
let(:other) { QueryString.new('param=1¶m=2') }
|
|
79
|
+
|
|
80
|
+
it 'returns an empty diff' do
|
|
81
|
+
expect(subject.difference(other)).to be_empty
|
|
82
|
+
end
|
|
83
|
+
end
|
|
75
84
|
end
|
|
76
85
|
end
|
|
77
86
|
|
|
@@ -82,6 +91,20 @@ module Pact
|
|
|
82
91
|
end
|
|
83
92
|
|
|
84
93
|
describe "#to_json" do
|
|
94
|
+
context "when the query contains an ArrayLike" do
|
|
95
|
+
let(:query) { { foo: Pact.each_like("1"), bar: "2" } }
|
|
96
|
+
let(:expected_json) do
|
|
97
|
+
{
|
|
98
|
+
foo: Pact.each_like("1"),
|
|
99
|
+
bar: ["2"]
|
|
100
|
+
}.to_json
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "serialises the ArrayLike without wrapping an array around it" do
|
|
104
|
+
expect(subject.to_json).to eq expected_json
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
85
108
|
context "when the query contains a Pact::Term" do
|
|
86
109
|
let(:term) { Pact::Term.new(generate: "thing", matcher: /th/) }
|
|
87
110
|
let(:query) { { param: term } }
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'pact/matchers/multipart_form_diff_formatter'
|
|
2
|
+
|
|
3
|
+
module Pact
|
|
4
|
+
module Matchers
|
|
5
|
+
describe MultipartFormDiffFormatter do
|
|
6
|
+
describe ".call" do
|
|
7
|
+
subject { MultipartFormDiffFormatter.call(diff, options)}
|
|
8
|
+
|
|
9
|
+
let(:diff) do
|
|
10
|
+
{
|
|
11
|
+
headers: header_diff,
|
|
12
|
+
body: body_diff
|
|
13
|
+
}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
let(:header_diff) do
|
|
17
|
+
{
|
|
18
|
+
"Content-Type" => Difference.new("foo", "bar", "Wrong header")
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
let(:body_diff) do
|
|
23
|
+
Difference.new("foo", "bar", "A message")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
let(:options) { {} }
|
|
27
|
+
|
|
28
|
+
let(:expected_output) { File.read("spec/fixtures/multipart-form-diff.txt")}
|
|
29
|
+
|
|
30
|
+
it "formats the diff" do
|
|
31
|
+
expect(subject).to eq expected_output
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|