I am currently learning Ruby on Rails on Rails Tutorial.
I did rails test, and then got this error.
error log
UsersSignupTest#test_valid_signup_information_with_account_activation:
NameError: uninitialized constant User::FILL_IN
app/models/user.rb:42:in `activate'
app/controllers/account_activations_controller.rb:6:in `edit'
test/integration/users_signup_test.rb:39:in `block in <class:UsersSignupTest>'
I do not understand the meaning of this error. I have to initialize constant User::FILL_IN probably.
app/models/user.rb
class User < ApplicationRecord
attr_accessor :remember_token, :activation_token
before_save :downcase_email
before_create :create_activation_digest
....
def activate
update_columns(activated:FILL_IN, activated_at:FILL_IN)
end
app/controllers/account_activations_controller.rb
class AccountActivationsController < ApplicationController
def edit
user = User.find_by(email: params[:email])
if user && !user.activated? && user.authenticated?(:activation, params[:id])
user.activate
log_in user
flash[:success] = "Account activated!"
redirect_to user
else
flash[:danger] = "Invalid activation link"
redirect_to root_url
end
end
end
test/integration/users_signup_test.rb
require 'test_helper'
class UsersSignupTest < ActionDispatch::IntegrationTest
...
assert_equal 1, ActionMailer::Base.deliveries.size
user = assigns(:user)
assert_not user.activated?
log_in_as(user)
assert_not is_logged_in?
get edit_account_activation_path("invalid token", email: user.email)
assert_not is_logged_in?
get edit_account_activation_path(user.activation_token, email: 'wrong')
assert_not is_logged_in?
get edit_account_activation_path(user.activation_token, email: user.email)
assert user.reload.activated?
follow_redirect!
assert_template 'users/show'
assert is_logged_in?
end
Could you help me to solve this?
You are not supposed to actually use the words FILL_IN. You are supposed to change FILL_IN the whatever you need to make the tests pass. You probably need something like:
update_columns(activated: true, activated_at: Time.now)
Related
All the other answers are wrong or out of date. I've tried several things. This is what I have:
require 'test_helper'
class DealsControllerTest < ActionDispatch::IntegrationTest
include Devise::Test::IntegrationHelpers
setup do
#deal = deals(:one)
#user = users(:one)
# https://github.com/plataformatec/devise/wiki/How-To:-Test-controllers-with-Rails-3-and-4-(and-RSpec)
##request.env["devise.mapping"] = Devise.mappings[:one]
#sign_in #user
#log_in_as #user
ApplicationController.allow_forgery_protection = false
post user_session_path, params: {user: {email: #user.email, password: #user.password}}
assert_select "p", "Invalid Email or password."
assert_response :redirect ############ line 16
#assert_text "Invalid Email or password."
assert_redirected_to root_url
end
Failure:
DealsControllerTest#test_should_destroy_deal [C:/Users/Chloe/workspace/fortuneempire/test/controllers/deals_controller_test.rb:16]:
Expected response to be a <3XX: redirect>, but was a <200: OK>
Since it passes the "Invalid email/password" test, that means the user is NOT logging in!
I tried these answers:
How to sign in a user using Devise from a Rails console?
How to sign_in for Devise to Test Controller with Minitest
https://github.com/plataformatec/devise/wiki/How-To:-Test-controllers-with-Rails-3-and-4-(and-RSpec)
Rails: Capybara can't log in user with Devise fixture data
This worked
require 'test_helper'
class DealsControllerTest < ActionDispatch::IntegrationTest
include Warden::Test::Helpers
setup do
#deal = deals(:one)
#user = users(:one)
# https://github.com/plataformatec/devise/wiki/How-To:-Test-with-Capybara
#user.confirmed_at = Time.now
#user.save
login_as(#user, :scope => :user)
end
teardown do
Warden.test_reset!
end
I'm going through Michael Hartl's Ruby tutorial and have been stuck for a day on a failing test
I get this when I run:
Error:
UsersControllerTest#test_should_redirect_edit_when_logged_in_as_wrong_user:
NoMethodError: undefined method `session' for nil:NilClass
test/test_helper.rb:19:in `log_in_as'
test/controllers/users_controller_test.rb:37:in `block in <class:UsersControllerTest>'
Here is the calling code:
require 'test_helper'
class UsersControllerTest < ActionDispatch::IntegrationTest
def setup
#user = users(:michael)
#otheruser = users(:archer)
end
test "should redirect update when logged in as wrong user" do
log_in_as(#other_user)
patch user_path(#user), params: { user: { name: #user.name,
email: #user.email } }
assert flash.empty?
assert_redirected_to root_url
end
*And here is the method I'm trying to call from the **test_helper** class:*
# Log in as a particular user
def log_in_as(user)
session[:user_id] = user.id
end
I was missing a part in my test_helper.rb class:
class ActionDispatch::IntegrationTest
# Log in as a particular user.
def log_in_as(user, password: 'password', remember_me: '1')
post login_path, params: { session: { email: user.email,
password: password,
remember_me: remember_me } }
end
end
Thank you for taking a look!
Did you include this line of code: include SessionsHelper in your application_controller.rb?
You have typo in setup method from the code above: #otheruser = users(:archer) should be #other_user = users(:archer)
Check again the code from the test file: test / controllers / users_controller_test.rb
especially this part of the code:
test "should redirect edit when logged in as wrong user" do
log_in_as(#other_user)
get edit_user_path(#user)
assert flash.empty?
assert_redirected_to root_url
end
Hope it helps!
I'm attempting to create some controller specs in my Rails 5 app using rspec, but the code keeps throwing the following error:
1) SessionsController Log in and log out logs in with valid user
Failure/Error: user = User.find_by(email: params[:session][:email].downcase)
NoMethodError:
undefined method `[]' for nil:NilClass
My spec is pretty straightforward. The user instance variable uses factory-girl to create a user with the email "user#example.com" and password as "password." When I call puts on these variables, I can see that they are set correctly.:
require 'rails_helper'
RSpec.describe SessionsController, type: :controller do
before :each do
#user = create(:user)
end
describe "Log in and log out" do
before :each do
post :create, { session: { email: #user.email,
password: #user.password }}
end
it "logs in with valid user" do
puts #user.email + " " + #user.password
expect(is_logged_in?).to be_truthy
end
end
end
Finally, the code from the sessions controller is below:
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
log_in user
remember user
redirect_to user
else
flash.now[:danger] = 'Invalid email/password combination'
render 'new'
end
end
end
Am I misunderstanding the way params are sent to the controller in rspec? Is there any other reason for this error to be returned?
Changes were made in Rails 5 to the way you send params in controller tests.
Instead of:
before :each do
post :create, { session: { email: #user.email,
password: #user.password }}
end
You need to provide the params key in post request attribute hash. Like so...
before :each do
post :create, params: { session: { email: #user.email,
password: #user.password }}
end
It's subtle, but it's different. Let me know if that works.
10 tutorial and has come up with this error
ERROR["test_password_resets", PasswordResetsTest, 2016-04-14 20:33:23 +0800]
test_password_resets#PasswordResetsTest (1460637203.22s)
NoMethodError: NoMethodError: undefined method `reset_sent_at=' for #<User:0x007f942d13d620>
app/models/user.rb:56:in `create_reset_digest'
app/controllers/password_resets_controller.rb:12:in `create'
test/integration/password_resets_test.rb:18:in `block in <class:PasswordResetsTest>'
app/models/user.rb:56:in `create_reset_digest'
app/controllers/password_resets_controller.rb:12:in `create'
test/integration/password_resets_test.rb:18:in `block in <class:PasswordResetsTest>'
33/33: [=================================] 100% Time: 00:00:01, Time: 00:00:01
Finished in 1.61023s
33 tests, 143 assertions, 0 failures, 1 errors, 0 skips
Here's my user model
class User < ActiveRecord::Base
attr_accessor :remember_token, :activation_token, :reset_token
before_save :downcase_email
before_create :create_activation_digest
...
#set the password reset attributes
def create_reset_digest
self.reset_token = User.new_token
self.update_attribute(:reset_digest, User.digest(reset_token))
self.update_attribute(:reset_sent_at, Time.zone.now)
end
Here's my controller code
def create
#user = User.find_by(email: params[:password_reset][:email].downcase)
if #user
#user.create_reset_digest
#user.send_password_reset_email
flash[:info] = "Email sent with password reset instruction"
redirect_to root_url
else
flash.now[:danger] = "Email address not found"
render 'new'
end
end
And Finally here's my test!
class PasswordResetsTest < ActionDispatch::IntegrationTest
def setup
ActionMailer::Base.deliveries.clear
#user = users(:michael)
end
test "password resets" do
get new_password_reset_path
assert_template 'password_resets/new'
# Invalid email
post password_resets_path, password_reset: { email: "" }
assert_not flash.empty?
assert_template 'password_resets/new'
# Valid email
post password_resets_path, password_reset: { email: #user.email }
assert_not_equal #user.reset_digest, #user.reload.reset_digest
assert_equal 1, ActionMailer::Base.deliveries.size
assert_not flash.empty?
assert_redirected_to root_url
# Password reset form
user = assigns(:user)
# Wrong Email
get edit_password_reset_path(user.reset_token, email: "")
assert_redirected_to root_url
# Inactive user
user.toggle!(:activated)
get edit_password_reset_path(user.reset_token, email: user.email)
assert_redirected_to root_url
user.toggle!(:activated)
# Right email, wrong token
get edit_password_reset_path('wrong token', email: user.email)
assert_redirected_to root_url
# Right email Right token
get edit_password_reset_path(user.reset_token, email: user.email)
assert_template 'password_resets/edit'
assert_select "input[name=email][type=hidden][value=?]", user.email
# Invalid password & confirmation
patch password_reset_path(user.reset_token),
email: user.email,
user: { password: "foobaz", password_confirmation: "barquux" }
assert_select 'div#error_explanation'
# Blank password & confirmation
patch password_reset_path(user.reset_token),
email: user.email,
user: { password: " ", password_confirmation: "foobar" }
assert_not flash.empty?
assert_template 'password_resets/edit'
# valid password & confirmation
patch password_reset_path(user.reset_token),
email: user.email,
user: { password: "foobaz", password_confirmation: "foobaz" }
assert is_logged_in?
assert_not flash.empty?
assert_redirected_to user
end
end
My app itself is working fine. So I'm not sure if i wrote the test wrong or something in my applicationn is wrong. Please help!
If your app itself is working fine, and only the test is breaking, then there is one thing I can guess is the fault:
The attribute reset_sent_at is not available in the test environment.
To solve this, try to run your migrations for the test environment as follow:
RAILS_ENV=test rake db:migrate
This can easily be the only thing you need done.
I've been stuck on this one for a while and keep getting 2 errors when I rake test. Referencing Listing 9.23 testing point. Any help would be much appreciated.
Test Error:
1) Error:
UsersControllerTest#test_should_redirect_update_when_logged_in_as_wrong_user:
NameError: undefined local variable or method `user_id' for #<UsersControllerTest:0x007fbff6be3120>
test/test_helper.rb:24:in `log_in_as'
test/controllers/users_controller_test.rb:35:in `block in <class:UsersControllerTest>'
2) Error:
UsersControllerTest#test_should_redirect_edit_when_logged_in_as_wrong_user:
NameError: undefined local variable or method `user_id' for #<UsersControllerTest:0x007fbff6c01850>
test/test_helper.rb:24:in `log_in_as'
test/controllers/users_controller_test.rb:28:in `block in <class:UsersControllerTest>'
29 runs, 66 assertions, 0 failures, 2 errors, 0 skips
User_Controller_Test file:
require 'test_helper'
class UsersControllerTest < ActionController::TestCase
def setup
#user = users(:michael)
#other_user = users(:archer)
end
test "should get new" do
get :new
assert_response :success
end
test "should redirect edit when not logged in" do
get :edit, id: #user
assert_not flash.empty?
assert_redirected_to login_url
end
test "should redirect update when not logged in" do
patch :update, id: #user, user: { name: #user.name, email: #user.email }
assert_not flash.empty?
assert_redirected_to login_url
end
test "should redirect edit when logged in as wrong user" do
log_in_as(#other_user)
get :edit, id: #user
assert flash.empty?
assert_redirected_to root_url
end
Test_Helper.rb:
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
class ActiveSupport::TestCase
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
fixtures :all
def is_logged_in?
!session[:user_id].nil?
end
#logs in a test user
def log_in_as(user, options = {})
password = options[:password] || 'password'
remember_me = options[:remember_me] || '1'
if integration_test?
post login_path, session: { email: user.email,
password: password,
remember_me: remember_me}
else
session[:user_id] = user_id
end
end
private
#returns true inside an int. test
def integration_test?
defined?(post_via_redirect)
end
end
And where does user_id come from here?
def log_in_as(user, options = {})
...
if integration_test?
...
else
session[:user_id] = user_id
end
end
Seems it should be:
session[:user_id] = user.id