pinch_hitter 0.3 → 0.4
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 +7 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +2 -1
- data/Changelog +4 -0
- data/Rakefile +5 -1
- data/cucumber.yml +2 -1
- data/features/messages/cancelled_reservation.xml +77 -0
- data/features/{test_replay.feature → replay.feature} +5 -0
- data/features/step_definitions/{test_replay_steps.rb → replay_steps.rb} +13 -1
- data/features/step_definitions/verify_requests_steps.rb +28 -0
- data/features/support/env.rb +1 -1
- data/features/verify.feature +40 -0
- data/lib/pinch_hitter/message/message_store.rb +5 -1
- data/lib/pinch_hitter/service/endpoint_handlers.rb +10 -9
- data/lib/pinch_hitter/service/endpoint_recorder.rb +28 -0
- data/lib/pinch_hitter/service/replay_ws.rb +32 -3
- data/lib/pinch_hitter/version.rb +1 -1
- data/lib/pinch_hitter.rb +10 -0
- data/test/test_endpoint_handlers.rb +7 -10
- data/test/test_endpoint_recorder.rb +43 -0
- data/test/test_json_message.rb +1 -2
- data/test/test_message.rb +2 -3
- data/test/test_pinch_hitter.rb +34 -5
- data/test/test_service.rb +31 -4
- data/test/test_xml_message.rb +1 -1
- metadata +38 -52
- data/.rvmrc +0 -52
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9ad281bbcbc46749dd62398bed9d7d5541e988b9
|
4
|
+
data.tar.gz: 6d1bf2170e91d25b57c85b1f457dd29b00c904b4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ca0d42f73c2a46a473e77ec4c0c0fe57b68fb1e7e48e254b2c70e5679d0c5d74afe5266961492e7b381d4bffbab7cfd85fc517228e7442cdfbcca61bc4008181
|
7
|
+
data.tar.gz: a34aea95d209d1e1b27ee7d52e1d95b0352716f7dc3d7ecc4cbb6a54c16497f7710501486310ff09de7026acbfcf0bdba5dfa3d0abd170170c564de4b159bd80
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pinch_hitter
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.0.0-p353
|
data/.travis.yml
CHANGED
data/Changelog
CHANGED
@@ -6,3 +6,7 @@ Switch json to do overrides by key rather than path (like xml)
|
|
6
6
|
|
7
7
|
=== Release 0.3 / 2013-3-22
|
8
8
|
Add ability to register modules for custom message handling
|
9
|
+
|
10
|
+
=== Release 0.4 / 2014-3-3
|
11
|
+
* Add ability to retrieve requests made by the application
|
12
|
+
* Support PUT, PATCH, DELETE
|
data/Rakefile
CHANGED
@@ -10,7 +10,11 @@ Rake::TestTask.new(:unit) do |t|
|
|
10
10
|
end
|
11
11
|
|
12
12
|
Cucumber::Rake::Task.new(:features) do |t|
|
13
|
-
|
13
|
+
if RUBY_VERSION == '1.9.2'
|
14
|
+
t.profile = '1.9.2'
|
15
|
+
else
|
16
|
+
t.profile = 'default'
|
17
|
+
end
|
14
18
|
end
|
15
19
|
|
16
20
|
desc 'Run all unit tests and features'
|
data/cucumber.yml
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
default: --no-source --color --format pretty
|
1
|
+
default: --no-source --color --format pretty
|
2
|
+
1.9.2: --no-source --color --format pretty --tags ~@not_1.9.2
|
@@ -0,0 +1,77 @@
|
|
1
|
+
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
|
2
|
+
<soapenv:Header></soapenv:Header>
|
3
|
+
<soapenv:Body>
|
4
|
+
<SubmitXmlResponse>
|
5
|
+
<SubmitXmlResult>
|
6
|
+
<CarStandardAvail_9 xmlns="">
|
7
|
+
<CarAvailDetail>
|
8
|
+
<Signature>0</Signature>
|
9
|
+
<DataQual>
|
10
|
+
<MktgTxtAry></MktgTxtAry>
|
11
|
+
<RateSepTextAry></RateSepTextAry>
|
12
|
+
<RefPt>GRAND FORKS MARK ANDREWS IN</RefPt>
|
13
|
+
<City>GFK</City>
|
14
|
+
<State>ND</State>
|
15
|
+
<Country>US</Country>
|
16
|
+
<DistUnit>M</DistUnit>
|
17
|
+
<RateTypeDesc>DAILY</RateTypeDesc>
|
18
|
+
<RateCatDesc> STND/PROM</RateCatDesc>
|
19
|
+
<Currency>USD</Currency>
|
20
|
+
<DecPos>2</DecPos>
|
21
|
+
<TruncDec>N</TruncDec>
|
22
|
+
<AltRateInd>5</AltRateInd>
|
23
|
+
<MoreCarsInd>N</MoreCarsInd>
|
24
|
+
<CarDetailAry>
|
25
|
+
<CarDetail>
|
26
|
+
<Vnd>ZI</Vnd>
|
27
|
+
<LocAffiliate>001</LocAffiliate>
|
28
|
+
<PrimeLocn>P</PrimeLocn>
|
29
|
+
<LinkInd>I</LinkInd>
|
30
|
+
<City>GFK</City>
|
31
|
+
<LocnCat>T</LocnCat>
|
32
|
+
<LocnExpansion></LocnExpansion>
|
33
|
+
<LocnNum>1</LocnNum>
|
34
|
+
<LocnCarRental>T</LocnCarRental>
|
35
|
+
<Dist></Dist>
|
36
|
+
<Dir>T</Dir>
|
37
|
+
<GeoLat></GeoLat>
|
38
|
+
<GeoLon></GeoLon>
|
39
|
+
<CarType>MVAR</CarType>
|
40
|
+
<YieldMgmt></YieldMgmt>
|
41
|
+
<Amt>10299</Amt>
|
42
|
+
<BaseRateAmt>10299</BaseRateAmt>
|
43
|
+
<DropChargeIncInd></DropChargeIncInd>
|
44
|
+
<UpsellInd></UpsellInd>
|
45
|
+
<RatePlcmtInd>3</RatePlcmtInd>
|
46
|
+
<RateType>D</RateType>
|
47
|
+
<RateGuar>G</RateGuar>
|
48
|
+
<AdditionalCharges></AdditionalCharges>
|
49
|
+
<AvailStatus>N</AvailStatus>
|
50
|
+
<MileRate>22</MileRate>
|
51
|
+
<Mile> 100</Mile>
|
52
|
+
<DropOffRestrictions>Y</DropOffRestrictions>
|
53
|
+
<RateCat>S</RateCat>
|
54
|
+
<MileageRestrictInd></MileageRestrictInd>
|
55
|
+
<FltInd></FltInd>
|
56
|
+
<CCInd></CCInd>
|
57
|
+
<Rate>2E</Rate>
|
58
|
+
<InclRateQual>
|
59
|
+
<RateDesc>DAILY PROMO</RateDesc>
|
60
|
+
<InclRate1></InclRate1>
|
61
|
+
<InclRate2></InclRate2>
|
62
|
+
<InclRate3></InclRate3>
|
63
|
+
<InclRate4></InclRate4>
|
64
|
+
<PrePayInd></PrePayInd>
|
65
|
+
<CarTypeDesc>FORD FREESTAR 4DR/7PS</CarTypeDesc>
|
66
|
+
<DropChargeAmt></DropChargeAmt>
|
67
|
+
<ApproxTotAmt>12762</ApproxTotAmt>
|
68
|
+
</InclRateQual>
|
69
|
+
</CarDetail>
|
70
|
+
</CarDetailAry>
|
71
|
+
</DataQual>
|
72
|
+
</CarAvailDetail>
|
73
|
+
</CarStandardAvail_9>
|
74
|
+
</SubmitXmlResult>
|
75
|
+
</SubmitXmlResponse>
|
76
|
+
</soapenv:Body>
|
77
|
+
</soapenv:Envelope>
|
@@ -7,7 +7,7 @@ Given /^I want a car rental$/ do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
When /^I make a reservation$/ do
|
10
|
-
@response = app.post '/car_rental', ''
|
10
|
+
@response = app.post '/car_rental', '{"reservation": "yes"}'
|
11
11
|
end
|
12
12
|
|
13
13
|
Then /^I see a car reservation$/ do
|
@@ -53,3 +53,15 @@ end
|
|
53
53
|
Then(/^I see (.*?) in the service response$/) do |response|
|
54
54
|
@response.body.to_s.should == "<response>#{response}</response>"
|
55
55
|
end
|
56
|
+
|
57
|
+
Given(/^I have a car reservation I want to delete$/) do
|
58
|
+
mock.prime '/car_rental', :cancelled_reservation
|
59
|
+
end
|
60
|
+
|
61
|
+
When(/^I delete a car reservation$/) do
|
62
|
+
@response = app.delete '/car_rental'
|
63
|
+
end
|
64
|
+
|
65
|
+
Then(/^I should see a car reservation cancellation$/) do
|
66
|
+
@response.body.to_s.should == messages.load(:cancelled_reservation).squish
|
67
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Given /^I setup my capture service$/ do
|
2
|
+
mock.reset
|
3
|
+
end
|
4
|
+
|
5
|
+
When /^I make (\d+) posts$/ do |number|
|
6
|
+
number.to_i.times.each do
|
7
|
+
app.post '/test_post', '{"reservation": "yes"}'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
Then /^the service has received (\d+) posts(?:s?)$/ do |number|
|
12
|
+
mock.request_log('/test_post').count.should == number.to_i
|
13
|
+
end
|
14
|
+
|
15
|
+
When /^I do a (.*?) on "(.*?)"$/ do |method, endpoint|
|
16
|
+
app.send method.downcase, endpoint, '{"payload": "2tons"}'
|
17
|
+
end
|
18
|
+
|
19
|
+
Then(/^the service has recieved a request on "(.*?)"$/) do |endpoint|
|
20
|
+
mock.request_log(endpoint).count.should be > 0
|
21
|
+
end
|
22
|
+
|
23
|
+
When /^the headers for the request on "(.*?)" should contain:$/ do |endpoint, table|
|
24
|
+
headers = mock.request_log(endpoint).first.headers
|
25
|
+
table.rows_hash.each do |key, value|
|
26
|
+
headers[key].should == value
|
27
|
+
end
|
28
|
+
end
|
data/features/support/env.rb
CHANGED
@@ -0,0 +1,40 @@
|
|
1
|
+
Feature: Verify application's output
|
2
|
+
I want to test that my application sends the correct requests to an external service
|
3
|
+
As a tester trying to test the application
|
4
|
+
So that I can verify my application independently of external services
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given I setup my capture service
|
8
|
+
|
9
|
+
Scenario: Retrieve posts
|
10
|
+
When I make 3 posts
|
11
|
+
Then the service has received 3 posts
|
12
|
+
|
13
|
+
Scenario Outline: HTTP methods
|
14
|
+
When I do a <method> on "<endpoint>"
|
15
|
+
Then the service has recieved a request on "<endpoint>"
|
16
|
+
Examples:
|
17
|
+
| method | endpoint |
|
18
|
+
| POST | /poster |
|
19
|
+
| PUT | /putter |
|
20
|
+
|
21
|
+
@not_1.9.2
|
22
|
+
Scenario Outline: HTTP methods
|
23
|
+
When I do a <method> on "<endpoint>"
|
24
|
+
Then the service has recieved a request on "<endpoint>"
|
25
|
+
Examples:
|
26
|
+
| method | endpoint |
|
27
|
+
| PATCH | /patcher |
|
28
|
+
|
29
|
+
Scenario: Verifying headers
|
30
|
+
When I do a POST on "/poster"
|
31
|
+
#This is not an exhaustive list
|
32
|
+
When the headers for the request on "/poster" should contain:
|
33
|
+
| PATH_INFO | /poster |
|
34
|
+
| QUERY_STRING | |
|
35
|
+
| REQUEST_METHOD | POST |
|
36
|
+
| SERVER_NAME | 127.0.0.1 |
|
37
|
+
| SERVER_PORT | 9292 |
|
38
|
+
| SERVER_PROTOCOL | HTTP/1.1 |
|
39
|
+
| HTTP_VERSION | HTTP/1.1 |
|
40
|
+
| REQUEST_PATH | /poster |
|
@@ -25,7 +25,11 @@ module PinchHitter::Message
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def find_filename(file)
|
28
|
-
Dir["#{message_directory}/#{file}*"].first
|
28
|
+
filename = Dir["#{message_directory}/#{file}*"].first
|
29
|
+
unless filename
|
30
|
+
fail "Could not find message for '#{file}' in '#{File.expand_path(File.dirname(message_directory))}'"
|
31
|
+
end
|
32
|
+
filename
|
29
33
|
end
|
30
34
|
|
31
35
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative 'message_queue'
|
2
|
+
require_relative 'endpoint_recorder'
|
2
3
|
|
3
4
|
module PinchHitter::Service
|
4
5
|
class EndpointHandlers
|
@@ -7,16 +8,20 @@ module PinchHitter::Service
|
|
7
8
|
end
|
8
9
|
|
9
10
|
def store_message(endpoint, body)
|
10
|
-
handler_for(endpoint)
|
11
|
+
handler_for(endpoint).store body.squish
|
11
12
|
end
|
12
13
|
|
13
|
-
def respond_to(endpoint='/', request=
|
14
|
+
def respond_to(endpoint='/', request=nil)
|
14
15
|
message = handler_for(endpoint).respond_to(request)
|
15
16
|
message.squish if message
|
16
17
|
end
|
17
18
|
|
19
|
+
def requests(endpoint)
|
20
|
+
handler_for(endpoint).requests
|
21
|
+
end
|
22
|
+
|
18
23
|
def handler_for(endpoint='/')
|
19
|
-
handlers[normalize(endpoint)] || store_handler(endpoint)
|
24
|
+
handlers[normalize(endpoint)] || store_handler(endpoint)
|
20
25
|
end
|
21
26
|
|
22
27
|
def register_module(endpoint, mod)
|
@@ -26,7 +31,7 @@ module PinchHitter::Service
|
|
26
31
|
end
|
27
32
|
|
28
33
|
def store_handler(endpoint, handler=MessageQueue.new)
|
29
|
-
handlers[normalize(endpoint)] = handler
|
34
|
+
handlers[normalize(endpoint)] = EndpointRecorder.new handler
|
30
35
|
end
|
31
36
|
|
32
37
|
def normalize(endpoint)
|
@@ -35,11 +40,7 @@ module PinchHitter::Service
|
|
35
40
|
end
|
36
41
|
|
37
42
|
def reset
|
38
|
-
handlers.values.each
|
39
|
-
if(handler.respond_to? :reset)
|
40
|
-
handler.reset
|
41
|
-
end
|
42
|
-
end
|
43
|
+
handlers.values.each(&:reset)
|
43
44
|
end
|
44
45
|
end
|
45
46
|
end
|
@@ -0,0 +1,28 @@
|
|
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
|
@@ -37,16 +37,32 @@ module PinchHitter::Service
|
|
37
37
|
status 200
|
38
38
|
end
|
39
39
|
|
40
|
+
get '/received_requests' do
|
41
|
+
requests request["endpoint"]
|
42
|
+
end
|
43
|
+
|
40
44
|
post '/respond' do
|
41
45
|
respond nil
|
42
46
|
end
|
43
47
|
|
44
48
|
get '/*' do
|
45
|
-
respond params[:splat].first
|
49
|
+
respond params[:splat].first, request
|
50
|
+
end
|
51
|
+
|
52
|
+
delete '/*' do
|
53
|
+
respond params[:splat].first, request
|
46
54
|
end
|
47
55
|
|
48
56
|
post '/*' do
|
49
|
-
respond params[:splat].first, request
|
57
|
+
respond params[:splat].first, request
|
58
|
+
end
|
59
|
+
|
60
|
+
put '/*' do
|
61
|
+
respond params[:splat].first, request
|
62
|
+
end
|
63
|
+
|
64
|
+
patch '/*' do
|
65
|
+
respond params[:splat].first, request
|
50
66
|
end
|
51
67
|
|
52
68
|
def store(endpoint='/', message=nil)
|
@@ -54,7 +70,7 @@ module PinchHitter::Service
|
|
54
70
|
end
|
55
71
|
|
56
72
|
def respond(endpoint='/', request=nil)
|
57
|
-
message = @@handlers.respond_to endpoint, request
|
73
|
+
message = @@handlers.respond_to endpoint, wrap(request)
|
58
74
|
content_type determine_content_type message
|
59
75
|
puts "No message found for #{endpoint}" unless message
|
60
76
|
message
|
@@ -64,5 +80,18 @@ module PinchHitter::Service
|
|
64
80
|
@@handlers.register_module endpoint, Marshal.load(mod)
|
65
81
|
end
|
66
82
|
|
83
|
+
def requests endpoint
|
84
|
+
content_type 'application/json'
|
85
|
+
{ requests: @@handlers.requests(endpoint) }.to_json
|
86
|
+
end
|
87
|
+
|
88
|
+
def wrap request
|
89
|
+
return nil unless request
|
90
|
+
{ headers: request_headers, body: request.body.read }
|
91
|
+
end
|
92
|
+
|
93
|
+
def request_headers
|
94
|
+
env.select { |key, value| key.upcase == key }
|
95
|
+
end
|
67
96
|
end
|
68
97
|
end
|
data/lib/pinch_hitter/version.rb
CHANGED
data/lib/pinch_hitter.rb
CHANGED
@@ -34,4 +34,14 @@ module PinchHitter
|
|
34
34
|
@session.post "/register_module?endpoint=#{endpoint}", Marshal.dump(handler)
|
35
35
|
end
|
36
36
|
|
37
|
+
def request_log(endpoint)
|
38
|
+
requests = @session.get "/received_requests?endpoint=#{endpoint}"
|
39
|
+
requests = JSON.parse(requests.body)['requests']
|
40
|
+
requests.map { |h| Struct.new(:body, :headers).new(h['body'], h['headers']) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def received_messages(endpoint)
|
44
|
+
request_log(endpoint).map { |request| request.body }
|
45
|
+
end
|
46
|
+
|
37
47
|
end
|
@@ -1,10 +1,8 @@
|
|
1
1
|
ENV['RACK_ENV'] = 'test'
|
2
2
|
|
3
3
|
require 'minitest/autorun'
|
4
|
-
require 'pinch_hitter/service/endpoint_handlers'
|
5
4
|
|
6
|
-
|
7
|
-
class TestEndpointHandlers < MiniTest::Unit::TestCase
|
5
|
+
class TestEndpointHandlers < MiniTest::Test
|
8
6
|
|
9
7
|
def setup
|
10
8
|
@handlers = PinchHitter::Service::EndpointHandlers.new
|
@@ -14,13 +12,6 @@ class TestEndpointHandlers < MiniTest::Unit::TestCase
|
|
14
12
|
%Q{{"key"::"value"}}
|
15
13
|
end
|
16
14
|
|
17
|
-
def test_message_queue
|
18
|
-
@handlers.store_message 'endpoint', json
|
19
|
-
handler = @handlers.handler_for 'endpoint'
|
20
|
-
assert_instance_of(PinchHitter::Service::MessageQueue, handler)
|
21
|
-
assert_equal json, handler.respond_to
|
22
|
-
end
|
23
|
-
|
24
15
|
def test_defaults_to_message_queue
|
25
16
|
@handlers.store_message 'endpoint', json
|
26
17
|
assert_equal json, @handlers.respond_to('endpoint')
|
@@ -49,6 +40,12 @@ class TestEndpointHandlers < MiniTest::Unit::TestCase
|
|
49
40
|
assert_equal "THIS IS A TEST", @handlers.respond_to('endpoint')
|
50
41
|
end
|
51
42
|
|
43
|
+
def test_requests
|
44
|
+
request = { body: '{"Hot Rod" : "Williams"}' }
|
45
|
+
@handlers.respond_to('endpoint', request)
|
46
|
+
assert_equal [request], @handlers.requests('endpoint')
|
47
|
+
end
|
48
|
+
|
52
49
|
|
53
50
|
module TestModule
|
54
51
|
def respond_to(msg)
|
@@ -0,0 +1,43 @@
|
|
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
|
data/test/test_json_message.rb
CHANGED
data/test/test_message.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
-
|
2
1
|
ENV['RACK_ENV'] = 'test'
|
3
2
|
|
4
3
|
require 'minitest/autorun'
|
5
|
-
|
6
|
-
class TestMessage < MiniTest::
|
4
|
+
|
5
|
+
class TestMessage < MiniTest::Test
|
7
6
|
|
8
7
|
def setup
|
9
8
|
File.open("#{xml_filename}.xml", 'w') {|f| f.write(xml_message) }
|
data/test/test_pinch_hitter.rb
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
ENV['RACK_ENV'] = 'test'
|
2
2
|
|
3
|
-
require 'pinch_hitter/service/replay_ws'
|
4
|
-
require 'pinch_hitter'
|
5
3
|
require 'minitest/autorun'
|
4
|
+
require 'pinch_hitter'
|
6
5
|
require 'rack/test'
|
7
6
|
|
8
|
-
class TestPinchHitter < MiniTest::
|
7
|
+
class TestPinchHitter < MiniTest::Test
|
9
8
|
include Rack::Test::Methods
|
10
9
|
|
11
10
|
def setup
|
12
11
|
@test = Object.new
|
13
12
|
@test.extend(PinchHitter)
|
14
13
|
@test.session=session
|
15
|
-
|
14
|
+
@test.reset
|
15
|
+
@test.messages_directory = File.dirname('.')
|
16
16
|
File.open(message_file, 'w') {|f| f.write(message_content) }
|
17
17
|
end
|
18
18
|
|
@@ -27,7 +27,7 @@ class TestPinchHitter < MiniTest::Unit::TestCase
|
|
27
27
|
def message_content
|
28
28
|
"{fizzbuzz}"
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
def app
|
32
32
|
PinchHitter::Service::ReplayWs
|
33
33
|
end
|
@@ -52,10 +52,39 @@ class TestPinchHitter < MiniTest::Unit::TestCase
|
|
52
52
|
assert_equal message_content, session.last_response.body
|
53
53
|
end
|
54
54
|
|
55
|
+
def test_prime_with_missing_message
|
56
|
+
begin
|
57
|
+
@test.prime '/foo', :non_existent_file
|
58
|
+
rescue => e
|
59
|
+
assert_match "Could not find message", e.message
|
60
|
+
assert_match :non_existent_file.to_s, e.message
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
55
64
|
def test_store
|
56
65
|
@test.store '/foo', message_content
|
57
66
|
session.get '/foo'
|
58
67
|
assert_equal message_content, session.last_response.body
|
59
68
|
end
|
60
69
|
|
70
|
+
def test_request_body
|
71
|
+
update_request = '{"update": "please"}'
|
72
|
+
session.put '/foo', update_request
|
73
|
+
assert_equal update_request, @test.request_log('/foo').first.body
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_request_headers
|
77
|
+
session.delete '/foo'
|
78
|
+
headers = @test.request_log('/foo').first.headers
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_received_messages
|
82
|
+
@test.store '/foo', message_content
|
83
|
+
@test.store '/foo', message_content
|
84
|
+
messages = [ '{"abc": "123"}', '{"def": "456"}' ]
|
85
|
+
session.post '/foo', messages.first
|
86
|
+
session.post '/foo', messages.last
|
87
|
+
assert_equal messages, @test.received_messages('/foo')
|
88
|
+
end
|
89
|
+
|
61
90
|
end
|
data/test/test_service.rb
CHANGED
@@ -1,12 +1,9 @@
|
|
1
1
|
ENV['RACK_ENV'] = 'test'
|
2
2
|
|
3
|
-
require 'pinch_hitter/service/replay_ws'
|
4
3
|
require 'minitest/autorun'
|
5
|
-
require 'rack/test'
|
6
|
-
require 'nokogiri'
|
7
4
|
require_relative 'message_assertions'
|
8
5
|
|
9
|
-
class TestService < MiniTest::
|
6
|
+
class TestService < MiniTest::Test
|
10
7
|
include Rack::Test::Methods
|
11
8
|
include MessageAssertions
|
12
9
|
|
@@ -93,6 +90,24 @@ class TestService < MiniTest::Unit::TestCase
|
|
93
90
|
assert_equal '', last_response.body
|
94
91
|
end
|
95
92
|
|
93
|
+
def test_put
|
94
|
+
post '/store/endpoint1', xml_message
|
95
|
+
put '/endpoint1'
|
96
|
+
assert_received xml_message
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_patch
|
100
|
+
post '/store/endpoint1', xml_message
|
101
|
+
patch '/endpoint1'
|
102
|
+
assert_received xml_message
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_delete
|
106
|
+
post '/store/endpoint1', xml_message
|
107
|
+
delete '/endpoint1'
|
108
|
+
assert_received xml_message
|
109
|
+
end
|
110
|
+
|
96
111
|
def test_module
|
97
112
|
post '/register_module?endpoint=stuff', Marshal.dump(TestModule)
|
98
113
|
post '/stuff', ''
|
@@ -107,4 +122,16 @@ class TestService < MiniTest::Unit::TestCase
|
|
107
122
|
end
|
108
123
|
end
|
109
124
|
|
125
|
+
def test_received_requests
|
126
|
+
user_post = '{ "command": "Gimme stuff" }'
|
127
|
+
post "/store?endpoint=do_things", xml_message
|
128
|
+
post "/do_things", user_post
|
129
|
+
get '/received_requests?endpoint=do_things'
|
130
|
+
|
131
|
+
response = JSON.parse(last_response.body)['requests']
|
132
|
+
assert_equal 1, response.length
|
133
|
+
assert_equal user_post, response.first['body']
|
134
|
+
assert response.first['headers']
|
135
|
+
end
|
136
|
+
|
110
137
|
end
|
data/test/test_xml_message.rb
CHANGED
metadata
CHANGED
@@ -1,142 +1,125 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pinch_hitter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
5
|
-
prerelease:
|
4
|
+
version: '0.4'
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Steve Jackson
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-03-03 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: sinatra
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: 1.3.3
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: 1.3.3
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: nokogiri
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: 1.5.6
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: 1.5.6
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: json
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: 1.7.6
|
54
48
|
type: :runtime
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: 1.7.6
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: minitest
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - '>='
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: 4.3.3
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- -
|
66
|
+
- - '>='
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: 4.3.3
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: rack-test
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- -
|
73
|
+
- - '>='
|
84
74
|
- !ruby/object:Gem::Version
|
85
75
|
version: 0.6.2
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- -
|
80
|
+
- - '>='
|
92
81
|
- !ruby/object:Gem::Version
|
93
82
|
version: 0.6.2
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
84
|
name: rake
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
86
|
requirements:
|
99
|
-
- -
|
87
|
+
- - '>='
|
100
88
|
- !ruby/object:Gem::Version
|
101
89
|
version: 10.0.3
|
102
90
|
type: :development
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
93
|
requirements:
|
107
|
-
- -
|
94
|
+
- - '>='
|
108
95
|
- !ruby/object:Gem::Version
|
109
96
|
version: 10.0.3
|
110
97
|
- !ruby/object:Gem::Dependency
|
111
98
|
name: rspec
|
112
99
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
100
|
requirements:
|
115
|
-
- -
|
101
|
+
- - '>='
|
116
102
|
- !ruby/object:Gem::Version
|
117
103
|
version: 2.12.0
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
107
|
requirements:
|
123
|
-
- -
|
108
|
+
- - '>='
|
124
109
|
- !ruby/object:Gem::Version
|
125
110
|
version: 2.12.0
|
126
111
|
- !ruby/object:Gem::Dependency
|
127
112
|
name: cucumber
|
128
113
|
requirement: !ruby/object:Gem::Requirement
|
129
|
-
none: false
|
130
114
|
requirements:
|
131
|
-
- -
|
115
|
+
- - '>='
|
132
116
|
- !ruby/object:Gem::Version
|
133
117
|
version: 1.2.1
|
134
118
|
type: :development
|
135
119
|
prerelease: false
|
136
120
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
-
none: false
|
138
121
|
requirements:
|
139
|
-
- -
|
122
|
+
- - '>='
|
140
123
|
- !ruby/object:Gem::Version
|
141
124
|
version: 1.2.1
|
142
125
|
description: A simple web service that returns primed responses in FIFO order
|
@@ -147,7 +130,8 @@ extensions: []
|
|
147
130
|
extra_rdoc_files: []
|
148
131
|
files:
|
149
132
|
- .gitignore
|
150
|
-
- .
|
133
|
+
- .ruby-gemset
|
134
|
+
- .ruby-version
|
151
135
|
- .travis.yml
|
152
136
|
- Changelog
|
153
137
|
- Gemfile
|
@@ -156,13 +140,16 @@ files:
|
|
156
140
|
- Rakefile
|
157
141
|
- config.ru
|
158
142
|
- cucumber.yml
|
143
|
+
- features/messages/cancelled_reservation.xml
|
159
144
|
- features/messages/car_rental.xml
|
160
145
|
- features/messages/glossary.json
|
161
|
-
- features/
|
146
|
+
- features/replay.feature
|
147
|
+
- features/step_definitions/replay_steps.rb
|
148
|
+
- features/step_definitions/verify_requests_steps.rb
|
162
149
|
- features/support/env.rb
|
163
150
|
- features/support/mock_web_service.rb
|
164
151
|
- features/support/xml_parser.rb
|
165
|
-
- features/
|
152
|
+
- features/verify.feature
|
166
153
|
- lib/pinch_hitter.rb
|
167
154
|
- lib/pinch_hitter/core_ext/string.rb
|
168
155
|
- lib/pinch_hitter/message/content_type.rb
|
@@ -170,6 +157,7 @@ files:
|
|
170
157
|
- lib/pinch_hitter/message/message_store.rb
|
171
158
|
- lib/pinch_hitter/message/xml.rb
|
172
159
|
- lib/pinch_hitter/service/endpoint_handlers.rb
|
160
|
+
- lib/pinch_hitter/service/endpoint_recorder.rb
|
173
161
|
- lib/pinch_hitter/service/message_queue.rb
|
174
162
|
- lib/pinch_hitter/service/replay_ws.rb
|
175
163
|
- lib/pinch_hitter/service/runner.rb
|
@@ -177,6 +165,7 @@ files:
|
|
177
165
|
- pinch_hitter.gemspec
|
178
166
|
- test/message_assertions.rb
|
179
167
|
- test/test_endpoint_handlers.rb
|
168
|
+
- test/test_endpoint_recorder.rb
|
180
169
|
- test/test_json_message.rb
|
181
170
|
- test/test_message.rb
|
182
171
|
- test/test_pinch_hitter.rb
|
@@ -184,44 +173,41 @@ files:
|
|
184
173
|
- test/test_xml_message.rb
|
185
174
|
homepage: https://github.com/stevenjackson/pinch_hitter
|
186
175
|
licenses: []
|
176
|
+
metadata: {}
|
187
177
|
post_install_message:
|
188
178
|
rdoc_options: []
|
189
179
|
require_paths:
|
190
180
|
- lib
|
191
181
|
required_ruby_version: !ruby/object:Gem::Requirement
|
192
|
-
none: false
|
193
182
|
requirements:
|
194
|
-
- -
|
183
|
+
- - '>='
|
195
184
|
- !ruby/object:Gem::Version
|
196
185
|
version: '0'
|
197
|
-
segments:
|
198
|
-
- 0
|
199
|
-
hash: 4282640623209066746
|
200
186
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
201
|
-
none: false
|
202
187
|
requirements:
|
203
|
-
- -
|
188
|
+
- - '>='
|
204
189
|
- !ruby/object:Gem::Version
|
205
190
|
version: '0'
|
206
|
-
segments:
|
207
|
-
- 0
|
208
|
-
hash: 4282640623209066746
|
209
191
|
requirements: []
|
210
192
|
rubyforge_project:
|
211
|
-
rubygems_version: 1.
|
193
|
+
rubygems_version: 2.1.11
|
212
194
|
signing_key:
|
213
|
-
specification_version:
|
195
|
+
specification_version: 4
|
214
196
|
summary: Test utility for mocking out external web responses
|
215
197
|
test_files:
|
198
|
+
- features/messages/cancelled_reservation.xml
|
216
199
|
- features/messages/car_rental.xml
|
217
200
|
- features/messages/glossary.json
|
218
|
-
- features/
|
201
|
+
- features/replay.feature
|
202
|
+
- features/step_definitions/replay_steps.rb
|
203
|
+
- features/step_definitions/verify_requests_steps.rb
|
219
204
|
- features/support/env.rb
|
220
205
|
- features/support/mock_web_service.rb
|
221
206
|
- features/support/xml_parser.rb
|
222
|
-
- features/
|
207
|
+
- features/verify.feature
|
223
208
|
- test/message_assertions.rb
|
224
209
|
- test/test_endpoint_handlers.rb
|
210
|
+
- test/test_endpoint_recorder.rb
|
225
211
|
- test/test_json_message.rb
|
226
212
|
- test/test_message.rb
|
227
213
|
- test/test_pinch_hitter.rb
|
data/.rvmrc
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
#!/usr/bin/env bash
|
2
|
-
|
3
|
-
# This is an RVM Project .rvmrc file, used to automatically load the ruby
|
4
|
-
# development environment upon cd'ing into the directory
|
5
|
-
|
6
|
-
# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
|
7
|
-
# Only full ruby name is supported here, for short names use:
|
8
|
-
# echo "rvm use 1.9.3" > .rvmrc
|
9
|
-
environment_id="ruby-1.9.3-p327@pinch_hitter"
|
10
|
-
|
11
|
-
|
12
|
-
# First we attempt to load the desired environment directly from the environment
|
13
|
-
# file. This is very fast and efficient compared to running through the entire
|
14
|
-
# CLI and selector. If you want feedback on which environment was used then
|
15
|
-
# insert the word 'use' after --create as this triggers verbose mode.
|
16
|
-
if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
|
17
|
-
&& -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
|
18
|
-
then
|
19
|
-
\. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
|
20
|
-
|
21
|
-
if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]]
|
22
|
-
then
|
23
|
-
. "${rvm_path:-$HOME/.rvm}/hooks/after_use"
|
24
|
-
fi
|
25
|
-
else
|
26
|
-
# If the environment file has not yet been created, use the RVM CLI to select.
|
27
|
-
if ! rvm --create "$environment_id"
|
28
|
-
then
|
29
|
-
echo "Failed to create RVM environment '${environment_id}'."
|
30
|
-
return 1
|
31
|
-
fi
|
32
|
-
fi
|
33
|
-
|
34
|
-
|
35
|
-
# If you use bundler, this might be useful to you:
|
36
|
-
if [[ -s Gemfile ]] && ! command -v bundle >/dev/null
|
37
|
-
then
|
38
|
-
printf "The rubygem 'bundler' is not installed. Installing it now.\n"
|
39
|
-
gem install bundler
|
40
|
-
fi
|
41
|
-
if [[ -s Gemfile ]] && command -v bundle
|
42
|
-
then
|
43
|
-
bundle install
|
44
|
-
fi
|
45
|
-
|
46
|
-
if [[ $- == *i* ]] # check for interactive shells
|
47
|
-
then
|
48
|
-
echo "Using: $(tput setaf 2)$GEM_HOME$(tput sgr0)" # show the user the ruby and gemset they are using in green
|
49
|
-
else
|
50
|
-
echo "Using: $GEM_HOME" # don't use colors in interactive shells
|
51
|
-
fi
|
52
|
-
|