4
votes

I am new to programming, this is my first application. While creating an application in Rails, i have two models. User&list,nested.

resources :users do
  resources :lists
end

These are the following routes i obtain with this setting:

user_lists GET    /users/:user_id/lists(.:format)             lists#index
           POST   /users/:user_id/lists(.:format)             lists#create
new_user_list GET    /users/:user_id/lists/new(.:format)      lists#new
edit_user_list GET    /users/:user_id/lists/:id/edit(.:format)lists#edit
user_list GET    /users/:user_id/lists/:id(.:format)          lists#show
           PUT    /users/:user_id/lists/:id(.:format)         lists#update
           DELETE /users/:user_id/lists/:id(.:format)         lists#destroy

With regards i have created the views with the following links.

<div class="stats">
  <a href="<%= user_lists_path(current_user) %>">
    <%= pluralize(current_user.lists.count, 'List') %>
  </a>
</div>

<div class="list">
  <%= link_to 'Create List', new_user_list_path(current_user) %>
</div>

These work as expected, however when i use the same url helpers in testing i get an error.

describe "List create page" do 
  let(:user) { FactoryGirl.create(:user) }
  before do  
    user.save
    visit new_user_list_path(user)
  end
  it { should have_selector('title', text: 'SocialTask | List') }
  it { should have_selector('h1', text: 'Create list') }

  describe "invalid list creation" do 
    before { click_button 'Create list' } 
    it { should have_content('Error in creating list') }
  end
 end

This causes the tests to have an error.

Failure/Error: visit new_user_list_path(user)
 NoMethodError:
   undefined method `lists' for nil:NilClass

I have tried playing around with the url that did not work. I tried updating rspec/capybara that did not work either. I have also checked the inclusion of

config.include Rails.application.routes.url_helpers

in the spec helper.

How do i get the helpers to work? Or am i missing some minor detail? Thanks in advance.

Helper Methods.

module SessionsHelper

def sign_in(user)
  cookies.permanent[:remember_token] = user.remember_token
  self.current_user = user 
end

def current_user=(user)
  @current_user = user 
end

def current_user 
  @current_user ||= User.find_by_remember_token(cookies[:remember_token])
end

def signed_in?
  !current_user.nil?
end

def sign_out
  self.current_user = nil 
  cookies.delete(:remember_token)
end

def current_user?(user)
  current_user == user
end
end

The rspec helper to sign in. support/utilities.rb

include ApplicationHelper
 def sign_in(user)
  visit signin_path
  fill_in "Email", with: user.email
  fill_in "Password", with: user.password
  click_button "Sign in"
  cookies[:remember_token] = user.remember_token
 end
2
Any idea why this is the case? Despite creating a user with FactoryGirl? - ShivamD
Yes once the user is created, it gets signed_in. - ShivamD
The user login step is not shown in the RSpec example you posted. You need something like sign_in(user). - zetetic
I already have a helper in the support/utilities.rb. Edited my post to show it. - ShivamD
I spotted the error. In the test file i only added "user.save" and forgot to put in "sign_in user" Once i did that, all the tests passed. - ShivamD

2 Answers

1
votes

Without seeing the stack trace, I think your problem is in the view on this line:

<%= pluralize(current_user.lists.count, 'List') %>

It seems like current_user is nil. Normally you should define some kind of helper method in your RSpec suite to simulate a user logging in. That way, current_user will return the user that you stub out in the test.

Here's an example:

# spec/support/session_helper.rb
module SessionHelper
  def login(username = 'admin')
    request.session[:user_id] = User.find_by_username(username).id
  end
end

Yours will differ depending on how you authenticate your users. For example, Devise publishes its own set of test helpers, so you can simply include its helpers directly:

# spec/support/devise.rb
RSpec.configure do |config|
  config.include Devise::TestHelpers, :type => :controller
end
0
votes

Seems it's getting an error because the user doesn't exists. Try to change user.save to user.save! then you'll catch the error on creation I think..