alovak-network 1.1.0 → 1.1.1

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.
data/lib/network.rb CHANGED
@@ -1,11 +1,8 @@
1
+ require 'benchmark'
1
2
  require 'net/https'
2
3
  require 'network/connection'
3
- module Network
4
- class Error < Exception
5
- end
6
-
7
- VERSION = '1.0.0'
8
4
 
5
+ module Network
9
6
  def self.post(url, data)
10
7
  Connection.new(url).post(data)
11
8
  end
@@ -1,4 +1,18 @@
1
1
  module Network
2
+ class Error < Exception
3
+ end
4
+
5
+ class ResponseError < Error
6
+ attr_reader :response
7
+ def initialize(response)
8
+ @response = response
9
+ end
10
+
11
+ def to_s
12
+ "Failed with #{@response.code} #{@response.message if @response.respond_to?(:message)}"
13
+ end
14
+ end
15
+
2
16
  class Connection
3
17
  attr_reader :uri, :pem
4
18
 
@@ -22,17 +36,14 @@ module Network
22
36
  end
23
37
 
24
38
  def post(data)
25
- begin
39
+ try_request do
26
40
  log_request(data)
27
- http.post(uri.path, data, post_headers(data))
28
- rescue Timeout::Error, Errno::ETIMEDOUT, Timeout::ExitException
29
- raise Error, "The connection to the remote server is timed out"
30
- rescue EOFError
31
- raise Error, "The connection to the remote server was dropped"
32
- rescue Errno::ECONNRESET, Errno::ECONNABORTED
33
- raise Error, "The remote server reset the connection"
34
- rescue Errno::ECONNREFUSED
35
- raise Error, "The connection was refused by the remote server"
41
+ response = nil
42
+ ms = Benchmark.realtime do
43
+ response = http.post(uri.path, data, post_headers(data))
44
+ end
45
+ log_response(response, ms)
46
+ handle_response(response)
36
47
  end
37
48
  end
38
49
 
@@ -55,9 +66,32 @@ module Network
55
66
  http
56
67
  end
57
68
 
69
+ def handle_response(response)
70
+ case response.code.to_i
71
+ when 200...300
72
+ response.body
73
+ else
74
+ raise ResponseError.new(response)
75
+ end
76
+ end
77
+
78
+ def try_request(&block)
79
+ begin
80
+ block.call
81
+ rescue Timeout::Error, Errno::ETIMEDOUT, Timeout::ExitException
82
+ raise Error, "The connection to the remote server is timed out"
83
+ rescue EOFError
84
+ raise Error, "The connection to the remote server was dropped"
85
+ rescue Errno::ECONNRESET, Errno::ECONNABORTED
86
+ raise Error, "The remote server reset the connection"
87
+ rescue Errno::ECONNREFUSED
88
+ raise Error, "The connection was refused by the remote server"
89
+ end
90
+ end
91
+
58
92
  def post_headers(data)
59
93
  @headers['Content-Type'] ||= 'application/x-www-form-urlencoded'
60
- @headers['Content-Length'] ||= data.size.to_s
94
+ @headers['Content-Length'] ||= data.bytesize.to_s
61
95
  @headers
62
96
  end
63
97
 
@@ -105,9 +139,9 @@ module Network
105
139
  log (request_filter ? request_filter.call(data) : data)
106
140
  end
107
141
 
108
- def log_response(data)
109
- log "<---"
110
- log (response_filter ? response_filter.call(data) : data)
142
+ def log_response(response, ms_time = -1)
143
+ log "<-- %s %s (%d bytes %.2fms)" % [response.code, response.message, (response.body ? response.body.bytesize : 0), ms_time]
144
+ log (response_filter ? response_filter.call(response.body) : response.body) if response.body
111
145
  log "----"
112
146
  end
113
147
  end
@@ -9,7 +9,10 @@ class TestLogger
9
9
  end
10
10
  end
11
11
 
12
+ ResponseStub = Struct.new(:code, :message, :body)
13
+
12
14
  class TestConnectionLogging < Test::Unit::TestCase
15
+
13
16
  def setup
14
17
  @connection = Network::Connection.new("http://example.com/path")
15
18
  @connection.logger = TestLogger.new
@@ -31,10 +34,11 @@ class TestConnectionLogging < Test::Unit::TestCase
31
34
  end
32
35
 
33
36
  def test_log_response
34
- @connection.send(:log_response, "response data")
37
+ response = ResponseStub.new("200", "OK", "response data")
38
+ @connection.send(:log_response, response, 0.16)
35
39
  log = @connection.logger.log
36
40
 
37
- assert_match /<---/, log
41
+ assert_match /<-- 200 OK \(13 bytes 0.16ms\)/, log
38
42
  assert_match /response data/, log
39
43
  assert_match /----/, log
40
44
  end
@@ -46,13 +50,15 @@ class TestConnectionLogging < Test::Unit::TestCase
46
50
  end
47
51
 
48
52
  def test_response_filtering
53
+ response = ResponseStub.new("200", "OK", "response")
49
54
  @connection.response_filter = Proc.new {|req| "#{req} is filtered"}
50
- @connection.send(:log_response, "response")
55
+ @connection.send(:log_response, response)
51
56
  assert_match /response is filtered/, @connection.logger.log
52
57
  end
53
58
  end
54
59
 
55
60
  class TestConnection < Test::Unit::TestCase
61
+
56
62
  def setup
57
63
  @connection = Network::Connection.new("http://example.com/path")
58
64
  @http = mock('http')
@@ -65,14 +71,37 @@ class TestConnection < Test::Unit::TestCase
65
71
  { :class => Errno::ECONNABORTED, :message => "The remote server reset the connection"},
66
72
  { :class => Errno::ECONNREFUSED, :message => "The connection was refused by the remote server"},
67
73
  ].each do |exception|
68
- Net::HTTP.any_instance.expects(:request).raises exception[:class]
69
74
  e = assert_raise Network::Error do
70
- @connection.post("some data")
75
+ @connection.send(:try_request) do
76
+ raise exception[:class]
77
+ end
71
78
  end
72
79
  assert_equal exception[:message], e.message
73
80
  end
74
81
  end
75
82
 
83
+ def test_post_methods
84
+ sec = sequence('order')
85
+ @connection.expects(:log_request).in_sequence(sec)
86
+ @connection.expects(:http).in_sequence(sec).returns(stub('http', :post => true))
87
+ @connection.expects(:log_response).in_sequence(sec)
88
+ @connection.expects(:handle_response).in_sequence(sec)
89
+
90
+ @connection.post("hello")
91
+ end
92
+
93
+ def test_response_handler_raises_response_error_if_response_code_not_in_200_299
94
+ [300, 400, 500].each do |code|
95
+ assert_raise Network::ResponseError do
96
+ @connection.send(:handle_response, ResponseStub.new(code))
97
+ end
98
+ end
99
+ end
100
+
101
+ def test_response_handler_returns_response_body_if_response_code_200_299
102
+ assert_equal "response", @connection.send(:handle_response, ResponseStub.new(200, "OK", "response"))
103
+ end
104
+
76
105
  def test_default_timeouts
77
106
  assert_equal Network::Connection::READ_TIMEOUT, @connection.read_timeout
78
107
  assert_equal Network::Connection::OPEN_TIMEOUT, @connection.open_timeout
@@ -86,24 +115,21 @@ class TestConnection < Test::Unit::TestCase
86
115
  end
87
116
 
88
117
  def test_default_headers_for_post_request
89
- Net::HTTP.any_instance.expects(:post).with("/path", "data",
90
- { 'Content-Type' => 'application/x-www-form-urlencoded',
91
- 'Content-Length' => '4' })
92
- @connection.post("data")
118
+ expected_headers = { 'Content-Type' => 'application/x-www-form-urlencoded',
119
+ 'Content-Length' => '4' }
120
+
121
+ assert_equal expected_headers, @connection.send(:post_headers, "data")
93
122
  end
94
123
 
95
124
  def test_user_headers_are_not_overwrited_by_default_headers
96
- excepted_headers = {
97
- 'Content-Type' => 'application/xml',
98
- 'Accept' => 'text/plain'
99
- }
125
+ user_headers = { 'Content-Type' => 'application/xml',
126
+ 'Accept' => 'text/plain' }
100
127
 
101
- Net::HTTP.any_instance.expects(:post).with("/path",
102
- "data",
103
- excepted_headers.update('Content-Length' => '4'))
128
+ expected_headers = { 'Content-Length' => '4' }.update(user_headers)
129
+
130
+ @connection.headers = user_headers
104
131
 
105
- @connection.headers = excepted_headers
106
- @connection.post("data")
132
+ assert_equal expected_headers, @connection.send(:post_headers, "data")
107
133
  end
108
134
 
109
135
  def test_configure_ssl_if_scheme_is_https
data/test/test_helper.rb CHANGED
@@ -1,6 +1,5 @@
1
- require "test/unit"
2
- require "rubygems"
3
- require "mocha"
4
- require 'turn'
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'mocha'
5
4
 
6
5
  require 'lib/network'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alovak-network
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pavel Gabriel
@@ -43,7 +43,6 @@ extra_rdoc_files: []
43
43
  files:
44
44
  - lib/network/connection.rb
45
45
  - lib/network.rb
46
- - test/network/test_connection.rb
47
46
  has_rdoc: false
48
47
  homepage: http://github.com/alovak/network/
49
48
  licenses:
@@ -73,4 +72,5 @@ specification_version: 2
73
72
  summary: HTTP/HTTPS communication module based on ruby net/http, net/https modules
74
73
  test_files:
75
74
  - test/network/test_network.rb
75
+ - test/network/test_connection.rb
76
76
  - test/test_helper.rb