webmock 1.8.6 → 3.14.0

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