mirror of
https://github.com/DatabaseCleaner/database_cleaner
synced 2023-03-27 23:22:03 -04:00
add safeguard for running in production, namespace errors, add error messages
This commit is contained in:
parent
2437dd08fe
commit
bec3f64b78
3 changed files with 130 additions and 21 deletions
|
@ -1,21 +1,70 @@
|
|||
module DatabaseCleaner
|
||||
DatabaseUrlSpecified = Class.new(Exception)
|
||||
|
||||
class Safeguard
|
||||
def run
|
||||
return if skip?
|
||||
raise DatabaseUrlSpecified if env_db_url?
|
||||
class Error < Exception
|
||||
class RemoteDatabaseUrl < Error
|
||||
def initialize
|
||||
super("ENV['DATABASE_URL'] is set to a remote URL. Please refer to https://github.com/DatabaseCleaner/database_cleaner#safeguards")
|
||||
end
|
||||
end
|
||||
|
||||
class ProductionEnv < Error
|
||||
def initialize(env)
|
||||
super("ENV['#{env}'] is set to production. Please refer to https://github.com/DatabaseCleaner/database_cleaner#safeguards")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def env_db_url?
|
||||
url = ENV['DATABASE_URL']
|
||||
url && !url.include?('localhost')
|
||||
class RemoteDatabaseUrl
|
||||
def run
|
||||
raise Error::RemoteDatabaseUrl if !skip? && given?
|
||||
end
|
||||
|
||||
def skip?
|
||||
!!ENV['DATABASE_CLEANER_SKIP_SAFEGUARD']
|
||||
private
|
||||
|
||||
def given?
|
||||
remote?(ENV['DATABASE_URL'])
|
||||
end
|
||||
|
||||
def remote?(url)
|
||||
url && !url.include?('localhost')
|
||||
end
|
||||
|
||||
def skip?
|
||||
ENV['DATABASE_CLEANER_ALLOW_REMOTE_DATABASE_URL'] ||
|
||||
DatabaseCleaner.allow_remote_database_url
|
||||
end
|
||||
end
|
||||
|
||||
class Production
|
||||
KEYS = %w(ENV RACK_ENV RAILS_ENV)
|
||||
|
||||
def run
|
||||
raise Error::ProductionEnv.new(key) if !skip? && given?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def given?
|
||||
!!key
|
||||
end
|
||||
|
||||
def key
|
||||
@key ||= KEYS.detect { |key| ENV[key] == 'production' }
|
||||
end
|
||||
|
||||
def skip?
|
||||
ENV['DATABASE_CLEANER_ALLOW_PRODUCTION'] ||
|
||||
DatabaseCleaner.allow_production
|
||||
end
|
||||
end
|
||||
|
||||
CHECKS = [
|
||||
RemoteDatabaseUrl,
|
||||
Production
|
||||
]
|
||||
|
||||
def run
|
||||
CHECKS.each { |const| const.new.run }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
require 'spec_helper'
|
||||
require 'support/env'
|
||||
require 'active_record'
|
||||
require 'database_cleaner/active_record/transaction'
|
||||
|
||||
module DatabaseCleaner
|
||||
describe Safeguard do
|
||||
include Support::Env
|
||||
|
||||
let(:strategy) { DatabaseCleaner::ActiveRecord::Transaction }
|
||||
let(:cleaner) { Base.new(:autodetect) }
|
||||
|
||||
|
@ -11,31 +14,66 @@ module DatabaseCleaner
|
|||
|
||||
describe 'DATABASE_URL is set' do
|
||||
describe 'to any value' do
|
||||
before { ENV['DATABASE_URL'] = 'postgres://remote.host' }
|
||||
after { ENV.delete('DATABASE_URL') }
|
||||
env DATABASE_URL: 'postgres://remote.host'
|
||||
|
||||
it 'raises DatabaseUrlSpecified' do
|
||||
expect { cleaner.start }.to raise_error(DatabaseUrlSpecified)
|
||||
it 'raises' do
|
||||
expect { cleaner.start }.to raise_error(Safeguard::Error::RemoteDatabaseUrl)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'to a local url' do
|
||||
before { ENV['DATABASE_URL'] = 'postgres://localhost' }
|
||||
after { ENV.delete('DATABASE_URL') }
|
||||
env DATABASE_URL: 'postgres://localhost'
|
||||
|
||||
it 'does not raise' do
|
||||
expect { cleaner.start }.to_not raise_error
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DATABASE_CLEANER_SKIP_SAFEGUARD is set' do
|
||||
before { ENV['DATABASE_CLEANER_SKIP_SAFEGUARD'] = 'true' }
|
||||
after { ENV.delete('DATABASE_CLEANER_SKIP_SAFEGUARD') }
|
||||
describe 'DATABASE_CLEANER_ALLOW_REMOTE_DATABASE_URL is set' do
|
||||
env DATABASE_CLEANER_ALLOW_REMOTE_DATABASE_URL: true
|
||||
|
||||
it 'does not raise' do
|
||||
expect { cleaner.start }.to_not raise_error
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DatabaseCleaner.allow_remote_database_url is true' do
|
||||
before { DatabaseCleaner.allow_remote_database_url = true }
|
||||
after { DatabaseCleaner.allow_remote_database_url = nil }
|
||||
|
||||
it 'does not raise' do
|
||||
expect { cleaner.start }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'ENV is set to production' do
|
||||
%w(ENV RACK_ENV RAILS_ENV).each do |key|
|
||||
describe "on #{key}" do
|
||||
env key => 'production'
|
||||
|
||||
it 'raises' do
|
||||
expect { cleaner.start }.to raise_error(Safeguard::Error::ProductionEnv)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DATABASE_CLEANER_ALLOW_PRODUCTION is set' do
|
||||
env DATABASE_CLEANER_ALLOW_PRODUCTION: true
|
||||
|
||||
it 'does not raise' do
|
||||
expect { cleaner.start }.to_not raise_error
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DatabaseCleaner.allow_production is true' do
|
||||
before { DatabaseCleaner.allow_production = true }
|
||||
after { DatabaseCleaner.allow_production = nil }
|
||||
|
||||
it 'does not raise' do
|
||||
expect { cleaner.start }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
22
spec/support/env.rb
Normal file
22
spec/support/env.rb
Normal file
|
@ -0,0 +1,22 @@
|
|||
module Support
|
||||
module Env
|
||||
def self.included(base)
|
||||
base.send(:extend, ClassMethods)
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def env(vars)
|
||||
before { define_env(vars) }
|
||||
after { undefine_env(vars) }
|
||||
end
|
||||
end
|
||||
|
||||
def define_env(vars)
|
||||
vars.each { |key, value| ENV[key.to_s.upcase] = value.to_s }
|
||||
end
|
||||
|
||||
def undefine_env(vars)
|
||||
vars.each { |key, _| ENV.delete(key.to_s) }
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue