diff --git a/app/assets/javascripts/discourse/components/user-selector.js.es6 b/app/assets/javascripts/discourse/components/user-selector.js.es6 index c583960abeb..fd9bb6ba3b1 100644 --- a/app/assets/javascripts/discourse/components/user-selector.js.es6 +++ b/app/assets/javascripts/discourse/components/user-selector.js.es6 @@ -21,6 +21,7 @@ export default TextField.extend({ groups = [], currentUser = this.currentUser, includeMentionableGroups = this.get('includeMentionableGroups') === 'true', + includeMessageableGroups = this.get('includeMessageableGroups') === 'true', includeGroups = this.get('includeGroups') === 'true', allowedUsers = this.get('allowedUsers') === 'true'; @@ -52,6 +53,7 @@ export default TextField.extend({ includeGroups, allowedUsers, includeMentionableGroups, + includeMessageableGroups, group: self.get("group") }); diff --git a/app/assets/javascripts/discourse/lib/user-search.js.es6 b/app/assets/javascripts/discourse/lib/user-search.js.es6 index 5186779d3c1..29ad228a050 100644 --- a/app/assets/javascripts/discourse/lib/user-search.js.es6 +++ b/app/assets/javascripts/discourse/lib/user-search.js.es6 @@ -7,7 +7,7 @@ var cache = {}, currentTerm, oldSearch; -function performSearch(term, topicId, includeGroups, includeMentionableGroups, allowedUsers, group, resultsFn) { +function performSearch(term, topicId, includeGroups, includeMentionableGroups, includeMessageableGroups, allowedUsers, group, resultsFn) { var cached = cache[term]; if (cached) { resultsFn(cached); @@ -20,6 +20,7 @@ function performSearch(term, topicId, includeGroups, includeMentionableGroups, a topic_id: topicId, include_groups: includeGroups, include_mentionable_groups: includeMentionableGroups, + include_messageable_groups: includeMessageableGroups, group: group, topic_allowed_users: allowedUsers } }); @@ -88,6 +89,7 @@ export default function userSearch(options) { var term = options.term || "", includeGroups = options.includeGroups, includeMentionableGroups = options.includeMentionableGroups, + includeMessageableGroups = options.includeMessageableGroups, allowedUsers = options.allowedUsers, topicId = options.topicId, group = options.group; @@ -120,6 +122,7 @@ export default function userSearch(options) { topicId, includeGroups, includeMentionableGroups, + includeMessageableGroups, allowedUsers, group, function(r) { diff --git a/app/assets/javascripts/discourse/templates/components/composer-user-selector.hbs b/app/assets/javascripts/discourse/templates/components/composer-user-selector.hbs index 402416a1d6e..99fc0a5b97d 100644 --- a/app/assets/javascripts/discourse/templates/components/composer-user-selector.hbs +++ b/app/assets/javascripts/discourse/templates/components/composer-user-selector.hbs @@ -2,7 +2,7 @@ {{user-selector topicId=topicId onChangeCallback='triggerResize' id="private-message-users" - includeMentionableGroups='true' + includeMessageableGroups='true' class="span8" placeholderKey="composer.users_placeholder" tabindex="1" diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 87f6332ab56..b71d9f6305d 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -698,12 +698,16 @@ class UsersController < ApplicationController end end - if params[:include_mentionable_groups] == "true" && current_user - to_render[:groups] = Group.mentionable(current_user) - .where("name ILIKE :term_like", term_like: "#{term}%") - .map do |m| - { name: m.name, full_name: m.full_name } - end + if current_user + groups = + if params[:include_mentionable_groups] == 'true' + Group.mentionable(current_user) + elsif params[:include_messageable_groups] == 'true' + Group.messageable(current_user) + end + + to_render[:groups] = groups.where("name ILIKE :term_like", term_like: "#{term}%") + .map { |m| { name: m.name, full_name: m.full_name } } end render json: to_render diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index a6906c06efa..a16779d4c29 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -1601,88 +1601,6 @@ describe UsersController do end end - describe "search_users" do - - let(:topic) { Fabricate :topic } - let(:user) { Fabricate :user, username: "joecabot", name: "Lawrence Tierney" } - - before do - SearchIndexer.enable - Fabricate :post, user: user, topic: topic - end - - it "searches when provided the term only" do - post :search_users, params: { term: user.name.split(" ").last }, format: :json - expect(response).to be_success - json = JSON.parse(response.body) - expect(json["users"].map { |u| u["username"] }).to include(user.username) - end - - it "searches when provided the topic only" do - post :search_users, params: { topic_id: topic.id }, format: :json - expect(response).to be_success - json = JSON.parse(response.body) - expect(json["users"].map { |u| u["username"] }).to include(user.username) - end - - it "searches when provided the term and topic" do - post :search_users, params: { - term: user.name.split(" ").last, topic_id: topic.id - }, format: :json - - expect(response).to be_success - json = JSON.parse(response.body) - expect(json["users"].map { |u| u["username"] }).to include(user.username) - end - - it "searches only for users who have access to private topic" do - privileged_user = Fabricate(:user, trust_level: 4, username: "joecabit", name: "Lawrence Tierney") - privileged_group = Fabricate(:group) - privileged_group.add(privileged_user) - privileged_group.save - - category = Fabricate(:category) - category.set_permissions(privileged_group => :readonly) - category.save - - private_topic = Fabricate(:topic, category: category) - - post :search_users, params: { - term: user.name.split(" ").last, topic_id: private_topic.id, topic_allowed_users: "true" - }, format: :json - - expect(response).to be_success - json = JSON.parse(response.body) - expect(json["users"].map { |u| u["username"] }).to_not include(user.username) - expect(json["users"].map { |u| u["username"] }).to include(privileged_user.username) - end - - context "when `enable_names` is true" do - before do - SiteSetting.enable_names = true - end - - it "returns names" do - post :search_users, params: { term: user.name }, format: :json - json = JSON.parse(response.body) - expect(json["users"].map { |u| u["name"] }).to include(user.name) - end - end - - context "when `enable_names` is false" do - before do - SiteSetting.enable_names = false - end - - it "returns names" do - post :search_users, params: { term: user.name }, format: :json - json = JSON.parse(response.body) - expect(json["users"].map { |u| u["name"] }).not_to include(user.name) - end - end - - end - describe 'send_activation_email' do context 'for an existing user' do let(:user) { Fabricate(:user, active: false) } diff --git a/spec/requests/users_controller_spec.rb b/spec/requests/users_controller_spec.rb index 53d5eb5a367..13bfab2d447 100644 --- a/spec/requests/users_controller_spec.rb +++ b/spec/requests/users_controller_spec.rb @@ -85,4 +85,136 @@ RSpec.describe UsersController do end end end + + describe "search_users" do + let(:topic) { Fabricate :topic } + let(:user) { Fabricate :user, username: "joecabot", name: "Lawrence Tierney" } + let(:post1) { Fabricate(:post, user: user, topic: topic) } + + before do + SearchIndexer.enable + post1 + end + + it "searches when provided the term only" do + get "/u/search/users.json", params: { term: user.name.split(" ").last } + expect(response).to be_success + json = JSON.parse(response.body) + expect(json["users"].map { |u| u["username"] }).to include(user.username) + end + + it "searches when provided the topic only" do + get "/u/search/users.json", params: { topic_id: topic.id } + expect(response).to be_success + json = JSON.parse(response.body) + expect(json["users"].map { |u| u["username"] }).to include(user.username) + end + + it "searches when provided the term and topic" do + get "/u/search/users.json", params: { + term: user.name.split(" ").last, topic_id: topic.id + } + + expect(response).to be_success + json = JSON.parse(response.body) + expect(json["users"].map { |u| u["username"] }).to include(user.username) + end + + it "searches only for users who have access to private topic" do + privileged_user = Fabricate(:user, trust_level: 4, username: "joecabit", name: "Lawrence Tierney") + privileged_group = Fabricate(:group) + privileged_group.add(privileged_user) + privileged_group.save + + category = Fabricate(:category) + category.set_permissions(privileged_group => :readonly) + category.save + + private_topic = Fabricate(:topic, category: category) + + get "/u/search/users.json", params: { + term: user.name.split(" ").last, topic_id: private_topic.id, topic_allowed_users: "true" + } + + expect(response).to be_success + json = JSON.parse(response.body) + expect(json["users"].map { |u| u["username"] }).to_not include(user.username) + expect(json["users"].map { |u| u["username"] }).to include(privileged_user.username) + end + + context "when `enable_names` is true" do + before do + SiteSetting.enable_names = true + end + + it "returns names" do + get "/u/search/users.json", params: { term: user.name } + json = JSON.parse(response.body) + expect(json["users"].map { |u| u["name"] }).to include(user.name) + end + end + + context "when `enable_names` is false" do + before do + SiteSetting.enable_names = false + end + + it "returns names" do + get "/u/search/users.json", params: { term: user.name } + json = JSON.parse(response.body) + expect(json["users"].map { |u| u["name"] }).not_to include(user.name) + end + end + + context 'groups' do + let!(:mentionable_group) { Fabricate(:group, mentionable_level: 99, messageable_level: 0) } + let!(:messageable_group) { Fabricate(:group, mentionable_level: 0, messageable_level: 99) } + + describe 'when signed in' do + before do + sign_in(user) + end + + it "searches for messageable groups" do + get "/u/search/users.json", params: { + include_mentionable_groups: 'false', + include_messageable_groups: 'true' + } + + expect(response).to be_success + expect(JSON.parse(response.body)["groups"].first['name']).to eq(messageable_group.name) + end + + it 'searches for mentionable groups' do + get "/u/search/users.json", params: { + include_messageable_groups: 'false', + include_mentionable_groups: 'true' + } + + expect(response).to be_success + expect(JSON.parse(response.body)["groups"].first['name']).to eq(mentionable_group.name) + end + end + + describe 'when not signed in' do + it 'should not include mentionable/messageable groups' do + get "/u/search/users.json", params: { + include_mentionable_groups: 'false', + include_messageable_groups: 'true' + } + + expect(response).to be_success + expect(JSON.parse(response.body)["groups"]).to eq(nil) + + get "/u/search/users.json", params: { + include_messageable_groups: 'false', + include_mentionable_groups: 'true' + } + + expect(response).to be_success + expect(JSON.parse(response.body)["groups"]).to eq(nil) + end + end + end + end end