UX: Exclude search ignored and user muted categories in similarity search (#19349)
When finding the candidates for `Topic.similar_to`, we will now ignore topics in categories where `Category#search_priority` has been set to ignore and also topics in categories which the user has specifically muted. Internal Ref: /t/87132
This commit is contained in:
parent
5aaaf26636
commit
207b764ea3
|
@ -634,14 +634,27 @@ class Topic < ActiveRecord::Base
|
|||
|
||||
tsquery = Search.to_tsquery(term: tsquery, joiner: "|")
|
||||
|
||||
guardian = Guardian.new(user)
|
||||
|
||||
excluded_category_ids_sql = Category.secured(guardian).where(search_priority: Searchable::PRIORITIES[:ignore]).select(:id).to_sql
|
||||
|
||||
if user
|
||||
excluded_category_ids_sql = <<~SQL
|
||||
#{excluded_category_ids_sql}
|
||||
UNION
|
||||
#{CategoryUser.where(notification_level: CategoryUser.notification_levels[:muted], user: user).select(:category_id).to_sql}
|
||||
SQL
|
||||
end
|
||||
|
||||
candidates = Topic
|
||||
.visible
|
||||
.listable_topics
|
||||
.secured(Guardian.new(user))
|
||||
.secured(guardian)
|
||||
.joins("JOIN topic_search_data s ON topics.id = s.topic_id")
|
||||
.joins("LEFT JOIN categories c ON topics.id = c.topic_id")
|
||||
.where("search_data @@ #{tsquery}")
|
||||
.where("c.topic_id IS NULL")
|
||||
.where("topics.category_id NOT IN (#{excluded_category_ids_sql})")
|
||||
.order("ts_rank(search_data, #{tsquery}) DESC")
|
||||
.limit(SiteSetting.max_similar_results * 3)
|
||||
|
||||
|
|
|
@ -685,10 +685,28 @@ RSpec.describe Topic do
|
|||
expect(topics).to eq([])
|
||||
end
|
||||
|
||||
it 'does not return topics from categories with search priority set to ignore' do
|
||||
expect(Topic.similar_to("has evil trout made any topics?", "")).to eq([topic])
|
||||
|
||||
topic.category.update!(search_priority: Searchable::PRIORITIES[:ignore])
|
||||
|
||||
expect(Topic.similar_to("has evil trout made any topics?", "")).to eq([])
|
||||
end
|
||||
|
||||
it 'does not return topics from categories which the user has muted' do
|
||||
expect(Topic.similar_to("has evil trout made any topics?", "", user)).to eq([topic])
|
||||
|
||||
CategoryUser.create!(category: topic.category, user: user, notification_level: CategoryUser.notification_levels[:muted])
|
||||
|
||||
expect(Topic.similar_to("has evil trout made any topics?", "", user)).to eq([])
|
||||
end
|
||||
|
||||
context "with secure categories" do
|
||||
fab!(:group) { Fabricate(:group) }
|
||||
fab!(:private_category) { Fabricate(:private_category, group: group) }
|
||||
|
||||
before do
|
||||
category.update!(read_restricted: true)
|
||||
topic.update!(category: category)
|
||||
topic.update!(category: private_category)
|
||||
end
|
||||
|
||||
it "doesn't return topics from private categories" do
|
||||
|
@ -696,7 +714,8 @@ RSpec.describe Topic do
|
|||
end
|
||||
|
||||
it "should return the cat since the user can see it" do
|
||||
Guardian.any_instance.expects(:secure_category_ids).returns([category.id])
|
||||
group.add(user)
|
||||
|
||||
expect(Topic.similar_to("has evil trout made any topics?", "i am wondering has evil trout made any topics?", user)).to include(topic)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue