pact 1.41.2 → 1.53.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 +5 -5
- data/CHANGELOG.md +219 -0
- data/lib/pact/cli/run_pact_verification.rb +23 -7
- data/lib/pact/cli/spec_criteria.rb +3 -0
- data/lib/pact/cli.rb +5 -0
- data/lib/pact/consumer/configuration/dsl.rb +0 -1
- data/lib/pact/consumer/consumer_contract_builder.rb +4 -0
- data/lib/pact/consumer/interaction_builder.rb +6 -0
- data/lib/pact/consumer/spec_hooks.rb +2 -2
- data/lib/pact/doc/sort_interactions.rb +2 -3
- data/lib/pact/hal/http_client.rb +11 -5
- data/lib/pact/hal/link.rb +50 -13
- data/lib/pact/hal/non_json_entity.rb +28 -0
- data/lib/pact/pact_broker/fetch_pact_uris_for_verification.rb +93 -0
- data/lib/pact/pact_broker/notices.rb +34 -0
- data/lib/pact/pact_broker/pact_selection_description.rb +24 -0
- data/lib/pact/pact_broker.rb +10 -4
- data/lib/pact/provider/configuration/dsl.rb +6 -1
- data/lib/pact/provider/configuration/message_provider_dsl.rb +59 -0
- data/lib/pact/provider/configuration/pact_verification_from_broker.rb +28 -4
- data/lib/pact/provider/configuration/service_provider_dsl.rb +1 -1
- data/lib/pact/provider/help/content.rb +4 -4
- data/lib/pact/provider/help/pact_diff.rb +10 -34
- data/lib/pact/provider/help/write.rb +6 -7
- data/lib/pact/provider/pact_helper_locator.rb +0 -1
- data/lib/pact/provider/pact_source.rb +10 -1
- data/lib/pact/provider/pact_spec_runner.rb +24 -16
- data/lib/pact/provider/pact_uri.rb +8 -6
- data/lib/pact/provider/request.rb +1 -1
- data/lib/pact/provider/rspec/formatter_rspec_3.rb +21 -6
- data/lib/pact/provider/rspec/json_formatter.rb +100 -0
- data/lib/pact/provider/rspec/pact_broker_formatter.rb +1 -1
- data/lib/pact/provider/rspec.rb +17 -7
- data/lib/pact/provider/test_methods.rb +9 -3
- data/lib/pact/provider/verification_results/publish.rb +3 -0
- data/lib/pact/provider/verification_results/publish_all.rb +14 -1
- data/lib/pact/provider/verification_results/verification_result.rb +1 -4
- data/lib/pact/provider/world.rb +1 -1
- data/lib/pact/tasks/task_helper.rb +6 -1
- data/lib/pact/version.rb +1 -1
- data/pact.gemspec +11 -13
- metadata +59 -56
- data/lib/pact/pact_broker/fetch_pending_pacts.rb +0 -58
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 36cdbcc7291013248a5b691e8dec77f7153fd3c5c75d664e5da651943a8673dc
|
|
4
|
+
data.tar.gz: 0a75d19524d85f5623f6f8f9b042b1e481f551a5784cb2c48e86633f2d3d7329
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: faa46bb073cdacca555022ee518d15e13182f286f1b6d75f309f7f5d6d6692674c046ced1d3b8598d10772b7dc25d3157aa556d6ac47453753dc90607ed8575b
|
|
7
|
+
data.tar.gz: 360a99577f6925e21ab6ce0949bca79a3309c1a16e7dbd21ae72fe20b7c46a87eca0f422d810061d2adc594141b76ca4be831eeb8859aff29eca00fe9227f78e
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,222 @@
|
|
|
1
|
+
<a name="v1.53.0"></a>
|
|
2
|
+
### v1.53.0 (2020-09-11)
|
|
3
|
+
|
|
4
|
+
#### Features
|
|
5
|
+
|
|
6
|
+
* add support for the enable_pending flag ([16866f4](/../../commit/16866f4))
|
|
7
|
+
|
|
8
|
+
<a name="v1.52.0"></a>
|
|
9
|
+
### v1.52.0 (2020-09-10)
|
|
10
|
+
|
|
11
|
+
#### Features
|
|
12
|
+
|
|
13
|
+
* support webdav http methods ([fa1d712](/../../commit/fa1d712))
|
|
14
|
+
|
|
15
|
+
<a name="v1.51.1"></a>
|
|
16
|
+
### v1.51.1 (2020-08-12)
|
|
17
|
+
|
|
18
|
+
#### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* update thor dependency (#218) ([bf3ce69](/../../commit/bf3ce69))
|
|
21
|
+
* bump rake dependency per CVE-2020-8130 (#219) ([09feaa6](/../../commit/09feaa6))
|
|
22
|
+
|
|
23
|
+
<a name="v1.51.0"></a>
|
|
24
|
+
### v1.51.0 (2020-06-24)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
#### Features
|
|
28
|
+
|
|
29
|
+
* allow individual interactions to be re-run by setting PACT_BROKER_INTERACTION_ID ([a586d80](/../../commit/a586d80))
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
<a name="v1.50.1"></a>
|
|
33
|
+
### v1.50.1 (2020-06-15)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
#### Bug Fixes
|
|
37
|
+
|
|
38
|
+
* fix integration with pact-message-ruby (#216) ([d2da13e](/../../commit/d2da13e))
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
<a name="v1.50.0"></a>
|
|
42
|
+
### v1.50.0 (2020-04-25)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
#### Features
|
|
46
|
+
|
|
47
|
+
* Set expected interactions on mock service but without writing them to pact file (#210) ([14f5327](/../../commit/14f5327))
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
<a name="v1.49.3"></a>
|
|
51
|
+
### v1.49.3 (2020-04-22)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
#### Bug Fixes
|
|
55
|
+
|
|
56
|
+
* pact selection verification options logging ([9ff59f4](/../../commit/9ff59f4))
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
<a name="v1.49.2"></a>
|
|
60
|
+
### v1.49.2 (2020-04-08)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
#### Bug Fixes
|
|
64
|
+
|
|
65
|
+
* json parser error for top level JSON values ([dafbc35](/../../commit/dafbc35))
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
<a name="v1.49.1"></a>
|
|
69
|
+
### v1.49.1 (2020-03-21)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
#### Bug Fixes
|
|
73
|
+
|
|
74
|
+
* ensure diff is included in the json output ([0bd9753](/../../commit/0bd9753))
|
|
75
|
+
* ensure the presence of basic auth credentials does not cause an error when displaying the path of a pact on the local filesystem ([f6a0b4d](/../../commit/f6a0b4d))
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
<a name="v1.49.0"></a>
|
|
79
|
+
### v1.49.0 (2020-02-18)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
#### Features
|
|
83
|
+
|
|
84
|
+
* use environment variables PACT_BROKER_USERNAME and PACT_BROKER_PASSWORD when verifying a pact by URL, if the environment variables are present ([308f25d](/../../commit/308f25d))
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
<a name="v1.48.0"></a>
|
|
88
|
+
### v1.48.0 (2020-02-13)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
#### Features
|
|
92
|
+
|
|
93
|
+
* use certificates from SSL_CERT_FILE and SSL_CERT_DIR environment variables in HTTP connections ([164912b](/../../commit/164912b))
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
<a name="v1.47.0"></a>
|
|
97
|
+
### v1.47.0 (2020-02-08)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
#### Features
|
|
101
|
+
|
|
102
|
+
* update json formatter output ([376e47a](/../../commit/376e47a))
|
|
103
|
+
* add pact metadata to json formatter ([6c6ddb8](/../../commit/6c6ddb8))
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
<a name="v1.46.1"></a>
|
|
107
|
+
### v1.46.1 (2020-01-22)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
#### Bug Fixes
|
|
111
|
+
|
|
112
|
+
* send output messages to the correct stream when using the XML formatter ([e768a33](/../../commit/e768a33))
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
<a name="v1.46.0"></a>
|
|
116
|
+
### v1.46.0 (2020-01-22)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
#### Features
|
|
120
|
+
|
|
121
|
+
* expose full notice object in JSON output ([bdc2711](/../../commit/bdc2711))
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
#### Bug Fixes
|
|
125
|
+
|
|
126
|
+
* remove accidentally committed verbose: true ([498518c](/../../commit/498518c))
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
<a name="v1.45.0"></a>
|
|
130
|
+
### v1.45.0 (2020-01-21)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
#### Features
|
|
134
|
+
|
|
135
|
+
* use custom json formatter when --format json is specified and send it straight to stdout or the configured file ([6c703a1](/../../commit/6c703a1))
|
|
136
|
+
* support pending pacts in json formatter ([2c0d20d](/../../commit/2c0d20d))
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
#### Bug Fixes
|
|
140
|
+
|
|
141
|
+
* show pending test output in yellow instead of red ([e8d4a55](/../../commit/e8d4a55))
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
<a name="v1.44.1"></a>
|
|
145
|
+
### v1.44.1 (2020-01-20)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
#### Bug Fixes
|
|
149
|
+
|
|
150
|
+
* print notices from 'pacts for verification' response to indicate why pacts are included an/or pending ([b107348](/../../commit/b107348))
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
<a name="v1.44.0"></a>
|
|
154
|
+
### v1.44.0 (2020-01-16)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
#### Features
|
|
158
|
+
|
|
159
|
+
* **message pact**
|
|
160
|
+
* add DSL for configuring Message Pact verifications ([a5181b6](/../../commit/a5181b6))
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
<a name="v1.43.1"></a>
|
|
164
|
+
### v1.43.1 (2020-01-11)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
#### Bug Fixes
|
|
168
|
+
|
|
169
|
+
* use configured credentials when fetching the diff with previous version ([b9deb09](/../../commit/b9deb09))
|
|
170
|
+
* use URI.open instead of Kernel.open ([7b3ea81](/../../commit/7b3ea81))
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
<a name="v1.43.0"></a>
|
|
174
|
+
### v1.43.0 (2020-01-11)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
#### Features
|
|
178
|
+
|
|
179
|
+
* **verify**
|
|
180
|
+
* allow includePendingStatus to be specified when fetching pacts ([1f5fc9c](/../../commit/1f5fc9c))
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
<a name="v1.42.3"></a>
|
|
184
|
+
### v1.42.3 (2019-11-15)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
#### Bug Fixes
|
|
188
|
+
|
|
189
|
+
* **verify**
|
|
190
|
+
* exit with status 0 if all pacts are in pending state ([2f7110b](/../../commit/2f7110b))
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
<a name="v1.42.2"></a>
|
|
194
|
+
### v1.42.2 (2019-11-09)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
#### Bug Fixes
|
|
198
|
+
|
|
199
|
+
* remove missed &. ([be700d8](/../../commit/be700d8))
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
<a name="v1.42.1"></a>
|
|
203
|
+
### v1.42.1 (2019-11-09)
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
#### Bug Fixes
|
|
207
|
+
|
|
208
|
+
* can't use safe navigation operator because of Ruby 2.2 in Travelling Ruby for the pact-ruby-standalone ([3068ceb](/../../commit/3068ceb))
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
<a name="v1.42.0"></a>
|
|
212
|
+
### v1.42.0 (2019-09-26)
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
#### Features
|
|
216
|
+
|
|
217
|
+
* use new 'pacts for verification' endpoint to retrieve pacts (#199) ([55bb935](/../../commit/55bb935))
|
|
218
|
+
|
|
219
|
+
|
|
1
220
|
<a name="v1.41.2"></a>
|
|
2
221
|
### v1.41.2 (2019-09-10)
|
|
3
222
|
|
|
@@ -3,7 +3,6 @@ require 'pact/cli/spec_criteria'
|
|
|
3
3
|
module Pact
|
|
4
4
|
module Cli
|
|
5
5
|
class RunPactVerification
|
|
6
|
-
|
|
7
6
|
attr_reader :options
|
|
8
7
|
|
|
9
8
|
def initialize options
|
|
@@ -15,6 +14,7 @@ module Pact
|
|
|
15
14
|
end
|
|
16
15
|
|
|
17
16
|
def call
|
|
17
|
+
configure_output
|
|
18
18
|
initialize_rspec
|
|
19
19
|
setup_load_path
|
|
20
20
|
load_pact_helper
|
|
@@ -44,24 +44,32 @@ module Pact
|
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
def run_specs
|
|
47
|
-
exit_code = if options[:pact_uri]
|
|
48
|
-
|
|
47
|
+
exit_code = if options[:pact_uri].is_a?(String)
|
|
48
|
+
run_with_pact_url_string
|
|
49
|
+
elsif options[:pact_uri]
|
|
50
|
+
run_with_pact_uri_object # from pact-provider-verifier
|
|
49
51
|
else
|
|
50
|
-
|
|
52
|
+
run_with_configured_pacts_from_pact_helper
|
|
51
53
|
end
|
|
52
54
|
exit exit_code
|
|
53
55
|
end
|
|
54
56
|
|
|
55
|
-
def
|
|
57
|
+
def run_with_pact_url_string
|
|
56
58
|
pact_repository_uri_options = {}
|
|
59
|
+
pact_repository_uri_options[:username] = ENV['PACT_BROKER_USERNAME'] if ENV['PACT_BROKER_USERNAME']
|
|
60
|
+
pact_repository_uri_options[:password] = ENV['PACT_BROKER_PASSWORD'] if ENV['PACT_BROKER_PASSWORD']
|
|
61
|
+
pact_repository_uri_options[:token] = ENV['PACT_BROKER_TOKEN']
|
|
57
62
|
pact_repository_uri_options[:username] = options[:pact_broker_username] if options[:pact_broker_username]
|
|
58
63
|
pact_repository_uri_options[:password] = options[:pact_broker_password] if options[:pact_broker_password]
|
|
59
|
-
pact_repository_uri_options[:token] = ENV['PACT_BROKER_TOKEN']
|
|
60
64
|
pact_uri = ::Pact::Provider::PactURI.new(options[:pact_uri], pact_repository_uri_options)
|
|
61
65
|
Pact::Provider::PactSpecRunner.new([pact_uri], pact_spec_options).run
|
|
62
66
|
end
|
|
63
67
|
|
|
64
|
-
def
|
|
68
|
+
def run_with_pact_uri_object
|
|
69
|
+
Pact::Provider::PactSpecRunner.new([options[:pact_uri]], pact_spec_options).run
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def run_with_configured_pacts_from_pact_helper
|
|
65
73
|
pact_urls = Pact.provider_world.pact_urls
|
|
66
74
|
raise "Please configure a pact to verify" if pact_urls.empty?
|
|
67
75
|
Pact::Provider::PactSpecRunner.new(pact_urls, pact_spec_options).run
|
|
@@ -77,6 +85,14 @@ module Pact
|
|
|
77
85
|
request_customizer: options[:request_customizer]
|
|
78
86
|
}
|
|
79
87
|
end
|
|
88
|
+
|
|
89
|
+
def configure_output
|
|
90
|
+
if options[:format] == 'json' && !options[:out]
|
|
91
|
+
# Don't want to mess up the JSON parsing with messages to stdout, so send it to stderr
|
|
92
|
+
require 'pact/configuration'
|
|
93
|
+
Pact.configuration.output_stream = Pact.configuration.error_stream
|
|
94
|
+
end
|
|
95
|
+
end
|
|
80
96
|
end
|
|
81
97
|
end
|
|
82
98
|
end
|
|
@@ -6,8 +6,11 @@ module Pact
|
|
|
6
6
|
criteria = {}
|
|
7
7
|
|
|
8
8
|
criteria[:description] = Regexp.new(options[:description]) if options[:description]
|
|
9
|
+
criteria[:_id] = options[:pact_broker_interaction_id] if options[:pact_broker_interaction_id]
|
|
10
|
+
criteria[:index] = options[:interaction_index] if options[:interaction_index]
|
|
9
11
|
|
|
10
12
|
provider_state = options[:provider_state]
|
|
13
|
+
|
|
11
14
|
if provider_state
|
|
12
15
|
if provider_state.length == 0
|
|
13
16
|
criteria[:provider_state] = nil #Allow PACT_PROVIDER_STATE="" to mean no provider state
|
data/lib/pact/cli.rb
CHANGED
|
@@ -4,6 +4,9 @@ require 'pact/provider/configuration'
|
|
|
4
4
|
|
|
5
5
|
module Pact
|
|
6
6
|
class CLI < Thor
|
|
7
|
+
def self.exit_on_failure? # Thor 1.0 deprecation guard
|
|
8
|
+
false
|
|
9
|
+
end
|
|
7
10
|
|
|
8
11
|
desc 'verify', "Verify a pact"
|
|
9
12
|
method_option :pact_helper, aliases: "-h", desc: "Pact helper file", :required => true
|
|
@@ -18,6 +21,8 @@ module Pact
|
|
|
18
21
|
default: Pact.configuration.interactions_replay_order
|
|
19
22
|
method_option :description, aliases: "-d", desc: "Interaction description filter"
|
|
20
23
|
method_option :provider_state, aliases: "-s", desc: "Provider state filter"
|
|
24
|
+
method_option :interaction_index, type: :numeric, desc: "Index filter"
|
|
25
|
+
method_option :pact_broker_interaction_id, desc: "Pact Broker interaction ID filter"
|
|
21
26
|
method_option :format, aliases: "-f", banner: "FORMATTER", desc: "RSpec formatter. Defaults to custom Pact formatter. [j]son may also be used."
|
|
22
27
|
method_option :out, aliases: "-o", banner: "FILE", desc: "Write output to a file instead of $stdout."
|
|
23
28
|
|
|
@@ -25,6 +25,10 @@ module Pact
|
|
|
25
25
|
@mock_service_base_url = "http://#{attributes[:host]}:#{attributes[:port]}"
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
+
def without_writing_to_pact
|
|
29
|
+
interaction_builder.without_writing_to_pact
|
|
30
|
+
end
|
|
31
|
+
|
|
28
32
|
def given(provider_state)
|
|
29
33
|
interaction_builder.given(provider_state)
|
|
30
34
|
end
|
|
@@ -13,6 +13,12 @@ module Pact
|
|
|
13
13
|
@callback = block
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
def without_writing_to_pact
|
|
17
|
+
interaction.metadata ||= {}
|
|
18
|
+
interaction.metadata[:write_to_pact] = false
|
|
19
|
+
self
|
|
20
|
+
end
|
|
21
|
+
|
|
16
22
|
def upon_receiving description
|
|
17
23
|
@interaction.description = description
|
|
18
24
|
self
|
|
@@ -29,7 +29,7 @@ module Pact
|
|
|
29
29
|
|
|
30
30
|
def after_suite
|
|
31
31
|
if Pact.consumer_world.any_pact_examples_ran?
|
|
32
|
-
Pact.consumer_world.consumer_contract_builders.each
|
|
32
|
+
Pact.consumer_world.consumer_contract_builders.each(&:write_pact)
|
|
33
33
|
Pact::Doc::Generate.call
|
|
34
34
|
Pact::MockService::AppManager.instance.kill_all
|
|
35
35
|
Pact::MockService::AppManager.instance.clear_all
|
|
@@ -37,4 +37,4 @@ module Pact
|
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
|
-
end
|
|
40
|
+
end
|
|
@@ -3,7 +3,7 @@ module Pact
|
|
|
3
3
|
class SortInteractions
|
|
4
4
|
|
|
5
5
|
def self.call interactions
|
|
6
|
-
interactions.
|
|
6
|
+
interactions.sort_by { |interaction| sortable_id(interaction) }
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
private
|
|
@@ -11,7 +11,6 @@ module Pact
|
|
|
11
11
|
def self.sortable_id interaction
|
|
12
12
|
"#{interaction.description.downcase} #{interaction.response.status} #{(interaction.provider_state || '').downcase}"
|
|
13
13
|
end
|
|
14
|
-
|
|
15
14
|
end
|
|
16
15
|
end
|
|
17
|
-
end
|
|
16
|
+
end
|
data/lib/pact/hal/http_client.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require 'pact/retry'
|
|
2
2
|
require 'pact/hal/authorization_header_redactor'
|
|
3
3
|
require 'net/http'
|
|
4
|
+
require 'rack'
|
|
4
5
|
|
|
5
6
|
module Pact
|
|
6
7
|
module Hal
|
|
@@ -15,9 +16,11 @@ module Pact
|
|
|
15
16
|
end
|
|
16
17
|
|
|
17
18
|
def get href, params = {}, headers = {}
|
|
18
|
-
query = params.collect{ |(key, value)| "#{CGI::escape(key)}=#{CGI::escape(value)}" }.join("&")
|
|
19
19
|
uri = URI(href)
|
|
20
|
-
|
|
20
|
+
if params && params.any?
|
|
21
|
+
existing_params = Rack::Utils.parse_nested_query(uri.query)
|
|
22
|
+
uri.query = Rack::Utils.build_nested_query(existing_params.merge(params))
|
|
23
|
+
end
|
|
21
24
|
perform_request(create_request(uri, 'Get', nil, headers), uri)
|
|
22
25
|
end
|
|
23
26
|
|
|
@@ -33,12 +36,9 @@ module Pact
|
|
|
33
36
|
|
|
34
37
|
def create_request uri, http_method, body = nil, headers = {}
|
|
35
38
|
request = Net::HTTP.const_get(http_method).new(uri.request_uri)
|
|
36
|
-
request['Content-Type'] = "application/json" if ['Post', 'Put', 'Patch'].include?(http_method)
|
|
37
|
-
request['Accept'] = "application/hal+json"
|
|
38
39
|
headers.each do | key, value |
|
|
39
40
|
request[key] = value
|
|
40
41
|
end
|
|
41
|
-
|
|
42
42
|
request.body = body if body
|
|
43
43
|
request.basic_auth username, password if username
|
|
44
44
|
request['Authorization'] = "Bearer #{token}" if token
|
|
@@ -50,6 +50,8 @@ module Pact
|
|
|
50
50
|
http = Net::HTTP.new(uri.host, uri.port, :ENV)
|
|
51
51
|
http.set_debug_output(output_stream) if verbose
|
|
52
52
|
http.use_ssl = (uri.scheme == 'https')
|
|
53
|
+
http.ca_file = ENV['SSL_CERT_FILE'] if ENV['SSL_CERT_FILE'] && ENV['SSL_CERT_FILE'] != ''
|
|
54
|
+
http.ca_path = ENV['SSL_CERT_DIR'] if ENV['SSL_CERT_DIR'] && ENV['SSL_CERT_DIR'] != ''
|
|
53
55
|
http.start do |http|
|
|
54
56
|
http.request request
|
|
55
57
|
end
|
|
@@ -82,6 +84,10 @@ module Pact
|
|
|
82
84
|
def success?
|
|
83
85
|
__getobj__().code.start_with?("2")
|
|
84
86
|
end
|
|
87
|
+
|
|
88
|
+
def json?
|
|
89
|
+
self['content-type'] && self['content-type'] =~ /json/
|
|
90
|
+
end
|
|
85
91
|
end
|
|
86
92
|
end
|
|
87
93
|
end
|
data/lib/pact/hal/link.rb
CHANGED
|
@@ -6,6 +6,15 @@ module Pact
|
|
|
6
6
|
class Link
|
|
7
7
|
attr_reader :request_method, :href
|
|
8
8
|
|
|
9
|
+
DEFAULT_GET_HEADERS = {
|
|
10
|
+
"Accept" => "application/hal+json"
|
|
11
|
+
}.freeze
|
|
12
|
+
|
|
13
|
+
DEFAULT_POST_HEADERS = {
|
|
14
|
+
"Accept" => "application/hal+json",
|
|
15
|
+
"Content-Type" => "application/json"
|
|
16
|
+
}.freeze
|
|
17
|
+
|
|
9
18
|
def initialize(attrs, http_client)
|
|
10
19
|
@attrs = attrs
|
|
11
20
|
@request_method = attrs.fetch(:method, :get).to_sym
|
|
@@ -14,14 +23,14 @@ module Pact
|
|
|
14
23
|
end
|
|
15
24
|
|
|
16
25
|
def run(payload = nil)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
case request_method
|
|
27
|
+
when :get
|
|
28
|
+
get(payload)
|
|
29
|
+
when :put
|
|
30
|
+
put(payload)
|
|
31
|
+
when :post
|
|
32
|
+
post(payload)
|
|
33
|
+
end
|
|
25
34
|
end
|
|
26
35
|
|
|
27
36
|
def title_or_name
|
|
@@ -37,29 +46,57 @@ module Pact
|
|
|
37
46
|
end
|
|
38
47
|
|
|
39
48
|
def get(payload = {}, headers = {})
|
|
40
|
-
wrap_response(href, @http_client.get(href, payload, headers))
|
|
49
|
+
wrap_response(href, @http_client.get(href, payload, DEFAULT_GET_HEADERS.merge(headers)))
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def get!(*args)
|
|
53
|
+
get(*args).assert_success!
|
|
41
54
|
end
|
|
42
55
|
|
|
43
56
|
def put(payload = nil, headers = {})
|
|
44
|
-
wrap_response(href, @http_client.put(href, payload ? payload.to_json : nil, headers))
|
|
57
|
+
wrap_response(href, @http_client.put(href, payload ? payload.to_json : nil, DEFAULT_POST_HEADERS.merge(headers)))
|
|
45
58
|
end
|
|
46
59
|
|
|
47
60
|
def post(payload = nil, headers = {})
|
|
48
|
-
wrap_response(href, @http_client.post(href, payload ? payload.to_json : nil, headers))
|
|
61
|
+
wrap_response(href, @http_client.post(href, payload ? payload.to_json : nil, DEFAULT_POST_HEADERS.merge(headers)))
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def post!(payload = nil, headers = {})
|
|
65
|
+
post(payload, headers).assert_success!
|
|
49
66
|
end
|
|
50
67
|
|
|
51
68
|
def expand(params)
|
|
52
69
|
expanded_url = expand_url(params, href)
|
|
53
70
|
new_attrs = @attrs.merge('href' => expanded_url)
|
|
54
|
-
Link.new(new_attrs,
|
|
71
|
+
Link.new(new_attrs, http_client)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def with_query(query)
|
|
75
|
+
if query && query.any?
|
|
76
|
+
uri = URI(href)
|
|
77
|
+
existing_query_params = Rack::Utils.parse_nested_query(uri.query)
|
|
78
|
+
uri.query = Rack::Utils.build_nested_query(existing_query_params.merge(query))
|
|
79
|
+
new_attrs = attrs.merge('href' => uri.to_s)
|
|
80
|
+
Link.new(new_attrs, http_client)
|
|
81
|
+
else
|
|
82
|
+
self
|
|
83
|
+
end
|
|
55
84
|
end
|
|
56
85
|
|
|
57
86
|
private
|
|
58
87
|
|
|
88
|
+
attr_reader :attrs, :http_client
|
|
89
|
+
|
|
59
90
|
def wrap_response(href, http_response)
|
|
60
91
|
require 'pact/hal/entity' # avoid circular reference
|
|
92
|
+
require 'pact/hal/non_json_entity'
|
|
93
|
+
|
|
61
94
|
if http_response.success?
|
|
62
|
-
|
|
95
|
+
if http_response.json?
|
|
96
|
+
Entity.new(href, http_response.body, @http_client, http_response)
|
|
97
|
+
else
|
|
98
|
+
NonJsonEntity.new(href, http_response.raw_body, @http_client, http_response)
|
|
99
|
+
end
|
|
63
100
|
else
|
|
64
101
|
ErrorEntity.new(href, http_response.raw_body, @http_client, http_response)
|
|
65
102
|
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Pact
|
|
2
|
+
module Hal
|
|
3
|
+
class NonJsonEntity
|
|
4
|
+
def initialize(href, body, http_client, response = nil)
|
|
5
|
+
@href = href
|
|
6
|
+
@body = body
|
|
7
|
+
@client = http_client
|
|
8
|
+
@response = response
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def success?
|
|
12
|
+
true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def response
|
|
16
|
+
@response
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def body
|
|
20
|
+
@body
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def assert_success!
|
|
24
|
+
self
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
require 'pact/hal/entity'
|
|
2
|
+
require 'pact/hal/http_client'
|
|
3
|
+
require 'pact/provider/pact_uri'
|
|
4
|
+
require 'pact/errors'
|
|
5
|
+
require 'pact/pact_broker/fetch_pacts'
|
|
6
|
+
require 'pact/pact_broker/notices'
|
|
7
|
+
require 'pact/pact_broker/pact_selection_description'
|
|
8
|
+
|
|
9
|
+
module Pact
|
|
10
|
+
module PactBroker
|
|
11
|
+
class FetchPactURIsForVerification
|
|
12
|
+
include PactSelectionDescription
|
|
13
|
+
attr_reader :provider, :consumer_version_selectors, :provider_version_tags, :broker_base_url, :http_client_options, :http_client, :options
|
|
14
|
+
|
|
15
|
+
PACTS_FOR_VERIFICATION_RELATION = 'beta:provider-pacts-for-verification'.freeze
|
|
16
|
+
PACTS = 'pacts'.freeze
|
|
17
|
+
HREF = 'href'.freeze
|
|
18
|
+
LINKS = '_links'.freeze
|
|
19
|
+
SELF = 'self'.freeze
|
|
20
|
+
EMBEDDED = '_embedded'.freeze
|
|
21
|
+
|
|
22
|
+
def initialize(provider, consumer_version_selectors, provider_version_tags, broker_base_url, http_client_options, options = {})
|
|
23
|
+
@provider = provider
|
|
24
|
+
@consumer_version_selectors = consumer_version_selectors || []
|
|
25
|
+
@provider_version_tags = [*provider_version_tags]
|
|
26
|
+
@http_client_options = http_client_options
|
|
27
|
+
@broker_base_url = broker_base_url
|
|
28
|
+
@http_client = Pact::Hal::HttpClient.new(http_client_options)
|
|
29
|
+
@options = options
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.call(provider, consumer_version_selectors, provider_version_tags, broker_base_url, http_client_options, options = {})
|
|
33
|
+
new(provider, consumer_version_selectors, provider_version_tags, broker_base_url, http_client_options, options).call
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def call
|
|
37
|
+
if index.can?(PACTS_FOR_VERIFICATION_RELATION)
|
|
38
|
+
log_message
|
|
39
|
+
pacts_for_verification
|
|
40
|
+
else
|
|
41
|
+
# Fall back to old method of fetching pacts
|
|
42
|
+
consumer_version_tags = consumer_version_selectors.collect{ | selector | selector[:tag] }
|
|
43
|
+
FetchPacts.call(provider, consumer_version_tags, broker_base_url, http_client_options)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def index
|
|
50
|
+
@index_entity ||= Pact::Hal::Link.new({ "href" => broker_base_url }, http_client).get.assert_success!
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def pacts_for_verification
|
|
54
|
+
pacts_for_verification_entity.response.body[EMBEDDED][PACTS].collect do | pact |
|
|
55
|
+
metadata = {
|
|
56
|
+
pending: pact["verificationProperties"]["pending"],
|
|
57
|
+
notices: extract_notices(pact),
|
|
58
|
+
short_description: pact["shortDescription"]
|
|
59
|
+
}
|
|
60
|
+
Pact::Provider::PactURI.new(pact[LINKS][SELF][HREF], http_client_options, metadata)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def pacts_for_verification_entity
|
|
65
|
+
index
|
|
66
|
+
._link(PACTS_FOR_VERIFICATION_RELATION)
|
|
67
|
+
.expand(provider: provider)
|
|
68
|
+
.post!(query)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def query
|
|
72
|
+
q = {}
|
|
73
|
+
q["includePendingStatus"] = true if options[:include_pending_status]
|
|
74
|
+
q["consumerVersionSelectors"] = consumer_version_selectors if consumer_version_selectors.any?
|
|
75
|
+
q["providerVersionTags"] = provider_version_tags if provider_version_tags.any?
|
|
76
|
+
q["includeWipPactsSince"] = options[:include_wip_pacts_since] if options[:include_wip_pacts_since]
|
|
77
|
+
q
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def extract_notices(pact)
|
|
81
|
+
Notices.new((pact["verificationProperties"]["notices"] || []).collect{ |notice| symbolize_keys(notice) })
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def symbolize_keys(hash)
|
|
85
|
+
hash.each_with_object({}){ |(k,v), h| h[k.to_sym] = v }
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def log_message
|
|
89
|
+
Pact.configuration.output_stream.puts "INFO: #{pact_selection_description(provider, consumer_version_selectors, options, broker_base_url)}"
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|