问题
Currently, my Rails app only displays activated user accounts in the search results. It also only allows people to navigate to a profile page if that profile has been activated. To do these things, users_controller.rb
is configured like this:
def index
@users = User.where(activated: true).paginate(page: params[:page])
end
def show
@user = User.find(params[:id])
redirect_to root_url and return unless @user.activated?
end
I am wondering how to use an integration test to check this behavior. My current test is this:
test "only show profiles of activated users" do
log_in_as(@admin)
get users_path
assert_template 'users/index'
assert_select 'div.pagination'
first_page_of_users = User.paginate(page: 1)
first_page_of_users.each do |user|
assert_equal true, user.activated?
end
end
I have also modified /fixtures/users.yml to include a user that has not activated his profile:
non:
name: Non Activated
email: nonactivated@example.gov
password_digest: <%= User.digest('password') %>
activated: false
When I run rake test
, I get this error:
FAIL["test_only_show_profiles_of_activated_users", UsersIndexTest, 1.271917]
test_only_show_profiles_of_activated_users#UsersIndexTest (1.27s)
Expected: true
Actual: false
test/integration/users_index_test.rb:40:in `block (2 levels) in <class:UsersIndexTest>'
test/integration/users_index_test.rb:39:in `block in <class:UsersIndexTest>'
Can anyone help me understand why the test is able to detect profiles of non-activated users?
回答1:
Firstly, let me state that my struggle with this same exercise landed me here, so I’m obliged for your post. 6 months late, but perhaps my response might still provide some insight.
After a good deal of effort, this much is clear to me:
User.paginate
is semi-redundant to the actual code in users_controller.rb, and furthermore, is actually causing your immediate problem -- namely, in your test,User.paginate
doesn’t include the where filter- Instantiating
User.paginate
directly in the test and using it to evaluate its own members doesn’t make sense - in this case, the test is only testing itself and not the app - In order to actually test the app, one must access the
@users
instance variable in users_controller.rb, e.g.,my_test_users = assigns(:users)
- In order to be thorough and test for presence of the non-activated user pre-defined in the users.yml fixture, we should check all pages, which presents the problem of how to determine total number of pages -- will_paginate provides this:
my_test_users.total_pages
- The final insight that helped with this exercise was to really begin understanding what makes up a REST-ful implementation, namely, how controller-action mapping works with named routes and parameterization, e.g.,
get users_path, page: 1
-- this obviously calls the users controller, and if we recall that will_paginate takes a :page argument -->User.paginate(page: params[:page])
-- we see that this argument is provided by the named path parameter above
So hopefully this much is enough to put the pieces together for a complete integration test.
(The test to see if non-activated user is redirected to root_url upon attempting to navigate to user profile is much more straightforward)
For what it’s worth, so far, this exercise has proven to be the most challenging and rewarding of the tutorial.
回答2:
I think for your case the better way of access you can use default scope
default_scope where(:published => true)
来源:https://stackoverflow.com/questions/30855953/railstutorial-ch-10-how-do-i-test-that-only-activated-users-are-viewable-to-ot