ik00ma
ik00ma

Reputation: 432

Rspec feature test. Page content doesn't differ among ordinary user and admin

I'm new to testing. I use rspec-rails, factory_girl_rails and capybara to test Rails 5 app. For authentication I have devise.

My User model has additional field admin. By default admin is false. But first registered user becomes an administrator (user.admin = true).

Now when I do user = create(:user) in my test it creates an 'ordinary' user (user.admin = false)

But if I puts page.body I can see content which should not be rendered for an ordinary user.

Here is my template:

%menu
 %ul
   - if user_signed_in?
     %li
       Hey, #{current_user.name}
     %li= link_to "Edit Profile", edit_user_registration_path
     - if current_user.admin
       %li= link_to "Today's Orders", todays_orders_path
       %li= link_to "Registered Users", users_path
       %li= link_to "Add Dish", new_dish_path
     %li= link_to "Sign Out", destroy_user_session_path

Feature test's snippet:

require 'rails_helper'
require_relative '../support/authentication'

feature 'page content' do

  let(:user) { create(:user) }

  scenario 'show page content' do
    authentication = Authentication.new user
    authentication.sign_in

    puts page.body
  end
end

That's what puts return:

<menu>
<ul>
<li>
Hey, Test User
</li>
<li><a href="/users/edit">Edit Profile</a></li>
<li><a href="/todays_orders">Today&#39;s Orders</a></li>
<li><a href="/users">Registered Users</a></li>
<li><a href="/dishes/new">Add Dish</a></li>
<li><a href="/users/sign_out">Sign Out</a></li>
</ul>
</menu>

I suppose current_user.admin is ignored or something. But how to make it work properly?

UPD

That's interesting. First of all if I create one user and than puts user.inspect it shows:

#<User id: 1, email: "[email protected]", name: "User_1", admin: false, created_at: "2016-09-06 15:15:31", updated_at: "2016-09-06 15:15:31">

but if I use (byebug) the output shows that user.admin is set to true:

(byebug) u = User.all <ActiveRecord::Relation [#<User id: 1, email: "[email protected]", name: "User_1", admin: true, created_at: "2016-09-06 15:15:31", updated_at: "2016-09-06 15:15:31">]>

Next thing is if I create two users with:

let(:admin) { create(:user) } let(:user) { create(:user) }

and than sign in with user I still have all links available.. but if I create users like this:

admin = User.create(name: 'admin', email: '[email protected]', password: 123456, password_confirmation: 123456) user = User.create(name: 'user', email: '[email protected]', password: 123456, password_confirmation: 123456)

and sign is with user, everything works fine.

Upvotes: 0

Views: 143

Answers (1)

Abhishek Dujari
Abhishek Dujari

Reputation: 2443

Tests run on test database which is empty. The first user created is admin as you said so thats whats happening. The tests are correct in that regard. You have to create a second user in your test to have an ordinary user.

You can use byebug inside the 'it' block and then query to see that admin is set to true.

Edit: using let!(:admin) forces rspec to create the record immediately as opposed to lazy loading which is the default behaviour. When lazy loading the factory it is possible that :admin is being called :user and therefore not really :admin

Upvotes: 2

Related Questions