diff --git a/app/assets/javascripts/discourse/components/user-selector.js.es6 b/app/assets/javascripts/discourse/components/user-selector.js.es6 index ebc11d4f711..2cc95441ed6 100644 --- a/app/assets/javascripts/discourse/components/user-selector.js.es6 +++ b/app/assets/javascripts/discourse/components/user-selector.js.es6 @@ -72,7 +72,7 @@ export default TextField.extend({ allowedUsers, includeMentionableGroups, includeMessageableGroups, - group: userSelectorComponent.group, + groupMembersOf: userSelectorComponent.groupMembersOf, allowEmails }); }, diff --git a/app/assets/javascripts/discourse/lib/user-search.js.es6 b/app/assets/javascripts/discourse/lib/user-search.js.es6 index fc2e29a7faf..753460f1fa5 100644 --- a/app/assets/javascripts/discourse/lib/user-search.js.es6 +++ b/app/assets/javascripts/discourse/lib/user-search.js.es6 @@ -16,7 +16,7 @@ function performSearch( includeMentionableGroups, includeMessageableGroups, allowedUsers, - group, + groupMembersOf, resultsFn ) { var cached = cache[term]; @@ -40,7 +40,7 @@ function performSearch( include_groups: includeGroups, include_mentionable_groups: includeMentionableGroups, include_messageable_groups: includeMessageableGroups, - group: group, + groups: groupMembersOf, topic_allowed_users: allowedUsers } }); @@ -140,7 +140,7 @@ export default function userSearch(options) { includeMessageableGroups = options.includeMessageableGroups, allowedUsers = options.allowedUsers, topicId = options.topicId, - group = options.group; + groupMembersOf = options.groupMembersOf; if (oldSearch) { oldSearch.abort(); @@ -172,7 +172,7 @@ export default function userSearch(options) { includeMentionableGroups, includeMessageableGroups, allowedUsers, - group, + groupMembersOf, function(r) { clearTimeout(clearPromise); resolve(organizeResults(r, options)); diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 6693ab6eb90..5a63496f3ea 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -843,15 +843,17 @@ class UsersController < ApplicationController topic_id = topic_id.to_i if topic_id topic_allowed_users = params[:topic_allowed_users] || false - if params[:group].present? - @group = Group.find_by(name: params[:group]) + group_names = params[:groups] || [] + group_names << params[:group] if params[:group] + if group_names.present? + @groups = Group.where(name: group_names) end results = UserSearch.new(term, topic_id: topic_id, topic_allowed_users: topic_allowed_users, searching_user: current_user, - group: @group + groups: @groups ).search user_fields = [:username, :upload_avatar_template] diff --git a/app/models/user_search.rb b/app/models/user_search.rb index 088c91bdd12..469c4dcb5f6 100644 --- a/app/models/user_search.rb +++ b/app/models/user_search.rb @@ -13,18 +13,18 @@ class UserSearch @searching_user = opts[:searching_user] @include_staged_users = opts[:include_staged_users] || false @limit = opts[:limit] || 20 - @group = opts[:group] + @groups = opts[:groups] @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 def scoped_users users = User.where(active: true) 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") - .where("group_users.group_id = ?", @group.id) + .where("group_users.group_id IN (?)", @groups.map(&:id)) end unless @searching_user && @searching_user.staff? diff --git a/spec/models/user_search_spec.rb b/spec/models/user_search_spec.rb index 3973a78d6ac..6d1ae9f8d81 100644 --- a/spec/models/user_search_spec.rb +++ b/spec/models/user_search_spec.rb @@ -51,10 +51,22 @@ describe UserSearch do _samantha = Fabricate(:user, username: 'samantha') group.add(sam) - results = search_for("sam", group: group) + results = search_for("sam", groups: [group]) expect(results.count).to eq(1) 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, # re-creating this entire test db is too expensive reuse it "operates correctly" do diff --git a/spec/requests/users_controller_spec.rb b/spec/requests/users_controller_spec.rb index 30f8b24d995..6fb04028ceb 100644 --- a/spec/requests/users_controller_spec.rb +++ b/spec/requests/users_controller_spec.rb @@ -3021,6 +3021,54 @@ describe UsersController do expect(JSON.parse(response.body)).not_to have_key(:groups) 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