transport 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.rdoc +109 -0
- data/Rakefile +50 -0
- data/lib/transport.rb +9 -0
- data/lib/transport/common.rb +41 -0
- data/lib/transport/common/request_builder.rb +43 -0
- data/lib/transport/http.rb +43 -0
- data/lib/transport/http/formatter.rb +85 -0
- data/lib/transport/http/request_builder.rb +73 -0
- data/lib/transport/http/request_builder/parameter_serializer.rb +61 -0
- data/lib/transport/json.rb +37 -0
- data/lib/transport/json/request_builder.rb +56 -0
- data/lib/transport/json/response_parser.rb +33 -0
- data/lib/transport/spec.rb +10 -0
- data/lib/transport/spec/faker.rb +75 -0
- data/lib/transport/unexpected_status_code_error.rb +21 -0
- data/spec/acceptance/http_spec.rb +20 -0
- data/spec/acceptance/json_spec.rb +10 -0
- data/spec/lib/transport/common/request_builder_spec.rb +61 -0
- data/spec/lib/transport/common_spec.rb +68 -0
- data/spec/lib/transport/http/formatter_spec.rb +28 -0
- data/spec/lib/transport/http/request_builder/parameter_serializer_spec.rb +18 -0
- data/spec/lib/transport/http/request_builder_spec.rb +134 -0
- data/spec/lib/transport/http_spec.rb +61 -0
- data/spec/lib/transport/json/request_builder_spec.rb +78 -0
- data/spec/lib/transport/json/response_parser_spec.rb +52 -0
- data/spec/lib/transport/json_spec.rb +58 -0
- data/spec/lib/transport/spec/faker_spec.rb +87 -0
- data/spec/lib/transport/unexpected_status_code_error_spec.rb +18 -0
- data/spec/spec_helper.rb +6 -0
- metadata +133 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "spec_helper"))
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "..", "lib", "transport", "http", "formatter"))
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
describe Transport::HTTP::Formatter do
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
@logger = mock Logger, :info => nil
|
9
|
+
|
10
|
+
@formatter = described_class.new @logger
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "log_transport" do
|
14
|
+
|
15
|
+
before :each do
|
16
|
+
@uri = mock URI, :host => "host", :port => 1234
|
17
|
+
@request = mock Net::HTTP::Get, :class => Net::HTTP::Get, :path => "/path", :each_capitalized_name => nil, :body => "line one\nline two"
|
18
|
+
@response = mock Net::HTTPResponse, :code => "200", :body => "body"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should write the formatted request to the logger" do
|
22
|
+
@logger.should_receive(:info).with("transport to host 1234\nrequest: Net::HTTP::Get /path\n body:\n line one\n line two\nresponse: 200\n body")
|
23
|
+
@formatter.log_transport @uri, @request, @response
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "..", "spec_helper"))
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "..", "..", "lib", "transport", "http", "request_builder", "parameter_serializer"))
|
3
|
+
|
4
|
+
describe Transport::HTTP::RequestBuilder::ParameterSerializer do
|
5
|
+
|
6
|
+
it "should return nil on an empty parameter hash" do
|
7
|
+
serializer = described_class.new
|
8
|
+
serializer.perform
|
9
|
+
serializer.result.should be_nil
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should return a correctly encoded query string" do
|
13
|
+
serializer = described_class.new :foo => "bar", :test => [ "value1", "value2" ]
|
14
|
+
serializer.perform
|
15
|
+
serializer.result.should == "foo=bar&test=value1&test=value2"
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "spec_helper"))
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "..", "lib", "transport", "http", "request_builder"))
|
3
|
+
|
4
|
+
describe Transport::HTTP::RequestBuilder do
|
5
|
+
|
6
|
+
before :each do
|
7
|
+
@url = "http://host:1234/test"
|
8
|
+
@options = {
|
9
|
+
:headers => { "Test-Header" => "test" },
|
10
|
+
:parameters => { "test_parameter" => "test" }
|
11
|
+
}
|
12
|
+
@parameter_serializer = mock described_class::ParameterSerializer, :perform => nil, :result => "test_parameter=test"
|
13
|
+
described_class::ParameterSerializer.stub(:new).and_return(@parameter_serializer)
|
14
|
+
end
|
15
|
+
|
16
|
+
def mock_request(http_method)
|
17
|
+
@request_class = Net::HTTP.const_get(:"#{http_method.to_s.capitalize}")
|
18
|
+
@request = mock @request_class, :path => "/test", :basic_auth => nil, :body= => nil
|
19
|
+
@request_class.stub(:new).and_return(@request)
|
20
|
+
end
|
21
|
+
|
22
|
+
shared_examples_for "any http request builder perform" do
|
23
|
+
|
24
|
+
it "should initialize the parameter serializer correctly" do
|
25
|
+
described_class::ParameterSerializer.should_receive(:new).with(@options[:parameters]).and_return(@parameter_serializer)
|
26
|
+
@request_builder.perform
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should set basic authentication for the request" do
|
30
|
+
@request.should_receive(:basic_auth).with("test_username", "test_password")
|
31
|
+
|
32
|
+
@request_builder.options.merge! :auth_type => :basic, :username => "test_username", :password => "test_password"
|
33
|
+
@request_builder.perform
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should raise a #{NotImplementedError} if auth_type is not supported" do
|
37
|
+
@request_builder.options.merge! :auth_type => :invalid
|
38
|
+
lambda do
|
39
|
+
@request_builder.perform
|
40
|
+
end.should raise_error(NotImplementedError)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
shared_examples_for "any http request builder request" do
|
46
|
+
|
47
|
+
before :each do
|
48
|
+
@request_builder.perform
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should return the request" do
|
52
|
+
@request_builder.request.should == @request
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
described_class::HTTP_METHODS_WITH_PARAMETERS.each do |http_method|
|
58
|
+
|
59
|
+
context "#{http_method} request" do
|
60
|
+
|
61
|
+
before :each do
|
62
|
+
mock_request http_method
|
63
|
+
@request_builder = described_class.new http_method, @url, @options
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "perform" do
|
67
|
+
|
68
|
+
it_should_behave_like "any http request builder perform"
|
69
|
+
|
70
|
+
it "should initialize the request correctly" do
|
71
|
+
@request_class.should_receive(:new).with("/test?test_parameter=test", @options[:headers]).and_return(@request)
|
72
|
+
@request_builder.perform
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should add no query string if parameter serializer returns nil" do
|
76
|
+
@request_class.should_receive(:new).with("/test", @options[:headers]).and_return(@request)
|
77
|
+
|
78
|
+
@parameter_serializer.stub(:result).and_return(nil)
|
79
|
+
@request_builder.perform
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should not set the request body" do
|
83
|
+
@request.should_not_receive(:body=)
|
84
|
+
@request_builder.perform
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "request" do
|
90
|
+
|
91
|
+
it_should_behave_like "any http request builder request"
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
described_class::HTTP_METHODS_WITH_BODY.each do |http_method|
|
100
|
+
|
101
|
+
context "#{http_method} request" do
|
102
|
+
|
103
|
+
before :each do
|
104
|
+
mock_request http_method
|
105
|
+
@request_builder = described_class.new http_method, @url, @options
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "perform" do
|
109
|
+
|
110
|
+
it_should_behave_like "any http request builder perform"
|
111
|
+
|
112
|
+
it "should initialize the request correctly" do
|
113
|
+
@request_class.should_receive(:new).with("/test", @options[:headers]).and_return(@request)
|
114
|
+
@request_builder.perform
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should set the request body" do
|
118
|
+
@request.should_receive(:body=).with("test_parameter=test")
|
119
|
+
@request_builder.perform
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "request" do
|
125
|
+
|
126
|
+
it_should_behave_like "any http request builder request"
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "lib", "transport", "http"))
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
describe Transport::HTTP do
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
@uri = mock URI, :host => "host", :port => 1234
|
9
|
+
@request = mock Net::HTTPRequest, :path => "/path"
|
10
|
+
@logger = mock ::Logger, :info => nil
|
11
|
+
@options = { :expected_status_code => 200, :logger => @logger }
|
12
|
+
|
13
|
+
@response = mock Net::HTTPResponse, :code => "200", :body => "test\ntest"
|
14
|
+
Net::HTTP.stub(:start).and_return(@response)
|
15
|
+
|
16
|
+
@formatter = mock described_class::Formatter, :log_transport => nil
|
17
|
+
described_class::Formatter.stub(:new).and_return(@formatter)
|
18
|
+
|
19
|
+
@transport = described_class.new @uri, @request, @options
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "perform" do
|
23
|
+
|
24
|
+
it "should perform the request" do
|
25
|
+
Net::HTTP.should_receive(:start).with("host", 1234).and_return(@response)
|
26
|
+
@transport.perform
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should initialize the formatter" do
|
30
|
+
described_class::Formatter.should_receive(:new).and_return(@formatter)
|
31
|
+
@transport.perform
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should log the transport" do
|
35
|
+
@formatter.should_receive(:log_transport).with(@uri, @request, @response)
|
36
|
+
@transport.perform
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should raise UnexpectedStatusCodeError if responded status code is wrong" do
|
40
|
+
@transport.options.merge! :expected_status_code => 201
|
41
|
+
lambda do
|
42
|
+
@transport.perform
|
43
|
+
end.should raise_error(Transport::UnexpectedStatusCodeError)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "response" do
|
49
|
+
|
50
|
+
before :each do
|
51
|
+
@transport.perform
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should return the response body" do
|
55
|
+
@transport.perform
|
56
|
+
@transport.response.should == "test\ntest"
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "spec_helper"))
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "..", "lib", "transport", "json", "request_builder"))
|
3
|
+
|
4
|
+
describe Transport::JSON::RequestBuilder do
|
5
|
+
|
6
|
+
before :each do
|
7
|
+
@http_method = :get
|
8
|
+
@url = "test_url"
|
9
|
+
@options = { :encode_parameters => true }
|
10
|
+
|
11
|
+
@request = mock Net::HTTP::Get
|
12
|
+
|
13
|
+
@http_request_builder = mock Transport::HTTP::RequestBuilder, :perform => nil, :request => @request
|
14
|
+
Transport::HTTP::RequestBuilder.stub(:new).and_return(@http_request_builder)
|
15
|
+
|
16
|
+
@request_builder = described_class.new @http_method, @url, @options
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "perform" do
|
20
|
+
|
21
|
+
it "should initialize the http request builder correctly" do
|
22
|
+
Transport::HTTP::RequestBuilder.should_receive(:new).with(
|
23
|
+
@http_method,
|
24
|
+
@url,
|
25
|
+
@options.merge(:headers => { "Accept" => "application/json" })
|
26
|
+
).and_return(@http_request_builder)
|
27
|
+
|
28
|
+
@request_builder.perform
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should set the content type to 'application/json' and convert body to json if a body is given" do
|
32
|
+
Transport::HTTP::RequestBuilder.should_receive(:new).with(
|
33
|
+
@http_method,
|
34
|
+
@url,
|
35
|
+
@options.merge(
|
36
|
+
:headers => { "Accept" => "application/json", "Content-Type" => "application/json" },
|
37
|
+
:body => "{\"test\":\"body\"}"
|
38
|
+
)
|
39
|
+
).and_return(@http_request_builder)
|
40
|
+
|
41
|
+
@request_builder.options.merge! :body => { "test" => "body" }
|
42
|
+
@request_builder.perform
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should convert the parameters to json if requested" do
|
46
|
+
Transport::HTTP::RequestBuilder.should_receive(:new).with(
|
47
|
+
@http_method,
|
48
|
+
@url,
|
49
|
+
@options.merge(
|
50
|
+
:headers => { "Accept" => "application/json" },
|
51
|
+
:parameters => { "test_parameter" => "\"test\"" }
|
52
|
+
)
|
53
|
+
).and_return(@http_request_builder)
|
54
|
+
|
55
|
+
@request_builder.options.merge! :parameters => { "test_parameter" => "test" }
|
56
|
+
@request_builder.perform
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should perform a http request build" do
|
60
|
+
@http_request_builder.should_receive(:perform)
|
61
|
+
@request_builder.perform
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "request" do
|
67
|
+
|
68
|
+
before :each do
|
69
|
+
@request_builder.perform
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should return the request" do
|
73
|
+
@request_builder.request.should == @request
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "spec_helper"))
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "..", "lib", "transport", "json", "response_parser"))
|
3
|
+
|
4
|
+
describe Transport::JSON::ResponseParser do
|
5
|
+
|
6
|
+
before :each do
|
7
|
+
@http_response = "{\"test\":\"test value\"}"
|
8
|
+
|
9
|
+
@response_parser = described_class.new @http_response
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "perform" do
|
13
|
+
|
14
|
+
it "should parse the response body" do
|
15
|
+
JSON.should_receive(:parse).with(@http_response).and_return("test" => "test value")
|
16
|
+
@response_parser.perform
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should set result to nil if http response is nil" do
|
20
|
+
response_parser = described_class.new nil
|
21
|
+
response_parser.perform
|
22
|
+
response_parser.result.should be_nil
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should set result to nil if http response is empty" do
|
26
|
+
response_parser = described_class.new " "
|
27
|
+
response_parser.perform
|
28
|
+
response_parser.result.should be_nil
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should raise a #{Transport::JSON::ParserError} if a #{JSON::ParserError} is raised" do
|
32
|
+
JSON.stub(:parse).and_raise(JSON::ParserError)
|
33
|
+
lambda do
|
34
|
+
@response_parser.perform
|
35
|
+
end.should raise_error(Transport::JSON::ParserError)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "result" do
|
41
|
+
|
42
|
+
before :each do
|
43
|
+
@response_parser.perform
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should return the result" do
|
47
|
+
@response_parser.result.should == { "test" => "test value" }
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "lib", "transport", "json"))
|
3
|
+
|
4
|
+
describe Transport::JSON do
|
5
|
+
|
6
|
+
before :each do
|
7
|
+
@uri = mock URI
|
8
|
+
@request = mock Net::HTTPRequest
|
9
|
+
@options = { }
|
10
|
+
|
11
|
+
@http_response = "test_http_response"
|
12
|
+
|
13
|
+
@http_transport = mock Transport::HTTP, :perform => nil, :response => @http_response
|
14
|
+
Transport::HTTP.stub(:new).and_return(@http_transport)
|
15
|
+
|
16
|
+
@response_parser = mock described_class::ResponseParser, :perform => nil, :result => :test_response
|
17
|
+
described_class::ResponseParser.stub(:new).and_return(@response_parser)
|
18
|
+
|
19
|
+
@transport = described_class.new @uri, @request, @options
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "perform" do
|
23
|
+
|
24
|
+
it "should initialize the http transport" do
|
25
|
+
Transport::HTTP.should_receive(:new).with(@uri, @request, @options).and_return(@http_transport)
|
26
|
+
@transport.perform
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should perform the http transport" do
|
30
|
+
@http_transport.should_receive(:perform)
|
31
|
+
@transport.perform
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should initialize the response parser" do
|
35
|
+
described_class::ResponseParser.should_receive(:new).with(@http_response).and_return(@response_parser)
|
36
|
+
@transport.perform
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should perform the response parse" do
|
40
|
+
@response_parser.should_receive(:perform)
|
41
|
+
@transport.perform
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "response" do
|
47
|
+
|
48
|
+
before :each do
|
49
|
+
@transport.perform
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should return the response parser result" do
|
53
|
+
@transport.response.should == :test_response
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "spec_helper"))
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "..", "lib", "transport", "spec", "faker"))
|
3
|
+
|
4
|
+
describe Transport::Spec::Faker do
|
5
|
+
|
6
|
+
before :each do
|
7
|
+
@fake = [
|
8
|
+
{
|
9
|
+
:http_method => "get",
|
10
|
+
:url => "http://host:1234/test.html",
|
11
|
+
:response => {
|
12
|
+
:code => 200,
|
13
|
+
:body => "<html></html>"
|
14
|
+
}
|
15
|
+
}, {
|
16
|
+
:http_method => "get",
|
17
|
+
:url => "http://host:1234/test.json",
|
18
|
+
:response => {
|
19
|
+
:code => 200,
|
20
|
+
:body => { "test" => "body" }
|
21
|
+
}
|
22
|
+
}
|
23
|
+
]
|
24
|
+
YAML.stub(:load_file).and_return(@fake)
|
25
|
+
@filename = "test_filename"
|
26
|
+
end
|
27
|
+
|
28
|
+
def do_fake
|
29
|
+
described_class.fake! @filename
|
30
|
+
end
|
31
|
+
|
32
|
+
shared_examples_for "any fake" do
|
33
|
+
|
34
|
+
it "should load the yaml file" do
|
35
|
+
YAML.should_receive(:load_file).with(@filename).and_return(@fake)
|
36
|
+
do_fake
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should raise a #{described_class::NoFakeRequestError} if fake request is matching" do
|
40
|
+
do_fake
|
41
|
+
lambda do
|
42
|
+
do_request :get, "invalid"
|
43
|
+
end.should raise_error(described_class::NoFakeRequestError)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should raise an #{Transport::UnexpectedStatusCodeError} if the wrong status code is returned" do
|
47
|
+
do_fake
|
48
|
+
lambda do
|
49
|
+
do_request :get, "http://host:1234/test.html", :expected_status_code => 201
|
50
|
+
end.should raise_error(Transport::UnexpectedStatusCodeError)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "fake an http transport" do
|
56
|
+
|
57
|
+
def do_request(*arguments)
|
58
|
+
Transport::HTTP.request *arguments
|
59
|
+
end
|
60
|
+
|
61
|
+
it_should_behave_like "any fake"
|
62
|
+
|
63
|
+
it "should fake a http transport" do
|
64
|
+
do_fake
|
65
|
+
response = do_request :get, "http://host:1234/test.html"
|
66
|
+
response.should == "<html></html>"
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "fake an json transport" do
|
72
|
+
|
73
|
+
def do_request(*arguments)
|
74
|
+
Transport::JSON.request *arguments
|
75
|
+
end
|
76
|
+
|
77
|
+
it_should_behave_like "any fake"
|
78
|
+
|
79
|
+
it "should fake a json transport" do
|
80
|
+
do_fake
|
81
|
+
response = do_request :get, "http://host:1234/test.json"
|
82
|
+
response.should == { "test" => "body" }
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|