pinch_hitter 0.5.5 → 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
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