0

I am trying to test AJAX requests and was told to use poltergeist with capybara to get it working. My tests are failing during authorization with Twitter even though it is mocked. Here is my spec:

def valid_sign_in_via_twitter
    visit root_path
    mock_omniauth_sign_in
    click_link "Sign in with"
end

describe '- input form via AJAX -', :js => true do
    it 'input form is valid if all fields are filled in.', :driver => :poltergeist do
        valid_sign_in_via_twitter
        valid_tweet_form_input
        expect(page).to have_content("Your tweet has been scheduled")
        expect(Tweet.all.count).to be(1)
    end

    it 'will be added to delayed_job process queue when scheduled.', :driver => :poltergeist do
        valid_sign_in_via_twitter
        valid_tweet_form_input
        expect(page).to have_content("Your tweet has been scheduled")
        expect(Delayed::Job.count).to eq(1)
        expect(Delayed::Job.last.handler).to have_content("This is a test scheduled tweet.")
    end
end

and here is the mock oauth sign in helper:

module OmniauthHelper
  def mock_omniauth_sign_in
    OmniAuth.config.mock_auth[:twitter] = OmniAuth::AuthHash.new({
    :provider => 'twitter',
    :uid => '1234567',
    :user_info => {
        :nickname => 'estlintester'
    },
    :credentials => {
        :token => '2342kmlskdlakmsdlkasmthisisfake',
        :secret => 'aslsakmdlkm32m3902jthisisfake'
    }
  })
  end
end

I can tell the tests are failing at "click_link" in the valid_sign_in_via_twitter method. This is the error, I believe it is hitting an Internal Server Error:

An error occurred in an after hook
  NoMethodError: undefined method `[]' for nil:NilClass
  occurred at /Users/alex/Documents/Side
Projects/estlin/app/models/user.rb:26:in `block in create_from_omniauth'

Here is the code from the user.rb that has to do with the error, line 26 is user.nickname = auth["info"]["nickname"]:

def self.from_omniauth(auth)
  user = User.where(auth.slice("uid")).first || create_from_omniauth(auth)
  if user.oauth_token != auth["credentials"]["token"] || user.oauth_token != auth["credentials"]["secret"]
    user.oauth_token = auth["credentials"]["token"]
    user.oauth_secret = auth["credentials"]["secret"]
    user.save!
  end
  user
end

def self.create_from_omniauth(auth)
  create! do |user|
    user.uid = auth["uid"]
    user.nickname = auth["info"]["nickname"]
    user.oauth_token = auth["credentials"]["token"]
    user.oauth_secret = auth["credentials"]["secret"]
  end
end

and here is the create action in my controller that is hit after going through Twitter when clicking on the sign in link:

def create
  user = User.from_omniauth(request.env['omniauth.auth'])
  session[:user_id] = user.id
  redirect_to root_path, notice: "You have signed in as '#{user.nickname}'"
end 

and here is my application_controller where the session[:user_id] is used:

def current_user
    @current_user ||= User.find_by_id(session[:user_id]) if session[:user_id]
end

The tests used to pass without a problem before I implemented AJAX, I'm completely lost here. I can't even test the AJAX requests yet because the authentication is failing. The app is also working fine and without an issue, it is just the tests that are failing. Not sure what to do here. Would I have to do something with VCR/FakeWeb? I haven't used those before so I'm not sure.

4

1 に答える 1

0

ところで!OmniAuth.config.mock_auth[:twitter] には:user_infoキーがありますが、User モデル (create_from_omniauth) では auth[" info "]["nickname"]を取得しようとしています

これを変える:

def self.create_from_omniauth(auth)
  create! do |user|
    user.uid = auth["uid"]
    user.nickname = auth["info"]["nickname"]
    user.oauth_token = auth["credentials"]["token"]
    user.oauth_secret = auth["credentials"]["secret"]
  end
end

これに:

def self.create_from_omniauth(auth)
  create! do |user|
    user.uid = auth["uid"]
    user.nickname = auth["user_info"]["nickname"]
    user.oauth_token = auth["credentials"]["token"]
    user.oauth_secret = auth["credentials"]["secret"]
  end
end

それはあなたのために問題を解決するかもしれません

于 2013-08-15T07:04:27.833 に答える