berkeley_library-util 0.1.5 → 0.1.7
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 +4 -4
- data/.github/workflows/build.yml +17 -5
- data/.idea/inspectionProfiles/Project_Default.xml +1 -0
- data/.idea/util.iml +48 -51
- data/.rubocop.yml +157 -2
- data/.simplecov +5 -6
- data/CHANGES.md +17 -0
- data/Rakefile +2 -2
- data/berkeley_library-util.gemspec +5 -6
- data/lib/berkeley_library/util/arrays.rb +3 -3
- data/lib/berkeley_library/util/files.rb +2 -2
- data/lib/berkeley_library/util/module_info.rb +1 -1
- data/lib/berkeley_library/util/uris/appender.rb +23 -19
- data/lib/berkeley_library/util/uris/requester.rb +97 -42
- data/lib/berkeley_library/util/uris.rb +15 -11
- data/rakelib/.rubocop.yml +4 -0
- data/spec/.rubocop.yml +89 -0
- data/spec/berkeley_library/util/arrays_spec.rb +10 -1
- data/spec/berkeley_library/util/files_spec.rb +1 -0
- data/spec/berkeley_library/util/stringios_spec.rb +7 -0
- data/spec/berkeley_library/util/strings_spec.rb +4 -0
- data/spec/berkeley_library/util/times_spec.rb +4 -0
- data/spec/berkeley_library/util/uris/requester_spec.rb +121 -0
- data/spec/berkeley_library/util/uris_spec.rb +62 -10
- data/spec/spec_helper.rb +2 -2
- metadata +16 -54
- data/rakelib/bundle.rake +0 -8
@@ -6,19 +6,23 @@ require 'berkeley_library/logging'
|
|
6
6
|
module BerkeleyLibrary
|
7
7
|
module Util
|
8
8
|
module URIs
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
class Requester
|
10
|
+
include BerkeleyLibrary::Logging
|
11
|
+
|
12
|
+
# ------------------------------------------------------------
|
13
|
+
# Class methods
|
12
14
|
|
15
|
+
class << self
|
13
16
|
# Performs a GET request and returns the response body as a string.
|
14
17
|
#
|
15
18
|
# @param uri [URI, String] the URI to GET
|
16
19
|
# @param params [Hash] the query parameters to add to the URI. (Note that the URI may already include query parameters.)
|
17
20
|
# @param headers [Hash] the request headers.
|
18
21
|
# @return [String] the body as a string.
|
22
|
+
# @param log [Boolean] whether to log each request URL and response code
|
19
23
|
# @raise [RestClient::Exception] in the event of an unsuccessful request.
|
20
|
-
def get(uri, params: {}, headers: {})
|
21
|
-
resp = make_request(:get, uri, params, headers)
|
24
|
+
def get(uri, params: {}, headers: {}, log: true)
|
25
|
+
resp = make_request(:get, uri, params, headers, log)
|
22
26
|
resp.body
|
23
27
|
end
|
24
28
|
|
@@ -29,9 +33,10 @@ module BerkeleyLibrary
|
|
29
33
|
# @param uri [URI, String] the URI to HEAD
|
30
34
|
# @param params [Hash] the query parameters to add to the URI. (Note that the URI may already include query parameters.)
|
31
35
|
# @param headers [Hash] the request headers.
|
36
|
+
# @param log [Boolean] whether to log each request URL and response code
|
32
37
|
# @return [Integer] the response code as an integer.
|
33
|
-
def head(uri, params: {}, headers: {})
|
34
|
-
head_response(uri, params: params, headers: headers).code
|
38
|
+
def head(uri, params: {}, headers: {}, log: true)
|
39
|
+
head_response(uri, params: params, headers: headers, log: log).code
|
35
40
|
end
|
36
41
|
|
37
42
|
# Performs a GET request and returns the response, even in the event of
|
@@ -40,9 +45,10 @@ module BerkeleyLibrary
|
|
40
45
|
# @param uri [URI, String] the URI to GET
|
41
46
|
# @param params [Hash] the query parameters to add to the URI. (Note that the URI may already include query parameters.)
|
42
47
|
# @param headers [Hash] the request headers.
|
48
|
+
# @param log [Boolean] whether to log each request URL and response code
|
43
49
|
# @return [RestClient::Response] the body as a string.
|
44
|
-
def get_response(uri, params: {}, headers: {})
|
45
|
-
make_request(:get, uri, params, headers)
|
50
|
+
def get_response(uri, params: {}, headers: {}, log: true)
|
51
|
+
make_request(:get, uri, params, headers, log)
|
46
52
|
rescue RestClient::Exception => e
|
47
53
|
e.response
|
48
54
|
end
|
@@ -53,56 +59,105 @@ module BerkeleyLibrary
|
|
53
59
|
# @param uri [URI, String] the URI to HEAD
|
54
60
|
# @param params [Hash] the query parameters to add to the URI. (Note that the URI may already include query parameters.)
|
55
61
|
# @param headers [Hash] the request headers.
|
56
|
-
# @
|
57
|
-
|
58
|
-
|
62
|
+
# @param log [Boolean] whether to log each request URL and response code
|
63
|
+
# @return [RestClient::Response] the response
|
64
|
+
def head_response(uri, params: {}, headers: {}, log: true)
|
65
|
+
make_request(:head, uri, params, headers, log)
|
59
66
|
rescue RestClient::Exception => e
|
60
67
|
e.response
|
61
68
|
end
|
62
69
|
|
63
70
|
private
|
64
71
|
|
65
|
-
|
66
|
-
|
67
|
-
url_str = url_str_with_params(uri, params)
|
68
|
-
req_resp_or_raise(method, url_str, headers)
|
72
|
+
def make_request(method, url, params, headers, log)
|
73
|
+
Requester.new(method, url, params: params, headers: headers, log: log).make_request
|
69
74
|
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# ------------------------------------------------------------
|
78
|
+
# Constants
|
79
|
+
|
80
|
+
SUPPORTED_METHODS = %i[get head].freeze
|
70
81
|
|
71
|
-
|
72
|
-
|
82
|
+
# ------------------------------------------------------------
|
83
|
+
# Attributes
|
73
84
|
|
74
|
-
|
75
|
-
ee << url_str
|
76
|
-
next if params.empty?
|
85
|
+
attr_reader :method, :url_str, :headers, :log
|
77
86
|
|
78
|
-
|
79
|
-
|
80
|
-
end
|
87
|
+
# ------------------------------------------------------------
|
88
|
+
# Initializer
|
81
89
|
|
82
|
-
|
83
|
-
|
90
|
+
# Initializes a new Requester.
|
91
|
+
#
|
92
|
+
# @param method [:get, :head] the HTTP method to use
|
93
|
+
# @param url [String, URI] the URL or URI to request
|
94
|
+
# @param params [Hash] the query parameters to add to the URI. (Note that the URI may already include query parameters.)
|
95
|
+
# @param headers [Hash] the request headers.
|
96
|
+
# @param log [Boolean] whether to log each request URL and response code
|
97
|
+
# @raise URI::InvalidURIError if the specified URL is invalid
|
98
|
+
def initialize(method, url, params: {}, headers: {}, log: true)
|
99
|
+
raise ArgumentError, "#{method} not supported" unless SUPPORTED_METHODS.include?(method)
|
100
|
+
raise ArgumentError, 'url cannot be nil' unless (uri = Validator.uri_or_nil(url))
|
101
|
+
|
102
|
+
@method = method
|
103
|
+
@url_str = url_str_with_params(uri, params)
|
104
|
+
@headers = headers
|
105
|
+
@log = log
|
106
|
+
end
|
107
|
+
|
108
|
+
# ------------------------------------------------------------
|
109
|
+
# Public instance methods
|
110
|
+
|
111
|
+
# @return [RestClient::Response]
|
112
|
+
def make_request
|
113
|
+
execute_request.tap do |resp|
|
114
|
+
log_response(resp)
|
84
115
|
end
|
116
|
+
rescue RestClient::Exception => e
|
117
|
+
log_response(e.response)
|
118
|
+
raise
|
119
|
+
end
|
120
|
+
|
121
|
+
# ------------------------------------------------------------
|
122
|
+
# Private methods
|
85
123
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
124
|
+
private
|
125
|
+
|
126
|
+
def log_response(response)
|
127
|
+
return unless log
|
128
|
+
|
129
|
+
logger.info("#{method.to_s.upcase} #{url_str} returned #{response.code}")
|
130
|
+
end
|
131
|
+
|
132
|
+
def url_str_with_params(uri, params)
|
133
|
+
elements = [uri]
|
134
|
+
if params.any?
|
135
|
+
elements << (uri.query ? '&' : '?')
|
136
|
+
elements << URI.encode_www_form(params)
|
137
|
+
end
|
138
|
+
|
139
|
+
Appender.new(*elements).to_url_str
|
140
|
+
end
|
141
|
+
|
142
|
+
def execute_request
|
143
|
+
RestClient::Request.execute(method: method, url: url_str, headers: headers).tap do |response|
|
144
|
+
# Not all failed RestClient requests throw exceptions
|
145
|
+
raise(exception_for(response)) unless response.code == 200
|
97
146
|
end
|
147
|
+
end
|
98
148
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
149
|
+
def exception_for(resp)
|
150
|
+
status = resp.code
|
151
|
+
ex_class_for(status).new(resp, status).tap do |ex|
|
152
|
+
status_message = RestClient::STATUSES[status] || '(Unknown)'
|
153
|
+
ex.message = "#{status} #{status_message}"
|
104
154
|
end
|
105
155
|
end
|
156
|
+
|
157
|
+
def ex_class_for(status)
|
158
|
+
RestClient::Exceptions::EXCEPTIONS_MAP[status] || RestClient::RequestFailed
|
159
|
+
end
|
160
|
+
|
106
161
|
end
|
107
162
|
end
|
108
163
|
end
|
@@ -31,10 +31,11 @@ module BerkeleyLibrary
|
|
31
31
|
# @param uri [URI, String] the URI to GET
|
32
32
|
# @param params [Hash] the query parameters to add to the URI. (Note that the URI may already include query parameters.)
|
33
33
|
# @param headers [Hash] the request headers.
|
34
|
+
# @param log [Boolean] whether to log each request URL and response code
|
34
35
|
# @return [String] the body as a string.
|
35
36
|
# @raise [RestClient::Exception] in the event of an unsuccessful request.
|
36
|
-
def get(uri, params: {}, headers: {})
|
37
|
-
Requester.get(uri, params: params, headers: headers)
|
37
|
+
def get(uri, params: {}, headers: {}, log: true)
|
38
|
+
Requester.get(uri, params: params, headers: headers, log: log)
|
38
39
|
end
|
39
40
|
|
40
41
|
# Performs a HEAD request and returns the response status as an integer.
|
@@ -44,9 +45,10 @@ module BerkeleyLibrary
|
|
44
45
|
# @param uri [URI, String] the URI to HEAD
|
45
46
|
# @param params [Hash] the query parameters to add to the URI. (Note that the URI may already include query parameters.)
|
46
47
|
# @param headers [Hash] the request headers.
|
48
|
+
# @param log [Boolean] whether to log each request URL and response code
|
47
49
|
# @return [Integer] the response code as an integer.
|
48
|
-
def head(uri, params: {}, headers: {})
|
49
|
-
Requester.head(uri, params: params, headers: headers)
|
50
|
+
def head(uri, params: {}, headers: {}, log: true)
|
51
|
+
Requester.head(uri, params: params, headers: headers, log: log)
|
50
52
|
end
|
51
53
|
|
52
54
|
# Performs a GET request and returns the response, even in the event of
|
@@ -55,9 +57,10 @@ module BerkeleyLibrary
|
|
55
57
|
# @param uri [URI, String] the URI to GET
|
56
58
|
# @param params [Hash] the query parameters to add to the URI. (Note that the URI may already include query parameters.)
|
57
59
|
# @param headers [Hash] the request headers.
|
58
|
-
# @
|
59
|
-
|
60
|
-
|
60
|
+
# @param log [Boolean] whether to log each request URL and response code
|
61
|
+
# @return [RestClient::Response] the response
|
62
|
+
def get_response(uri, params: {}, headers: {}, log: true)
|
63
|
+
Requester.get_response(uri, params: params, headers: headers, log: log)
|
61
64
|
end
|
62
65
|
|
63
66
|
# Performs a HEAD request and returns the response, even in the event of
|
@@ -66,9 +69,10 @@ module BerkeleyLibrary
|
|
66
69
|
# @param uri [URI, String] the URI to HEAD
|
67
70
|
# @param params [Hash] the query parameters to add to the URI. (Note that the URI may already include query parameters.)
|
68
71
|
# @param headers [Hash] the request headers.
|
69
|
-
# @
|
70
|
-
|
71
|
-
|
72
|
+
# @param log [Boolean] whether to log each request URL and response code
|
73
|
+
# @return [RestClient::Response] the response
|
74
|
+
def head_response(uri, params: {}, headers: {}, log: true)
|
75
|
+
Requester.head_response(uri, params: params, headers: headers, log: log)
|
72
76
|
end
|
73
77
|
|
74
78
|
# Returns the specified URL as a URI, or `nil` if the URL is `nil`.
|
@@ -115,7 +119,7 @@ module BerkeleyLibrary
|
|
115
119
|
|
116
120
|
def should_escape?(b, mode)
|
117
121
|
return false if unreserved?(b)
|
118
|
-
return false if ALLOWED_BYTES_BY_MODE[mode]
|
122
|
+
return false if ALLOWED_BYTES_BY_MODE[mode].include?(b)
|
119
123
|
|
120
124
|
true
|
121
125
|
end
|
data/spec/.rubocop.yml
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
inherit_from: ../.rubocop.yml
|
2
2
|
|
3
|
+
require:
|
4
|
+
- rubocop-rspec
|
5
|
+
|
3
6
|
AllCops:
|
4
7
|
# Exclude generated files
|
5
8
|
Exclude:
|
@@ -38,3 +41,89 @@ Metrics/MethodLength:
|
|
38
41
|
# Sometimes we're testing the operator
|
39
42
|
Lint/BinaryOperatorWithIdenticalOperands:
|
40
43
|
Enabled: false
|
44
|
+
|
45
|
+
############################################################
|
46
|
+
# rubocop-rspec
|
47
|
+
|
48
|
+
# believe me, it wasn't by choice
|
49
|
+
RSpec/AnyInstance:
|
50
|
+
Enabled: false
|
51
|
+
|
52
|
+
# we meant to do that
|
53
|
+
RSpec/BeforeAfterAll:
|
54
|
+
Enabled: false
|
55
|
+
|
56
|
+
# more words != more readable
|
57
|
+
RSpec/ContextWording:
|
58
|
+
Enabled: false
|
59
|
+
|
60
|
+
# explicit >>> implicit
|
61
|
+
RSpec/DescribedClass:
|
62
|
+
Enabled: false
|
63
|
+
|
64
|
+
# more punctuation != more readable
|
65
|
+
RSpec/DescribeSymbol:
|
66
|
+
Enabled: false
|
67
|
+
|
68
|
+
# setup cost / time >>> failure granularity
|
69
|
+
RSpec/ExampleLength:
|
70
|
+
Max: 15
|
71
|
+
CountAsOne:
|
72
|
+
- array
|
73
|
+
- hash
|
74
|
+
- heredoc
|
75
|
+
|
76
|
+
# we meant to do that
|
77
|
+
RSpec/ExpectInHook:
|
78
|
+
Enabled: false
|
79
|
+
|
80
|
+
# your naming scheme is not in possession of all the facts
|
81
|
+
RSpec/FilePath:
|
82
|
+
Enabled: false
|
83
|
+
|
84
|
+
# explicit >>> implicit
|
85
|
+
RSpec/InstanceVariable:
|
86
|
+
Enabled: false
|
87
|
+
|
88
|
+
# maybe when 'all' has a corresponding 'none' matcher
|
89
|
+
RSpec/IteratedExpectation:
|
90
|
+
Enabled: false
|
91
|
+
|
92
|
+
# we meant to do that
|
93
|
+
RSpec/MessageSpies:
|
94
|
+
Enabled: false
|
95
|
+
|
96
|
+
# too late now
|
97
|
+
RSpec/MultipleMemoizedHelpers:
|
98
|
+
Enabled: false
|
99
|
+
|
100
|
+
# setup cost / time >>> failure granularity
|
101
|
+
RSpec/MultipleExpectations:
|
102
|
+
Enabled: false
|
103
|
+
|
104
|
+
# cure is worse than the disease
|
105
|
+
RSpec/NestedGroups:
|
106
|
+
Enabled: false
|
107
|
+
|
108
|
+
# more quotation marks != more readable
|
109
|
+
RSpec/SharedExamples:
|
110
|
+
Enabled: false
|
111
|
+
|
112
|
+
# we meant to do that
|
113
|
+
RSpec/StubbedMock:
|
114
|
+
Enabled: false
|
115
|
+
|
116
|
+
# we meant to do that
|
117
|
+
RSpec/VerifiedDoubles:
|
118
|
+
Enabled: false
|
119
|
+
|
120
|
+
############################################################
|
121
|
+
# rubocop-rspec
|
122
|
+
|
123
|
+
# enable newer rubocop-rspec cops
|
124
|
+
|
125
|
+
RSpec/IdenticalEqualityAssertion: # new in 2.4
|
126
|
+
Enabled: true
|
127
|
+
|
128
|
+
RSpec/Rails/AvoidSetupHook: # new in 2.4
|
129
|
+
Enabled: true
|
@@ -113,12 +113,13 @@ module BerkeleyLibrary::Util
|
|
113
113
|
]
|
114
114
|
sources.each do |source|
|
115
115
|
expect(Arrays.find_indices(for_array: source, in_array: target)).to be_nil
|
116
|
+
expect(Arrays.find_indices(for_array: source, in_array: target) { |s, t| t == s.to_s }).to be_nil
|
116
117
|
end
|
117
118
|
end
|
118
119
|
|
119
120
|
it 'takes a comparison block' do
|
120
121
|
sub = %i[a c e]
|
121
|
-
expect(Arrays.find_indices(for_array: sub, in_array: target) { |
|
122
|
+
expect(Arrays.find_indices(for_array: sub, in_array: target) { |s, t| t == s.to_s }).to eq([0, 2, 4])
|
122
123
|
end
|
123
124
|
end
|
124
125
|
|
@@ -145,6 +146,10 @@ module BerkeleyLibrary::Util
|
|
145
146
|
expect(Arrays.find_index(in_array: arr, start_index: 2) { |x| x < 4 }).to be_nil
|
146
147
|
end
|
147
148
|
|
149
|
+
it 'raises ArgumentError if given extra arguments' do
|
150
|
+
expect { Arrays.find_index(1, 2, 3, in_array: [1, 2, 3]) }.to raise_error(ArgumentError)
|
151
|
+
end
|
152
|
+
|
148
153
|
# rubocop:disable Lint/Void
|
149
154
|
it 'returns an enumerator if given no arguments' do
|
150
155
|
e = Arrays.find_index(in_array: arr)
|
@@ -327,6 +332,10 @@ module BerkeleyLibrary::Util
|
|
327
332
|
expect(Arrays.invert([0, 2, 3])).to eq([0, nil, 1, 2])
|
328
333
|
end
|
329
334
|
|
335
|
+
it 'returns nil if given nil' do
|
336
|
+
expect(Arrays.invert(nil)).to be_nil
|
337
|
+
end
|
338
|
+
|
330
339
|
it 'fails if values are not ints' do
|
331
340
|
# noinspection RubyYardParamTypeMatch
|
332
341
|
expect { Arrays.invert(%i[a b c]) }.to raise_error(TypeError)
|
@@ -16,6 +16,13 @@ module BerkeleyLibrary
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
it 'reads from the end if given a negative index' do
|
20
|
+
bytes.reverse.each_with_index do |b, i|
|
21
|
+
end_offset = i + 1
|
22
|
+
expect(StringIOs.getbyte(sio, -end_offset)).to eq(b)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
19
26
|
it 'resets the current offset' do
|
20
27
|
StringIOs.getbyte(sio, bytes.size / 2)
|
21
28
|
expect(sio.pos).to eq(0)
|
@@ -41,6 +41,10 @@ module BerkeleyLibrary
|
|
41
41
|
expect(Strings.diff_index(s, s)).to be_nil
|
42
42
|
end
|
43
43
|
|
44
|
+
it 'returns nil for non-strings' do
|
45
|
+
expect(Strings.diff_index(2, ['2'])).to be_nil
|
46
|
+
end
|
47
|
+
|
44
48
|
it 'returns the index for different strings' do
|
45
49
|
s1 = 'elvis aaron presley'
|
46
50
|
s2 = 'elvis nikita presley'
|
@@ -97,6 +97,17 @@ module BerkeleyLibrary
|
|
97
97
|
expect(result).to eq(expected_status)
|
98
98
|
end
|
99
99
|
|
100
|
+
it 'appends query parameters to URL with existing params' do
|
101
|
+
url = 'https://example.org/endpoint?foo=bar'
|
102
|
+
params = { p1: 1, p2: 2 }
|
103
|
+
url_with_query = "#{url}&#{URI.encode_www_form(params)}"
|
104
|
+
expected_status = 203
|
105
|
+
stub_request(:head, url_with_query).to_return(status: expected_status)
|
106
|
+
|
107
|
+
result = Requester.head(url, params: params)
|
108
|
+
expect(result).to eq(expected_status)
|
109
|
+
end
|
110
|
+
|
100
111
|
it 'sends request headers' do
|
101
112
|
url = 'https://example.org/'
|
102
113
|
headers = { 'X-help' => 'I am trapped in a unit test' }
|
@@ -129,6 +140,116 @@ module BerkeleyLibrary
|
|
129
140
|
result = Requester.head(url1)
|
130
141
|
expect(result).to eq(expected_status)
|
131
142
|
end
|
143
|
+
|
144
|
+
it 'rejects a nil URI' do
|
145
|
+
expect { Requester.head(nil) }.to raise_error(ArgumentError)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe 'logging' do
|
150
|
+
attr_reader :logger
|
151
|
+
|
152
|
+
before do
|
153
|
+
@logger = instance_double(BerkeleyLibrary::Logging::Logger)
|
154
|
+
allow(BerkeleyLibrary::Logging).to receive(:logger).and_return(logger)
|
155
|
+
end
|
156
|
+
|
157
|
+
context 'GET' do
|
158
|
+
it 'logs request URLs and response codes for successful GET requests' do
|
159
|
+
url = 'https://example.org/'
|
160
|
+
expected_body = 'Help! I am trapped in a unit test'
|
161
|
+
stub_request(:get, url).to_return(body: expected_body)
|
162
|
+
|
163
|
+
expect(logger).to receive(:info).with(/#{url}.*200/)
|
164
|
+
Requester.send(:get, url)
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'can suppress logging for successful GET requests' do
|
168
|
+
url = 'https://example.org/'
|
169
|
+
expected_body = 'Help! I am trapped in a unit test'
|
170
|
+
stub_request(:get, url).to_return(body: expected_body)
|
171
|
+
|
172
|
+
expect(logger).not_to receive(:info)
|
173
|
+
Requester.send(:get, url, log: false)
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'logs request URLs and response codes for failed GET requests' do
|
177
|
+
url = 'https://example.org/'
|
178
|
+
status = 500
|
179
|
+
stub_request(:get, url).to_return(status: status)
|
180
|
+
|
181
|
+
expect(logger).to receive(:info).with(/#{url}.*#{status}/)
|
182
|
+
expect { Requester.send(:get, url) }.to raise_error(RestClient::InternalServerError)
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'can suppress logging for failed GET requests' do
|
186
|
+
url = 'https://example.org/'
|
187
|
+
stub_request(:get, url).to_return(status: 500)
|
188
|
+
|
189
|
+
expect(logger).not_to receive(:info)
|
190
|
+
expect { Requester.send(:get, url, log: false) }.to raise_error(RestClient::InternalServerError)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
context 'HEAD' do
|
195
|
+
it 'logs request URLs and response codes for successful HEAD requests' do
|
196
|
+
url = 'https://example.org/'
|
197
|
+
expected_body = 'Help! I am trapped in a unit test'
|
198
|
+
stub_request(:head, url).to_return(body: expected_body)
|
199
|
+
|
200
|
+
expect(logger).to receive(:info).with(/#{url}.*200/)
|
201
|
+
Requester.send(:head, url)
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'can suppress logging for successful HEAD requests' do
|
205
|
+
url = 'https://example.org/'
|
206
|
+
expected_body = 'Help! I am trapped in a unit test'
|
207
|
+
stub_request(:head, url).to_return(body: expected_body)
|
208
|
+
|
209
|
+
expect(logger).not_to receive(:info)
|
210
|
+
Requester.send(:head, url, log: false)
|
211
|
+
end
|
212
|
+
|
213
|
+
it 'logs request URLs and response codes for failed HEAD requests' do
|
214
|
+
url = 'https://example.org/'
|
215
|
+
status = 500
|
216
|
+
stub_request(:head, url).to_return(status: status)
|
217
|
+
|
218
|
+
expect(logger).to receive(:info).with(/#{url}.*#{status}/)
|
219
|
+
expect(Requester.send(:head, url)).to eq(status)
|
220
|
+
end
|
221
|
+
|
222
|
+
it 'can suppress logging for failed HEAD requests' do
|
223
|
+
url = 'https://example.org/'
|
224
|
+
status = 500
|
225
|
+
stub_request(:head, url).to_return(status: status)
|
226
|
+
|
227
|
+
expect(logger).not_to receive(:info)
|
228
|
+
expect(Requester.send(:head, url, log: false)).to eq(status)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
describe :new do
|
234
|
+
it 'rejects invalid URIs' do
|
235
|
+
url = 'not a uri'
|
236
|
+
Requester::SUPPORTED_METHODS.each do |method|
|
237
|
+
expect { Requester.new(method, url) }.to raise_error(URI::InvalidURIError)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
it 'rejects nil URIs' do
|
242
|
+
Requester::SUPPORTED_METHODS.each do |method|
|
243
|
+
expect { Requester.new(method, nil) }.to raise_error(ArgumentError)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
it 'rejects unsupported methods' do
|
248
|
+
url = 'https://example.org/'
|
249
|
+
%i[put patch post].each do |method|
|
250
|
+
expect { Requester.new(method, url) }.to raise_error(ArgumentError)
|
251
|
+
end
|
252
|
+
end
|
132
253
|
end
|
133
254
|
end
|
134
255
|
end
|