Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing uniqueness in a scope in a Rails project using shoulda (but not rspec)

I have a user class with an email that is unique but scoped to the tenant:

class User < ActiveRecord::Base
  validates :email, :uniqueness => {:scope => :tenant_id, :allow_blank => true}
  #...
end

I'm trying to test it with:

class UserTest < ActiveSupport::TestCase
  context "a user" do
    setup { @user = create :user }
    subject { @user }

    should validate_uniqueness_of(:email).scoped_to(:tenant_id)
  end
end

but the test fails with this message:

Expected errors to include "has already been taken" when email is set to "[email protected]", got errors: ["email has already been taken (\"[email protected]\")", "first_name can't be blank (nil)", "last_name can't be blank (nil)"] (with different value of tenant_id)

which raises many questions. Why is the error message not matching? It seems because the actual email address is included in the error message, but why is it included? When I generate the error from the UI it doesn't seem to be included:

enter image description here

Also, at the end it says that it's trying it with a different tenant, which if it was true, it shouldn't generate any error (it doesn't when I run the app itself), but, why is it expecting the error? It should only expect the error if it's the same tenant_id.

This is so confusing. Any ideas what's going on and/or how to properly test this?

like image 441
pupeno Avatar asked Mar 12 '12 10:03

pupeno


1 Answers

Just ran into this same issue. We were able to resolve it by changing

should validate_uniqueness_of(:email).scoped_to(:tenant_id)

to

should validate_uniqueness_of(:email_id).scoped_to(:tenant_id)

Don't know if it's exactly the same situation, but apparently our issue was caused by nested resources throwing the matcher for a loop somehow.

like image 62
Austin Wang Avatar answered Oct 23 '22 21:10

Austin Wang