aboutsummaryrefslogtreecommitdiffstats
path: root/spec
diff options
context:
space:
mode:
authorSamuel E. Giddins <segiddins@segiddins.me>2015-07-31 00:05:17 -0700
committerSamuel Giddins <segiddins@segiddins.me>2016-01-25 10:45:41 -0600
commitfb8d40c3462751e5853f76e2cd342b8b9a4b4430 (patch)
treeef4033054565ce039aff39ed304fdbf3e2a547d4 /spec
parentb3ad3f5a947645a23be6bc2c98d9655a73df2a7d (diff)
downloadbundler-fb8d40c3462751e5853f76e2cd342b8b9a4b4430.tar.gz
Add integration specs for the compact index
Diffstat (limited to 'spec')
-rw-r--r--spec/install/gems/compact_index_spec.rb633
-rw-r--r--spec/support/artifice/compact_index.rb36
-rw-r--r--spec/support/artifice/compact_index_api_missing.rb16
-rw-r--r--spec/support/artifice/compact_index_basic_authentication.rb13
-rw-r--r--spec/support/artifice/compact_index_creds_diff_host.rb38
-rw-r--r--spec/support/artifice/compact_index_extra.rb31
-rw-r--r--spec/support/artifice/compact_index_extra_api.rb51
-rw-r--r--spec/support/artifice/compact_index_extra_missing.rb15
-rw-r--r--spec/support/artifice/compact_index_forbidden.rb11
-rw-r--r--spec/support/artifice/compact_index_host_redirect.rb19
-rw-r--r--spec/support/artifice/compact_index_redirects.rb19
-rw-r--r--spec/support/artifice/compact_index_strict_basic_authentication.rb18
-rw-r--r--spec/support/artifice/endpoint_500.rb18
13 files changed, 868 insertions, 50 deletions
diff --git a/spec/install/gems/compact_index_spec.rb b/spec/install/gems/compact_index_spec.rb
new file mode 100644
index 00000000..85e28ad4
--- /dev/null
+++ b/spec/install/gems/compact_index_spec.rb
@@ -0,0 +1,633 @@
+require "spec_helper"
+
+describe "compact index api" do
+ let(:source_hostname) { "localgemserver.test" }
+ let(:source_uri) { "http://#{source_hostname}" }
+
+ fit "should use the API" do
+ gemfile <<-G
+ source "#{source_uri}"
+ gem "rack"
+ G
+
+ bundle :install, :artifice => "compact_index"
+ expect(out).to include("Fetching source index from #{source_uri}")
+ should_be_installed "rack 1.0.0"
+ end
+
+ it "should URI encode gem names" do
+ gemfile <<-G
+ source "#{source_uri}"
+ gem " sinatra"
+ G
+
+ bundle :install, :artifice => "compact_index"
+ expect(out).to include("' sinatra' is not a valid gem name because it contains whitespace.")
+ end
+
+ it "should handle nested dependencies" do
+ gemfile <<-G
+ source "#{source_uri}"
+ gem "rails"
+ G
+
+ bundle :install, :artifice => "compact_index"
+ expect(out).to include("Fetching source index from #{source_uri}/")
+ should_be_installed(
+ "rails 2.3.2",
+ "actionpack 2.3.2",
+ "activerecord 2.3.2",
+ "actionmailer 2.3.2",
+ "activeresource 2.3.2",
+ "activesupport 2.3.2")
+ end
+
+ it "should handle multiple gem dependencies on the same gem" do
+ gemfile <<-G
+ source "#{source_uri}"
+ gem "net-sftp"
+ G
+
+ bundle :install, :artifice => "compact_index"
+ should_be_installed "net-sftp 1.1.1"
+ end
+
+ it "should use the endpoint when using --deployment" do
+ gemfile <<-G
+ source "#{source_uri}"
+ gem "rack"
+ G
+ bundle :install, :artifice => "compact_index"
+
+ bundle "install --deployment", :artifice => "compact_index"
+ expect(out).to include("Fetching source index from #{source_uri}")
+ should_be_installed "rack 1.0.0"
+ end
+
+ it "handles git dependencies that are in rubygems" do
+ build_git "foo" do |s|
+ s.executables = "foobar"
+ s.add_dependency "rails", "2.3.2"
+ end
+
+ gemfile <<-G
+ source "#{source_uri}"
+ git "file:///#{lib_path("foo-1.0")}" do
+ gem 'foo'
+ end
+ G
+
+ bundle :install, :artifice => "compact_index"
+
+ should_be_installed("rails 2.3.2")
+ end
+
+ it "handles git dependencies that are in rubygems using --deployment" do
+ build_git "foo" do |s|
+ s.executables = "foobar"
+ s.add_dependency "rails", "2.3.2"
+ end
+
+ gemfile <<-G
+ source "#{source_uri}"
+ gem 'foo', :git => "file:///#{lib_path("foo-1.0")}"
+ G
+
+ bundle :install, :artifice => "compact_index"
+
+ bundle "install --deployment", :artifice => "compact_index"
+
+ should_be_installed("rails 2.3.2")
+ end
+
+ it "doesn't fail if you only have a git gem with no deps when using --deployment" do
+ build_git "foo"
+ gemfile <<-G
+ source "#{source_uri}"
+ gem 'foo', :git => "file:///#{lib_path("foo-1.0")}"
+ G
+
+ bundle "install", :artifice => "compact_index"
+ bundle "install --deployment", :artifice => "compact_index"
+
+ expect(exitstatus).to eq(0) if exitstatus
+ should_be_installed("foo 1.0")
+ end
+
+ it "falls back when the API errors out" do
+ simulate_platform mswin
+
+ gemfile <<-G
+ source "#{source_uri}"
+ gem "rcov"
+ G
+
+ bundle :install, :fakeweb => "windows"
+ expect(out).to include("Fetching source index from #{source_uri}")
+ should_be_installed "rcov 1.0.0"
+ end
+
+ it "falls back when the API URL returns 403 Forbidden" do
+ gemfile <<-G
+ source "#{source_uri}"
+ gem "rack"
+ G
+
+ bundle :install, :verbose => true, :artifice => "compact_index_forbidden"
+ expect(out).to include("Fetching gem metadata from #{source_uri}")
+ should_be_installed "rack 1.0.0"
+ end
+
+ it "handles host redirects" do
+ gemfile <<-G
+ source "#{source_uri}"
+ gem "rack"
+ G
+
+ bundle :install, :artifice => "compact_index_host_redirect"
+ should_be_installed "rack 1.0.0"
+ end
+
+ it "handles host redirects without Net::HTTP::Persistent" do
+ gemfile <<-G
+ source "#{source_uri}"
+ gem "rack"
+ G
+
+ FileUtils.mkdir_p lib_path
+ File.open(lib_path("disable_net_http_persistent.rb"), "w") do |h|
+ h.write <<-H
+ module Kernel
+ alias require_without_disabled_net_http require
+ def require(*args)
+ raise LoadError, 'simulated' if args.first == 'openssl' && !caller.grep(/vendored_persistent/).empty?
+ require_without_disabled_net_http(*args)
+ end
+ end
+ H
+ end
+
+ bundle :install, :artifice => "compact_index_host_redirect", :requires => [lib_path("disable_net_http_persistent.rb")]
+ expect(out).to_not match(/Too many redirects/)
+ should_be_installed "rack 1.0.0"
+ end
+
+ it "timeouts when Bundler::Fetcher redirects too much" do
+ gemfile <<-G
+ source "#{source_uri}"
+ gem "rack"
+ G
+
+ bundle :install, :artifice => "compact_index_redirects"
+ expect(out).to match(/Too many redirects/)
+ end
+
+ context "when --full-index is specified" do
+ it "should use the modern index for install" do
+ gemfile <<-G
+ source "#{source_uri}"
+ gem "rack"
+ G
+
+ bundle "install --full-index", :artifice => "compact_index"
+ expect(out).to include("Fetching source index from #{source_uri}")
+ should_be_installed "rack 1.0.0"
+ end
+
+ it "should use the modern index for update" do
+ gemfile <<-G
+ source "#{source_uri}"
+ gem "rack"
+ G
+
+ bundle "update --full-index", :artifice => "compact_index"
+ expect(out).to include("Fetching source index from #{source_uri}")
+ should_be_installed "rack 1.0.0"
+ end
+ end
+
+ it "fetches again when more dependencies are found in subsequent sources" do
+ build_repo2 do
+ build_gem "back_deps" do |s|
+ s.add_dependency "foo"
+ end
+ FileUtils.rm_rf Dir[gem_repo2("gems/foo-*.gem")]
+ end
+
+ gemfile <<-G
+ source "#{source_uri}"
+ source "#{source_uri}/extra"
+ gem "back_deps"
+ G
+
+ bundle :install, :artifice => "compact_index_extra"
+ should_be_installed "back_deps 1.0"
+ end
+
+ it "fetches gem versions even when those gems are already installed" do
+ gemfile <<-G
+ source "#{source_uri}"
+ gem "rack", "1.0.0"
+ G
+ bundle :install, :artifice => "compact_index_extra_api"
+ should_be_installed "rack 1.0.0"
+
+ build_repo4 do
+ build_gem "rack", "1.2" do |s|
+ s.executables = "rackup"
+ end
+ end
+
+ gemfile <<-G
+ source "#{source_uri}" do; end
+ source "#{source_uri}/extra"
+ gem "rack", "1.2"
+ G
+ bundle :install, :artifice => "compact_index_extra_api"
+ should_be_installed "rack 1.2"
+ end
+
+ it "considers all possible versions of dependencies from all api gem sources" do
+ # In this scenario, the gem "somegem" only exists in repo4. It depends on specific version of activesupport that
+ # exists only in repo1. There happens also be a version of activesupport in repo4, but not the one that version 1.0.0
+ # of somegem wants. This test makes sure that bundler actually finds version 1.2.3 of active support in the other
+ # repo and installs it.
+ build_repo4 do
+ build_gem "activesupport", "1.2.0"
+ build_gem "somegem", "1.0.0" do |s|
+ s.add_dependency "activesupport", "1.2.3" #This version exists only in repo1
+ end
+ end
+
+ gemfile <<-G
+ source "#{source_uri}"
+ source "#{source_uri}/extra"
+ gem 'somegem', '1.0.0'
+ G
+
+ bundle :install, :artifice => "compact_index_extra_api"
+
+ should_be_installed "somegem 1.0.0"
+ should_be_installed "activesupport 1.2.3"
+ end
+
+ it "prints API output properly with back deps" do
+ build_repo2 do
+ build_gem "back_deps" do |s|
+ s.add_dependency "foo"
+ end
+ FileUtils.rm_rf Dir[gem_repo2("gems/foo-*.gem")]
+ end
+
+ gemfile <<-G
+ source "#{source_uri}"
+ source "#{source_uri}/extra"
+ gem "back_deps"
+ G
+
+ bundle :install, :artifice => "compact_index_extra"
+
+ expect(out).to include("Fetching source index from http://localgemserver.test/")
+ expect(out).to include("Fetching source index from http://localgemserver.test/extra")
+ end
+
+ it "does not fetch every spec if the index of gems is large when doing back deps" do
+ build_repo2 do
+ build_gem "back_deps" do |s|
+ s.add_dependency "foo"
+ end
+ build_gem "missing"
+ # need to hit the limit
+ 1.upto(Bundler::Source::Rubygems::API_REQUEST_LIMIT) do |i|
+ build_gem "gem#{i}"
+ end
+
+ FileUtils.rm_rf Dir[gem_repo2("gems/foo-*.gem")]
+ end
+
+ gemfile <<-G
+ source "#{source_uri}"
+ source "#{source_uri}/extra"
+ gem "back_deps"
+ G
+
+ bundle :install, :artifice => "compact_index_extra_missing"
+ should_be_installed "back_deps 1.0"
+ end
+
+ it "uses the endpoint if all sources support it" do
+ gemfile <<-G
+ source "#{source_uri}"
+
+ gem 'foo'
+ G
+
+ bundle :install, :artifice => "compact_index_api_missing"
+ should_be_installed "foo 1.0"
+ end
+
+ it "fetches again when more dependencies are found in subsequent sources using --deployment" do
+ build_repo2 do
+ build_gem "back_deps" do |s|
+ s.add_dependency "foo"
+ end
+ FileUtils.rm_rf Dir[gem_repo2("gems/foo-*.gem")]
+ end
+
+ gemfile <<-G
+ source "#{source_uri}"
+ source "#{source_uri}/extra"
+ gem "back_deps"
+ G
+
+ bundle :install, :artifice => "compact_index_extra"
+
+ bundle "install --deployment", :artifice => "compact_index_extra"
+ should_be_installed "back_deps 1.0"
+ end
+
+ it "does not refetch if the only unmet dependency is bundler" do
+ gemfile <<-G
+ source "#{source_uri}"
+
+ gem "bundler_dep"
+ G
+
+ bundle :install, :artifice => "compact_index"
+ expect(out).to include("Fetching source index from #{source_uri}")
+ end
+
+ it "should install when EndpointSpecification has a bin dir owned by root", :sudo => true do
+ sudo "mkdir -p #{system_gem_path("bin")}"
+ sudo "chown -R root #{system_gem_path("bin")}"
+
+ gemfile <<-G
+ source "#{source_uri}"
+ gem "rails"
+ G
+ bundle :install, :artifice => "compact_index"
+ should_be_installed "rails 2.3.2"
+ end
+
+ it "installs the binstubs" do
+ gemfile <<-G
+ source "#{source_uri}"
+ gem "rack"
+ G
+
+ bundle "install --binstubs", :artifice => "compact_index"
+
+ gembin "rackup"
+ expect(out).to eq("1.0.0")
+ end
+
+ it "installs the bins when using --path and uses autoclean" do
+ gemfile <<-G
+ source "#{source_uri}"
+ gem "rack"
+ G
+
+ bundle "install --path vendor/bundle", :artifice => "compact_index"
+
+ expect(vendored_gems("bin/rackup")).to exist
+ end
+
+ it "installs the bins when using --path and uses bundle clean" do
+ gemfile <<-G
+ source "#{source_uri}"
+ gem "rack"
+ G
+
+ bundle "install --path vendor/bundle --no-clean", :artifice => "compact_index"
+
+ expect(vendored_gems("bin/rackup")).to exist
+ end
+
+ it "prints post_install_messages" do
+ gemfile <<-G
+ source "#{source_uri}"
+ gem 'rack-obama'
+ G
+
+ bundle :install, :artifice => "compact_index"
+ expect(out).to include("Post-install message from rack:")
+ end
+
+ it "should display the post install message for a dependency" do
+ gemfile <<-G
+ source "#{source_uri}"
+ gem 'rack_middleware'
+ G
+
+ bundle :install, :artifice => "compact_index"
+ expect(out).to include("Post-install message from rack:")
+ expect(out).to include("Rack's post install message")
+ end
+
+ context "when using basic authentication" do
+ let(:user) { "user" }
+ let(:password) { "pass" }
+ let(:basic_auth_source_uri) do
+ uri = URI.parse(source_uri)
+ uri.user = user
+ uri.password = password
+
+ uri
+ end
+
+ it "passes basic authentication details and strips out creds" do
+ gemfile <<-G
+ source "#{basic_auth_source_uri}"
+ gem "rack"
+ G
+
+ bundle :install, :artifice => "compact_index_basic_authentication"
+ expect(out).not_to include("#{user}:#{password}")
+ should_be_installed "rack 1.0.0"
+ end
+
+ it "strips http basic authentication creds for modern index" do
+ gemfile <<-G
+ source "#{basic_auth_source_uri}"
+ gem "rack"
+ G
+
+ bundle :install, :artifice => "endopint_marshal_fail_basic_authentication"
+ expect(out).not_to include("#{user}:#{password}")
+ should_be_installed "rack 1.0.0"
+ end
+
+ it "strips http basic auth creds when it can't reach the server" do
+ gemfile <<-G
+ source "#{basic_auth_source_uri}"
+ gem "rack"
+ G
+
+ bundle :install, :artifice => "endpoint_500"
+ expect(out).not_to include("#{user}:#{password}")
+ end
+
+ it "strips http basic auth creds when warning about ambiguous sources" do
+ gemfile <<-G
+ source "#{basic_auth_source_uri}"
+ source "file://#{gem_repo1}"
+ gem "rack"
+ G
+
+ bundle :install, :artifice => "compact_index_basic_authentication"
+ expect(out).to include("Warning: the gem 'rack' was found in multiple sources.")
+ expect(out).not_to include("#{user}:#{password}")
+ should_be_installed "rack 1.0.0"
+ end
+
+ it "does not pass the user / password to different hosts on redirect" do
+ gemfile <<-G
+ source "#{basic_auth_source_uri}"
+ gem "rack"
+ G
+
+ bundle :install, :artifice => "compact_index_creds_diff_host"
+ should_be_installed "rack 1.0.0"
+ end
+
+ describe "with authentication details in bundle config" do
+ before do
+ gemfile <<-G
+ source "#{source_uri}"
+ gem "rack"
+ G
+ end
+
+ it "reads authentication details by host name from bundle config" do
+ bundle "config #{source_hostname} #{user}:#{password}"
+
+ bundle :install, :artifice => "compact_index_strict_basic_authentication"
+
+ expect(out).to include("Fetching source index from #{source_uri}")
+ should_be_installed "rack 1.0.0"
+ end
+
+ it "reads authentication details by full url from bundle config" do
+ # The trailing slash is necessary here; Fetcher canonicalizes the URI.
+ bundle "config #{source_uri}/ #{user}:#{password}"
+
+ bundle :install, :artifice => "compact_index_strict_basic_authentication"
+
+ expect(out).to include("Fetching source index from #{source_uri}")
+ should_be_installed "rack 1.0.0"
+ end
+
+ it "should use the API" do
+ bundle "config #{source_hostname} #{user}:#{password}"
+ bundle :install, :artifice => "compact_index_strict_basic_authentication"
+ expect(out).to include("Fetching source index from #{source_uri}")
+ should_be_installed "rack 1.0.0"
+ end
+
+ it "prefers auth supplied in the source uri" do
+ gemfile <<-G
+ source "#{basic_auth_source_uri}"
+ gem "rack"
+ G
+
+ bundle "config #{source_hostname} otheruser:wrong"
+
+ bundle :install, :artifice => "compact_index_strict_basic_authentication"
+ should_be_installed "rack 1.0.0"
+ end
+
+ it "shows instructions if auth is not provided for the source" do
+ bundle :install, :artifice => "compact_index_strict_basic_authentication"
+ expect(out).to include("bundle config #{source_hostname} username:password")
+ end
+
+ it "fails if authentication has already been provided, but failed" do
+ bundle "config #{source_hostname} #{user}:wrong"
+
+ bundle :install, :artifice => "compact_index_strict_basic_authentication"
+ expect(out).to include("Bad username or password")
+ end
+ end
+
+ describe "with no password" do
+ let(:password) { nil }
+
+ it "passes basic authentication details" do
+ gemfile <<-G
+ source "#{basic_auth_source_uri}"
+ gem "rack"
+ G
+
+ bundle :install, :artifice => "compact_index_basic_authentication"
+ should_be_installed "rack 1.0.0"
+ end
+ end
+ end
+
+ context "when ruby is compiled without openssl" do
+ before do
+ # Install a monkeypatch that reproduces the effects of openssl being
+ # missing when the fetcher runs, as happens in real life. The reason
+ # we can't just overwrite openssl.rb is that Artifice uses it.
+ bundled_app("broken_ssl").mkpath
+ bundled_app("broken_ssl/openssl.rb").open("w") do |f|
+ f.write <<-RUBY
+ raise LoadError, "cannot load such file -- openssl"
+ RUBY
+ end
+ end
+
+ it "explains what to do to get it" do
+ gemfile <<-G
+ source "#{source_uri.gsub(/http/, "https")}"
+ gem "rack"
+ G
+
+ bundle :install, :env => { "RUBYOPT" => "-I#{bundled_app("broken_ssl")}" }
+ expect(out).to include("OpenSSL")
+ end
+ end
+
+ context "when SSL certificate verification fails" do
+ it "explains what happened" do
+ # Install a monkeypatch that reproduces the effects of openssl raising
+ # a certificate validation error when Rubygems tries to connect.
+ gemfile <<-G
+ class Net::HTTP
+ def start
+ raise OpenSSL::SSL::SSLError, "certificate verify failed"
+ end
+ end
+
+ source "#{source_uri.gsub(/http/, "https")}"
+ gem "rack"
+ G
+
+ bundle :install
+ expect(out).to match(/could not verify the SSL certificate/i)
+ end
+ end
+
+ context ".gemrc with sources is present" do
+ before do
+ File.open(home(".gemrc"), "w") do |file|
+ file.puts({ :sources => ["https://rubygems.org"] }.to_yaml)
+ end
+ end
+
+ after do
+ home(".gemrc").rmtree
+ end
+
+ it "uses other sources declared in the Gemfile" do
+ gemfile <<-G
+ source "#{source_uri}"
+ gem 'rack'
+ G
+
+ bundle "install", :artifice => "compact_index_forbidden"
+
+ expect(exitstatus).to eq(0) if exitstatus
+ end
+ end
+end
diff --git a/spec/support/artifice/compact_index.rb b/spec/support/artifice/compact_index.rb
index 94759b01..40bbbc66 100644
--- a/spec/support/artifice/compact_index.rb
+++ b/spec/support/artifice/compact_index.rb
@@ -1,19 +1,9 @@
-require File.expand_path("../../path.rb", __FILE__)
-require File.expand_path("../../../../lib/bundler/deprecate", __FILE__)
-include Spec::Path
+require File.expand_path("../endpoint", __FILE__)
-# Set up pretend http gem server with FakeWeb
-$LOAD_PATH.unshift "#{Dir[base_system_gems.join("gems/artifice*/lib")].first}"
-$LOAD_PATH.unshift "#{Dir[base_system_gems.join("gems/rack-*/lib")].first}"
-$LOAD_PATH.unshift "#{Dir[base_system_gems.join("gems/rack-*/lib")].last}"
-$LOAD_PATH.unshift "#{Dir[base_system_gems.join("gems/tilt*/lib")].first}"
-$LOAD_PATH.unshift "#{Dir[base_system_gems.join("gems/sinatra*/lib")].first}"
$LOAD_PATH.unshift "#{Dir[base_system_gems.join("gems/compact_index*/lib")].first}"
-require "artifice"
require "compact_index"
-require "sinatra/base"
-class CompactIndexAPI < Sinatra::Base
+class CompactIndexAPI < Endpoint
helpers do
def load_spec(name, version, platform, gem_repo)
full_name = "#{name}-#{version}"
@@ -86,29 +76,9 @@ class CompactIndexAPI < Sinatra::Base
get "/info/:name" do
etag_response do
specs = gems.select { |s| s[:name] == params[:name] }
- CompactIndex.info(specs).tap { |i| puts i }
+ CompactIndex.info(specs)
end
end
-
- get "/quick/Marshal.4.8/:id" do
- redirect "/fetch/actual/gem/#{params[:id]}"
- end
-
- get "/fetch/actual/gem/:id" do
- File.read("#{gem_repo1}/quick/Marshal.4.8/#{params[:id]}")
- end
-
- get "/gems/:id" do
- File.read("#{gem_repo1}/gems/#{params[:id]}")
- end
-
- get "/specs.4.8.gz" do
- File.read("#{gem_repo1}/specs.4.8.gz")
- end
-
- get "/prerelease_specs.4.8.gz" do
- File.read("#{gem_repo1}/prerelease_specs.4.8.gz")
- end
end
Artifice.activate_with(CompactIndexAPI)
diff --git a/spec/support/artifice/compact_index_api_missing.rb b/spec/support/artifice/compact_index_api_missing.rb
new file mode 100644
index 00000000..db6528b8
--- /dev/null
+++ b/spec/support/artifice/compact_index_api_missing.rb
@@ -0,0 +1,16 @@
+require File.expand_path("../compact_index", __FILE__)
+
+Artifice.deactivate
+
+class CompactIndexApiMissing < CompactIndexAPI
+ get "/fetch/actual/gem/:id" do
+ $stderr.puts params[:id]
+ if params[:id] == "rack-1.0.gemspec.rz"
+ halt 404
+ else
+ File.read("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}")
+ end
+ end
+end
+
+Artifice.activate_with(CompactIndexApiMissing)
diff --git a/spec/support/artifice/compact_index_basic_authentication.rb b/spec/support/artifice/compact_index_basic_authentication.rb
new file mode 100644
index 00000000..5ddcdf7f
--- /dev/null
+++ b/spec/support/artifice/compact_index_basic_authentication.rb
@@ -0,0 +1,13 @@
+require File.expand_path("../compact_index", __FILE__)
+
+Artifice.deactivate
+
+class CompactIndexBasicAuthentication < CompactIndexAPI
+ before do
+ unless env["HTTP_AUTHORIZATION"]
+ halt 401, "Authentication info not supplied"
+ end
+ end
+end
+
+Artifice.activate_with(CompactIndexBasicAuthentication)
diff --git a/spec/support/artifice/compact_index_creds_diff_host.rb b/spec/support/artifice/compact_index_creds_diff_host.rb
new file mode 100644
index 00000000..f2ea9d96
--- /dev/null
+++ b/spec/support/artifice/compact_index_creds_diff_host.rb
@@ -0,0 +1,38 @@
+require File.expand_path("../compact_index", __FILE__)
+
+Artifice.deactivate
+
+class CompactIndexCredsDiffHost < CompactIndexAPI
+ helpers do
+ def auth
+ @auth ||= Rack::Auth::Basic::Request.new(request.env)
+ end
+
+ def authorized?
+ auth.provided? && auth.basic? && auth.credentials && auth.credentials == ["user", "pass"]
+ end
+
+ def protected!
+ unless authorized?
+ response["WWW-Authenticate"] = %(Basic realm="Testing HTTP Auth")
+ throw(:halt, [401, "Not authorized\n"])
+ end
+ end
+ end
+
+ before do
+ protected! unless request.path_info.include?("/no/creds/")
+ end
+
+ get "/gems/:id" do
+ redirect "http://diffhost.com/no/creds/#{params[:id]}"
+ end
+
+ get "/no/creds/:id" do
+ if request.host.include?("diffhost") && !auth.provided?
+ File.read("#{gem_repo1}/gems/#{params[:id]}")
+ end
+ end
+end
+
+Artifice.activate_with(CompactIndexCredsDiffHost)
diff --git a/spec/support/artifice/compact_index_extra.rb b/spec/support/artifice/compact_index_extra.rb
new file mode 100644
index 00000000..d5cf00d8
--- /dev/null
+++ b/spec/support/artifice/compact_index_extra.rb
@@ -0,0 +1,31 @@
+require File.expand_path("../compact_index", __FILE__)
+
+Artifice.deactivate
+
+class CompactIndexExtra < CompactIndexAPI
+ get "/extra/versions" do
+ halt 404
+ end
+
+ get "/extra/specs.4.8.gz" do
+ File.read("#{gem_repo2}/specs.4.8.gz")
+ end
+
+ get "/extra/prerelease_specs.4.8.gz" do
+ File.read("#{gem_repo2}/prerelease_specs.4.8.gz")
+ end
+
+ get "/extra/quick/Marshal.4.8/:id" do
+ redirect "/extra/fetch/actual/gem/#{params[:id]}"
+ end
+
+ get "/extra/fetch/actual/gem/:id" do
+ File.read("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}")
+ end
+
+ get "/extra/gems/:id" do
+ File.read("#{gem_repo2}/gems/#{params[:id]}")
+ end
+end
+
+Artifice.activate_with(CompactIndexExtra)
diff --git a/spec/support/artifice/compact_index_extra_api.rb b/spec/support/artifice/compact_index_extra_api.rb
new file mode 100644
index 00000000..bd056291
--- /dev/null
+++ b/spec/support/artifice/compact_index_extra_api.rb
@@ -0,0 +1,51 @@
+require File.expand_path("../compact_index", __FILE__)
+
+Artifice.deactivate
+
+class CompactIndexExtraApi < CompactIndexAPI
+ get "/extra/names" do
+ etag_response do
+ CompactIndex.names(gems(gem_repo4).map(&:name))
+ end
+ end
+
+ get "/extra/versions" do
+ etag_response do
+ file = tmp('versions.list')
+ file.delete if file.file?
+ file = CompactIndex::VersionsFile.new(file.to_path)
+ versions = gems(gem_repo4).group_by { |s| s[:name] }
+ file.update_with(versions)
+ CompactIndex.versions(file, [])
+ end
+ end
+
+ get "/extra/info/:name" do
+ etag_response do
+ specs = gems(gem_repo4).select { |s| s[:name] == params[:name] }
+ CompactIndex.info(specs)
+ end
+ end
+
+ get "/extra/specs.4.8.gz" do
+ File.read("#{gem_repo4}/specs.4.8.gz")
+ end
+
+ get "/extra/prerelease_specs.4.8.gz" do
+ File.read("#{gem_repo4}/prerelease_specs.4.8.gz")
+ end
+
+ get "/extra/quick/Marshal.4.8/:id" do
+ redirect "/extra/fetch/actual/gem/#{params[:id]}"
+ end
+
+ get "/extra/fetch/actual/gem/:id" do
+ File.read("#{gem_repo4}/quick/Marshal.4.8/#{params[:id]}")
+ end
+
+ get "/extra/gems/:id" do
+ File.read("#{gem_repo4}/gems/#{params[:id]}")
+ end
+end
+
+Artifice.activate_with(CompactIndexExtraApi)
diff --git a/spec/support/artifice/compact_index_extra_missing.rb b/spec/support/artifice/compact_index_extra_missing.rb
new file mode 100644
index 00000000..48fffd51
--- /dev/null
+++ b/spec/support/artifice/compact_index_extra_missing.rb
@@ -0,0 +1,15 @@
+require File.expand_path("../compact_index_extra", __FILE__)
+
+Artifice.deactivate
+
+class CompactIndexExtraMissing < CompactIndexExtra
+ get "/extra/fetch/actual/gem/:id" do
+ if params[:id] == "missing-1.0.gemspec.rz"
+ halt 404
+ else
+ File.read("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}")
+ end
+ end
+end
+
+Artifice.activate_with(CompactIndexExtraMissing)
diff --git a/spec/support/artifice/compact_index_forbidden.rb b/spec/support/artifice/compact_index_forbidden.rb
new file mode 100644
index 00000000..09d03bc8
--- /dev/null
+++ b/spec/support/artifice/compact_index_forbidden.rb
@@ -0,0 +1,11 @@
+require File.expand_path("../compact_index", __FILE__)
+
+Artifice.deactivate
+
+class CompactIndexForbidden < CompactIndexAPI
+ get "/versions" do
+ halt 403
+ end
+end
+
+Artifice.activate_with(CompactIndexForbidden)
diff --git a/spec/support/artifice/compact_index_host_redirect.rb b/spec/support/artifice/compact_index_host_redirect.rb
new file mode 100644
index 00000000..2e53cc78
--- /dev/null
+++ b/spec/support/artifice/compact_index_host_redirect.rb
@@ -0,0 +1,19 @@
+require File.expand_path("../compact_index", __FILE__)
+
+Artifice.deactivate
+
+class CompactIndexHostRedirect < CompactIndexAPI
+ get "/fetch/actual/gem/:id", :host_name => "localgemserver.test" do
+ redirect "http://bundler.localgemserver.test#{request.path_info}"
+ end
+
+ get "/versions" do
+ status 404
+ end
+
+ get "/api/v1/dependencies" do
+ status 404
+ end
+end
+
+Artifice.activate_with(CompactIndexHostRedirect)
diff --git a/spec/support/artifice/compact_index_redirects.rb b/spec/support/artifice/compact_index_redirects.rb
new file mode 100644
index 00000000..256e73d7
--- /dev/null
+++ b/spec/support/artifice/compact_index_redirects.rb
@@ -0,0 +1,19 @@
+require File.expand_path("../compact_index", __FILE__)
+
+Artifice.deactivate
+
+class CompactIndexRedirect < CompactIndexAPI
+ get "/fetch/actual/gem/:id" do
+ redirect "/fetch/actual/gem/#{params[:id]}"
+ end
+
+ get "/versions" do
+ status 404
+ end
+
+ get "/api/v1/dependencies" do
+ status 404
+ end
+end
+
+Artifice.activate_with(CompactIndexRedirect)
diff --git a/spec/support/artifice/compact_index_strict_basic_authentication.rb b/spec/support/artifice/compact_index_strict_basic_authentication.rb
new file mode 100644
index 00000000..bb1e794b
--- /dev/null
+++ b/spec/support/artifice/compact_index_strict_basic_authentication.rb
@@ -0,0 +1,18 @@
+require File.expand_path("../compact_index", __FILE__)
+
+Artifice.deactivate
+
+class CompactIndexStrictBasicAuthentication < CompactIndexAPI
+ before do
+ unless env["HTTP_AUTHORIZATION"]
+ halt 401, "Authentication info not supplied"
+ end
+
+ # Only accepts password == "password"
+ unless env["HTTP_AUTHORIZATION"] == "Basic dXNlcjpwYXNz"
+ halt 403, "Authentication failed"
+ end
+ end
+end
+
+Artifice.activate_with(CompactIndexStrictBasicAuthentication)
diff --git a/spec/support/artifice/endpoint_500.rb b/spec/support/artifice/endpoint_500.rb
index 41076bf2..2812a0d2 100644
--- a/spec/support/artifice/endpoint_500.rb
+++ b/spec/support/artifice/endpoint_500.rb
@@ -13,23 +13,7 @@ require "sinatra/base"
Artifice.deactivate
class Endpoint500 < Sinatra::Base
- get "/quick/Marshal.4.8/:id" do
- halt 500
- end
-
- get "/fetch/actual/gem/:id" do
- halt 500
- end
-
- get "/gems/:id" do
- halt 500
- end
-
- get "/api/v1/dependencies" do
- halt 500
- end
-
- get "/specs.4.8.gz" do
+ before do
halt 500
end
end