Note that there are some explanatory texts on larger screens.

plurals
  1. POcapybara/rspec: should GET/PUT tests be in different files?
    primarykey
    data
    text
    <p>I'm following the <a href="http://ruby.railstutorial.org/" rel="nofollow">Ruby on Rails Tutorial</a>, and now I need to write tests for the authorization code, e.g. making sure users can only edit their own profile.</p> <p>There are two actions to test. One is to ensure a user can't access the page of editing other users' profile. This one is easy, a simple "feature" test in capybara.</p> <p>But I certainly want to test the PUT action too, so that a user can't manually submit a PUT request, bypassing the edit page. From what I read, this should be done as an rspec "request" test.</p> <p>Now my question is, do I have to maintain them in different dirs? (spec/features vs spec/requests)? It doesn't sound right since these two scenarios are closely related. How are such tests usually done in Rails?</p> <p>For example,</p> <pre><code>describe "as wrong user" do let(:user) { FactoryGirl.create(:user) } let(:wrong_user) { FactoryGirl.create(:user, email: "wrong@example.com") } before { sign_in user } describe "visiting Users#edit page" do before { visit edit_user_path(wrong_user) } it { should_not have_selector('title', text: full_title('Edit user')) } end describe "submitting a PUT request to the Users#update action" do before { put user_path(wrong_user) } specify { response.should redirect_to(root_path) } end end </code></pre> <p>The second test doesn't work in capybara 2.x since "put" is not supported any longer. It has to be a request test. And now I have to write a second "sign_in" method, since the current one uses methods that are only available to feature tests. Smells like a lot of code duplication.</p> <p>======== my solution ========</p> <p>After figuring out how to login in a request test, thanks to Paul Fioravanti's answer,</p> <pre><code> before do post sessions_path, email: user.email, password: user.password cookies[:remember_token] = user.remember_token end </code></pre> <p>I changed all tests to request tests. So I don't have to split them into different files. Paul's solution would also work though I think this is cleaner.</p> <pre><code>describe 'authorization' do describe 'as un-signed-in user' do let(:user) { FactoryGirl.create(:user) } describe 'getting user edit page' do before { get edit_user_path(user) } specify { response.should redirect_to(signin_path) } end describe 'putting to user update page' do before { put user_path(user) } specify { response.should redirect_to(signin_path) } end end describe 'as wrong user' do let(:user) { FactoryGirl.create(:user) } let(:wrong_user) { FactoryGirl.create(:user, email: 'wrong@example.com') } before do post sessions_path, email: user.email, password: user.password cookies[:remember_token] = user.remember_token end describe 'getting user edit page' do before { get edit_user_path(wrong_user) } specify { response.should redirect_to(root_path) } end describe 'putting to user update page' do before { put user_path(wrong_user) } specify { response.should redirect_to(root_path) } end end end </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload