Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scaffolded tests failing with ActionController::InvalidAuthenticityToken

In Rails 4.1.6, I'm getting InvalidAuthenticityToken errors when running the tests generated with scaffold. Is there any way to disable the authenticity token check for a specific test?

rails g scaffold user name:string email:string password_digest:string
rake

Output:

...

  1) Error:
UsersControllerTest#test_should_create_user:
ActionController::InvalidAuthenticityToken: ActionController::InvalidAuthenticityToken
    test/controllers/users_controller_test.rb:21:in `block (2 levels) in <class:UsersControllerTest>'
    test/controllers/users_controller_test.rb:20:in `block in <class:UsersControllerTest>'

...

This is the source code:

test "should create admin_user" do
  assert_difference('Admin::User.count') do
    post :create, admin_user: { email: @admin_user.email, password_digest: @admin_user.password_digest, username: @admin_user.username }
  end

  assert_redirected_to admin_user_path(assigns(:admin_user))
end
like image 1000
Schrute Avatar asked Oct 20 '14 18:10

Schrute


1 Answers

There are some options:

-> You can change behaviour of detecting CSRF invalid token to reseting session (like it was in Rails 3):

In application_controller.rb

protect_from_forgery with: :exception

to

protect_from_forgery with: :null_session

-> You can do that with conditional expression, something like:

if Rails.env.test?
  protect_from_forgery with: :null_session
else 
  protect_from_forgery with: :exception
end

However this gave you a little bit different configuration for test and for dev/production env.

-> You can provide authenticity token manually in tests:

def set_form_authenticity_token
  session[:_csrf_token] = SecureRandom.base64(32)
end

And in particular test:

post :create, admin_user: { email: @admin_user.email, password_digest: @admin_user.password_digest, username: @admin_user.username }, authenticity_token:  set_form_authenticity_token

-> You can write your own helper, something like:

def set_form_authenticity_token
  session[:_csrf_token] = SecureRandom.base64(32)
end

alias_method :post_without_token, :post
def post_with_token(symbol, args_hash)
  args_hash.merge!(authenticity_token: set_form_authenticity_token)
  post_without_token(symbol, args_hash)
end
alias_method :post, :post_with_token
like image 107
Esse Avatar answered Nov 15 '22 00:11

Esse