pact-mock_service 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +5 -13
  2. data/.gitignore +1 -0
  3. data/.rspec +1 -0
  4. data/CHANGELOG.md +4 -0
  5. data/lib/pact/consumer/mock_service/interaction_post.rb +3 -2
  6. data/lib/pact/consumer/mock_service/interaction_replay.rb +5 -4
  7. data/lib/pact/consumer/mock_service_client.rb +10 -2
  8. data/lib/pact/consumer_contract/consumer_contract_decorator.rb +33 -0
  9. data/lib/pact/consumer_contract/consumer_contract_writer.rb +41 -8
  10. data/lib/pact/consumer_contract/interaction_decorator.rb +43 -0
  11. data/lib/pact/consumer_contract/request_decorator.rb +69 -0
  12. data/lib/pact/consumer_contract/response_decorator.rb +29 -0
  13. data/lib/pact/mock_service/interaction_decorator.rb +48 -0
  14. data/lib/pact/mock_service/request_decorator.rb +36 -0
  15. data/lib/pact/mock_service/response_decorator.rb +31 -0
  16. data/lib/pact/mock_service/version.rb +1 -1
  17. data/pact-mock-service.gemspec +1 -3
  18. data/spec/lib/pact/consumer/mock_service_client_spec.rb +1 -1
  19. data/spec/lib/pact/consumer_contract/consumer_contract_writer_spec.rb +2 -2
  20. data/spec/lib/pact/consumer_contract/request_decorator_spec.rb +80 -0
  21. data/spec/lib/pact/consumer_contract/response_decorator_spec.rb +10 -0
  22. data/spec/lib/pact/mock_service/interaction_decorator_spec.rb +74 -0
  23. data/spec/lib/pact/mock_service/request_decorator_spec.rb +76 -0
  24. data/spec/lib/pact/mock_service/response_decorator_spec.rb +12 -0
  25. data/spec/support/shared_examples_for_response_decorator.rb +25 -0
  26. metadata +54 -26
  27. data/Gemfile.lock +0 -100
  28. data/lib/pact/consumer/mock_service_interaction_expectation.rb +0 -37
  29. data/lib/pact/consumer/request.rb +0 -27
  30. data/spec/lib/pact/consumer/mock_service_interaction_expectation_spec.rb +0 -54
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NjM1YTc2NzkzNDg1MjEzZDEwMDMyY2YxZWZlMGE1MjdlYjQyZTI2Nw==
5
- data.tar.gz: !binary |-
6
- ZDgyMzllNDQ5MTc1NDlkNjRhZmQyYzU1ZTRiM2M5N2JkYjRkNWUxMA==
2
+ SHA1:
3
+ metadata.gz: d4d778c67c786242b411bfeb2ea68de4d8a8ba02
4
+ data.tar.gz: be3a2b3caab987b807e6844f35311450e51b5a7f
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- NmQ3ZmMyNjQ4ZDBmN2U5N2E5OTI5NDVhZWE1MDg3M2FiNzQ4MjlmMWE0MzBl
10
- YmM3MWU1OWY2NTg4MGRiYWU2OWM4NDZjYjlhNGQwNzRlMDA0M2QyMDk3Nzdj
11
- NTA4MGI0YzAzOTg5ZWI5OTczNThkNzE3MWJhYmFmZTNjZjQxZGQ=
12
- data.tar.gz: !binary |-
13
- MDQxMWZmNGI3YjI5NmM1ZDk4Yzc3YjkyM2U5Y2Q3OGE2NWMwYWE3ZGFkMjVi
14
- Y2ZlZTU5N2U5ZjM4YTEwMTVmNjFhNmJmNGU3ZTE0NjhjYTI2MzExOTY2ZmVm
15
- ZGZmYzRjZTdhZjJlZTE5MjA5OGE4NzQxZWU1MzA4YzAzNWU5MTg=
6
+ metadata.gz: 77f56fc00125a93dc33d68e7ec16c1355393fa05f30b89df2370000b794ebe0d6a245d11c35476155c1934f29a09df1b7aec9a5e772996919d4573df6f9702d0
7
+ data.tar.gz: b3b60e97d6553ce8318bbe71e76c681263fed8598fe5cf22e25db38a0be6ac1704c4cad12ef7f169706b8d9e8ddfd5727a12eff13d6e55ca8bddf247e6d92ff8
data/.gitignore CHANGED
@@ -27,3 +27,4 @@ spec/pacts
27
27
  log
28
28
  .idea
29
29
  reports
30
+ Gemfile.lock
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
1
  --color
2
2
  --format documentation
3
+ --require spec_helper
data/CHANGELOG.md CHANGED
@@ -2,3 +2,7 @@ Do this to generate your change history
2
2
 
3
3
  git log --pretty=format:' * %h - %s (%an, %ad)'
4
4
 
5
+ ### 0.1.0 (22 October 2014)
6
+
7
+ * 62caf8e - Removed Gemfile.lock from git (bethesque, Wed Oct 22 13:07:54 2014 +1100)
8
+ * 5b4d54e - Moved JSON serialisation code into decorators. Serialisation between DSL and mock service is different from serialisation to the pact file. (bethesque, Wed Oct 22 13:07:00 2014 +1100)
@@ -20,10 +20,11 @@ module Pact
20
20
  end
21
21
 
22
22
  def respond env
23
- interaction = Interaction.from_hash(JSON.load(env['rack.input'].string))
23
+ request_body = env['rack.input'].string
24
+ interaction = Interaction.from_hash(JSON.load(request_body))
24
25
  interaction_list.add interaction
25
26
  logger.info "Registered expected interaction #{interaction.request.method_and_path}"
26
- logger.debug JSON.pretty_generate JSON.parse(interaction.to_json)
27
+ logger.debug JSON.pretty_generate JSON.parse(request_body)
27
28
  [200, {}, ['Added interaction']]
28
29
  end
29
30
  end
@@ -3,6 +3,7 @@ require 'pact/consumer/mock_service/rack_request_helper'
3
3
  require 'pact/consumer/mock_service/interaction_mismatch'
4
4
  require 'pact/consumer_contract'
5
5
  require 'pact/consumer/interactions_filter'
6
+ require 'pact/mock_service/response_decorator'
6
7
 
7
8
  module Pact
8
9
  module Consumer
@@ -37,7 +38,7 @@ module Pact
37
38
  def find_response request_hash
38
39
  actual_request = Request::Actual.from_hash(request_hash)
39
40
  logger.info "Received request #{actual_request.method_and_path}"
40
- logger.debug pretty_generate actual_request
41
+ logger.debug pretty_generate request_hash
41
42
  candidate_interactions = interaction_list.find_candidate_interactions actual_request
42
43
  matching_interactions = find_matching_interactions actual_request, from: candidate_interactions
43
44
 
@@ -61,7 +62,7 @@ module Pact
61
62
  add_verified_interaction interaction
62
63
  response = response_from(interaction.response)
63
64
  logger.info "Found matching response for #{interaction.request.method_and_path}"
64
- logger.debug pretty_generate(interaction.response)
65
+ logger.debug pretty_generate(Pact::MockService::ResponseDecorator.new(interaction.response))
65
66
  response
66
67
  end
67
68
 
@@ -76,7 +77,7 @@ module Pact
76
77
  def handle_more_than_one_matching_interaction actual_request, matching_interactions
77
78
  logger.error "Multiple interactions found for #{actual_request.method_and_path}:"
78
79
  matching_interactions.each do | interaction |
79
- logger.debug pretty_generate(interaction)
80
+ logger.debug pretty_generate(Pact::MockService::InteractionDecorator.new(interaction))
80
81
  end
81
82
  multiple_interactions_found_response actual_request, matching_interactions
82
83
  end
@@ -88,7 +89,7 @@ module Pact
88
89
  def request_summary_for interaction
89
90
  summary = {:description => interaction.description}
90
91
  summary[:provider_state] if interaction.provider_state
91
- summary[:request] = interaction.request
92
+ summary[:request] = Pact::MockService::RequestDecorator.new(interaction.request)
92
93
  summary
93
94
  end
94
95
 
@@ -1,5 +1,5 @@
1
1
  require 'net/http'
2
- require 'pact/consumer/mock_service_interaction_expectation'
2
+ require 'pact/mock_service/interaction_decorator'
3
3
 
4
4
  module Pact
5
5
  module Consumer
@@ -32,7 +32,11 @@ module Pact
32
32
  end
33
33
 
34
34
  def add_expected_interaction interaction
35
- response = http.request_post('/interactions', MockServiceInteractionExpectation.new(interaction).to_json, MOCK_SERVICE_ADMINISTRATON_HEADERS.merge("Content-Type" => "application/json"))
35
+ response = http.request_post(
36
+ '/interactions',
37
+ interaction_json(interaction),
38
+ MOCK_SERVICE_ADMINISTRATON_HEADERS.merge("Content-Type" => "application/json")
39
+ )
36
40
  raise "\e[31m#{response.body}\e[m" unless response.is_a? Net::HTTPSuccess
37
41
  end
38
42
 
@@ -60,6 +64,10 @@ module Pact
60
64
  end
61
65
  end
62
66
 
67
+ def interaction_json interaction
68
+ Pact::MockService::InteractionDecorator.new(interaction).to_json
69
+ end
70
+
63
71
  end
64
72
  end
65
73
  end
@@ -0,0 +1,33 @@
1
+ require 'pact/shared/active_support_support'
2
+ require 'pact/consumer_contract/interaction_decorator'
3
+
4
+ module Pact
5
+ class ConsumerContractDecorator
6
+
7
+ include ActiveSupportSupport
8
+
9
+ def initialize consumer_contract
10
+ @consumer_contract = consumer_contract
11
+ end
12
+
13
+ def as_json(options = {})
14
+ fix_all_the_things(
15
+ consumer: consumer_contract.consumer.as_json,
16
+ provider: consumer_contract.provider.as_json,
17
+ interactions: consumer_contract.interactions.collect{ |i| InteractionDecorator.new(i).as_json},
18
+ metadata: {
19
+ pactSpecificationVersion: "1.0.0"
20
+ }
21
+ )
22
+ end
23
+
24
+ def to_json(options = {})
25
+ as_json.to_json(options)
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :consumer_contract
31
+
32
+ end
33
+ end
@@ -1,12 +1,17 @@
1
1
  require 'pact/consumer_contract'
2
2
  require 'pact/consumer/interactions_filter'
3
3
  require 'pact/consumer_contract/file_name'
4
+ require 'pact/consumer_contract/pact_file'
5
+ require 'pact/consumer_contract/consumer_contract_decorator'
6
+ require 'pact/shared/active_support_support'
4
7
 
5
8
  module Pact
6
9
 
7
10
  class ConsumerContractWriter
8
11
 
9
- attr_reader :consumer_contract_details, :pactfile_write_mode, :interactions, :logger
12
+ include Pact::FileName
13
+ include Pact::PactFile
14
+ include ActiveSupportSupport
10
15
 
11
16
  def initialize consumer_contract_details, logger
12
17
  @logger = logger
@@ -23,13 +28,37 @@ module Pact
23
28
  end
24
29
 
25
30
  def write
26
- consumer_contract.update_pactfile
27
- consumer_contract.to_json
31
+ update_pactfile
32
+ pact_json
33
+ end
34
+
35
+ private
36
+
37
+ attr_reader :consumer_contract_details, :pactfile_write_mode, :interactions, :logger
38
+
39
+ def pactfile_path
40
+ raise 'You must specify a consumer and provider name' unless (consumer_name && provider_name)
41
+ file_path consumer_name, provider_name, Pact.configuration.pact_dir
42
+ end
43
+
44
+ def update_pactfile
45
+ logger.debug "Updating pact file for #{provider_name} at #{pactfile_path}"
46
+ File.open(pactfile_path, 'w') do |f|
47
+ f.write pact_json
48
+ end
49
+ end
50
+
51
+ def pact_json
52
+ @pact_json ||= fix_json_formatting(JSON.pretty_generate(decorated_pact))
53
+ end
54
+
55
+ def decorated_pact
56
+ @decorated_pact ||= Pact::ConsumerContractDecorator.new(consumer_contract)
28
57
  end
29
58
 
30
59
  def interactions_for_new_consumer_contract
31
60
  if pactfile_write_mode == :update
32
- merged_interactions = existing_interactions
61
+ merged_interactions = existing_interactions.dup
33
62
  filter = Consumer::UpdatableInteractionsFilter.new(merged_interactions)
34
63
  interactions.each {|i| filter << i }
35
64
  merged_interactions
@@ -62,10 +91,6 @@ module Pact
62
91
  File.exist?(pactfile_path)
63
92
  end
64
93
 
65
- def pactfile_path
66
- Pact::FileName.file_path consumer_contract_details[:consumer][:name], consumer_contract_details[:provider][:name]
67
- end
68
-
69
94
  def existing_consumer_contract
70
95
  Pact::ConsumerContract.from_uri(pactfile_path)
71
96
  end
@@ -79,6 +104,14 @@ module Pact
79
104
  $stdout.puts msg
80
105
  logger.info msg
81
106
  end
107
+
108
+ def consumer_name
109
+ consumer_contract_details[:consumer][:name]
110
+ end
111
+
112
+ def provider_name
113
+ consumer_contract_details[:provider][:name]
114
+ end
82
115
  end
83
116
 
84
117
  end
@@ -0,0 +1,43 @@
1
+ require 'pact/shared/active_support_support'
2
+ require 'pact/consumer_contract/request_decorator'
3
+ require 'pact/consumer_contract/response_decorator'
4
+
5
+ module Pact
6
+ class InteractionDecorator
7
+
8
+ include ActiveSupportSupport
9
+
10
+ def initialize interaction
11
+ @interaction = interaction
12
+ end
13
+
14
+ def as_json options = {}
15
+ fix_all_the_things to_hash
16
+ end
17
+
18
+ def to_json(options = {})
19
+ as_json.to_json(options)
20
+ end
21
+
22
+ def to_hash
23
+ hash = { :description => interaction.description }
24
+ hash[:provider_state] = interaction.provider_state if interaction.provider_state
25
+ hash[:request] = decorate_request.as_json
26
+ hash[:response] = decorate_response.as_json
27
+ hash
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :interaction
33
+
34
+ def decorate_request
35
+ RequestDecorator.new(interaction.request)
36
+ end
37
+
38
+ def decorate_response
39
+ ResponseDecorator.new(interaction.response)
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,69 @@
1
+ require 'pact/reification'
2
+
3
+ module Pact
4
+ class RequestDecorator
5
+
6
+ def initialize request
7
+ @request = request
8
+ end
9
+
10
+ def to_json(options = {})
11
+ as_json.to_json(options)
12
+ end
13
+
14
+ def as_json options = {}
15
+ to_hash
16
+ end
17
+
18
+ def to_hash
19
+ hash = {
20
+ method: request.method,
21
+ path: request.path,
22
+ }
23
+ hash[:query] = query if request.specified?(:query)
24
+ hash[:headers] = request.headers if request.specified?(:headers)
25
+ hash[:body] = body if request.specified?(:body)
26
+ hash
27
+ end
28
+
29
+ private
30
+
31
+ attr_reader :request
32
+
33
+ # This feels wrong to be checking the class type of the Query
34
+ # Do this better somehow.
35
+ def query
36
+ if request.query.is_a?(Pact::QueryHash)
37
+ Pact::Reification.from_term(request.query)
38
+ else
39
+ request.query
40
+ end
41
+ end
42
+
43
+ # This feels wrong to be checking the class type of the body
44
+ # Do this better somehow.
45
+ def body
46
+ if content_type_is_form && request.body.is_a?(Hash)
47
+ URI.encode_www_form convert_hash_body_to_array_of_arrays
48
+ else
49
+ request.body
50
+ end
51
+ end
52
+
53
+ def content_type_is_form
54
+ request.content_type? 'application/x-www-form-urlencoded'
55
+ end
56
+
57
+ #This probably belongs somewhere else.
58
+ def convert_hash_body_to_array_of_arrays
59
+ arrays = []
60
+ request.body.keys.each do | key |
61
+ [*request.body[key]].each do | value |
62
+ arrays << [key, Pact::Reification.from_term(value)]
63
+ end
64
+ end
65
+ arrays
66
+ end
67
+
68
+ end
69
+ end
@@ -0,0 +1,29 @@
1
+ module Pact
2
+ class ResponseDecorator
3
+
4
+ def initialize response
5
+ @response = response
6
+ end
7
+
8
+ def to_json(options = {})
9
+ as_json.to_json(options)
10
+ end
11
+
12
+ def as_json options = {}
13
+ to_hash
14
+ end
15
+
16
+ def to_hash
17
+ hash = {}
18
+ hash[:status] = response.status if response.specified?(:status)
19
+ hash[:headers] = response.headers if response.specified?(:headers)
20
+ hash[:body] = response.body if response.specified?(:body)
21
+ hash
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :response
27
+
28
+ end
29
+ end
@@ -0,0 +1,48 @@
1
+ require 'pact/shared/active_support_support'
2
+ require 'pact/mock_service/request_decorator'
3
+ require 'pact/mock_service/response_decorator'
4
+
5
+ # Represents the Interaction in the form required by the MockService
6
+ # The json generated will be posted to the MockService to register the expectation
7
+
8
+ module Pact
9
+ module MockService
10
+ class InteractionDecorator
11
+
12
+ include ActiveSupportSupport
13
+
14
+ def initialize interaction
15
+ @interaction = interaction
16
+ end
17
+
18
+ def as_json options = {}
19
+ fix_all_the_things to_hash
20
+ end
21
+
22
+ def to_json(options = {})
23
+ as_json.to_json(options)
24
+ end
25
+
26
+ def to_hash
27
+ hash = { :description => interaction.description }
28
+ hash[:provider_state] = interaction.provider_state if interaction.provider_state
29
+ hash[:request] = decorate_request.as_json
30
+ hash[:response] = decorate_response.as_json
31
+ hash
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader :interaction
37
+
38
+ def decorate_request
39
+ RequestDecorator.new(interaction.request)
40
+ end
41
+
42
+ def decorate_response
43
+ ResponseDecorator.new(interaction.response)
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,36 @@
1
+ module Pact
2
+ module MockService
3
+ class RequestDecorator
4
+
5
+ def initialize request
6
+ @request = request
7
+ end
8
+
9
+ def to_json(options = {})
10
+ as_json.to_json(options)
11
+ end
12
+
13
+ def as_json options = {}
14
+ to_hash
15
+ end
16
+
17
+ def to_hash
18
+ hash = {
19
+ method: request.method,
20
+ path: request.path,
21
+ }
22
+
23
+ hash[:query] = request.query if request.specified?(:query)
24
+ hash[:headers] = request.headers if request.specified?(:headers)
25
+ hash[:body] = request.body if request.specified?(:body)
26
+ hash[:options] = request.options if request.options.any?
27
+ hash
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :request
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,31 @@
1
+ module Pact
2
+ module MockService
3
+ class ResponseDecorator
4
+
5
+ def initialize response
6
+ @response = response
7
+ end
8
+
9
+ def to_json(options = {})
10
+ as_json.to_json(options)
11
+ end
12
+
13
+ def as_json options = {}
14
+ to_hash
15
+ end
16
+
17
+ def to_hash
18
+ hash = {}
19
+ hash[:status] = response.status if response.specified?(:status)
20
+ hash[:headers] = response.headers if response.specified?(:headers)
21
+ hash[:body] = response.body if response.specified?(:body)
22
+ hash
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :response
28
+
29
+ end
30
+ end
31
+ end
@@ -1,5 +1,5 @@
1
1
  module Pact
2
2
  module MockService
3
- VERSION = "0.0.1"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
@@ -27,9 +27,7 @@ Gem::Specification.new do |gem|
27
27
  gem.add_runtime_dependency 'webrick'
28
28
  gem.add_runtime_dependency 'term-ansicolor', '~> 1.0'
29
29
 
30
- unless ENV['X_PACT_DEVELOPMENT']
31
- gem.add_runtime_dependency 'pact-support', '~> 0.0.1'
32
- end
30
+ gem.add_runtime_dependency 'pact-support', '~> 0.1.1'
33
31
 
34
32
  gem.add_development_dependency 'rake', '~> 10.0.3'
35
33
  gem.add_development_dependency 'webmock', '~> 1.18.0'
@@ -11,7 +11,7 @@ module Pact
11
11
 
12
12
  describe "#add_expected_interaction" do
13
13
  let(:interaction) { InteractionFactory.create }
14
- let(:request_body) { MockServiceInteractionExpectation.new(interaction).to_json }
14
+ let(:request_body) { Pact::MockService::InteractionDecorator.new(interaction).to_json }
15
15
 
16
16
  context "when successful" do
17
17
  let!(:post_interaction) do
@@ -100,8 +100,8 @@ module Pact
100
100
  end
101
101
 
102
102
  describe "write" do
103
- it "writes the pact file" do
104
- expect_any_instance_of(ConsumerContract).to receive(:update_pactfile)
103
+ it "writes the pact file, this is a useless test" do
104
+ expect_any_instance_of(ConsumerContractWriter).to receive(:update_pactfile)
105
105
  consumer_contract_writer.write
106
106
  end
107
107
  end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+ require 'pact/consumer_contract/request_decorator'
3
+ require 'pact/consumer/request'
4
+
5
+ module Pact
6
+ describe RequestDecorator do
7
+
8
+ let(:options) { {some: 'opts'} }
9
+ let(:body) { {some: "bod"} }
10
+ let(:headers) { {some: "header"} }
11
+ let(:query) { "param=foo" }
12
+ let(:request_params) do
13
+ {
14
+ method: :get,
15
+ query: query,
16
+ headers: headers,
17
+ path: "/",
18
+ body: body
19
+ }
20
+ end
21
+
22
+ let(:request) { Pact::Request::Expected.from_hash(request_params) }
23
+
24
+ subject { RequestDecorator.new(request) }
25
+
26
+ describe "#to_json" do
27
+
28
+ let(:parsed_json) { JSON.parse subject.to_json, symbolize_names: true }
29
+
30
+ it "renders the keys in a meaningful order" do
31
+ expect(subject.to_json).to match(/method.*path.*query.*headers.*body/)
32
+ end
33
+
34
+ it "does not render the options" do
35
+ expect(subject.to_json).to_not include('options')
36
+ end
37
+
38
+ context "with a query hash containing a Pact::Term" do
39
+ let(:query) { { param: Pact::Term.new(generate: 'apple', matcher: /a/) } }
40
+
41
+ it "reifies the query for backwards compatibility with pact-specification 1.0.0" do
42
+ expect(parsed_json[:query]).to eq "param=apple"
43
+ end
44
+ end
45
+
46
+ context "with a Pact::Term query" do
47
+ let(:query) { Pact::Term.new(generate: 'param=apple', matcher: /param=a/) }
48
+
49
+ it "serialises the Pact::Term to Ruby specific JSON that is not compatible with pact-specification 1.0.0" do
50
+ expect(subject.to_json).to include "Pact::Term"
51
+ end
52
+ end
53
+
54
+ context "with a Content-Type of form and body specified as a hash with a Pact::Term" do
55
+ let(:headers) { { 'Content-Type' => 'application/x-www-form-urlencoded' } }
56
+ let(:body) { {"param" => Pact::Term.new(generate: 'apple', matcher: /a/ )} }
57
+
58
+ it "reifies the body for backwards compatibility with pact-specification 1.0.0" do
59
+ expect(parsed_json[:body]).to eq "param=apple"
60
+ end
61
+ end
62
+
63
+ context "with a Content-Type of form and body specified as a hash with an array value" do
64
+ let(:headers) { { 'Content-Type' => 'application/x-www-form-urlencoded' } }
65
+ let(:body) { {"param" => ['pear', Pact::Term.new(generate: 'apple', matcher: /a/ )] } }
66
+
67
+ it "reifies the body for backwards compatibility with pact-specification 1.0.0" do
68
+ expect(parsed_json[:body]).to eq "param=pear&param=apple"
69
+ end
70
+ end
71
+
72
+ context "with no Content-Type and a body specified as a Hash" do
73
+ it "renders the body as JSON" do
74
+ expect(parsed_json[:body]).to eq body
75
+ end
76
+ end
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,10 @@
1
+ require 'pact/consumer_contract/response_decorator'
2
+ require 'support/shared_examples_for_response_decorator'
3
+
4
+ module Pact
5
+ describe ResponseDecorator do
6
+
7
+ include_examples "request decorator to_json"
8
+
9
+ end
10
+ end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+ require 'pact/mock_service/interaction_decorator'
3
+
4
+ module Pact
5
+ module MockService
6
+ describe InteractionDecorator do
7
+
8
+ describe "#to_json" do
9
+
10
+ let(:request) do
11
+ {
12
+ method: 'post',
13
+ path: '/foo',
14
+ body: Term.new(generate: 'waffle', matcher: /ffl/),
15
+ headers: { 'Content-Type' => 'application/json' },
16
+ query: '',
17
+ }
18
+ end
19
+
20
+ let(:response) do
21
+ { body: { baz: /qux/, wiffle: Term.new(generate: 'wiffle', matcher: /iff/) } }
22
+ end
23
+
24
+ let(:interaction) do
25
+ Interaction.from_hash(
26
+ 'description' => 'description',
27
+ 'provider_state' => 'provider_state',
28
+ 'response' => response,
29
+ 'request' => request)
30
+ end
31
+
32
+ subject { InteractionDecorator.new(interaction) }
33
+
34
+ let(:parsed_result) do
35
+ JSON.load(subject.to_json)
36
+ end
37
+
38
+ it "contains the request" do
39
+ expect(parsed_result).to have_key('request')
40
+ end
41
+
42
+ it "contains the response" do
43
+ expect(parsed_result).to have_key('request')
44
+ end
45
+
46
+ it "contains the description" do
47
+ expect(parsed_result['description']).to eq 'description'
48
+ end
49
+
50
+ context "with a provider state" do
51
+ it "contains the provider_state" do
52
+ expect(parsed_result['provider_state']).to eq 'provider_state'
53
+ end
54
+ end
55
+
56
+ context "without a provider state" do
57
+
58
+ let(:interaction) do
59
+ Interaction.from_hash(
60
+ 'description' => 'description',
61
+ 'response' => response,
62
+ 'request' => request)
63
+ end
64
+
65
+ it "does not contain the provider_state" do
66
+ expect(parsed_result).to_not have_key 'provider_state'
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+ require 'pact/mock_service/request_decorator'
3
+ require 'pact/consumer_contract/request'
4
+
5
+
6
+ module Pact
7
+ module MockService
8
+ describe RequestDecorator do
9
+
10
+ let(:options) { {} }
11
+ let(:body) { {some: "bod"} }
12
+ let(:headers) { {some: "header"} }
13
+ let(:request_params) do
14
+ {
15
+ method: :get,
16
+ query: "param=foo",
17
+ headers: headers,
18
+ path: "/",
19
+ body: body
20
+ }
21
+ end
22
+
23
+ let(:request) { Pact::Request::Expected.from_hash(request_params) }
24
+
25
+ subject { RequestDecorator.new(request) }
26
+
27
+ describe "#to_json" do
28
+
29
+ let(:parsed_json) { JSON.parse subject.to_json, symbolize_names: true}
30
+
31
+ it "renders the keys in a meaningful order" do
32
+ expect(subject.to_json).to match(/method.*path.*query.*headers.*body/)
33
+ end
34
+
35
+ context "with a body specified as a Hash" do
36
+ it "serialises the body as a Hash" do
37
+ expect(parsed_json[:body]).to eq body
38
+ end
39
+ end
40
+
41
+ context "with a body specified as a Hash containing a Pact::Term" do
42
+ let(:body) { { some: Pact::Term.new(generate: 'apple', matcher: /a/) } }
43
+
44
+ it "serialises the Pact::Term to Ruby specific JSON that is not compatible with pact-specification 1.0.0" do
45
+ expect(subject.to_json).to include "Pact::Term"
46
+ end
47
+ end
48
+ end
49
+
50
+ describe "#as_json" do
51
+ context "without options" do
52
+ it "does not include the options key" do
53
+ expect(subject.as_json.key?(:options)).to be false
54
+ end
55
+ end
56
+
57
+ context "with options" do
58
+ let(:request_params) do
59
+ {
60
+ method: :get,
61
+ path: "/",
62
+ options: options
63
+ }
64
+ end
65
+
66
+ let(:options) { {:opts => 'blah'} }
67
+
68
+ it "includes the options in the request hash" do
69
+ expect(subject.as_json[:options]).to eq options
70
+ end
71
+ end
72
+ end
73
+
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,12 @@
1
+ require 'pact/mock_service/response_decorator'
2
+ require 'support/shared_examples_for_response_decorator'
3
+
4
+ module Pact
5
+ module MockService
6
+ describe ResponseDecorator do
7
+
8
+ include_examples "request decorator to_json"
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,25 @@
1
+ require 'pact/consumer_contract/response'
2
+
3
+ shared_examples_for "request decorator to_json" do
4
+
5
+ describe "#to_json" do
6
+
7
+ let(:response) { Pact::Response.new(status: 200, body: body) }
8
+ let(:body) { { baz: /qux/, wiffle: Pact::Term.new(generate: 'wiffle', matcher: /iff/) } }
9
+
10
+ let(:decorator) { described_class.new(response) }
11
+
12
+ subject { JSON.load decorator.to_json }
13
+
14
+ it "serialises regexes" do
15
+ expect(subject['body']['baz']).to eql /qux/
16
+ end
17
+
18
+ it "serialises terms" do
19
+ parsed_term = subject['body']['wiffle']
20
+ expect(parsed_term.matcher).to eql /iff/
21
+ expect(parsed_term.generate).to eql 'wiffle'
22
+ end
23
+
24
+ end
25
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pact-mock_service
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Fraser
@@ -12,34 +12,34 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2014-10-12 00:00:00.000000000 Z
15
+ date: 2014-10-22 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rack
19
19
  requirement: !ruby/object:Gem::Requirement
20
20
  requirements:
21
- - - ! '>='
21
+ - - '>='
22
22
  - !ruby/object:Gem::Version
23
23
  version: '0'
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
27
27
  requirements:
28
- - - ! '>='
28
+ - - '>='
29
29
  - !ruby/object:Gem::Version
30
30
  version: '0'
31
31
  - !ruby/object:Gem::Dependency
32
32
  name: rspec
33
33
  requirement: !ruby/object:Gem::Requirement
34
34
  requirements:
35
- - - ! '>='
35
+ - - '>='
36
36
  - !ruby/object:Gem::Version
37
37
  version: '2.14'
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  requirements:
42
- - - ! '>='
42
+ - - '>='
43
43
  - !ruby/object:Gem::Version
44
44
  version: '2.14'
45
45
  - !ruby/object:Gem::Dependency
@@ -88,42 +88,42 @@ dependencies:
88
88
  name: thor
89
89
  requirement: !ruby/object:Gem::Requirement
90
90
  requirements:
91
- - - ! '>='
91
+ - - '>='
92
92
  - !ruby/object:Gem::Version
93
93
  version: '0'
94
94
  type: :runtime
95
95
  prerelease: false
96
96
  version_requirements: !ruby/object:Gem::Requirement
97
97
  requirements:
98
- - - ! '>='
98
+ - - '>='
99
99
  - !ruby/object:Gem::Version
100
100
  version: '0'
101
101
  - !ruby/object:Gem::Dependency
102
102
  name: json
103
103
  requirement: !ruby/object:Gem::Requirement
104
104
  requirements:
105
- - - ! '>='
105
+ - - '>='
106
106
  - !ruby/object:Gem::Version
107
107
  version: '0'
108
108
  type: :runtime
109
109
  prerelease: false
110
110
  version_requirements: !ruby/object:Gem::Requirement
111
111
  requirements:
112
- - - ! '>='
112
+ - - '>='
113
113
  - !ruby/object:Gem::Version
114
114
  version: '0'
115
115
  - !ruby/object:Gem::Dependency
116
116
  name: webrick
117
117
  requirement: !ruby/object:Gem::Requirement
118
118
  requirements:
119
- - - ! '>='
119
+ - - '>='
120
120
  - !ruby/object:Gem::Version
121
121
  version: '0'
122
122
  type: :runtime
123
123
  prerelease: false
124
124
  version_requirements: !ruby/object:Gem::Requirement
125
125
  requirements:
126
- - - ! '>='
126
+ - - '>='
127
127
  - !ruby/object:Gem::Version
128
128
  version: '0'
129
129
  - !ruby/object:Gem::Dependency
@@ -140,6 +140,20 @@ dependencies:
140
140
  - - ~>
141
141
  - !ruby/object:Gem::Version
142
142
  version: '1.0'
143
+ - !ruby/object:Gem::Dependency
144
+ name: pact-support
145
+ requirement: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ~>
148
+ - !ruby/object:Gem::Version
149
+ version: 0.1.1
150
+ type: :runtime
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - ~>
155
+ - !ruby/object:Gem::Version
156
+ version: 0.1.1
143
157
  - !ruby/object:Gem::Dependency
144
158
  name: rake
145
159
  requirement: !ruby/object:Gem::Requirement
@@ -172,14 +186,14 @@ dependencies:
172
186
  name: pry
173
187
  requirement: !ruby/object:Gem::Requirement
174
188
  requirements:
175
- - - ! '>='
189
+ - - '>='
176
190
  - !ruby/object:Gem::Version
177
191
  version: '0'
178
192
  type: :development
179
193
  prerelease: false
180
194
  version_requirements: !ruby/object:Gem::Requirement
181
195
  requirements:
182
- - - ! '>='
196
+ - - '>='
183
197
  - !ruby/object:Gem::Version
184
198
  version: '0'
185
199
  - !ruby/object:Gem::Dependency
@@ -214,28 +228,28 @@ dependencies:
214
228
  name: activesupport
215
229
  requirement: !ruby/object:Gem::Requirement
216
230
  requirements:
217
- - - ! '>='
231
+ - - '>='
218
232
  - !ruby/object:Gem::Version
219
233
  version: '0'
220
234
  type: :development
221
235
  prerelease: false
222
236
  version_requirements: !ruby/object:Gem::Requirement
223
237
  requirements:
224
- - - ! '>='
238
+ - - '>='
225
239
  - !ruby/object:Gem::Version
226
240
  version: '0'
227
241
  - !ruby/object:Gem::Dependency
228
242
  name: faraday
229
243
  requirement: !ruby/object:Gem::Requirement
230
244
  requirements:
231
- - - ! '>='
245
+ - - '>='
232
246
  - !ruby/object:Gem::Version
233
247
  version: '0'
234
248
  type: :development
235
249
  prerelease: false
236
250
  version_requirements: !ruby/object:Gem::Requirement
237
251
  requirements:
238
- - - ! '>='
252
+ - - '>='
239
253
  - !ruby/object:Gem::Version
240
254
  version: '0'
241
255
  description:
@@ -255,7 +269,6 @@ files:
255
269
  - .travis.yml
256
270
  - CHANGELOG.md
257
271
  - Gemfile
258
- - Gemfile.lock
259
272
  - LICENSE.txt
260
273
  - README.md
261
274
  - Rakefile
@@ -276,12 +289,17 @@ files:
276
289
  - lib/pact/consumer/mock_service/rack_request_helper.rb
277
290
  - lib/pact/consumer/mock_service/verification_get.rb
278
291
  - lib/pact/consumer/mock_service_client.rb
279
- - lib/pact/consumer/mock_service_interaction_expectation.rb
280
- - lib/pact/consumer/request.rb
281
292
  - lib/pact/consumer/server.rb
293
+ - lib/pact/consumer_contract/consumer_contract_decorator.rb
282
294
  - lib/pact/consumer_contract/consumer_contract_writer.rb
295
+ - lib/pact/consumer_contract/interaction_decorator.rb
296
+ - lib/pact/consumer_contract/request_decorator.rb
297
+ - lib/pact/consumer_contract/response_decorator.rb
283
298
  - lib/pact/mock_service.rb
284
299
  - lib/pact/mock_service/cli.rb
300
+ - lib/pact/mock_service/interaction_decorator.rb
301
+ - lib/pact/mock_service/request_decorator.rb
302
+ - lib/pact/mock_service/response_decorator.rb
285
303
  - lib/pact/mock_service/version.rb
286
304
  - pact-mock-service.gemspec
287
305
  - spec/lib/pact/consumer/app_manager_spec.rb
@@ -292,9 +310,13 @@ files:
292
310
  - spec/lib/pact/consumer/mock_service/rack_request_helper_spec.rb
293
311
  - spec/lib/pact/consumer/mock_service/verification_get_spec.rb
294
312
  - spec/lib/pact/consumer/mock_service_client_spec.rb
295
- - spec/lib/pact/consumer/mock_service_interaction_expectation_spec.rb
296
313
  - spec/lib/pact/consumer/service_consumer_spec.rb
297
314
  - spec/lib/pact/consumer_contract/consumer_contract_writer_spec.rb
315
+ - spec/lib/pact/consumer_contract/request_decorator_spec.rb
316
+ - spec/lib/pact/consumer_contract/response_decorator_spec.rb
317
+ - spec/lib/pact/mock_service/interaction_decorator_spec.rb
318
+ - spec/lib/pact/mock_service/request_decorator_spec.rb
319
+ - spec/lib/pact/mock_service/response_decorator_spec.rb
298
320
  - spec/spec_helper.rb
299
321
  - spec/support/a_consumer-a_producer.json
300
322
  - spec/support/a_consumer-a_provider.json
@@ -315,6 +337,7 @@ files:
315
337
  - spec/support/options_app.rb
316
338
  - spec/support/pact_helper.rb
317
339
  - spec/support/shared_examples_for_request.rb
340
+ - spec/support/shared_examples_for_response_decorator.rb
318
341
  - spec/support/spec_support.rb
319
342
  - spec/support/stubbing.json
320
343
  - spec/support/stubbing_using_allow.rb
@@ -333,17 +356,17 @@ require_paths:
333
356
  - lib
334
357
  required_ruby_version: !ruby/object:Gem::Requirement
335
358
  requirements:
336
- - - ! '>='
359
+ - - '>='
337
360
  - !ruby/object:Gem::Version
338
361
  version: '0'
339
362
  required_rubygems_version: !ruby/object:Gem::Requirement
340
363
  requirements:
341
- - - ! '>='
364
+ - - '>='
342
365
  - !ruby/object:Gem::Version
343
366
  version: '0'
344
367
  requirements: []
345
368
  rubyforge_project:
346
- rubygems_version: 2.1.11
369
+ rubygems_version: 2.0.14
347
370
  signing_key:
348
371
  specification_version: 4
349
372
  summary: Provides a mock service for use with Pact
@@ -356,9 +379,13 @@ test_files:
356
379
  - spec/lib/pact/consumer/mock_service/rack_request_helper_spec.rb
357
380
  - spec/lib/pact/consumer/mock_service/verification_get_spec.rb
358
381
  - spec/lib/pact/consumer/mock_service_client_spec.rb
359
- - spec/lib/pact/consumer/mock_service_interaction_expectation_spec.rb
360
382
  - spec/lib/pact/consumer/service_consumer_spec.rb
361
383
  - spec/lib/pact/consumer_contract/consumer_contract_writer_spec.rb
384
+ - spec/lib/pact/consumer_contract/request_decorator_spec.rb
385
+ - spec/lib/pact/consumer_contract/response_decorator_spec.rb
386
+ - spec/lib/pact/mock_service/interaction_decorator_spec.rb
387
+ - spec/lib/pact/mock_service/request_decorator_spec.rb
388
+ - spec/lib/pact/mock_service/response_decorator_spec.rb
362
389
  - spec/spec_helper.rb
363
390
  - spec/support/a_consumer-a_producer.json
364
391
  - spec/support/a_consumer-a_provider.json
@@ -379,6 +406,7 @@ test_files:
379
406
  - spec/support/options_app.rb
380
407
  - spec/support/pact_helper.rb
381
408
  - spec/support/shared_examples_for_request.rb
409
+ - spec/support/shared_examples_for_response_decorator.rb
382
410
  - spec/support/spec_support.rb
383
411
  - spec/support/stubbing.json
384
412
  - spec/support/stubbing_using_allow.rb
data/Gemfile.lock DELETED
@@ -1,100 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- pact-mock_service (0.0.1)
5
- awesome_print (~> 1.1)
6
- find_a_port (~> 1.0.1)
7
- json
8
- rack
9
- rack-test (~> 0.6.2)
10
- rspec (>= 2.14)
11
- term-ansicolor (~> 1.0)
12
- thor
13
- webrick
14
-
15
- PATH
16
- remote: ../pact-support
17
- specs:
18
- pact-support (0.0.1)
19
- awesome_print (~> 1.1)
20
- find_a_port (~> 1.0.1)
21
- json
22
- rack-test (~> 0.6.2)
23
- randexp (~> 0.1.7)
24
- rspec (>= 2.14)
25
- term-ansicolor (~> 1.0)
26
- thor
27
-
28
- GEM
29
- remote: https://rubygems.org/
30
- specs:
31
- activesupport (4.1.1)
32
- i18n (~> 0.6, >= 0.6.9)
33
- json (~> 1.7, >= 1.7.7)
34
- minitest (~> 5.1)
35
- thread_safe (~> 0.1)
36
- tzinfo (~> 1.1)
37
- addressable (2.3.6)
38
- awesome_print (1.2.0)
39
- coderay (1.1.0)
40
- crack (0.4.2)
41
- safe_yaml (~> 1.0.0)
42
- diff-lcs (1.2.5)
43
- fakefs (0.5.2)
44
- faraday (0.9.0)
45
- multipart-post (>= 1.2, < 3)
46
- find_a_port (1.0.1)
47
- hashie (2.1.1)
48
- i18n (0.6.9)
49
- json (1.8.1)
50
- method_source (0.8.2)
51
- minitest (5.3.4)
52
- multipart-post (2.0.0)
53
- pry (0.10.0)
54
- coderay (~> 1.1.0)
55
- method_source (~> 0.8.1)
56
- slop (~> 3.4)
57
- rack (1.5.2)
58
- rack-test (0.6.2)
59
- rack (>= 1.0)
60
- rake (10.0.4)
61
- randexp (0.1.7)
62
- rspec (3.1.0)
63
- rspec-core (~> 3.1.0)
64
- rspec-expectations (~> 3.1.0)
65
- rspec-mocks (~> 3.1.0)
66
- rspec-core (3.1.6)
67
- rspec-support (~> 3.1.0)
68
- rspec-expectations (3.1.2)
69
- diff-lcs (>= 1.2.0, < 2.0)
70
- rspec-support (~> 3.1.0)
71
- rspec-mocks (3.1.3)
72
- rspec-support (~> 3.1.0)
73
- rspec-support (3.1.2)
74
- safe_yaml (1.0.3)
75
- slop (3.5.0)
76
- term-ansicolor (1.3.0)
77
- tins (~> 1.0)
78
- thor (0.19.1)
79
- thread_safe (0.3.4)
80
- tins (1.3.3)
81
- tzinfo (1.2.1)
82
- thread_safe (~> 0.1)
83
- webmock (1.18.0)
84
- addressable (>= 2.3.6)
85
- crack (>= 0.3.2)
86
- webrick (1.3.1)
87
-
88
- PLATFORMS
89
- ruby
90
-
91
- DEPENDENCIES
92
- activesupport
93
- fakefs (~> 0.4)
94
- faraday
95
- hashie (~> 2.0)
96
- pact-mock_service!
97
- pact-support!
98
- pry
99
- rake (~> 10.0.3)
100
- webmock (~> 1.18.0)
@@ -1,37 +0,0 @@
1
- require 'pact/reification'
2
-
3
- # Represents the Interaction in the form required by the MockService
4
- # The json generated will be posted to the MockService to register the expectation
5
- module Pact
6
- module Consumer
7
- class MockServiceInteractionExpectation
8
-
9
-
10
- def initialize interaction
11
- @interaction = interaction
12
- end
13
-
14
- def to_hash
15
- hash = {:description => interaction.description}
16
- hash[:provider_state] = interaction.provider_state if interaction.provider_state
17
- options = interaction.request.options.empty? ? {} : { options: interaction.request.options}
18
- hash[:request] = interaction.request.as_json.merge(options)
19
- hash[:response] = interaction.response
20
- hash
21
- end
22
-
23
- def as_json options = {}
24
- to_hash
25
- end
26
-
27
- def to_json opts = {}
28
- as_json.to_json(opts)
29
- end
30
-
31
- private
32
-
33
- attr_reader :interaction
34
-
35
- end
36
- end
37
- end
@@ -1,27 +0,0 @@
1
- require 'pact/shared/request'
2
- require 'pact/shared/key_not_found'
3
-
4
- module Pact
5
- module Consumer
6
- module Request
7
- class Actual < Pact::Request::Base
8
-
9
- def self.from_hash(hash)
10
- sym_hash = symbolize_keys hash
11
- method = sym_hash.fetch(:method)
12
- path = sym_hash.fetch(:path)
13
- query = sym_hash.fetch(:query)
14
- headers = sym_hash.fetch(:headers)
15
- body = sym_hash.fetch(:body, nil)
16
- new(method, path, headers, body, query)
17
- end
18
-
19
- protected
20
-
21
- def self.key_not_found
22
- nil
23
- end
24
- end
25
- end
26
- end
27
- end
@@ -1,54 +0,0 @@
1
- require 'spec_helper'
2
- require 'pact/consumer/mock_service_interaction_expectation'
3
-
4
- describe Pact::Consumer::MockServiceInteractionExpectation do
5
- describe "as_json" do
6
-
7
- let(:options ) { {} }
8
- let(:request_as_json) { {a: 'request'} }
9
- let(:request) { instance_double('Pact::Request::Expected', :as_json => request_as_json, :options => options)}
10
- let(:response) { double('response') }
11
- let(:generated_response ) { double('generated_response', :to_json => 'generated_response') }
12
- let(:interaction) { instance_double('Pact::Interaction', :description => 'description', :request => request, :response => response, :provider_state => 'some state') }
13
- subject { described_class.new(interaction)}
14
- let(:expected_hash) { {:response => generated_response, :request => as_json_with_options, :description => '' } }
15
-
16
- before do
17
- allow(Pact::Reification).to receive(:from_term).with(response).and_return(generated_response)
18
- end
19
-
20
- it "includes the response" do
21
- expect(subject.as_json[:response]).to eq response
22
- end
23
-
24
- it "includes the options in the request" do
25
- expect(subject.as_json[:request]).to eq request_as_json
26
- end
27
-
28
- it "includes the provider state" do
29
- expect(subject.as_json[:provider_state]).to eq 'some state'
30
- end
31
-
32
- it "includes the description" do
33
- expect(subject.as_json[:description]).to eq 'description'
34
- end
35
-
36
- it "doesn't have any other keys" do
37
- expect(subject.as_json.keys).to eq [:description, :provider_state, :request, :response]
38
- end
39
-
40
- context "without options" do
41
- it "does not include the options key" do
42
- expect(subject.as_json.key?(:options)).to be false
43
- end
44
- end
45
-
46
- context "with options" do
47
- let(:options) { {:opts => 'blah'} }
48
- it "includes the options in the request hash" do
49
- expect(subject.as_json[:request][:options]).to eq options
50
- end
51
- end
52
- end
53
-
54
- end