Ruby on Rails testing password presence fails - ruby-on-rails

I wanted to test that password should be present for a user signup.
In my test:
def setup
#user = User.new(name: "foobar", email: "foobar#gmail.com",
password: 'password',
password_confirmation: 'password')
end
test "password can't be blank" do
#user.password = nil
assert_not #user.valid?
end
User model:
validates :name, presence: true, length: { maximum: 20 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false}
has_secure_password
validates :password, presence: true, length: { minimum: 8}
this test passes fine, but if I change it to #user.password = "", the test fails. Could anyone help me understand why? what is the difference here for password? For emails, i used "" and it worked fine.
Thanks !

The test for #user.email = "", passes because even you don't specify minimum length validation you have regex validation.
VALID_EMAIL_REGEX =
/\A[\w+-.]+#[a-z\d-]+(.[a-z\d-]+)*.[a-z]+\z/i.
For password, you have minimum length validation, so #user.password = "" should also pass the test.

Related

how to test with sorcery

i have a little problem with sorcery
this is my test :
def setup
#user = users(:anouar)
end
test "should be valid" do
assert #user.valid?
end
and this is my fixture :
anouar:
email: anouar#gmail.com
salt: <%= salt = "asdasdastr4325234324sdfds" %>
crypted_password: <%= Sorcery::CryptoProviders::BCrypt.encrypt("secret", salt) %>
and my model :
class User < ActiveRecord::Base
authenticates_with_sorcery!
validates :email, presence: true, length: { maximum: 255 },
email_format: { message: 'has invalid format' },
uniqueness: { case_sensitive: false }
end
until here when i run bundle exec rake test the test is green
but when i add the validation of the password
validates :password, presence: true, confirmation: true, length: { minimum: 3}
the test "should be valid" is fail
please help?
Did you try to provide directly a password in your fixture ?

Issues with validation in rails

I have a working validation on my user model. But since we're discovered that users tend to give up during their long registration form, we've split up registration form into steps so that user can give up any time and still use the site.
I'm having issues with the first step of user registration with validations. Here is the relevant bit of my User model :
with_options :if => lambda { |u| u.current_step == "get_started" } do |user|
user.validates :firstname, presence: true, length: { maximum: 50 }
user.validates :surname, presence: true, length: { maximum: 50 }
user.validates :email, presence: true,
format: { with: VALID_EMAIL_REGEX }
user.validates :password_digest, presence: true
user.validates :password, length: { minimum: 6 }
end
This validation works perfectly. However we now added facebook so its possible to login with facebook and we have hidden fields in our form facebook_uid. So I want to validate password only if these fields are nil.
Here is how I tried to modify my current validation :
with_options :if => lambda { |u| u.current_step == "get_started" } do |user|
user.validates :firstname, presence: true, length: { maximum: 50 }
user.validates :surname, presence: true, length: { maximum: 50 }
user.validates :email, presence: true,
format: { with: VALID_EMAIL_REGEX }
with_options :if => lambda { |u| u.facebook_uid.nil? } do |user|
user.validates :password_digest, presence: true
end
with_options :if => lambda { |u| u.user.password_digest_changed? && !u.password.nil? } do |user|
user.validates :password, length: { minimum: 6 }
end
end
Or inline (the relevant password part only) :
user.validates :password_digest, presence: true, if: lambda { |u| u.facebook_uid.nil? }
user.validates :password, length: { minimum: 6 }, if: lambda { |u| u.user.password_digest_changed? && !u.password.nil? }
None of these worked for me, whatever I tried I get this error :
undefined method `user' for #<User:0x00000008e924a8>
Again if I remove ifs and lambdas works as charm. Is there another way of accomplishing this or something I'm currently doing wrong with my code?
In your password validation lambda, you're calling
u.user.password_digest_changed? && !u.password.nil?
ie, you're sending a user method to the u object, which is your User instance. That object doesn't respond to user. You probably just want
u.password_digest_changed? && !u.password.nil?

Generate reset password token don't save on model

Hello I trying to create a reset password for my rails app; but when I try to save I get the following error:
Validation failed: Password can't be blank, Password is too short
(minimum is 6 characters), Password confirmation can't be blank
This is my user model.
class User < ActiveRecord::Base
attr_accessible :email, :password, :password_confirmation
has_secure_password
before_save { |user| user.email = email.downcase }
before_save :create_remember_token
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false }
validates :password, presence: true, length: { minimum: 6 }
validates :password_confirmation, presence: true
def send_password_reset
self.password_reset_token = SecureRandom.urlsafe_base64
self.password_reset_at = Time.zone.now
self.password = self.password
self.password_confirmation = self.password
save!
end
private
def create_remember_token
self.remember_token = SecureRandom.urlsafe_base64
end
end
the method "send_password_reset" doesn't update the user and I don't understand why is trying to save the user instead on updating just password_reset_token and the password_reset_at.
Does anybody can help me, please?
When you call save! on the model instance, it's going to run the validations on your User model; all of them.
There are a number of ways to skip the password validations conditionally. One is to use a Proc
validates :password, presence: true, length: { minimum: 6 }, unless: Proc.new { |a| !a.new_record? && a.password.blank? }
This will allow the User instance to be saved and will skip the validation of the :password field if it's blank and the User is not new (already persisted to the database).
Here is most of a password validation I use in my applications
validates :password, confirmation: true,
length: {:within => 6..40},
format: {:with => /^(?=.*\d)(?=.*([a-z]|[A-Z]))([\x20-\x7E]){6,40}$/},
Notice, you don't need the separate validation on :password_confirmation. Instead just pass confirmation: true to the :password validator.
Suggested Reading:
http://guides.rubyonrails.org/active_record_validations_callbacks.html#confirmation

Rails tutorial 6.3.4 authenticate error

I'm doing the ruby on rails tutorial book and I have come to an error. I checked everything he wrote and I still get the error. It tells me authenticate is an undefined method for nil:NILclass. I don't know what to do.
user.rb:
class User < ActiveRecord::Base
attr_accessible :email, :name, :password, :password_confirmation
attr_accessor :password, :password_confirmation
has_secure password
before_save { |user| user.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX}, uniqueness: {case_sensitive: false}
validates :password, presence: true, length:{ minimum: 6 }
validates :password_confirmation, presence: true
end
and (some of) my user_spec.rb
before do
#user = User.new(name: "Example User", email: "User#example", password: "foobar", password_confirmation:"foobar")
end
subject { #user }
it { should respond_to(:password_digest) }
it { should respond_to(:password) }
it { should respond_to(:password_confirmation) }
it { should respond_to(:authenticate) }
it { should be_valid }
# USER.PASSWORD
describe "when password is not present" do
before { #user.password = #user.password_confirmation = " "}
it {should_not be_valid}
end
describe "when password is not present" do
before { #user.password_confirmation = "mismatch" }
it { should_not be_valid }
describe "when password is nil" do
before { #user.password_confirmation = nil }
it {should_not be_valid}
end
describe "with a password that's too short" do
before { #user.password = #user.password_confirmation = "a" * 5 }
it { should be_valid }
end
describe "return value of authenticate method" do
before { #user.save }
let(:found_user) { User.find_by_email(#user.email) }
describe "with valid password" do
it { should == found_user.authenticate(#user.password) }
end
describe "with invalid password" do
let(:user_for_invalid_password) { found_user.authenticate("invalid") }
it {should_not == user_for_invalid_password}
specify { user_for_invalid_password.should be_false}
end
end
end
Thanks alot for all that can help.
I am new in ruby on rails.I just pass this tutorials. when I doing I found errors same you.
I hope my solved can help you.
in your user.rb
remove line: attr_accessor and edit has_secure password to has_secure_password (add underscore)
class User < ActiveRecord::Base
attr_accessible :email, :name, :password, :password_confirmation
has_secure_password
enter code here
before_save { |user| user.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX},
uniqueness: {case_sensitive: false}
validates :password, presence: true, length:{ minimum: 6 }
validates :password_confirmation, presence: true
end
in your user.spec.rb
1) you missed 'end' tag in describe "when password is not present"
2) Change test describe 'with a password that's too short'
from it { should be_valid} to it { should be_invalid } I think it should be invalid if password less than 5.
3) finally if you want to test pass authenticate you should change your email end with .com or any that matches with VALID_EMAIL_REGEX in user.rb like:
before do
#user = User.new(name: "Example User", email: "User#example.com",
password: "foobar", password_confirmation:"foobar")
end
I wish this help you.
sorry for my bad english.

Rails Tutorial User.save

I am working on Michael Hartl's tutorial (chapter 6). When I try to create a new user in the rails console:
user = User.new(name: "Lord of Darkness", email: "LoD#hell.com")
I get:
=> #<User id: nil, name: "Lord of Darkness", email: "LoD#hell.com",
created_at: nil, updated_at: nil, password_digest: nil>
Which seem to be correct. But when I try to save I get this:
irb(main):007:0> user.save
←[1m←[36m (0.0ms)←[0m ←[1mbegin transaction←[0m
←[1m←[35mUser Exists (0.0ms)←[0m SELECT 1 AS one FROM "users" WHERE LOWER("us
ers"."email") = LOWER('mhartl#example.com') LIMIT 1
←[1m←[36m (0.0ms)←[0m ←[1mrollback transaction←[0m
=> false
which definitely is not what I want. My user_spec is passing all tests.
My user.rb looks like that:
class User < ActiveRecord::Base
attr_accessible :email, :name, :password, :password_confirmation
has_secure_password
before_save { |user| user.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
validates :password, presence: true, length: { minimum: 6 }
validates :password_confirmation, presence: true
end
What causes this save problem? Without solving this error I cannot go on with the tutorial.
I believe your error is stemming from the fact that the User you are creating doesn't have a password.
Your User model validates a password and requires its presence, but when you create new a User from the command line, he/she doesn't have a password yet.

Resources