pinch_hitter 0.5.5 → 0.5.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 351d287c33f0a63055aa89e9e33dcc0cd5bf8843
4
- data.tar.gz: 7373585ec0c9cc3c70767d2bdfae3d9c66b91df8
3
+ metadata.gz: 61b0f448b1236a0470c64ffdd3015e536db68cf9
4
+ data.tar.gz: a451b062d54056d41397a2d187d260bf7ec00162
5
5
  SHA512:
6
- metadata.gz: 4e52306f9da1c7daaccdcb18cfe84444902dd5820e1f5f09cb921e89a39436057795a08b7206e8015ae1610bbf05ba8f79debe1750dfed54a2d0d83d1b7a462c
7
- data.tar.gz: 47d3972f594e178de665e4b021943b326e33d1bad41e921ccba42495b6adaeaccdbf5c6ef86e3c025b875c748d882178b8997b82fc1539fdbda47adfbea3a5a6
6
+ metadata.gz: b266a49251d14f0adb19d9103f9a750eaec21073f32986723d8687aeb8f331d63fb91b61e6dd4baf559d7f16ce3ab088fa13cc3ef7d79bb00a86fb44d9e459aa
7
+ data.tar.gz: 664117aff93c40d35fd9b09b1cf5257d35c5050c70869c70ae6df49ef64b9c7f7f96a01653f7b52176d41f7b46bb28e189f2e3b01d821e1901c267c193b5314b
data/.travis.yml CHANGED
@@ -4,3 +4,5 @@ rvm:
4
4
  - 2.0.0
5
5
  - 2.1.5
6
6
  - 2.2.2
7
+ before_install:
8
+ - gem update bundler
data/Changelog CHANGED
@@ -32,3 +32,8 @@ test logs.
32
32
 
33
33
  === Release 0.5.5 / 2015-11-5
34
34
  * Allow Cross-Origin requests
35
+
36
+ === Release 0.5.6 / 2016-03-19
37
+ * Add ability to disable cache control (useful for IE testing)
38
+ * Allow client to register a module that will hydrate the response object.
39
+ * Break apart recording and responding to better support full response payloads
@@ -0,0 +1,10 @@
1
+ Feature: Response headers
2
+ I want to put headers on my responses
3
+ As a tester trying to test the application
4
+ So that my application works with something close to my production server
5
+
6
+ Scenario: Disable caching
7
+ Given I setup my replay service with no-cache
8
+ When I make a request
9
+ Then my response has a no-cache,no-store Cache-Control header
10
+
@@ -0,0 +1,13 @@
1
+ Given(/^I setup my replay service with no\-cache$/) do
2
+ mock.reset
3
+ mock.no_cache
4
+ end
5
+
6
+ When(/^I make a request$/) do
7
+ mock.prime '/car_rental', :car_rental
8
+ @response = app.post '/car_rental', '{"reservation": "yes"}'
9
+ end
10
+
11
+ Then(/^my response has a no\-cache,no\-store Cache\-Control header$/) do
12
+ @response.header['Cache-Control'].should == 'no-cache, no-store'
13
+ end
@@ -0,0 +1,4 @@
1
+ class NilClass
2
+ def squish
3
+ end
4
+ end
@@ -1,7 +1,6 @@
1
1
  require 'pinch_hitter/message/xml'
2
2
  require 'pinch_hitter/message/json'
3
3
  require 'pinch_hitter/message/content_type'
4
- require 'pinch_hitter/core_ext/string'
5
4
 
6
5
  module PinchHitter::Message
7
6
  class MessageStore
@@ -1,5 +1,6 @@
1
+ require 'pinch_hitter/core_ext/string'
2
+ require 'pinch_hitter/core_ext/nil_class'
1
3
  require_relative 'message_queue'
2
- require_relative 'endpoint_recorder'
3
4
 
4
5
  module PinchHitter::Service
5
6
  class EndpointHandlers
@@ -7,21 +8,22 @@ module PinchHitter::Service
7
8
  @handlers ||= {}
8
9
  end
9
10
 
10
- def store_message(endpoint, body)
11
- handler_for(endpoint).store body.squish
11
+ def store_message(endpoint, message)
12
+ handler = handler_for(endpoint)
13
+ handler.store(message.squish) if handler.respond_to? :store
12
14
  end
13
15
 
14
- def respond_to(endpoint='/', request=nil)
15
- message = handler_for(endpoint).respond_to(request)
16
- message.squish if message
17
- end
18
-
19
- def requests(endpoint)
20
- handler_for(endpoint).requests
16
+ def respond_to(endpoint='/', body=nil, request=nil, response = nil)
17
+ handler = handler_for(endpoint)
18
+ if handler.respond_to?(:handle_request)
19
+ handler.handle_request(request, response)
20
+ else
21
+ handler.respond_to(body).squish
22
+ end
21
23
  end
22
24
 
23
25
  def handler_for(endpoint='/')
24
- handlers[normalize(endpoint)] || store_handler(endpoint)
26
+ handlers[endpoint] || store_handler(endpoint)
25
27
  end
26
28
 
27
29
  def register_module(endpoint, mod)
@@ -31,16 +33,13 @@ module PinchHitter::Service
31
33
  end
32
34
 
33
35
  def store_handler(endpoint, handler=MessageQueue.new)
34
- handlers[normalize(endpoint)] = EndpointRecorder.new handler
35
- end
36
-
37
- def normalize(endpoint)
38
- return endpoint if endpoint =~ /^\//
39
- "/#{endpoint}"
36
+ handlers[endpoint] = handler
40
37
  end
41
38
 
42
39
  def reset
43
- handlers.values.each(&:reset)
40
+ handlers.values.each do |handler|
41
+ handler.reset if handler.respond_to? :reset
42
+ end
44
43
  end
45
44
  end
46
45
  end
@@ -0,0 +1,23 @@
1
+ module PinchHitter::Service
2
+ class EndpointRecorders
3
+ def recorders
4
+ @recorders ||= {}
5
+ end
6
+
7
+ def record(endpoint, request)
8
+ recorder_for(endpoint) << request
9
+ end
10
+
11
+ def requests(endpoint)
12
+ recorder_for(endpoint)
13
+ end
14
+
15
+ def recorder_for(endpoint='/')
16
+ recorders[endpoint] ||= []
17
+ end
18
+
19
+ def reset
20
+ recorders.clear
21
+ end
22
+ end
23
+ end
@@ -1,5 +1,9 @@
1
1
  module PinchHitter::Service
2
2
  class MessageQueue < Array
3
+ def store(msg)
4
+ push msg
5
+ end
6
+
3
7
  def respond_to(msg=nil)
4
8
  shift
5
9
  end
@@ -5,6 +5,7 @@ require 'nokogiri'
5
5
  require 'json'
6
6
 
7
7
  require 'pinch_hitter/service/endpoint_handlers'
8
+ require 'pinch_hitter/service/endpoint_recorders'
8
9
  require 'pinch_hitter/message/content_type'
9
10
 
10
11
  module PinchHitter::Service
@@ -16,13 +17,21 @@ module PinchHitter::Service
16
17
  configure do
17
18
  enable :cross_origin
18
19
  @@handlers = EndpointHandlers.new
20
+ @@recorder = EndpointRecorders.new
19
21
  #SOAP expects a mime_type of text/xml
20
22
  mime_type :xml, "text/xml"
21
23
  mime_type :json, "application/json"
24
+ disable :no_cache
25
+ end
26
+
27
+
28
+ before do
29
+ cache_control :no_cache, :no_store if settings.no_cache
22
30
  end
23
31
 
24
32
  post '/reset' do
25
33
  @@handlers.reset
34
+ @@recorder.reset
26
35
  status 200
27
36
  end
28
37
 
@@ -70,32 +79,48 @@ module PinchHitter::Service
70
79
  end
71
80
 
72
81
  def store(endpoint='/', message=nil)
82
+ endpoint = normalize(endpoint)
73
83
  @@handlers.store_message endpoint, message
74
84
  end
75
85
 
76
86
  def respond(endpoint='/', request=nil)
77
- message = @@handlers.respond_to endpoint, wrap(request)
78
- content_type determine_content_type message
79
- puts "No message found for #{endpoint}" unless message
87
+ endpoint = normalize(endpoint)
88
+ body, request = wrap(request)
89
+ @@recorder.record(endpoint, request)
90
+ message = @@handlers.respond_to(endpoint, body, request, response)
91
+ if message.is_a? String
92
+ content_type determine_content_type message
93
+ puts "No message found for #{endpoint}" unless message
94
+ end
80
95
  message
81
96
  end
82
97
 
83
98
  def register_module(endpoint='/', mod='')
99
+ endpoint = normalize(endpoint)
84
100
  @@handlers.register_module endpoint, Marshal.load(mod)
85
101
  end
86
102
 
87
103
  def requests endpoint
104
+ endpoint = normalize(endpoint)
88
105
  content_type 'application/json'
89
- { requests: @@handlers.requests(endpoint) }.to_json
106
+ { requests: @@recorder.requests(endpoint) }.to_json
90
107
  end
91
108
 
92
- def wrap request
93
- return nil unless request
94
- { headers: request_headers, body: request.body.read }
109
+ def wrap(request)
110
+ return [nil, nil] unless request
111
+
112
+ body = request.body.read
113
+ [body, { headers: request_headers, body: body }]
95
114
  end
96
115
 
97
116
  def request_headers
98
117
  env.select { |key, value| key.upcase == key }
99
118
  end
119
+
120
+ def normalize(endpoint)
121
+ return endpoint if endpoint =~ /^\//
122
+ "/#{endpoint}"
123
+ end
124
+
100
125
  end
101
126
  end
@@ -8,9 +8,15 @@ module PinchHitter::Service::Runner
8
8
  @silent_console = true
9
9
  end
10
10
 
11
+ def no_cache
12
+ @no_cache = true
13
+ @app.settings.enable :no_cache if @app
14
+ end
15
+
11
16
  def start_service(host, port, timeout=10)
12
17
  Thread.abort_on_exception = true
13
18
  @app = PinchHitter::Service::ReplayWs.new
19
+ @app.settings.enable :no_cache if @no_cache
14
20
  @replay_service = Thread.new do
15
21
  Rack::Handler::WEBrick.run @app, service_options(host, port)
16
22
  end
@@ -1,3 +1,3 @@
1
1
  module PinchHitter
2
- VERSION = "0.5.5"
2
+ VERSION = "0.5.6"
3
3
  end
@@ -40,13 +40,12 @@ class TestEndpointHandlers < MiniTest::Test
40
40
  assert_equal "THIS IS A TEST", @handlers.respond_to('endpoint')
41
41
  end
42
42
 
43
- def test_requests
44
- request = { body: '{"Hot Rod" : "Williams"}' }
45
- @handlers.respond_to('endpoint', request)
46
- assert_equal [request], @handlers.requests('endpoint')
43
+ def test_full_request_module_with_marshalling
44
+ mod = Marshal.dump(RequestHandlerTest)
45
+ @handlers.register_module('endpoint', Marshal.load(mod))
46
+ assert_equal "HANDLING REQUESTS", @handlers.respond_to('endpoint')
47
47
  end
48
48
 
49
-
50
49
  module TestModule
51
50
  def respond_to(msg)
52
51
  test_message
@@ -55,4 +54,10 @@ class TestEndpointHandlers < MiniTest::Test
55
54
  "THIS IS A TEST"
56
55
  end
57
56
  end
57
+
58
+ module RequestHandlerTest
59
+ def handle_request(request, response)
60
+ "HANDLING REQUESTS"
61
+ end
62
+ end
58
63
  end
@@ -0,0 +1,16 @@
1
+
2
+ ENV['RACK_ENV'] = 'test'
3
+
4
+ require 'minitest/autorun'
5
+
6
+ class TestEndpointRecorders < MiniTest::Test
7
+ def setup
8
+ @recorders = PinchHitter::Service::EndpointRecorders.new
9
+ end
10
+
11
+ def test_requests
12
+ request = { body: '{"Hot Rod" : "Williams"}' }
13
+ @recorders.record('endpoint', request)
14
+ assert_equal [request], @recorders.requests('endpoint')
15
+ end
16
+ end
data/test/test_service.rb CHANGED
@@ -131,4 +131,39 @@ class TestService < MiniTest::Test
131
131
  assert_equal user_post, response.first['body']
132
132
  assert response.first['headers']
133
133
  end
134
+
135
+ def test_cache_control_defaults_to_nil
136
+ post "/store", xml_message
137
+ post "/respond", ''
138
+
139
+ assert_nil last_response['Cache-Control']
140
+ end
141
+
142
+ def test_cache_control
143
+ app.enable :no_cache
144
+ post "/store", xml_message
145
+ post "/respond", ''
146
+
147
+ assert_equal 'no-cache, no-store', last_response['Cache-Control']
148
+ app.disable :no_cache
149
+ end
150
+
151
+ def test_request_handler
152
+ post '/register_module?endpoint=stuff', Marshal.dump(TestRequestHandler)
153
+ post '/stuff', ''
154
+
155
+ assert_received xml_message
156
+ assert_equal 202, last_response.status
157
+ assert(last_response.headers.include? "Kyrie")
158
+ end
159
+
160
+ module TestRequestHandler
161
+ include MessageAssertions
162
+ def handle_request(request, response)
163
+ response.status = 202
164
+ response["Kyrie"] = "Irving"
165
+ response.body = xml_message.squish
166
+ response
167
+ end
168
+ end
134
169
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pinch_hitter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.5
4
+ version: 0.5.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Jackson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-05 00:00:00.000000000 Z
11
+ date: 2016-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra
@@ -158,20 +158,23 @@ files:
158
158
  - features/messages/car_rental.xml
159
159
  - features/messages/glossary.json
160
160
  - features/replay.feature
161
+ - features/response_headers.feature
161
162
  - features/step_definitions/replay_steps.rb
163
+ - features/step_definitions/response_steps.rb
162
164
  - features/step_definitions/verify_requests_steps.rb
163
165
  - features/support/env.rb
164
166
  - features/support/mock_web_service.rb
165
167
  - features/support/xml_parser.rb
166
168
  - features/verify.feature
167
169
  - lib/pinch_hitter.rb
170
+ - lib/pinch_hitter/core_ext/nil_class.rb
168
171
  - lib/pinch_hitter/core_ext/string.rb
169
172
  - lib/pinch_hitter/message/content_type.rb
170
173
  - lib/pinch_hitter/message/json.rb
171
174
  - lib/pinch_hitter/message/message_store.rb
172
175
  - lib/pinch_hitter/message/xml.rb
173
176
  - lib/pinch_hitter/service/endpoint_handlers.rb
174
- - lib/pinch_hitter/service/endpoint_recorder.rb
177
+ - lib/pinch_hitter/service/endpoint_recorders.rb
175
178
  - lib/pinch_hitter/service/message_queue.rb
176
179
  - lib/pinch_hitter/service/replay_ws.rb
177
180
  - lib/pinch_hitter/service/runner.rb
@@ -179,7 +182,7 @@ files:
179
182
  - pinch_hitter.gemspec
180
183
  - test/message_assertions.rb
181
184
  - test/test_endpoint_handlers.rb
182
- - test/test_endpoint_recorder.rb
185
+ - test/test_endpoint_recorders.rb
183
186
  - test/test_json_message.rb
184
187
  - test/test_message.rb
185
188
  - test/test_pinch_hitter.rb
@@ -213,7 +216,9 @@ test_files:
213
216
  - features/messages/car_rental.xml
214
217
  - features/messages/glossary.json
215
218
  - features/replay.feature
219
+ - features/response_headers.feature
216
220
  - features/step_definitions/replay_steps.rb
221
+ - features/step_definitions/response_steps.rb
217
222
  - features/step_definitions/verify_requests_steps.rb
218
223
  - features/support/env.rb
219
224
  - features/support/mock_web_service.rb
@@ -221,7 +226,7 @@ test_files:
221
226
  - features/verify.feature
222
227
  - test/message_assertions.rb
223
228
  - test/test_endpoint_handlers.rb
224
- - test/test_endpoint_recorder.rb
229
+ - test/test_endpoint_recorders.rb
225
230
  - test/test_json_message.rb
226
231
  - test/test_message.rb
227
232
  - test/test_pinch_hitter.rb
@@ -1,28 +0,0 @@
1
- module PinchHitter::Service
2
- class EndpointRecorder
3
- attr_reader :handler
4
-
5
- def initialize(handler)
6
- @handler = handler
7
- end
8
-
9
- def store message
10
- handler << message if handler.respond_to? :<<
11
- end
12
-
13
- def respond_to(request)
14
- requests << request if request
15
- message = request[:body] if request
16
- handler.respond_to message
17
- end
18
-
19
- def requests
20
- @requests ||= []
21
- end
22
-
23
- def reset
24
- requests.clear
25
- handler.reset if handler.respond_to? :reset
26
- end
27
- end
28
- end
@@ -1,43 +0,0 @@
1
- ENV['RACK_ENV'] = 'test'
2
-
3
- require 'minitest/autorun'
4
-
5
- class TestEndpointRecorder < MiniTest::Test
6
-
7
- def setup
8
- @mock = MiniTest::Mock.new
9
- @recorder = PinchHitter::Service::EndpointRecorder.new @mock
10
- end
11
-
12
- def test_is_facade_for_handler
13
- @mock.expect(:<<, nil, ['blah'])
14
- @recorder.store 'blah'
15
- @mock.verify
16
- end
17
-
18
- def test_is_facade_reset
19
- @mock.expect(:reset, nil)
20
- @recorder.reset
21
- @mock.verify
22
- end
23
-
24
- def test_stores_request_if_present
25
- @mock.expect(:respond_to, '', [String])
26
- @recorder.respond_to({ body: 'request' })
27
- assert_equal [{body: 'request'}], @recorder.requests
28
- end
29
-
30
- def test_passes_body_to_handler_if_present
31
- @mock.expect(:respond_to, '', ['request'])
32
- @recorder.respond_to({ body: 'request' })
33
- @mock.verify
34
- end
35
-
36
- def reset_clears_stored_requests
37
- @mock.expect(:respond_to, '', [String])
38
- @mock.expect(:reset, nil)
39
- @recorder.respond_to({ body: 'request' })
40
- @recorder.reset
41
- assert_empty @recorder.requests
42
- end
43
- end