Skip to content

Commit 4d39974

Browse files
authored
FIX: Auto-tag improperly when category is changed (#215)
1 parent e8087f2 commit 4d39974

File tree

2 files changed

+96
-59
lines changed

2 files changed

+96
-59
lines changed

lib/category_experts/post_handler.rb

Lines changed: 35 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,11 @@ def mark_topic_as_question
6666
topic.save!
6767
end
6868

69-
def correct_topic_custom_fields_after_removal(group_name:, new_post: false)
69+
def correct_topic_custom_fields_after_removal(
70+
group_name:,
71+
new_post: false,
72+
category: topic.category
73+
)
7074
has_accepted_posts_from_same_group =
7175
group_name &&
7276
PostCustomField.where(
@@ -101,10 +105,10 @@ def correct_topic_custom_fields_after_removal(group_name:, new_post: false)
101105

102106
DiscourseEvent.trigger(:category_experts_unapproved, post) if post && !new_post
103107

104-
remove_auto_tag if should_remove_auto_tag
108+
remove_auto_tag(category: category) if should_remove_auto_tag
105109
end
106110

107-
def correct_topic_custom_fields_after_addition(new_post: false)
111+
def correct_topic_custom_fields_after_addition(new_post: false, category: topic.category)
108112
topic.custom_fields[CategoryExperts::TOPIC_EXPERT_POST_GROUP_NAMES] = (
109113
topic.custom_fields[CategoryExperts::TOPIC_EXPERT_POST_GROUP_NAMES]&.split("|") || []
110114
).push(users_expert_group.name).uniq.join("|")
@@ -119,13 +123,17 @@ def correct_topic_custom_fields_after_addition(new_post: false)
119123

120124
DiscourseEvent.trigger(:category_experts_approved, post) unless new_post
121125

122-
add_auto_tag
126+
add_auto_tag(category: category)
123127
end
124128

125129
def handle_topic_category_change(old_category_id, new_category_id)
126130
old_category = Category.find_by(id: old_category_id)
127131
new_category = Category.find_by(id: new_category_id)
128132

133+
# Get auto-tags before processing posts
134+
old_auto_tag = old_category&.custom_fields&.[](CategoryExperts::CATEGORY_EXPERT_AUTO_TAG)
135+
new_auto_tag = new_category&.custom_fields&.[](CategoryExperts::CATEGORY_EXPERT_AUTO_TAG)
136+
129137
# Get all posts in the topic that have expert status
130138
expert_posts =
131139
Post
@@ -158,7 +166,10 @@ def handle_topic_category_change(old_category_id, new_category_id)
158166
CategoryExperts::PostHandler.new(
159167
post: expert_post,
160168
topic: topic,
161-
).correct_topic_custom_fields_after_removal(group_name: old_group_name)
169+
).correct_topic_custom_fields_after_removal(
170+
group_name: old_group_name,
171+
category: old_category,
172+
)
162173
else
163174
# Author is still an expert in the new category - update the group name
164175
new_expert_group = Group.find_by(id: author_expert_group_ids.first)
@@ -175,20 +186,20 @@ def handle_topic_category_change(old_category_id, new_category_id)
175186
CategoryExperts::PostHandler.new(
176187
post: expert_post,
177188
topic: topic,
178-
).correct_topic_custom_fields_after_removal(group_name: old_group_name)
189+
).correct_topic_custom_fields_after_removal(
190+
group_name: old_group_name,
191+
category: old_category,
192+
)
179193

180194
# Add new group to topic custom fields
181195
CategoryExperts::PostHandler.new(
182196
post: expert_post,
183197
topic: topic,
184198
user: post_author,
185-
).correct_topic_custom_fields_after_addition
199+
).correct_topic_custom_fields_after_addition(category: new_category)
186200
end
187201
end
188202
end
189-
190-
# Handle auto-tag changes
191-
handle_auto_tag_change(old_category, new_category)
192203
end
193204

194205
private
@@ -206,63 +217,40 @@ def users_expert_group
206217
@users_expert_group = group_id.nil? ? nil : Group.find_by(id: group_id)
207218
end
208219

209-
def add_auto_tag
220+
def add_auto_tag(category:)
210221
return if !SiteSetting.tagging_enabled
211-
return if auto_tag_for_category.blank?
222+
223+
auto_tag = auto_tag_for_category(category: category)
224+
return if auto_tag.blank?
212225

213226
existing_tag_names = topic.tags.map(&:name)
214227
# Return early if the topic already has the automatic tag
215-
return if existing_tag_names.include?(auto_tag_for_category)
228+
return if existing_tag_names.include?(auto_tag)
216229

217230
PostRevisor.new(topic.ordered_posts.first).revise!(
218231
Discourse.system_user,
219-
{ tags: (existing_tag_names << auto_tag_for_category) },
232+
{ tags: (existing_tag_names << auto_tag) },
220233
)
221234
end
222235

223-
def remove_auto_tag
236+
def remove_auto_tag(category:)
224237
return if !SiteSetting.tagging_enabled
225-
return if auto_tag_for_category.blank?
238+
239+
auto_tag = auto_tag_for_category(category: category)
240+
return if auto_tag.blank?
226241

227242
existing_tag_names = topic.tags.map(&:name)
228243
# Return early if the topic doesn't have the automatic tag
229-
return if !existing_tag_names.include?(auto_tag_for_category)
244+
return if !existing_tag_names.include?(auto_tag)
230245

231246
PostRevisor.new(topic.ordered_posts.first).revise!(
232247
Discourse.system_user,
233-
{ tags: ((existing_tag_names || []) - [auto_tag_for_category]) },
248+
{ tags: ((existing_tag_names || []) - [auto_tag]) },
234249
)
235250
end
236251

237-
def auto_tag_for_category
238-
return @auto_tag_for_category if defined?(@auto_tag_for_category)
239-
240-
@auto_tag_for_category =
241-
@topic.category.custom_fields[CategoryExperts::CATEGORY_EXPERT_AUTO_TAG]
242-
end
243-
244-
def handle_auto_tag_change(old_category, new_category)
245-
return if !SiteSetting.tagging_enabled
246-
247-
old_auto_tag = old_category&.custom_fields&.[](CategoryExperts::CATEGORY_EXPERT_AUTO_TAG)
248-
new_auto_tag = new_category&.custom_fields&.[](CategoryExperts::CATEGORY_EXPERT_AUTO_TAG)
249-
250-
existing_tag_names = topic.tags.map(&:name)
251-
252-
# Determine what tags to add/remove
253-
tags_to_remove = old_auto_tag.present? ? [old_auto_tag] : []
254-
tags_to_add = new_auto_tag.present? ? [new_auto_tag] : []
255-
256-
# Only revise if there's actually a change needed
257-
if (tags_to_remove.any? && existing_tag_names.include?(old_auto_tag)) ||
258-
(tags_to_add.any? && !existing_tag_names.include?(new_auto_tag))
259-
new_tag_names = (existing_tag_names - tags_to_remove + tags_to_add).uniq
260-
261-
PostRevisor.new(topic.ordered_posts.first).revise!(
262-
Discourse.system_user,
263-
{ tags: new_tag_names },
264-
)
265-
end
252+
def auto_tag_for_category(category:)
253+
category.custom_fields[CategoryExperts::CATEGORY_EXPERT_AUTO_TAG]
266254
end
267255
end
268256
end

spec/plugin_spec.rb

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
fab!(:group) { Fabricate(:group, users: [expert]) }
1111
fab!(:auto_tag, :tag)
1212

13-
fab!(:original_topic) { Fabricate(:topic, category: category, tags: [auto_tag]) }
13+
fab!(:original_topic) { Fabricate(:topic, category: category) }
1414
fab!(:first_post) { Fabricate(:post, topic: original_topic, user: expert) }
1515
fab!(:second_post) { Fabricate(:post, topic: original_topic, user: expert) }
1616

@@ -221,9 +221,12 @@
221221
describe "on 'post_edited' with category change" do
222222
fab!(:category_b, :category)
223223
fab!(:group_b, :group)
224+
fab!(:auto_tag_b, :tag)
224225

225226
before do
227+
SiteSetting.tagging_enabled = true
226228
category_b.custom_fields[CategoryExperts::CATEGORY_EXPERT_GROUP_IDS] = "#{group_b.id}"
229+
category_b.custom_fields[CategoryExperts::CATEGORY_EXPERT_AUTO_TAG] = auto_tag_b.name
227230
category_b.save!
228231
end
229232

@@ -257,6 +260,27 @@
257260
).to be_blank
258261
expect(second_post.custom_fields[CategoryExperts::POST_APPROVED_GROUP_NAME]).to be_blank
259262
end
263+
264+
it "removes old auto-tag and do not add new one" do
265+
expect(original_topic.tags.map(&:name)).to include(auto_tag.name)
266+
expect(original_topic.tags.map(&:name)).not_to include(auto_tag_b.name)
267+
268+
category_without_experts = Fabricate(:category)
269+
category_without_experts.custom_fields[
270+
CategoryExperts::CATEGORY_EXPERT_AUTO_TAG
271+
] = auto_tag_b.name
272+
category_without_experts.save!
273+
274+
PostRevisor.new(original_topic.first_post).revise!(
275+
admin,
276+
category_id: category_without_experts.id,
277+
)
278+
279+
original_topic.reload
280+
281+
expect(original_topic.tags.map(&:name)).not_to include(auto_tag.name)
282+
expect(original_topic.tags.map(&:name)).not_to include(auto_tag_b.name)
283+
end
260284
end
261285

262286
context "when topic is moved from one category with experts to another with different experts" do
@@ -339,18 +363,9 @@
339363
expect(third_post.custom_fields[CategoryExperts::POST_APPROVED_GROUP_NAME]).to be_blank
340364
end
341365
end
342-
end
343-
344-
context "when topic has auto-tag" do
345-
fab!(:auto_tag_b, :tag)
346366

347-
before do
348-
SiteSetting.tagging_enabled = true
349-
category_b.custom_fields[CategoryExperts::CATEGORY_EXPERT_AUTO_TAG] = auto_tag_b.name
350-
category_b.save!
351-
end
352-
353-
it "removes old auto-tag and adds new auto-tag when category changes" do
367+
it "updates auto-tag appropriately" do
368+
group_b.add(expert)
354369
expect(original_topic.tags.map(&:name)).to include(auto_tag.name)
355370
expect(original_topic.tags.map(&:name)).not_to include(auto_tag_b.name)
356371

@@ -362,6 +377,40 @@
362377
expect(original_topic.tags.map(&:name)).to include(auto_tag_b.name)
363378
end
364379
end
380+
381+
context "when topic is moved between two categories without experts" do
382+
fab!(:category_without_experts_a, :category)
383+
fab!(:category_without_experts_b, :category)
384+
385+
fab!(:topic_without_experts) { Fabricate(:topic, category: category_without_experts_a) }
386+
fab!(:post_without_experts) { Fabricate(:post, topic: topic_without_experts) }
387+
388+
before do
389+
category_without_experts_a.custom_fields[
390+
CategoryExperts::CATEGORY_EXPERT_AUTO_TAG
391+
] = auto_tag.name
392+
category_without_experts_b.custom_fields[
393+
CategoryExperts::CATEGORY_EXPERT_AUTO_TAG
394+
] = auto_tag_b.name
395+
category_without_experts_a.save!
396+
category_without_experts_b.save!
397+
end
398+
399+
it "does not auto-tag" do
400+
expect(topic_without_experts.tags.map(&:name)).not_to include(auto_tag.name)
401+
expect(topic_without_experts.tags.map(&:name)).not_to include(auto_tag_b.name)
402+
403+
PostRevisor.new(topic_without_experts.first_post).revise!(
404+
admin,
405+
category_id: category_without_experts_b.id,
406+
)
407+
408+
topic_without_experts.reload
409+
410+
expect(topic_without_experts.tags.map(&:name)).not_to include(auto_tag.name)
411+
expect(topic_without_experts.tags.map(&:name)).not_to include(auto_tag_b.name)
412+
end
413+
end
365414
end
366415
end
367416
end

0 commit comments

Comments
 (0)