diff --git a/app/models/translation_override.rb b/app/models/translation_override.rb index f60b19545c5..77d0b99975d 100644 --- a/app/models/translation_override.rb +++ b/app/models/translation_override.rb @@ -27,53 +27,73 @@ class TranslationOverride < ActiveRecord::Base translation_override = find_or_initialize_by(params) params.merge!(data) if translation_override.new_record? - i18n_changed if translation_override.update(data) + i18n_changed([key]) if translation_override.update(data) translation_override end def self.revert!(locale, *keys) TranslationOverride.where(locale: locale, translation_key: keys).delete_all - i18n_changed + i18n_changed(keys) end + def self.i18n_changed(keys) + I18n.reload! + MessageBus.publish('/i18n-flush', refresh: true) + + keys.each do |key| + return if expire_cache(key) + end + end + + def self.expire_cache(key) + if key.starts_with?('post_action_types.') + ApplicationSerializer.expire_cache_fragment!("post_action_types_#{I18n.locale}") + elsif key.starts_with?('topic_flag_types.') + ApplicationSerializer.expire_cache_fragment!("post_action_flag_types_#{I18n.locale}") + else + return false + end + + Site.clear_anon_cache! + true + end + + private_class_method :i18n_changed + private_class_method :expire_cache + private - def self.i18n_changed - I18n.reload! - MessageBus.publish('/i18n-flush', refresh: true) + def check_interpolation_keys + original_text = I18n.overrides_disabled do + I18n.backend.send(:lookup, self.locale, self.translation_key) end - def check_interpolation_keys - original_text = I18n.overrides_disabled do - I18n.backend.send(:lookup, self.locale, self.translation_key) + if original_text + original_interpolation_keys = I18nInterpolationKeysFinder.find(original_text) + new_interpolation_keys = I18nInterpolationKeysFinder.find(value) + + custom_interpolation_keys = [] + + CUSTOM_INTERPOLATION_KEYS_WHITELIST.select do |key, value| + if self.translation_key.start_with?(key) + custom_interpolation_keys = value + end end - if original_text - original_interpolation_keys = I18nInterpolationKeysFinder.find(original_text) - new_interpolation_keys = I18nInterpolationKeysFinder.find(value) + invalid_keys = (original_interpolation_keys | new_interpolation_keys) - + original_interpolation_keys - + custom_interpolation_keys - custom_interpolation_keys = [] + if invalid_keys.present? + self.errors.add(:base, I18n.t( + 'activerecord.errors.models.translation_overrides.attributes.value.invalid_interpolation_keys', + keys: invalid_keys.join(', ') + )) - CUSTOM_INTERPOLATION_KEYS_WHITELIST.select do |key, value| - if self.translation_key.start_with?(key) - custom_interpolation_keys = value - end - end - - invalid_keys = (original_interpolation_keys | new_interpolation_keys) - - original_interpolation_keys - - custom_interpolation_keys - - if invalid_keys.present? - self.errors.add(:base, I18n.t( - 'activerecord.errors.models.translation_overrides.attributes.value.invalid_interpolation_keys', - keys: invalid_keys.join(', ') - )) - - return false - end + return false end end + end end diff --git a/spec/models/translation_override_spec.rb b/spec/models/translation_override_spec.rb index 7f31c015a61..c6b214fac5e 100644 --- a/spec/models/translation_override_spec.rb +++ b/spec/models/translation_override_spec.rb @@ -54,4 +54,44 @@ describe TranslationOverride do expect(ovr.compiled_js).to_not match(/Invalid Format/i) end + context "site cache" do + def cached_value(guardian, types_name, name_key, attribute) + json = Site.json_for(guardian) + + JSON.parse(json)[types_name] + .find { |x| x['name_key'] == name_key }[attribute] + end + + shared_examples "resets site text" do + it "resets the site cache when translations of post_action_types are changed" do + anon_guardian = Guardian.new + user_guardian = Guardian.new(Fabricate(:user)) + original_value = I18n.t(translation_key) + types_name, name_key, attribute = translation_key.split('.') + + expect(cached_value(user_guardian, types_name, name_key, attribute)).to eq(original_value) + expect(cached_value(anon_guardian, types_name, name_key, attribute)).to eq(original_value) + + TranslationOverride.upsert!('en', translation_key, 'bar') + expect(cached_value(user_guardian, types_name, name_key, attribute)).to eq('bar') + expect(cached_value(anon_guardian, types_name, name_key, attribute)).to eq('bar') + + TranslationOverride.revert!('en', translation_key) + expect(cached_value(user_guardian, types_name, name_key, attribute)).to eq(original_value) + expect(cached_value(anon_guardian, types_name, name_key, attribute)).to eq(original_value) + end + end + + context "post_action_types" do + let(:translation_key) { 'post_action_types.off_topic.description' } + + include_examples "resets site text" + end + + context "topic_flag_types" do + let(:translation_key) { 'topic_flag_types.spam.description' } + + include_examples "resets site text" + end + end end