I'm using the gems pundit
and devise
. I have a delete link that only shows up if you are an admin. I have an integration test that I would like to verify that the delete link only shows up for admins.
test 'comment delete link shows when it should' do
log_in_as @admin
get movie_path(@movie)
assert_select 'a[href=?]', movie_comment_path(comments(:one), @movie.id)
end
My test_helper.rb
looks like this:
...
class ActiveSupport::TestCase
...
def log_in_as(user, options = {})
password = options[:password] || 'password'
if integration_test?
post user_session_path, 'user[email]' => user.email, 'user[password]' => user.password
else
Devise::TestHelpers.sign_in user
end
end
private
# Returns true inside an integration test.
def integration_test?
defined?(post_via_redirect)
end
end
The response.body
looks all right, but indeed there is no delete link. There is one when I run the development server and visit the page myself. I've narrowed this down to the current_user
that pundit uses in the policies is being passed in with a value of nil
. This is my comment_policy.rb
:
class CommentPolicy
attr_reader :current_user, :comment
def initialize(current_user, model)
@current_user = current_user
@comment = model
end
def create?
if @current_user
@current_user.member? or @current_user.content_creator? or @current_user.moderator? or @current_user.admin?
end
end
def destroy?
if @current_user
@current_user == @comment.user or @current_user.moderator? or @current_user.admin?
end
end
end
As a closing remark, I've heard that Rails 5 has opted for integration tests instead of controller tests as we know them from Rails 4 for the default type of tests to be generated for our controllers. If this is the case, devise
would be a heck of a lot more useful out of the box when using Rails 5 if the sign_in
/sign_out
helpers that work in controller tests were made to work in integration tests as well. But would I still have this issue of pundit
not knowing what current_user
is? I'm assuming this all works fine in controller tests because the current_user
is scoped to controllers? Any and all light shed on this topic is much appreciated, but I would really like to figure out how to get integration tests to work with this setup because I have about a billion I want to write right now.
Not that it totally matters, but does it need to be using current_user in the policy or can it just use user in the policy. By this I mean according to the elabs/pundit README on Github I would just use @user
and user
everywhere instead of current_user
. Read the README if I confused you.
Additionally the nil
for current_user
typically occurs when you don't have a valid CSRF token for your request. When you do this on the website manually by going to localhost:3000
or w/e you are first performing a get
on the login path before doing the post on the login path with your credentials. In your integration test I don't seem to see where you are performing that get
in order to get the CSRF for your session.
Hope this helps!!!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With