From 18adf3c20edfe6afeef63886635a6eb1092ed39d Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Lesaint?= Date: Thu, 19 Dec 2019 14:03:56 +0100 Subject: [PATCH] SONAR-12720 user list in response of api/hotspots/show the list contains users of comments and changelog entries, as well as author and assignee --- .../sonar/server/hotspot/ws/ShowAction.java | 37 ++++-- .../server/issue/IssueChangeWSSupport.java | 7 + .../server/hotspot/ws/ShowActionTest.java | 120 +++++++++++++++++- .../issue/IssueChangeWSSupportTest.java | 18 +++ sonar-ws/src/main/protobuf/ws-hotspots.proto | 1 + 5 files changed, 172 insertions(+), 11 deletions(-) diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/ShowAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/ShowAction.java index 2bf315ca165..1ff2504d105 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/ShowAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/ShowAction.java @@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableSet; import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.stream.Stream; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.api.rule.RuleKey; @@ -55,6 +56,7 @@ import static java.lang.String.format; import static java.util.Collections.singleton; import static java.util.Optional.ofNullable; import static org.sonar.api.utils.DateUtils.formatDateTime; +import static org.sonar.core.util.stream.MoreCollectors.toSet; import static org.sonar.server.ws.WsUtils.writeProtobuf; public class ShowAction implements HotspotsWsAction { @@ -107,12 +109,14 @@ public class ShowAction implements HotspotsWsAction { RuleDefinitionDto rule = loadRule(dbSession, hotspot); ShowWsResponse.Builder responseBuilder = ShowWsResponse.newBuilder(); + Common.User.Builder userBuilder = Common.User.newBuilder(); formatHotspot(responseBuilder, hotspot); - formatUsers(responseBuilder, users, hotspot); + formatHotspotAuthorAndAssignee(responseBuilder, userBuilder, users, hotspot); formatComponents(components, responseBuilder); formatRule(responseBuilder, rule); - formatTextRange(hotspot, responseBuilder); - formatChangeLogAndComments(dbSession, hotspot, components, responseBuilder); + formatTextRange(responseBuilder, hotspot); + FormattingContext formattingContext = formatChangeLogAndComments(dbSession, hotspot, users, components, responseBuilder); + formatUsers(responseBuilder, userBuilder, users, formattingContext); writeProtobuf(responseBuilder.build(), request, response); } @@ -143,8 +147,8 @@ public class ShowAction implements HotspotsWsAction { builder.setUpdateDate(formatDateTime(hotspot.getIssueUpdateDate())); } - private void formatUsers(ShowWsResponse.Builder responseBuilder, Users users, IssueDto hotspot) { - Common.User.Builder userBuilder = Common.User.newBuilder(); + private void formatHotspotAuthorAndAssignee(ShowWsResponse.Builder responseBuilder, + Common.User.Builder userBuilder, Users users, IssueDto hotspot) { users.getAssignee().map(t -> userFormatter.formatUser(userBuilder, t)).ifPresent(responseBuilder::setAssignee); Common.User author = users.getAuthor() @@ -174,19 +178,36 @@ public class ShowAction implements HotspotsWsAction { responseBuilder.setRule(ruleBuilder.build()); } - private void formatTextRange(IssueDto hotspot, ShowWsResponse.Builder responseBuilder) { + private void formatTextRange(ShowWsResponse.Builder responseBuilder, IssueDto hotspot) { textRangeFormatter.formatTextRange(hotspot, responseBuilder::setTextRange); } - private void formatChangeLogAndComments(DbSession dbSession, IssueDto hotspot, Components components, ShowWsResponse.Builder responseBuilder) { + private FormattingContext formatChangeLogAndComments(DbSession dbSession, IssueDto hotspot, Users users, Components components, ShowWsResponse.Builder responseBuilder) { + Set preloadedUsers = Stream.of(users.getAssignee(), users.getAuthor()) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(toSet()); Set preloadedComponents = ImmutableSet.of(components.project, components.component); FormattingContext formattingContext = issueChangeSupport - .newFormattingContext(dbSession, singleton(hotspot), Load.ALL, ImmutableSet.of(), preloadedComponents); + .newFormattingContext(dbSession, singleton(hotspot), Load.ALL, preloadedUsers, preloadedComponents); issueChangeSupport.formatChangelog(hotspot, formattingContext) .forEach(responseBuilder::addChangelog); issueChangeSupport.formatComments(hotspot, Common.Comment.newBuilder(), formattingContext) .forEach(responseBuilder::addComment); + + return formattingContext; + } + + private void formatUsers(ShowWsResponse.Builder responseBuilder, Common.User.Builder userBuilder, Users users, FormattingContext formattingContext) { + Stream.concat( + Stream.of(users.getAssignee(), users.getAuthor()) + .filter(Optional::isPresent) + .map(Optional::get), + formattingContext.getUsers().stream()) + .distinct() + .map(user -> userFormatter.formatUser(userBuilder, user)) + .forEach(responseBuilder::addUsers); } private RuleDefinitionDto loadRule(DbSession dbSession, IssueDto hotspot) { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/IssueChangeWSSupport.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/IssueChangeWSSupport.java index 986dc4dcb24..ad2536baa9d 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/IssueChangeWSSupport.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/IssueChangeWSSupport.java @@ -88,6 +88,8 @@ public class IssueChangeWSSupport { List getComments(IssueDto dto); + Set getUsers(); + Optional getUserByUuid(@Nullable String uuid); Optional getFileByUuid(@Nullable String uuid); @@ -328,6 +330,11 @@ public class IssueChangeWSSupport { return ImmutableList.copyOf(comments); } + @Override + public Set getUsers() { + return ImmutableSet.copyOf(usersByUuid.values()); + } + @Override public Optional getUserByUuid(@Nullable String uuid) { if (uuid == null) { diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/hotspot/ws/ShowActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/hotspot/ws/ShowActionTest.java index 1a0b8b61336..2a2f67a2263 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/hotspot/ws/ShowActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/hotspot/ws/ShowActionTest.java @@ -33,6 +33,7 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; import javax.annotation.Nullable; +import org.assertj.core.groups.Tuple; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -54,6 +55,7 @@ import org.sonar.db.protobuf.DbIssues; import org.sonar.db.rule.RuleDefinitionDto; import org.sonar.db.rule.RuleTesting; import org.sonar.db.user.UserDto; +import org.sonar.db.user.UserTesting; import org.sonar.server.es.EsTester; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; @@ -77,6 +79,7 @@ import org.sonarqube.ws.Hotspots; import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.tuple; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anySet; import static org.mockito.ArgumentMatchers.argThat; @@ -178,6 +181,7 @@ public class ShowActionTest { ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT); IssueDto hotspot = dbTester.issues().insertIssue(newHotspot(project, file, rule)); + mockChangelogAndCommentsFormattingContext(); Hotspots.ShowWsResponse response = newRequest(hotspot) .executeProtobuf(Hotspots.ShowWsResponse.class); @@ -193,6 +197,7 @@ public class ShowActionTest { ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT); IssueDto hotspot = dbTester.issues().insertIssue(newHotspot(project, file, rule)); + mockChangelogAndCommentsFormattingContext(); Hotspots.ShowWsResponse response = newRequest(hotspot) .executeProtobuf(Hotspots.ShowWsResponse.class); @@ -209,6 +214,7 @@ public class ShowActionTest { ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT); IssueDto hotspot = dbTester.issues().insertIssue(newHotspot(project, file, rule).setStatus(status).setResolution(resolution)); + mockChangelogAndCommentsFormattingContext(); Hotspots.ShowWsResponse response = newRequest(hotspot) .executeProtobuf(Hotspots.ShowWsResponse.class); @@ -238,6 +244,7 @@ public class ShowActionTest { ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT); IssueDto hotspot = dbTester.issues().insertIssue(newHotspot(project, file, rule)); + mockChangelogAndCommentsFormattingContext(); Hotspots.ShowWsResponse response = newRequest(hotspot) .executeProtobuf(Hotspots.ShowWsResponse.class); @@ -257,6 +264,7 @@ public class ShowActionTest { RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT); IssueDto hotspot = dbTester.issues().insertIssue(newHotspot(project, file, rule) .setLocations(DbIssues.Locations.newBuilder().build())); + mockChangelogAndCommentsFormattingContext(); Hotspots.ShowWsResponse response = newRequest(hotspot) .executeProtobuf(Hotspots.ShowWsResponse.class); @@ -280,9 +288,11 @@ public class ShowActionTest { .setEndOffset(endOffset) .build()) .build())); + mockChangelogAndCommentsFormattingContext(); Hotspots.ShowWsResponse response = newRequest(hotspot) .executeProtobuf(Hotspots.ShowWsResponse.class); + assertThat(response.hasTextRange()).isTrue(); Common.TextRange textRange = response.getTextRange(); assertThat(textRange.getStartLine()).isEqualTo(startLine); @@ -299,6 +309,7 @@ public class ShowActionTest { RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT); IssueDto hotspot = dbTester.issues().insertIssue(newHotspot(project, file, rule) .setAssigneeUuid(randomAlphabetic(10))); + mockChangelogAndCommentsFormattingContext(); Hotspots.ShowWsResponse response = newRequest(hotspot) .executeProtobuf(Hotspots.ShowWsResponse.class); @@ -315,6 +326,7 @@ public class ShowActionTest { UserDto assignee = dbTester.users().insertUser(); IssueDto hotspot = dbTester.issues().insertIssue(newHotspot(project, file, rule) .setAssigneeUuid(assignee.getUuid())); + mockChangelogAndCommentsFormattingContext(); Hotspots.ShowWsResponse response = newRequest(hotspot) .executeProtobuf(Hotspots.ShowWsResponse.class); @@ -335,6 +347,7 @@ public class ShowActionTest { UserDto assignee = dbTester.users().insertUser(t -> t.setEmail(null)); IssueDto hotspot = dbTester.issues().insertIssue(newHotspot(project, file, rule) .setAssigneeUuid(assignee.getUuid())); + mockChangelogAndCommentsFormattingContext(); Hotspots.ShowWsResponse response = newRequest(hotspot) .executeProtobuf(Hotspots.ShowWsResponse.class); @@ -351,11 +364,14 @@ public class ShowActionTest { UserDto assignee = dbTester.users().insertUser(t -> t.setActive(false)); IssueDto hotspot = dbTester.issues().insertIssue(newHotspot(project, file, rule) .setAssigneeUuid(assignee.getUuid())); + mockChangelogAndCommentsFormattingContext(); Hotspots.ShowWsResponse response = newRequest(hotspot) .executeProtobuf(Hotspots.ShowWsResponse.class); assertThat(response.getAssignee().getActive()).isFalse(); + assertThat(response.getUsersList()).hasSize(1); + assertThat(response.getUsersList().iterator().next().getActive()).isFalse(); } @Test @@ -367,6 +383,7 @@ public class ShowActionTest { String authorLogin = randomAlphabetic(10); IssueDto hotspot = dbTester.issues().insertIssue(newHotspot(project, file, rule) .setAuthorLogin(authorLogin)); + mockChangelogAndCommentsFormattingContext(); Hotspots.ShowWsResponse response = newRequest(hotspot) .executeProtobuf(Hotspots.ShowWsResponse.class); @@ -376,6 +393,7 @@ public class ShowActionTest { assertThat(wsAuthor.hasName()).isFalse(); assertThat(wsAuthor.hasActive()).isFalse(); assertThat(wsAuthor.hasAvatar()).isFalse(); + assertThat(response.getUsersList()).isEmpty(); } @Test @@ -387,6 +405,7 @@ public class ShowActionTest { UserDto author = dbTester.users().insertUser(); IssueDto hotspot = dbTester.issues().insertIssue(newHotspot(project, file, rule) .setAuthorLogin(author.getLogin())); + mockChangelogAndCommentsFormattingContext(); Hotspots.ShowWsResponse response = newRequest(hotspot) .executeProtobuf(Hotspots.ShowWsResponse.class); @@ -396,6 +415,12 @@ public class ShowActionTest { assertThat(wsAuthor.getName()).isEqualTo(author.getName()); assertThat(wsAuthor.getActive()).isEqualTo(author.isActive()); assertThat(wsAuthor.getAvatar()).isEqualTo(avatarResolver.create(author)); + assertThat(response.getUsersList()).hasSize(1); + User wsAuthorFromList = response.getUsersList().iterator().next(); + assertThat(wsAuthorFromList.getLogin()).isEqualTo(author.getLogin()); + assertThat(wsAuthorFromList.getName()).isEqualTo(author.getName()); + assertThat(wsAuthorFromList.getActive()).isEqualTo(author.isActive()); + assertThat(wsAuthorFromList.getAvatar()).isEqualTo(avatarResolver.create(author)); } @Test @@ -407,11 +432,14 @@ public class ShowActionTest { UserDto author = dbTester.users().insertUser(t -> t.setEmail(null)); IssueDto hotspot = dbTester.issues().insertIssue(newHotspot(project, file, rule) .setAuthorLogin(author.getLogin())); + mockChangelogAndCommentsFormattingContext(); Hotspots.ShowWsResponse response = newRequest(hotspot) .executeProtobuf(Hotspots.ShowWsResponse.class); assertThat(response.getAuthor().hasAvatar()).isFalse(); + assertThat(response.getUsersList()).hasSize(1); + assertThat(response.getUsersList().iterator().next().hasAvatar()).isFalse(); } @Test @@ -423,6 +451,7 @@ public class ShowActionTest { UserDto author = dbTester.users().insertUser(t -> t.setActive(false)); IssueDto hotspot = dbTester.issues().insertIssue(newHotspot(project, file, rule) .setAuthorLogin(author.getLogin())); + mockChangelogAndCommentsFormattingContext(); Hotspots.ShowWsResponse response = newRequest(hotspot) .executeProtobuf(Hotspots.ShowWsResponse.class); @@ -451,6 +480,7 @@ public class ShowActionTest { .setLocations(DbIssues.Locations.newBuilder() .setTextRange(DbCommons.TextRange.newBuilder().build()) .build())); + mockChangelogAndCommentsFormattingContext(); Hotspots.ShowWsResponse response = newRequest(hotspot) .executeProtobuf(Hotspots.ShowWsResponse.class); @@ -475,6 +505,7 @@ public class ShowActionTest { .setLocations(DbIssues.Locations.newBuilder() .setTextRange(DbCommons.TextRange.newBuilder().build()) .build())); + mockChangelogAndCommentsFormattingContext(); Hotspots.ShowWsResponse response = newRequest(hotspot) .executeProtobuf(Hotspots.ShowWsResponse.class); @@ -509,6 +540,7 @@ public class ShowActionTest { .setLocations(DbIssues.Locations.newBuilder() .setTextRange(DbCommons.TextRange.newBuilder().build()) .build())); + mockChangelogAndCommentsFormattingContext(); Hotspots.ShowWsResponse response = newRequest(hotspot) .executeProtobuf(Hotspots.ShowWsResponse.class); @@ -528,6 +560,7 @@ public class ShowActionTest { .setLocations(DbIssues.Locations.newBuilder() .setTextRange(DbCommons.TextRange.newBuilder().build()) .build())); + mockChangelogAndCommentsFormattingContext(); Hotspots.ShowWsResponse response = newRequest(hotspot) .executeProtobuf(Hotspots.ShowWsResponse.class); @@ -548,6 +581,7 @@ public class ShowActionTest { .setLocations(DbIssues.Locations.newBuilder() .setTextRange(DbCommons.TextRange.newBuilder().build()) .build())); + mockChangelogAndCommentsFormattingContext(); Hotspots.ShowWsResponse response = newRequest(hotspot) .executeProtobuf(Hotspots.ShowWsResponse.class); @@ -566,14 +600,13 @@ public class ShowActionTest { .setLocations(DbIssues.Locations.newBuilder() .setTextRange(DbCommons.TextRange.newBuilder().build()) .build())); - FormattingContext formattingContext = Mockito.mock(FormattingContext.class); List changelog = IntStream.range(0, 1 + new Random().nextInt(12)) .mapToObj(i -> Common.Changelog.newBuilder().setUser("u" + i).build()) .collect(Collectors.toList()); List comments = IntStream.range(0, 1 + new Random().nextInt(12)) .mapToObj(i -> Common.Comment.newBuilder().setKey("u" + i).build()) .collect(Collectors.toList()); - when(issueChangeSupport.newFormattingContext(any(), any(), any(), anySet(), anySet())).thenReturn(formattingContext); + FormattingContext formattingContext = mockChangelogAndCommentsFormattingContext(); when(issueChangeSupport.formatChangelog(any(), any())).thenReturn(changelog.stream()); when(issueChangeSupport.formatComments(any(), any(), any())).thenReturn(comments.stream()); @@ -594,7 +627,88 @@ public class ShowActionTest { verify(issueChangeSupport).formatComments(argThat(new IssueDtoArgumentMatcher(hotspot)), any(Common.Comment.Builder.class), eq(formattingContext)); } - public void verifyRule(Hotspots.Rule wsRule, RuleDefinitionDto dto) { + @Test + public void returns_user_details_of_users_from_ChangelogAndComments() { + ComponentDto project = dbTester.components().insertPublicProject(); + userSessionRule.registerComponents(project); + RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT); + ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); + IssueDto hotspot = dbTester.issues().insertIssue(newHotspot(project, file, rule)); + FormattingContext formattingContext = mockChangelogAndCommentsFormattingContext(); + Set changeLogAndCommentsUsers = IntStream.range(0, 1 + RANDOM.nextInt(14)) + .mapToObj(i -> UserTesting.newUserDto()) + .collect(Collectors.toSet()); + when(formattingContext.getUsers()).thenReturn(changeLogAndCommentsUsers); + + Hotspots.ShowWsResponse response = newRequest(hotspot) + .executeProtobuf(Hotspots.ShowWsResponse.class); + + assertThat(response.getUsersList()) + .extracting(User::getLogin, User::getName, User::getActive) + .containsExactlyInAnyOrder( + changeLogAndCommentsUsers.stream() + .map(t -> tuple(t.getLogin(), t.getName(), t.isActive())) + .toArray(Tuple[]::new)); + } + + @Test + public void returns_user_of_users_from_ChangelogAndComments_and_assignee_and_author() { + ComponentDto project = dbTester.components().insertPublicProject(); + userSessionRule.registerComponents(project); + RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT); + ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); + UserDto author = dbTester.users().insertUser(); + UserDto assignee = dbTester.users().insertUser(); + IssueDto hotspot = dbTester.issues().insertIssue(newHotspot(project, file, rule) + .setAuthorLogin(author.getLogin()) + .setAssigneeUuid(assignee.getUuid())); + FormattingContext formattingContext = mockChangelogAndCommentsFormattingContext(); + Set changeLogAndCommentsUsers = IntStream.range(0, 1 + RANDOM.nextInt(14)) + .mapToObj(i -> UserTesting.newUserDto()) + .collect(Collectors.toSet()); + when(formattingContext.getUsers()).thenReturn(changeLogAndCommentsUsers); + + Hotspots.ShowWsResponse response = newRequest(hotspot) + .executeProtobuf(Hotspots.ShowWsResponse.class); + + assertThat(response.getUsersList()) + .extracting(User::getLogin, User::getName, User::getActive) + .containsExactlyInAnyOrder( + Stream.concat( + Stream.of(author, assignee), + changeLogAndCommentsUsers.stream()) + .map(t -> tuple(t.getLogin(), t.getName(), t.isActive())) + .toArray(Tuple[]::new)); + } + + @Test + public void do_not_duplicate_user_if_author_assignee_ChangeLogComment_user() { + ComponentDto project = dbTester.components().insertPublicProject(); + userSessionRule.registerComponents(project); + RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT); + ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); + UserDto author = dbTester.users().insertUser(); + IssueDto hotspot = dbTester.issues().insertIssue(newHotspot(project, file, rule) + .setAuthorLogin(author.getLogin()) + .setAssigneeUuid(author.getUuid())); + FormattingContext formattingContext = mockChangelogAndCommentsFormattingContext(); + when(formattingContext.getUsers()).thenReturn(ImmutableSet.of(author)); + + Hotspots.ShowWsResponse response = newRequest(hotspot) + .executeProtobuf(Hotspots.ShowWsResponse.class); + + assertThat(response.getUsersList()) + .extracting(User::getLogin, User::getName, User::getActive) + .containsOnly(tuple(author.getLogin(), author.getName(), author.isActive())); + } + + private FormattingContext mockChangelogAndCommentsFormattingContext() { + FormattingContext formattingContext = Mockito.mock(FormattingContext.class); + when(issueChangeSupport.newFormattingContext(any(), any(), any(), anySet(), anySet())).thenReturn(formattingContext); + return formattingContext; + } + + private void verifyRule(Hotspots.Rule wsRule, RuleDefinitionDto dto) { assertThat(wsRule.getKey()).isEqualTo(dto.getKey().toString()); assertThat(wsRule.getName()).isEqualTo(dto.getName()); assertThat(wsRule.getSecurityCategory()).isEqualTo(SQCategory.OTHERS.getKey()); diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/IssueChangeWSSupportTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/IssueChangeWSSupportTest.java index eafb637a3b3..c9b99c2e3ab 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/IssueChangeWSSupportTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/IssueChangeWSSupportTest.java @@ -166,6 +166,9 @@ public class IssueChangeWSSupportTest { FormattingContext formattingContext = underTest.newFormattingContext(dbTester.getSession(), singleton(issue), Load.CHANGE_LOG); + assertThat(formattingContext.getUsers()) + .extracting(UserDto::getUuid) + .containsExactlyInAnyOrder(user1.getUuid(), user2.getUuid()); assertThat(formattingContext.getUserByUuid(user1.getUuid())).isNotEmpty(); assertThat(formattingContext.getUserByUuid(user2.getUuid())).isNotEmpty(); assertThat(formattingContext.getUserByUuid(user3.getUuid())).isEmpty(); @@ -187,6 +190,9 @@ public class IssueChangeWSSupportTest { FormattingContext formattingContext = underTest.newFormattingContext(dbTester.getSession(), singleton(issue), Load.COMMENTS); + assertThat(formattingContext.getUsers()) + .extracting(UserDto::getUuid) + .containsExactlyInAnyOrder(user1.getUuid(), user2.getUuid()); assertThat(formattingContext.getUserByUuid(user1.getUuid())).isNotEmpty(); assertThat(formattingContext.getUserByUuid(user2.getUuid())).isNotEmpty(); assertThat(formattingContext.getUserByUuid(user3.getUuid())).isEmpty(); @@ -219,6 +225,9 @@ public class IssueChangeWSSupportTest { FormattingContext formattingContext = underTest.newFormattingContext(dbTester.getSession(), singleton(issue), Load.ALL); + assertThat(formattingContext.getUsers()) + .extracting(UserDto::getUuid) + .containsExactlyInAnyOrder(user1.getUuid(), user2.getUuid(), user4.getUuid()); assertThat(formattingContext.getUserByUuid(user1.getUuid())).isNotEmpty(); assertThat(formattingContext.getUserByUuid(user2.getUuid())).isNotEmpty(); assertThat(formattingContext.getUserByUuid(user3.getUuid())).isEmpty(); @@ -294,6 +303,9 @@ public class IssueChangeWSSupportTest { // no users are preloaded FormattingContext formattingContext = underTest.newFormattingContext(dbTester.getSession(), singleton(issue), Load.ALL, emptySet(), emptySet()); + assertThat(formattingContext.getUsers()) + .extracting(UserDto::getUuid) + .containsExactlyInAnyOrder(user1.getUuid(), user2.getUuid(), user3.getUuid(), user4.getUuid()); assertThat(formattingContext.getUserByUuid(user1.getUuid()).get().getEmail()).isNotEqualTo(user1.getEmail()); assertThat(formattingContext.getUserByUuid(user2.getUuid()).get().getEmail()).isNotEqualTo(user2.getEmail()); assertThat(formattingContext.getUserByUuid(user3.getUuid()).get().getEmail()).isNotEqualTo(user3.getEmail()); @@ -302,6 +314,9 @@ public class IssueChangeWSSupportTest { // some users are preloaded formattingContext = underTest.newFormattingContext(dbTester.getSession(), singleton(issue), Load.ALL, ImmutableSet.of(user1, user4), emptySet()); + assertThat(formattingContext.getUsers()) + .extracting(UserDto::getUuid) + .containsExactlyInAnyOrder(user1.getUuid(), user2.getUuid(), user3.getUuid(), user4.getUuid()); assertThat(formattingContext.getUserByUuid(user1.getUuid()).get().getEmail()).isEqualTo(user1.getEmail()); assertThat(formattingContext.getUserByUuid(user2.getUuid()).get().getEmail()).isNotEqualTo(user2.getEmail()); assertThat(formattingContext.getUserByUuid(user3.getUuid()).get().getEmail()).isNotEqualTo(user3.getEmail()); @@ -310,6 +325,9 @@ public class IssueChangeWSSupportTest { // all users are preloaded formattingContext = underTest.newFormattingContext(dbTester.getSession(), singleton(issue), Load.ALL, ImmutableSet.of(user1, user2, user3, user4), emptySet()); + assertThat(formattingContext.getUsers()) + .extracting(UserDto::getUuid) + .containsExactlyInAnyOrder(user1.getUuid(), user2.getUuid(), user3.getUuid(), user4.getUuid()); assertThat(formattingContext.getUserByUuid(user1.getUuid()).get().getEmail()).isEqualTo(user1.getEmail()); assertThat(formattingContext.getUserByUuid(user2.getUuid()).get().getEmail()).isEqualTo(user2.getEmail()); assertThat(formattingContext.getUserByUuid(user3.getUuid()).get().getEmail()).isEqualTo(user3.getEmail()); diff --git a/sonar-ws/src/main/protobuf/ws-hotspots.proto b/sonar-ws/src/main/protobuf/ws-hotspots.proto index 51c3133b0ec..66ea284f4a9 100644 --- a/sonar-ws/src/main/protobuf/ws-hotspots.proto +++ b/sonar-ws/src/main/protobuf/ws-hotspots.proto @@ -66,6 +66,7 @@ message ShowWsResponse { optional sonarqube.ws.commons.TextRange textRange = 13; repeated sonarqube.ws.commons.Changelog changelog = 14; repeated sonarqube.ws.commons.Comment comment = 15; + repeated sonarqube.ws.commons.User users = 16; } message Component { -- 2.39.5