mechanize 2.14.0 → 2.14.2

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.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -1
  3. data/README.md +7 -0
  4. data/SECURITY.md +11 -0
  5. data/lib/mechanize/directory_saver.rb +2 -1
  6. data/lib/mechanize/file_saver.rb +2 -0
  7. data/lib/mechanize/http/agent.rb +83 -29
  8. data/lib/mechanize/parser.rb +33 -3
  9. data/lib/mechanize/test_case.rb +2 -9
  10. data/lib/mechanize/version.rb +1 -1
  11. data/lib/mechanize.rb +12 -2
  12. data/test/htdocs/frame_test.html +8 -6
  13. data/test/htdocs/relative/tc_relative_links.html +1 -1
  14. metadata +7 -174
  15. data/.autotest +0 -6
  16. data/.github/dependabot.yml +0 -11
  17. data/.github/workflows/ci.yml +0 -43
  18. data/.github/workflows/upstream.yml +0 -51
  19. data/.gitignore +0 -15
  20. data/.yardopts +0 -8
  21. data/Gemfile +0 -12
  22. data/Rakefile +0 -56
  23. data/examples/flickr_upload.rb +0 -22
  24. data/examples/latest_user_agents.rb +0 -100
  25. data/examples/mech-dump.rb +0 -5
  26. data/examples/proxy_req.rb +0 -7
  27. data/examples/rubygems.rb +0 -23
  28. data/examples/spider.rb +0 -22
  29. data/examples/wikipedia_links_to_philosophy.rb +0 -158
  30. data/mechanize.gemspec +0 -74
  31. data/test/data/htpasswd +0 -1
  32. data/test/data/server.crt +0 -16
  33. data/test/data/server.csr +0 -12
  34. data/test/data/server.key +0 -15
  35. data/test/data/server.pem +0 -15
  36. data/test/test_mechanize.rb +0 -1382
  37. data/test/test_mechanize_cookie.rb +0 -559
  38. data/test/test_mechanize_cookie_jar.rb +0 -615
  39. data/test/test_mechanize_directory_saver.rb +0 -60
  40. data/test/test_mechanize_download.rb +0 -102
  41. data/test/test_mechanize_element_not_found_error.rb +0 -16
  42. data/test/test_mechanize_file.rb +0 -118
  43. data/test/test_mechanize_file_connection.rb +0 -40
  44. data/test/test_mechanize_file_request.rb +0 -26
  45. data/test/test_mechanize_file_response.rb +0 -48
  46. data/test/test_mechanize_file_saver.rb +0 -22
  47. data/test/test_mechanize_form.rb +0 -1025
  48. data/test/test_mechanize_form_check_box.rb +0 -49
  49. data/test/test_mechanize_form_encoding.rb +0 -110
  50. data/test/test_mechanize_form_field.rb +0 -78
  51. data/test/test_mechanize_form_file_upload.rb +0 -21
  52. data/test/test_mechanize_form_image_button.rb +0 -13
  53. data/test/test_mechanize_form_keygen.rb +0 -34
  54. data/test/test_mechanize_form_multi_select_list.rb +0 -98
  55. data/test/test_mechanize_form_option.rb +0 -60
  56. data/test/test_mechanize_form_radio_button.rb +0 -96
  57. data/test/test_mechanize_form_select_list.rb +0 -81
  58. data/test/test_mechanize_form_textarea.rb +0 -53
  59. data/test/test_mechanize_headers.rb +0 -36
  60. data/test/test_mechanize_history.rb +0 -104
  61. data/test/test_mechanize_http_agent.rb +0 -1915
  62. data/test/test_mechanize_http_auth_challenge.rb +0 -64
  63. data/test/test_mechanize_http_auth_realm.rb +0 -56
  64. data/test/test_mechanize_http_auth_store.rb +0 -233
  65. data/test/test_mechanize_http_content_disposition_parser.rb +0 -167
  66. data/test/test_mechanize_http_www_authenticate_parser.rb +0 -204
  67. data/test/test_mechanize_image.rb +0 -9
  68. data/test/test_mechanize_link.rb +0 -171
  69. data/test/test_mechanize_page.rb +0 -295
  70. data/test/test_mechanize_page_encoding.rb +0 -215
  71. data/test/test_mechanize_page_frame.rb +0 -17
  72. data/test/test_mechanize_page_image.rb +0 -191
  73. data/test/test_mechanize_page_link.rb +0 -377
  74. data/test/test_mechanize_page_meta_refresh.rb +0 -151
  75. data/test/test_mechanize_parser.rb +0 -316
  76. data/test/test_mechanize_pluggable_parser.rb +0 -68
  77. data/test/test_mechanize_redirect_limit_reached_error.rb +0 -25
  78. data/test/test_mechanize_redirect_not_get_or_head_error.rb +0 -15
  79. data/test/test_mechanize_response_read_error.rb +0 -29
  80. data/test/test_mechanize_subclass.rb +0 -23
  81. data/test/test_mechanize_util.rb +0 -144
  82. data/test/test_mechanize_xml_file.rb +0 -30
  83. data/test/test_multi_select.rb +0 -120
@@ -1,64 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'mechanize/test_case'
3
-
4
- class TestMechanizeHttpAuthChallenge < Mechanize::TestCase
5
-
6
- def setup
7
- super
8
-
9
- @uri = URI 'http://example/'
10
- @AR = Mechanize::HTTP::AuthRealm
11
- @AC = Mechanize::HTTP::AuthChallenge
12
- @challenge = @AC.new 'Digest', { 'realm' => 'r' }, 'Digest realm=r'
13
- end
14
-
15
- def test_realm_basic
16
- @challenge.scheme = 'Basic'
17
-
18
- expected = @AR.new 'Basic', @uri, 'r'
19
-
20
- assert_equal expected, @challenge.realm(@uri + '/foo')
21
- end
22
-
23
- def test_realm_digest
24
- expected = @AR.new 'Digest', @uri, 'r'
25
-
26
- assert_equal expected, @challenge.realm(@uri + '/foo')
27
- end
28
-
29
- def test_realm_digest_case
30
- challenge = @AC.new 'Digest', { 'realm' => 'R' }, 'Digest realm=R'
31
-
32
- expected = @AR.new 'Digest', @uri, 'R'
33
-
34
- assert_equal expected, challenge.realm(@uri + '/foo')
35
- end
36
-
37
- def test_realm_unknown
38
- @challenge.scheme = 'Unknown'
39
-
40
- e = assert_raises Mechanize::Error do
41
- @challenge.realm(@uri + '/foo')
42
- end
43
-
44
- assert_equal 'unknown HTTP authentication scheme Unknown', e.message
45
- end
46
-
47
- def test_realm_name
48
- assert_equal 'r', @challenge.realm_name
49
- end
50
-
51
- def test_realm_name_case
52
- challenge = @AC.new 'Digest', { 'realm' => 'R' }, 'Digest realm=R'
53
-
54
- assert_equal 'R', challenge.realm_name
55
- end
56
-
57
- def test_realm_name_ntlm
58
- challenge = @AC.new 'Negotiate, NTLM'
59
-
60
- assert_nil challenge.realm_name
61
- end
62
-
63
- end
64
-
@@ -1,56 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'mechanize/test_case'
3
-
4
- class TestMechanizeHttpAuthRealm < Mechanize::TestCase
5
-
6
- def setup
7
- super
8
-
9
- @uri = URI 'http://example/'
10
- @AR = Mechanize::HTTP::AuthRealm
11
- @realm = @AR.new 'Digest', @uri, 'r'
12
- end
13
-
14
- def test_initialize
15
- assert_equal 'r', @realm.realm
16
-
17
- realm = @AR.new 'Digest', @uri, 'R'
18
- refute_equal 'r', realm.realm
19
-
20
- realm = @AR.new 'Digest', @uri, 'R'
21
- assert_equal 'R', realm.realm
22
-
23
- realm = @AR.new 'Digest', @uri, nil
24
- assert_nil realm.realm
25
- end
26
-
27
- def test_equals2
28
- other = @realm.dup
29
- assert_equal @realm, other
30
-
31
- other = @AR.new 'Basic', @uri, 'r'
32
- refute_equal @realm, other
33
-
34
- other = @AR.new 'Digest', URI('http://other.example/'), 'r'
35
- refute_equal @realm, other
36
-
37
- other = @AR.new 'Digest', @uri, 'R'
38
- refute_equal @realm, other
39
-
40
- other = @AR.new 'Digest', @uri, 's'
41
- refute_equal @realm, other
42
- end
43
-
44
- def test_hash
45
- h = {}
46
- h[@realm] = 1
47
-
48
- other = @realm.dup
49
- assert_equal 1, h[other]
50
-
51
- other = @AR.new 'Basic', @uri, 'r'
52
- assert_nil h[other]
53
- end
54
-
55
- end
56
-
@@ -1,233 +0,0 @@
1
- # coding: utf-8
2
- # frozen_string_literal: true
3
-
4
- require 'mechanize/test_case'
5
-
6
- class TestMechanizeHttpAuthStore < Mechanize::TestCase
7
-
8
- def setup
9
- super
10
-
11
- @store = Mechanize::HTTP::AuthStore.new
12
-
13
- @uri = URI.parse 'http://example/'
14
- end
15
-
16
- def test_add_auth
17
- @store.add_auth @uri + '/path', 'user', 'pass'
18
-
19
- expected = {
20
- @uri => {
21
- nil => ['user', 'pass', nil],
22
- }
23
- }
24
-
25
- assert_equal expected, @store.auth_accounts
26
- end
27
-
28
- def test_add_auth_domain
29
- @store.add_auth @uri + '/path', 'user1', 'pass', nil, 'domain'
30
-
31
- expected = {
32
- @uri => {
33
- nil => %w[user1 pass domain],
34
- }
35
- }
36
-
37
- assert_equal expected, @store.auth_accounts
38
-
39
- e = assert_raises ArgumentError do
40
- @store.add_auth @uri, 'user3', 'pass', 'realm', 'domain'
41
- end
42
-
43
- assert_equal 'NTLM domain given with realm which NTLM does not use',
44
- e.message
45
- end
46
-
47
- def test_add_auth_realm
48
- @store.add_auth @uri, 'user1', 'pass'
49
- @store.add_auth @uri, 'user2', 'pass', 'realm'
50
-
51
- expected = {
52
- @uri => {
53
- nil => ['user1', 'pass', nil],
54
- 'realm' => ['user2', 'pass', nil],
55
- }
56
- }
57
-
58
- assert_equal expected, @store.auth_accounts
59
- end
60
-
61
- def test_add_auth_realm_case
62
- @store.add_auth @uri, 'user1', 'pass', 'realm'
63
- @store.add_auth @uri, 'user2', 'pass', 'Realm'
64
-
65
- expected = {
66
- @uri => {
67
- 'realm' => ['user1', 'pass', nil],
68
- 'Realm' => ['user2', 'pass', nil],
69
- }
70
- }
71
-
72
- assert_equal expected, @store.auth_accounts
73
- end
74
-
75
- def test_add_auth_string
76
- @store.add_auth "#{@uri}/path", 'user', 'pass'
77
-
78
- expected = {
79
- @uri => {
80
- nil => ['user', 'pass', nil],
81
- }
82
- }
83
-
84
- assert_equal expected, @store.auth_accounts
85
- end
86
-
87
- def test_add_default_auth
88
- _, err = capture_io do
89
- @store.add_default_auth 'user', 'pass'
90
- end
91
-
92
- expected = ['user', 'pass', nil]
93
-
94
- assert_equal expected, @store.default_auth
95
-
96
- assert_match 'DISCLOSURE WITHOUT YOUR KNOWLEDGE', err
97
-
98
- capture_io do
99
- @store.add_default_auth 'user', 'pass', 'realm'
100
- end
101
-
102
- expected = %w[user pass realm]
103
-
104
- assert_equal expected, @store.default_auth
105
- end
106
-
107
- def test_credentials_eh
108
- challenges = [
109
- Mechanize::HTTP::AuthChallenge.new('Basic', 'realm' => 'r'),
110
- Mechanize::HTTP::AuthChallenge.new('Digest', 'realm' => 'r'),
111
- ]
112
-
113
- refute @store.credentials? @uri, challenges
114
-
115
- @store.add_auth @uri, 'user', 'pass'
116
-
117
- assert @store.credentials? @uri, challenges
118
- assert @store.credentials? "#{@uri}/path", challenges
119
- end
120
-
121
- def test_credentials_for
122
- assert_nil @store.credentials_for(@uri, 'realm')
123
-
124
- @store.add_auth @uri, 'user', 'pass', 'realm'
125
-
126
- assert_equal ['user', 'pass', nil], @store.credentials_for(@uri, 'realm')
127
- assert_equal ['user', 'pass', nil],
128
- @store.credentials_for(@uri.to_s, 'realm')
129
- assert_nil @store.credentials_for(@uri, 'other')
130
- end
131
-
132
- def test_credentials_for_default
133
- assert_nil @store.credentials_for(@uri, 'realm')
134
-
135
- capture_io do
136
- @store.add_default_auth 'user1', 'pass'
137
- end
138
-
139
- assert_equal ['user1', 'pass', nil], @store.credentials_for(@uri, 'realm')
140
-
141
- @store.add_auth @uri, 'user2', 'pass'
142
-
143
- assert_equal ['user2', 'pass', nil], @store.credentials_for(@uri, 'realm')
144
- assert_equal ['user2', 'pass', nil], @store.credentials_for(@uri, 'other')
145
- end
146
-
147
- def test_credentials_for_no_realm
148
- @store.add_auth @uri, 'user', 'pass' # no realm set
149
-
150
- assert_equal ['user', 'pass', nil], @store.credentials_for(@uri, 'realm')
151
- end
152
-
153
- def test_credentials_for_realm
154
- @store.add_auth @uri, 'user1', 'pass'
155
- @store.add_auth @uri, 'user2', 'pass', 'realm'
156
-
157
- assert_equal ['user2', 'pass', nil], @store.credentials_for(@uri, 'realm')
158
- assert_equal ['user1', 'pass', nil], @store.credentials_for(@uri, 'other')
159
- end
160
-
161
- def test_credentials_for_realm_case
162
- @store.add_auth @uri, 'user1', 'pass', 'realm'
163
- @store.add_auth @uri, 'user2', 'pass', 'Realm'
164
-
165
- assert_equal ['user1', 'pass', nil], @store.credentials_for(@uri, 'realm')
166
- assert_equal ['user2', 'pass', nil], @store.credentials_for(@uri, 'Realm')
167
- end
168
-
169
- def test_credentials_for_path
170
- @store.add_auth @uri, 'user', 'pass', 'realm'
171
-
172
- uri = @uri + '/path'
173
-
174
- assert_equal ['user', 'pass', nil], @store.credentials_for(uri, 'realm')
175
- end
176
-
177
- def test_remove_auth
178
- @store.remove_auth @uri
179
-
180
- assert_empty @store.auth_accounts
181
- end
182
-
183
- def test_remove_auth_both
184
- @store.add_auth @uri, 'user1', 'pass'
185
- @store.add_auth @uri, 'user2', 'pass', 'realm'
186
-
187
- uri = @uri + '/path'
188
-
189
- @store.remove_auth uri
190
-
191
- assert_empty @store.auth_accounts
192
- end
193
-
194
- def test_remove_auth_realm
195
- @store.add_auth @uri, 'user1', 'pass'
196
- @store.add_auth @uri, 'user2', 'pass', 'realm'
197
-
198
- @store.remove_auth @uri, 'realm'
199
-
200
- expected = {
201
- @uri => {
202
- nil => ['user1', 'pass', nil]
203
- }
204
- }
205
-
206
- assert_equal expected, @store.auth_accounts
207
- end
208
-
209
- def test_remove_auth_realm_case
210
- @store.add_auth @uri, 'user1', 'pass', 'realm'
211
- @store.add_auth @uri, 'user2', 'pass', 'Realm'
212
-
213
- @store.remove_auth @uri, 'Realm'
214
-
215
- expected = {
216
- @uri => {
217
- 'realm' => ['user1', 'pass', nil]
218
- }
219
- }
220
-
221
- assert_equal expected, @store.auth_accounts
222
- end
223
-
224
- def test_remove_auth_string
225
- @store.add_auth @uri, 'user1', 'pass'
226
-
227
- @store.remove_auth "#{@uri}/path"
228
-
229
- assert_empty @store.auth_accounts
230
- end
231
-
232
- end
233
-
@@ -1,167 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'mechanize/test_case'
3
-
4
- class TestMechanizeHttpContentDispositionParser < Mechanize::TestCase
5
-
6
- def setup
7
- super
8
-
9
- @parser = Mechanize::HTTP::ContentDispositionParser.new
10
- end
11
-
12
- def test_parse
13
- now = Time.at Time.now.to_i
14
-
15
- content_disposition = @parser.parse \
16
- 'attachment;' \
17
- 'filename=value;' \
18
- "creation-date=\"#{now.rfc822}\";" \
19
- "modification-date=\"#{(now + 1).rfc822}\";" \
20
- "read-date=\"#{(now + 2).rfc822}\";" \
21
- 'size=5;' \
22
- 'arbitrary=value'
23
-
24
- assert_equal 'attachment', content_disposition.type
25
- assert_equal 'value', content_disposition.filename
26
- assert_equal now, content_disposition.creation_date
27
- assert_equal((now + 1), content_disposition.modification_date)
28
- assert_equal((now + 2), content_disposition.read_date)
29
- assert_equal 5, content_disposition.size
30
- expected = { 'arbitrary' => 'value' }
31
- assert_equal expected, content_disposition.parameters
32
- end
33
-
34
- def test_parse_date_iso8601_fallback
35
- now = Time.at Time.now.to_i
36
-
37
- content_disposition = @parser.parse \
38
- 'attachment;' \
39
- 'filename=value;' \
40
- "creation-date=\"#{now.iso8601}\";" \
41
- "modification-date=\"#{(now + 1).iso8601}\""
42
-
43
- assert_equal 'attachment', content_disposition.type
44
- assert_equal 'value', content_disposition.filename
45
- assert_equal now, content_disposition.creation_date
46
- assert_equal((now + 1), content_disposition.modification_date)
47
- end
48
-
49
- def test_parse_date_invalid
50
- now = Time.at Time.now.to_i
51
-
52
- content_disposition = @parser.parse \
53
- 'attachment;' \
54
- 'filename=value;' \
55
- "creation-date=\"#{now.to_s}\";" \
56
- "modification-date=\"#{(now + 1).to_s}\""
57
-
58
- assert_nil content_disposition
59
- end
60
-
61
- def test_parse_header
62
- content_disposition = @parser.parse \
63
- 'content-disposition: attachment;filename=value', true
64
-
65
- assert_equal 'attachment', content_disposition.type
66
- assert_equal 'value', content_disposition.filename
67
- end
68
-
69
- def test_parse_no_type
70
- content_disposition = @parser.parse 'filename=value'
71
-
72
- assert_nil content_disposition.type
73
- assert_equal 'value', content_disposition.filename
74
- end
75
-
76
- def test_parse_semicolons
77
- content_disposition = @parser.parse 'attachment;;filename=value'
78
-
79
- assert_equal 'attachment', content_disposition.type
80
- assert_equal 'value', content_disposition.filename
81
- end
82
-
83
- def test_parse_quoted_size
84
- content_disposition = @parser.parse 'size="5"'
85
-
86
- assert_equal 5, content_disposition.size
87
- end
88
-
89
- def test_rfc_2045_quoted_string
90
- @parser.scanner = StringScanner.new '"text"'
91
-
92
- string = @parser.rfc_2045_quoted_string
93
-
94
- assert_equal 'text', string
95
- end
96
-
97
- def test_rfc_2045_quoted_string_bad
98
- @parser.scanner = StringScanner.new '"text'
99
-
100
- assert_nil @parser.rfc_2045_quoted_string
101
- end
102
-
103
- def test_rfc_2045_quoted_string_crlf
104
- @parser.scanner = StringScanner.new "\"multiline\\\r\n\ttext\""
105
-
106
- string = @parser.rfc_2045_quoted_string
107
-
108
- assert_equal "multiline\r\n\ttext", string
109
- end
110
-
111
- def test_rfc_2045_quoted_string_escape
112
- @parser.scanner = StringScanner.new "\"escape\\ text\""
113
-
114
- string = @parser.rfc_2045_quoted_string
115
-
116
- assert_equal 'escape text', string
117
- end
118
-
119
- def test_rfc_2045_quoted_string_escape_bad
120
- @parser.scanner = StringScanner.new '"escape\\'
121
-
122
- string = @parser.rfc_2045_quoted_string
123
-
124
- assert_nil string
125
- end
126
-
127
- def test_rfc_2045_quoted_string_folded
128
- @parser.scanner = StringScanner.new "\"multiline\r\n\ttext\""
129
-
130
- string = @parser.rfc_2045_quoted_string
131
-
132
- assert_equal 'multiline text', string
133
- end
134
-
135
- def test_rfc_2045_quoted_string_quote
136
- @parser.scanner = StringScanner.new '"escaped \\" here"'
137
-
138
- string = @parser.rfc_2045_quoted_string
139
-
140
- assert_equal 'escaped " here', string
141
- end
142
-
143
- def test_rfc_2045_quoted_string_quote_end
144
- @parser.scanner = StringScanner.new '"end \\""'
145
-
146
- string = @parser.rfc_2045_quoted_string
147
-
148
- assert_equal 'end "', string
149
- end
150
-
151
- def test_parse_uppercase
152
- content_disposition = @parser.parse \
153
- 'content-disposition: attachment; Filename=value', true
154
-
155
- assert_equal 'attachment', content_disposition.type
156
- assert_equal 'value', content_disposition.filename
157
- end
158
-
159
- def test_parse_filename_starting_with_escaped_quote
160
- content_disposition = @parser.parse \
161
- 'content-disposition: attachment; Filename="\"value\""', true
162
-
163
- assert_equal '"value"', content_disposition.filename
164
- end
165
-
166
- end
167
-