diff options
Diffstat (limited to 'spec/bundler/bundler/fetcher_spec.rb')
-rw-r--r-- | spec/bundler/bundler/fetcher_spec.rb | 126 |
1 files changed, 112 insertions, 14 deletions
diff --git a/spec/bundler/bundler/fetcher_spec.rb b/spec/bundler/bundler/fetcher_spec.rb index a104760075..e20f7e7c48 100644 --- a/spec/bundler/bundler/fetcher_spec.rb +++ b/spec/bundler/bundler/fetcher_spec.rb @@ -3,8 +3,8 @@ require "bundler/fetcher" RSpec.describe Bundler::Fetcher do - let(:uri) { Bundler::URI("https://example.com") } - let(:remote) { double("remote", :uri => uri, :original_uri => nil) } + let(:uri) { Gem::URI("https://example.com") } + let(:remote) { double("remote", uri: uri, original_uri: nil) } subject(:fetcher) { Bundler::Fetcher.new(remote) } @@ -45,9 +45,9 @@ RSpec.describe Bundler::Fetcher do end context "when a rubygems source mirror is set" do - let(:orig_uri) { Bundler::URI("http://zombo.com") } + let(:orig_uri) { Gem::URI("http://zombo.com") } let(:remote_with_mirror) do - double("remote", :uri => uri, :original_uri => orig_uri, :anonymized_uri => uri) + double("remote", uri: uri, original_uri: orig_uri, anonymized_uri: uri) end let(:fetcher) { Bundler::Fetcher.new(remote_with_mirror) } @@ -61,7 +61,7 @@ RSpec.describe Bundler::Fetcher do context "when there is no rubygems source mirror set" do let(:remote_no_mirror) do - double("remote", :uri => uri, :original_uri => nil, :anonymized_uri => uri) + double("remote", uri: uri, original_uri: nil, anonymized_uri: uri) end let(:fetcher) { Bundler::Fetcher.new(remote_no_mirror) } @@ -114,9 +114,9 @@ RSpec.describe Bundler::Fetcher do context "when gem ssl configuration is set" do before do allow(Gem.configuration).to receive_messages( - :http_proxy => nil, - :ssl_client_cert => "cert", - :ssl_ca_cert => "ca" + http_proxy: nil, + ssl_client_cert: "cert", + ssl_ca_cert: "ca" ) expect(File).to receive(:read).and_return("") expect(OpenSSL::X509::Certificate).to receive(:new).and_return("cert") @@ -143,20 +143,118 @@ RSpec.describe Bundler::Fetcher do describe "include CI information" do it "from one CI" do - with_env_vars("JENKINS_URL" => "foo") do + with_env_vars("CI" => nil, "JENKINS_URL" => "foo") do ci_part = fetcher.user_agent.split(" ").find {|x| x.start_with?("ci/") } - expect(ci_part).to match("jenkins") + cis = ci_part.split("/").last.split(",") + expect(cis).to include("jenkins") + expect(cis).not_to include("ci") end end it "from many CI" do - with_env_vars("TRAVIS" => "foo", "GITLAB_CI" => "gitlab", "CI_NAME" => "my_ci") do + with_env_vars("CI" => "true", "SEMAPHORE" => nil, "TRAVIS" => "foo", "GITLAB_CI" => "gitlab", "CI_NAME" => "MY_ci") do ci_part = fetcher.user_agent.split(" ").find {|x| x.start_with?("ci/") } - expect(ci_part).to match("travis") - expect(ci_part).to match("gitlab") - expect(ci_part).to match("my_ci") + cis = ci_part.split("/").last.split(",") + expect(cis).to include("ci", "gitlab", "my_ci", "travis") + expect(cis).not_to include("semaphore") end end end end + + describe "#fetch_spec" do + let(:name) { "name" } + let(:version) { "1.3.17" } + let(:platform) { "platform" } + let(:downloader) { double("downloader") } + let(:body) { double(Gem::Net::HTTP::Get, body: downloaded_data) } + + context "when attempting to load a Gem::Specification" do + let(:spec) { Gem::Specification.new(name, version) } + let(:downloaded_data) { Zlib::Deflate.deflate(Marshal.dump(spec)) } + + it "returns the spec" do + expect(Bundler::Fetcher::Downloader).to receive(:new).and_return(downloader) + expect(downloader).to receive(:fetch).once.and_return(body) + result = fetcher.fetch_spec([name, version, platform]) + expect(result).to eq(spec) + end + end + + context "when attempting to load an unexpected class" do + let(:downloaded_data) { Zlib::Deflate.deflate(Marshal.dump(3)) } + + it "raises a HTTPError error" do + expect(Bundler::Fetcher::Downloader).to receive(:new).and_return(downloader) + expect(downloader).to receive(:fetch).once.and_return(body) + expect { fetcher.fetch_spec([name, version, platform]) }.to raise_error(Bundler::HTTPError, /Gemspec .* contained invalid data/i) + end + end + end + + describe "#specs_with_retry" do + let(:downloader) { double(:downloader) } + let(:remote) { double(:remote, cache_slug: "slug", uri: uri, original_uri: nil, anonymized_uri: uri) } + let(:compact_index) { double(Bundler::Fetcher::CompactIndex, available?: true, api_fetcher?: true) } + let(:dependency) { double(Bundler::Fetcher::Dependency, available?: true, api_fetcher?: true) } + let(:index) { double(Bundler::Fetcher::Index, available?: true, api_fetcher?: false) } + + before do + allow(Bundler::Fetcher::CompactIndex).to receive(:new).and_return(compact_index) + allow(Bundler::Fetcher::Dependency).to receive(:new).and_return(dependency) + allow(Bundler::Fetcher::Index).to receive(:new).and_return(index) + end + + it "picks the first fetcher that works" do + expect(compact_index).to receive(:specs).with("name").and_return([["name", "1.2.3", "ruby"]]) + expect(dependency).not_to receive(:specs) + expect(index).not_to receive(:specs) + fetcher.specs_with_retry("name", double(Bundler::Source::Rubygems)) + end + + context "when APIs are not available" do + before do + allow(compact_index).to receive(:available?).and_return(false) + allow(dependency).to receive(:available?).and_return(false) + end + + it "uses the index" do + expect(compact_index).not_to receive(:specs) + expect(dependency).not_to receive(:specs) + expect(index).to receive(:specs).with("name").and_return([["name", "1.2.3", "ruby"]]) + + fetcher.specs_with_retry("name", double(Bundler::Source::Rubygems)) + end + end + end + + describe "#api_fetcher?" do + let(:downloader) { double(:downloader) } + let(:remote) { double(:remote, cache_slug: "slug", uri: uri, original_uri: nil, anonymized_uri: uri) } + let(:compact_index) { double(Bundler::Fetcher::CompactIndex, available?: false, api_fetcher?: true) } + let(:dependency) { double(Bundler::Fetcher::Dependency, available?: false, api_fetcher?: true) } + let(:index) { double(Bundler::Fetcher::Index, available?: true, api_fetcher?: false) } + + before do + allow(Bundler::Fetcher::CompactIndex).to receive(:new).and_return(compact_index) + allow(Bundler::Fetcher::Dependency).to receive(:new).and_return(dependency) + allow(Bundler::Fetcher::Index).to receive(:new).and_return(index) + end + + context "when an api fetcher is available" do + before do + allow(compact_index).to receive(:available?).and_return(true) + end + + it "is truthy" do + expect(fetcher).to be_api_fetcher + end + end + + context "when only the index fetcher is available" do + it "is falsey" do + expect(fetcher).not_to be_api_fetcher + end + end + end end |