resource_accessor 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 32baacfc4e7a916204597ea8d1f6241e56c38807
4
- data.tar.gz: a1994c6edd8045267b9ab688cf658edcd70bec12
3
+ metadata.gz: 9f6eb7b46ad736c090bf61416ff239b6f39254d3
4
+ data.tar.gz: 5415d79f310c60cdce46f42666878c834d335cbe
5
5
  SHA512:
6
- metadata.gz: afb238c1736db16a20a52b995b789bff9a3fbdc0989ecd174607972584ee87903d3071f0e5fcf69bbd22b7f49be2f8c456be6593f64aa075ac0c61c5e634acbe
7
- data.tar.gz: b9e1d3c2f7069b857d86e9d4d4dbe42000055c79dc7344f3871df29ce5f5ddfc05709ca8d449b7362e80e727800bbccf631e08eb7ec431e6ae1f1c7da5678026
6
+ metadata.gz: d979406e639d945bde47697aea567afefd11e3014bb581789552ef0d67fd4070e092b45b0454131c7ee4f288b35ce618c59c2210f5a44740b606b1b2e0436158
7
+ data.tar.gz: db397ac1b3f05c92f69674fbf4f81f4f2858d518fe148d6fb7021cece49138a00b26f4aa77f6f10ffae85973f06fb333d59b562c5d55a23e9d303b03fc5b7aef
data/CHANGES CHANGED
@@ -10,4 +10,8 @@
10
10
 
11
11
  == Version 1.1.0
12
12
 
13
- * Write documentation;API change.
13
+ * Write documentation;API change.
14
+
15
+ == Version 1.1.1
16
+
17
+ * Adding specs.
data/Gemfile CHANGED
@@ -8,4 +8,5 @@ end
8
8
  group :test do
9
9
  gem "rspec"
10
10
  gem "mocha"
11
+ gem "log4r"
11
12
  end
@@ -7,6 +7,7 @@ GEM
7
7
  gemspec_deps_gen (1.1.2)
8
8
  bundler
9
9
  file_utils
10
+ log4r (1.1.10)
10
11
  metaclass (0.0.1)
11
12
  mocha (0.14.0)
12
13
  metaclass (~> 0.0.1)
@@ -25,5 +26,6 @@ PLATFORMS
25
26
  DEPENDENCIES
26
27
  gemcutter
27
28
  gemspec_deps_gen
29
+ log4r
28
30
  mocha
29
31
  rspec
@@ -1,4 +1,5 @@
1
1
  require 'net/https'
2
+ require 'cgi'
2
3
 
3
4
  class ResourceAccessor
4
5
  attr_accessor :timeout, :ca_file, :validate_ssl_cert
@@ -43,6 +44,12 @@ class ResourceAccessor
43
44
  response.response['set-cookie']
44
45
  end
45
46
 
47
+ def query_from_hash(params)
48
+ return "" if params.empty?
49
+
50
+ params.sort.map {|k, v| "#{k}=#{v.nil? ? '' : CGI.escape(v)}"}.join("&")
51
+ end
52
+
46
53
  private
47
54
 
48
55
  def locate_response url, method, headers, body, cookie=nil
@@ -1,3 +1,3 @@
1
1
  class ResourceAccessor
2
- VERSION = "1.1.0"
2
+ VERSION = "1.1.1"
3
3
  end
@@ -0,0 +1,188 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ GatewayError = Class.new(Exception)
4
+
5
+ require 'resource_accessor'
6
+ require 'log4r'
7
+
8
+ class Gateway
9
+ include Log4r
10
+
11
+ attr_accessor :accessor, :logger
12
+
13
+ def initialize
14
+ @accessor = ResourceAccessor.new
15
+ @accessor.timeout = 30
16
+
17
+ @logger = Logger.new 'my_logger'
18
+ #@logger.outputters = Outputter.stdout
19
+ end
20
+
21
+ def bad_response? response
22
+ response.class == Net::HTTPNotFound or (response.kind_of?(Net::HTTPSuccess) and !!(response.body =~/error/))
23
+ end
24
+
25
+ def get params = {}, headers = {}
26
+ with_exception_handler(params, headers) do |params, headers|
27
+ @accessor.get_response(params, headers)
28
+ end
29
+ end
30
+
31
+ def post params = {}, headers = {}
32
+ with_exception_handler(params, headers) do |params, headers|
33
+ @accessor.get_response(params.merge(:method => :post), headers)
34
+ end
35
+ end
36
+
37
+ def soap_post params = {}, headers = {}
38
+ with_exception_handler(params, headers) do |params, headers|
39
+ response = @accessor.get_soap_response(params.merge(:method => :post), headers)
40
+
41
+ logger.debug "#{params[:body]}" if params[:body]
42
+
43
+ response
44
+ end
45
+ end
46
+
47
+ def with_exception_handler params, headers, &code
48
+ begin
49
+ response = code.call(params, headers)
50
+
51
+ if bad_response?(response)
52
+ log.error(response, "#{self.class.name} failed with #{response.code}:#{response.message}\n#{response.body}")
53
+
54
+ raise GatewayError, "#{response.code} #{response.message}\n#{response.body}\n(URL: '#{params[:url]}')"
55
+ else
56
+ logger.info("Got #{response.code} response from #{self.class.name} Service")
57
+ end
58
+ rescue GatewayError
59
+ raise
60
+ rescue Exception => e
61
+ logger.error("#{self.class.name} received error: #{e}")
62
+
63
+ raise GatewayError, "Error: #{e} (URL: '#{params[:url]}')"
64
+ end
65
+ end
66
+ end
67
+
68
+ describe Gateway do
69
+ let(:some_https_url) { "https://somehost.com" }
70
+
71
+ let(:simple_response) do
72
+ good_response = Net::HTTPSuccess.new "1.1", "200", "success"
73
+ good_response.stubs(:stream_check => '')
74
+ good_response
75
+ end
76
+
77
+ it "uses certificate file and OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT as verify mode if validate_ssl_cert is on" do
78
+ subject.accessor.validate_ssl_cert = true
79
+ subject.accessor.ca_file = 'some_ca_file'
80
+
81
+ Net::HTTP.any_instance.expects(:use_ssl=).with(true)
82
+ Net::HTTP.any_instance.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT)
83
+ Net::HTTP.any_instance.expects(:ca_file=).with('some_ca_file')
84
+
85
+ Timeout.expects(:timeout).yields
86
+ Net::HTTP.any_instance.stubs(:request).returns(stub_everything(:kind_of? => true))
87
+
88
+ subject.get(:url => some_https_url)
89
+ end
90
+
91
+ it "uses VERIFY_NONE to enforce certificate validation" do
92
+ subject.accessor.validate_ssl_cert = false
93
+ subject.accessor.ca_file = 'some_ca_file'
94
+
95
+ Net::HTTP.any_instance.expects(:use_ssl=).with(true)
96
+ Net::HTTP.any_instance.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
97
+ Net::HTTP.any_instance.expects(:ca_file=).with('some_ca_file').never
98
+
99
+ Timeout.expects(:timeout).yields
100
+ Net::HTTP.any_instance.stubs(:request).returns(stub_everything(:kind_of? => true))
101
+
102
+ subject.get(:url => some_https_url)
103
+ end
104
+
105
+ it "logs error and raises exception if response is bad" do
106
+ Timeout.expects(:timeout).yields
107
+ Net::HTTP.any_instance.expects(:request).returns(simple_response)
108
+
109
+ subject.stubs(:bad_response? => true)
110
+
111
+ subject.logger.expects(:error)
112
+
113
+ expect do
114
+ subject.soap_post(:url => some_https_url, :body => 'body')
115
+ end.to raise_error(GatewayError)
116
+ end
117
+
118
+ it "should set content type to text/xml for soap post request" do
119
+ Net::HTTP.any_instance.expects(:request).returns(simple_response)
120
+
121
+ Timeout.expects(:timeout).yields
122
+
123
+ params = {:url => some_https_url}
124
+ headers = {}
125
+
126
+ subject.soap_post(params, headers)
127
+
128
+ headers["Content-Type"].should match "text/xml"
129
+ end
130
+
131
+ it "should set content type to application/x-www-form-urlencoded for regular post request" do
132
+ post_request = Net::HTTP::Post.new 'someurl.com'
133
+ Net::HTTP::Post.expects(:new).returns(post_request)
134
+
135
+ Net::HTTP.any_instance.expects(:request => simple_response)
136
+
137
+ Timeout.expects(:timeout).yields
138
+
139
+ params = {:url => some_https_url}
140
+ headers = {}
141
+
142
+ subject.post(params, headers)
143
+
144
+ headers["Content-Type"].should match "application/x-www-form-urlencoded"
145
+ end
146
+
147
+ it "should log timeout errors and raise GatewayError" do
148
+ subject.logger.expects(:error).with("#{subject.class.name} received error: Timeout::Error")
149
+ Net::HTTP.any_instance.expects(:request).raises(Timeout::Error.new(nil))
150
+
151
+ Timeout.expects(:timeout).yields
152
+
153
+ expect do
154
+ subject.soap_post(:url => some_https_url, :body => 'body')
155
+ end.to raise_error(GatewayError)
156
+ end
157
+
158
+ it "logs SocketError and raises GatewayError when service not found" do
159
+ subject.logger.expects(:error).with("#{subject.class.name} received error: SocketError")
160
+
161
+ Net::HTTP.any_instance.expects(:request).raises(SocketError)
162
+ Timeout.expects(:timeout).yields
163
+
164
+ expect do
165
+ subject.get(:url => some_https_url, :body => '')
166
+ end.to raise_error(GatewayError)
167
+ end
168
+
169
+ it "logs Errno::ECONNRESET and raises GatewayError when service connection reset" do
170
+ subject.logger.expects(:error).with("#{subject.class.name} received error: Connection reset by peer")
171
+
172
+ Net::HTTP.any_instance.expects(:request).raises(Errno::ECONNRESET)
173
+ Timeout.expects(:timeout).yields
174
+
175
+ expect do
176
+ subject.get(:url => some_https_url, :body => '')
177
+ end.to raise_error(GatewayError)
178
+ end
179
+
180
+ it "logs body of request" do
181
+ Net::HTTP.any_instance.expects(:request).returns(simple_response)
182
+
183
+ subject.logger.expects(:debug).with('some_request')
184
+
185
+ subject.soap_post(:url => some_https_url, :body => 'some_request')
186
+ end
187
+
188
+ end
@@ -1,6 +1,6 @@
1
1
  require_relative 'spec_helper'
2
2
 
3
- require 'resource_accessor/resource_accessor'
3
+ require 'resource_accessor'
4
4
 
5
5
  describe ResourceAccessor do
6
6
 
@@ -10,5 +10,13 @@ describe ResourceAccessor do
10
10
  response.should_not be_nil
11
11
  end
12
12
 
13
+ it "query_string_from_hash escapes ampersands and spaces in values" do
14
+ subject.query_from_hash({'name1' => "name 1", 'name2' => "name 2"}).should eql "name1=name+1&name2=name+2"
15
+ end
16
+
17
+ it "query_string_from_hash maps properly nil values " do
18
+ subject.query_from_hash({'param1' => nil, 'param2' => "A&B", 'param3' => "C & D"}).should eql "param1=&param2=A%26B&param3=C+%26+D"
19
+ end
20
+
13
21
  end
14
22
 
@@ -3,4 +3,13 @@ require 'rspec'
3
3
  # add lib directory
4
4
  $:.unshift File.dirname(__FILE__) + '/../lib'
5
5
 
6
+ RSpec.configure do |config|
7
+ # ## Mock Framework
8
+ #
9
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
10
+
11
+ config.mock_with :mocha
12
+ end
13
+
14
+
6
15
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resource_accessor
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
  - Alexander Shvets
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-08-24 00:00:00.000000000 Z
11
+ date: 2013-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gemspec_deps_gen
@@ -61,6 +61,7 @@ files:
61
61
  - lib/resource_accessor/version.rb
62
62
  - resource_accessor.gemspec
63
63
  - resource_accessor.gemspec.erb
64
+ - spec/gateway_spec.rb
64
65
  - spec/resource_accessor_spec.rb
65
66
  - spec/spec_helper.rb
66
67
  homepage: http://github.com/shvets/resource_accessor
@@ -83,11 +84,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
84
  version: '0'
84
85
  requirements: []
85
86
  rubyforge_project:
86
- rubygems_version: 2.0.3
87
+ rubygems_version: 2.0.5
87
88
  signing_key:
88
89
  specification_version: 4
89
90
  summary: This library is used to simplify access to protected or unprotected http
90
91
  resource
91
92
  test_files:
93
+ - spec/gateway_spec.rb
92
94
  - spec/resource_accessor_spec.rb
93
95
  - spec/spec_helper.rb