diff options
author | Simon Brandhof <simon.brandhof@gmail.com> | 2013-05-14 18:42:51 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@gmail.com> | 2013-05-14 19:02:41 +0200 |
commit | f5f73537f6b8bf961cd189c93ed2b256dd66c7a2 (patch) | |
tree | 5f57109b0d01c7f03162eff95801ece4acd914be | |
parent | 971be0c76e753adb739b09f79a42b8502fcf43fa (diff) | |
download | sonarqube-f5f73537f6b8bf961cd189c93ed2b256dd66c7a2.tar.gz sonarqube-f5f73537f6b8bf961cd189c93ed2b256dd66c7a2.zip |
SONAR-4323 add search by free text and support of Select2
11 files changed, 109 insertions, 3 deletions
diff --git a/sonar-core/src/main/resources/org/sonar/core/user/UserMapper.xml b/sonar-core/src/main/resources/org/sonar/core/user/UserMapper.xml index 5bc41686c67..adfeea60245 100644 --- a/sonar-core/src/main/resources/org/sonar/core/user/UserMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/user/UserMapper.xml @@ -42,6 +42,9 @@ <if test="includeDeactivated==false"> and u.active=${_true} </if> + <if test="searchText != null"> + and (u.login like #{searchTextSql} or u.name like #{searchTextSql}) + </if> </where> order by u.name </select> diff --git a/sonar-core/src/test/java/org/sonar/core/user/UserDaoTest.java b/sonar-core/src/test/java/org/sonar/core/user/UserDaoTest.java index b6665245efe..a91acd2bd66 100644 --- a/sonar-core/src/test/java/org/sonar/core/user/UserDaoTest.java +++ b/sonar-core/src/test/java/org/sonar/core/user/UserDaoTest.java @@ -102,6 +102,26 @@ public class UserDaoTest extends AbstractDaoTestCase { } @Test + public void selectUsersByQuery_search_by_login_text() throws Exception { + setupData("selectUsersByText"); + + UserQuery query = UserQuery.builder().searchText("sbr").build(); + List<UserDto> users = dao.selectUsers(query); + assertThat(users).hasSize(1); + assertThat(users.get(0).getLogin()).isEqualTo("sbrandhof"); + } + + @Test + public void selectUsersByQuery_search_by_name_text() throws Exception { + setupData("selectUsersByText"); + + UserQuery query = UserQuery.builder().searchText("Simon").build(); + List<UserDto> users = dao.selectUsers(query); + assertThat(users).hasSize(1); + assertThat(users.get(0).getLogin()).isEqualTo("sbrandhof"); + } + + @Test public void selectGroupByName() { setupData("selectGroupByName"); diff --git a/sonar-core/src/test/resources/org/sonar/core/user/UserDaoTest/selectUsersByText.xml b/sonar-core/src/test/resources/org/sonar/core/user/UserDaoTest/selectUsersByText.xml new file mode 100644 index 00000000000..4eb95dae80f --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/user/UserDaoTest/selectUsersByText.xml @@ -0,0 +1,24 @@ +<!-- + ~ SonarQube, open source software quality management tool. + ~ Copyright (C) 2008-2013 SonarSource + ~ mailto:contact AT sonarsource DOT com + ~ + ~ SonarQube is free software; you can redistribute it and/or + ~ modify it under the terms of the GNU Lesser General Public + ~ License as published by the Free Software Foundation; either + ~ version 3 of the License, or (at your option) any later version. + ~ + ~ SonarQube is distributed in the hope that it will be useful, + ~ but WITHOUT ANY WARRANTY; without even the implied warranty of + ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + ~ Lesser General Public License for more details. + ~ + ~ You should have received a copy of the GNU Lesser General Public License + ~ along with this program; if not, write to the Free Software Foundation, + ~ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + --> +<dataset> + <users id="101" login="marius" name="Marius" email="marius@lesbronzes.fr" created_at="2011-05-18" updated_at="2012-07-21" active="[true]"/> + <users id="102" login="sbrandhof" name="Simon Brandhof" email="marius@lesbronzes.fr" created_at="2011-05-18" updated_at="2012-07-21" active="[true]"/> + +</dataset> diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/RubyIssueService.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/RubyIssueService.java index 6f5d6f6a573..61d7ec2bfa2 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/RubyIssueService.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/RubyIssueService.java @@ -33,6 +33,8 @@ import java.util.Map; */ public interface RubyIssueService extends ServerComponent { + IssueQueryResult find(String issueKey); + /** * Search for issues. * <p/> diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/user/RubyUserService.java b/sonar-plugin-api/src/main/java/org/sonar/api/user/RubyUserService.java index a1e7180a453..cb46f2fa95c 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/user/RubyUserService.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/user/RubyUserService.java @@ -38,6 +38,7 @@ public interface RubyUserService extends ServerComponent { * <p/> * Optional parameters are: * <ul> + * <li><code>q</code> to match all the logins or names containing this search query</li> * <li><code>logins</code>, as an array of strings (['simon', 'julien']) or a comma-separated list of logins ('simon,julien')</li> * <li><code>includeDeactivated</code> as a boolean. By Default deactivated users are excluded from query.</li> * </ul> diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/user/UserQuery.java b/sonar-plugin-api/src/main/java/org/sonar/api/user/UserQuery.java index d4c84c728b4..027be9f5e60 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/user/UserQuery.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/user/UserQuery.java @@ -19,6 +19,8 @@ */ package org.sonar.api.user; +import org.apache.commons.lang.StringUtils; + import javax.annotation.CheckForNull; import javax.annotation.Nullable; import java.util.Arrays; @@ -33,10 +35,16 @@ public class UserQuery { private final Collection<String> logins; private final boolean includeDeactivated; + private final String searchText; + + // for internal use in MyBatis + final String searchTextSql; private UserQuery(Builder builder) { this.logins = builder.logins; this.includeDeactivated = builder.includeDeactivated; + this.searchText = builder.searchText; + this.searchTextSql = (searchText !=null ? "%" + searchText + "%" : null); } @CheckForNull @@ -48,6 +56,14 @@ public class UserQuery { return includeDeactivated; } + /** + * Search for logins or names containing a given string + */ + @CheckForNull + public String searchText() { + return searchText; + } + public static Builder builder() { return new Builder(); } @@ -55,6 +71,7 @@ public class UserQuery { public static class Builder { private boolean includeDeactivated = false; private Collection<String> logins; + private String searchText; private Builder() { } @@ -75,6 +92,11 @@ public class UserQuery { return this; } + public Builder searchText(@Nullable String s) { + this.searchText = StringUtils.defaultIfBlank(s, null); + return this; + } + public UserQuery build() { if (logins != null && logins.size() >= 1000) { throw new IllegalArgumentException("Max number of logins is 1000. Got " + logins.size()); diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/user/UserQueryTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/user/UserQueryTest.java index e6dbc92a126..3cbc5822f1c 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/user/UserQueryTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/user/UserQueryTest.java @@ -33,6 +33,8 @@ public class UserQueryTest { public void test_all_actives() throws Exception { assertThat(UserQuery.ALL_ACTIVES.includeDeactivated()).isFalse(); assertThat(UserQuery.ALL_ACTIVES.logins()).isNull(); + assertThat(UserQuery.ALL_ACTIVES.searchText()).isNull(); + assertThat(UserQuery.ALL_ACTIVES.searchTextSql).isNull(); } @Test @@ -65,4 +67,11 @@ public class UserQueryTest { assertThat(e).hasMessage("Max number of logins is 1000. Got 1010"); } } + + @Test + public void test_searchText() throws Exception { + UserQuery query = UserQuery.builder().searchText("sim").build(); + assertThat(query.searchText()).isEqualTo("sim"); + assertThat(query.searchTextSql).isEqualTo("%sim%"); + } } diff --git a/sonar-server/src/main/java/org/sonar/server/user/DefaultRubyUserService.java b/sonar-server/src/main/java/org/sonar/server/user/DefaultRubyUserService.java index db042c5a8d5..d561d7230a5 100644 --- a/sonar-server/src/main/java/org/sonar/server/user/DefaultRubyUserService.java +++ b/sonar-server/src/main/java/org/sonar/server/user/DefaultRubyUserService.java @@ -52,6 +52,7 @@ public class DefaultRubyUserService implements RubyUserService { builder.includeDeactivated(); } builder.logins(RubyUtils.toStrings(params.get("logins"))); + builder.searchText((String)params.get("q")); return builder.build(); } } diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/users_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/users_controller.rb index 4adc531cb4f..76f73e5b9d3 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/users_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/users_controller.rb @@ -29,9 +29,17 @@ class Api::UsersController < Api::ApiController # def search users = Api.users.find(params) - hash = { - :users => users.map { |user| User.to_hash(user) } - } + + select2_format=(params[:f]=='s2') + if select2_format + hash = { + :more => false, + :results => users.map { |user| {:id => user.login, :text => "#{user.name} (#{user.login})"} } + } + else + hash = {:users => users.map { |user| User.to_hash(user) }} + end + respond_to do |format| format.json { render :json => jsonp(hash) } diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/user/UserQuery.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/user/UserQuery.java index 49de3a8e506..07f802fb8a9 100644 --- a/sonar-ws-client/src/main/java/org/sonar/wsclient/user/UserQuery.java +++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/user/UserQuery.java @@ -21,6 +21,7 @@ package org.sonar.wsclient.user; import org.sonar.wsclient.internal.EncodingUtils; +import javax.annotation.Nullable; import java.util.HashMap; import java.util.Map; @@ -49,6 +50,15 @@ public class UserQuery { return this; } + public UserQuery searchText(@Nullable String s) { + if (s != null) { + params.put("q", s); + } else { + params.remove("q"); + } + return this; + } + Map<String, Object> urlParams() { return params; } diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/user/UserQueryTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/user/UserQueryTest.java index 752f85c1da4..fbb9b4d26a1 100644 --- a/sonar-ws-client/src/test/java/org/sonar/wsclient/user/UserQueryTest.java +++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/user/UserQueryTest.java @@ -48,4 +48,10 @@ public class UserQueryTest { UserQuery query = UserQuery.create().logins("simon").logins("loic"); assertThat(query.urlParams().get("logins")).isEqualTo("loic"); } + + @Test + public void should_search_by_text() throws Exception { + UserQuery query = UserQuery.create().searchText("sim"); + assertThat(query.urlParams().get("q")).isEqualTo("sim"); + } } |