File: C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/roadie-4.0.0/spec/lib/roadie/net_http_provider_spec.rb
# frozen_string_literal: true
require 'spec_helper'
require 'roadie/rspec'
require 'shared_examples/asset_provider'
module Roadie
describe NetHttpProvider do
around do |example|
WebMock.disable_net_connect!
example.run
WebMock.allow_net_connect!
end
url = "http://example.com/style.css".freeze
it_behaves_like(
"roadie asset provider",
valid_name: "http://example.com/green.css",
invalid_name: "http://example.com/red.css"
) do
before do
stub_request(:get, "http://example.com/green.css").and_return(body: +"p { color: green; }")
stub_request(:get, "http://example.com/red.css").and_return(status: 404, body: "Not here!")
end
end
it "can download over HTTPS" do
stub_request(:get, "https://example.com/style.css").and_return(body: +"p { color: green; }")
expect {
NetHttpProvider.new.find_stylesheet!("https://example.com/style.css")
}.to_not raise_error
end
it "assumes HTTPS when given a scheme-less URL" do
# Some people might re-use the same template as they use on a webpage,
# and browsers support URLs without a scheme in them, replacing the
# scheme with the current one. There's no "current" scheme when doing
# asset inlining, but the scheme-less URL implies that there should exist
# both a HTTP and a HTTPS endpoint. Let's take the secure one in that
# case!
stub_request(:get, "https://example.com/style.css").and_return(body: +"p { color: green; }")
expect {
NetHttpProvider.new.find_stylesheet!("//example.com/style.css")
}.to_not raise_error
end
it "applies encoding from the response" do
# Net::HTTP always returns the body string as a byte-encoded string
# (US-ASCII). The headers will indicate what charset the client should
# use when trying to make sense of these bytes.
stub_request(:get, url).and_return(
body: (+%(p::before { content: "l\xF6ve" })).force_encoding("US-ASCII"),
headers: {"Content-Type" => "text/css;charset=ISO-8859-1"},
)
# Seems like CssParser strips out the non-ascii character for some
# reason.
# stylesheet = NetHttpProvider.new.find_stylesheet!(url)
# expect(stylesheet.to_s).to eq('p::before{content:"löve"}')
allow(Stylesheet).to receive(:new).and_return(instance_double(Stylesheet))
NetHttpProvider.new.find_stylesheet!(url)
expect(Stylesheet).to have_received(:new).with(url, 'p::before { content: "löve" }')
end
it "assumes UTF-8 encoding if server headers do not specify a charset" do
stub_request(:get, url).and_return(
body: (+%(p::before { content: "Åh nej" })).force_encoding("US-ASCII"),
headers: {"Content-Type" => "text/css"},
)
# Seems like CssParser strips out the non-ascii characters for some
# reason.
# stylesheet = NetHttpProvider.new.find_stylesheet!(url)
# expect(stylesheet.to_s).to eq('p::before{content:"Åh nej"}')
allow(Stylesheet).to receive(:new).and_return(instance_double(Stylesheet))
NetHttpProvider.new.find_stylesheet!(url)
expect(Stylesheet).to have_received(:new).with(url, 'p::before { content: "Åh nej" }')
end
describe "error handling" do
it "handles timeouts" do
stub_request(:get, url).and_timeout
expect {
NetHttpProvider.new.find_stylesheet!(url)
}.to raise_error CssNotFound, /timeout/i
expect { NetHttpProvider.new.find_stylesheet(url) }.to_not raise_error
end
it "displays response code and beginning of message body" do
stub_request(:get, url).and_return(
status: 503,
body: "Whoah there! Didn't you see we have a service window at this
time? It's kind of disrespectful not to remember everything I tell
you all the time!"
)
expect {
NetHttpProvider.new.find_stylesheet!(url)
}.to raise_error CssNotFound, /503.*whoah/i
end
end
describe "whitelist" do
it "can have a whitelist of host names" do
provider = NetHttpProvider.new(whitelist: ["example.com", "foo.bar"])
expect(provider.whitelist).to eq Set["example.com", "foo.bar"]
end
it "defaults to empty whitelist" do
expect(NetHttpProvider.new.whitelist).to eq Set[]
expect(NetHttpProvider.new(whitelist: nil).whitelist).to eq Set[]
end
it "will not download from other hosts if set" do
provider = NetHttpProvider.new(whitelist: ["whitelisted.example.com"])
whitelisted_url = "http://whitelisted.example.com/style.css"
other_url = "http://www.example.com/style.css"
whitelisted_request = stub_request(:get, whitelisted_url).and_return(body: +"x")
other_request = stub_request(:get, other_url).and_return(body: +"x")
expect(provider.find_stylesheet(other_url)).to be_nil
expect {
provider.find_stylesheet!(other_url)
}.to raise_error CssNotFound, /whitelist/
expect {
expect(provider.find_stylesheet(whitelisted_url)).to_not be_nil
provider.find_stylesheet!(whitelisted_url)
}.to_not raise_error
expect(whitelisted_request).to have_been_made.twice
expect(other_request).to_not have_been_made
end
it "is displayed in the string representation" do
expect(NetHttpProvider.new(whitelist: ["bar.baz"]).to_s).to include "bar.baz"
end
it "raises error when given invalid hostnames" do
expect { NetHttpProvider.new(whitelist: [nil]) }.to raise_error(ArgumentError)
expect { NetHttpProvider.new(whitelist: [""]) }.to raise_error(ArgumentError)
expect { NetHttpProvider.new(whitelist: ["."]) }.to raise_error(ArgumentError)
expect { NetHttpProvider.new(whitelist: ["http://foo.bar"]) }.to raise_error(ArgumentError)
expect { NetHttpProvider.new(whitelist: ["foo/bar"]) }.to raise_error(ArgumentError)
end
end
end
end