Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rails omniauth error in rspec output

I have a rails 4 application using devise / omniauth to allow login via facebook. The application seems to work, and the tests seem to work too. However I have one test which checks for the situation where the user goes to login via facebook, but decides not to grant permission.

This test works correctly but sends an error message into the rspec output

$ rspec -fd --tag inspect 
Sign in with facebook
  new user
E, [2013-10-20T21:25:24.232573 #17137] ERROR -- omniauth: (facebook) Authentication failure! invalid_credentials encountered
    does not grant permission

Finished in 0.21152 seconds
1 example, 0 failures

Randomised with seed 52495

or

$ rspec 
....E, [2013-10-20T21:25:24.232573 #17137] ERROR -- omniauth: (facebook) Authentication failure! invalid_credentials encountered.
............................................................

Finished in 0.95531 seconds
74 examples, 0 failures

Randomized with seed 2946

Relevant test

require 'spec_helper.rb'

feature "sign in with facebook" do
  context "new user" do
    scenario "does not grant permission", inspect: true do
      dont_sign_in_with_facebook
      expect(notice_area).to have_content "Could not authenticate you from Facebook because \"Invalid credentials\""
    end
  end
end

and the authentication_helper

module Features
  module AuthenticationHelpers
    def dont_sign_in_with_facebook
      OmniAuth.config.test_mode = true
      OmniAuth.config.mock_auth[:facebook] = :invalid_credentials
      visit "/users/auth/facebook"
    end
  end
end

Is there something I can do to suppress the error message from the rspec output ?

Edit

I tried implementing the silence function described by @Shepmaster and that did not solve the issue. Then tried redirecting errors from the rspec command:

rspec -fd --tag inspect  2> /dev/null
Sign in with facebook
  new user
E, [2013-10-20T21:25:24.232573 #17137] ERROR -- omniauth: (facebook) Authentication failure! invalid_credentials encounterd
    does not grant permission

Finished in 0.21152 seconds
1 example, 0 failures

Randomised with seed 65190

and redirecting stdout

rspec -fd --tag inspect  > /dev/null

no output!

and finally using the output option

rspec -fd --tag inspect -o /tmp/rspec.out 2> /dev/null
cat /tmp/rspec.out 

Sign in with facebook
  new user
    does not grant permission

Finished in 0.21152 seconds
1 example, 0 failures

Randomised with seed 65190

ANSWER using the answer from @shepmaster

module Features
  module AuthenticationHelpers
    def dont_sign_in_with_facebook
      OmniAuth.config.test_mode = true
      OmniAuth.config.mock_auth[:facebook] = :invalid_credentials
      silence_omniauth {visit "/users/auth/facebook"}
    end
  end
end
like image 387
Ian Kenney Avatar asked Oct 20 '13 21:10

Ian Kenney


2 Answers

I had the same issue in a Rails 4.2 app. The fix was to set the OmniAuth logger to the Rails logger in an initializer per the README:

# config/initializers/omniauth.rb
OmniAuth.config.logger = Rails.logger
like image 164
Abe Voelker Avatar answered Nov 06 '22 21:11

Abe Voelker


The best bet is to find the code that is printing that error, then you can figure out if there is a precise way of silencing that error.

That error message has a unique misspelling (encountererd) that does not seem to occur (or ever have occurred) in the devise source. Perhaps it is coming from your code or another gem? A quick github search didn't have any useful results.

Added

It appears that you didn't copy-and-paste the error exactly, so I was looking for a string that never occurs! This is the source of the error. You should be able to set the OmniAuth logger to something else for the duration of the test. This is the same style as silence below:

def silence_omniauth
  previous_logger = OmniAuth.config.logger
  OmniAuth.config.logger = Logger.new("/dev/null")
  yield
ensure
  OmniAuth.config.logger = previous_logger
end

Original

If you cannot find the source of the message, then there is always the nuclear option: completely disabling printing to the standard output streams during that test. This other SO question has an example of how to do it, which I'll modify and reproduce here:

def silence
  previous_stdout, $stdout = $stdout, StringIO.new
  previous_stderr, $stderr = $stderr, StringIO.new
  yield
ensure
  # Restore the previous values of stdout and stderr
  $stdout = previous_stdout
  $stderr = previous_stderr
end

# And in your test
it 'does whatever' do
  silence { code.that_causes.the_warning }
end

To reiterate, it is much better to find a narrower solution. Silencing stdout / stderr will undoubtedly confuse someone when they go to print out debugging information during the test and see nothing. I say this as it happened to me just this last week. :-)

like image 6
Shepmaster Avatar answered Nov 06 '22 22:11

Shepmaster