diff --git a/lib/discourse_tagging.rb b/lib/discourse_tagging.rb index 0699cf7e3c..96dd3274a4 100644 --- a/lib/discourse_tagging.rb +++ b/lib/discourse_tagging.rb @@ -311,7 +311,13 @@ module DiscourseTagging sql.gsub!("/*and_name_like*/", "") end - if opts[:for_input] && filter_for_non_staff && category&.required_tag_group + # show required tags for non-staff + # or for staff when + # - there are more available tags than the query limit + # - and no search term has been included + filter_required_tags = category&.required_tag_group && (filter_for_non_staff || (term.blank? && category&.required_tag_group&.tags.size >= opts[:limit].to_i)) + + if opts[:for_input] && filter_required_tags required_tag_ids = category.required_tag_group.tags.pluck(:id) if (required_tag_ids & selected_tag_ids).size < category.min_tags_from_required_group builder.where("id IN (?)", required_tag_ids) @@ -364,7 +370,15 @@ module DiscourseTagging builder.where("id NOT IN (SELECT target_tag_id FROM tags WHERE target_tag_id IS NOT NULL)") end - builder.limit(opts[:limit]) if opts[:limit] + if opts[:limit] + if required_tag_ids && term.blank? + # override limit so all required tags are shown by default + builder.limit(required_tag_ids.size) + else + builder.limit(opts[:limit]) + end + end + if opts[:order_popularity] builder.order_by("topic_count DESC, name") elsif opts[:order_search_results] && !term.blank? diff --git a/spec/components/discourse_tagging_spec.rb b/spec/components/discourse_tagging_spec.rb index 30e51bcad0..815e399d26 100644 --- a/spec/components/discourse_tagging_spec.rb +++ b/spec/components/discourse_tagging_spec.rb @@ -162,14 +162,53 @@ describe DiscourseTagging do expect(sorted_tag_names(tags)).to contain_exactly(tag2.name) end - it "let's staff ignore the requirement" do + it "lets staff ignore the requirement" do + tags = DiscourseTagging.filter_allowed_tags(Guardian.new(admin), + for_input: true, + category: category, + limit: 5 + ).to_a + + expect(sorted_tag_names(tags)).to eq(sorted_tag_names([tag1, tag2, tag3])) + end + + end + + context 'with many required tags in a tag group' do + fab!(:tag4) { Fabricate(:tag, name: "T4") } + fab!(:tag5) { Fabricate(:tag, name: "T5") } + fab!(:tag6) { Fabricate(:tag, name: "T6") } + fab!(:tag7) { Fabricate(:tag, name: "T7") } + fab!(:tag_group) { Fabricate(:tag_group, tags: [tag1, tag2, tag4, tag5, tag6, tag7]) } + fab!(:category) { Fabricate(:category, required_tag_group: tag_group, min_tags_from_required_group: 1) } + + it "returns required tags for staff by default" do + tags = DiscourseTagging.filter_allowed_tags(Guardian.new(admin), + for_input: true, + category: category + ).to_a + expect(sorted_tag_names(tags)).to eq(sorted_tag_names([tag1, tag2, tag4, tag5, tag6, tag7])) + end + + it "ignores required tags for staff when searching using a term" do tags = DiscourseTagging.filter_allowed_tags(Guardian.new(admin), for_input: true, category: category, term: 'fun' ).to_a + expect(sorted_tag_names(tags)).to eq(sorted_tag_names([tag1, tag2, tag3])) end + + it "returns required tags for nonstaff and overrides limit" do + tags = DiscourseTagging.filter_allowed_tags(Guardian.new(user), + for_input: true, + limit: 5, + category: category + ).to_a + expect(sorted_tag_names(tags)).to eq(sorted_tag_names([tag1, tag2, tag4, tag5, tag6, tag7])) + end + end context 'empty term' do