webmock 3.7.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 +7 -0
- data/.gemtest +0 -0
- data/.gitignore +34 -0
- data/.rspec-tm +2 -0
- data/.travis.yml +19 -0
- data/CHANGELOG.md +1698 -0
- data/Gemfile +9 -0
- data/LICENSE +20 -0
- data/README.md +1125 -0
- data/Rakefile +28 -0
- data/lib/webmock.rb +59 -0
- data/lib/webmock/api.rb +109 -0
- data/lib/webmock/assertion_failure.rb +11 -0
- data/lib/webmock/callback_registry.rb +35 -0
- data/lib/webmock/config.rb +18 -0
- data/lib/webmock/cucumber.rb +10 -0
- data/lib/webmock/deprecation.rb +9 -0
- data/lib/webmock/errors.rb +17 -0
- data/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +214 -0
- data/lib/webmock/http_lib_adapters/curb_adapter.rb +347 -0
- data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +228 -0
- data/lib/webmock/http_lib_adapters/excon_adapter.rb +162 -0
- data/lib/webmock/http_lib_adapters/http_lib_adapter.rb +7 -0
- data/lib/webmock/http_lib_adapters/http_lib_adapter_registry.rb +19 -0
- data/lib/webmock/http_lib_adapters/http_rb/client.rb +14 -0
- data/lib/webmock/http_lib_adapters/http_rb/request.rb +16 -0
- data/lib/webmock/http_lib_adapters/http_rb/response.rb +43 -0
- data/lib/webmock/http_lib_adapters/http_rb/streamer.rb +29 -0
- data/lib/webmock/http_lib_adapters/http_rb/webmock.rb +68 -0
- data/lib/webmock/http_lib_adapters/http_rb_adapter.rb +37 -0
- data/lib/webmock/http_lib_adapters/httpclient_adapter.rb +242 -0
- data/lib/webmock/http_lib_adapters/manticore_adapter.rb +130 -0
- data/lib/webmock/http_lib_adapters/net_http.rb +361 -0
- data/lib/webmock/http_lib_adapters/net_http_response.rb +34 -0
- data/lib/webmock/http_lib_adapters/patron_adapter.rb +130 -0
- data/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +174 -0
- data/lib/webmock/matchers/any_arg_matcher.rb +13 -0
- data/lib/webmock/matchers/hash_argument_matcher.rb +21 -0
- data/lib/webmock/matchers/hash_excluding_matcher.rb +15 -0
- data/lib/webmock/matchers/hash_including_matcher.rb +17 -0
- data/lib/webmock/minitest.rb +41 -0
- data/lib/webmock/rack_response.rb +69 -0
- data/lib/webmock/request_body_diff.rb +64 -0
- data/lib/webmock/request_execution_verifier.rb +77 -0
- data/lib/webmock/request_pattern.rb +370 -0
- data/lib/webmock/request_registry.rb +35 -0
- data/lib/webmock/request_signature.rb +54 -0
- data/lib/webmock/request_signature_snippet.rb +61 -0
- data/lib/webmock/request_stub.rb +100 -0
- data/lib/webmock/response.rb +153 -0
- data/lib/webmock/responses_sequence.rb +40 -0
- data/lib/webmock/rspec.rb +41 -0
- data/lib/webmock/rspec/matchers.rb +27 -0
- data/lib/webmock/rspec/matchers/request_pattern_matcher.rb +78 -0
- data/lib/webmock/rspec/matchers/webmock_matcher.rb +67 -0
- data/lib/webmock/stub_registry.rb +67 -0
- data/lib/webmock/stub_request_snippet.rb +38 -0
- data/lib/webmock/test_unit.rb +22 -0
- data/lib/webmock/util/hash_counter.rb +39 -0
- data/lib/webmock/util/hash_keys_stringifier.rb +25 -0
- data/lib/webmock/util/hash_validator.rb +17 -0
- data/lib/webmock/util/headers.rb +64 -0
- data/lib/webmock/util/json.rb +67 -0
- data/lib/webmock/util/query_mapper.rb +281 -0
- data/lib/webmock/util/uri.rb +110 -0
- data/lib/webmock/util/values_stringifier.rb +20 -0
- data/lib/webmock/util/version_checker.rb +111 -0
- data/lib/webmock/version.rb +3 -0
- data/lib/webmock/webmock.rb +161 -0
- data/minitest/test_helper.rb +34 -0
- data/minitest/test_webmock.rb +9 -0
- data/minitest/webmock_spec.rb +60 -0
- data/spec/acceptance/async_http_client/async_http_client_spec.rb +349 -0
- data/spec/acceptance/async_http_client/async_http_client_spec_helper.rb +73 -0
- data/spec/acceptance/curb/curb_spec.rb +492 -0
- data/spec/acceptance/curb/curb_spec_helper.rb +147 -0
- data/spec/acceptance/em_http_request/em_http_request_spec.rb +406 -0
- data/spec/acceptance/em_http_request/em_http_request_spec_helper.rb +77 -0
- data/spec/acceptance/excon/excon_spec.rb +77 -0
- data/spec/acceptance/excon/excon_spec_helper.rb +50 -0
- data/spec/acceptance/http_rb/http_rb_spec.rb +82 -0
- data/spec/acceptance/http_rb/http_rb_spec_helper.rb +54 -0
- data/spec/acceptance/httpclient/httpclient_spec.rb +217 -0
- data/spec/acceptance/httpclient/httpclient_spec_helper.rb +57 -0
- data/spec/acceptance/manticore/manticore_spec.rb +56 -0
- data/spec/acceptance/manticore/manticore_spec_helper.rb +35 -0
- data/spec/acceptance/net_http/net_http_shared.rb +153 -0
- data/spec/acceptance/net_http/net_http_spec.rb +331 -0
- data/spec/acceptance/net_http/net_http_spec_helper.rb +64 -0
- data/spec/acceptance/net_http/real_net_http_spec.rb +20 -0
- data/spec/acceptance/patron/patron_spec.rb +125 -0
- data/spec/acceptance/patron/patron_spec_helper.rb +54 -0
- data/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +313 -0
- data/spec/acceptance/shared/callbacks.rb +148 -0
- data/spec/acceptance/shared/complex_cross_concern_behaviors.rb +36 -0
- data/spec/acceptance/shared/enabling_and_disabling_webmock.rb +95 -0
- data/spec/acceptance/shared/precedence_of_stubs.rb +15 -0
- data/spec/acceptance/shared/request_expectations.rb +930 -0
- data/spec/acceptance/shared/returning_declared_responses.rb +409 -0
- data/spec/acceptance/shared/stubbing_requests.rb +643 -0
- data/spec/acceptance/typhoeus/typhoeus_hydra_spec.rb +135 -0
- data/spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb +60 -0
- data/spec/acceptance/webmock_shared.rb +41 -0
- data/spec/fixtures/test.txt +1 -0
- data/spec/quality_spec.rb +84 -0
- data/spec/spec_helper.rb +48 -0
- data/spec/support/example_curl_output.txt +22 -0
- data/spec/support/failures.rb +9 -0
- data/spec/support/my_rack_app.rb +53 -0
- data/spec/support/network_connection.rb +19 -0
- data/spec/support/webmock_server.rb +70 -0
- data/spec/unit/api_spec.rb +175 -0
- data/spec/unit/errors_spec.rb +129 -0
- data/spec/unit/http_lib_adapters/http_lib_adapter_registry_spec.rb +17 -0
- data/spec/unit/http_lib_adapters/http_lib_adapter_spec.rb +12 -0
- data/spec/unit/matchers/hash_excluding_matcher_spec.rb +61 -0
- data/spec/unit/matchers/hash_including_matcher_spec.rb +87 -0
- data/spec/unit/rack_response_spec.rb +112 -0
- data/spec/unit/request_body_diff_spec.rb +90 -0
- data/spec/unit/request_execution_verifier_spec.rb +208 -0
- data/spec/unit/request_pattern_spec.rb +601 -0
- data/spec/unit/request_registry_spec.rb +95 -0
- data/spec/unit/request_signature_snippet_spec.rb +89 -0
- data/spec/unit/request_signature_spec.rb +155 -0
- data/spec/unit/request_stub_spec.rb +199 -0
- data/spec/unit/response_spec.rb +282 -0
- data/spec/unit/stub_registry_spec.rb +103 -0
- data/spec/unit/stub_request_snippet_spec.rb +115 -0
- data/spec/unit/util/hash_counter_spec.rb +39 -0
- data/spec/unit/util/hash_keys_stringifier_spec.rb +27 -0
- data/spec/unit/util/headers_spec.rb +28 -0
- data/spec/unit/util/json_spec.rb +33 -0
- data/spec/unit/util/query_mapper_spec.rb +157 -0
- data/spec/unit/util/uri_spec.rb +361 -0
- data/spec/unit/util/version_checker_spec.rb +65 -0
- data/spec/unit/webmock_spec.rb +19 -0
- data/test/http_request.rb +24 -0
- data/test/shared_test.rb +108 -0
- data/test/test_helper.rb +23 -0
- data/test/test_webmock.rb +6 -0
- data/webmock.gemspec +45 -0
- metadata +496 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe WebMock::Util::HashCounter do
|
|
4
|
+
|
|
5
|
+
it "should return 0 for non existing key" do
|
|
6
|
+
expect(WebMock::Util::HashCounter.new.get(:abc)).to eq(0)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "should increase the returned value on every put with the same key" do
|
|
10
|
+
counter = WebMock::Util::HashCounter.new
|
|
11
|
+
counter.put(:abc)
|
|
12
|
+
expect(counter.get(:abc)).to eq(1)
|
|
13
|
+
counter.put(:abc)
|
|
14
|
+
expect(counter.get(:abc)).to eq(2)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "should only increase value for given key provided to put" do
|
|
18
|
+
counter = WebMock::Util::HashCounter.new
|
|
19
|
+
counter.put(:abc)
|
|
20
|
+
expect(counter.get(:abc)).to eq(1)
|
|
21
|
+
expect(counter.get(:def)).to eq(0)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe "each" do
|
|
25
|
+
it "should provide elements in order of the last modified" do
|
|
26
|
+
counter = WebMock::Util::HashCounter.new
|
|
27
|
+
counter.put(:a)
|
|
28
|
+
counter.put(:b)
|
|
29
|
+
counter.put(:c)
|
|
30
|
+
counter.put(:b)
|
|
31
|
+
counter.put(:a)
|
|
32
|
+
counter.put(:d)
|
|
33
|
+
|
|
34
|
+
elements = []
|
|
35
|
+
counter.each {|k,v| elements << [k,v]}
|
|
36
|
+
expect(elements).to eq([[:c, 1], [:b, 2], [:a, 2], [:d, 1]])
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe WebMock::Util::HashKeysStringifier do
|
|
4
|
+
|
|
5
|
+
it "should recursively stringify all symbol keys" do
|
|
6
|
+
hash = {
|
|
7
|
+
a: {
|
|
8
|
+
b: [
|
|
9
|
+
{
|
|
10
|
+
c: [{d: "1"}]
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
stringified = {
|
|
16
|
+
'a' => {
|
|
17
|
+
'b' => [
|
|
18
|
+
{
|
|
19
|
+
'c' => [{'d' => "1"}]
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
expect(WebMock::Util::HashKeysStringifier.stringify_keys!(hash, deep: true)).to eq(stringified)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe WebMock::Util::Headers do
|
|
4
|
+
|
|
5
|
+
it "should decode_userinfo_from_header handles basic auth" do
|
|
6
|
+
authorization_header = "Basic dXNlcm5hbWU6c2VjcmV0"
|
|
7
|
+
userinfo = WebMock::Util::Headers.decode_userinfo_from_header(authorization_header)
|
|
8
|
+
expect(userinfo).to eq("username:secret")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe "sorted_headers_string" do
|
|
12
|
+
|
|
13
|
+
it "should return nice string for hash with string values" do
|
|
14
|
+
expect(WebMock::Util::Headers.sorted_headers_string({"a" => "b"})).to eq("{'A'=>'b'}")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "should return nice string for hash with array values" do
|
|
18
|
+
expect(WebMock::Util::Headers.sorted_headers_string({"a" => ["b", "c"]})).to eq("{'A'=>['b', 'c']}")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should return nice string for hash with array values and string values" do
|
|
22
|
+
expect(WebMock::Util::Headers.sorted_headers_string({"a" => ["b", "c"], "d" => "e"})).to eq("{'A'=>['b', 'c'], 'D'=>'e'}")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
describe WebMock::Util::JSON do
|
|
5
|
+
describe ".parse" do
|
|
6
|
+
it "should parse json without parsing dates" do
|
|
7
|
+
expect(WebMock::Util::JSON.parse("\"a\":\"2011-01-01\"")).to eq(
|
|
8
|
+
{"a" => "2011-01-01"}
|
|
9
|
+
)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "can parse json with multibyte characters" do
|
|
13
|
+
expect(WebMock::Util::JSON.parse(
|
|
14
|
+
"{\"name\":\"山田太郎\"\,\"job\":\"会社員\"}"
|
|
15
|
+
)).to eq({"name" => "山田太郎", "job" => "会社員"})
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "rescues ArgumentError's from YAML.load" do
|
|
19
|
+
allow(YAML).to receive(:load).and_raise(ArgumentError)
|
|
20
|
+
expect {
|
|
21
|
+
WebMock::Util::JSON.parse("Bad JSON")
|
|
22
|
+
}.to raise_error WebMock::Util::JSON::ParseError
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe ".convert_json_to_yaml" do
|
|
27
|
+
it "parses multibyte characters" do
|
|
28
|
+
expect(WebMock::Util::JSON.convert_json_to_yaml(
|
|
29
|
+
"{\"name\":\"山田太郎\"\,\"job\":\"会社員\"}"
|
|
30
|
+
)).to eq "{\"name\": \"山田太郎\", \"job\": \"会社員\"}"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe WebMock::Util::QueryMapper do
|
|
4
|
+
subject { described_class }
|
|
5
|
+
|
|
6
|
+
context '#query_to_values' do
|
|
7
|
+
it 'should raise on invalid notation' do
|
|
8
|
+
query = 'a=&b=c'
|
|
9
|
+
expect { subject.query_to_values(query, {notation: 'foo'}) }.to raise_error(
|
|
10
|
+
ArgumentError,
|
|
11
|
+
'Invalid notation. Must be one of: [:flat, :dot, :subscript, :flat_array].'
|
|
12
|
+
)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'should parse hash queries' do
|
|
16
|
+
# {"one" => {"two" => {"three" => ["four", "five"]}}}
|
|
17
|
+
query = 'one%5Btwo%5D%5Bthree%5D%5B%5D=four&one%5Btwo%5D%5Bthree%5D%5B%5D=five'
|
|
18
|
+
hsh = subject.query_to_values(query)
|
|
19
|
+
expect(hsh['one']['two']['three']).to eq(%w(four five))
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'should parse one nil value queries' do
|
|
23
|
+
# {'a' => nil, 'b' => 'c'}
|
|
24
|
+
query = 'a=&b=c'
|
|
25
|
+
hsh = subject.query_to_values(query)
|
|
26
|
+
expect(hsh['a']).to be_empty
|
|
27
|
+
expect(hsh['b']).to eq('c')
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'should parse array queries' do
|
|
31
|
+
# {"one" => ["foo", "bar"]}
|
|
32
|
+
query = 'one%5B%5D=foo&one%5B%5D=bar'
|
|
33
|
+
hsh = subject.query_to_values(query)
|
|
34
|
+
expect(hsh['one']).to eq(%w(foo bar))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'should parse string queries' do
|
|
38
|
+
# {"one" => "two", "three" => "four"}
|
|
39
|
+
query = 'one=two&three=four'
|
|
40
|
+
hsh = subject.query_to_values(query)
|
|
41
|
+
expect(hsh).to eq({'one' => 'two', 'three' => 'four'})
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'should parse nested queries' do
|
|
45
|
+
# [{"b"=>[{"c"=>[{"d"=>["1", {"e"=>"2"}]}]}]}]
|
|
46
|
+
query = 'a%5B%5D%5Bb%5D%5B%5D%5Bc%5D%5B%5D%5Bd%5D%5B%5D=1&a%5B%5D%5Bb%5D%5B%5D%5Bc%5D%5B%5D%5Bd%5D%5B%5D%5Be%5D=2'
|
|
47
|
+
hsh = subject.query_to_values(query)
|
|
48
|
+
expect(hsh['a'][0]['b'][0]['c'][0]['d'][0]).to eq('1')
|
|
49
|
+
expect(hsh['a'][0]['b'][0]['c'][0]['d'][1]['e']).to eq('2')
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "should parse nested repeated correctly" do
|
|
53
|
+
query = "a[][b][]=one&a[][b][]=two"
|
|
54
|
+
hsh = subject.query_to_values(query)
|
|
55
|
+
expect(hsh['a']).to be_a(Array)
|
|
56
|
+
expect(hsh['a'][0]).to eq({"b" => ['one']})
|
|
57
|
+
expect(hsh['a'][1]).to eq({"b" => ['two']})
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "should parse nested non-repeated correctly" do
|
|
61
|
+
query = "a[][b][]=one&a[][c][]=two"
|
|
62
|
+
hsh = subject.query_to_values(query)
|
|
63
|
+
expect(hsh['a']).to be_a(Array)
|
|
64
|
+
expect(hsh['a'][0]['b']).to eq(['one'])
|
|
65
|
+
expect(hsh['a'][0]['c']).to eq(['two'])
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'should not attempt to mutate its query argument' do
|
|
69
|
+
query = "a=foo".freeze
|
|
70
|
+
hsh = subject.query_to_values(query)
|
|
71
|
+
expect(hsh['a']).to eq('foo')
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "should parse hash query with key starting with non word character" do
|
|
75
|
+
query = "a[$in]=1".freeze
|
|
76
|
+
hsh = subject.query_to_values(query)
|
|
77
|
+
expect(hsh).to eql({'a' => {'$in' => '1'}})
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
context '#to_query' do
|
|
82
|
+
it 'should transform nil value' do
|
|
83
|
+
expect(subject.to_query('a', nil)).to eq('a')
|
|
84
|
+
end
|
|
85
|
+
it 'should transform string value' do
|
|
86
|
+
expect(subject.to_query('a', 'b')).to eq('a=b')
|
|
87
|
+
end
|
|
88
|
+
it 'should transform hash value' do
|
|
89
|
+
expect(subject.to_query('a', {'key' => 'value'})).to eq('a[key]=value')
|
|
90
|
+
end
|
|
91
|
+
it 'should transform hash value with keys that are symbols' do
|
|
92
|
+
expect(subject.to_query('a', {key: 'value'})).to eq('a[key]=value')
|
|
93
|
+
end
|
|
94
|
+
it 'should transform array value' do
|
|
95
|
+
expect(subject.to_query('a', ['b', 'c'])).to eq('a[0]=b&a[1]=c')
|
|
96
|
+
end
|
|
97
|
+
it 'should transform boolean values' do
|
|
98
|
+
expect(subject.to_query('a', true)).to eq('a=true')
|
|
99
|
+
expect(subject.to_query('a', false)).to eq('a=false')
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
context '#values_to_query' do
|
|
104
|
+
it 'converts values to a query string' do
|
|
105
|
+
query = "key=value&other_key=other_value"
|
|
106
|
+
values = [['key','value'],['other_key','other_value']]
|
|
107
|
+
expect(subject.values_to_query values).to eq query
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it 'converts values with missing keys to a query string' do
|
|
111
|
+
query = "=value"
|
|
112
|
+
values = { '' => 'value' }
|
|
113
|
+
expect(subject.values_to_query values).to eq query
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it 'converts values with nil keys to a query string' do
|
|
117
|
+
query = "=value"
|
|
118
|
+
values = { nil => 'value' }
|
|
119
|
+
expect(subject.values_to_query values).to eq query
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it 'converts array values, vice versa' do
|
|
124
|
+
query = "one%5B%5D=1&one%5B%5D=2" # one[]=1&one[]=2
|
|
125
|
+
values = {"one" => ["1","2"]}
|
|
126
|
+
expect(subject.values_to_query values).to eq query
|
|
127
|
+
expect(subject.query_to_values query).to eq values
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it 'converts hash values, vice versa' do
|
|
131
|
+
query = "one%5Ba%5D=1&one%5Bb%5D=2" # one[a]=1&one[b]=2
|
|
132
|
+
values = {"one" => {"a" => "1", "b" => "2"}}
|
|
133
|
+
expect(subject.values_to_query values).to eq query
|
|
134
|
+
expect(subject.query_to_values query).to eq values
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it 'converts complex nested hashes, vice versa' do
|
|
138
|
+
query = "one%5B%5D[foo]=bar&one%5B%5D[zoo]=car" # one[][foo]=bar&one[][zoo]=car
|
|
139
|
+
values = {"one" => [{"foo" => "bar", "zoo" => "car"}]}
|
|
140
|
+
expect(subject.values_to_query values).to eq query
|
|
141
|
+
expect(subject.query_to_values query).to eq values
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it 'converts complex nested array of hashes, vice versa' do
|
|
145
|
+
query = "one%5B%5D[foo]=bar&one%5B%5D[foo]=bar&one%5B%5D[zoo]=car" # one[][foo]=bar&one[][foo]=bar&one[][zoo]=car
|
|
146
|
+
values = {"one" => [{"foo" => "bar"}, {"foo" => "bar", "zoo" => "car"}]}
|
|
147
|
+
expect(subject.values_to_query values).to eq query
|
|
148
|
+
expect(subject.query_to_values query).to eq values
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it 'converts an empty array to ?' do
|
|
152
|
+
query = "one%5B%5D"
|
|
153
|
+
values = {"one" => []}
|
|
154
|
+
expect(subject.values_to_query values).to eq query
|
|
155
|
+
expect(subject.query_to_values query).to eq values
|
|
156
|
+
end
|
|
157
|
+
end
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
URIS_WITHOUT_PATH_OR_PARAMS =
|
|
4
|
+
[
|
|
5
|
+
"www.example.com",
|
|
6
|
+
"www.example.com/",
|
|
7
|
+
"www.example.com:80",
|
|
8
|
+
"www.example.com:80/",
|
|
9
|
+
"http://www.example.com",
|
|
10
|
+
"http://www.example.com/",
|
|
11
|
+
"http://www.example.com:80",
|
|
12
|
+
"http://www.example.com:80/"
|
|
13
|
+
].sort
|
|
14
|
+
|
|
15
|
+
URIS_WITHOUT_PATH_BUT_WITH_PARAMS =
|
|
16
|
+
[
|
|
17
|
+
"www.example.com?a=b",
|
|
18
|
+
"www.example.com/?a=b",
|
|
19
|
+
"www.example.com:80?a=b",
|
|
20
|
+
"www.example.com:80/?a=b",
|
|
21
|
+
"http://www.example.com?a=b",
|
|
22
|
+
"http://www.example.com/?a=b",
|
|
23
|
+
"http://www.example.com:80?a=b",
|
|
24
|
+
"http://www.example.com:80/?a=b"
|
|
25
|
+
].sort
|
|
26
|
+
|
|
27
|
+
URIS_WITH_AUTH =
|
|
28
|
+
[
|
|
29
|
+
"a b:pass@www.example.com",
|
|
30
|
+
"a b:pass@www.example.com/",
|
|
31
|
+
"a b:pass@www.example.com:80",
|
|
32
|
+
"a b:pass@www.example.com:80/",
|
|
33
|
+
"http://a b:pass@www.example.com",
|
|
34
|
+
"http://a b:pass@www.example.com/",
|
|
35
|
+
"http://a b:pass@www.example.com:80",
|
|
36
|
+
"http://a b:pass@www.example.com:80/",
|
|
37
|
+
"a%20b:pass@www.example.com",
|
|
38
|
+
"a%20b:pass@www.example.com/",
|
|
39
|
+
"a%20b:pass@www.example.com:80",
|
|
40
|
+
"a%20b:pass@www.example.com:80/",
|
|
41
|
+
"http://a%20b:pass@www.example.com",
|
|
42
|
+
"http://a%20b:pass@www.example.com/",
|
|
43
|
+
"http://a%20b:pass@www.example.com:80",
|
|
44
|
+
"http://a%20b:pass@www.example.com:80/"
|
|
45
|
+
].sort
|
|
46
|
+
|
|
47
|
+
URIS_WITH_PATH_AND_PARAMS =
|
|
48
|
+
[
|
|
49
|
+
"www.example.com/my path/?a=my param&b=c d",
|
|
50
|
+
"www.example.com/my%20path/?a=my%20param&b=c%20d",
|
|
51
|
+
"www.example.com:80/my path/?a=my param&b=c d",
|
|
52
|
+
"www.example.com:80/my%20path/?a=my%20param&b=c%20d",
|
|
53
|
+
"http://www.example.com/my path/?a=my param&b=c d",
|
|
54
|
+
"http://www.example.com/my%20path/?a=my%20param&b=c%20d",
|
|
55
|
+
"http://www.example.com:80/my path/?a=my param&b=c d",
|
|
56
|
+
"http://www.example.com:80/my%20path/?a=my%20param&b=c%20d",
|
|
57
|
+
].sort
|
|
58
|
+
|
|
59
|
+
URIS_WITH_DIFFERENT_PORT =
|
|
60
|
+
[
|
|
61
|
+
"www.example.com:88",
|
|
62
|
+
"www.example.com:88/",
|
|
63
|
+
"http://www.example.com:88",
|
|
64
|
+
"http://www.example.com:88/"
|
|
65
|
+
].sort
|
|
66
|
+
|
|
67
|
+
URIS_FOR_HTTPS =
|
|
68
|
+
[
|
|
69
|
+
"https://www.example.com",
|
|
70
|
+
"https://www.example.com/",
|
|
71
|
+
"https://www.example.com:443",
|
|
72
|
+
"https://www.example.com:443/"
|
|
73
|
+
].sort
|
|
74
|
+
|
|
75
|
+
URIS_FOR_LOCALHOST =
|
|
76
|
+
[
|
|
77
|
+
"localhost",
|
|
78
|
+
"localhost/",
|
|
79
|
+
"localhost:80",
|
|
80
|
+
"localhost:80/",
|
|
81
|
+
"http://localhost",
|
|
82
|
+
"http://localhost/",
|
|
83
|
+
"http://localhost:80",
|
|
84
|
+
"http://localhost:80/"
|
|
85
|
+
].sort
|
|
86
|
+
|
|
87
|
+
URIS_WITH_SCHEME =
|
|
88
|
+
[
|
|
89
|
+
"http://www.example.com",
|
|
90
|
+
"http://www.example.com/",
|
|
91
|
+
"http://www.example.com:80",
|
|
92
|
+
"http://www.example.com:80/"
|
|
93
|
+
].sort
|
|
94
|
+
|
|
95
|
+
URIS_WITH_COLON_IN_PATH =
|
|
96
|
+
[
|
|
97
|
+
[
|
|
98
|
+
"https://example.com/a/b:80",
|
|
99
|
+
"https://example.com:443/a/b:80",
|
|
100
|
+
].sort,
|
|
101
|
+
[
|
|
102
|
+
"https://example.com:443/a/b:443",
|
|
103
|
+
"https://example.com/a/b:443",
|
|
104
|
+
].sort,
|
|
105
|
+
[
|
|
106
|
+
"http://example.com/a/b:443",
|
|
107
|
+
"example.com/a/b:443",
|
|
108
|
+
"http://example.com:80/a/b:443",
|
|
109
|
+
"example.com:80/a/b:443",
|
|
110
|
+
].sort,
|
|
111
|
+
[
|
|
112
|
+
"http://example.com/a/b:80",
|
|
113
|
+
"example.com/a/b:80",
|
|
114
|
+
"http://example.com:80/a/b:80",
|
|
115
|
+
"example.com:80/a/b:80",
|
|
116
|
+
].sort
|
|
117
|
+
]
|
|
118
|
+
|
|
119
|
+
describe WebMock::Util::URI do
|
|
120
|
+
|
|
121
|
+
describe "reporting variations of uri" do
|
|
122
|
+
|
|
123
|
+
it "should find all variations of the same uri for all variations of uri with params and path" do
|
|
124
|
+
URIS_WITH_PATH_AND_PARAMS.each do |uri|
|
|
125
|
+
expect(WebMock::Util::URI.variations_of_uri_as_strings(uri).sort).to eq(URIS_WITH_PATH_AND_PARAMS)
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it "should find all variations of the same uri for all variations of uri with params but without path" do
|
|
130
|
+
URIS_WITHOUT_PATH_BUT_WITH_PARAMS.each do |uri|
|
|
131
|
+
expect(WebMock::Util::URI.variations_of_uri_as_strings(uri).sort).to eq(URIS_WITHOUT_PATH_BUT_WITH_PARAMS)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
it "should find all variations of the same uri for all variations of uri without params or path" do
|
|
136
|
+
URIS_WITHOUT_PATH_OR_PARAMS.each do |uri|
|
|
137
|
+
expect(WebMock::Util::URI.variations_of_uri_as_strings(uri).sort).to eq(URIS_WITHOUT_PATH_OR_PARAMS)
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it "should find all variations of the same uri for all variations of uri with auth" do
|
|
142
|
+
URIS_WITH_AUTH.each do |uri|
|
|
143
|
+
expect(WebMock::Util::URI.variations_of_uri_as_strings(uri).sort).to eq(URIS_WITH_AUTH)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it "should find all variations of the same uri for all variations of uri with different port" do
|
|
148
|
+
URIS_WITH_DIFFERENT_PORT.each do |uri|
|
|
149
|
+
expect(WebMock::Util::URI.variations_of_uri_as_strings(uri).sort).to eq(URIS_WITH_DIFFERENT_PORT)
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
it "should find all variations of the same uri for all variations of https uris" do
|
|
154
|
+
URIS_FOR_HTTPS.each do |uri|
|
|
155
|
+
expect(WebMock::Util::URI.variations_of_uri_as_strings(uri).sort).to eq(URIS_FOR_HTTPS)
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it "should find all variations of the same uri for all variations of host names uris without a period" do
|
|
160
|
+
URIS_FOR_LOCALHOST.each do |uri|
|
|
161
|
+
expect(WebMock::Util::URI.variations_of_uri_as_strings(uri).sort).to eq(URIS_FOR_LOCALHOST)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
it "should find all variations of the same uri with scheme for all variations when only_with_scheme is true" do
|
|
166
|
+
URIS_WITHOUT_PATH_OR_PARAMS.each do |uri|
|
|
167
|
+
variations_of_uri_with_scheme = WebMock::Util::URI.variations_of_uri_as_strings(uri, only_with_scheme: true)
|
|
168
|
+
expect(variations_of_uri_with_scheme.sort).to eq(URIS_WITH_SCHEME)
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it "should not replace :80 or :443 in path" do
|
|
173
|
+
URIS_WITH_COLON_IN_PATH.each do |uris|
|
|
174
|
+
uris.each do |uri|
|
|
175
|
+
expect(WebMock::Util::URI.variations_of_uri_as_strings(uri).sort).to eq(uris)
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
describe "normalized uri equality" do
|
|
183
|
+
|
|
184
|
+
it "should successfully compare all variations of the same uri with path and params" do
|
|
185
|
+
URIS_WITH_PATH_AND_PARAMS.each do |uri_a|
|
|
186
|
+
URIS_WITH_PATH_AND_PARAMS.each do |uri_b|
|
|
187
|
+
expect(WebMock::Util::URI.normalize_uri(uri_a)).to be === WebMock::Util::URI.normalize_uri(uri_b)
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
it "should successfully compare all variations of the same uri with path but with params" do
|
|
193
|
+
URIS_WITHOUT_PATH_BUT_WITH_PARAMS.each do |uri_a|
|
|
194
|
+
URIS_WITHOUT_PATH_BUT_WITH_PARAMS.each do |uri_b|
|
|
195
|
+
expect(WebMock::Util::URI.normalize_uri(uri_a)).to be === WebMock::Util::URI.normalize_uri(uri_b)
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
it "should successfully compare all variations of the same uri without path or params" do
|
|
201
|
+
URIS_WITHOUT_PATH_OR_PARAMS.each do |uri_a|
|
|
202
|
+
URIS_WITHOUT_PATH_OR_PARAMS.each do |uri_b|
|
|
203
|
+
expect(WebMock::Util::URI.normalize_uri(uri_a)).to be === WebMock::Util::URI.normalize_uri(uri_b)
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
it "should successfully compare all variations of the same uri with authority" do
|
|
209
|
+
URIS_WITH_AUTH.each do |uri_a|
|
|
210
|
+
URIS_WITH_AUTH.each do |uri_b|
|
|
211
|
+
expect(WebMock::Util::URI.normalize_uri(uri_a)).to be === WebMock::Util::URI.normalize_uri(uri_b)
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
it "should successfully compare all variations of the same uri custom port" do
|
|
217
|
+
URIS_WITH_DIFFERENT_PORT.each do |uri_a|
|
|
218
|
+
URIS_WITH_DIFFERENT_PORT.each do |uri_b|
|
|
219
|
+
expect(WebMock::Util::URI.normalize_uri(uri_a)).to be === WebMock::Util::URI.normalize_uri(uri_b)
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
it "should successfully compare all variations of the same https uri" do
|
|
225
|
+
URIS_FOR_HTTPS.each do |uri_a|
|
|
226
|
+
URIS_FOR_HTTPS.each do |uri_b|
|
|
227
|
+
expect(WebMock::Util::URI.normalize_uri(uri_a)).to be === WebMock::Util::URI.normalize_uri(uri_b)
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
it "should successfully handle array parameters" do
|
|
233
|
+
uri_string = 'http://www.example.com:80/path?a[]=b&a[]=c'
|
|
234
|
+
uri = WebMock::Util::URI.normalize_uri(uri_string)
|
|
235
|
+
expect(WebMock::Util::QueryMapper.query_to_values(uri.query)).to eq({"a"=>["b", "c"]})
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
it "should successfully handle hash parameters" do
|
|
239
|
+
uri_string = 'http://www.example.com:80/path?a[d]=b&a[e]=c&a[b][c]=1'
|
|
240
|
+
uri = WebMock::Util::URI.normalize_uri(uri_string)
|
|
241
|
+
expect(WebMock::Util::QueryMapper.query_to_values(uri.query)).to eq({"a"=>{"d"=>"b", "e"=>"c", "b"=>{"c"=>"1"}}})
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
it "should successfully handle nested hash parameters" do
|
|
245
|
+
uri_string = 'http://www.example.com:80/path?one[two][three][]=four&one[two][three][]=five'
|
|
246
|
+
uri = WebMock::Util::URI.normalize_uri(uri_string)
|
|
247
|
+
expect(WebMock::Util::QueryMapper.query_to_values(uri.query)).to eq({"one"=>{"two"=>{"three" => ["four", "five"]}}})
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
it "should successfully handle mixed array and hash parameters" do
|
|
251
|
+
# derived from an elasticsearch query:
|
|
252
|
+
# load => {
|
|
253
|
+
# :include => [
|
|
254
|
+
# { :staff => :email },
|
|
255
|
+
# :business_name
|
|
256
|
+
# ]
|
|
257
|
+
# }
|
|
258
|
+
uri_string = "http://www.example.com:80/path?load[include][][staff]=email&load[include][]=business_name"
|
|
259
|
+
uri = WebMock::Util::URI.normalize_uri(uri_string)
|
|
260
|
+
expect(WebMock::Util::QueryMapper.query_to_values(uri.query)).to eq({"load"=>{"include"=>[{"staff"=>"email"},"business_name"]}})
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
context "when query notation is set to :flat_array" do
|
|
264
|
+
before :all do
|
|
265
|
+
WebMock::Config.instance.query_values_notation = :flat_array
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
it "should successfully handle repeated paramters" do
|
|
269
|
+
uri_string = "http://www.example.com:80/path?target=host1&target=host2"
|
|
270
|
+
uri = WebMock::Util::URI.normalize_uri(uri_string)
|
|
271
|
+
expect(WebMock::Util::QueryMapper.query_to_values(uri.query, notation: WebMock::Config.instance.query_values_notation)).to eq([['target', 'host1'], ['target', 'host2']])
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
describe "sorting query values" do
|
|
277
|
+
|
|
278
|
+
context "when query values is a Hash" do
|
|
279
|
+
it "returns an alphabetically sorted hash" do
|
|
280
|
+
sorted_query = WebMock::Util::URI.sort_query_values({"b"=>"one", "a"=>"two"})
|
|
281
|
+
expect(sorted_query).to eq({"a"=>"two", "b"=>"one"})
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
context "when query values is an Array" do
|
|
286
|
+
it "returns an alphabetically sorted array" do
|
|
287
|
+
sorted_query = WebMock::Util::URI.sort_query_values([["b","two"],["a","one_b"],["a","one_a"]])
|
|
288
|
+
expect(sorted_query).to eq([["a","one_a"],["a","one_b"],["b","two"]])
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
describe "stripping default port" do
|
|
294
|
+
|
|
295
|
+
it "should strip_default_port_from_uri strips 80 from http with path" do
|
|
296
|
+
uri = "http://example.com:80/foo/bar"
|
|
297
|
+
stripped_uri = WebMock::Util::URI.strip_default_port_from_uri_string(uri)
|
|
298
|
+
expect(stripped_uri).to eq("http://example.com/foo/bar")
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
it "should strip_default_port_from_uri strips 80 from http without path" do
|
|
302
|
+
uri = "http://example.com:80"
|
|
303
|
+
stripped_uri = WebMock::Util::URI.strip_default_port_from_uri_string(uri)
|
|
304
|
+
expect(stripped_uri).to eq("http://example.com")
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
it "should strip_default_port_from_uri strips 443 from https without path" do
|
|
308
|
+
uri = "https://example.com:443"
|
|
309
|
+
stripped_uri = WebMock::Util::URI.strip_default_port_from_uri_string(uri)
|
|
310
|
+
expect(stripped_uri).to eq("https://example.com")
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
it "should strip_default_port_from_uri strips 443 from https" do
|
|
314
|
+
uri = "https://example.com:443/foo/bar"
|
|
315
|
+
stripped_uri = WebMock::Util::URI.strip_default_port_from_uri_string(uri)
|
|
316
|
+
expect(stripped_uri).to eq("https://example.com/foo/bar")
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
it "should strip_default_port_from_uri does not strip 8080 from http" do
|
|
320
|
+
uri = "http://example.com:8080/foo/bar"
|
|
321
|
+
expect(WebMock::Util::URI.strip_default_port_from_uri_string(uri)).to eq(uri)
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
it "should strip_default_port_from_uri does not strip 443 from http" do
|
|
325
|
+
uri = "http://example.com:443/foo/bar"
|
|
326
|
+
expect(WebMock::Util::URI.strip_default_port_from_uri_string(uri)).to eq(uri)
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
it "should strip_default_port_from_uri does not strip 80 from query string" do
|
|
330
|
+
uri = "http://example.com/?a=:80&b=c"
|
|
331
|
+
expect(WebMock::Util::URI.strip_default_port_from_uri_string(uri)).to eq(uri)
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
it "should strip_default_port_from_uri does not modify strings that do not start with http or https" do
|
|
335
|
+
uri = "httpz://example.com:80/"
|
|
336
|
+
expect(WebMock::Util::URI.strip_default_port_from_uri_string(uri)).to eq(uri)
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
describe "encoding userinfo" do
|
|
343
|
+
|
|
344
|
+
it "should encode unsafe chars in userinfo does not encode userinfo safe punctuation" do
|
|
345
|
+
userinfo = "user;&=+$,:secret"
|
|
346
|
+
expect(WebMock::Util::URI.encode_unsafe_chars_in_userinfo(userinfo)).to eq(userinfo)
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
it "should encode unsafe chars in userinfo does not encode rfc 3986 unreserved characters" do
|
|
350
|
+
userinfo = "-.!~*'()abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:secret"
|
|
351
|
+
expect(WebMock::Util::URI.encode_unsafe_chars_in_userinfo(userinfo)).to eq(userinfo)
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
it "should encode unsafe chars in userinfo does encode other characters" do
|
|
355
|
+
userinfo, safe_userinfo = 'us#rn@me:sec//ret?"', 'us%23rn%40me:sec%2F%2Fret%3F%22'
|
|
356
|
+
expect(WebMock::Util::URI.encode_unsafe_chars_in_userinfo(userinfo)).to eq(safe_userinfo)
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
end
|