ficon 0.4 → 0.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4e8577eb04ba2dceefb974b436520ff73b8c37f6beb04c85ac62f02e774bbc94
4
- data.tar.gz: 4196a3eb41905e40f0285eb132b3ae4d9e9c2c00f002584f6dc0b667893842db
3
+ metadata.gz: 95a5b1a8dba294c92d13f898bde371078e1927d67cb9e4af351608647f916d2f
4
+ data.tar.gz: 06f32b6dc310b8c7ea7dba49672f2ae85a8f1eaac890938414d27b031bf0808c
5
5
  SHA512:
6
- metadata.gz: afbea646a672f8654bd8ba76a628c373ca1c40dbf051af8937656f755f65872031a6fc88e6a223914469a5baf10e303fc47e770ddb3abbf70305c1e08ebe1714
7
- data.tar.gz: b08f3e0d30b5f93f503d03b5222938ab37e7c5fb423b5cbcf2df3fe217ed791aec4dc8cb8a32e540e41cd9bf06d7ea62b3bc062b159aa64452caa992c069de29
6
+ metadata.gz: bf4e5662d4b7322e559dd116524453025cd23d76407395c6da71ed7d15e8c8298f87ac97009c5ab52b551bfed6f1cc3bc61ba5f730e026340b09c9faef355161
7
+ data.tar.gz: df182b513fe144fca1d6a5eb6d5a2e58c4d92b69df063ce6df08a0567d7e7a83d9cef0c34a464778723f664e3650f95aee49b13814f1913133912ab81f83cc12
data/lib/ficon/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Ficon
2
- VERSION = "0.4"
2
+ VERSION = "0.6"
3
3
  end
data/lib/ficon.rb CHANGED
@@ -64,9 +64,15 @@ class Ficon
64
64
  end
65
65
 
66
66
  def process
67
- @site[:images] = self.class.site_images(@uri, doc) || []
68
- @site[:page_images] = self.class.page_images(@uri, doc) || []
69
- other_page_data
67
+ document = doc
68
+ if document
69
+ @site[:images] = self.class.site_images(@uri, document) || []
70
+ @site[:page_images] = self.class.page_images(@uri, document) || []
71
+ other_page_data(document)
72
+ else
73
+ @site[:images] = []
74
+ @site[:page_images] = []
75
+ end
70
76
  nil
71
77
  end
72
78
 
@@ -82,13 +88,9 @@ class Ficon
82
88
  report_lines.join("\n") + "\n"
83
89
  end
84
90
 
85
- def site_icons = @site[:images]
86
-
87
- def site_icon = site_icons&.first
88
-
89
- def page_images = @site[:page_images]
91
+ def site_icons = @site[:images] || []
90
92
 
91
- def page_image = page_images&.first
93
+ def page_images = @site[:page_images] || []
92
94
 
93
95
  def title = @site[:title]
94
96
 
@@ -98,11 +100,11 @@ class Ficon
98
100
  Cache.clear_cache
99
101
  end
100
102
 
101
- def other_page_data
102
- @site[:title] = doc.at_xpath("//meta[@property='og:title']/@content")&.value || @doc.at_xpath("//title")&.text&.strip
103
- @site[:description] = doc.at_xpath("//meta[@property='og:description']/@content")&.value
104
- canonical = doc.at_xpath("//link[@rel='canonical']/@href")&.value
105
- @site[:canonical] = canonical unless canonical == @url
103
+ def other_page_data(document)
104
+ @site[:title] = document.at_xpath("//meta[@property='og:title']/@content")&.value || document.at_xpath("//title")&.text&.strip
105
+ @site[:description] = document.at_xpath("//meta[@property='og:description']/@content")&.value
106
+ canonical = document.at_xpath("//link[@rel='canonical']/@href")&.value
107
+ @site[:canonical] = canonical unless canonical == @uri.to_s
106
108
  end
107
109
 
108
110
  def self.site_images(uri, doc)
@@ -137,6 +139,34 @@ class Ficon
137
139
  parsed_candidate.to_s
138
140
  end
139
141
 
142
+ def classify_response_status(response)
143
+ case response.code.to_i
144
+ when 200..299
145
+ ALIVE
146
+ when 404, 410
147
+ DEAD
148
+ when 401, 403, 429
149
+ BLOCKED
150
+ when 500..599
151
+ SICK
152
+ else
153
+ SICK
154
+ end
155
+ end
156
+
157
+ def classify_exception_status(exception)
158
+ case exception
159
+ when SocketError, Resolv::ResolvError
160
+ DEAD # DNS resolution failures
161
+ when Net::HTTPError, Timeout::Error, Errno::ECONNREFUSED
162
+ SICK # Network issues worth retrying
163
+ when OpenSSL::SSL::SSLError
164
+ SICK # SSL certificate errors
165
+ else
166
+ SICK # Default to retryable for unknown errors
167
+ end
168
+ end
169
+
140
170
  private
141
171
 
142
172
  def fetch_url(uri, redirect_limit = 5)
@@ -173,35 +203,28 @@ class Ficon
173
203
  end
174
204
  rescue => e
175
205
  @url_status = classify_exception_status(e)
206
+
207
+ # If HTTP request failed and we're using HTTP, try HTTPS automatically
208
+ if uri.scheme == "http" &&
209
+ !uri.to_s.include?("://localhost") &&
210
+ !uri.host.match?(/^\d+\.\d+\.\d+\.\d+$/)
211
+ puts "HTTP request failed, trying HTTPS for #{uri}"
212
+ https_uri = uri.dup
213
+ https_uri.scheme = "https"
214
+ https_uri.port = 443 if https_uri.port == 80
215
+
216
+ begin
217
+ https_response = fetch_url(https_uri, redirect_limit)
218
+ if https_response
219
+ puts "HTTPS request succeeded, using HTTPS URL"
220
+ return https_response
221
+ end
222
+ rescue => https_error
223
+ puts "HTTPS fallback also failed: #{https_error.inspect}"
224
+ end
225
+ end
226
+
176
227
  puts "Failed to fetch #{uri}: #{e.inspect}"
177
228
  nil
178
229
  end
179
-
180
- def classify_response_status(response)
181
- case response.code.to_i
182
- when 200..299
183
- ALIVE
184
- when 404, 410
185
- DEAD
186
- when 401, 403, 429
187
- BLOCKED
188
- when 500..599
189
- SICK
190
- else
191
- SICK
192
- end
193
- end
194
-
195
- def classify_exception_status(exception)
196
- case exception
197
- when SocketError, Resolv::ResolutionError
198
- DEAD # DNS resolution failures
199
- when Net::HTTPError, Timeout::Error, Errno::ECONNREFUSED
200
- SICK # Network issues worth retrying
201
- when OpenSSL::SSL::SSLError
202
- SICK # SSL certificate errors
203
- else
204
- SICK # Default to retryable for unknown errors
205
- end
206
- end
207
230
  end
data/test/ficon_test.rb CHANGED
@@ -1,72 +1,178 @@
1
- #require 'rubygems'
2
- require 'debug'
1
+ # require 'rubygems'
2
+ require "debug"
3
+ require "resolv"
3
4
 
4
5
  require "minitest/autorun"
5
6
 
6
7
  PathHere = File.dirname(__FILE__)
7
8
  $LOAD_PATH.unshift File.join(PathHere, "..", "lib")
8
9
 
9
- require 'ficon'
10
-
11
- SiteTests = []
12
- SiteTests << { html: %Q{<meta name="msapplication-TileImage" content="https://s.yimg.com/pw/images/favicon-msapplication-tileimage.png"/> }, value: 'https://s.yimg.com/pw/images/favicon-msapplication-tileimage.png' }
13
- SiteTests << { html: %Q{<link rel="shortcut icon" type="image/ico" href="https://s.yimg.com/pw/favicon.ico"> }, value: 'https://s.yimg.com/pw/favicon.ico' }
14
- SiteTests << { html: %Q{<link href="/apple-touch-icon.png" rel="apple-touch-icon-precomposed">}, value: 'https://site.com/apple-touch-icon.png' }
15
- SiteTests << { html: %Q{<link rel="shortcut icon" href="/wp-content/themes/torrentfreakredux/assets/img/icons/favicon.png">}, value: 'https://site.com/wp-content/themes/torrentfreakredux/assets/img/icons/favicon.png' }
16
- SiteTests << { html: %Q{<link rel="apple-touch-icon-precomposed" href="/wp-content/themes/torrentfreakredux/assets/img/icons/57.png">}, value: 'https://site.com/wp-content/themes/torrentfreakredux/assets/img/icons/57.png' }
17
- SiteTests << { html: %Q{<link rel="apple-touch-icon-precomposed" sizes="114x114" href="/wp-content/themes/torrentfreakredux/assets/img/icons/114.png">}, value: 'https://site.com/wp-content/themes/torrentfreakredux/assets/img/icons/114.png' }
18
- SiteTests << { html: %Q{<link rel="apple-touch-icon-precomposed" sizes="72x72" href="/wp-content/themes/torrentfreakredux/assets/img/icons/72.png">}, value: 'https://site.com/wp-content/themes/torrentfreakredux/assets/img/icons/72.png' }
19
- SiteTests << { html: %Q{<link rel="apple-touch-icon-precomposed" sizes="144x144" href="/wp-content/themes/torrentfreakredux/assets/img/icons/144.png">}, value: 'https://site.com/wp-content/themes/torrentfreakredux/assets/img/icons/144.png' }
20
- SiteTests << { html: %Q{<link rel="shortcut icon" href="/favicon.png">}, value: 'https://site.com/favicon.png' }
21
- SiteTests << { html: %Q{<link rel="shortcut icon" href="favicon.ico" />}, value: 'https://site.com/favicon.ico' }
22
- SiteTests << { html: %Q{<link rel="apple-touch-icon" href="/apple-touch-icon.png">}, value: 'https://site.com/apple-touch-icon.png' }
23
- SiteTests << { html: %Q{<link rel="shortcut icon" href="http://example.com/myicon.ico" />}, value: 'http://example.com/myicon.ico'}
24
- SiteTests << { html: %Q{<link rel="icon" href="http://example.com/image.ico" />}, value: 'http://example.com/image.ico' }
25
- SiteTests << { html: %Q{<link rel="icon" type="image/vnd.microsoft.icon" href="http://example.com/image.ico" />}, value: 'http://example.com/image.ico' }
26
- SiteTests << { html: %Q{<link rel="icon" type="image/png" href="http://example.com/image.png" />}, value: 'http://example.com/image.png' }
27
- SiteTests << { html: %Q{<link rel="icon" type="image/gif" href="http://example.com/image.gif" />}, value: 'http://example.com/image.gif' }
28
- SiteTests << { html: %Q{<link rel="icon" type="image/x-icon" href="http://example.com/image.ico"/>}, value: 'http://example.com/image.ico' }
29
- SiteTests << { html: %Q{<link rel="shortcut icon" href="https://fbstatic-a.akamaihd.net/rsrc.php/yl/r/H3nktOa7ZMg.ico" />}, value: 'https://fbstatic-a.akamaihd.net/rsrc.php/yl/r/H3nktOa7ZMg.ico' }
30
- SiteTests << { html: %Q{<link rel="icon" type="image/vnd.microsoft.icon" href="/viconline/img/favicon.ico?1393375504" />}, value: 'https://site.com/viconline/img/favicon.ico?1393375504' }
31
- SiteTests << { html: %Q{<link rel="shortcut icon" type="image/x-icon" href="/viconline/img/favicon.ico?1393375504" />}, value: 'https://site.com/viconline/img/favicon.ico?1393375504' }
32
- SiteTests << { html: %Q{<meta name="msapplication-TileImage" content="/win8-tile-144.png"/><meta name="msapplication-TileColor" content="#00aced"/>}, value: 'https://site.com/win8-tile-144.png' }
33
-
34
- PageTests = []
35
- PageTests << { html: %Q{<meta property="og:image" content="https://www.facebook.com/images/fb_icon_325x325.png" />}, value: 'https://www.facebook.com/images/fb_icon_325x325.png' }
10
+ require "ficon"
36
11
 
12
+ SiteTests = []
13
+ SiteTests << {html: %(<meta name="msapplication-TileImage" content="https://s.yimg.com/pw/images/favicon-msapplication-tileimage.png"/> ), value: "https://s.yimg.com/pw/images/favicon-msapplication-tileimage.png"}
14
+ SiteTests << {html: %(<link rel="shortcut icon" type="image/ico" href="https://s.yimg.com/pw/favicon.ico"> ), value: "https://s.yimg.com/pw/favicon.ico"}
15
+ SiteTests << {html: %(<link href="/apple-touch-icon.png" rel="apple-touch-icon-precomposed">), value: "https://site.com/apple-touch-icon.png"}
16
+ SiteTests << {html: %(<link rel="shortcut icon" href="/wp-content/themes/torrentfreakredux/assets/img/icons/favicon.png">), value: "https://site.com/wp-content/themes/torrentfreakredux/assets/img/icons/favicon.png"}
17
+ SiteTests << {html: %(<link rel="apple-touch-icon-precomposed" href="/wp-content/themes/torrentfreakredux/assets/img/icons/57.png">), value: "https://site.com/wp-content/themes/torrentfreakredux/assets/img/icons/57.png"}
18
+ SiteTests << {html: %(<link rel="apple-touch-icon-precomposed" sizes="114x114" href="/wp-content/themes/torrentfreakredux/assets/img/icons/114.png">), value: "https://site.com/wp-content/themes/torrentfreakredux/assets/img/icons/114.png"}
19
+ SiteTests << {html: %(<link rel="apple-touch-icon-precomposed" sizes="72x72" href="/wp-content/themes/torrentfreakredux/assets/img/icons/72.png">), value: "https://site.com/wp-content/themes/torrentfreakredux/assets/img/icons/72.png"}
20
+ SiteTests << {html: %(<link rel="apple-touch-icon-precomposed" sizes="144x144" href="/wp-content/themes/torrentfreakredux/assets/img/icons/144.png">), value: "https://site.com/wp-content/themes/torrentfreakredux/assets/img/icons/144.png"}
21
+ SiteTests << {html: %(<link rel="shortcut icon" href="/favicon.png">), value: "https://site.com/favicon.png"}
22
+ SiteTests << {html: %(<link rel="shortcut icon" href="favicon.ico" />), value: "https://site.com/favicon.ico"}
23
+ SiteTests << {html: %(<link rel="apple-touch-icon" href="/apple-touch-icon.png">), value: "https://site.com/apple-touch-icon.png"}
24
+ SiteTests << {html: %(<link rel="shortcut icon" href="http://example.com/myicon.ico" />), value: "http://example.com/myicon.ico"}
25
+ SiteTests << {html: %(<link rel="icon" href="http://example.com/image.ico" />), value: "http://example.com/image.ico"}
26
+ SiteTests << {html: %(<link rel="icon" type="image/vnd.microsoft.icon" href="http://example.com/image.ico" />), value: "http://example.com/image.ico"}
27
+ SiteTests << {html: %(<link rel="icon" type="image/png" href="http://example.com/image.png" />), value: "http://example.com/image.png"}
28
+ SiteTests << {html: %(<link rel="icon" type="image/gif" href="http://example.com/image.gif" />), value: "http://example.com/image.gif"}
29
+ SiteTests << {html: %(<link rel="icon" type="image/x-icon" href="http://example.com/image.ico"/>), value: "http://example.com/image.ico"}
30
+ SiteTests << {html: %(<link rel="shortcut icon" href="https://fbstatic-a.akamaihd.net/rsrc.php/yl/r/H3nktOa7ZMg.ico" />), value: "https://fbstatic-a.akamaihd.net/rsrc.php/yl/r/H3nktOa7ZMg.ico"}
31
+ SiteTests << {html: %(<link rel="icon" type="image/vnd.microsoft.icon" href="/viconline/img/favicon.ico?1393375504" />), value: "https://site.com/viconline/img/favicon.ico?1393375504"}
32
+ SiteTests << {html: %(<link rel="shortcut icon" type="image/x-icon" href="/viconline/img/favicon.ico?1393375504" />), value: "https://site.com/viconline/img/favicon.ico?1393375504"}
33
+ SiteTests << {html: %(<meta name="msapplication-TileImage" content="/win8-tile-144.png"/><meta name="msapplication-TileColor" content="#00aced"/>), value: "https://site.com/win8-tile-144.png"}
34
+
35
+ PageTests = []
36
+ PageTests << {html: %(<meta property="og:image" content="https://www.facebook.com/images/fb_icon_325x325.png" />), value: "https://www.facebook.com/images/fb_icon_325x325.png"}
37
37
 
38
38
  class FiconTest < Minitest::Test
39
- ENV['FICON_DB']=File.join( File.dirname(__FILE__), 'test.db')
39
+ ENV["FICON_DB"] = File.join(File.dirname(__FILE__), "test.db")
40
40
  def test_html_chunks
41
41
  SiteTests.each do |t|
42
- result = Ficon.site_images('https://site.com', Nokogiri::HTML(t[:html]) )[0]
43
- assert result&.url == t[:value], "Seaching |#{t[:html]}| expected #{t[:value]}, got #{result}"
42
+ result = Ficon.site_images("https://site.com", Nokogiri::HTML(t[:html]))[0]
43
+ assert result&.url == t[:value], "Seaching |#{t[:html]}| expected #{t[:value]}, got #{result}"
44
44
  end
45
45
  PageTests.each do |t|
46
- result = Ficon.page_images('https://site.com', Nokogiri::HTML(t[:html]) )[0]
47
- assert result&.url == t[:value], "Seaching |#{t[:html]}| expected #{t[:value]}, got #{result}"
46
+ result = Ficon.page_images("https://site.com", Nokogiri::HTML(t[:html]))[0]
47
+ assert result&.url == t[:value], "Seaching |#{t[:html]}| expected #{t[:value]}, got #{result}"
48
48
  end
49
49
  end
50
50
 
51
51
  def test_tile_color_extraction
52
- html = %Q{<meta name="msapplication-TileImage" content="/win8-tile-144.png"/><meta name="msapplication-TileColor" content="#00aced"/>}
53
- result = Ficon.site_images('https://site.com', Nokogiri::HTML(html))[0]
54
- assert_equal 'https://site.com/win8-tile-144.png', result.url
55
- assert_equal '#00aced', result.tile_color
52
+ html = %(<meta name="msapplication-TileImage" content="/win8-tile-144.png"/><meta name="msapplication-TileColor" content="#00aced"/>)
53
+ result = Ficon.site_images("https://site.com", Nokogiri::HTML(html))[0]
54
+ assert_equal "https://site.com/win8-tile-144.png", result.url
55
+ assert_equal "#00aced", result.tile_color
56
56
  end
57
57
 
58
58
  def test_custom_user_agent
59
59
  # Test default user agent
60
- ficon_default = Ficon.new('https://example.com')
60
+ ficon_default = Ficon.new("https://example.com")
61
61
  assert_match(/^FiconBot\/0\.\d+/, ficon_default.user_agent)
62
-
62
+
63
63
  # Test custom user agent
64
- custom_agent = 'MyApp/1.0 (Custom Bot)'
65
- ficon_custom = Ficon.new('https://example.com', user_agent: custom_agent)
64
+ custom_agent = "MyApp/1.0 (Custom Bot)"
65
+ ficon_custom = Ficon.new("https://example.com", user_agent: custom_agent)
66
66
  assert_equal custom_agent, ficon_custom.user_agent
67
-
67
+
68
68
  # Test user agent can be changed after initialization
69
- ficon_custom.user_agent = 'Changed/2.0'
70
- assert_equal 'Changed/2.0', ficon_custom.user_agent
69
+ ficon_custom.user_agent = "Changed/2.0"
70
+ assert_equal "Changed/2.0", ficon_custom.user_agent
71
+ end
72
+
73
+ def test_response_status_classification
74
+ ficon = Ficon.new("https://example.com")
75
+
76
+ # Test ALIVE status (2xx)
77
+ assert_equal Ficon::ALIVE, ficon.classify_response_status(mock_response(200))
78
+ assert_equal Ficon::ALIVE, ficon.classify_response_status(mock_response(201))
79
+ assert_equal Ficon::ALIVE, ficon.classify_response_status(mock_response(299))
80
+
81
+ # Test DEAD status (404, 410)
82
+ assert_equal Ficon::DEAD, ficon.classify_response_status(mock_response(404))
83
+ assert_equal Ficon::DEAD, ficon.classify_response_status(mock_response(410))
84
+
85
+ # Test BLOCKED status (401, 403, 429)
86
+ assert_equal Ficon::BLOCKED, ficon.classify_response_status(mock_response(401))
87
+ assert_equal Ficon::BLOCKED, ficon.classify_response_status(mock_response(403))
88
+ assert_equal Ficon::BLOCKED, ficon.classify_response_status(mock_response(429))
89
+
90
+ # Test SICK status (5xx and others)
91
+ assert_equal Ficon::SICK, ficon.classify_response_status(mock_response(500))
92
+ assert_equal Ficon::SICK, ficon.classify_response_status(mock_response(502))
93
+ assert_equal Ficon::SICK, ficon.classify_response_status(mock_response(503))
94
+ assert_equal Ficon::SICK, ficon.classify_response_status(mock_response(300)) # Other codes default to SICK
95
+ end
96
+
97
+ def test_exception_status_classification
98
+ ficon = Ficon.new("https://example.com")
99
+
100
+ # Test DEAD status (DNS and resolution errors)
101
+ assert_equal Ficon::DEAD, ficon.classify_exception_status(SocketError.new)
102
+ assert_equal Ficon::DEAD, ficon.classify_exception_status(Resolv::ResolvError.new)
103
+
104
+ # Test SICK status (network and timeout errors)
105
+ assert_equal Ficon::SICK, ficon.classify_exception_status(Timeout::Error.new)
106
+ assert_equal Ficon::SICK, ficon.classify_exception_status(Errno::ECONNREFUSED.new)
107
+ assert_equal Ficon::SICK, ficon.classify_exception_status(OpenSSL::SSL::SSLError.new)
108
+ assert_equal Ficon::SICK, ficon.classify_exception_status(Net::HTTPError.new("error", nil))
109
+
110
+ # Test default to SICK for unknown exceptions
111
+ assert_equal Ficon::SICK, ficon.classify_exception_status(StandardError.new)
112
+ end
113
+
114
+ def test_http_to_https_fallback_conditions
115
+ # Test that localhost URLs are not converted to HTTPS
116
+ ficon_localhost = Ficon.allocate
117
+ uri_localhost = URI("http://localhost:3000/test")
118
+
119
+ # Mock the fetch_url method to simulate HTTP failure
120
+ def ficon_localhost.fetch_url(uri, redirect_limit = 5)
121
+ if uri.scheme == "http" && !uri.to_s.include?("://localhost") && !uri.host.match?(/^\d+\.\d+\.\d+\.\d+$/)
122
+ # This should not be reached for localhost
123
+ raise "Should not attempt HTTPS fallback for localhost"
124
+ end
125
+ nil
126
+ end
127
+
128
+ # This should not raise an exception
129
+ result = ficon_localhost.send(:fetch_url, uri_localhost)
130
+ assert_nil result
131
+
132
+ # Test that IP addresses are not converted to HTTPS
133
+ ficon_ip = Ficon.allocate
134
+ uri_ip = URI("http://192.168.1.1/test")
135
+
136
+ def ficon_ip.fetch_url(uri, redirect_limit = 5)
137
+ if uri.scheme == "http" && !uri.to_s.include?("://localhost") && !uri.host.match?(/^\d+\.\d+\.\d+\.\d+$/)
138
+ # This should not be reached for IP addresses
139
+ raise "Should not attempt HTTPS fallback for IP addresses"
140
+ end
141
+ nil
142
+ end
143
+
144
+ # This should not raise an exception
145
+ result = ficon_ip.send(:fetch_url, uri_ip)
146
+ assert_nil result
147
+ end
148
+
149
+ def test_https_port_conversion
150
+ # Test that port 80 is converted to 443 when switching to HTTPS
151
+ http_uri = URI("http://example.com:80/test")
152
+ assert_equal 80, http_uri.port
153
+
154
+ https_uri = http_uri.dup
155
+ https_uri.scheme = "https"
156
+ https_uri.port = 443 if https_uri.port == 80
157
+
158
+ assert_equal "https", https_uri.scheme
159
+ assert_equal 443, https_uri.port
160
+
161
+ # Test that custom ports are preserved
162
+ http_custom_uri = URI("http://example.com:8080/test")
163
+ https_custom_uri = http_custom_uri.dup
164
+ https_custom_uri.scheme = "https"
165
+ https_custom_uri.port = 443 if https_custom_uri.port == 80
166
+
167
+ assert_equal "https", https_custom_uri.scheme
168
+ assert_equal 8080, https_custom_uri.port # Should remain unchanged
169
+ end
170
+
171
+ private
172
+
173
+ def mock_response(code)
174
+ response = Object.new
175
+ response.define_singleton_method(:code) { code }
176
+ response
71
177
  end
72
178
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ficon
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.4'
4
+ version: '0.6'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Milne