require "abstract_unit"
require "minitest/mock"
require "rails/commands/dbconsole"
class Rails::DBConsoleTest < ActiveSupport::TestCase
def setup
Rails::DBConsole.const_set("APP_PATH", "rails/all")
end
def teardown
Rails::DBConsole.send(:remove_const, "APP_PATH")
%w[PGUSER PGHOST PGPORT PGPASSWORD DATABASE_URL].each{|key| ENV.delete(key)}
end
def test_config_with_db_config_only
config_sample = {
"test"=> {
"adapter"=> "sqlite3",
"host"=> "localhost",
"port"=> "9000",
"database"=> "foo_test",
"user"=> "foo",
"password"=> "bar",
"pool"=> "5",
"timeout"=> "3000"
}
}
app_db_config(config_sample) do
assert_equal config_sample["test"], Rails::DBConsole.new.config
end
end
def test_config_with_no_db_config
app_db_config(nil) do
assert_raise(ActiveRecord::AdapterNotSpecified) {
Rails::DBConsole.new.config
}
end
end
def test_config_with_database_url_only
ENV["DATABASE_URL"] = "postgresql://foo:bar@localhost:9000/foo_test?pool=5&timeout=3000"
expected = {
"adapter" => "postgresql",
"host" => "localhost",
"port" => 9000,
"database" => "foo_test",
"username" => "foo",
"password" => "bar",
"pool" => "5",
"timeout" => "3000"
}.sort
app_db_config(nil) do
assert_equal expected, Rails::DBConsole.new.config.sort
end
end
def test_config_choose_database_url_if_exists
host = "database-url-host.com"
ENV["DATABASE_URL"] = "postgresql://foo:bar@#{host}:9000/foo_test?pool=5&timeout=3000"
sample_config = {
"test" => {
"adapter" => "postgresql",
"host" => "not-the-#{host}",
"port" => 9000,
"database" => "foo_test",
"username" => "foo",
"password" => "bar",
"pool" => "5",
"timeout" => "3000"
}
}
app_db_config(sample_config) do
assert_equal host, Rails::DBConsole.new.config["host"]
end
end
def test_env
assert_equal "test", Rails::DBConsole.new.environment
ENV["RAILS_ENV"] = nil
ENV["RACK_ENV"] = nil
Rails.stub(:respond_to?, false) do
assert_equal "development", Rails::DBConsole.new.environment
ENV["RACK_ENV"] = "rack_env"
assert_equal "rack_env", Rails::DBConsole.new.environment
ENV["RAILS_ENV"] = "rails_env"
assert_equal "rails_env", Rails::DBConsole.new.environment
end
ensure
ENV["RAILS_ENV"] = "test"
ENV["RACK_ENV"] = nil
end
def test_rails_env_is_development_when_argument_is_dev
Rails::DBConsole.stub(:available_environments, ["development", "test"]) do
options = Rails::DBConsole.send(:parse_arguments, ["dev"])
assert_match("development", options[:environment])
end
end
def test_rails_env_is_dev_when_argument_is_dev_and_dev_env_is_present
Rails::DBConsole.stub(:available_environments, ["dev"]) do
options = Rails::DBConsole.send(:parse_arguments, ["dev"])
assert_match("dev", options[:environment])
end
end
def test_mysql
start(adapter: "mysql2", database: "db")
assert !aborted
assert_equal [%w[mysql mysql5], "db"], dbconsole.find_cmd_and_exec_args
end
def test_mysql_full
start(adapter: "mysql2", database: "db", host: "locahost", port: 1234, socket: "socket", username: "user", password: "qwerty", encoding: "UTF-8")
assert !aborted
assert_equal [%w[mysql mysql5], "--host=locahost", "--port=1234", "--socket=socket", "--user=user", "--default-character-set=UTF-8", "-p", "db"], dbconsole.find_cmd_and_exec_args
end
def test_mysql_include_password
start({adapter: "mysql2", database: "db", username: "user", password: "qwerty"}, ["-p"])
assert !aborted
assert_equal [%w[mysql mysql5], "--user=user", "--password=qwerty", "db"], dbconsole.find_cmd_and_exec_args
end
def test_postgresql
start(adapter: "postgresql", database: "db")
assert !aborted
assert_equal ["psql", "db"], dbconsole.find_cmd_and_exec_args
end
def test_postgresql_full
start(adapter: "postgresql", database: "db", username: "user", password: "q1w2e3", host: "host", port: 5432)
assert !aborted
assert_equal ["psql", "db"], dbconsole.find_cmd_and_exec_args
assert_equal "user", ENV["PGUSER"]
assert_equal "host", ENV["PGHOST"]
assert_equal "5432", ENV["PGPORT"]
assert_not_equal "q1w2e3", ENV["PGPASSWORD"]
end
def test_postgresql_include_password
start({adapter: "postgresql", database: "db", username: "user", password: "q1w2e3"}, ["-p"])
assert !aborted
assert_equal ["psql", "db"], dbconsole.find_cmd_and_exec_args
assert_equal "user", ENV["PGUSER"]
assert_equal "q1w2e3", ENV["PGPASSWORD"]
end
def test_sqlite3
start(adapter: "sqlite3", database: "db.sqlite3")
assert !aborted
assert_equal ["sqlite3", Rails.root.join("db.sqlite3").to_s], dbconsole.find_cmd_and_exec_args
end
def test_sqlite3_mode
start({adapter: "sqlite3", database: "db.sqlite3"}, ["--mode", "html"])
assert !aborted
assert_equal ["sqlite3", "-html", Rails.root.join("db.sqlite3").to_s], dbconsole.find_cmd_and_exec_args
end
def test_sqlite3_header
start({adapter: "sqlite3", database: "db.sqlite3"}, ["--header"])
assert_equal ["sqlite3", "-header", Rails.root.join("db.sqlite3").to_s], dbconsole.find_cmd_and_exec_args
end
def test_sqlite3_db_absolute_path
start(adapter: "sqlite3", database: "/tmp/db.sqlite3")
assert !aborted
assert_equal ["sqlite3", "/tmp/db.sqlite3"], dbconsole.find_cmd_and_exec_args
end
def test_sqlite3_db_without_defined_rails_root
Rails.stub(:respond_to?, false) do
start(adapter: "sqlite3", database: "config/db.sqlite3")
assert !aborted
assert_equal ["sqlite3", Rails.root.join("../config/db.sqlite3").to_s], dbconsole.find_cmd_and_exec_args
end
end
def test_oracle
start(adapter: "oracle", database: "db", username: "user", password: "secret")
assert !aborted
assert_equal ["sqlplus", "user@db"], dbconsole.find_cmd_and_exec_args
end
def test_oracle_include_password
start({adapter: "oracle", database: "db", username: "user", password: "secret"}, ["-p"])
assert !aborted
assert_equal ["sqlplus", "user/secret@db"], dbconsole.find_cmd_and_exec_args
end
def test_unknown_command_line_client
start(adapter: "unknown", database: "db")
assert aborted
assert_match(/Unknown command-line client for db/, output)
end
def test_print_help_short
stdout = capture(:stdout) do
start({}, ["-h"])
end
assert aborted
assert_equal "", output
assert_match(/Usage:.*dbconsole/, stdout)
end
def test_print_help_long
stdout = capture(:stdout) do
start({}, ["--help"])
end
assert aborted
assert_equal "", output
assert_match(/Usage:.*dbconsole/, stdout)
end
attr_reader :aborted, :output
private :aborted, :output
private
def app_db_config(results)
Rails.application.config.stub(:database_configuration, results || {}) do
yield
end
end
def dbconsole
@dbconsole ||= Class.new(Rails::DBConsole) do
attr_reader :find_cmd_and_exec_args
def find_cmd_and_exec(*args)
@find_cmd_and_exec_args = args
end
end.new(nil)
end
def start(config = {}, argv = [])
dbconsole.stub(:config, config.stringify_keys) do
dbconsole.stub(:arguments, argv) do
capture_abort { dbconsole.start }
end
end
end
def capture_abort
@aborted = false
@output = capture(:stderr) do
begin
yield
rescue SystemExit
@aborted = true
end
end
end
end