FEATURE: Add `group_messages:` keyword to advanced search (#16584)

This commit is contained in:
Penar Musaraj 2022-04-28 10:47:40 -04:00 committed by GitHub
parent de19003bad
commit b266a36967
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 97 additions and 35 deletions

View File

@ -609,6 +609,20 @@ class Search
end
end
advanced_filter(/^group_messages:(.+)$/i) do |posts, match|
group_id = Group
.visible_groups(@guardian.user)
.members_visible_groups(@guardian.user)
.where(has_messages: true)
.where('name ilike ? OR (id = ? AND id > 0)', match, match.to_i).pluck_first(:id)
if group_id
posts.where('posts.topic_id IN (SELECT topic_id FROM topic_allowed_groups WHERE group_id = ?)', group_id)
else
posts.where("1 = 0")
end
end
advanced_filter(/^user:(.+)$/i) do |posts, match|
user_id = User.where(staged: false).where('username_lower = ? OR id = ?', match.downcase, match.to_i).pluck_first(:id)
if user_id
@ -757,6 +771,9 @@ class Search
elsif word =~ /^in:all-pms$/i
@search_all_pms = true
nil
elsif word =~ /^group_messages:(.+)$/i
@search_pms = true
nil
elsif word =~ /^personal_messages:(.+)$/i
if user = User.find_by_username($1)
@search_pms = true

View File

@ -582,10 +582,11 @@ describe Search do
end
end
context 'personal-direct flag' do
context 'personal-direct and group_messages flags' do
let(:current) { Fabricate(:user, admin: true, username: "current_user") }
let(:participant) { Fabricate(:user, username: "participant_1") }
let(:participant_2) { Fabricate(:user, username: "participant_2") }
let(:non_participant) { Fabricate(:user, username: "non_participant") }
let(:group) do
group = Fabricate(:group, has_messages: true)
@ -609,49 +610,93 @@ describe Search do
pm.reload
end
it 'can find all direct PMs of the current user' do
pm = create_pm(users: [current, participant])
_pm_2 = create_pm(users: [participant_2, participant])
pm_3 = create_pm(users: [participant, current])
pm_4 = create_pm(users: [participant_2, current])
context "personal-direct flag" do
it 'can find all direct PMs of the current user' do
pm = create_pm(users: [current, participant])
_pm_2 = create_pm(users: [participant_2, participant])
pm_3 = create_pm(users: [participant, current])
pm_4 = create_pm(users: [participant_2, current])
["in:personal-direct", "In:PeRsOnAl-DiReCt"].each do |query|
results = Search.execute(query, guardian: Guardian.new(current))
["in:personal-direct", "In:PeRsOnAl-DiReCt"].each do |query|
results = Search.execute(query, guardian: Guardian.new(current))
expect(results.posts.size).to eq(3)
expect(results.posts.map(&:topic_id)).to eq([pm_4.id, pm_3.id, pm.id])
end
end
it 'can filter direct PMs by @username' do
pm = create_pm(users: [current, participant])
pm_2 = create_pm(users: [participant, current])
pm_3 = create_pm(users: [participant_2, current])
[
"@#{participant.username} in:personal-direct",
"@#{participant.username} iN:pErSoNaL-dIrEcT",
].each do |query|
results = Search.execute(query, guardian: Guardian.new(current))
expect(results.posts.size).to eq(2)
expect(results.posts.map(&:topic_id)).to contain_exactly(pm_2.id, pm.id)
expect(results.posts.map(&:user_id).uniq).to eq([participant.id])
end
results = Search.execute("@me in:personal-direct", guardian: Guardian.new(current))
expect(results.posts.size).to eq(3)
expect(results.posts.map(&:topic_id)).to eq([pm_4.id, pm_3.id, pm.id])
expect(results.posts.map(&:topic_id)).to contain_exactly(pm_3.id, pm_2.id, pm.id)
expect(results.posts.map(&:user_id).uniq).to eq([current.id])
end
it "doesn't include PMs that have more than 2 participants" do
_pm = create_pm(users: [current, participant, participant_2])
results = Search.execute("@#{participant.username} in:personal-direct", guardian: Guardian.new(current))
expect(results.posts.size).to eq(0)
end
it "doesn't include PMs that have groups" do
_pm = create_pm(users: [current, participant], group: group)
results = Search.execute("@#{participant.username} in:personal-direct", guardian: Guardian.new(current))
expect(results.posts.size).to eq(0)
end
end
it 'can filter direct PMs by @username' do
pm = create_pm(users: [current, participant])
pm_2 = create_pm(users: [participant, current])
pm_3 = create_pm(users: [participant_2, current])
[
"@#{participant.username} in:personal-direct",
"@#{participant.username} iN:pErSoNaL-dIrEcT",
].each do |query|
results = Search.execute(query, guardian: Guardian.new(current))
expect(results.posts.size).to eq(2)
expect(results.posts.map(&:topic_id)).to contain_exactly(pm_2.id, pm.id)
expect(results.posts.map(&:user_id).uniq).to eq([participant.id])
context "group_messages flag" do
it 'returns results correctly for a PM in a given group' do
pm = create_pm(users: [participant, participant_2], group: group)
results = Search.execute("group_messages:#{group.name}", guardian: Guardian.new(current))
expect(results.posts).to contain_exactly(pm.first_post)
results = Search.execute("secret group_messages:#{group.name}", guardian: Guardian.new(current))
expect(results.posts).to contain_exactly(pm.first_post)
end
results = Search.execute("@me in:personal-direct", guardian: Guardian.new(current))
expect(results.posts.size).to eq(3)
expect(results.posts.map(&:topic_id)).to contain_exactly(pm_3.id, pm_2.id, pm.id)
expect(results.posts.map(&:user_id).uniq).to eq([current.id])
end
it 'returns nothing if user is not a group member' do
pm = create_pm(users: [current, participant], group: group)
it "doesn't include PMs that have more than 2 participants" do
_pm = create_pm(users: [current, participant, participant_2])
results = Search.execute("@#{participant.username} in:personal-direct", guardian: Guardian.new(current))
expect(results.posts.size).to eq(0)
end
results = Search.execute("group_messages:#{group.name}", guardian: Guardian.new(non_participant))
expect(results.posts.size).to eq(0)
it "doesn't include PMs that have groups" do
_pm = create_pm(users: [current, participant], group: group)
results = Search.execute("@#{participant.username} in:personal-direct", guardian: Guardian.new(current))
expect(results.posts.size).to eq(0)
# even for admins
results = Search.execute("group_messages:#{group.name}", guardian: Guardian.new(admin))
expect(results.posts.size).to eq(0)
end
it 'returns nothing if group has messages disabled' do
pm = create_pm(users: [current, participant], group: group)
group.update!(has_messages: false)
results = Search.execute("group_messages:#{group.name}", guardian: Guardian.new(current))
expect(results.posts.size).to eq(0)
end
it 'is correctly scoped to a given group' do
wrong_group = Fabricate(:group, has_messages: true)
pm = create_pm(users: [current, participant], group: group)
results = Search.execute("group_messages:#{group.name}", guardian: Guardian.new(current))
expect(results.posts).to contain_exactly(pm.first_post)
results = Search.execute("group_messages:#{wrong_group.name}", guardian: Guardian.new(current))
expect(results.posts.size).to eq(0)
end
end
end