I set up a User AR model which has conditional validation which is pretty much identical to the Railscast episode on conditional validation. So basically my User model looks like this:
class User < ActiveRecord::Base attr_accessor :password, :updating_password validates :password, :presence => true, :confirmation => true, :length => { :within => 6..40 }, :if => :should_validate_password? def should_validate_password? updating_password || new_record? end end Now in my action where the User can change their password I have the following two lines:
@user.updating_password = true if @user.update_attributes(params[:user]) ... so that I flag the validations to be run on the password. In development mode this works great - if the user tries to put in a password that is too short or too long the model does not pass validation. My problem is that for the life of me I can not get my tests for this to pass. Here is my spec:
require 'spec_helper' describe PasswordsController do render_views before(:each) do @user = Factory(:user) end describe "PUT 'update'" do describe "validations" do before(:each) do test_sign_in(@user) end it "should reject short passwords" do short = "short" old_password = @user.password @attr2 = { :password => short, :password_confirmation => short } put :update, :user_id => @user, :old_password => @user.password, :user => @attr2 @user.password.should == old_password end it "should reject long passwords" do long = "a" * 41 old_password = @user.password @attr2 = { :password => long, :password_confirmation => long } put :update, :user_id => @user, :old_password => @user.password, :user => @attr2 @user.password.should == old_password end end end end When I run these tests I always get the error:
1) PasswordsController PUT 'update' validations should reject short passwords Failure/Error: @user.password.should == old_password2 expected: "foobar" got: "short" (using ==) and of course the error for the password being too long. But should'nt the password be validated as a result of me setting @user.updating_password = true before any save attempts in the controller?