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