From 38ab45cb93cb5b0e499a4df3bb83e9a7e8724aae Mon Sep 17 00:00:00 2001 From: Krzysztof Kotlarek Date: Wed, 3 Mar 2021 10:59:23 +1100 Subject: [PATCH] FIX: check min tag count requirement when change category (#12252) When a category is created, we can set `minimum_required_tags` property. When the topic is created, we are checking that field and ensuring that the minimum amount of tags were added - unless topic created by a staff member. Problem is that validation is skipped when we change the category from for example category with 0 tags required to the category with 1 tag required. Changing category is kind of the unicorn as it is a complicated operation: https://github.com/discourse/discourse/blob/master/lib/post_revisor.rb#L84 https://github.com/discourse/discourse/blob/master/app/models/topic.rb#L911 https://github.com/discourse/discourse/blob/master/app/models/topic.rb#L823 Before we start to try to change the category, we should ensure that the tags requirement is fulfilled. https://meta.discourse.org/t/the-category-setting-for-tags-is-not-respected/181214 --- lib/post_revisor.rb | 10 ++++++++-- spec/components/post_revisor_spec.rb | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/lib/post_revisor.rb b/lib/post_revisor.rb index c94d03e108f..eab76c38fdf 100644 --- a/lib/post_revisor.rb +++ b/lib/post_revisor.rb @@ -75,11 +75,17 @@ class PostRevisor end end - track_topic_field(:category_id) do |tc, category_id| + track_topic_field(:category_id) do |tc, category_id, fields| if category_id == 0 && tc.topic.private_message? tc.record_change('category_id', tc.topic.category_id, nil) tc.topic.category_id = nil elsif category_id == 0 || tc.guardian.can_move_topic_to_category?(category_id) + tags = fields[:tags] || tc.topic.tags.map(&:name) + if category_id != 0 && !DiscourseTagging.validate_min_required_tags_for_category(tc.guardian, tc.topic, Category.find(category_id), tags) + tc.check_result(false) + next + end + tc.record_change('category_id', tc.topic.category_id, category_id) tc.check_result(tc.topic.change_category_to_id(category_id)) end @@ -454,7 +460,7 @@ class PostRevisor Topic.transaction do PostRevisor.tracked_topic_fields.each do |f, cb| if !@topic_changes.errored? && @fields.has_key?(f) - cb.call(@topic_changes, @fields[f]) + cb.call(@topic_changes, @fields[f], @fields) end end diff --git a/spec/components/post_revisor_spec.rb b/spec/components/post_revisor_spec.rb index 00f49f1342a..7926c487239 100644 --- a/spec/components/post_revisor_spec.rb +++ b/spec/components/post_revisor_spec.rb @@ -84,6 +84,28 @@ describe PostRevisor do post.revise(post.user, category_id: new_category.id) expect(post.reload.topic.category_id).to eq(new_category.id) end + + it 'does not revise category if incorrect amount of tags' do + SiteSetting.min_trust_to_create_tag = 0 + SiteSetting.min_trust_level_to_tag_topics = 0 + + new_category = Fabricate(:category, minimum_required_tags: 1) + + post = create_post + old_category_id = post.topic.category_id + + post.revise(post.user, category_id: new_category.id) + expect(post.reload.topic.category_id).to eq(old_category_id) + + tag = Fabricate(:tag) + topic_tag = Fabricate(:topic_tag, topic: post.topic, tag: tag) + post.revise(post.user, category_id: new_category.id) + expect(post.reload.topic.category_id).to eq(new_category.id) + topic_tag.destroy + + post.revise(post.user, category_id: new_category.id, tags: ['test_tag']) + expect(post.reload.topic.category_id).to eq(new_category.id) + end end context 'revise wiki' do