Signup Validation Test didn't change by 1 - ruby-on-rails

Signup Test Validation not working. Here is the code.
test "valid signup information" do
get signup_path
assert_difference 'User.count', 1 do
post_via_redirect users_path, user:{
name: "Example User",
email: "user#invalid.com",
password: "password",
password_confirmation: "password "
}
end
assert_template 'users/show'
end
Here is the result of Minitest.
"User.count" didn't change by 1.
Expected: 1
Actual: 0
I have done the invalid test, it works fine. the valid path is not working, when i add 1 to the block.
def show
#user = User.find(params[:id])
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
flash[:success] = "Welcome to the app"
redirect_to user_url(#user)
else
render 'new'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
end
Updated

Related

Rails tutorial 3rd ed. NoMethodError: undefined method `remember_token' for nil:NilClass

i go the problem with test in 9 chapter Rails Tutorial, but problem with test from the 8 chapter. Could anybody help me to solve it?
Problem is here
test "login with remembering" do
log_in_as(#user, remember_me: '1')
assert_not_nil cookies['remember_token']
assert_equal cookies['remember_token'], assigns(:user).remember_token
end
The test says that problem in
NoMethodError: undefined method `remember_token' for nil:NilClass
test/integration/users_login_test.rb:43:in `block in <class:UsersLoginTest>'
test/integration/users_login_test.rb:43:in `block in <class:UsersLoginTest>'
My full user_login_test
require 'test_helper'
class UsersLoginTest < ActionDispatch::IntegrationTest
def setup
#user = users(:michael)
end
test "login with invalid information" do #INVALID
get login_path
assert_template 'sessions/new'
post login_path, session: { email: "", password: "" }
assert_template 'sessions/new'
assert_not flash.empty?
get root_path
assert flash.empty?
end
test "login with valid information followed by logout" do
get login_path
post login_path, session: { email: #user.email, password: 'password' }
assert is_logged_in?
assert_redirected_to #user
follow_redirect!
assert_template 'users/show'
assert_select "a[href=?]", login_path, count: 0
assert_select "a[href=?]", logout_path
assert_select "a[href=?]", user_path(#user)
delete logout_path
assert_not is_logged_in?
assert_redirected_to root_url
# Simulate a user clicking logout in a second window.
delete logout_path
follow_redirect!
assert_select "a[href=?]", login_path
assert_select "a[href=?]", logout_path, count: 0
assert_select "a[href=?]", user_path(#user), count: 0
end
test "login with remembering" do
log_in_as(#user, remember_me: '1')
assert_not_nil cookies['remember_token']
assert_equal cookies['remember_token'], assigns(:user).remember_token
end
test "login without remembering" do
log_in_as(#user, remember_me: '0')
assert_nil cookies['remember_token']
end
end
My user controller is
class UsersController < ApplicationController
before_action :logged_in_user, only: [:edit, :update]
before_action :correct_user, only: [:edit, :update]
def show
#user = User.find(params[:id])
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
log_in #user
flash[:success] = "Welcome to the Sample App!"
redirect_to #user
else
render 'new'
end
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to #user
else
render 'edit'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
# Before filters
# Confirms a logged-in user.
def logged_in_user
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
# Confirms the correct user.
def correct_user
#user = User.find(params[:id])
redirect_to(root_url) unless current_user?(#user)
end
end
All test was green, till i add some code from Chapter 9.2.3 And then i had this problem. Im new in Ruby and its little hard for me solve this problem.
Best regards, and sorry for my english)
The problem is that assigns[:user] is nil. log_in_as is a test helper, it is not calling your controller so assigns is always empty. Also, it is not really testing your controller. You need to write it as the rest of your tests:
test "login with remembering" do
post login_path, session: { email: #user.email, password: 'password', remember_me: '1' }
assert_not_nil cookies['remember_token']
assert_equal cookies['remember_token'], assigns(:user).remember_token
end

Failure: UsersSignupTest#test_valid_signup_information_with_account_activation Expected: 1 Actual: 2

I am following railstutorial and am having this error in chapter 10.
I thought it should be similar with this post. Unfortunately, the solution does not work with my problem.
Changing 1 into 2 in line assert_equal 1, ActionMailer::Base.deliveries.size in user_signup_test.rb make the test GREEN. lol.
But I am a complete noob so do not really understand the real issue.
could someone show me where I miss?
Failure:
UsersSignupTest#test_valid_signup_information_with_account_activation
[/home/xxx/sample_app/test/integration/users_signup_test.rb:30]:
Expected: 1
Actual: 2
user_signup_test.rb
require 'test_helper'
class UsersSignupTest < ActionDispatch::IntegrationTest
# test "the truth" do
# assert true
# end
def setup
ActionMailer::Base.deliveries.clear
end
test "invalid signup information" do
get signup_path
assert_no_difference 'User.count' do
post users_path, user: { name: "",
email: "user#invalid",
password: "foo",
password_confirmation: "bar" }
end
assert_template 'users/new'
end
test "valid signup information with account activation" do
get signup_path
assert_difference 'User.count', 1 do
post users_path, user: { name: "Example User",
email: "user#example.com",
password: "password",
password_confirmation: "password" }
end
assert_equal 1, ActionMailer::Base.deliveries.size
user = assigns(:user)
assert_not user.activated?
# Try to log in before activation.
log_in_as(user)
assert_not is_logged_in?
# Invalid activation token
get edit_account_activation_path("invalid token")
assert_not is_logged_in?
# Valid token, wrong email
get edit_account_activation_path(user.activation_token, email: 'wrong')
assert_not is_logged_in?
# Valid activation token
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
#assert_template 'users/show'
#assert is_logged_in?
end
user_controller.rb
class UsersController < ApplicationController
before_action :logged_in_user, only: [:edit, :update, :index, :destroy ]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: :destroy
def new
#user = User.new
end
def index
##users = User.all
#users = User.paginate(page: params[:page])
end
def show
#user = User.find(params[:id])
#debugger
end
def create
#user = User.new(user_params) # Not the final implementation!
if #user.save
# Handle a successful save.
#log_in #user
#flash[:success] = "Welcome to the Sample App!"
#redirect_to #user
#user.send_activation_email
UserMailer.account_activation(#user).deliver_now
flash[:info] = "Please check your email to activate your account."
redirect_to root_url
else
render 'new'
end
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
#Handle a successful update
flash[:success] = "Profile updated"
redirect_to #user
else
render 'edit'
end
end
def destroy
User.find(params[:id]).destroy
flash[:success] = "User deleted"
redirect_to users_url
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
# Before filters
# Confirms a logged-in user.
def logged_in_user
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
# Confirms the correct user.
def correct_user
#user = User.find(params[:id])
#redirect_to root_url unless #user == current_user
redirect_to root_url unless current_user?(#user)
end
# Confirms an admin user.
def admin_user
redirect_to(root_url) unless current_user.admin?
end
end
user_mailer.rb
class UserMailer < ApplicationMailer
# Subject can be set in your I18n file at config/locales/en.yml
# with the following lookup:
#
# en.user_mailer.account_activation.subject
#
def account_activation(user)
#user = user
mail to: user.email, subject: "Account activation"
end
# Subject can be set in your I18n file at config/locales/en.yml
# with the following lookup:
#
# en.user_mailer.password_reset.subject
#
def password_reset
#greeting = "Hi"
mail to: "to#example.org"
end
end
application_mailer.rb
class ApplicationMailer < ActionMailer::Base
#default from: "from#example.com"
default from: "noreply#example.com"
layout 'mailer'
end
account_activation_controller.eb
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
session_controller.rb
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
if user.activated?
log_in user
params[:session][:remember_me] == '1' ? remember(user) : forget(user)
#redirect_to user
redirect_back_or(user)
else
message = "Account not activated."
message += "Check your email for the activation link."
flash[:warning] = message
redirect_to root_url
end
else
flash.now[:danger] = 'Invalid email/password combination' # Not quite right!
render 'new'
end
end
def destroy
log_out if logged_in?
log_out
redirect_to root_url
end
end
user_mailer_test.rb
require 'test_helper'
class UserMailerTest < ActionMailer::TestCase
test "account_activation" do
user = users(:michael)
user.activation_token = User.new_token
mail = UserMailer.account_activation(user)
assert_equal "Account activation", mail.subject
assert_equal [user.email], mail.to
assert_equal ["noreply#example.com"], mail.from
assert_match user.name, mail.body.encoded
assert_match user.activation_token, mail.body.encoded
assert_match CGI::escape(user.email), mail.body.encoded
end
test "password_reset" do
mail = UserMailer.password_reset
assert_equal "Password reset", mail.subject
assert_equal ["to#example.org"], mail.to
assert_equal ["noreply#example.com"], mail.from
assert_match "Hi", mail.body.encoded
end
end
#user.send_activation_email
UserMailer.account_activation(#user).deliver_now
Without seeing the rest of your code, this looks like it should send two separate emails. The second line definitely does send an email, but we can't see the User model to know what the first line is doing.
If that code does send two emails, then the test is failing correctly.

Password Reset Redirect Test Failing in M.Hartl's Ruby on Rails Tutorial

I've been working through M.Hartl's Ruby on Rails tutorial for a while now, and I've been able to work out when I've made typos that caused my integration tests to fail and the like, but I've run into one that I can't figure out. My get edit_password_reset_path() with correct arguments is redirecting to the home url, not password_resets/edit like it should.
The failing test:
FAIL["test_password_resets", PasswordResetsTest, 2015-11-02 15:50:02 +0000]
test_password_resets#PasswordResetsTest (1446479402.08s)
expecting <"password_resets/edit"> but rendering with <[]>
test/integration/password_resets_test.rb:37:in `block in <class:PasswordResetsTest>'
Here is my password_resets_test.rb:
require 'test_helper'
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' # This is the assertion that fails
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: "foobazzz",
password_confirmation: "barquuxz" }
assert_select 'div#error_explanation'
# Empty password
patch password_reset_path(user.reset_token),
email: user.email,
user: { password: "",
password_confirmation: "" }
assert_not flash.empty?
# Valid password & confirmation
patch password_reset_path(user.reset_token),
email: user.email,
user: { password: "foobazzz",
password_confirmation: "foobazzz" }
assert is_logged_in?
assert_not flash.empty?
assert_redirected_to user
end
end
Here is my password_resets_controller.rb
class PasswordResetsController < ApplicationController
before_action :get_user, only: [:edit, :update]
before_action :valid_user, only: [:edit, :update]
before_action :check_expiration, only: [:edit, :update]
def new
end
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 instructions"
redirect_to root_url
else
flash.now[:danger] = "Email address not found"
render 'new'
end
end
def edit
end
def update
if params[:user][:password].empty?
#user.errors.add(:password, "can't be empty")
render 'edit'
elsif #user.update_attributes(user_params)
log_in #user
flash[:success] = "Password has been reset"
redirect_to #user
else
render 'edit'
end
end
private
def user_params
params.require(:user).permit(:password, :password_confirmation)
end
def get_user
#user = User.find_by(email: params[:email])
end
def valid_user
unless (#user && #user.activated? &&
#user.authenticated?(:reset, params[:id]))
redirect_to root_url
end
end
def check_expiration
if #user.password_reset_expired?
flash[:danger] = "Password reset has expired."
redirect_to new_password_reset_url
end
end
end
The authenticated? method in user.rb :
# Returns true if the given token matches the digest.
def authenticated?(attribute, token)
digest = send("#{attribute}_digest")
return false if digest.nil?
BCrypt::Password.new(digest).is_password?(token)
end
I'm not super sure what else is needed to figure out my problem. I've searched StackOverflow, worked through the code a second time, and I've even compared the source code at M.Hartl's github repo.
Link to the appropriate branch on my repo.
I'm trying to follow exactly this part of the tutorial.
The problem was in the user.rb model.
In my model, I had the following code:
def create_reset_digest
self.reset_token = User.new_token
update_attribute(:reset_digest, User.digest(reset_digest))
update_attribute(:reset_sent_at, Time.zone.now)
end
Note the second parameter to the first update_attribute() call, reset_digest. That should actually be reset_token. The correct method looks like this:
def create_reset_digest
self.reset_token = User.new_token
update_attribute(:reset_digest, User.digest(reset_token))
update_attribute(:reset_sent_at, Time.zone.now)
end

Rails Tutorial by Michael Hartl chapter 9.2.2 errors

I'm new to rails and I'm stuck in chapter 9.2.2 "Requiring the Right User", when I add the 2nd user archer to the users.yml file and add the other code to the user_controller_test.rb and the users_controller.rb, the run bundle exec rake test, I get 30 errors stating that:
ERROR["test_layout_links", SiteLayoutTest, 0.019046]
test_layout_links#SiteLayoutTest (0.02s)
ActiveRecord::StatementInvalid: ActiveRecord::StatementInvalid: SQLite3::SQLException: table users has no column named archer: INSERT INTO "users" ("name", "email", "password_digest", "archer", "created_at", "updated_at", "id") VALUES ('Michael Example', 'michael#example.com', '$2a$04$kDHpg7Zah2wc3X.YbWs5E.pytz8byEkUYo6O7uyPCftblGq3BEogW', '---
name: Sterling Archer
email: duchess#example.gov
password_digest:
users.yml code
michael:
name: Michael Example
email: michael#example.com
password_digest: <%= User.digest('password') %>
archer:
name: Sterling Archer
email: duchess#example.gov
password_digest: <%= User.digest('password') %>
users_controller_test.rb code
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 "should redirect update when logged in as wrong user" do
log_in_as(#other_user)
patch :update, id: #user, user: { name: #user.name, email: #user.email }
assert flash.empty?
assert_redirected_to root_url
end
end
user_controller.rb code
class UsersController < ApplicationController
before_action :logged_in_user, only: [:edit, :update]
before_action :correct_user, only: [:edit, :update]
def show
#user = User.find(params[:id])
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
log_in #user
flash[:success] = "Welcome to the Sample Application of the Great Bakerboi!"
redirect_to #user
else
render 'new'
end
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to #user
else
render 'edit'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
# Before filters
# Confirms a logged-in user.
def logged_in_user
unless logged_in?
flash[:danger] = "Please log in."
redirect_to login_url
end
end
Confirms the correct user.
def correct_user
#user = User.find(params[:id])
redirect_to(root_url) unless #user == current_user
end
end
The problem is that you have inadvertently indented the definition of :archer in users.yml.

Testing: patch_via_redirect and strong_parameters

Integration test (with Test/Unit) of update method:
test "do the patch" do
user = users(:alex)
get signin_url
assert_response :success
post_via_redirect signin_path, email: user.email, password: 'qwerty'
assert_equal profile_path, path
get edit_user_url(user)
patch_via_redirect user_url(user),
email: 'patch#it.man',
name: 'Patch!',
password: 'qwerty',
password_confirmation: 'qwerty'
assert_equal 'User updated!', flash[:notice]
end
When I run the test I got this error:
1) Error:
UserFlowsTest#test_do_the_patch:
ActionController::ParameterMissing: param not found: user
app/controllers/users_controller.rb:43:in `user_params'
app/controllers/users_controller.rb:31:in `update'
test/integration/user_flows_test.rb:124:in `block in <class:UserFlowsTest>'
Functions in my users_controller.rb:
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
flash[:success] = t('activecontroller.actions.user.updated')
sign_in #user
redirect_to #user
else
render :edit
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
How to test the patch, when I use strong parameters in my controller?
params.require(:user) requires there to be a :user => param at the root of the parameters hash.
Try this:
patch_via_redirect user_url(user), { user: {
email: 'patch#it.man',
name: 'Patch!',
password: 'qwerty',
password_confirmation: 'qwerty'
} }
Terrible formatting, but should get the point across.

Resources