summaryrefslogtreecommitdiff
path: root/test/rubygems/test_gem_commands_push_command.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/rubygems/test_gem_commands_push_command.rb')
-rw-r--r--test/rubygems/test_gem_commands_push_command.rb284
1 files changed, 205 insertions, 79 deletions
diff --git a/test/rubygems/test_gem_commands_push_command.rb b/test/rubygems/test_gem_commands_push_command.rb
index 1bbd341eca..a7a18ff4ab 100644
--- a/test/rubygems/test_gem_commands_push_command.rb
+++ b/test/rubygems/test_gem_commands_push_command.rb
@@ -1,6 +1,9 @@
# frozen_string_literal: true
-require_relative 'helper'
-require 'rubygems/commands/push_command'
+
+require_relative "helper"
+require_relative "multifactor_auth_utilities"
+require "rubygems/commands/push_command"
+require "rubygems/config_file"
class TestGemCommandsPushCommand < Gem::TestCase
def setup
@@ -12,7 +15,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
Gem.host = Gem::DEFAULT_HOST
Gem.configuration.disable_default_gem_server = false
- @gems_dir = File.join @tempdir, 'gems'
+ @gems_dir = File.join @tempdir, "gems"
@cache_dir = File.join @gemhome, "cache"
FileUtils.mkdir @gems_dir
@@ -21,10 +24,10 @@ class TestGemCommandsPushCommand < Gem::TestCase
"ed244fbf2b1a52e012da8616c512fa47f9aa5250"
@spec, @path = util_gem "freewill", "1.0.0"
- @host = 'https://rubygems.example'
+ @host = "https://rubygems.example"
@api_key = Gem.configuration.rubygems_api_key
- @fetcher = Gem::FakeFetcher.new
+ @fetcher = Gem::MultifactorAuthFetcher.new
Gem::RemoteFetcher.fetcher = @fetcher
@cmd = Gem::Commands::PushCommand.new
@@ -55,9 +58,9 @@ class TestGemCommandsPushCommand < Gem::TestCase
@cmd.send_gem(@path)
end
- assert_match %r{Pushing gem to #{@host}...}, @ui.output
+ assert_match(/Pushing gem to #{@host}.../, @ui.output)
- assert_equal Net::HTTP::Post, @fetcher.last_request.class
+ assert_equal Gem::Net::HTTP::Post, @fetcher.last_request.class
assert_equal Gem.read_binary(@path), @fetcher.last_request.body
assert_equal File.size(@path), @fetcher.last_request["Content-Length"].to_i
assert_equal "application/octet-stream", @fetcher.last_request["Content-Type"]
@@ -68,32 +71,32 @@ class TestGemCommandsPushCommand < Gem::TestCase
def test_execute
@response = "Successfully registered gem: freewill (1.0.0)"
- @fetcher.data["#{Gem.host}/api/v1/gems"] = [@response, 200, 'OK']
+ @fetcher.data["#{Gem.host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
@cmd.options[:args] = [@path]
@cmd.execute
- assert_equal Net::HTTP::Post, @fetcher.last_request.class
+ assert_equal Gem::Net::HTTP::Post, @fetcher.last_request.class
assert_equal Gem.read_binary(@path), @fetcher.last_request.body
assert_equal "application/octet-stream",
@fetcher.last_request["Content-Type"]
end
def test_execute_host
- host = 'https://other.example'
+ host = "https://other.example"
@response = "Successfully registered gem: freewill (1.0.0)"
- @fetcher.data["#{host}/api/v1/gems"] = [@response, 200, 'OK']
+ @fetcher.data["#{host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
@fetcher.data["#{Gem.host}/api/v1/gems"] =
- ['fail', 500, 'Internal Server Error']
+ ["fail", 500, "Internal Server Error"]
@cmd.options[:host] = host
@cmd.options[:args] = [@path]
@cmd.execute
- assert_equal Net::HTTP::Post, @fetcher.last_request.class
+ assert_equal Gem::Net::HTTP::Post, @fetcher.last_request.class
assert_equal Gem.read_binary(@path), @fetcher.last_request.body
assert_equal "application/octet-stream",
@fetcher.last_request["Content-Type"]
@@ -101,19 +104,19 @@ class TestGemCommandsPushCommand < Gem::TestCase
def test_execute_allowed_push_host
@spec, @path = util_gem "freebird", "1.0.1" do |spec|
- spec.metadata['allowed_push_host'] = "https://privategemserver.example"
+ spec.metadata["allowed_push_host"] = "https://privategemserver.example"
end
@response = "Successfully registered gem: freewill (1.0.0)"
- @fetcher.data["#{@spec.metadata['allowed_push_host']}/api/v1/gems"] = [@response, 200, 'OK']
+ @fetcher.data["#{@spec.metadata["allowed_push_host"]}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
@fetcher.data["#{Gem.host}/api/v1/gems"] =
- ['fail', 500, 'Internal Server Error']
+ ["fail", 500, "Internal Server Error"]
@cmd.options[:args] = [@path]
@cmd.execute
- assert_equal Net::HTTP::Post, @fetcher.last_request.class
+ assert_equal Gem::Net::HTTP::Post, @fetcher.last_request.class
assert_equal Gem.read_binary(@path), @fetcher.last_request.body
assert_equal "application/octet-stream",
@fetcher.last_request["Content-Type"]
@@ -136,7 +139,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
ENV["RUBYGEMS_HOST"] = @host
Gem.configuration.disable_default_gem_server = true
@response = "Successfully registered gem: freewill (1.0.0)"
- @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK']
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
send_battery
end
@@ -145,32 +148,32 @@ class TestGemCommandsPushCommand < Gem::TestCase
@host = "http://privategemserver.example"
@spec, @path = util_gem "freebird", "1.0.1" do |spec|
- spec.metadata['default_gem_server'] = @host
+ spec.metadata["default_gem_server"] = @host
end
@api_key = "EYKEY"
keys = {
- :rubygems_api_key => 'KEY',
+ :rubygems_api_key => "KEY",
@host => @api_key,
}
- File.open Gem.configuration.credentials_path, 'w' do |f|
- f.write keys.to_yaml
+ File.open Gem.configuration.credentials_path, "w" do |f|
+ f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
end
Gem.configuration.load_api_keys
FileUtils.rm Gem.configuration.credentials_path
@response = "Successfully registered gem: freebird (1.0.1)"
- @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK']
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
send_battery
end
def test_sending_gem
@response = "Successfully registered gem: freewill (1.0.0)"
- @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK']
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
send_battery
end
@@ -179,25 +182,25 @@ class TestGemCommandsPushCommand < Gem::TestCase
@host = "http://privategemserver.example"
@spec, @path = util_gem "freebird", "1.0.1" do |spec|
- spec.metadata['allowed_push_host'] = @host
+ spec.metadata["allowed_push_host"] = @host
end
@api_key = "PRIVKEY"
keys = {
- :rubygems_api_key => 'KEY',
+ :rubygems_api_key => "KEY",
@host => @api_key,
}
- File.open Gem.configuration.credentials_path, 'w' do |f|
- f.write keys.to_yaml
+ File.open Gem.configuration.credentials_path, "w" do |f|
+ f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
end
Gem.configuration.load_api_keys
FileUtils.rm Gem.configuration.credentials_path
@response = "Successfully registered gem: freebird (1.0.1)"
- @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK']
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
send_battery
end
@@ -205,14 +208,14 @@ class TestGemCommandsPushCommand < Gem::TestCase
@host = "http://privategemserver.example"
@spec, @path = util_gem "freebird", "1.0.1" do |spec|
- spec.metadata['allowed_push_host'] = @host
+ spec.metadata["allowed_push_host"] = @host
end
@api_key = "PRIVKEY"
ENV["GEM_HOST_API_KEY"] = "PRIVKEY"
@response = "Successfully registered gem: freebird (1.0.1)"
- @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK']
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
send_battery
end
@@ -221,30 +224,30 @@ class TestGemCommandsPushCommand < Gem::TestCase
@host = "http://user:password@privategemserver.example"
@spec, @path = util_gem "freebird", "1.0.1" do |spec|
- spec.metadata['allowed_push_host'] = @sanitized_host
+ spec.metadata["allowed_push_host"] = @sanitized_host
end
@api_key = "DOESNTMATTER"
keys = {
- :rubygems_api_key => @api_key,
+ rubygems_api_key: @api_key,
}
- File.open Gem.configuration.credentials_path, 'w' do |f|
- f.write keys.to_yaml
+ File.open Gem.configuration.credentials_path, "w" do |f|
+ f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
end
Gem.configuration.load_api_keys
FileUtils.rm Gem.configuration.credentials_path
@response = "Successfully registered gem: freebird (1.0.1)"
- @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK']
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
send_battery
end
def test_sending_gem_to_disallowed_default_host
@spec, @path = util_gem "freebird", "1.0.1" do |spec|
- spec.metadata['allowed_push_host'] = "https://privategemserver.example"
+ spec.metadata["allowed_push_host"] = "https://privategemserver.example"
end
response = %(ERROR: "#{@host}" is not allowed by the gemspec, which only allows "https://privategemserver.example")
@@ -261,18 +264,18 @@ class TestGemCommandsPushCommand < Gem::TestCase
push_host = "https://privategemserver.example"
@spec, @path = util_gem "freebird", "1.0.1" do |spec|
- spec.metadata['allowed_push_host'] = push_host
+ spec.metadata["allowed_push_host"] = push_host
end
@api_key = "PRIVKEY"
keys = {
- :rubygems_api_key => 'KEY',
+ :rubygems_api_key => "KEY",
@host => @api_key,
}
- File.open Gem.configuration.credentials_path, 'w' do |f|
- f.write keys.to_yaml
+ File.open Gem.configuration.credentials_path, "w" do |f|
+ f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
end
Gem.configuration.load_api_keys
@@ -291,8 +294,8 @@ class TestGemCommandsPushCommand < Gem::TestCase
host = "http://privategemserver.example"
@spec, @path = util_gem "freebird", "1.0.1" do |spec|
- spec.metadata.delete('default_gem_server')
- spec.metadata['allowed_push_host'] = host
+ spec.metadata.delete("default_gem_server")
+ spec.metadata["allowed_push_host"] = host
end
api_key = "PRIVKEY"
@@ -301,22 +304,22 @@ class TestGemCommandsPushCommand < Gem::TestCase
host => api_key,
}
- File.open Gem.configuration.credentials_path, 'w' do |f|
- f.write keys.to_yaml
+ File.open Gem.configuration.credentials_path, "w" do |f|
+ f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
end
Gem.configuration.load_api_keys
FileUtils.rm Gem.configuration.credentials_path
@response = "Successfully registered gem: freebird (1.0.1)"
- @fetcher.data["#{host}/api/v1/gems"] = [@response, 200, 'OK']
+ @fetcher.data["#{host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
# do not set @host
use_ui(@ui) { @cmd.send_gem(@path) }
- assert_match %r{Pushing gem to #{host}...}, @ui.output
+ assert_match(/Pushing gem to #{host}.../, @ui.output)
- assert_equal Net::HTTP::Post, @fetcher.last_request.class
+ assert_equal Gem::Net::HTTP::Post, @fetcher.last_request.class
assert_equal Gem.read_binary(@path), @fetcher.last_request.body
assert_equal File.size(@path), @fetcher.last_request["Content-Length"].to_i
assert_equal "application/octet-stream", @fetcher.last_request["Content-Type"]
@@ -325,6 +328,27 @@ class TestGemCommandsPushCommand < Gem::TestCase
assert_match @response, @ui.output
end
+ def test_sending_gem_to_host_permanent_redirect
+ @host = "http://rubygems.example"
+ redirected_uri = "https://rubygems.example/api/v1/gems"
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(
+ body: "",
+ code: 308,
+ msg: "Permanent Redirect",
+ headers: { "Location" => redirected_uri }
+ )
+
+ assert_raise Gem::MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.instance_variable_set :@host, @host
+ @cmd.send_gem(@path)
+ end
+ end
+
+ response = "The request has redirected permanently to #{redirected_uri}. Please check your defined push host URL."
+ assert_match response, @ui.output
+ end
+
def test_raises_error_with_no_arguments
def @cmd.sign_in(*); end
assert_raise Gem::CommandLineError do
@@ -334,7 +358,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
def test_sending_gem_denied
response = "You don't have permission to push to this gem"
- @fetcher.data["#{@host}/api/v1/gems"] = [response, 403, 'Forbidden']
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: response, code: 403, msg: "Forbidden")
@cmd.instance_variable_set :@host, @host
assert_raise Gem::MockGemUi::TermError do
@@ -348,9 +372,9 @@ class TestGemCommandsPushCommand < Gem::TestCase
def test_sending_gem_key
@response = "Successfully registered gem: freewill (1.0.0)"
- @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, "OK"]
- File.open Gem.configuration.credentials_path, 'a' do |f|
- f.write ':other: 701229f217cdf23b1344c7b4b54ca97'
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
+ File.open Gem.configuration.credentials_path, "a" do |f|
+ f.write ":other: 701229f217cdf23b1344c7b4b54ca97"
end
Gem.configuration.load_api_keys
@@ -363,28 +387,26 @@ class TestGemCommandsPushCommand < Gem::TestCase
end
def test_otp_verified_success
- response_fail = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
- response_success = 'Successfully registered gem: freewill (1.0.0)'
+ response_success = "Successfully registered gem: freewill (1.0.0)"
- @fetcher.data["#{Gem.host}/api/v1/gems"] = [
- [response_fail, 401, 'Unauthorized'],
- [response_success, 200, 'OK'],
- ]
+ @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success)
@otp_ui = Gem::MockGemUi.new "111111\n"
use_ui @otp_ui do
@cmd.send_gem(@path)
end
- assert_match 'You have enabled multi-factor authentication. Please enter OTP code.', @otp_ui.output
- assert_match 'Code: ', @otp_ui.output
+ assert_match "You have enabled multi-factor authentication. Please enter OTP code.", @otp_ui.output
+ assert_match "Code: ", @otp_ui.output
assert_match response_success, @otp_ui.output
- assert_equal '111111', @fetcher.last_request['OTP']
+ assert_equal "111111", @fetcher.last_request["OTP"]
end
def test_otp_verified_failure
response = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
- @fetcher.data["#{Gem.host}/api/v1/gems"] = [response, 401, 'Unauthorized']
+ @fetcher.data["#{Gem.host}/api/v1/gems"] = HTTPResponseFactory.create(body: response, code: 401, msg: "Unauthorized")
+ @fetcher.data["#{Gem.host}/api/v1/webauthn_verification"] =
+ HTTPResponseFactory.create(body: "You don't have any security devices", code: 422, msg: "Unprocessable Entity")
@otp_ui = Gem::MockGemUi.new "111111\n"
assert_raise Gem::MockGemUi::TermError do
@@ -394,23 +416,125 @@ class TestGemCommandsPushCommand < Gem::TestCase
end
assert_match response, @otp_ui.output
- assert_match 'You have enabled multi-factor authentication. Please enter OTP code.', @otp_ui.output
- assert_match 'Code: ', @otp_ui.output
- assert_equal '111111', @fetcher.last_request['OTP']
+ assert_match "You have enabled multi-factor authentication. Please enter OTP code.", @otp_ui.output
+ assert_match "Code: ", @otp_ui.output
+ assert_equal "111111", @fetcher.last_request["OTP"]
+ end
+
+ def test_with_webauthn_enabled_success
+ response_success = "Successfully registered gem: freewill (1.0.0)"
+ server = Gem::MockTCPServer.new
+
+ @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success)
+ @fetcher.respond_with_webauthn_url
+
+ TCPServer.stub(:new, server) do
+ Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:otp] = "Uvh6T57tkWuUnWYo" }) do
+ use_ui @ui do
+ @cmd.send_gem(@path)
+ end
+ end
+ end
+
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output
+ assert_match "You are verified with a security device. You may close the browser window.", @ui.output
+ assert_equal "Uvh6T57tkWuUnWYo", @fetcher.last_request["OTP"]
+ assert_match response_success, @ui.output
+ end
+
+ def test_with_webauthn_enabled_failure
+ response_success = "Successfully registered gem: freewill (1.0.0)"
+ server = Gem::MockTCPServer.new
+ error = Gem::WebauthnVerificationError.new("Something went wrong")
+
+ @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success)
+ @fetcher.respond_with_webauthn_url
+
+ error = assert_raise Gem::MockGemUi::TermError do
+ TCPServer.stub(:new, server) do
+ Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:error] = error }) do
+ use_ui @ui do
+ @cmd.send_gem(@path)
+ end
+ end
+ end
+ end
+ assert_equal 1, error.exit_code
+
+ assert_match @fetcher.last_request["Authorization"], Gem.configuration.rubygems_api_key
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output
+ assert_match "ERROR: Security device verification failed: Something went wrong", @ui.error
+ refute_match "You are verified with a security device. You may close the browser window.", @ui.output
+ refute_match response_success, @ui.output
+ end
+
+ def test_with_webauthn_enabled_success_with_polling
+ response_success = "Successfully registered gem: freewill (1.0.0)"
+ server = Gem::MockTCPServer.new
+
+ @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success)
+ @fetcher.respond_with_webauthn_url
+ @fetcher.respond_with_webauthn_polling("Uvh6T57tkWuUnWYo")
+
+ TCPServer.stub(:new, server) do
+ use_ui @ui do
+ @cmd.send_gem(@path)
+ end
+ end
+
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output
+ assert_match "You are verified with a security device. You may close the browser window.", @ui.output
+ assert_equal "Uvh6T57tkWuUnWYo", @fetcher.last_request["OTP"]
+ assert_match response_success, @ui.output
+ end
+
+ def test_with_webauthn_enabled_failure_with_polling
+ response_success = "Successfully registered gem: freewill (1.0.0)"
+ server = Gem::MockTCPServer.new
+
+ @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success)
+ @fetcher.respond_with_webauthn_url
+ @fetcher.respond_with_webauthn_polling_failure
+
+ error = assert_raise Gem::MockGemUi::TermError do
+ TCPServer.stub(:new, server) do
+ use_ui @ui do
+ @cmd.send_gem(@path)
+ end
+ end
+ end
+ assert_equal 1, error.exit_code
+
+ assert_match @fetcher.last_request["Authorization"], Gem.configuration.rubygems_api_key
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, you can re-run the gem signin " \
+ "command with the `--otp [your_code]` option.", @ui.output
+ assert_match "ERROR: Security device verification failed: The token in the link you used has either expired " \
+ "or been used already.", @ui.error
+ refute_match "You are verified with a security device. You may close the browser window.", @ui.output
+ refute_match response_success, @ui.output
end
def test_sending_gem_unathorized_api_key_with_mfa_enabled
response_mfa_enabled = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
response_forbidden = "The API key doesn't have access"
- response_success = 'Successfully registered gem: freewill (1.0.0)'
+ response_success = "Successfully registered gem: freewill (1.0.0)"
@fetcher.data["#{@host}/api/v1/gems"] = [
- [response_mfa_enabled, 401, 'Unauthorized'],
- [response_forbidden, 403, 'Forbidden'],
- [response_success, 200, "OK"],
+ HTTPResponseFactory.create(body: response_mfa_enabled, code: 401, msg: "Unauthorized"),
+ HTTPResponseFactory.create(body: response_forbidden, code: 403, msg: "Forbidden"),
+ HTTPResponseFactory.create(body: response_success, code: 200, msg: "OK"),
]
+ @fetcher.data["#{@host}/api/v1/webauthn_verification"] =
+ HTTPResponseFactory.create(body: "You don't have any security devices", code: 422, msg: "Unprocessable Entity")
- @fetcher.data["#{@host}/api/v1/api_key"] = ["", 200, "OK"]
+ @fetcher.data["#{@host}/api/v1/api_key"] = HTTPResponseFactory.create(body: "", code: 200, msg: "OK")
@cmd.instance_variable_set :@host, @host
@cmd.instance_variable_set :@scope, :push_rubygem
@@ -423,32 +547,34 @@ class TestGemCommandsPushCommand < Gem::TestCase
access_notice = "The existing key doesn't have access of push_rubygem on https://rubygems.example. Please sign in to update access."
assert_match mfa_notice, @ui.output
assert_match access_notice, @ui.output
- assert_match "Email:", @ui.output
+ assert_match "Username/email:", @ui.output
assert_match "Password:", @ui.output
assert_match "Added push_rubygem scope to the existing API key", @ui.output
assert_match response_success, @ui.output
- assert_equal '11111', @fetcher.last_request['OTP']
+ assert_equal "11111", @fetcher.last_request["OTP"]
end
def test_sending_gem_with_no_local_creds
Gem.configuration.rubygems_api_key = nil
response_mfa_enabled = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
- response_success = 'Successfully registered gem: freewill (1.0.0)'
+ response_success = "Successfully registered gem: freewill (1.0.0)"
response_profile = "mfa: disabled\n"
@fetcher.data["#{@host}/api/v1/gems"] = [
- [response_success, 200, "OK"],
+ HTTPResponseFactory.create(body: response_success, code: 200, msg: "OK"),
]
@fetcher.data["#{@host}/api/v1/api_key"] = [
- [response_mfa_enabled, 401, 'Unauthorized'],
- ["", 200, "OK"],
+ HTTPResponseFactory.create(body: response_mfa_enabled, code: 401, msg: "Unauthorized"),
+ HTTPResponseFactory.create(body: "", code: 200, msg: "OK"),
]
@fetcher.data["#{@host}/api/v1/profile/me.yaml"] = [
- [response_profile, 200, "OK"],
+ HTTPResponseFactory.create(body: response_profile, code: 200, msg: "OK"),
]
+ @fetcher.data["#{@host}/api/v1/webauthn_verification"] =
+ HTTPResponseFactory.create(body: "You don't have any security devices", code: 422, msg: "Unprocessable Entity")
@cmd.instance_variable_set :@scope, :push_rubygem
@cmd.options[:args] = [@path]
@@ -462,11 +588,11 @@ class TestGemCommandsPushCommand < Gem::TestCase
mfa_notice = "You have enabled multi-factor authentication. Please enter OTP code."
assert_match mfa_notice, @ui.output
assert_match "Enter your https://rubygems.example credentials.", @ui.output
- assert_match "Email:", @ui.output
+ assert_match "Username/email:", @ui.output
assert_match "Password:", @ui.output
assert_match "Signed in with API key:", @ui.output
assert_match response_success, @ui.output
- assert_equal '11111', @fetcher.last_request['OTP']
+ assert_equal "11111", @fetcher.last_request["OTP"]
end
private