|
|
@@ -20,8 +20,6 @@ |
|
|
|
package org.sonar.server.organization.ws; |
|
|
|
|
|
|
|
import java.util.stream.IntStream; |
|
|
|
import javax.annotation.CheckForNull; |
|
|
|
import javax.annotation.Nullable; |
|
|
|
import org.junit.Rule; |
|
|
|
import org.junit.Test; |
|
|
|
import org.junit.rules.ExpectedException; |
|
|
@@ -35,6 +33,7 @@ import org.sonar.db.permission.OrganizationPermission; |
|
|
|
import org.sonar.db.user.GroupDto; |
|
|
|
import org.sonar.db.user.UserDto; |
|
|
|
import org.sonar.server.es.EsTester; |
|
|
|
import org.sonar.server.exceptions.ForbiddenException; |
|
|
|
import org.sonar.server.exceptions.NotFoundException; |
|
|
|
import org.sonar.server.issue.ws.AvatarResolverImpl; |
|
|
|
import org.sonar.server.organization.DefaultOrganizationProvider; |
|
|
@@ -42,15 +41,15 @@ import org.sonar.server.organization.TestDefaultOrganizationProvider; |
|
|
|
import org.sonar.server.tester.UserSessionRule; |
|
|
|
import org.sonar.server.user.index.UserIndex; |
|
|
|
import org.sonar.server.user.index.UserIndexer; |
|
|
|
import org.sonar.server.ws.TestRequest; |
|
|
|
import org.sonar.server.ws.WsActionTester; |
|
|
|
import org.sonarqube.ws.Common.Paging; |
|
|
|
import org.sonarqube.ws.Organizations.SearchMembersWsResponse; |
|
|
|
import org.sonarqube.ws.Organizations.User; |
|
|
|
|
|
|
|
import static java.lang.String.format; |
|
|
|
import static org.assertj.core.api.Assertions.assertThat; |
|
|
|
import static org.assertj.core.api.Assertions.tuple; |
|
|
|
import static org.sonar.core.util.Protobuf.setNullable; |
|
|
|
import static org.sonar.api.server.ws.WebService.SelectionMode.DESELECTED; |
|
|
|
import static org.sonar.test.JsonAssert.assertJson; |
|
|
|
|
|
|
|
public class SearchMembersActionTest { |
|
|
@@ -69,13 +68,17 @@ public class SearchMembersActionTest { |
|
|
|
private DefaultOrganizationProvider organizationProvider = TestDefaultOrganizationProvider.from(db); |
|
|
|
private UserIndexer indexer = new UserIndexer(dbClient, es.client()); |
|
|
|
|
|
|
|
private WsActionTester ws = new WsActionTester(new SearchMembersAction(dbClient, new UserIndex(es.client(), System2.INSTANCE), organizationProvider, userSession, new AvatarResolverImpl())); |
|
|
|
|
|
|
|
private SearchMembersRequest request = new SearchMembersRequest(); |
|
|
|
private WsActionTester ws = new WsActionTester( |
|
|
|
new SearchMembersAction(dbClient, new UserIndex(es.client(), System2.INSTANCE), organizationProvider, userSession, new AvatarResolverImpl())); |
|
|
|
|
|
|
|
@Test |
|
|
|
public void empty_response() { |
|
|
|
SearchMembersWsResponse result = call(); |
|
|
|
OrganizationDto organization = db.organizations().insert(); |
|
|
|
logAsOrganizationMember(organization); |
|
|
|
|
|
|
|
SearchMembersWsResponse result = ws.newRequest() |
|
|
|
.setParam("organization", organization.getKey()) |
|
|
|
.executeProtobuf(SearchMembersWsResponse.class); |
|
|
|
|
|
|
|
assertThat(result.getUsersList()).isEmpty(); |
|
|
|
assertThat(result.getPaging()) |
|
|
@@ -85,13 +88,17 @@ public class SearchMembersActionTest { |
|
|
|
|
|
|
|
@Test |
|
|
|
public void search_members_of_default_organization() { |
|
|
|
OrganizationDto defaultOrganization = db.getDefaultOrganization(); |
|
|
|
logAsOrganizationMember(defaultOrganization); |
|
|
|
UserDto user = db.users().insertUser(); |
|
|
|
db.organizations().addMember(db.getDefaultOrganization(), user); |
|
|
|
db.organizations().addMember(defaultOrganization, user); |
|
|
|
UserDto anotherUser = db.users().insertUser(); |
|
|
|
db.organizations().addMember(db.getDefaultOrganization(), anotherUser); |
|
|
|
db.organizations().addMember(defaultOrganization, anotherUser); |
|
|
|
indexAllUsers(); |
|
|
|
|
|
|
|
SearchMembersWsResponse result = call(); |
|
|
|
SearchMembersWsResponse result = ws.newRequest() |
|
|
|
.setParam("organization", defaultOrganization.getKey()) |
|
|
|
.executeProtobuf(SearchMembersWsResponse.class); |
|
|
|
|
|
|
|
assertThat(result.getUsersList()) |
|
|
|
.extracting(User::getLogin, User::getName) |
|
|
@@ -103,17 +110,18 @@ public class SearchMembersActionTest { |
|
|
|
@Test |
|
|
|
public void search_members_of_specified_organization() { |
|
|
|
OrganizationDto organization = db.organizations().insert(); |
|
|
|
logAsOrganizationMember(organization); |
|
|
|
OrganizationDto anotherOrganization = db.organizations().insert(); |
|
|
|
UserDto user = db.users().insertUser(); |
|
|
|
UserDto anotherUser = db.users().insertUser(); |
|
|
|
UserDto userInAnotherOrganization = db.users().insertUser(); |
|
|
|
db.organizations().addMember(organization, user); |
|
|
|
db.organizations().addMember(organization, anotherUser); |
|
|
|
db.organizations().addMember(organization, user, anotherUser); |
|
|
|
db.organizations().addMember(anotherOrganization, userInAnotherOrganization); |
|
|
|
indexAllUsers(); |
|
|
|
request.setOrganization(organization.getKey()); |
|
|
|
|
|
|
|
SearchMembersWsResponse result = call(); |
|
|
|
SearchMembersWsResponse result = ws.newRequest() |
|
|
|
.setParam("organization", organization.getKey()) |
|
|
|
.executeProtobuf(SearchMembersWsResponse.class); |
|
|
|
|
|
|
|
assertThat(result.getUsersList()) |
|
|
|
.extracting(User::getLogin, User::getName) |
|
|
@@ -124,81 +132,106 @@ public class SearchMembersActionTest { |
|
|
|
|
|
|
|
@Test |
|
|
|
public void return_avatar() { |
|
|
|
OrganizationDto organization = db.organizations().insert(); |
|
|
|
logAsOrganizationMember(organization); |
|
|
|
UserDto user = db.users().insertUser(u -> u.setEmail("email@domain.com")); |
|
|
|
db.organizations().addMember(db.getDefaultOrganization(), user); |
|
|
|
db.organizations().addMember(organization, user); |
|
|
|
indexer.commitAndIndex(db.getSession(), user); |
|
|
|
|
|
|
|
SearchMembersWsResponse result = call(); |
|
|
|
SearchMembersWsResponse result = ws.newRequest() |
|
|
|
.setParam("organization", organization.getKey()) |
|
|
|
.executeProtobuf(SearchMembersWsResponse.class); |
|
|
|
|
|
|
|
assertThat(result.getUsers(0).getAvatar()).isEqualTo("7328fddefd53de471baeb6e2b764f78a"); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void do_not_return_group_count_if_no_admin_permission() { |
|
|
|
OrganizationDto organization = db.organizations().insert(); |
|
|
|
logAsOrganizationMember(organization); |
|
|
|
UserDto user = db.users().insertUser(); |
|
|
|
db.organizations().addMember(db.getDefaultOrganization(), user); |
|
|
|
db.organizations().addMember(organization, user); |
|
|
|
GroupDto group = db.users().insertGroup(); |
|
|
|
db.users().insertMember(group, user); |
|
|
|
indexAllUsers(); |
|
|
|
|
|
|
|
SearchMembersWsResponse result = call(); |
|
|
|
SearchMembersWsResponse result = ws.newRequest() |
|
|
|
.setParam("organization", organization.getKey()) |
|
|
|
.executeProtobuf(SearchMembersWsResponse.class); |
|
|
|
|
|
|
|
assertThat(result.getUsers(0).hasGroupCount()).isFalse(); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void return_group_counts_if_org_admin() { |
|
|
|
userSession.addPermission(OrganizationPermission.ADMINISTER, db.getDefaultOrganization()); |
|
|
|
OrganizationDto organization = db.organizations().insert(); |
|
|
|
UserDto currentUser = db.users().insertUser(); |
|
|
|
userSession.logIn(currentUser) |
|
|
|
.addPermission(OrganizationPermission.ADMINISTER, organization) |
|
|
|
.addMembership(organization); |
|
|
|
UserDto user = db.users().insertUser(); |
|
|
|
db.organizations().addMember(db.getDefaultOrganization(), user); |
|
|
|
db.organizations().addMember(organization, user); |
|
|
|
UserDto anotherUser = db.users().insertUser(); |
|
|
|
db.organizations().addMember(db.getDefaultOrganization(), anotherUser); |
|
|
|
db.organizations().addMember(organization, anotherUser); |
|
|
|
IntStream.range(0, 10) |
|
|
|
.mapToObj(i -> db.users().insertGroup()) |
|
|
|
.mapToObj(i -> db.users().insertGroup(organization)) |
|
|
|
.forEach(g -> db.users().insertMembers(g, user)); |
|
|
|
OrganizationDto anotherOrganization = db.organizations().insert(); |
|
|
|
GroupDto anotherGroup = db.users().insertGroup(anotherOrganization); |
|
|
|
db.users().insertMember(anotherGroup, user); |
|
|
|
indexAllUsers(); |
|
|
|
|
|
|
|
SearchMembersWsResponse result = call(); |
|
|
|
SearchMembersWsResponse result = ws.newRequest() |
|
|
|
.setParam("organization", organization.getKey()) |
|
|
|
.executeProtobuf(SearchMembersWsResponse.class); |
|
|
|
|
|
|
|
assertThat(result.getUsersList()).extracting(User::getLogin, User::getGroupCount).containsOnly( |
|
|
|
tuple(user.getLogin(), 10), |
|
|
|
tuple(anotherUser.getLogin(), 0)); |
|
|
|
assertThat(result.getUsersList()).extracting(User::getLogin, User::getGroupCount, User::hasGroupCount) |
|
|
|
.containsExactlyInAnyOrder( |
|
|
|
tuple(user.getLogin(), 10, true), |
|
|
|
tuple(anotherUser.getLogin(), 0, true)); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void search_non_members() { |
|
|
|
OrganizationDto anotherOrganization = db.organizations().insert(); |
|
|
|
UserDto user = db.users().insertUser(); |
|
|
|
OrganizationDto organization = db.organizations().insert(); |
|
|
|
UserDto currentUser = db.users().insertUser(); |
|
|
|
userSession.logIn(currentUser).addMembership(organization); |
|
|
|
UserDto anotherUser = db.users().insertUser(); |
|
|
|
db.organizations().addMember(organization, currentUser, anotherUser); |
|
|
|
|
|
|
|
OrganizationDto anotherOrganization = db.organizations().insert(); |
|
|
|
UserDto userInNoOrganization = db.users().insertUser(); |
|
|
|
UserDto userInAnotherOrganization = db.users().insertUser(); |
|
|
|
db.organizations().addMember(anotherOrganization, userInAnotherOrganization); |
|
|
|
indexAllUsers(); |
|
|
|
request |
|
|
|
.setOrganization(anotherOrganization.getKey()) |
|
|
|
.setSelected(WebService.SelectionMode.DESELECTED.value()); |
|
|
|
|
|
|
|
SearchMembersWsResponse result = call(); |
|
|
|
SearchMembersWsResponse result = ws.newRequest() |
|
|
|
.setParam("organization", organization.getKey()) |
|
|
|
.setParam("selected", DESELECTED.value()) |
|
|
|
.executeProtobuf(SearchMembersWsResponse.class); |
|
|
|
|
|
|
|
assertThat(result.getUsersList()) |
|
|
|
.extracting(User::getLogin, User::getName) |
|
|
|
.containsOnly( |
|
|
|
tuple(user.getLogin(), user.getName()), |
|
|
|
tuple(anotherUser.getLogin(), anotherUser.getName())); |
|
|
|
tuple(userInNoOrganization.getLogin(), userInNoOrganization.getName()), |
|
|
|
tuple(userInAnotherOrganization.getLogin(), userInAnotherOrganization.getName())); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void search_members_pagination() { |
|
|
|
OrganizationDto organization = db.organizations().insert(); |
|
|
|
logAsOrganizationMember(organization); |
|
|
|
IntStream.range(0, 10).forEach(i -> { |
|
|
|
UserDto userDto = db.users().insertUser(user -> user.setName("USER_" + i)); |
|
|
|
db.organizations().addMember(db.getDefaultOrganization(), userDto); |
|
|
|
db.organizations().addMember(organization, userDto); |
|
|
|
}); |
|
|
|
indexAllUsers(); |
|
|
|
request.setPage(2).setPageSize(3); |
|
|
|
|
|
|
|
SearchMembersWsResponse result = call(); |
|
|
|
SearchMembersWsResponse result = ws.newRequest() |
|
|
|
.setParam("organization", organization.getKey()) |
|
|
|
.setParam("p", "2") |
|
|
|
.setParam("ps", "3") |
|
|
|
.executeProtobuf(SearchMembersWsResponse.class); |
|
|
|
|
|
|
|
assertThat(result.getUsersList()).extracting(User::getName) |
|
|
|
.containsExactly("USER_3", "USER_4", "USER_5"); |
|
|
@@ -209,87 +242,101 @@ public class SearchMembersActionTest { |
|
|
|
|
|
|
|
@Test |
|
|
|
public void search_members_by_name() { |
|
|
|
OrganizationDto organization = db.organizations().insert(); |
|
|
|
logAsOrganizationMember(organization); |
|
|
|
IntStream.range(0, 10).forEach(i -> { |
|
|
|
UserDto userDto = db.users().insertUser(user -> user.setName("USER_" + i)); |
|
|
|
db.organizations().addMember(db.getDefaultOrganization(), userDto); |
|
|
|
db.organizations().addMember(organization, userDto); |
|
|
|
}); |
|
|
|
indexAllUsers(); |
|
|
|
request.setQuery("_9"); |
|
|
|
|
|
|
|
SearchMembersWsResponse result = call(); |
|
|
|
SearchMembersWsResponse result = ws.newRequest() |
|
|
|
.setParam("organization", organization.getKey()) |
|
|
|
.setParam("q", "_9") |
|
|
|
.executeProtobuf(SearchMembersWsResponse.class); |
|
|
|
|
|
|
|
assertThat(result.getUsersList()).extracting(User::getName).containsExactly("USER_9"); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void search_members_by_login() { |
|
|
|
OrganizationDto organization = db.organizations().insert(); |
|
|
|
logAsOrganizationMember(organization); |
|
|
|
IntStream.range(0, 10).forEach(i -> { |
|
|
|
UserDto userDto = db.users().insertUser(user -> user.setLogin("USER_" + i)); |
|
|
|
db.organizations().addMember(db.getDefaultOrganization(), userDto); |
|
|
|
db.organizations().addMember(organization, userDto); |
|
|
|
}); |
|
|
|
indexAllUsers(); |
|
|
|
request.setQuery("_9"); |
|
|
|
|
|
|
|
SearchMembersWsResponse result = call(); |
|
|
|
SearchMembersWsResponse result = ws.newRequest() |
|
|
|
.setParam("organization", organization.getKey()) |
|
|
|
.setParam("q", "_9") |
|
|
|
.executeProtobuf(SearchMembersWsResponse.class); |
|
|
|
|
|
|
|
assertThat(result.getUsersList()).extracting(User::getLogin).containsExactly("USER_9"); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void search_members_by_email() { |
|
|
|
OrganizationDto organization = db.organizations().insert(); |
|
|
|
logAsOrganizationMember(organization); |
|
|
|
IntStream.range(0, 10).forEach(i -> { |
|
|
|
UserDto userDto = db.users().insertUser(user -> user |
|
|
|
.setLogin("L" + i) |
|
|
|
.setEmail("USER_" + i + "@email.com")); |
|
|
|
db.organizations().addMember(db.getDefaultOrganization(), userDto); |
|
|
|
db.organizations().addMember(organization, userDto); |
|
|
|
}); |
|
|
|
indexAllUsers(); |
|
|
|
request.setQuery("_9"); |
|
|
|
|
|
|
|
SearchMembersWsResponse result = call(); |
|
|
|
SearchMembersWsResponse result = ws.newRequest() |
|
|
|
.setParam("organization", organization.getKey()) |
|
|
|
.setParam("q", "_9") |
|
|
|
.executeProtobuf(SearchMembersWsResponse.class); |
|
|
|
|
|
|
|
assertThat(result.getUsersList()).extracting(User::getLogin).containsExactly("L9"); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void fail_if_organization_is_unknown() { |
|
|
|
request.setOrganization("ORGA 42"); |
|
|
|
OrganizationDto organization = db.organizations().insert(); |
|
|
|
logAsOrganizationMember(organization); |
|
|
|
|
|
|
|
expectedException.expect(NotFoundException.class); |
|
|
|
expectedException.expectMessage("No organization with key 'ORGA 42'"); |
|
|
|
expectedException.expectMessage("No organization with key 'unknown'"); |
|
|
|
|
|
|
|
call(); |
|
|
|
ws.newRequest() |
|
|
|
.setParam("organization", "unknown") |
|
|
|
.execute(); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void fail_if_page_size_greater_than_500() { |
|
|
|
request.setPageSize(501); |
|
|
|
|
|
|
|
expectedException.expect(IllegalArgumentException.class); |
|
|
|
expectedException.expectMessage("'ps' value (501) must be less than 500"); |
|
|
|
|
|
|
|
call(); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void fail_if_query_length_lower_than_2() { |
|
|
|
request.setQuery("a"); |
|
|
|
public void fail_when_not_member_of_organization() { |
|
|
|
OrganizationDto organization = db.organizations().insert(); |
|
|
|
UserDto user = db.users().insertUser(); |
|
|
|
userSession.logIn(user); |
|
|
|
|
|
|
|
expectedException.expect(IllegalArgumentException.class); |
|
|
|
expectedException.expectMessage("Query length must be greater than or equal to 2"); |
|
|
|
expectedException.expect(ForbiddenException.class); |
|
|
|
expectedException.expectMessage(format("You're not member of organization '%s'", organization.getKey())); |
|
|
|
|
|
|
|
call(); |
|
|
|
ws.newRequest() |
|
|
|
.setParam("organization", organization.getKey()) |
|
|
|
.execute(); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void json_example() { |
|
|
|
OrganizationDto organization = db.organizations().insert(); |
|
|
|
logAsOrganizationMember(organization); |
|
|
|
UserDto user1 = db.users().insertUser(u -> u.setLogin("ada.lovelace").setName("Ada Lovelace").setEmail("ada@lovelace.com")); |
|
|
|
db.organizations().addMember(db.getDefaultOrganization(), user1); |
|
|
|
db.organizations().addMember(organization, user1); |
|
|
|
UserDto user2 = db.users().insertUser(u -> u.setLogin("grace.hopper").setName("Grace Hopper").setEmail("grace@hopper.com")); |
|
|
|
db.organizations().addMember(db.getDefaultOrganization(), user2); |
|
|
|
db.organizations().addMember(organization, user2); |
|
|
|
indexAllUsers(); |
|
|
|
|
|
|
|
String result = ws.newRequest().execute().getInput(); |
|
|
|
String result = ws.newRequest() |
|
|
|
.setParam("organization", organization.getKey()) |
|
|
|
.execute() |
|
|
|
.getInput(); |
|
|
|
|
|
|
|
assertJson(result).isSimilarTo(ws.getDef().responseExampleAsString()); |
|
|
|
} |
|
|
@@ -311,78 +358,17 @@ public class SearchMembersActionTest { |
|
|
|
assertThat(selected.possibleValues()).containsOnly("selected", "deselected"); |
|
|
|
assertThat(selected.isInternal()).isTrue(); |
|
|
|
assertThat(selected.defaultValue()).isEqualTo("selected"); |
|
|
|
|
|
|
|
assertThat(action.param("ps").maximumValue()).isEqualTo(500); |
|
|
|
assertThat(action.param("q").minimumLength()).isEqualTo(2); |
|
|
|
} |
|
|
|
|
|
|
|
private void indexAllUsers() { |
|
|
|
indexer.indexOnStartup(indexer.getIndexTypes()); |
|
|
|
} |
|
|
|
|
|
|
|
private SearchMembersWsResponse call() { |
|
|
|
TestRequest wsRequest = ws.newRequest(); |
|
|
|
setNullable(request.getOrganization(), o -> wsRequest.setParam("organization", o)); |
|
|
|
setNullable(request.getQuery(), q -> wsRequest.setParam(Param.TEXT_QUERY, q)); |
|
|
|
setNullable(request.getPage(), p -> wsRequest.setParam(Param.PAGE, String.valueOf(p))); |
|
|
|
setNullable(request.getPageSize(), ps -> wsRequest.setParam(Param.PAGE_SIZE, String.valueOf(ps))); |
|
|
|
setNullable(request.getSelected(), s -> wsRequest.setParam(Param.SELECTED, s)); |
|
|
|
|
|
|
|
return wsRequest.executeProtobuf(SearchMembersWsResponse.class); |
|
|
|
private void logAsOrganizationMember(OrganizationDto organization) { |
|
|
|
userSession.logIn(db.users().insertUser()).addMembership(organization); |
|
|
|
} |
|
|
|
|
|
|
|
private static class SearchMembersRequest { |
|
|
|
private String organization; |
|
|
|
private String selected; |
|
|
|
private String query; |
|
|
|
private Integer page; |
|
|
|
private Integer pageSize; |
|
|
|
|
|
|
|
@CheckForNull |
|
|
|
public String getOrganization() { |
|
|
|
return organization; |
|
|
|
} |
|
|
|
|
|
|
|
public SearchMembersRequest setOrganization(@Nullable String organization) { |
|
|
|
this.organization = organization; |
|
|
|
return this; |
|
|
|
} |
|
|
|
|
|
|
|
@CheckForNull |
|
|
|
public String getSelected() { |
|
|
|
return selected; |
|
|
|
} |
|
|
|
|
|
|
|
public SearchMembersRequest setSelected(@Nullable String selected) { |
|
|
|
this.selected = selected; |
|
|
|
return this; |
|
|
|
} |
|
|
|
|
|
|
|
@CheckForNull |
|
|
|
public String getQuery() { |
|
|
|
return query; |
|
|
|
} |
|
|
|
|
|
|
|
public SearchMembersRequest setQuery(@Nullable String query) { |
|
|
|
this.query = query; |
|
|
|
return this; |
|
|
|
} |
|
|
|
|
|
|
|
@CheckForNull |
|
|
|
public Integer getPage() { |
|
|
|
return page; |
|
|
|
} |
|
|
|
|
|
|
|
public SearchMembersRequest setPage(@Nullable Integer page) { |
|
|
|
this.page = page; |
|
|
|
return this; |
|
|
|
} |
|
|
|
|
|
|
|
@CheckForNull |
|
|
|
public Integer getPageSize() { |
|
|
|
return pageSize; |
|
|
|
} |
|
|
|
|
|
|
|
public SearchMembersRequest setPageSize(@Nullable Integer pageSize) { |
|
|
|
this.pageSize = pageSize; |
|
|
|
return this; |
|
|
|
} |
|
|
|
} |
|
|
|
} |