http_wrapper 2.1.1 → 3.0.0
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 +5 -5
- data/CHANGELOG.md +7 -0
- data/Gemfile +3 -1
- data/README.md +6 -10
- data/Rakefile +3 -7
- data/lib/http_wrapper/constants.rb +15 -16
- data/lib/http_wrapper/errors.rb +6 -4
- data/lib/http_wrapper/http_wrapper.rb +11 -9
- data/lib/http_wrapper/request.rb +28 -26
- data/lib/http_wrapper/{utils.rb → util.rb} +7 -5
- data/lib/http_wrapper/version.rb +4 -2
- data/lib/http_wrapper.rb +4 -2
- data/spec/http_wrapper_spec.rb +135 -137
- data/spec/spec_helper.rb +16 -9
- metadata +68 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6b8cafac3f93ee092cd47ba4c265369937d998919ac06172436764ec448bbe9a
|
4
|
+
data.tar.gz: 49bf3caf2c4791f3af3ed9b360f014ff674816687acc18c60cc53194eac85bd3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81ad733418da9109bd1a38891325797b278572e5c889d05bbcc20239f6a33d03f72986ac4cd1c0ab7cf23dd5edc7ac3495f79f81721c04f77722b20a48d0c512
|
7
|
+
data.tar.gz: 145bb14e27b4725019b7289c8577b71b4c21eb770a41e9608ad7bfae6eb2b2a62dfe88c1b657047d18f2b6442210501e0be8279930d9b404efd753dc2b2048ee
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v3.0.0
|
4
|
+
|
5
|
+
* dropped support for Ruby 1.9-2.2 and Rubinius
|
6
|
+
* rubocop and rubocop-spec gems added for better code quality
|
7
|
+
* simplecov gem added to track test coverage
|
8
|
+
* code refactoring due to all the changes above
|
9
|
+
|
3
10
|
## v2.1.1
|
4
11
|
|
5
12
|
* code refactoring
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,11 +2,10 @@
|
|
2
2
|
|
3
3
|
Simple wrapper around standard Net::HTTP library
|
4
4
|
|
5
|
-
[](https://coveralls.io/r/svyatov/http_wrapper)
|
5
|
+
[](https://badge.fury.io/rb/http_wrapper)
|
6
|
+
[](https://travis-ci.org/svyatov/http_wrapper)
|
7
|
+
[](https://codeclimate.com/github/svyatov/http_wrapper/maintainability)
|
8
|
+
[](https://codeclimate.com/github/svyatov/http_wrapper/test_coverage)
|
10
9
|
|
11
10
|
---
|
12
11
|
|
@@ -15,7 +14,7 @@ Simple wrapper around standard Net::HTTP library
|
|
15
14
|
Add this line to your Gemfile:
|
16
15
|
|
17
16
|
```ruby
|
18
|
-
gem 'http_wrapper', '~>
|
17
|
+
gem 'http_wrapper', '~> 3.0'
|
19
18
|
```
|
20
19
|
|
21
20
|
And then execute:
|
@@ -245,10 +244,7 @@ http.get sample_url, headers: { user_agent: 'custom user agent' }
|
|
245
244
|
```ruby
|
246
245
|
uri = URI 'http://example.com'
|
247
246
|
|
248
|
-
# Ruby 2.0.0
|
249
247
|
request = Net::HTTP::Head.new uri
|
250
|
-
# Ruby 1.9.3
|
251
|
-
request = Net::HTTP::Head.new uri.request_uri
|
252
248
|
|
253
249
|
http.execute request, uri
|
254
250
|
```
|
@@ -320,4 +316,4 @@ If any unknown options or parameters found, it raises the `UnknownKeyError` exce
|
|
320
316
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
321
317
|
3. Commit your changes (`git commit -am 'Added some feature'`)
|
322
318
|
4. Push to the branch (`git push origin my-new-feature`)
|
323
|
-
5. Create new Pull Request
|
319
|
+
5. Create new Pull Request
|
data/Rakefile
CHANGED
@@ -1,12 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'bundler/gem_tasks'
|
4
4
|
require 'rspec/core/rake_task'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
RSpec::Core::RakeTask.new do |task|
|
9
|
-
task.pattern = 'spec/**/*_spec.rb'
|
10
|
-
task.verbose = false
|
11
|
-
end
|
6
|
+
RSpec::Core::RakeTask.new(:spec)
|
12
7
|
|
8
|
+
task default: :spec
|
@@ -1,20 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class HTTPWrapper
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
USER_AGENT = "HTTPWrapper/#{HTTPWrapper::VERSION}; Ruby/#{RUBY_VERSION}"
|
5
|
+
|
6
|
+
CONTENT_TYPE_HEADER_NAME = 'content-type'
|
7
|
+
USER_AGENT_HEADER_NAME = 'user-agent'
|
8
|
+
COOKIE_HEADER_NAME = 'cookie'
|
9
|
+
AJAX_HEADER_NAME = 'x-requested-with'
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
MULTIPART = 'multipart/form-data'.freeze
|
14
|
-
end
|
11
|
+
DEFAULT_CONTENT_TYPE = 'text/html; charset=UTF-8'
|
12
|
+
JSON_CONTENT_TYPE = 'application/json; charset=UTF-8'
|
13
|
+
POST_CONTENT_TYPE = 'application/x-www-form-urlencoded'
|
14
|
+
MULTIPART_CONTENT_TYPE = 'multipart/form-data'
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
JSON_HEADER = { HEADER::CONTENT_TYPE => CONTENT_TYPE::JSON }.freeze
|
16
|
+
AJAX_HEADER = { AJAX_HEADER_NAME => 'XMLHttpRequest' }.freeze
|
17
|
+
JSON_HEADER = { CONTENT_TYPE_HEADER_NAME => JSON_CONTENT_TYPE }.freeze
|
19
18
|
AJAX_JSON_HEADER = AJAX_HEADER.dup.merge!(JSON_HEADER).freeze
|
20
|
-
end
|
19
|
+
end
|
data/lib/http_wrapper/errors.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class HTTPWrapper
|
2
|
-
|
3
|
-
TooManyRedirectsError = Class.new
|
4
|
-
UnknownKeyError
|
5
|
-
end
|
4
|
+
Error = Class.new StandardError
|
5
|
+
TooManyRedirectsError = Class.new Error
|
6
|
+
UnknownKeyError = Class.new Error
|
7
|
+
end
|
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'net/https'
|
2
4
|
|
3
5
|
class HTTPWrapper
|
4
|
-
KNOWN_OPTIONS_KEYS = [
|
6
|
+
KNOWN_OPTIONS_KEYS = %i[timeout verify_cert logger max_redirects user_agent].freeze
|
5
7
|
|
6
8
|
attr_accessor :timeout, :verify_cert, :logger, :max_redirects, :user_agent
|
7
9
|
|
8
10
|
def initialize(options = {})
|
9
|
-
|
11
|
+
Util.validate_hash_keys options, KNOWN_OPTIONS_KEYS
|
10
12
|
|
11
13
|
@timeout = options.fetch(:timeout) { 10 }
|
12
14
|
@verify_cert = options.fetch(:verify_cert) { true }
|
@@ -15,7 +17,7 @@ class HTTPWrapper
|
|
15
17
|
@user_agent = options.fetch(:user_agent) { USER_AGENT }
|
16
18
|
end
|
17
19
|
|
18
|
-
[
|
20
|
+
%i[get post put delete].each do |method_as_symbol|
|
19
21
|
define_method method_as_symbol do |url, params = {}|
|
20
22
|
params[:user_agent] ||= @user_agent
|
21
23
|
get_response Request.new(url, method_as_symbol, params)
|
@@ -23,9 +25,9 @@ class HTTPWrapper
|
|
23
25
|
|
24
26
|
method_as_string = method_as_symbol.to_s
|
25
27
|
|
26
|
-
%w
|
28
|
+
%w[ajax json ajax_json].each do |request_type|
|
27
29
|
define_method "#{method_as_string}_#{request_type}" do |url, params = {}|
|
28
|
-
(params[:headers] ||= {}).merge!(headers_specific_for
|
30
|
+
(params[:headers] ||= {}).merge!(headers_specific_for(request_type))
|
29
31
|
public_send method_as_symbol, url, params
|
30
32
|
end
|
31
33
|
end
|
@@ -46,11 +48,11 @@ class HTTPWrapper
|
|
46
48
|
private
|
47
49
|
|
48
50
|
def get_response(request, redirects_limit = @max_redirects)
|
49
|
-
raise TooManyRedirectsError
|
51
|
+
raise TooManyRedirectsError, 'Too many redirects!' if redirects_limit == 0
|
50
52
|
|
51
53
|
response = execute request.create, request.uri
|
52
54
|
|
53
|
-
if response.
|
55
|
+
if response.is_a? Net::HTTPRedirection
|
54
56
|
request.uri = response['location']
|
55
57
|
response = get_response request, redirects_limit - 1
|
56
58
|
end
|
@@ -67,7 +69,7 @@ class HTTPWrapper
|
|
67
69
|
connection.read_timeout = @timeout
|
68
70
|
connection.open_timeout = @timeout
|
69
71
|
|
70
|
-
if uri.
|
72
|
+
if uri.is_a? URI::HTTPS
|
71
73
|
connection.use_ssl = true
|
72
74
|
connection.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @verify_cert
|
73
75
|
end
|
@@ -75,4 +77,4 @@ class HTTPWrapper
|
|
75
77
|
connection.set_debug_output(@logger)
|
76
78
|
connection
|
77
79
|
end
|
78
|
-
end
|
80
|
+
end
|
data/lib/http_wrapper/request.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'uri/common'
|
2
4
|
|
3
5
|
class HTTPWrapper
|
4
6
|
class Request
|
5
|
-
KNOWN_PARAMS_KEYS = [
|
7
|
+
KNOWN_PARAMS_KEYS = %i[headers query cookie auth body user_agent content_type multipart].freeze
|
6
8
|
|
7
|
-
def initialize(url, method, params = {})
|
8
|
-
|
9
|
+
def initialize(url, method, params = {}) # rubocop:disable Metrics/AbcSize
|
10
|
+
Util.validate_hash_keys params, KNOWN_PARAMS_KEYS
|
9
11
|
|
10
12
|
self.uri = url
|
11
13
|
|
@@ -30,7 +32,7 @@ class HTTPWrapper
|
|
30
32
|
attr_reader :uri
|
31
33
|
|
32
34
|
def uri=(url)
|
33
|
-
url = "http://#{url}" unless url =~
|
35
|
+
url = "http://#{url}" unless url =~ %r{\Ahttps?://}
|
34
36
|
@uri = URI.parse url
|
35
37
|
end
|
36
38
|
|
@@ -43,16 +45,14 @@ class HTTPWrapper
|
|
43
45
|
|
44
46
|
def normalize_headers(headers)
|
45
47
|
normal_headers = {}
|
46
|
-
|
47
|
-
|
48
|
-
normal_headers[normalize_header header] = value
|
49
|
-
end
|
48
|
+
headers&.each do |header, value|
|
49
|
+
normal_headers[normalize_header header] = value
|
50
50
|
end
|
51
51
|
normal_headers
|
52
52
|
end
|
53
53
|
|
54
54
|
def normalize_header(header)
|
55
|
-
header = header.to_s.
|
55
|
+
header = header.to_s.tr('_', '-') if header.is_a? Symbol
|
56
56
|
header.downcase
|
57
57
|
end
|
58
58
|
|
@@ -62,28 +62,27 @@ class HTTPWrapper
|
|
62
62
|
|
63
63
|
def default_content_type_for(method)
|
64
64
|
case method
|
65
|
-
|
66
|
-
|
65
|
+
when :post, :put then POST_CONTENT_TYPE
|
66
|
+
else DEFAULT_CONTENT_TYPE
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
70
|
def initialize_headers
|
71
|
-
@headers[
|
72
|
-
@headers[
|
73
|
-
@headers[
|
71
|
+
@headers[USER_AGENT_HEADER_NAME] ||= @user_agent
|
72
|
+
@headers[CONTENT_TYPE_HEADER_NAME] ||= @content_type
|
73
|
+
@headers[COOKIE_HEADER_NAME] ||= @cookie if @cookie
|
74
74
|
end
|
75
75
|
|
76
76
|
def merge_uri_query
|
77
|
-
return
|
78
|
-
|
77
|
+
return if @query.empty?
|
78
|
+
|
79
|
+
original_query = @uri.query ? Util.query_to_hash(@uri.query) : {}
|
79
80
|
merged_query = original_query.merge @query
|
80
|
-
@uri.query =
|
81
|
+
@uri.query = Util.hash_to_query merged_query
|
81
82
|
end
|
82
83
|
|
83
84
|
def create_method_specific_request
|
84
|
-
|
85
|
-
uri = RUBY_VERSION =~ /\A2/ ? @uri : @uri.request_uri
|
86
|
-
@request = @method.new uri, @headers
|
85
|
+
@request = @method.new @uri, @headers
|
87
86
|
set_body
|
88
87
|
set_basic_auth
|
89
88
|
@request
|
@@ -91,6 +90,7 @@ class HTTPWrapper
|
|
91
90
|
|
92
91
|
def set_body
|
93
92
|
return unless @request.request_body_permitted?
|
93
|
+
|
94
94
|
if @multipart_data
|
95
95
|
set_body_from_multipart_data
|
96
96
|
else
|
@@ -100,22 +100,24 @@ class HTTPWrapper
|
|
100
100
|
|
101
101
|
def set_body_from_multipart_data
|
102
102
|
convert_body_data_to_multipart_data if @body_data
|
103
|
-
@request.set_form @multipart_data,
|
103
|
+
@request.set_form @multipart_data, MULTIPART_CONTENT_TYPE
|
104
104
|
end
|
105
105
|
|
106
106
|
def convert_body_data_to_multipart_data
|
107
|
-
@body_data =
|
108
|
-
@body_data.each{|key, value| @multipart_data << [key.to_s, value.to_s]}
|
107
|
+
@body_data = Util.query_to_hash(@body_data) unless @body_data.is_a? Hash
|
108
|
+
@body_data.each { |key, value| @multipart_data << [key.to_s, value.to_s] }
|
109
109
|
end
|
110
110
|
|
111
111
|
def set_body_from_body_data
|
112
112
|
return unless @body_data
|
113
|
-
|
113
|
+
|
114
|
+
@request.body = @body_data.is_a?(Hash) ? Util.hash_to_query(@body_data) : @body_data
|
114
115
|
end
|
115
116
|
|
116
117
|
def set_basic_auth
|
117
|
-
return unless @login
|
118
|
+
return unless @login && @password
|
119
|
+
|
118
120
|
@request.basic_auth @login, @password
|
119
121
|
end
|
120
122
|
end
|
121
|
-
end
|
123
|
+
end
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class HTTPWrapper
|
2
|
-
module
|
4
|
+
module Util
|
3
5
|
def self.validate_hash_keys(hash_to_check, known_keys_array)
|
4
6
|
unknown_keys = hash_to_check.keys - known_keys_array
|
5
|
-
if unknown_keys.
|
6
|
-
|
7
|
-
|
7
|
+
return if unknown_keys.empty?
|
8
|
+
|
9
|
+
raise UnknownKeyError, "Unknown keys: #{unknown_keys.join(', ')}"
|
8
10
|
end
|
9
11
|
|
10
12
|
def self.query_to_hash(query)
|
@@ -15,4 +17,4 @@ class HTTPWrapper
|
|
15
17
|
URI.encode_www_form hash
|
16
18
|
end
|
17
19
|
end
|
18
|
-
end
|
20
|
+
end
|
data/lib/http_wrapper/version.rb
CHANGED
data/lib/http_wrapper.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'http_wrapper/version'
|
2
4
|
require 'http_wrapper/constants'
|
3
5
|
require 'http_wrapper/errors'
|
4
|
-
require 'http_wrapper/
|
6
|
+
require 'http_wrapper/util'
|
5
7
|
require 'http_wrapper/request'
|
6
|
-
require 'http_wrapper/http_wrapper'
|
8
|
+
require 'http_wrapper/http_wrapper'
|
data/spec/http_wrapper_spec.rb
CHANGED
@@ -1,271 +1,269 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'spec_helper'
|
2
4
|
|
3
5
|
require 'http_wrapper'
|
4
6
|
|
5
|
-
describe HTTPWrapper do
|
7
|
+
RSpec.describe HTTPWrapper do
|
8
|
+
subject(:http) { described_class.new }
|
9
|
+
|
6
10
|
let(:basic_auth_login) { 'balogin' }
|
7
11
|
let(:basic_auth_password) { 'bapassword' }
|
8
12
|
|
9
|
-
it '
|
10
|
-
[
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
it 'defines all dynamic methods' do
|
14
|
+
%i[get post put delete
|
15
|
+
get_json post_json put_json delete_json
|
16
|
+
get_ajax post_ajax put_ajax delete_ajax
|
17
|
+
get_ajax_json post_ajax_json put_ajax_json delete_ajax_json
|
18
|
+
get_json_ajax post_json_ajax put_json_ajax delete_json_ajax].each do |method|
|
19
|
+
expect(http).to respond_to method
|
16
20
|
end
|
17
21
|
end
|
18
22
|
|
19
|
-
|
23
|
+
describe 'HTTP' do
|
20
24
|
let(:sample_url) { 'http://example.com' }
|
21
|
-
let(:sample_url_with_basic_auth) { "http://#{basic_auth_login}:#{basic_auth_password}@example.com" }
|
22
25
|
|
23
|
-
|
24
|
-
it '
|
26
|
+
describe 'Options' do
|
27
|
+
it 'raises UnknownParameterError if initial options key is unknown' do
|
25
28
|
expect do
|
26
|
-
|
29
|
+
described_class.new unknown_option: 'test', maybe_this_known: '?'
|
27
30
|
end.to raise_error HTTPWrapper::UnknownKeyError, 'Unknown keys: unknown_option, maybe_this_known'
|
28
31
|
end
|
29
32
|
|
30
|
-
it '
|
33
|
+
it 'raises UnknownParameterError if params key is unknown' do
|
31
34
|
expect do
|
32
|
-
|
35
|
+
http.get sample_url, unknown_param_key: 'test', another_param_key: 'wow'
|
33
36
|
end.to raise_error HTTPWrapper::UnknownKeyError, 'Unknown keys: unknown_param_key, another_param_key'
|
34
37
|
end
|
35
38
|
|
36
|
-
it '
|
39
|
+
it 'follows redirects no more then 10 times by default' do
|
37
40
|
stub_redirects sample_url, 9
|
38
|
-
response =
|
39
|
-
response.code.
|
41
|
+
response = http.get sample_url
|
42
|
+
expect(response.code).to eq '200'
|
40
43
|
|
41
44
|
stub_redirects sample_url, 10
|
42
|
-
expect {
|
45
|
+
expect { http.get sample_url }.to raise_error HTTPWrapper::TooManyRedirectsError, 'Too many redirects!'
|
43
46
|
end
|
44
47
|
|
45
|
-
it '
|
46
|
-
|
48
|
+
it 'follows redirects no more times then specified' do
|
49
|
+
http.max_redirects = 5
|
47
50
|
|
48
51
|
stub_redirects sample_url, 4
|
49
|
-
response =
|
50
|
-
response.code.
|
52
|
+
response = http.get sample_url
|
53
|
+
expect(response.code).to eq '200'
|
51
54
|
|
52
55
|
stub_redirects sample_url, 5
|
53
|
-
expect {
|
56
|
+
expect { http.get sample_url }.to raise_error HTTPWrapper::TooManyRedirectsError, 'Too many redirects!'
|
54
57
|
end
|
55
58
|
|
56
|
-
it '
|
59
|
+
it 'uses logger' do
|
57
60
|
require 'logger'
|
58
61
|
logger = Logger.new StringIO.new
|
59
|
-
logger.
|
60
|
-
|
62
|
+
allow(logger).to receive(:<<)
|
63
|
+
http.logger = logger
|
61
64
|
|
62
65
|
WebMock.allow_net_connect!
|
63
66
|
begin
|
64
|
-
|
65
|
-
rescue
|
67
|
+
http.get 'localhost'
|
68
|
+
rescue StandardError # rubocop:disable Lint/HandleExceptions
|
66
69
|
# NOOP, rescue from "connection refused" and such
|
67
70
|
end
|
68
71
|
WebMock.disable_net_connect!
|
72
|
+
|
73
|
+
expect(logger).to have_received(:<<).at_least(:once)
|
69
74
|
end
|
70
75
|
end
|
71
76
|
|
72
|
-
|
73
|
-
it '
|
77
|
+
describe 'GET' do
|
78
|
+
it 'adds http uri scheme if missing' do
|
74
79
|
stub_get sample_url
|
75
|
-
|
80
|
+
http.get sample_url.gsub(%r{\Ahttp://}, '')
|
76
81
|
end
|
77
82
|
|
78
|
-
it '
|
79
|
-
params = { headers: {HTTPWrapper::
|
83
|
+
it 'hits provided url with default content type' do
|
84
|
+
params = { headers: { HTTPWrapper::CONTENT_TYPE_HEADER_NAME => HTTPWrapper::DEFAULT_CONTENT_TYPE } }
|
80
85
|
stub_get sample_url, params
|
81
|
-
|
86
|
+
http.get sample_url
|
82
87
|
end
|
83
88
|
|
84
|
-
it '
|
85
|
-
params = { headers: {HTTPWrapper::
|
89
|
+
it 'sets content type if provided' do
|
90
|
+
params = { headers: { HTTPWrapper::CONTENT_TYPE_HEADER_NAME => 'Custom Content Type' } }
|
86
91
|
stub_get sample_url, params
|
87
|
-
|
88
|
-
|
89
|
-
|
92
|
+
http.get sample_url, params
|
93
|
+
http.get sample_url, content_type: 'Custom Content Type'
|
94
|
+
http.get sample_url, params.merge(content_type: 'Should Be Overwritten')
|
90
95
|
end
|
91
96
|
|
92
|
-
it '
|
97
|
+
it 'sets proper header for JSON requests' do
|
93
98
|
params = { headers: HTTPWrapper::JSON_HEADER }
|
94
99
|
stub_get sample_url, params
|
95
|
-
|
100
|
+
http.get_json sample_url
|
96
101
|
end
|
97
102
|
|
98
|
-
it '
|
103
|
+
it 'sets proper header for AJAX requests' do
|
99
104
|
params = {
|
100
105
|
headers: {
|
101
|
-
HTTPWrapper::
|
106
|
+
HTTPWrapper::CONTENT_TYPE_HEADER_NAME => HTTPWrapper::DEFAULT_CONTENT_TYPE
|
102
107
|
}.merge(HTTPWrapper::AJAX_HEADER)
|
103
108
|
}
|
104
109
|
stub_get sample_url, params
|
105
|
-
|
110
|
+
http.get_ajax sample_url
|
106
111
|
end
|
107
112
|
|
108
|
-
it '
|
113
|
+
it 'sets proper headers for AJAX-JSON requests' do
|
109
114
|
params = { headers: HTTPWrapper::AJAX_JSON_HEADER }
|
110
115
|
stub_get sample_url, params
|
111
|
-
|
116
|
+
http.get_ajax_json sample_url
|
112
117
|
end
|
113
118
|
|
114
|
-
it '
|
115
|
-
stub_get sample_url
|
116
|
-
|
119
|
+
it 'correctlies escape query parameters' do
|
120
|
+
stub_get "#{sample_url}/?param1=¶m2=A%26B¶m3=C%20%26%20D"
|
121
|
+
http.get sample_url, query: { param1: '', param2: 'A&B', param3: 'C & D' }
|
117
122
|
end
|
118
123
|
|
119
|
-
it '
|
120
|
-
params = { headers: {HTTPWrapper::
|
124
|
+
it 'sets default user agent' do
|
125
|
+
params = { headers: { HTTPWrapper::USER_AGENT_HEADER_NAME => HTTPWrapper::USER_AGENT } }
|
121
126
|
stub_get sample_url, params
|
122
|
-
|
127
|
+
http.get sample_url
|
123
128
|
end
|
124
129
|
|
125
|
-
it '
|
130
|
+
it 'changes user agent if provided' do
|
126
131
|
custom_user_agent = 'Mozilla v1.2.3'
|
127
|
-
params = { headers: {HTTPWrapper::
|
132
|
+
params = { headers: { HTTPWrapper::USER_AGENT_HEADER_NAME => custom_user_agent } }
|
128
133
|
stub_get sample_url, params
|
129
|
-
|
134
|
+
http.get sample_url, params
|
130
135
|
|
131
|
-
|
136
|
+
http.get sample_url, user_agent: custom_user_agent
|
132
137
|
|
133
|
-
|
134
|
-
|
138
|
+
http.user_agent = custom_user_agent
|
139
|
+
http.get sample_url
|
135
140
|
|
136
141
|
expect do
|
137
|
-
|
142
|
+
http.get sample_url, user_agent: 'abracadabra'
|
138
143
|
end.to raise_error WebMock::NetConnectNotAllowedError
|
139
144
|
|
140
145
|
expect do
|
141
|
-
|
142
|
-
|
146
|
+
http.user_agent = 'another test'
|
147
|
+
http.get sample_url
|
143
148
|
end.to raise_error WebMock::NetConnectNotAllowedError
|
144
149
|
end
|
145
150
|
|
146
|
-
it '
|
147
|
-
params = { headers: {HTTPWrapper::
|
151
|
+
it 'precedences header user agent before params' do
|
152
|
+
params = { headers: { HTTPWrapper::USER_AGENT_HEADER_NAME => 'TestUserAgent' } }
|
148
153
|
stub_get sample_url, params
|
149
154
|
|
150
|
-
|
151
|
-
|
155
|
+
http.user_agent = 'Should Be Overwritten'
|
156
|
+
http.get sample_url, params
|
152
157
|
end
|
153
158
|
|
154
|
-
it '
|
159
|
+
it 'sends cookie if provided' do
|
155
160
|
cookie_value = 'some cookie'
|
156
|
-
params = { headers: {'Cookie' => cookie_value} }
|
161
|
+
params = { headers: { 'Cookie' => cookie_value } }
|
157
162
|
stub_get sample_url, params
|
158
|
-
|
159
|
-
|
163
|
+
http.get sample_url, cookie: cookie_value
|
164
|
+
http.get sample_url, params
|
160
165
|
end
|
161
166
|
|
162
|
-
it '
|
163
|
-
params = { headers: {'Cookie' => 'Custom cookie'} }
|
167
|
+
it 'uses headers cookie if both (headers and parameters) cookies provided' do
|
168
|
+
params = { headers: { 'Cookie' => 'Custom cookie' } }
|
164
169
|
stub_get sample_url, params
|
165
|
-
|
170
|
+
http.get sample_url, params.merge(cookie: 'should not use this one')
|
166
171
|
end
|
167
172
|
|
168
|
-
it '
|
169
|
-
|
170
|
-
|
173
|
+
it 'hits provided url with basic auth' do
|
174
|
+
stub_request(:get, sample_url).with(basic_auth: [basic_auth_login, basic_auth_password])
|
175
|
+
http.get sample_url, auth: { login: basic_auth_login, password: basic_auth_password }
|
171
176
|
end
|
172
177
|
|
173
|
-
it '
|
174
|
-
stub_get sample_url
|
175
|
-
|
178
|
+
it 'merges query parameters and params should take precedence' do
|
179
|
+
stub_get "#{sample_url}/?text=edf&time=16:44&user=test"
|
180
|
+
http.get "#{sample_url}/?user=test&text=abc", query: { time: '16:44', text: 'edf' }
|
176
181
|
end
|
177
182
|
|
178
|
-
it '
|
183
|
+
it 'equallies treat header as string and header as symbol' do
|
179
184
|
custom_content_type = 'Some Content Type'
|
180
|
-
stub_get sample_url,
|
181
|
-
|
185
|
+
stub_get sample_url, headers: { 'Content-Type' => custom_content_type }
|
186
|
+
http.get sample_url, headers: { content_type: custom_content_type }
|
182
187
|
end
|
183
188
|
end
|
184
189
|
|
185
|
-
|
186
|
-
it '
|
187
|
-
params = { headers: {HTTPWrapper::
|
190
|
+
describe 'POST' do
|
191
|
+
it 'sets content type if provided' do
|
192
|
+
params = { headers: { HTTPWrapper::CONTENT_TYPE_HEADER_NAME => 'Custom Content Type' } }
|
188
193
|
stub_post sample_url, params
|
189
|
-
|
194
|
+
http.post sample_url, params
|
190
195
|
end
|
191
196
|
|
192
|
-
it '
|
197
|
+
it 'returns cookies after post' do
|
193
198
|
cookie_value = 'some cookie'
|
194
|
-
params = { body: {username: 'test', password: 'test'} }
|
195
|
-
stub_post(sample_url, params).to_return(
|
196
|
-
cookie =
|
197
|
-
cookie.
|
199
|
+
params = { body: { username: 'test', password: 'test' } }
|
200
|
+
stub_post(sample_url, params).to_return(headers: { 'Set-Cookie' => cookie_value })
|
201
|
+
cookie = http.post_and_get_cookie sample_url, params
|
202
|
+
expect(cookie).to eq cookie_value
|
198
203
|
end
|
199
204
|
|
200
|
-
it '
|
201
|
-
params = { headers: {HTTPWrapper::
|
205
|
+
it 'hits provided url with default content type' do
|
206
|
+
params = { headers: { HTTPWrapper::CONTENT_TYPE_HEADER_NAME => HTTPWrapper::POST_CONTENT_TYPE } }
|
202
207
|
stub_post sample_url, params
|
203
|
-
|
208
|
+
http.post sample_url
|
204
209
|
end
|
205
210
|
|
206
|
-
it '
|
207
|
-
stub_request(:post,
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
211
|
+
it 'sets all possible parameters correctly' do
|
212
|
+
stub_request(:post, "#{sample_url}/?a=b&c=d")
|
213
|
+
.with(
|
214
|
+
body: 'e=f&g=k',
|
215
|
+
headers: {
|
216
|
+
'Content-Type' => 'Custom content type',
|
217
|
+
'User-Agent' => 'Custom user agent',
|
218
|
+
'Cookie' => 'cookie',
|
219
|
+
'X-Requested-With' => 'XMLHttpRequest'
|
220
|
+
},
|
221
|
+
basic_auth: %w[user passw]
|
222
|
+
)
|
223
|
+
|
224
|
+
http.post sample_url,
|
225
|
+
content_type: 'Custom content type',
|
226
|
+
user_agent: 'Custom user agent',
|
227
|
+
headers: { x_requested_with: 'XMLHttpRequest' },
|
228
|
+
query: { a: 'b', c: 'd' },
|
229
|
+
body: { e: 'f', g: 'k' },
|
230
|
+
auth: { login: 'user', password: 'passw' },
|
231
|
+
cookie: 'cookie'
|
226
232
|
end
|
227
233
|
end
|
228
234
|
|
229
|
-
|
230
|
-
it '
|
231
|
-
params = { headers: {HTTPWrapper::
|
235
|
+
describe 'PUT' do
|
236
|
+
it 'hits provided url with default content type' do
|
237
|
+
params = { headers: { HTTPWrapper::CONTENT_TYPE_HEADER_NAME => HTTPWrapper::POST_CONTENT_TYPE } }
|
232
238
|
stub_put sample_url, params
|
233
|
-
|
239
|
+
http.put sample_url
|
234
240
|
end
|
235
241
|
end
|
236
242
|
|
237
|
-
|
238
|
-
it '
|
239
|
-
params = { headers: {HTTPWrapper::
|
243
|
+
describe 'DELETE' do
|
244
|
+
it 'hits provided url with default content type' do
|
245
|
+
params = { headers: { HTTPWrapper::CONTENT_TYPE_HEADER_NAME => HTTPWrapper::DEFAULT_CONTENT_TYPE } }
|
240
246
|
stub_delete sample_url, params
|
241
|
-
|
247
|
+
http.delete sample_url
|
242
248
|
end
|
243
249
|
end
|
244
250
|
|
245
|
-
|
246
|
-
it '
|
251
|
+
describe 'Custom request instance' do
|
252
|
+
it 'performs request for custom Net::HTTP request instance' do
|
247
253
|
stub_request :head, sample_url
|
248
254
|
uri = URI sample_url
|
249
|
-
|
250
|
-
|
251
|
-
request = Net::HTTP::Head.new uri
|
252
|
-
subject.execute request, request.uri
|
253
|
-
else
|
254
|
-
# Ruby v1.9.3 doesn't understand full URI object, it needs just path :(
|
255
|
-
request = Net::HTTP::Head.new uri.request_uri
|
256
|
-
subject.execute request, uri
|
257
|
-
end
|
255
|
+
request = Net::HTTP::Head.new uri
|
256
|
+
http.execute request, request.uri
|
258
257
|
end
|
259
258
|
end
|
260
259
|
end
|
261
260
|
|
262
|
-
|
261
|
+
describe 'HTTPS' do
|
263
262
|
let(:sample_url) { 'https://example.com' }
|
264
263
|
|
265
|
-
it '
|
264
|
+
it 'hits provided url with HTTPS protocol' do
|
266
265
|
stub_get sample_url
|
267
|
-
|
266
|
+
http.get sample_url
|
268
267
|
end
|
269
268
|
end
|
270
269
|
end
|
271
|
-
|
data/spec/spec_helper.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
2
4
|
require 'webmock/rspec'
|
3
5
|
|
4
6
|
if ENV['TRAVIS'] == 'true'
|
5
|
-
require '
|
6
|
-
|
7
|
+
require 'simplecov'
|
8
|
+
SimpleCov.start
|
7
9
|
end
|
8
10
|
|
9
|
-
$LOAD_PATH.unshift File.expand_path('../lib', File.dirname(__FILE__))
|
10
|
-
|
11
11
|
module HTTPWrapperSpecHelpers
|
12
|
-
[
|
13
|
-
define_method("stub_#{type
|
12
|
+
%i[get post put delete].each do |type|
|
13
|
+
define_method("stub_#{type}") do |url, params = nil|
|
14
14
|
if params
|
15
15
|
stub_request(type, url).with(params)
|
16
16
|
else
|
@@ -20,7 +20,7 @@ module HTTPWrapperSpecHelpers
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def stub_redirects(url, amount_of_redirects)
|
23
|
-
stub_get(url).to_return(status: 301, headers: {'Location' => url})
|
23
|
+
stub_get(url).to_return(status: 301, headers: { 'Location' => url })
|
24
24
|
.times(amount_of_redirects)
|
25
25
|
.then
|
26
26
|
.to_return(status: 200)
|
@@ -29,4 +29,11 @@ end
|
|
29
29
|
|
30
30
|
RSpec.configure do |config|
|
31
31
|
config.include HTTPWrapperSpecHelpers
|
32
|
-
|
32
|
+
|
33
|
+
# Disable RSpec exposing methods globally on `Module` and `main`
|
34
|
+
config.disable_monkey_patching!
|
35
|
+
|
36
|
+
config.expect_with :rspec do |c|
|
37
|
+
c.syntax = :expect
|
38
|
+
end
|
39
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: http_wrapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Leonid Svyatov
|
@@ -9,64 +9,106 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2019-02-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- -
|
18
|
+
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: '
|
20
|
+
version: '0'
|
21
21
|
type: :development
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- -
|
25
|
+
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: '
|
27
|
+
version: '0'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: rake
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
|
-
- -
|
32
|
+
- - ">="
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: '
|
34
|
+
version: '0'
|
35
35
|
type: :development
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- -
|
39
|
+
- - ">="
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: '
|
41
|
+
version: '0'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: rspec
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- - ~>
|
46
|
+
- - "~>"
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version:
|
48
|
+
version: '3.7'
|
49
49
|
type: :development
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
|
-
- - ~>
|
53
|
+
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version:
|
55
|
+
version: '3.7'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: rubocop
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 0.63.1
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.63.1
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rubocop-rspec
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '1.32'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '1.32'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: simplecov
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 0.16.1
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: 0.16.1
|
56
98
|
- !ruby/object:Gem::Dependency
|
57
99
|
name: webmock
|
58
100
|
requirement: !ruby/object:Gem::Requirement
|
59
101
|
requirements:
|
60
|
-
- - ~>
|
102
|
+
- - "~>"
|
61
103
|
- !ruby/object:Gem::Version
|
62
|
-
version:
|
104
|
+
version: '3.5'
|
63
105
|
type: :development
|
64
106
|
prerelease: false
|
65
107
|
version_requirements: !ruby/object:Gem::Requirement
|
66
108
|
requirements:
|
67
|
-
- - ~>
|
109
|
+
- - "~>"
|
68
110
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
111
|
+
version: '3.5'
|
70
112
|
description: Simple wrapper around standard Net::HTTP library with multipart/form-data
|
71
113
|
file upload ability
|
72
114
|
email: leonid@svyatov.ru
|
@@ -74,18 +116,18 @@ executables: []
|
|
74
116
|
extensions: []
|
75
117
|
extra_rdoc_files: []
|
76
118
|
files:
|
119
|
+
- CHANGELOG.md
|
77
120
|
- Gemfile
|
78
121
|
- LICENSE
|
79
122
|
- README.md
|
80
|
-
- CHANGELOG.md
|
81
123
|
- Rakefile
|
124
|
+
- lib/http_wrapper.rb
|
82
125
|
- lib/http_wrapper/constants.rb
|
83
126
|
- lib/http_wrapper/errors.rb
|
84
127
|
- lib/http_wrapper/http_wrapper.rb
|
85
128
|
- lib/http_wrapper/request.rb
|
86
|
-
- lib/http_wrapper/
|
129
|
+
- lib/http_wrapper/util.rb
|
87
130
|
- lib/http_wrapper/version.rb
|
88
|
-
- lib/http_wrapper.rb
|
89
131
|
- spec/http_wrapper_spec.rb
|
90
132
|
- spec/spec_helper.rb
|
91
133
|
homepage: http://github.com/svyatov/http_wrapper
|
@@ -98,20 +140,19 @@ require_paths:
|
|
98
140
|
- lib
|
99
141
|
required_ruby_version: !ruby/object:Gem::Requirement
|
100
142
|
requirements:
|
101
|
-
- -
|
143
|
+
- - ">="
|
102
144
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
145
|
+
version: 2.3.0
|
104
146
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
147
|
requirements:
|
106
|
-
- -
|
148
|
+
- - ">="
|
107
149
|
- !ruby/object:Gem::Version
|
108
150
|
version: '0'
|
109
151
|
requirements: []
|
110
|
-
|
111
|
-
rubygems_version: 2.1.4
|
152
|
+
rubygems_version: 3.0.2
|
112
153
|
signing_key:
|
113
154
|
specification_version: 4
|
114
155
|
summary: Simple wrapper around standard Net::HTTP library
|
115
156
|
test_files:
|
116
|
-
- spec/http_wrapper_spec.rb
|
117
157
|
- spec/spec_helper.rb
|
158
|
+
- spec/http_wrapper_spec.rb
|