Reputation: 151
I implemented point system. User.point increases by 2 when he does login. My devise session controller is below.
class Users::SessionsController < Devise::SessionsController
after_action :add_point, only: [:create]
# POST /resource/sign_in
def create
super
end
private
def add_point
resource.rewards.create(point: 2)
end
end
and My spec/controllers/users_controller_spec.rb is below.
RSpec.describe UsersController, type: :controller do
describe 'adds 2 point with login' do
before do
@user=create(:user)
end
it 'adds 2 point in one day if two times login' do
expect{login_user(@user)}.to change {@user.points}.by(0)
end
it 'adds 4 point in two day ' do
expect{login_user(@user)}.to change {@user.points}.by(2)
end
end
end
and my model/user.rb is below.
class User < ActiveRecord::Base
def points
self.rewards.sum(:point)
end
end
When I did rspec command , I had this error.
Failure/Error: expect{login_user(@user)}.to change {@user.points}.by(2)
expected result to have changed by 2, but was changed by 0
I confirmed that @user.points increased by 2 in rails/console. Why do I have this error? Please tell me.
By looking at answers , I change it to below.
require 'rails_helper'
RSpec.describe Users::SessionsController, type: :controller do
describe 'adds 2 point with login' do
before do
@user=create(:user)
@request.env["devise.mapping"] = Devise.mappings[:user]
end
it 'adds 2 point in one day if two times login' do
expect{post :create, params: {email: @user.email ,password: @user.password} }.to change {@user.points(true)}.by(0)
end
it 'adds 4 point in two day ' do
expect{post :create, params: {email: @user.email ,password: @user.password} }.to change {@user.points(true)}.by(2)
end
end
end
Upvotes: 0
Views: 640
Reputation: 186
First, have you configured the routing since you use a custom controller (albeit that inherits from Devise Session controller)?
something like this, but in your case, it's sessions instead of registrations:
devise_for :users, :controllers => { :registrations => "registrations" }
Second, since you basically use a custom controller, try hitting the controller the normal way rather than using the Devise test helper.
Assuming you got the login_user
method from the Devise documentation like below here:
module ControllerMacros
def login_user
before(:each) do
@request.env["devise.mapping"] = Devise.mappings[:user]
user = FactoryGirl.create(:user)
user.confirm! # or set a confirmed_at inside the factory. Only necessary if you are using the "confirmable" module
sign_in user
end
end
end
you have to understand that the login_user method DOES NOT make a request to the Users::SessionsController you created. This is why your callback after_action :add_point, only: [:create]
is not triggered, hence no points were added to the logged_in user.
What I meant by hitting the rspec with proper request is calling like this:
post :create, params: { session_params }
Upvotes: 1
Reputation: 845
In most cases that will work:
expect{ login_user(@user) }.to change { @user.reload.points }.by(0)
Looks like @user
instance is desynchronized with DB.
Upvotes: 0