docbrown/spec/validators/cross_model_slug_validator_spec.rb
Joshua Wehner a20cf3e02b
Unique cross-model-slug check is likely misconfigured (#19263)
* Page unique_cross_model_slug seems misconfigured

* Update validator test

* More verbose invalid attribute message

* Try dynamic model/attribute registration

* Rubocop

* Use the cross-model-slug existence check

* Register with the dynamic cross-model-slug checker

* Cleanup

* Add missing keys to fr

* Update format regex

* Adjust validation: always presence, unique if changed

* Tests can create reserved-word pages when they need to

* Slugs can be mixed case?

* Case-sensitive is better, actually

* Refactor to use CrossModel check

* Refactor, rename for clarity

* Refactor, avoid mocking oneself

* Refactor, injectable everything

* Add reservedword check to extracted exists? checker

* Move to concerns

* Without dynamic registration

* extend when needed

* Cleanup comments, remove registration references

---------

Co-authored-by: Goran <gorang.pub@gmail.com>
2023-04-07 17:04:45 +02:00

83 lines
1.8 KiB
Ruby

require "rails_helper"
RSpec.describe CrossModelSlugValidator do
subject(:record) { validatable.new.tap { |m| m.name = name } }
let(:validatable) do
Class.new do
def self.name
"Validatable"
end
include ActiveModel::Validations
attr_accessor :name
def initialize
@enforce_validation = true
end
def name_changed?
true
end
attr_accessor :enforce_validation
alias_method :enforce_validation?, :enforce_validation
validates :name, cross_model_slug: true, if: :enforce_validation?
end
end
context "when if option is false" do
let(:name) { "sitemap-happy" }
before { record.enforce_validation = false }
it { is_expected.to be_valid }
end
context "when name includes sitemap-" do
let(:name) { "sitemap-happy" }
it { is_expected.not_to be_valid }
end
context "when name is a ReservedWord" do
let(:name) { "members" }
it { is_expected.not_to be_valid }
end
context "when name exists in User model" do
let(:user) { create(:user) }
let(:name) { user.username }
it { is_expected.not_to be_valid }
end
context "when name exists in Organization model" do
let(:org) { create(:organization) }
let(:name) { org.slug }
it { is_expected.not_to be_valid }
end
context "when name exists in Podcast model" do
let(:org) { create(:podcast) }
let(:name) { org.slug }
it { is_expected.not_to be_valid }
end
context "when name exists in Page model" do
let(:org) { create(:page) }
let(:name) { org.slug }
it { is_expected.not_to be_valid }
end
context "when name is something different" do
let(:org) { create(:organization) }
let(:name) { "not-#{org.slug}" }
it { is_expected.to be_valid }
end
end