Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 'undefined constant RED' error + add tests #25

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/safer_rails_console/patches/sandbox/auto_rollback.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def self.rollback_and_begin_new_transaction

def self.handle_and_reraise_exception(e)
if e.message.include?('PG::ReadOnlySqlTransaction')
puts color_text('An operation could not be completed due to read-only mode.', RED) # rubocop:disable Rails/Output
puts color_text('An operation could not be completed due to read-only mode.', Colors::RED) # rubocop:disable Rails/Output
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd use the entire namespace from the root to be safe - ::SaferRailsConsole::Colors::RED. The fact that RED resolved correctly was serendipitous.

A better way to do this would be to include SaferRailsConsole::Colors instead of extend ..., ensuring that the constants are included into the metaclass. That'd involve a little bit of shuffling within Colors though, so no pressure and the first solution is totally adequate!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about including, but then the color_text won't be available.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, the shuffling I mentioned would involve putting that into a ClassMethods or similar module and using the popular self.included; extend ClassMethods pattern.

else
rollback_and_begin_new_transaction
end
Expand Down
45 changes: 45 additions & 0 deletions spec/safer_rails_console/patches/sandbox/auto_rollback_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# require 'safer_rails_console/patches/sandbox/auto_rollback'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently all the patches are integration tested in a real rails setup and console. We don't require anything within patches outside of that. See this context https://github.com/salsify/safer_rails_console/blob/master/spec/integration/patches/sandbox_spec.rb#L8 for more information. Feel free to help improve that by including the case where a normal exception is forwarded!

That being said, I'm totally for unit testing the patches. I'd probably update the test for SaferRailsConsole::Console.initialize_sandbox to the following:

  context ".initialize_sandbox" do
    before do
      allow(SaferRailsConsole::Console).to receive(:require)
    end

    it "loads sandbox patches" do
      described_class.initialize_sandbox

      expect(SaferRailsConsole::Console).to have_received(:require).with('safer_rails_console/patches/sandbox')
    end
  end


describe "::SaferRailsConsole::Patches::Sandbox::AutoRollback" do
describe ".handle_and_reraise_exception" do
let(:mocked_ar_connection) { spy('ar_connection') } # rubocop:disable RSpec/VerifiedDoubles

# mock ActiveRecord::Base.connection
before do
::SaferRailsConsole::Console.initialize_sandbox
module ActiveRecord
module Base
end
end
allow(::ActiveRecord::Base).to receive(:connection).and_return(mocked_ar_connection)
end

after do
Object.send(:remove_const, :ActiveRecord)
end

context "when raising a PG::ReadOnlySqlTransaction exception" do
let(:error) { RuntimeError.new('Beware of the PG::ReadOnlySqlTransaction exception!') }

it "outputs a message on stdout and forwards the exception" do
expect do
::SaferRailsConsole::Patches::Sandbox::AutoRollback.handle_and_reraise_exception(error)
end.to raise_exception(error)
.and output(/An operation could not be completed due to read-only mode./).to_stdout
end
end

context "when raising a classic exception" do
let(:error) { RuntimeError.new('normal error') }

it "rollbacks, begins a new transaction and forwards the exception" do
expect do
::SaferRailsConsole::Patches::Sandbox::AutoRollback.handle_and_reraise_exception(error)
end.to raise_exception(error)

expect(mocked_ar_connection).to have_received(:rollback_db_transaction).ordered
expect(mocked_ar_connection).to have_received(:begin_db_transaction).ordered
end
end
end
end