pact 1.41.2 → 1.54.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.
Files changed (43) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +228 -0
  3. data/lib/pact/cli/run_pact_verification.rb +23 -7
  4. data/lib/pact/cli/spec_criteria.rb +3 -0
  5. data/lib/pact/cli.rb +5 -0
  6. data/lib/pact/consumer/configuration/dsl.rb +0 -1
  7. data/lib/pact/consumer/consumer_contract_builder.rb +4 -0
  8. data/lib/pact/consumer/interaction_builder.rb +6 -0
  9. data/lib/pact/consumer/spec_hooks.rb +2 -2
  10. data/lib/pact/doc/sort_interactions.rb +2 -3
  11. data/lib/pact/hal/http_client.rb +11 -5
  12. data/lib/pact/hal/link.rb +50 -13
  13. data/lib/pact/hal/non_json_entity.rb +28 -0
  14. data/lib/pact/pact_broker/fetch_pact_uris_for_verification.rb +94 -0
  15. data/lib/pact/pact_broker/notices.rb +34 -0
  16. data/lib/pact/pact_broker/pact_selection_description.rb +24 -0
  17. data/lib/pact/pact_broker.rb +10 -4
  18. data/lib/pact/provider/configuration/dsl.rb +6 -1
  19. data/lib/pact/provider/configuration/message_provider_dsl.rb +59 -0
  20. data/lib/pact/provider/configuration/pact_verification_from_broker.rb +37 -4
  21. data/lib/pact/provider/configuration/service_provider_dsl.rb +1 -1
  22. data/lib/pact/provider/help/content.rb +4 -4
  23. data/lib/pact/provider/help/pact_diff.rb +10 -34
  24. data/lib/pact/provider/help/write.rb +6 -7
  25. data/lib/pact/provider/pact_helper_locator.rb +0 -1
  26. data/lib/pact/provider/pact_source.rb +10 -1
  27. data/lib/pact/provider/pact_spec_runner.rb +24 -16
  28. data/lib/pact/provider/pact_uri.rb +8 -6
  29. data/lib/pact/provider/request.rb +1 -1
  30. data/lib/pact/provider/rspec/formatter_rspec_3.rb +21 -6
  31. data/lib/pact/provider/rspec/json_formatter.rb +100 -0
  32. data/lib/pact/provider/rspec/pact_broker_formatter.rb +1 -1
  33. data/lib/pact/provider/rspec.rb +17 -7
  34. data/lib/pact/provider/test_methods.rb +9 -3
  35. data/lib/pact/provider/verification_results/publish.rb +3 -0
  36. data/lib/pact/provider/verification_results/publish_all.rb +14 -1
  37. data/lib/pact/provider/verification_results/verification_result.rb +1 -4
  38. data/lib/pact/provider/world.rb +1 -1
  39. data/lib/pact/tasks/task_helper.rb +6 -1
  40. data/lib/pact/version.rb +1 -1
  41. data/pact.gemspec +11 -13
  42. metadata +59 -56
  43. data/lib/pact/pact_broker/fetch_pending_pacts.rb +0 -58
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 682d57626c30c4ce3f4e83038a3e5ff54d0f4878
4
- data.tar.gz: 7eb5834ea442abebf6e8739a5a2746514560fdc8
2
+ SHA256:
3
+ metadata.gz: 668b177b7d244716ded4b592c37be8788ce6d0e1fd4036becdf5025a73e40022
4
+ data.tar.gz: 3185c5eeca1d02878e916b1feb6eddc4888a139374548987fc295d90b38d67c6
5
5
  SHA512:
6
- metadata.gz: 369f376d001db7fac67ed5fce394dd0672c735de178c4c940b67082e7f36e7b8f43e18f2eb91d93403c969a1c26a995c229331f14780563e18b957456951b814
7
- data.tar.gz: db56fdd2c74f3cba9dd6b1e3ec7983eb50a46888f2c6ea7a9a70f2153738be1bbd6a53894a433d70d8f8dd4329b3526334b31c825cc7bcf75d4072e962f4f506
6
+ metadata.gz: 217392c245364ea7df2e75851d211760a57cb5ec19285d8a5f7cd1f770ff85211115d4137d8b60a2c6c7b75ccb7a2fceb85c17ba00f4ef727f452f11e09e2d67
7
+ data.tar.gz: 111d4ddd772e5367485f716c19d9a8e64f8ce3e3045c273b48535dade001913bb6af2e552f6cc9f7e767b0f14d9111f62d7f114dd7b5318cdfcaade3a1ecab0f
data/CHANGELOG.md CHANGED
@@ -1,3 +1,231 @@
1
+ <a name="v1.54.0"></a>
2
+ ### v1.54.0 (2020-09-12)
3
+
4
+ #### Features
5
+
6
+ * use pb relation in preference to beta relation when fetching pacts for verification ([7563fcf](/../../commit/7563fcf))
7
+ * allow include_wip_pacts_since to use a Date, DateTime or Time ([dd35366](/../../commit/dd35366))
8
+ * add support for include_wip_pacts_since ([f2247b8](/../../commit/f2247b8))
9
+
10
+ <a name="v1.53.0"></a>
11
+ ### v1.53.0 (2020-09-11)
12
+
13
+ #### Features
14
+
15
+ * add support for the enable_pending flag ([16866f4](/../../commit/16866f4))
16
+
17
+ <a name="v1.52.0"></a>
18
+ ### v1.52.0 (2020-09-10)
19
+
20
+ #### Features
21
+
22
+ * support webdav http methods ([fa1d712](/../../commit/fa1d712))
23
+
24
+ <a name="v1.51.1"></a>
25
+ ### v1.51.1 (2020-08-12)
26
+
27
+ #### Bug Fixes
28
+
29
+ * update thor dependency (#218) ([bf3ce69](/../../commit/bf3ce69))
30
+ * bump rake dependency per CVE-2020-8130 (#219) ([09feaa6](/../../commit/09feaa6))
31
+
32
+ <a name="v1.51.0"></a>
33
+ ### v1.51.0 (2020-06-24)
34
+
35
+
36
+ #### Features
37
+
38
+ * allow individual interactions to be re-run by setting PACT_BROKER_INTERACTION_ID ([a586d80](/../../commit/a586d80))
39
+
40
+
41
+ <a name="v1.50.1"></a>
42
+ ### v1.50.1 (2020-06-15)
43
+
44
+
45
+ #### Bug Fixes
46
+
47
+ * fix integration with pact-message-ruby (#216) ([d2da13e](/../../commit/d2da13e))
48
+
49
+
50
+ <a name="v1.50.0"></a>
51
+ ### v1.50.0 (2020-04-25)
52
+
53
+
54
+ #### Features
55
+
56
+ * Set expected interactions on mock service but without writing them to pact file (#210) ([14f5327](/../../commit/14f5327))
57
+
58
+
59
+ <a name="v1.49.3"></a>
60
+ ### v1.49.3 (2020-04-22)
61
+
62
+
63
+ #### Bug Fixes
64
+
65
+ * pact selection verification options logging ([9ff59f4](/../../commit/9ff59f4))
66
+
67
+
68
+ <a name="v1.49.2"></a>
69
+ ### v1.49.2 (2020-04-08)
70
+
71
+
72
+ #### Bug Fixes
73
+
74
+ * json parser error for top level JSON values ([dafbc35](/../../commit/dafbc35))
75
+
76
+
77
+ <a name="v1.49.1"></a>
78
+ ### v1.49.1 (2020-03-21)
79
+
80
+
81
+ #### Bug Fixes
82
+
83
+ * ensure diff is included in the json output ([0bd9753](/../../commit/0bd9753))
84
+ * 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))
85
+
86
+
87
+ <a name="v1.49.0"></a>
88
+ ### v1.49.0 (2020-02-18)
89
+
90
+
91
+ #### Features
92
+
93
+ * 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))
94
+
95
+
96
+ <a name="v1.48.0"></a>
97
+ ### v1.48.0 (2020-02-13)
98
+
99
+
100
+ #### Features
101
+
102
+ * use certificates from SSL_CERT_FILE and SSL_CERT_DIR environment variables in HTTP connections ([164912b](/../../commit/164912b))
103
+
104
+
105
+ <a name="v1.47.0"></a>
106
+ ### v1.47.0 (2020-02-08)
107
+
108
+
109
+ #### Features
110
+
111
+ * update json formatter output ([376e47a](/../../commit/376e47a))
112
+ * add pact metadata to json formatter ([6c6ddb8](/../../commit/6c6ddb8))
113
+
114
+
115
+ <a name="v1.46.1"></a>
116
+ ### v1.46.1 (2020-01-22)
117
+
118
+
119
+ #### Bug Fixes
120
+
121
+ * send output messages to the correct stream when using the XML formatter ([e768a33](/../../commit/e768a33))
122
+
123
+
124
+ <a name="v1.46.0"></a>
125
+ ### v1.46.0 (2020-01-22)
126
+
127
+
128
+ #### Features
129
+
130
+ * expose full notice object in JSON output ([bdc2711](/../../commit/bdc2711))
131
+
132
+
133
+ #### Bug Fixes
134
+
135
+ * remove accidentally committed verbose: true ([498518c](/../../commit/498518c))
136
+
137
+
138
+ <a name="v1.45.0"></a>
139
+ ### v1.45.0 (2020-01-21)
140
+
141
+
142
+ #### Features
143
+
144
+ * use custom json formatter when --format json is specified and send it straight to stdout or the configured file ([6c703a1](/../../commit/6c703a1))
145
+ * support pending pacts in json formatter ([2c0d20d](/../../commit/2c0d20d))
146
+
147
+
148
+ #### Bug Fixes
149
+
150
+ * show pending test output in yellow instead of red ([e8d4a55](/../../commit/e8d4a55))
151
+
152
+
153
+ <a name="v1.44.1"></a>
154
+ ### v1.44.1 (2020-01-20)
155
+
156
+
157
+ #### Bug Fixes
158
+
159
+ * print notices from 'pacts for verification' response to indicate why pacts are included an/or pending ([b107348](/../../commit/b107348))
160
+
161
+
162
+ <a name="v1.44.0"></a>
163
+ ### v1.44.0 (2020-01-16)
164
+
165
+
166
+ #### Features
167
+
168
+ * **message pact**
169
+ * add DSL for configuring Message Pact verifications ([a5181b6](/../../commit/a5181b6))
170
+
171
+
172
+ <a name="v1.43.1"></a>
173
+ ### v1.43.1 (2020-01-11)
174
+
175
+
176
+ #### Bug Fixes
177
+
178
+ * use configured credentials when fetching the diff with previous version ([b9deb09](/../../commit/b9deb09))
179
+ * use URI.open instead of Kernel.open ([7b3ea81](/../../commit/7b3ea81))
180
+
181
+
182
+ <a name="v1.43.0"></a>
183
+ ### v1.43.0 (2020-01-11)
184
+
185
+
186
+ #### Features
187
+
188
+ * **verify**
189
+ * allow includePendingStatus to be specified when fetching pacts ([1f5fc9c](/../../commit/1f5fc9c))
190
+
191
+
192
+ <a name="v1.42.3"></a>
193
+ ### v1.42.3 (2019-11-15)
194
+
195
+
196
+ #### Bug Fixes
197
+
198
+ * **verify**
199
+ * exit with status 0 if all pacts are in pending state ([2f7110b](/../../commit/2f7110b))
200
+
201
+
202
+ <a name="v1.42.2"></a>
203
+ ### v1.42.2 (2019-11-09)
204
+
205
+
206
+ #### Bug Fixes
207
+
208
+ * remove missed &. ([be700d8](/../../commit/be700d8))
209
+
210
+
211
+ <a name="v1.42.1"></a>
212
+ ### v1.42.1 (2019-11-09)
213
+
214
+
215
+ #### Bug Fixes
216
+
217
+ * can't use safe navigation operator because of Ruby 2.2 in Travelling Ruby for the pact-ruby-standalone ([3068ceb](/../../commit/3068ceb))
218
+
219
+
220
+ <a name="v1.42.0"></a>
221
+ ### v1.42.0 (2019-09-26)
222
+
223
+
224
+ #### Features
225
+
226
+ * use new 'pacts for verification' endpoint to retrieve pacts (#199) ([55bb935](/../../commit/55bb935))
227
+
228
+
1
229
  <a name="v1.41.2"></a>
2
230
  ### v1.41.2 (2019-09-10)
3
231
 
@@ -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
- run_with_pact_uri
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
- run_with_configured_pacts
52
+ run_with_configured_pacts_from_pact_helper
51
53
  end
52
54
  exit exit_code
53
55
  end
54
56
 
55
- def run_with_pact_uri
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 run_with_configured_pacts
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
 
@@ -1,7 +1,6 @@
1
1
  require 'pact/consumer/configuration/service_consumer'
2
2
 
3
3
  module Pact
4
-
5
4
  module Consumer
6
5
  module DSL
7
6
  def service_consumer name, &block
@@ -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 { | c | c.write_pact }
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.sort{|a, b| sortable_id(a) <=> sortable_id(b)}
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
@@ -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
- uri.query = query
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
- response = case request_method
18
- when :get
19
- get(payload)
20
- when :put
21
- put(payload)
22
- when :post
23
- post(payload)
24
- end
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, @http_client)
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
- Entity.new(href, http_response.body, @http_client, http_response)
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