Add coverage for name/display_name changes in Tag model

This commit is contained in:
Matt Jankowski 2024-09-11 11:16:26 -04:00
parent c35ea59ee6
commit ef2a9d58af
2 changed files with 51 additions and 8 deletions

View file

@ -47,8 +47,10 @@ class Tag < ApplicationRecord
validates :name, presence: true, format: { with: HASHTAG_NAME_RE } validates :name, presence: true, format: { with: HASHTAG_NAME_RE }
validates :display_name, format: { with: HASHTAG_NAME_RE } validates :display_name, format: { with: HASHTAG_NAME_RE }
validate :validate_name_change, if: -> { !new_record? && name_changed? } with_options on: :update do
validate :validate_display_name_change, if: -> { !new_record? && display_name_changed? } validate :validate_name_change, if: :name_changed?
validate :validate_display_name_change, if: :display_name_changed?
end
scope :reviewed, -> { where.not(reviewed_at: nil) } scope :reviewed, -> { where.not(reviewed_at: nil) }
scope :unreviewed, -> { where(reviewed_at: nil) } scope :unreviewed, -> { where(reviewed_at: nil) }
@ -160,13 +162,22 @@ class Tag < ApplicationRecord
private private
def validate_name_change def validate_name_change
errors.add(:name, I18n.t('tags.does_not_match_previous_name')) unless name_was.mb_chars.casecmp(name.mb_chars).zero? errors.add(:name, previous_name_error_message) unless matches_name_chars?(name_was.mb_chars)
end end
def validate_display_name_change def validate_display_name_change
unless HashtagNormalizer.new.normalize(display_name).casecmp(name.mb_chars).zero? errors.add(:display_name, previous_name_error_message) unless matches_name_chars?(normalized_display_name)
errors.add(:display_name, end
I18n.t('tags.does_not_match_previous_name'))
end def normalized_display_name
HashtagNormalizer.new.normalize(display_name)
end
def matches_name_chars?(value)
value.casecmp(name.mb_chars).zero?
end
def previous_name_error_message
I18n.t('tags.does_not_match_previous_name')
end end
end end

View file

@ -5,7 +5,39 @@ require 'rails_helper'
RSpec.describe Tag do RSpec.describe Tag do
include_examples 'Reviewable' include_examples 'Reviewable'
describe 'validations' do describe 'Validations' do
describe 'name' do
context 'with a new record' do
subject { Fabricate.build :tag, name: 'original' }
it { is_expected.to allow_value('changed').for(:name) }
end
context 'with an existing record' do
subject { Fabricate :tag, name: 'original' }
it { is_expected.to_not allow_value('changed').for(:name).with_message(previous_name_error_message) }
end
end
describe 'display_name' do
context 'with a new record' do
subject { Fabricate.build :tag, name: 'original', display_name: 'OriginalDisplayName' }
it { is_expected.to allow_value('ChangedDisplayName').for(:display_name) }
end
context 'with an existing record' do
subject { Fabricate :tag, name: 'original', display_name: 'OriginalDisplayName' }
it { is_expected.to_not allow_value('ChangedDisplayName').for(:display_name).with_message(previous_name_error_message) }
end
end
def previous_name_error_message
I18n.t('tags.does_not_match_previous_name')
end
it 'invalid with #' do it 'invalid with #' do
expect(described_class.new(name: '#hello_world')).to_not be_valid expect(described_class.new(name: '#hello_world')).to_not be_valid
end end