require 'abstract_unit' require 'rails/commands/dbconsole' class Rails::DBConsoleTest < ActiveSupport::TestCase def teardown %w[PGUSER PGHOST PGPORT PGPASSWORD].each{|key| ENV.delete(key)} end def test_config Rails::DBConsole.const_set(:APP_PATH, "erb") app_config({}) capture_abort { Rails::DBConsole.new.config } assert aborted assert_match(/No database is configured for the environment '\w+'/, output) app_config(test: "with_init") assert_equal Rails::DBConsole.new.config, "with_init" app_db_file("test:\n without_init") assert_equal Rails::DBConsole.new.config, "without_init" app_db_file("test:\n <%= Rails.something_app_specific %>") assert_equal Rails::DBConsole.new.config, "with_init" app_db_file("test:\n\ninvalid") assert_equal Rails::DBConsole.new.config, "with_init" end def test_env assert_equal Rails::DBConsole.new.environment, "test" ENV['RAILS_ENV'] = nil ENV['RACK_ENV'] = nil Rails.stubs(:respond_to?).with(:env).returns(false) assert_equal Rails::DBConsole.new.environment, "development" ENV['RACK_ENV'] = "rack_env" assert_equal Rails::DBConsole.new.environment, "rack_env" ENV['RAILS_ENV'] = "rails_env" assert_equal Rails::DBConsole.new.environment, "rails_env" ensure ENV['RAILS_ENV'] = "test" end def test_mysql dbconsole.expects(:find_cmd_and_exec).with(%w[mysql mysql5], 'db') start(adapter: 'mysql', database: 'db') assert !aborted end def test_mysql_full dbconsole.expects(:find_cmd_and_exec).with(%w[mysql mysql5], '--host=locahost', '--port=1234', '--socket=socket', '--user=user', '--default-character-set=UTF-8', '-p', 'db') start(adapter: 'mysql', database: 'db', host: 'locahost', port: 1234, socket: 'socket', username: 'user', password: 'qwerty', encoding: 'UTF-8') assert !aborted end def test_mysql_include_password dbconsole.expects(:find_cmd_and_exec).with(%w[mysql mysql5], '--user=user', '--password=qwerty', 'db') start({adapter: 'mysql', database: 'db', username: 'user', password: 'qwerty'}, ['-p']) assert !aborted end def test_postgresql dbconsole.expects(:find_cmd_and_exec).with('psql', 'db') start(adapter: 'postgresql', database: 'db') assert !aborted end def test_postgresql_full dbconsole.expects(:find_cmd_and_exec).with('psql', 'db') start(adapter: 'postgresql', database: 'db', username: 'user', password: 'q1w2e3', host: 'host', port: 5432) assert !aborted 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 dbconsole.expects(:find_cmd_and_exec).with('psql', 'db') start({adapter: 'postgresql', database: 'db', username: 'user', password: 'q1w2e3'}, ['-p']) assert !aborted assert_equal 'user', ENV['PGUSER'] assert_equal 'q1w2e3', ENV['PGPASSWORD'] end def test_sqlite dbconsole.expects(:find_cmd_and_exec).with('sqlite', 'db') start(adapter: 'sqlite', database: 'db') assert !aborted end def test_sqlite3 dbconsole.expects(:find_cmd_and_exec).with('sqlite3', Rails.root.join('db.sqlite3').to_s) start(adapter: 'sqlite3', database: 'db.sqlite3') assert !aborted end def test_sqlite3_mode dbconsole.expects(:find_cmd_and_exec).with('sqlite3', '-html', Rails.root.join('db.sqlite3').to_s) start({adapter: 'sqlite3', database: 'db.sqlite3'}, ['--mode', 'html']) assert !aborted end def test_sqlite3_header dbconsole.expects(:find_cmd_and_exec).with('sqlite3', '-header', Rails.root.join('db.sqlite3').to_s) start({adapter: 'sqlite3', database: 'db.sqlite3'}, ['--header']) end def test_sqlite3_db_absolute_path dbconsole.expects(:find_cmd_and_exec).with('sqlite3', '/tmp/db.sqlite3') start(adapter: 'sqlite3', database: '/tmp/db.sqlite3') assert !aborted end def test_sqlite3_db_without_defined_rails_root Rails.stubs(:respond_to?) Rails.expects(:respond_to?).with(:root).once.returns(false) dbconsole.expects(:find_cmd_and_exec).with('sqlite3', Rails.root.join('../config/db.sqlite3').to_s) start(adapter: 'sqlite3', database: 'config/db.sqlite3') assert !aborted end def test_oracle dbconsole.expects(:find_cmd_and_exec).with('sqlplus', 'user@db') start(adapter: 'oracle', database: 'db', username: 'user', password: 'secret') assert !aborted end def test_oracle_include_password dbconsole.expects(:find_cmd_and_exec).with('sqlplus', 'user/secret@db') start({adapter: 'oracle', database: 'db', username: 'user', password: 'secret'}, ['-p']) assert !aborted 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 private attr_reader :aborted, :output def dbconsole @dbconsole ||= Rails::DBConsole.new(nil) end def start(config = {}, argv = []) dbconsole.stubs(config: config.stringify_keys, arguments: argv) capture_abort { dbconsole.start } end def capture_abort @aborted = false @output = capture(:stderr) do begin yield rescue SystemExit @aborted = true end end end def app_db_file(result) IO.stubs(:read).with("config/database.yml").returns(result) end def app_config(result) Rails.application.config.stubs(:database_configuration).returns(result.stringify_keys) end end