Support multi-group user search

This commit is contained in:
romanrizzi 2019-05-10 12:35:36 -03:00 committed by Guo Xiang Tan
parent 8728850452
commit e7ee556e87
6 changed files with 75 additions and 13 deletions

View File

@ -72,7 +72,7 @@ export default TextField.extend({
allowedUsers, allowedUsers,
includeMentionableGroups, includeMentionableGroups,
includeMessageableGroups, includeMessageableGroups,
group: userSelectorComponent.group, groupMembersOf: userSelectorComponent.groupMembersOf,
allowEmails allowEmails
}); });
}, },

View File

@ -16,7 +16,7 @@ function performSearch(
includeMentionableGroups, includeMentionableGroups,
includeMessageableGroups, includeMessageableGroups,
allowedUsers, allowedUsers,
group, groupMembersOf,
resultsFn resultsFn
) { ) {
var cached = cache[term]; var cached = cache[term];
@ -40,7 +40,7 @@ function performSearch(
include_groups: includeGroups, include_groups: includeGroups,
include_mentionable_groups: includeMentionableGroups, include_mentionable_groups: includeMentionableGroups,
include_messageable_groups: includeMessageableGroups, include_messageable_groups: includeMessageableGroups,
group: group, groups: groupMembersOf,
topic_allowed_users: allowedUsers topic_allowed_users: allowedUsers
} }
}); });
@ -140,7 +140,7 @@ export default function userSearch(options) {
includeMessageableGroups = options.includeMessageableGroups, includeMessageableGroups = options.includeMessageableGroups,
allowedUsers = options.allowedUsers, allowedUsers = options.allowedUsers,
topicId = options.topicId, topicId = options.topicId,
group = options.group; groupMembersOf = options.groupMembersOf;
if (oldSearch) { if (oldSearch) {
oldSearch.abort(); oldSearch.abort();
@ -172,7 +172,7 @@ export default function userSearch(options) {
includeMentionableGroups, includeMentionableGroups,
includeMessageableGroups, includeMessageableGroups,
allowedUsers, allowedUsers,
group, groupMembersOf,
function(r) { function(r) {
clearTimeout(clearPromise); clearTimeout(clearPromise);
resolve(organizeResults(r, options)); resolve(organizeResults(r, options));

View File

@ -843,15 +843,17 @@ class UsersController < ApplicationController
topic_id = topic_id.to_i if topic_id topic_id = topic_id.to_i if topic_id
topic_allowed_users = params[:topic_allowed_users] || false topic_allowed_users = params[:topic_allowed_users] || false
if params[:group].present? group_names = params[:groups] || []
@group = Group.find_by(name: params[:group]) group_names << params[:group] if params[:group]
if group_names.present?
@groups = Group.where(name: group_names)
end end
results = UserSearch.new(term, results = UserSearch.new(term,
topic_id: topic_id, topic_id: topic_id,
topic_allowed_users: topic_allowed_users, topic_allowed_users: topic_allowed_users,
searching_user: current_user, searching_user: current_user,
group: @group groups: @groups
).search ).search
user_fields = [:username, :upload_avatar_template] user_fields = [:username, :upload_avatar_template]

View File

@ -13,18 +13,18 @@ class UserSearch
@searching_user = opts[:searching_user] @searching_user = opts[:searching_user]
@include_staged_users = opts[:include_staged_users] || false @include_staged_users = opts[:include_staged_users] || false
@limit = opts[:limit] || 20 @limit = opts[:limit] || 20
@group = opts[:group] @groups = opts[:groups]
@guardian = Guardian.new(@searching_user) @guardian = Guardian.new(@searching_user)
@guardian.ensure_can_see_group!(@group) if @group @groups.each { |group| @guardian.ensure_can_see_group!(group) } if @groups
end end
def scoped_users def scoped_users
users = User.where(active: true) users = User.where(active: true)
users = users.where(staged: false) unless @include_staged_users users = users.where(staged: false) unless @include_staged_users
if @group if @groups
users = users.joins("INNER JOIN group_users ON group_users.user_id = users.id") users = users.joins("INNER JOIN group_users ON group_users.user_id = users.id")
.where("group_users.group_id = ?", @group.id) .where("group_users.group_id IN (?)", @groups.map(&:id))
end end
unless @searching_user && @searching_user.staff? unless @searching_user && @searching_user.staff?

View File

@ -51,10 +51,22 @@ describe UserSearch do
_samantha = Fabricate(:user, username: 'samantha') _samantha = Fabricate(:user, username: 'samantha')
group.add(sam) group.add(sam)
results = search_for("sam", group: group) results = search_for("sam", groups: [group])
expect(results.count).to eq(1) expect(results.count).to eq(1)
end end
it 'allows filtering by multiple groups' do
group_1 = Fabricate(:group)
sam = Fabricate(:user, username: 'sam')
group_2 = Fabricate(:group)
samantha = Fabricate(:user, username: 'samantha')
group_1.add(sam)
group_2.add(samantha)
results = search_for("sam", groups: [group_1, group_2])
expect(results.count).to eq(2)
end
# this is a seriously expensive integration test, # this is a seriously expensive integration test,
# re-creating this entire test db is too expensive reuse # re-creating this entire test db is too expensive reuse
it "operates correctly" do it "operates correctly" do

View File

@ -3021,6 +3021,54 @@ describe UsersController do
expect(JSON.parse(response.body)).not_to have_key(:groups) expect(JSON.parse(response.body)).not_to have_key(:groups)
end end
end end
describe 'when searching by group name' do
fab!(:exclusive_group) { Fabricate(:group) }
it 'return results if the user is a group member' do
exclusive_group.add(user)
get "/u/search/users.json", params: {
group: exclusive_group.name,
term: user.username
}
expect(users_found).to contain_exactly(user.username)
end
it 'does not return results if the user is not a group member' do
get "/u/search/users.json", params: {
group: exclusive_group.name,
term: user.username
}
expect(users_found).to be_empty
end
it 'returns results if the user is member of one of the groups' do
exclusive_group.add(user)
get "/u/search/users.json", params: {
groups: [exclusive_group.name],
term: user.username
}
expect(users_found).to contain_exactly(user.username)
end
it 'does not return results if the user is not a member of the groups' do
get "/u/search/users.json", params: {
groups: [exclusive_group.name],
term: user.username
}
expect(users_found).to be_empty
end
def users_found
JSON.parse(response.body)['users'].map { |u| u['username'] }
end
end
end end
end end