Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

should validate_uniqueness_of is expecting an invalid record with a different scoped value, which would be valid #1656

Open
chiperific opened this issue Nov 20, 2024 · 1 comment

Comments

@chiperific
Copy link

chiperific commented Nov 20, 2024

Description

I extended shoulda_matchers for a concern that I wrote. This concern adds a uniqueness validation. The error message produced by shoulda_matchers makes me think shoulda_matchers isn't performing the right test.

Given this concern:

module Animal::Pet
  extend ActiveSupport::Concern

  ...
  included do
    # a name must be unique within a household
    validates_uniqueness_of :name, scope: :household_id, case_sensitive: false
  end
  ...
end

and this spec:

RSpec.configure do |config|
  config.include(Shoulda::Matchers::ActiveModel, type: :concern)
  config.include(Shoulda::Matchers::ActiveRecord, type: :concern)
end

RSpec.describe Animal::Pet, type: :concern do
 ...
 it { should validate_uniqueness_of(:name).scoped_to(:household_id).case_insensitive }
 ...
end

the spec fails with this message:

Expected Animal::Pet to validate
that :name is case-insensitively unique within the scope of
:household_id, but this could not be proved.
After taking the given Animal::Pet, whose :name is
‹"Fluffy"›, and saving it as the existing record, then making a
new Animal::Pet and setting its
:name to ‹"Fluffy"› as well and its :household_id
to a different value, ‹"b37b3f61-193c-4ff4-97db-5004e69e2c64"›, the
matcher expected the new
Animal::Pet to be invalid, but it
was valid instead.

But the failure message makes it seem like the test is being performed wrong. Two pets can have the same name as long as they are in different households.

So I would expect a message like this:

After taking the given Animal::Pet, whose :name is
‹"Fluffy"›, and saving it as the existing record, then making a
new Animal::Pet and setting its
:name to ‹"Fluffy"› as well and its :household_id
to ** the same ** value, ‹"b37b3f61-193c-4ff4-97db-5004e69e2c64"›, the
matcher expected the new
Animal::Pet to be invalid

System configuration

shoulda_matchers version: 6.4.0
rails version: 7.1
ruby version: 3.3.4

@chiperific
Copy link
Author

Ok, so I found the issue: the records were not getting saved because of an around_create callback that didn't yield.

The spec now passes as expected.

However, the error message still seems to be wrong/misleading:

as well and its :household_id
to a different value, ‹"b37b3f61-193c-4ff4-97db-5004e69e2c64"›

I would expect the message to read:

as well and its :household_id
to the same value, ‹"b37b3f61-193c-4ff4-97db-5004e69e2c64"›

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant