title: How to Test Facebook Login Action with Rails, Omniauth and Rspec
body: <p>I asked a similar question before but I think I've gotten past my original error. Anyway I have a new fun failure that I'm having a blast trying to figure out (note the sarcasm). Here's my failure:</p>
  
  <pre><code>1) SessionsController#facebook_login should be valid
     Failure/Error: get :facebook_login
     NoMethodError:
       undefined method `slice' for nil:NilClass
     # ./app/models/user.rb:19:in `from_omniauth'
     # ./app/controllers/sessions_controller.rb:22:in `facebook_login'
     # ./spec/controllers/sessions_controller_spec.rb:96:in `block (3 levels) in &lt;top (required)&gt;'
  </code></pre>
  
  <p>sessions_controller_spec.rb</p>
  
  <pre><code>describe '#facebook_login' do
  
    before(:each) do
      valid_facebook_login_setup
      request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:facebook]
      get :facebook_login
    end
  
    it "should be valid" do
      expect(response).to be_success
    end
  
    it "should set user_id" do
      expect(session[:user_id]).to be_true
    end
  end
  </code></pre>
  
  <p>sessions_controller.rb</p>
  
  <pre><code>def facebook_login
    if request.env['omniauth.auth']
      user = User.from_omniauth(env['omniauth.auth'])
      session[:user_id] = user.id
      redirect_back_or root_path
    else
      redirect_to root_path
    end
  end
  </code></pre>
  
  <p>omniauth_test_helper.rb</p>
  
  <pre><code>module OmniAuthTestHelper
    def valid_facebook_login_setup
      if Rails.env.test?
        OmniAuth.config.test_mode = true
        OmniAuth.config.mock_auth[:facebook] = OmniAuth::AuthHash.new({
          provider: 'facebook',
          uid: '123545',
          info: {
            first_name: "Andrea",
            last_name:  "Del Rio",
            email:      "test@example.com"
          },
          credentials: {
            token: "123456",
            expires_at: Time.now + 1.week
          }
        })
      end
    end
  
    def facebook_login_failure
      OmniAuth.config.mock_auth[:facebook] = :invalid_credentials
    end
  end
  </code></pre>
  
  <p>spec_helper.rb</p>
  
  <pre><code>RSpec.configure do |config|
    config.include FactoryGirl::Syntax::Methods
    config.include Capybara::DSL
    config.fixture_path = "#{::Rails.root}/spec/fixtures"
    config.use_transactional_fixtures = true
    config.infer_base_class_for_anonymous_controllers = false
    config.order = "random"
    config.include SessionTestHelper, type: :controller
    config.include OmniAuthTestHelper, type: :controller
  end
  </code></pre>
  
  <p>user.rb</p>
  
  <pre><code>class User &lt; ActiveRecord::Base
  
    def self.from_omniauth(auth)
      where(auth.slice(:provider, :uid)).first_or_create do |user|
        user.provider = auth.provider
        user.uid = auth.uid
        user.first_name = auth.info.first_name
        user.last_name = auth.info.last_name
        user.email = auth.info.email
        user.password = auth.credentials.token
        user.password_confirmation = auth.credentials.token
        user.oauth_token = auth.credentials.token
        user.oauth_expires_at = Time.at(auth.credentials.expires_at)
      end
    end
  end
  </code></pre>
  
  <p>Any help would be really cool. Thanks guys!</p>