FIX: corrently handle hidden tags when checking for edit conflicts

In 806e37aaec, I improved the conflict handling when editing a post to account for title and tags.

This fixes an edge cases when a topic has a hidden tag the current editor can't see. When they submit their edit, we automatically add the hidden tags before checking with the tags stored in the database.

Reported in https://meta.discourse.org/t/341375
This commit is contained in:
zogstrip 2024-12-09 18:50:57 +01:00 committed by Régis Hanol
parent 61f23b2d65
commit 6e54696003
2 changed files with 42 additions and 2 deletions

View File

@ -108,8 +108,15 @@ class DraftsController < ApplicationController
if post.post_number == 1 if post.post_number == 1
conflict ||= original_title.present? && original_title != post.topic.title conflict ||= original_title.present? && original_title != post.topic.title
conflict ||=
original_tags.present? && original_tags.sort != post.topic.tags.pluck(:name).sort # Since the topic might have hidden tags the current editor can't see,
# we need to check for conflicts even though there might not be any visible tags in the editor
if !conflict
original_tags = (original_tags || []).map(&:downcase).to_set
current_tags = post.topic.tags.pluck(:name).to_set
hidden_tags = DiscourseTagging.hidden_tag_names(@guardian).to_set
conflict = original_tags != (current_tags - hidden_tags)
end
end end
if conflict if conflict

View File

@ -164,6 +164,39 @@ RSpec.describe DraftsController do
expect(response.parsed_body["conflict_user"]["id"]).to eq(post.last_editor.id) expect(response.parsed_body["conflict_user"]["id"]).to eq(post.last_editor.id)
end end
it "handles hidden tags when checking for tag conflict" do
sign_in(user)
regular_tag = Fabricate(:tag)
admin_only_tag_one = Fabricate(:tag)
admin_only_tag_two = Fabricate(:tag)
admin_only_tag_group = Fabricate(:tag_group)
admin_only_tag_group.tags = [admin_only_tag_one, admin_only_tag_two]
admin_only_tag_group.permissions = [
[Group::AUTO_GROUPS[:admins], TagGroupPermission.permission_types[:full]],
]
admin_only_tag_group.save!
post = Fabricate(:post, user:)
post.topic.tags = [regular_tag, admin_only_tag_one]
post "/drafts.json",
params: {
draft_key: "topic",
sequence: 0,
data: {
postId: post.id,
original_text: post.raw,
original_tags: [regular_tag.name],
action: "edit",
}.to_json,
}
expect(response.status).to eq(200)
expect(response.parsed_body["conflict_user"]).to eq(nil)
end
it "cant trivially resolve conflicts without interaction" do it "cant trivially resolve conflicts without interaction" do
sign_in(user) sign_in(user)