DaniG2k
DaniG2k

Reputation: 4903

Simple authorization test with RSpec & Capybara failing

I'm trying to test some authorization on my website using RSpec & Capybara. The idea is that an article can only be editable by ad administrator or the person who wrote the article. I'm not using any gems, just a few simple rules.

This is my spec:

require 'rails_helper'
require 'capybara/rspec'

describe "the authorization process", :type => :feature do
  before :each do
    @user = User.new(:id => 3, :email => '[email protected]', :password => 'password', :password_confirmation => 'password', :username => 'Dummy User')
    @user.save
  end

  it "does not allow a registered user to edit others' articles" do
    visit '/login'
    within("#new_user") do
      fill_in 'Email', :with => '[email protected]'
      fill_in 'Password', :with => 'password'
    end
    click_button 'Log in'
    expect(page).to have_title 'Website Name'
    expect(page).to have_content 'Signed in successfully!'

    # Seems to be working up to here

    visit section_path('mysection')

    click_link 'Some link on the page'
    expect(current_path).to eq(my_article_path(section: 'mysection', year: 2014, month: 10))
  end
end

but running this returns the following error:

Failures:

  1) the authorization process does not allow a registered user to edit others' articles
     Failure/Error: click_link 'Some link on the page'
     NoMethodError:
       undefined method `username' for nil:NilClass
     # ./app/controllers/articles_controller.rb:38:in `show'

So I look at the articles_controller.rb file and find:

34 def show
35   if @article.nil?
36     redirect_to root_path, alert: "Oops! There are no articles matching a url ending in \"#{params[:id]}\""
37   else
38     @username = @article.user.username
39   end
40 end

I tried using pry to see what happens right before the @username = @article.user.username line. It appears as if my @article object exists, but calling .user from my test returns nil and as a consequence, calling .username on that also returns nil, causing the failed test.

This works in development and production, just not in test. I'm wondering how I can fix this?

Thanks!

Upvotes: 0

Views: 216

Answers (1)

K M Rakibul Islam
K M Rakibul Islam

Reputation: 34336

Try to stub the username of the article so that it is not nil when it gets called:

before(:each) {allow(@article.user).to receive(:username).and_return('username')}

Upvotes: 1

Related Questions