DEV: Add include_pms option to TopicQuery (#10647)

This is intended for use by plugins which are building their own topic lists, and want to include PMs alongside regular topics (e.g. discourse-assign). It does not get used directly in core.
This commit is contained in:
David Taylor 2020-09-14 12:07:35 +01:00 committed by GitHub
parent 21adc07057
commit 66eda8c9df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 29 additions and 7 deletions

View File

@ -70,7 +70,8 @@ class TopicQuery
visible visible
guardian guardian
no_definitions no_definitions
destination_category_id) destination_category_id
include_pms)
end end
# Maps `order` to a columns in `topics` # Maps `order` to a columns in `topics`
@ -724,7 +725,15 @@ class TopicQuery
end end
result = apply_ordering(result, options) result = apply_ordering(result, options)
result = result.listable_topics
all_listable_topics = @guardian.filter_allowed_categories(Topic.unscoped.listable_topics)
if options[:include_pms]
all_pm_topics = Topic.unscoped.private_messages_for_user(@user)
result = result.merge(all_listable_topics.or(all_pm_topics))
else
result = result.merge(all_listable_topics)
end
# Don't include the category topics if excluded # Don't include the category topics if excluded
if options[:no_definitions] if options[:no_definitions]
@ -851,7 +860,7 @@ class TopicQuery
result = TopicQuery.apply_custom_filters(result, self) result = TopicQuery.apply_custom_filters(result, self)
@guardian.filter_allowed_categories(result) result
end end
def remove_muted_topics(list, user) def remove_muted_topics(list, user)

View File

@ -9,7 +9,7 @@ describe TopicQuery do
# it indeed happens first, but is not obvious later in the tests we depend on the user being # it indeed happens first, but is not obvious later in the tests we depend on the user being
# created so early otherwise finding new topics does not work # created so early otherwise finding new topics does not work
# we should remove the let! here and use freeze time to communicate how the clock moves # we should remove the let! here and use freeze time to communicate how the clock moves
let!(:user) { Fabricate(:coding_horror) } let!(:user) { Fabricate(:user) }
fab!(:creator) { Fabricate(:user) } fab!(:creator) { Fabricate(:user) }
let(:topic_query) { TopicQuery.new(user) } let(:topic_query) { TopicQuery.new(user) }
@ -162,6 +162,18 @@ describe TopicQuery do
end end
end end
describe 'include_pms option' do
it "includes users own pms in regular topic lists" do
topic = Fabricate(:topic)
own_pm = Fabricate(:private_message_topic, user: user)
other_pm = Fabricate(:private_message_topic, user: Fabricate(:user))
expect(TopicQuery.new(user).list_latest.topics).to contain_exactly(topic)
expect(TopicQuery.new(admin).list_latest.topics).to contain_exactly(topic)
expect(TopicQuery.new(user, include_pms: true).list_latest.topics).to contain_exactly(topic, own_pm)
end
end
context 'category filter' do context 'category filter' do
let(:category) { Fabricate(:category_with_definition) } let(:category) { Fabricate(:category_with_definition) }
let(:diff_category) { Fabricate(:category_with_definition, name: "Different Category") } let(:diff_category) { Fabricate(:category_with_definition, name: "Different Category") }

View File

@ -21,11 +21,12 @@ Fabricator(:banner_topic, from: :topic) do
end end
Fabricator(:private_message_topic, from: :topic) do Fabricator(:private_message_topic, from: :topic) do
transient :recipient
category_id { nil } category_id { nil }
title { sequence(:title) { |i| "This is a private message #{i}" } } title { sequence(:title) { |i| "This is a private message #{i}" } }
archetype "private_message" archetype "private_message"
topic_allowed_users { |t| [ topic_allowed_users { |t| [
Fabricate.build(:topic_allowed_user, user: t[:user]), Fabricate.build(:topic_allowed_user, user: t[:user]),
Fabricate.build(:topic_allowed_user, user: Fabricate(:coding_horror)) Fabricate.build(:topic_allowed_user, user: t[:recipient] || Fabricate(:user))
]} ]}
end end

View File

@ -894,9 +894,9 @@ describe Topic do
end end
context 'private message' do context 'private message' do
let(:coding_horror) { User.find_by(username: "CodingHorror") } let(:coding_horror) { Fabricate(:coding_horror) }
fab!(:evil_trout) { Fabricate(:evil_trout) } fab!(:evil_trout) { Fabricate(:evil_trout) }
let(:topic) { Fabricate(:private_message_topic) } let(:topic) { Fabricate(:private_message_topic, recipient: coding_horror) }
it "should integrate correctly" do it "should integrate correctly" do
expect(Guardian.new(topic.user).can_see?(topic)).to eq(true) expect(Guardian.new(topic.user).can_see?(topic)).to eq(true)