throw notImplemented();
}
+ @Override public String getUuid() {
+ throw notImplemented();
+ }
+
@Override
public String getName() {
throw notImplemented();
import java.util.List;
import java.util.Optional;
import java.util.Set;
-import org.apache.ibatis.session.ResultHandler;
+
import org.sonar.db.Dao;
import org.sonar.db.DbSession;
import org.sonar.db.RowNotFoundException;
return mapper(session).selectComponentUuidsOfOpenIssuesForProjectUuid(projectUuid);
}
- public void scrollNonClosedByComponentUuidExcludingExternals(DbSession dbSession, String componentUuid, ResultHandler<IssueDto> handler) {
- mapper(dbSession).scrollNonClosedByComponentUuidExcludingExternals(componentUuid, handler);
+ public List<IssueDto> selectNonClosedByComponentUuidExcludingExternals(DbSession dbSession, String componentUuid) {
+ return mapper(dbSession).selectNonClosedByComponentUuidExcludingExternals(componentUuid);
}
- public void scrollNonClosedByModuleOrProjectExcludingExternals(DbSession dbSession, ComponentDto module, ResultHandler<IssueDto> handler) {
+ public List<IssueDto> selectNonClosedByModuleOrProjectExcludingExternals(DbSession dbSession, ComponentDto module) {
String likeModuleUuidPath = buildLikeValue(module.moduleUuidPath(), WildcardPosition.AFTER);
- mapper(dbSession).scrollNonClosedByModuleOrProject(module.projectUuid(), likeModuleUuidPath, handler);
+ return mapper(dbSession).selectNonClosedByModuleOrProject(module.projectUuid(), likeModuleUuidPath);
}
public List<ShortBranchIssueDto> selectOpenByComponentUuids(DbSession dbSession, Collection<String> componentUuids) {
private String status;
private String resolution;
private String checksum;
- private String assignee;
+ private String assigneeUuid;
private String authorLogin;
private String issueAttributes;
private byte[] locations;
.setSeverity(issue.severity())
.setManualSeverity(issue.manualSeverity())
.setChecksum(issue.checksum())
- .setAssignee(issue.assignee())
+ .setAssigneeUuid(issue.assignee())
.setRuleId(ruleId)
.setRuleKey(issue.ruleKey().repository(), issue.ruleKey().rule())
.setExternal(issue.isFromExternalRuleEngine())
.setSeverity(issue.severity())
.setChecksum(issue.checksum())
.setManualSeverity(issue.manualSeverity())
- .setAssignee(issue.assignee())
+ .setAssigneeUuid(issue.assignee())
.setIssueAttributes(KeyValueFormat.format(issue.attributes()))
.setAuthorLogin(issue.authorLogin())
.setRuleKey(issue.ruleKey().repository(), issue.ruleKey().rule())
}
@CheckForNull
- public String getAssignee() {
- return assignee;
+ public String getAssigneeUuid() {
+ return assigneeUuid;
}
- public IssueDto setAssignee(@Nullable String s) {
- checkArgument(s == null || s.length() <= 255, "Value is too long for issue assignee: %s", s);
- this.assignee = s;
+ public IssueDto setAssigneeUuid(@Nullable String s) {
+ checkArgument(s == null || s.length() <= 255, "Value is too long for issue assigneeUuid: %s", s);
+ this.assigneeUuid = s;
return this;
}
issue.setLine(line);
issue.setChecksum(checksum);
issue.setSeverity(severity);
- issue.setAssignee(assignee);
+ issue.setAssigneeUuid(assigneeUuid);
issue.setAttributes(KeyValueFormat.parse(MoreObjects.firstNonNull(issueAttributes, "")));
issue.setComponentKey(componentKey);
issue.setComponentUuid(componentUuid);
void scrollNonClosedByComponentUuid(@Param("componentUuid") String componentUuid, ResultHandler<IssueDto> handler);
- void scrollNonClosedByComponentUuidExcludingExternals(@Param("componentUuid") String componentUuid, ResultHandler<IssueDto> handler);
+ List<IssueDto> selectNonClosedByComponentUuidExcludingExternals(@Param("componentUuid") String componentUuid);
- void scrollNonClosedByModuleOrProject(
- @Param("projectUuid") String projectUuid,
- @Param("likeModuleUuidPath") String likeModuleUuidPath,
- ResultHandler<IssueDto> handler);
+ List<IssueDto> selectNonClosedByModuleOrProject(@Param("projectUuid") String projectUuid, @Param("likeModuleUuidPath") String likeModuleUuidPath);
Collection<IssueGroupDto> selectIssueGroupsByBaseComponent(
@Param("baseComponent") ComponentDto baseComponent,
.setResolution(null)
.setSeverity(Severity.ALL.get(nextInt(Severity.ALL.size())))
.setEffort((long) RandomUtils.nextInt(10))
- .setAssignee("assignee_" + randomAlphabetic(5))
+ .setAssigneeUuid("assignee-uuid_" + randomAlphabetic(26))
.setAuthorLogin("author_" + randomAlphabetic(5))
// Adding one to the generated random value in order to never get 0 (as it's a forbidden value)
.setLine(nextInt(1_000) + 1)
i.status as status,
i.resolution as resolution,
i.checksum as checksum,
- i.assignee as assignee,
+ i.assignee as assigneeUuid,
i.author_login as authorLogin,
i.tags as tagsString,
i.issue_attributes as issueAttributes,
i.status as status
</when>
<when test="'ASSIGNEE'.equals(query.sort())">
- i.assignee as assignee
+ i.assignee as assigneeUuid
</when>
<when test="'CREATION_DATE'.equals(query.sort())">
i.issue_creation_date as issueCreationTime
#{manualSeverity,jdbcType=BOOLEAN}, #{message,jdbcType=VARCHAR}, #{line,jdbcType=INTEGER},
#{locations,jdbcType=BINARY},
#{gap,jdbcType=DOUBLE}, #{effort,jdbcType=INTEGER}, #{status,jdbcType=VARCHAR},
- #{tagsString,jdbcType=VARCHAR}, #{resolution,jdbcType=VARCHAR}, #{checksum,jdbcType=VARCHAR},
- #{assignee,jdbcType=VARCHAR}, #{authorLogin,jdbcType=VARCHAR},
+ #{tagsString,jdbcType=VARCHAR}, #{resolution,jdbcType=VARCHAR},
+ #{checksum,jdbcType=VARCHAR},
+ #{assigneeUuid,jdbcType=VARCHAR},
+ #{authorLogin,jdbcType=VARCHAR},
#{issueAttributes,jdbcType=VARCHAR},
#{issueCreationTime,jdbcType=BIGINT},#{issueUpdateTime,jdbcType=BIGINT}, #{issueCloseTime,jdbcType=BIGINT},
#{createdAt,jdbcType=BIGINT}, #{updatedAt,jdbcType=BIGINT},
status=#{status,jdbcType=VARCHAR},
resolution=#{resolution,jdbcType=VARCHAR},
checksum=#{checksum,jdbcType=VARCHAR},
- assignee=#{assignee,jdbcType=VARCHAR},
+ assignee=#{assigneeUuid,jdbcType=VARCHAR},
author_login=#{authorLogin,jdbcType=VARCHAR},
tags=#{tagsString,jdbcType=VARCHAR},
project_uuid=#{projectUuid,jdbcType=VARCHAR},
status=#{status,jdbcType=VARCHAR},
resolution=#{resolution,jdbcType=VARCHAR},
checksum=#{checksum,jdbcType=VARCHAR},
- assignee=#{assignee,jdbcType=VARCHAR},
+ assignee=#{assigneeUuid,jdbcType=VARCHAR},
author_login=#{authorLogin,jdbcType=VARCHAR},
tags=#{tagsString,jdbcType=VARCHAR},
component_uuid=#{componentUuid,jdbcType=VARCHAR},
i.component_uuid = #{componentUuid,jdbcType=VARCHAR} and
i.status <> 'CLOSED'
</select>
-
- <select id="scrollNonClosedByComponentUuidExcludingExternals" parameterType="String" resultType="Issue" fetchSize="${_scrollFetchSize}" resultSetType="FORWARD_ONLY">
+
+ <select id="selectNonClosedByComponentUuidExcludingExternals" parameterType="String" resultType="Issue">
select
<include refid="issueColumns"/>
from issues i
and i.status <> 'CLOSED'
</select>
- <select id="scrollNonClosedByModuleOrProject" parameterType="map" resultType="Issue" fetchSize="${_scrollFetchSize}" resultSetType="FORWARD_ONLY">
+ <select id="selectNonClosedByModuleOrProject" parameterType="map" resultType="Issue">
select
<include refid="issueColumns"/>
from issues i
*/
package org.sonar.db.issue;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
-import org.apache.ibatis.session.ResultContext;
-import org.apache.ibatis.session.ResultHandler;
+
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.rules.ExpectedException.none;
import static org.sonar.db.component.ComponentTesting.newFileDto;
import static org.sonar.db.component.ComponentTesting.newModuleDto;
private static final String ISSUE_KEY2 = "I2";
@Rule
- public ExpectedException expectedException = ExpectedException.none();
+ public ExpectedException expectedException = none();
@Rule
public DbTester db = DbTester.create(System2.INSTANCE);
assertThat(issue.getResolution()).isEqualTo("FIXED");
assertThat(issue.getChecksum()).isEqualTo("123456789");
assertThat(issue.getAuthorLogin()).isEqualTo("morgan");
- assertThat(issue.getAssignee()).isEqualTo("karadoc");
+ assertThat(issue.getAssigneeUuid()).isEqualTo("karadoc");
assertThat(issue.getIssueAttributes()).isEqualTo("JIRA=FOO-1234");
assertThat(issue.getIssueCreationDate()).isNotNull();
assertThat(issue.getIssueUpdateDate()).isNotNull();
RuleDefinitionDto external = db.rules().insert(ruleDefinitionDto -> ruleDefinitionDto.setIsExternal(true));
IssueDto issueFromExteralruleOnFile = db.issues().insert(external, project, file, i -> i.setKee("ON_FILE_FROM_EXTERNAL"));
- Accumulator accumulator = new Accumulator();
- underTest.scrollNonClosedByComponentUuidExcludingExternals(db.getSession(), file.uuid(), accumulator);
- accumulator.assertThatContainsOnly(openIssue1OnFile, openIssue2OnFile);
+ assertThat(underTest.selectNonClosedByComponentUuidExcludingExternals(db.getSession(), file.uuid()))
+ .extracting(IssueDto::getKey)
+ .containsExactlyInAnyOrder(Arrays.stream(new IssueDto[] {openIssue1OnFile, openIssue2OnFile}).map(IssueDto::getKey).toArray(String[]::new));
- accumulator.clear();
- underTest.scrollNonClosedByComponentUuidExcludingExternals(db.getSession(), project.uuid(), accumulator);
- accumulator.assertThatContainsOnly(openIssueOnProject);
+ assertThat(underTest.selectNonClosedByComponentUuidExcludingExternals(db.getSession(), project.uuid()))
+ .extracting(IssueDto::getKey)
+ .containsExactlyInAnyOrder(Arrays.stream(new IssueDto[] {openIssueOnProject}).map(IssueDto::getKey).toArray(String[]::new));
- accumulator.clear();
- underTest.scrollNonClosedByComponentUuidExcludingExternals(db.getSession(), "does_not_exist", accumulator);
- assertThat(accumulator.list).isEmpty();
+ assertThat(underTest.selectNonClosedByComponentUuidExcludingExternals(db.getSession(), "does_not_exist")).isEmpty();
}
@Test
RuleDefinitionDto external = db.rules().insert(ruleDefinitionDto -> ruleDefinitionDto.setIsExternal(true));
IssueDto issueFromExteralruleOnFile = db.issues().insert(external, project, file, i -> i.setKee("ON_FILE_FROM_EXTERNAL"));
- Accumulator accumulator = new Accumulator();
- underTest.scrollNonClosedByModuleOrProjectExcludingExternals(db.getSession(), project, accumulator);
- accumulator.assertThatContainsOnly(openIssue1OnFile, openIssue2OnFile, openIssueOnModule, openIssueOnProject);
+ assertThat(underTest.selectNonClosedByModuleOrProjectExcludingExternals(db.getSession(), project))
+ .extracting(IssueDto::getKey)
+ .containsExactlyInAnyOrder(Arrays.stream(new IssueDto[] {openIssue1OnFile, openIssue2OnFile, openIssueOnModule, openIssueOnProject}).map(IssueDto::getKey).toArray(String[]::new));
- accumulator.clear();
- underTest.scrollNonClosedByModuleOrProjectExcludingExternals(db.getSession(), module, accumulator);
- accumulator.assertThatContainsOnly(openIssue1OnFile, openIssue2OnFile, openIssueOnModule);
+ assertThat(underTest.selectNonClosedByModuleOrProjectExcludingExternals(db.getSession(), module))
+ .extracting(IssueDto::getKey)
+ .containsExactlyInAnyOrder(Arrays.stream(new IssueDto[] {openIssue1OnFile, openIssue2OnFile, openIssueOnModule}).map(IssueDto::getKey).toArray(String[]::new));
- accumulator.clear();
ComponentDto notPersisted = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
- underTest.scrollNonClosedByModuleOrProjectExcludingExternals(db.getSession(), notPersisted, accumulator);
- assertThat(accumulator.list).isEmpty();
+ assertThat(underTest.selectNonClosedByModuleOrProjectExcludingExternals(db.getSession(), notPersisted)).isEmpty();
}
@Test
dto.setStatus("RESOLVED");
dto.setSeverity("BLOCKER");
dto.setAuthorLogin("morgan");
- dto.setAssignee("karadoc");
+ dto.setAssigneeUuid("karadoc");
dto.setIssueAttributes("JIRA=FOO-1234");
dto.setChecksum("123456789");
dto.setMessage("the message");
.setProjectUuid(PROJECT_UUID));
db.getSession().commit();
}
-
- private static class Accumulator implements ResultHandler<IssueDto> {
- private final List<IssueDto> list = new ArrayList<>();
-
- private void clear() {
- list.clear();
- }
-
- @Override
- public void handleResult(ResultContext<? extends IssueDto> resultContext) {
- list.add(resultContext.getResultObject());
- }
-
- private void assertThatContainsOnly(IssueDto... issues) {
- assertThat(list)
- .extracting(IssueDto::getKey)
- .containsExactlyInAnyOrder(Arrays.stream(issues).map(IssueDto::getKey).toArray(String[]::new));
- }
- }
}
.setSeverity("BLOCKER")
.setMessage("message")
.setManualSeverity(true)
- .setAssignee("perceval")
+ .setAssigneeUuid("perceval")
.setIssueAttributes("key=value")
.setAuthorLogin("pierre")
.setIssueCreationDate(createdAt)
assertThat(result.getStatus()).isEqualTo("RESOLVED");
assertThat(result.getSeverity()).isEqualTo("BLOCKER");
assertThat(result.getAuthorLogin()).isEqualTo("morgan");
- assertThat(result.getAssignee()).isEqualTo("karadoc");
+ assertThat(result.getAssigneeUuid()).isEqualTo("karadoc");
assertThat(result.getIssueAttributes()).isEqualTo("JIRA=FOO-1234");
assertThat(result.getChecksum()).isEqualTo("123456789");
assertThat(result.getMessage()).isEqualTo("the message");
update.setStatus("RESOLVED");
update.setSeverity("BLOCKER");
update.setAuthorLogin("morgan");
- update.setAssignee("karadoc");
+ update.setAssigneeUuid("karadoc");
update.setIssueAttributes("JIRA=FOO-1234");
update.setChecksum("123456789");
update.setMessage("the message");
assertThat(result.getStatus()).isEqualTo("RESOLVED");
assertThat(result.getSeverity()).isEqualTo("BLOCKER");
assertThat(result.getAuthorLogin()).isEqualTo("morgan");
- assertThat(result.getAssignee()).isEqualTo("karadoc");
+ assertThat(result.getAssigneeUuid()).isEqualTo("karadoc");
assertThat(result.getIssueAttributes()).isEqualTo("JIRA=FOO-1234");
assertThat(result.getChecksum()).isEqualTo("123456789");
assertThat(result.getMessage()).isEqualTo("the message");
.setStatus("RESOLVED")
.setSeverity("BLOCKER")
.setAuthorLogin("morgan")
- .setAssignee("karadoc")
+ .setAssigneeUuid("karadoc")
.setIssueAttributes("JIRA=FOO-1234")
.setChecksum("123456789")
.setMessage("the message")
public static UserDto newUserDto() {
return new UserDto()
.setId(nextInt())
+ .setUuid(randomAlphanumeric(40))
.setActive(true)
.setLocal(nextBoolean())
.setLogin(randomAlphanumeric(30))
import java.sql.SQLException;
-import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE;
import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class MakeQualityProfileKeyUnique extends DdlChange {
if (login == null) {
login = uuidFactory.create();
}
- update.setString(1, login); // login -> uuid
+ // login -> uuid
+ update.setString(1, login);
update.setLong(2, system2.now());
update.setLong(3, row.getLong(1));
return true;
--- /dev/null
+CREATE TABLE "ISSUES" (
+ "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "KEE" VARCHAR(50) UNIQUE NOT NULL,
+ "COMPONENT_UUID" VARCHAR(50),
+ "PROJECT_UUID" VARCHAR(50),
+ "RULE_ID" INTEGER,
+ "SEVERITY" VARCHAR(10),
+ "MANUAL_SEVERITY" BOOLEAN NOT NULL,
+ "MESSAGE" VARCHAR(4000),
+ "LINE" INTEGER,
+ "GAP" DOUBLE,
+ "EFFORT" INTEGER,
+ "STATUS" VARCHAR(20),
+ "RESOLUTION" VARCHAR(20),
+ "CHECKSUM" VARCHAR(1000),
+ "REPORTER" VARCHAR(255),
+ "ASSIGNEE" VARCHAR(255),
+ "AUTHOR_LOGIN" VARCHAR(255),
+ "ACTION_PLAN_KEY" VARCHAR(50) NULL,
+ "ISSUE_ATTRIBUTES" VARCHAR(4000),
+ "TAGS" VARCHAR(4000),
+ "ISSUE_CREATION_DATE" BIGINT,
+ "ISSUE_CLOSE_DATE" BIGINT,
+ "ISSUE_UPDATE_DATE" BIGINT,
+ "CREATED_AT" BIGINT,
+ "UPDATED_AT" BIGINT,
+ "LOCATIONS" BLOB,
+ "ISSUE_TYPE" TINYINT
+);
+CREATE UNIQUE INDEX "ISSUES_KEE" ON "ISSUES" ("KEE");
+CREATE INDEX "ISSUES_COMPONENT_UUID" ON "ISSUES" ("COMPONENT_UUID");
+CREATE INDEX "ISSUES_PROJECT_UUID" ON "ISSUES" ("PROJECT_UUID");
+CREATE INDEX "ISSUES_RULE_ID" ON "ISSUES" ("RULE_ID");
+CREATE INDEX "ISSUES_RESOLUTION" ON "ISSUES" ("RESOLUTION");
+CREATE INDEX "ISSUES_ASSIGNEE" ON "ISSUES" ("ASSIGNEE");
+CREATE INDEX "ISSUES_CREATION_DATE" ON "ISSUES" ("ISSUE_CREATION_DATE");
+CREATE INDEX "ISSUES_UPDATED_AT" ON "ISSUES" ("UPDATED_AT");
return null;
}
+ @CheckForNull
+ @Override
+ public String getUuid() {
+ return null;
+ }
+
@CheckForNull
@Override
public String getName() {
package org.sonar.server.batch;
import com.google.common.base.Splitter;
+
import java.io.IOException;
import java.io.OutputStream;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import org.apache.ibatis.session.ResultHandler;
+
import org.sonar.api.resources.Scopes;
import org.sonar.api.rules.RuleType;
import org.sonar.api.server.ws.Request;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.issue.IssueDto;
+import org.sonar.db.user.UserDto;
import org.sonar.scanner.protocol.input.ScannerInput;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.user.UserSession;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.Maps.newHashMap;
import static java.lang.String.format;
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toMap;
import static org.sonar.api.web.UserRole.USER;
import static org.sonar.core.util.Protobuf.setNullable;
import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001;
response.stream().setMediaType(MediaTypes.PROTOBUF);
OutputStream output = response.stream().output();
- ResultHandler<IssueDto> handler = resultContext -> {
- IssueDto issue = resultContext.getResultObject();
- handleIssue(issue, responseBuilder, keysByUUid, output);
- };
+ List<IssueDto> issueDtos = new ArrayList<>();
switch (component.scope()) {
case Scopes.PROJECT:
- dbClient.issueDao().scrollNonClosedByModuleOrProjectExcludingExternals(dbSession, component, handler);
+ issueDtos.addAll(dbClient.issueDao().selectNonClosedByModuleOrProjectExcludingExternals(dbSession, component));
break;
case Scopes.FILE:
- dbClient.issueDao().scrollNonClosedByComponentUuidExcludingExternals(dbSession, component.uuid(), handler);
+ issueDtos.addAll(dbClient.issueDao().selectNonClosedByComponentUuidExcludingExternals(dbSession, component.uuid()));
break;
default:
// only projects, modules and files are supported. Other types of components are not allowed.
throw new IllegalArgumentException(format("Component of scope '%s' is not allowed", component.scope()));
}
+
+ List<String> usersUuids = issueDtos.stream()
+ .filter(issue -> issue.getAssigneeUuid() != null)
+ .map(IssueDto::getAssigneeUuid)
+ .collect(toList());
+
+ Map<String, String> userLoginsByUserUuids = dbClient.userDao().selectByUuids(dbSession, usersUuids)
+ .stream().collect(toMap(UserDto::getUuid, UserDto::getLogin));
+
+ issueDtos.forEach(issue -> {
+ issue.setAssigneeUuid(userLoginsByUserUuids.get(issue.getAssigneeUuid()));
+ handleIssue(issue, responseBuilder, keysByUUid, output);
+ });
}
}
- private static void handleIssue(IssueDto issue, ScannerInput.ServerIssue.Builder issueBuilder,
- Map<String, String> keysByUUid, OutputStream out) {
+ private static void handleIssue(IssueDto issue, ScannerInput.ServerIssue.Builder issueBuilder, Map<String, String> keysByUUid, OutputStream out) {
issueBuilder.setKey(issue.getKey());
String moduleUuid = extractModuleUuid(issue);
issueBuilder.setModuleKey(keysByUUid.get(moduleUuid));
issueBuilder.setRuleRepository(issue.getRuleRepo());
issueBuilder.setRuleKey(issue.getRule());
setNullable(issue.getChecksum(), issueBuilder::setChecksum);
- setNullable(issue.getAssignee(), issueBuilder::setAssigneeLogin);
+ setNullable(issue.getAssigneeUuid(), issueBuilder::setAssigneeLogin);
setNullable(issue.getLine(), issueBuilder::setLine);
setNullable(issue.getMessage(), issueBuilder::setMsg);
issueBuilder.setSeverity(org.sonar.scanner.protocol.Constants.Severity.valueOf(issue.getSeverity()));
*/
package org.sonar.server.computation.task.projectanalysis.issue;
-import com.google.common.base.Strings;
import javax.annotation.CheckForNull;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder;
import org.sonar.server.computation.task.projectanalysis.component.ConfigurationRepository;
+import static com.google.common.base.Strings.isNullOrEmpty;
import static org.sonar.api.CoreProperties.DEFAULT_ISSUE_ASSIGNEE;
/**
private final AnalysisMetadataHolder analysisMetadataHolder;
private boolean loaded = false;
- private String login = null;
+ private String userUuid = null;
public DefaultAssignee(DbClient dbClient, ConfigurationRepository configRepository, AnalysisMetadataHolder analysisMetadataHolder) {
this.dbClient = dbClient;
}
@CheckForNull
- public String loadDefaultAssigneeLogin() {
+ public String loadDefaultAssigneeUuid() {
if (loaded) {
- return login;
+ return userUuid;
}
- String configuredLogin = configRepository.getConfiguration().get(DEFAULT_ISSUE_ASSIGNEE).orElse(null);
- if (!Strings.isNullOrEmpty(configuredLogin) && isValidLogin(configuredLogin)) {
- this.login = configuredLogin;
+ String login = configRepository.getConfiguration().get(DEFAULT_ISSUE_ASSIGNEE).orElse(null);
+ if (!isNullOrEmpty(login)) {
+ userUuid = findValidUserUuidFromLogin(login);
}
loaded = true;
- return login;
+ return userUuid;
}
- private boolean isValidLogin(String login) {
+ private String findValidUserUuidFromLogin(String login) {
try (DbSession dbSession = dbClient.openSession(false)) {
UserDto user = dbClient.userDao().selectActiveUserByLogin(dbSession, login);
if (user == null) {
LOG.info("Property {} is set with an unknown login: {}", DEFAULT_ISSUE_ASSIGNEE, login);
- return false;
+ return null;
}
if (!isUserMemberOfOrganization(dbSession, user)) {
LOG.info("Property {} is set with a user which is not member of the organization of the project : {}", DEFAULT_ISSUE_ASSIGNEE, login);
- return false;
+ return null;
}
- return true;
+ return user.getUuid();
}
}
*/
package org.sonar.server.computation.task.projectanalysis.issue;
-import com.google.common.base.Strings;
import java.util.Date;
import java.util.Optional;
import javax.annotation.CheckForNull;
-import org.apache.commons.lang.StringUtils;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.core.issue.DefaultIssue;
import org.sonar.server.computation.task.projectanalysis.scm.ScmInfoRepository;
import org.sonar.server.issue.IssueFieldsSetter;
+import static com.google.common.base.Strings.isNullOrEmpty;
import static org.apache.commons.lang.StringUtils.defaultIfEmpty;
import static org.sonar.core.issue.IssueChangeContext.createScan;
loadScmChangesets(component);
String scmAuthor = guessScmAuthor(issue);
- if (!Strings.isNullOrEmpty(scmAuthor)) {
+ if (!isNullOrEmpty(scmAuthor)) {
if (scmAuthor.length() <= IssueDto.AUTHOR_MAX_SIZE) {
issueUpdater.setNewAuthor(issue, scmAuthor, changeContext);
} else {
}
if (issue.assignee() == null) {
- String author = Strings.isNullOrEmpty(scmAuthor) ? null : scmAccountToUser.getNullable(scmAuthor);
- String assigneeLogin = StringUtils.defaultIfEmpty(author, defaultAssignee.loadDefaultAssigneeLogin());
-
- issueUpdater.setNewAssignee(issue, assigneeLogin, changeContext);
+ String assigneeUuid = isNullOrEmpty(scmAuthor) ? null : scmAccountToUser.getNullable(scmAuthor);
+ assigneeUuid = defaultIfEmpty(assigneeUuid, defaultAssignee.loadDefaultAssigneeUuid());
+ issueUpdater.setNewAssignee(issue, assigneeUuid, changeContext);
}
}
}
toIssue.setCloseDate(fromIssue.closeDate());
toIssue.setResolution(fromIssue.resolution());
toIssue.setStatus(fromIssue.status());
- toIssue.setAssignee(fromIssue.assignee());
+ toIssue.setAssigneeUuid(fromIssue.assignee());
toIssue.setAuthorLogin(fromIssue.authorLogin());
toIssue.setTags(fromIssue.tags());
toIssue.setAttributes(fromIssue.attributes());
import org.sonar.server.util.cache.MemoryCache;
/**
- * Cache of dictionary {SCM account -> SQ user login}. Kept in memory
+ * Cache of dictionary {SCM account -> SQ user uuid}. Kept in memory
* during the execution of Compute Engine.
*/
public class ScmAccountToUser extends MemoryCache<String,String> {
public String load(String scmAccount) {
List<UserDoc> users = index.getAtMostThreeActiveUsersForScmAccount(scmAccount, analysisMetadataHolder.getOrganization().getUuid());
if (users.size() == 1) {
- return users.get(0).login();
+ return users.get(0).uuid();
}
if (!users.isEmpty()) {
// multiple users are associated to the same SCM account, for example
}
private void resolveAssignee(IssueDto dbIssue, DefaultIssue issue) {
- issue.setAssignee(dbIssue.getAssignee());
+ issue.setAssigneeUuid(dbIssue.getAssigneeUuid());
}
}
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Date;
+import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
import org.sonar.api.utils.Duration;
import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.util.CloseableIterator;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.user.UserDto;
import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder;
import org.sonar.server.computation.task.projectanalysis.analysis.Branch;
import org.sonar.server.computation.task.projectanalysis.component.Component;
import org.sonar.server.issue.notification.NewIssuesStatistics;
import org.sonar.server.notification.NotificationService;
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toMap;
+import static java.util.stream.StreamSupport.stream;
import static org.sonar.db.component.BranchType.PULL_REQUEST;
import static org.sonar.server.computation.task.projectanalysis.component.ComponentVisitor.Order.POST_ORDER;
private final NotificationService service;
private final AnalysisMetadataHolder analysisMetadataHolder;
private final NewIssuesNotificationFactory newIssuesNotificationFactory;
+ private final DbClient dbClient;
+
private Map<String, Component> componentsByDbKey;
public SendIssueNotificationsStep(IssueCache issueCache, RuleRepository rules, TreeRootHolder treeRootHolder,
NotificationService service, AnalysisMetadataHolder analysisMetadataHolder,
- NewIssuesNotificationFactory newIssuesNotificationFactory) {
+ NewIssuesNotificationFactory newIssuesNotificationFactory, DbClient dbClient) {
this.issueCache = issueCache;
this.rules = rules;
this.treeRootHolder = treeRootHolder;
this.service = service;
this.analysisMetadataHolder = analysisMetadataHolder;
this.newIssuesNotificationFactory = newIssuesNotificationFactory;
+ this.dbClient = dbClient;
}
@Override
long analysisDate = analysisMetadataHolder.getAnalysisDate();
Predicate<DefaultIssue> isOnLeakPredicate = i -> i.isNew() && i.creationDate().getTime() >= truncateToSeconds(analysisDate);
NewIssuesStatistics newIssuesStats = new NewIssuesStatistics(isOnLeakPredicate);
+ Map<String, UserDto> usersDtoByUuids;
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ Iterable<DefaultIssue> iterable = issueCache::traverse;
+ List<String> assigneeUuids = stream(iterable.spliterator(), false).map(DefaultIssue::assignee).filter(Objects::nonNull).collect(toList());
+ usersDtoByUuids = dbClient.userDao().selectByUuids(dbSession, assigneeUuids).stream().collect(toMap(UserDto::getUuid, dto -> dto));
+ }
try (CloseableIterator<DefaultIssue> issues = issueCache.traverse()) {
- processIssues(newIssuesStats, issues, project);
+ processIssues(newIssuesStats, issues, project, usersDtoByUuids);
}
if (newIssuesStats.hasIssuesOnLeak()) {
sendNewIssuesNotification(newIssuesStats, project, analysisDate);
return Date.from(instant).getTime();
}
- private void processIssues(NewIssuesStatistics newIssuesStats, CloseableIterator<DefaultIssue> issues, Component project) {
+ private void processIssues(NewIssuesStatistics newIssuesStats, CloseableIterator<DefaultIssue> issues, Component project, Map<String, UserDto> usersDtoByUuids) {
while (issues.hasNext()) {
DefaultIssue issue = issues.next();
if (issue.isNew() && issue.resolution() == null) {
newIssuesStats.add(issue);
} else if (issue.isChanged() && issue.mustSendNotifications()) {
- sendIssueChangeNotification(issue, project);
+ sendIssueChangeNotification(issue, project, usersDtoByUuids);
}
}
}
- private void sendIssueChangeNotification(DefaultIssue issue, Component project) {
+ private void sendIssueChangeNotification(DefaultIssue issue, Component project, Map<String, UserDto> usersDtoByUuids) {
IssueChangeNotification changeNotification = new IssueChangeNotification();
changeNotification.setRuleName(rules.getByKey(issue.ruleKey()).getName());
changeNotification.setIssue(issue);
+ changeNotification.setAssignee(usersDtoByUuids.get(issue.assignee()));
changeNotification.setProject(project.getPublicKey(), project.getName(), getBranchName(), getPullRequest());
getComponentKey(issue).ifPresent(c -> changeNotification.setComponent(c.getPublicKey(), c.getName()));
service.deliver(changeNotification);
}
private void sendNewIssuesNotificationToAssignees(NewIssuesStatistics statistics, Component project, long analysisDate) {
+ Map<String, UserDto> userDtoByUuid = loadUserDtoByUuid(statistics);
statistics.getAssigneesStatistics().entrySet()
.stream()
.filter(e -> e.getValue().hasIssuesOnLeak())
.forEach(e -> {
- String assignee = e.getKey();
+ String assigneeUuid = e.getKey();
NewIssuesStatistics.Stats assigneeStatistics = e.getValue();
MyNewIssuesNotification myNewIssuesNotification = newIssuesNotificationFactory
.newMyNewIssuesNotification()
- .setAssignee(assignee);
+ .setAssignee(userDtoByUuid.get(assigneeUuid));
myNewIssuesNotification
.setProject(project.getPublicKey(), project.getName(), getBranchName(), getPullRequest())
.setProjectVersion(project.getReportAttributes().getVersion())
});
}
+ private Map<String, UserDto> loadUserDtoByUuid(NewIssuesStatistics statistics) {
+ List<Map.Entry<String, NewIssuesStatistics.Stats>> entriesWithIssuesOnLeak = statistics.getAssigneesStatistics().entrySet()
+ .stream().filter(e -> e.getValue().hasIssuesOnLeak()).collect(toList());
+ List<String> assigneeUuids = entriesWithIssuesOnLeak.stream().map(Map.Entry::getKey).collect(toList());
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ return dbClient.userDao().selectByUuids(dbSession, assigneeUuids).stream().collect(toMap(UserDto::getUuid, u -> u));
+ }
+ }
+
private Optional<Component> getComponentKey(DefaultIssue issue) {
if (componentsByDbKey == null) {
final ImmutableMap.Builder<String, Component> builder = ImmutableMap.builder();
import java.util.Objects;
import java.util.Set;
import javax.annotation.Nullable;
-import org.apache.commons.lang.StringUtils;
+
import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.rules.RuleType;
import org.sonar.api.server.ServerSide;
}
return false;
}
-
public boolean assign(DefaultIssue issue, @Nullable UserDto user, IssueChangeContext context) {
- String sanitizedAssignee = null;
- if (user != null) {
- sanitizedAssignee = StringUtils.defaultIfBlank(user.getLogin(), null);
- }
- if (!Objects.equals(sanitizedAssignee, issue.assignee())) {
- String newAssigneeName = user != null ? user.getName() : null;
- issue.setFieldChange(context, ASSIGNEE, UNUSED, newAssigneeName);
- issue.setAssignee(sanitizedAssignee);
+ String assigneeUuid = user != null ? user.getUuid() : null;
+ if (!Objects.equals(assigneeUuid, issue.assignee())) {
+ issue.setFieldChange(context, ASSIGNEE, UNUSED, user != null ? user.getUuid() : null);
+ issue.setAssigneeUuid(user != null ? user.getUuid() : null);
issue.setUpdateDate(context.date());
issue.setChanged(true);
issue.setSendNotifications(true);
/**
* Used to set the assignee when it was null
*/
- public boolean setNewAssignee(DefaultIssue issue, @Nullable String newAssignee, IssueChangeContext context) {
- if (newAssignee == null) {
+ public boolean setNewAssignee(DefaultIssue issue, @Nullable String newAssigneeUuid, IssueChangeContext context) {
+ if (newAssigneeUuid == null) {
return false;
}
checkState(issue.assignee() == null, "It's not possible to update the assignee with this method, please use assign()");
- issue.setFieldChange(context, ASSIGNEE, UNUSED, newAssignee);
- issue.setAssignee(newAssignee);
+ issue.setFieldChange(context, ASSIGNEE, UNUSED, newAssigneeUuid);
+ issue.setAssigneeUuid(newAssigneeUuid);
issue.setUpdateDate(context.date());
issue.setChanged(true);
issue.setSendNotifications(true);
this.files = defaultCollection(builder.files);
this.views = defaultCollection(builder.views);
this.rules = defaultCollection(builder.rules);
- this.assignees = defaultCollection(builder.assignees);
+ this.assignees = defaultCollection(builder.assigneeUuids);
this.authors = defaultCollection(builder.authors);
this.languages = defaultCollection(builder.languages);
this.tags = defaultCollection(builder.tags);
private Collection<String> files;
private Collection<String> views;
private Collection<RuleDefinitionDto> rules;
- private Collection<String> assignees;
+ private Collection<String> assigneeUuids;
private Collection<String> authors;
private Collection<String> languages;
private Collection<String> tags;
return this;
}
- public Builder assignees(@Nullable Collection<String> l) {
- this.assignees = l;
+ public Builder assigneeUuids(@Nullable Collection<String> l) {
+ this.assigneeUuids = l;
return this;
}
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
-import com.google.common.collect.Lists;
import java.time.Clock;
import java.time.OffsetDateTime;
import java.time.Period;
@ServerSide
public class IssueQueryFactory {
- public static final String LOGIN_MYSELF = "__me__";
-
- private static final String UNKNOWN = "<UNKNOWN>";
-
+ public static final String UNKNOWN = "<UNKNOWN>";
private static final ComponentDto UNKNOWN_COMPONENT = new ComponentDto().setUuid(UNKNOWN).setProjectUuid(UNKNOWN);
private final DbClient dbClient;
.resolutions(request.getResolutions())
.resolved(request.getResolved())
.rules(ruleKeysToRuleId(dbSession, request.getRules()))
- .assignees(buildAssignees(request.getAssignees()))
+ .assigneeUuids(request.getAssigneeUuids())
.languages(request.getLanguages())
.tags(request.getTags())
.types(request.getTypes())
return snapshot.map(s -> longToDate(s.getPeriodDate())).orElse(null);
}
- private List<String> buildAssignees(@Nullable List<String> assigneesFromParams) {
- List<String> assignees = Lists.newArrayList();
- if (assigneesFromParams != null) {
- assignees.addAll(assigneesFromParams);
- }
- if (assignees.contains(LOGIN_MYSELF)) {
- String login = userSession.getLogin();
- if (login == null) {
- assignees.add(UNKNOWN);
- } else {
- assignees.add(login);
- }
- }
- return assignees;
- }
-
private boolean mergeDeprecatedComponentParameters(DbSession session, SearchRequest request, List<ComponentDto> allComponents) {
Boolean onComponentOnly = request.getOnComponentOnly();
Collection<String> components = request.getComponents();
import org.sonar.db.component.ComponentDto;
import org.sonar.db.issue.IssueDto;
import org.sonar.db.rule.RuleDefinitionDto;
+import org.sonar.db.user.UserDto;
import org.sonar.server.issue.notification.IssueChangeNotification;
import org.sonar.server.issue.ws.SearchResponseData;
import org.sonar.server.notification.NotificationManager;
*/
public SearchResponseData saveIssueAndPreloadSearchResponseData(DbSession dbSession, DefaultIssue issue, IssueChangeContext context,
@Nullable String comment, boolean refreshMeasures) {
+
Optional<RuleDefinitionDto> rule = getRuleByKey(dbSession, issue.getRuleKey());
ComponentDto project = dbClient.componentDao().selectOrFailByUuid(dbSession, issue.projectUuid());
ComponentDto component = dbClient.componentDao().selectOrFailByUuid(dbSession, issue.componentUuid());
private IssueDto doSaveIssue(DbSession session, DefaultIssue issue, IssueChangeContext context, @Nullable String comment,
Optional<RuleDefinitionDto> rule, ComponentDto project, ComponentDto component) {
IssueDto issueDto = issueStorage.save(session, issue);
+ String assigneeUuid = issue.assignee();
+ UserDto assignee = assigneeUuid == null ? null : dbClient.userDao().selectByUuid(session, assigneeUuid);
notificationService.scheduleForSending(new IssueChangeNotification()
.setIssue(issue)
+ .setAssignee(assignee)
.setChangeAuthorLogin(context.login())
.setRuleName(rule.map(RuleDefinitionDto::getName).orElse(null))
.setProject(project)
static class AssigneeSortIssueProcessor extends TextSortIssueProcessor {
@Override
String sortField(IssueDto issueDto) {
- return issueDto.getAssignee();
+ return issueDto.getAssigneeUuid();
}
}
private List<String> additionalFields;
private Boolean asc;
private Boolean assigned;
- private List<String> assignees;
+ private List<String> assigneesUuid;
private List<String> authors;
private List<String> componentKeys;
private List<String> componentRootUuids;
}
@CheckForNull
- public List<String> getAssignees() {
- return assignees;
+ public List<String> getAssigneeUuids() {
+ return assigneesUuid;
}
- public SearchRequest setAssignees(@Nullable List<String> assignees) {
- this.assignees = assignees;
+ public SearchRequest setAssigneesUuid(@Nullable List<String> assigneesUuid) {
+ this.assigneesUuid = assigneesUuid;
return this;
}
}
@CheckForNull
- public String assignee() {
- return getNullableField(IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE);
+ public String assigneeUuid() {
+ return getNullableField(IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE_UUID);
}
/**
return this;
}
- public IssueDoc setAssignee(@Nullable String s) {
- setField(IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE, s);
+ public IssueDoc setAssigneeUuid(@Nullable String s) {
+ setField(IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE_UUID, s);
return this;
}
this.authorizationTypeSupport = authorizationTypeSupport;
this.sorting = new Sorting();
- this.sorting.add(IssueQuery.SORT_BY_ASSIGNEE, IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE);
+ this.sorting.add(IssueQuery.SORT_BY_ASSIGNEE, IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE_UUID);
this.sorting.add(IssueQuery.SORT_BY_STATUS, IssueIndexDefinition.FIELD_ISSUE_STATUS);
this.sorting.add(IssueQuery.SORT_BY_SEVERITY, IssueIndexDefinition.FIELD_ISSUE_SEVERITY_VALUE);
this.sorting.add(IssueQuery.SORT_BY_CREATION_DATE, IssueIndexDefinition.FIELD_ISSUE_FUNC_CREATED_AT);
}
private static AggregationBuilder createAssigneesFacet(IssueQuery query, Map<String, QueryBuilder> filters, QueryBuilder queryBuilder) {
- String fieldName = IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE;
+ String fieldName = IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE_UUID;
String facetName = PARAM_ASSIGNEES;
// Same as in super.stickyFacetBuilder
// Issue is assigned Filter
if (BooleanUtils.isTrue(query.assigned())) {
- filters.put(IS_ASSIGNED_FILTER, existsQuery(IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE));
+ filters.put(IS_ASSIGNED_FILTER, existsQuery(IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE_UUID));
} else if (BooleanUtils.isFalse(query.assigned())) {
- filters.put(IS_ASSIGNED_FILTER, boolQuery().mustNot(existsQuery(IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE)));
+ filters.put(IS_ASSIGNED_FILTER, boolQuery().mustNot(existsQuery(IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE_UUID)));
}
// Issue is Resolved Filter
// Field Filters
filters.put(IssueIndexDefinition.FIELD_ISSUE_KEY, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_KEY, query.issueKeys()));
- filters.put(IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE, query.assignees()));
+ filters.put(IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE_UUID, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE_UUID, query.assignees()));
addComponentRelatedFilters(query, filters);
}
private void addAssignedToMeFacetIfNeeded(SearchRequestBuilder builder, SearchOptions options, IssueQuery query, Map<String, QueryBuilder> filters, QueryBuilder queryBuilder) {
- String login = userSession.getLogin();
+ String uuid = userSession.getUuid();
- if (!options.getFacets().contains(FACET_ASSIGNED_TO_ME) || StringUtils.isEmpty(login)) {
+ if (!options.getFacets().contains(FACET_ASSIGNED_TO_ME) || StringUtils.isEmpty(uuid)) {
return;
}
- String fieldName = IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE;
+ String fieldName = IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE_UUID;
String facetName = FACET_ASSIGNED_TO_ME;
// Same as in super.stickyFacetBuilder
.filter(facetName + "__filter", facetFilter)
.subAggregation(addEffortAggregationIfNeeded(query, AggregationBuilders.terms(facetName + "__terms")
.field(fieldName)
- .includeExclude(new IncludeExclude(escapeSpecialRegexChars(login), null))));
+ .includeExclude(new IncludeExclude(escapeSpecialRegexChars(uuid), null))));
builder.addAggregation(
AggregationBuilders.global(facetName)
return boolQuery;
}
- public List<ProjectStatistics> searchProjectStatistics(List<String> projectUuids, List<Long> froms, String assignee) {
+ public List<ProjectStatistics> searchProjectStatistics(List<String> projectUuids, List<Long> froms, @Nullable String assigneeUuid) {
checkState(projectUuids.size() == froms.size(),
"Expected same size for projectUuids (had size %s) and froms (had size %s)", projectUuids.size(), froms.size());
if (projectUuids.isEmpty()) {
.setQuery(
boolQuery()
.mustNot(existsQuery(IssueIndexDefinition.FIELD_ISSUE_RESOLUTION))
- .filter(termQuery(IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE, assignee)))
+ .filter(termQuery(IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE_UUID, assigneeUuid)))
.setSize(0);
IntStream.range(0, projectUuids.size()).forEach(i -> {
String projectUuid = projectUuids.get(i);
public class IssueIndexDefinition implements IndexDefinition {
public static final IndexType INDEX_TYPE_ISSUE = new IndexType("issues", "issue");
- public static final String FIELD_ISSUE_ASSIGNEE = "assignee";
+ public static final String FIELD_ISSUE_ASSIGNEE_UUID = "assignee";
public static final String FIELD_ISSUE_AUTHOR_LOGIN = "authorLogin";
public static final String FIELD_ISSUE_COMPONENT_UUID = "component";
public static final String FIELD_ISSUE_EFFORT = "effort";
type.requireProjectAuthorization();
type.setEnableSource(enableSource);
- type.keywordFieldBuilder(FIELD_ISSUE_ASSIGNEE).disableNorms().addSubFields(SORTABLE_ANALYZER).build();
+ type.keywordFieldBuilder(FIELD_ISSUE_ASSIGNEE_UUID).disableNorms().addSubFields(SORTABLE_ANALYZER).build();
type.keywordFieldBuilder(FIELD_ISSUE_AUTHOR_LOGIN).disableNorms().build();
type.keywordFieldBuilder(FIELD_ISSUE_COMPONENT_UUID).disableNorms().build();
type.createLongField(FIELD_ISSUE_EFFORT);
// all the fields must be present, even if value is null
doc.setKey(key);
- doc.setAssignee(rs.getString(2));
+ doc.setAssigneeUuid(rs.getString(2));
doc.setLine(DatabaseUtils.getInt(rs, 3));
doc.setResolution(rs.getString(4));
doc.setSeverity(rs.getString(5));
import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.issue.FieldDiffs;
import org.sonar.db.component.ComponentDto;
+import org.sonar.db.user.UserDto;
import static org.sonar.server.issue.notification.AbstractNewIssuesEmailTemplate.FIELD_BRANCH;
import static org.sonar.server.issue.notification.AbstractNewIssuesEmailTemplate.FIELD_PROJECT_KEY;
public IssueChangeNotification setIssue(DefaultIssue issue) {
setFieldValue("key", issue.key());
- setFieldValue("assignee", issue.assignee());
setFieldValue("message", issue.message());
FieldDiffs currentChange = issue.currentChange();
if (currentChange != null) {
private static String neverEmptySerializableToString(@Nullable Serializable s) {
return s != null ? Strings.emptyToNull(s.toString()) : null;
}
+
+ public IssueChangeNotification setAssignee(@Nullable UserDto assignee) {
+ if (assignee != null) {
+ setFieldValue("assignee", assignee.getLogin());
+ }
+ return this;
+ }
}
import org.sonar.api.utils.Durations;
import org.sonar.db.DbClient;
+import org.sonar.db.user.UserDto;
+
+import javax.annotation.Nullable;
import static org.sonar.server.issue.notification.AbstractNewIssuesEmailTemplate.FIELD_ASSIGNEE;
super(MY_NEW_ISSUES_NOTIF_TYPE, dbClient, durations);
}
- public MyNewIssuesNotification setAssignee(String assignee) {
- setFieldValue(FIELD_ASSIGNEE, assignee);
-
+ public MyNewIssuesNotification setAssignee(@Nullable UserDto assignee) {
+ if (assignee == null) {
+ return this;
+ }
+ setFieldValue(FIELD_ASSIGNEE, assignee.getLogin());
return this;
}
import java.util.Date;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.ToIntFunction;
import org.sonar.db.user.UserDto;
import org.sonar.server.issue.notification.NewIssuesStatistics.Metric;
+import static java.util.stream.Collectors.toMap;
+import static java.util.stream.Collectors.toSet;
import static org.sonar.server.issue.notification.AbstractNewIssuesEmailTemplate.FIELD_BRANCH;
import static org.sonar.server.issue.notification.AbstractNewIssuesEmailTemplate.FIELD_PROJECT_VERSION;
import static org.sonar.server.issue.notification.AbstractNewIssuesEmailTemplate.FIELD_PULL_REQUEST;
}
private void setAssigneesStatistics(DbSession dbSession, NewIssuesStatistics.Stats stats) {
+
Metric metric = Metric.ASSIGNEE;
+ List<Map.Entry<String, MetricStatsInt>> entries = fiveBiggest(stats.getDistributedMetricStats(metric), MetricStatsInt::getOnLeak);
+
+ Set<String> assigneeUuids = entries.stream().map(Map.Entry::getKey).filter(Objects::nonNull).collect(toSet());
+ Map<String, UserDto> userDtoByUuid = dbClient.userDao().selectByUuids(dbSession, assigneeUuids).stream().collect(toMap(UserDto::getUuid, u -> u));
+
int i = 1;
- for (Map.Entry<String, MetricStatsInt> assigneeStats : fiveBiggest(stats.getDistributedMetricStats(metric), MetricStatsInt::getOnLeak)) {
- String login = assigneeStats.getKey();
- UserDto user = dbClient.userDao().selectByLogin(dbSession, login);
- String name = user == null ? login : user.getName();
+ for (Map.Entry<String, MetricStatsInt> assigneeStats : entries) {
+ String assigneeUuid = assigneeStats.getKey();
+ UserDto user = userDtoByUuid.get(assigneeUuid);
+ String name = user == null ? assigneeUuid : user.getName();
setFieldValue(metric + DOT + i + LABEL, name);
setFieldValue(metric + DOT + i + COUNT, String.valueOf(assigneeStats.getValue().getOnLeak()));
i++;
public void add(DefaultIssue issue) {
globalStatistics.add(issue);
- String login = issue.assignee();
- if (login != null) {
- assigneesStatistics.computeIfAbsent(login, a -> new Stats(onLeakPredicate)).add(issue);
+ String userUuid = issue.assignee();
+ if (userUuid != null) {
+ assigneesStatistics.computeIfAbsent(userUuid, a -> new Stats(onLeakPredicate)).add(issue);
}
}
if (ruleKey != null) {
distributions.get(RULE).increment(ruleKey.toString(), isOnLeak);
}
- String assignee = issue.assignee();
- if (assignee != null) {
- distributions.get(ASSIGNEE).increment(assignee, isOnLeak);
+ String assigneeUuid = issue.assignee();
+ if (assigneeUuid != null) {
+ distributions.get(ASSIGNEE).increment(assigneeUuid, isOnLeak);
}
for (String tag : issue.tags()) {
distributions.get(TAG).increment(tag, isOnLeak);
responseWriter.write(key, preloadedResponseData, request, response);
}
- private SearchResponseData assign(String issueKey, @Nullable String assignee) {
+ private SearchResponseData assign(String issueKey, @Nullable String login) {
try (DbSession dbSession = dbClient.openSession(false)) {
IssueDto issueDto = issueFinder.getByKey(dbSession, issueKey);
DefaultIssue issue = issueDto.toDefaultIssue();
- UserDto user = getUser(dbSession, assignee);
+ UserDto user = getUser(dbSession, login);
if (user != null) {
checkMembership(dbSession, issueDto, user);
}
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
-import java.util.stream.Collectors;
import org.sonar.api.issue.DefaultTransitions;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.issue.IssueDto;
import org.sonar.db.rule.RuleDefinitionDto;
+import org.sonar.db.user.UserDto;
import org.sonar.server.issue.Action;
import org.sonar.server.issue.AddTagsAction;
import org.sonar.server.issue.AssignAction;
import static com.google.common.collect.ImmutableMap.of;
import static java.lang.String.format;
import static java.util.function.Function.identity;
+import static java.util.stream.Collectors.toMap;
+import static java.util.stream.Collectors.toSet;
import static org.sonar.api.issue.DefaultTransitions.REOPEN;
import static org.sonar.api.rule.Severity.BLOCKER;
import static org.sonar.api.rules.RuleType.BUG;
refreshLiveMeasures(dbSession, bulkChangeData, result);
- items.forEach(sendNotification(issueChangeContext, bulkChangeData));
+ Set<String> assigneeUuids = items.stream().map(DefaultIssue::assignee).filter(Objects::nonNull).collect(toSet());
+ Map<String, UserDto> userDtoByUuid = dbClient.userDao().selectByUuids(dbSession, assigneeUuids).stream().collect(toMap(UserDto::getUuid, u -> u));
+
+ items.forEach(sendNotification(issueChangeContext, bulkChangeData, userDtoByUuid));
return result;
}
}
Set<String> touchedComponentUuids = result.success.stream()
.map(DefaultIssue::componentUuid)
- .collect(Collectors.toSet());
+ .collect(toSet());
List<ComponentDto> touchedComponents = touchedComponentUuids.stream()
.map(data.componentsByUuid::get)
.collect(MoreCollectors.toList(touchedComponentUuids.size()));
bulkChangeData.getCommentAction().ifPresent(action -> action.execute(bulkChangeData.getProperties(action.key()), actionContext));
}
- private Consumer<DefaultIssue> sendNotification(IssueChangeContext issueChangeContext, BulkChangeData bulkChangeData) {
+ private Consumer<DefaultIssue> sendNotification(IssueChangeContext issueChangeContext, BulkChangeData bulkChangeData,
+ Map<String, UserDto> userDtoByUuid) {
return issue -> {
if (bulkChangeData.sendNotification) {
notificationService.scheduleForSending(new IssueChangeNotification()
.setIssue(issue)
+ .setAssignee(userDtoByUuid.get(issue.assignee()))
.setChangeAuthorLogin(issueChangeContext.login())
.setRuleName(bulkChangeData.rulesByKey.get(issue.ruleKey()).getName())
.setProject(bulkChangeData.projectsByUuid.get(issue.projectUuid()))
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.rule.RuleDefinitionDto;
+import org.sonar.db.user.UserDto;
import org.sonar.server.es.Facets;
import org.sonar.server.es.SearchOptions;
import org.sonar.server.issue.IssueQuery;
import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Strings.nullToEmpty;
import static com.google.common.collect.Iterables.concat;
import static com.google.common.collect.Sets.newHashSet;
import static java.lang.String.format;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.toList;
import static org.sonar.api.utils.Paging.forPageIndex;
import static org.sonar.core.util.stream.MoreCollectors.toSet;
import static org.sonar.server.es.SearchOptions.MAX_LIMIT;
+import static org.sonar.server.issue.IssueQueryFactory.UNKNOWN;
import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
import static org.sonar.server.ws.KeyExamples.KEY_PULL_REQUEST_EXAMPLE_001;
public class SearchAction implements IssuesWsAction {
+ public static final String LOGIN_MYSELF = "__me__";
+
private static final String INTERNAL_PARAMETER_DISCLAIMER = "This parameter is mostly used by the Issues page, please prefer usage of the componentKeys parameter. ";
private static final Set<String> IGNORED_FACETS = newHashSet(PARAM_PLANNED, DEPRECATED_PARAM_ACTION_PLANS, PARAM_REPORTERS);
private static final Set<String> FACETS_REQUIRING_PROJECT_OR_ORGANIZATION = newHashSet(PARAM_FILE_UUIDS, PARAM_DIRECTORIES, PARAM_MODULE_UUIDS);
@Override
public final void handle(Request request, Response response) {
- SearchWsResponse searchWsResponse = doHandle(toSearchWsRequest(request), request);
+ SearchRequest searchRequest = toSearchWsRequest(request)
+ .setAssigneesUuid(getLogins(request));
+ SearchWsResponse searchWsResponse = doHandle(searchRequest, request);
writeProtobuf(searchWsResponse, request, response);
}
+ private List<String> getLogins(Request request) {
+
+ List<String> assigneeLogins = request.paramAsStrings(PARAM_ASSIGNEES);
+
+ List<String> onlyLogins = new ArrayList<>();
+ for (String login : ofNullable(assigneeLogins).orElse(emptyList())) {
+ if (LOGIN_MYSELF.equals(login)) {
+ if (userSession.getLogin() == null) {
+ onlyLogins.add(UNKNOWN);
+ } else {
+ onlyLogins.add(userSession.getLogin());
+ }
+ } else {
+ onlyLogins.add(login);
+ }
+ }
+
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ List<UserDto> userDtos = dbClient.userDao().selectByLogins(dbSession, onlyLogins);
+ List<String> assigneeUuid = userDtos.stream().map(UserDto::getUuid).collect(toList());
+
+ if ((assigneeLogins != null) && firstNonNull(assigneeUuid, emptyList()).isEmpty()) {
+ assigneeUuid = ImmutableList.of("non-existent-uuid");
+ }
+ return assigneeUuid;
+ }
+ }
+
private SearchWsResponse doHandle(SearchRequest request, Request wsRequest) {
// prepare the Elasticsearch request
SearchOptions options = createSearchOptionsFromRequest(request);
EnumSet<SearchAdditionalField> additionalFields = SearchAdditionalField.getFromRequest(request);
+
IssueQuery query = issueQueryFactory.create(request);
// execute request
.filter(FACETS_REQUIRING_PROJECT_OR_ORGANIZATION::contains)
.collect(toSet());
checkArgument(facetsRequiringProjectOrOrganizationParameter.isEmpty() ||
- (!query.projectUuids().isEmpty()) || query.organizationUuid() != null, "Facet(s) '%s' require to also filter by project or organization",
+ (!query.projectUuids().isEmpty()) || query.organizationUuid() != null, "Facet(s) '%s' require to also filter by project or organization",
COMA_JOINER.join(facetsRequiringProjectOrOrganizationParameter));
}
SearchResponseData preloadedData = new SearchResponseData(emptyList());
// can be used to get total debt.
facets = reorderFacets(facets, options.getFacets());
replaceRuleIdsByRuleKeys(facets, firstNonNull(data.getRules(), emptyList()));
+ replaceAssigneeUuidByUserLogin(facets, data, PARAM_ASSIGNEES);
+ replaceAssigneeUuidByUserLogin(facets, data, FACET_ASSIGNED_TO_ME);
// FIXME allow long in Paging
Paging paging = forPageIndex(options.getPage()).withPageSize(options.getLimit()).andTotal((int) result.getHits().getTotalHits());
return searchResponseFormat.formatSearch(additionalFields, data, paging, facets);
}
+ private static void replaceAssigneeUuidByUserLogin(@Nullable Facets facets, SearchResponseData data, String facet) {
+ if (facets == null) {
+ return;
+ }
+ LinkedHashMap<String, Long> assigneeFacets = facets.get(facet);
+ if (assigneeFacets == null) {
+ return;
+ }
+
+ LinkedHashMap<String, Long> newAssigneeFacets = new LinkedHashMap<>();
+ assigneeFacets.forEach((k, v) -> newAssigneeFacets.put(nullToEmpty(data.getLoginByUserUuid(k)), v));
+ assigneeFacets.clear();
+ assigneeFacets.putAll(newAssigneeFacets);
+ }
+
private void replaceRuleIdsByRuleKeys(@Nullable Facets facets, List<RuleDefinitionDto> alreadyLoadedRules) {
if (facets == null) {
return;
alreadyLoadedRules
.stream()
.map(RuleDefinitionDto::getId)
- .collect(Collectors.toList()));
+ .collect(toList()));
List<RuleDefinitionDto> ruleDefinitions = Stream.concat(
alreadyLoadedRules.stream(),
addMandatoryValuesToFacet(facets, PARAM_PROJECT_UUIDS, request.getProjectUuids());
List<String> assignees = Lists.newArrayList("");
- List<String> assigneesFromRequest = request.getAssignees();
+ List<String> assigneesFromRequest = request.getAssigneeUuids();
if (assigneesFromRequest != null) {
assignees.addAll(assigneesFromRequest);
- assignees.remove(IssueQueryFactory.LOGIN_MYSELF);
+ assignees.remove(LOGIN_MYSELF);
}
addMandatoryValuesToFacet(facets, PARAM_ASSIGNEES, assignees);
- addMandatoryValuesToFacet(facets, FACET_ASSIGNED_TO_ME, singletonList(userSession.getLogin()));
+ addMandatoryValuesToFacet(facets, FACET_ASSIGNED_TO_ME, singletonList(userSession.getUuid()));
addMandatoryValuesToFacet(facets, PARAM_RULES, request.getRules());
addMandatoryValuesToFacet(facets, PARAM_LANGUAGES, request.getLanguages());
addMandatoryValuesToFacet(facets, PARAM_TAGS, request.getTags());
}
requestedFacets.stream()
.filter(facetName -> !FACET_ASSIGNED_TO_ME.equals(facetName))
+ .filter(facetName -> !PARAM_ASSIGNEES.equals(facetName))
.filter(facetName -> !IGNORED_FACETS.contains(facetName))
.forEach(facetName -> {
LinkedHashMap<String, Long> buckets = facets.get(facetName);
return;
}
requestParams.stream()
- .filter(param -> !buckets.containsKey(param) && !IssueQueryFactory.LOGIN_MYSELF.equals(param))
+ .filter(param -> !buckets.containsKey(param) && !LOGIN_MYSELF.equals(param))
// Prevent appearance of a glitch value due to dedicated parameter for this facet
.forEach(param -> buckets.put(param, 0L));
});
private void collectLoggedInUser(SearchResponseLoader.Collector collector) {
if (userSession.isLoggedIn()) {
- collector.add(SearchAdditionalField.USERS, userSession.getLogin());
+ collector.add(SearchAdditionalField.USERS, userSession.getUuid());
}
}
collector.addComponentUuids(request.getFileUuids());
collector.addComponentUuids(request.getModuleUuids());
collector.addComponentUuids(request.getComponentRootUuids());
- collector.addAll(SearchAdditionalField.USERS, request.getAssignees());
+ collector.addAll(SearchAdditionalField.USERS, request.getAssigneeUuids());
}
private static SearchRequest toSearchWsRequest(Request request) {
.setAdditionalFields(request.paramAsStrings(PARAM_ADDITIONAL_FIELDS))
.setAsc(request.paramAsBoolean(PARAM_ASC))
.setAssigned(request.paramAsBoolean(PARAM_ASSIGNED))
- .setAssignees(request.paramAsStrings(PARAM_ASSIGNEES))
.setAuthors(request.paramAsStrings(PARAM_AUTHORS))
.setComponentKeys(request.paramAsStrings(PARAM_COMPONENT_KEYS))
.setComponentRootUuids(request.paramAsStrings(PARAM_COMPONENT_ROOT_UUIDS))
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ListMultimap;
+
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
+
import org.sonar.db.component.ComponentDto;
import org.sonar.db.issue.IssueChangeDto;
import org.sonar.db.issue.IssueDto;
private final List<IssueDto> issues;
private Long effortTotal = null;
- private List<UserDto> users = null;
+ private final Map<String, UserDto> usersByUuid = new HashMap<>();
private List<RuleDefinitionDto> rules = null;
private final Map<String, String> organizationKeysByUuid = new HashMap<>();
private final Map<String, ComponentDto> componentsByUuid = new HashMap<>();
return componentsByUuid.get(uuid);
}
- @CheckForNull
public List<UserDto> getUsers() {
- return users;
+ return new ArrayList<>(usersByUuid.values());
}
@CheckForNull
return null;
}
- public void setUsers(@Nullable List<UserDto> users) {
- this.users = users;
+ public void addUsers(@Nullable List<UserDto> users) {
+ if (users != null) {
+ users.forEach(u -> usersByUuid.put(u.getUuid(), u));
+ }
}
public void setRules(@Nullable List<RuleDefinitionDto> rules) {
public void addOrganization(OrganizationDto organizationDto) {
this.organizationKeysByUuid.put(organizationDto.getUuid(), organizationDto.getKey());
}
+
+ @CheckForNull
+ public String getLoginByUserUuid(@Nullable String userUuid) {
+ UserDto userDto = usersByUuid.get(userUuid);
+ if (userDto != null) {
+ return userDto.getLogin();
+ }
+ return null;
+ }
}
issueBuilder.setExternalRuleEngine(engineNameFrom(dto.getRuleKey()));
}
issueBuilder.setSeverity(Common.Severity.valueOf(dto.getSeverity()));
- setNullable(emptyToNull(dto.getAssignee()), issueBuilder::setAssignee);
+ setNullable(data.getLoginByUserUuid(dto.getAssigneeUuid()), issueBuilder::setAssignee);
setNullable(emptyToNull(dto.getResolution()), issueBuilder::setResolution);
issueBuilder.setStatus(dto.getStatus());
issueBuilder.setMessage(nullToEmpty(dto.getMessage()));
wsComment
.clear()
.setKey(comment.getKey())
- .setLogin(nullToEmpty(comment.getUserLogin()))
+ .setLogin(nullToEmpty(data.getLoginByUserUuid(comment.getUserLogin())))
.setUpdatable(data.isUpdatableComment(comment.getKey()))
.setCreatedAt(DateUtils.formatDateTime(new Date(comment.getIssueChangeCreationDate())));
if (markdown != null) {
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Sets.difference;
import static java.util.Collections.emptyList;
+import static java.util.Optional.ofNullable;
import static java.util.stream.Stream.concat;
import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
import static org.sonar.core.util.stream.MoreCollectors.toList;
collector.collect(result.getIssues());
loadRules(preloadedResponseData, collector, dbSession, result);
- // order is important - loading of comments complete the list of users: loadComments() is
- // before loadUsers()
+ // order is important - loading of comments complete the list of users: loadComments() is before loadUsers()
loadComments(collector, dbSession, result);
- loadUsers(preloadedResponseData, collector, dbSession, result);
+ loadUsers(preloadedResponseData, collector, dbSession, result, facets);
loadComponents(preloadedResponseData, collector, dbSession, result);
loadOrganizations(dbSession, result);
loadActionsAndTransitions(collector, result);
.collect(Collectors.toList());
}
- private void loadUsers(SearchResponseData preloadedResponseData, Collector collector, DbSession dbSession, SearchResponseData result) {
+ private void loadUsers(SearchResponseData preloadedResponseData, Collector collector, DbSession dbSession, SearchResponseData result, @Nullable Facets facets) {
+ Set<String> usersUuidToLoad = new HashSet<>();
+ // logged in user
+ ofNullable(userSession.getUuid()).ifPresent(usersUuidToLoad::add);
+
+ // add from issues (uuid -> login)
+ result.getIssues().forEach(issue -> ofNullable(issue.getAssigneeUuid()).ifPresent(usersUuidToLoad::add));
+
+ // add from facets (uuid -> login)
+ if (facets != null) {
+ getAssigneesFacet(facets).forEach((key, value) -> usersUuidToLoad.add(key));
+ }
+
+ // from facets
if (collector.contains(USERS)) {
- List<UserDto> preloadedUsers = firstNonNull(preloadedResponseData.getUsers(), emptyList());
- Set<String> preloadedLogins = preloadedUsers.stream().map(UserDto::getLogin).collect(MoreCollectors.toSet(preloadedUsers.size()));
- Set<String> requestedLogins = collector.get(USERS);
- Set<String> loginsToLoad = copyOf(difference(requestedLogins, preloadedLogins));
-
- if (loginsToLoad.isEmpty()) {
- result.setUsers(preloadedUsers);
- } else {
- List<UserDto> loadedUsers = dbClient.userDao().selectByLogins(dbSession, loginsToLoad);
- result.setUsers(concat(preloadedUsers.stream(), loadedUsers.stream()).collect(toList(preloadedUsers.size() + loadedUsers.size())));
- }
+ usersUuidToLoad.addAll(collector.get(USERS));
}
+
+ List<UserDto> preloadedUsers = firstNonNull(preloadedResponseData.getUsers(), emptyList());
+ result.addUsers(preloadedUsers);
+ preloadedUsers.forEach(userDto -> usersUuidToLoad.remove(userDto.getUuid()));
+
+ result.addUsers(dbClient.userDao().selectByUuids(dbSession, usersUuidToLoad));
+ }
+
+ private static HashMap<String, Long> getAssigneesFacet(Facets facets) {
+ LinkedHashMap<String, Long> assigneeFacet = facets.get("assignees");
+ return assigneeFacet != null ? assigneeFacet : new LinkedHashMap<>();
}
private void loadComponents(SearchResponseData preloadedResponseData, Collector collector, DbSession dbSession, SearchResponseData result) {
List<IssueChangeDto> comments = dbClient.issueChangeDao().selectByTypeAndIssueKeys(dbSession, collector.getIssueKeys(), IssueChangeDto.TYPE_COMMENT);
result.setComments(comments);
for (IssueChangeDto comment : comments) {
+ // TODO GJT when addressing ticket on IssueChangesUuid
collector.add(USERS, comment.getUserLogin());
if (canEditOrDelete(comment)) {
result.addUpdatableComment(comment.getKey());
componentUuids.add(issue.getComponentUuid());
projectUuids.add(issue.getProjectUuid());
ruleIds.add(issue.getRuleId());
- add(USERS, issue.getAssignee());
+ add(USERS, issue.getAssigneeUuid());
collectComponentsFromIssueLocations(issue);
}
}
return null;
}
+ @Override
+ public String getUuid() {
+ return null;
+ }
+
@Override
public String getName() {
return null;
return userDto == null ? null : userDto.getLogin();
}
+ @Override
+ @CheckForNull
+ public String getUuid() {
+ return userDto == null ? null : userDto.getUuid();
+ }
+
@Override
@CheckForNull
public String getName() {
return get().getLogin();
}
+ @Override
+ @CheckForNull
+ public String getUuid() {
+ return get().getUuid();
+ }
+
@Override
@CheckForNull
public String getName() {
@CheckForNull
String getLogin();
+ /**
+ * Uuid of the authenticated user. Returns {@code null}
+ * if {@link #isLoggedIn()} is {@code false}.
+ */
+ @CheckForNull
+ String getUuid();
+
/**
* Name of the authenticated user. Returns {@code null}
* if {@link #isLoggedIn()} is {@code false}.
@Test
public void session_is_anonymous() {
assertThat(underTest.getLogin()).isNull();
+ assertThat(underTest.getUuid()).isNull();
assertThat(underTest.isLoggedIn()).isFalse();
assertThat(underTest.getName()).isNull();
assertThat(underTest.getUserId()).isNull();
import org.sonar.db.component.ComponentDto;
import org.sonar.db.issue.IssueDto;
import org.sonar.db.rule.RuleDefinitionDto;
+import org.sonar.db.user.UserDto;
import org.sonar.scanner.protocol.Constants.Severity;
import org.sonar.scanner.protocol.input.ScannerInput.ServerIssue;
import org.sonar.server.component.TestComponentFinder;
.setMessage(null)
.setLine(null)
.setChecksum(null)
- .setAssignee(null));
+ .setAssigneeUuid(null));
addPermissionTo(project);
ServerIssue serverIssue = call(project.getKey());
@Test
public void test_fields_with_non_null_values() throws Exception {
+ UserDto user = db.users().insertUser(u -> u.setLogin("simon").setName("Simon").setEmail("simon@email.com"));
RuleDefinitionDto rule = db.rules().insert();
ComponentDto project = db.components().insertPrivateProject();
ComponentDto module = db.components().insertComponent(newModuleDto(project));
.setMessage("the message")
.setLine(10)
.setChecksum("ABC")
- .setAssignee("foo"));
+ .setAssigneeUuid(user.getUuid()));
addPermissionTo(project);
ServerIssue serverIssue = call(project.getKey());
assertThat(serverIssue.getMsg()).isEqualTo(issue.getMessage());
assertThat(serverIssue.getResolution()).isEqualTo(issue.getResolution());
assertThat(serverIssue.getChecksum()).isEqualTo(issue.getChecksum());
- assertThat(serverIssue.getAssigneeLogin()).isEqualTo(issue.getAssignee());
+ assertThat(serverIssue.getAssigneeLogin()).isEqualTo(user.getLogin());
}
@Test
@Test
public void no_default_assignee() {
- assertThat(underTest.loadDefaultAssigneeLogin()).isNull();
+ assertThat(underTest.loadDefaultAssigneeUuid()).isNull();
}
@Test
UserDto userDto = db.users().insertUser("erik");
db.organizations().addMember(organizationDto, userDto);
- assertThat(underTest.loadDefaultAssigneeLogin()).isEqualTo("erik");
+ assertThat(underTest.loadDefaultAssigneeUuid()).isEqualTo(userDto.getUuid());
}
@Test
public void configured_login_does_not_exist() {
settings.setProperty(CoreProperties.DEFAULT_ISSUE_ASSIGNEE, "erik");
- assertThat(underTest.loadDefaultAssigneeLogin()).isNull();
+ assertThat(underTest.loadDefaultAssigneeUuid()).isNull();
}
@Test
settings.setProperty(CoreProperties.DEFAULT_ISSUE_ASSIGNEE, "erik");
db.users().insertUser(user -> user.setLogin("erik").setActive(false));
- assertThat(underTest.loadDefaultAssigneeLogin()).isNull();
+ assertThat(underTest.loadDefaultAssigneeUuid()).isNull();
}
@Test
UserDto userDto = db.users().insertUser("erik");
db.organizations().addMember(otherOrganization, userDto);
- assertThat(underTest.loadDefaultAssigneeLogin()).isNull();
+ assertThat(underTest.loadDefaultAssigneeUuid()).isNull();
}
@Test
settings.setProperty(CoreProperties.DEFAULT_ISSUE_ASSIGNEE, "erik");
UserDto userDto = db.users().insertUser("erik");
db.organizations().addMember(organizationDto, userDto);
- assertThat(underTest.loadDefaultAssigneeLogin()).isEqualTo("erik");
+ assertThat(underTest.loadDefaultAssigneeUuid()).isEqualTo(userDto.getUuid());
// The setting is updated but the assignee hasn't changed
settings.setProperty(CoreProperties.DEFAULT_ISSUE_ASSIGNEE, "other");
- assertThat(underTest.loadDefaultAssigneeLogin()).isEqualTo("erik");
+ assertThat(underTest.loadDefaultAssigneeUuid()).isEqualTo(userDto.getUuid());
}
}
public void set_default_assignee_if_author_not_found() {
addScmUser("john", null);
setSingleChangeset("john", 123456789L, "rev-1");
- when(defaultAssignee.loadDefaultAssigneeLogin()).thenReturn("John C");
+ when(defaultAssignee.loadDefaultAssigneeUuid()).thenReturn("John C");
DefaultIssue issue = new DefaultIssue().setLine(1);
underTest.onIssue(FILE, issue);
setSingleChangeset("john", 123456789L, "rev-1");
DefaultIssue issue = new DefaultIssue().setLine(1)
.setAuthorLogin("john")
- .setAssignee(null);
+ .setAssigneeUuid(null);
underTest.onIssue(FILE, issue);
public void when_noscm_data_is_available_defaultAssignee_should_be_used() {
DefaultIssue issue = new DefaultIssue().setLine(null);
- when(defaultAssignee.loadDefaultAssigneeLogin()).thenReturn("DefaultAssignee");
+ when(defaultAssignee.loadDefaultAssigneeUuid()).thenReturn("DefaultAssignee");
underTest.onIssue(FILE, issue);
assertThat(issue.assignee()).isEqualTo("DefaultAssignee");
"No SCM info has been found for issue DefaultIssue[key=<null>,type=VULNERABILITY,componentUuid=<null>,componentKey=<null>," +
"moduleUuid=<null>,moduleUuidPath=<null>,projectUuid=<null>,projectKey=<null>,ruleKey=<null>,language=<null>,severity=<null>," +
"manualSeverity=false,message=<null>,line=2,gap=<null>,effort=<null>,status=<null>,resolution=<null>," +
- "assignee=<null>,checksum=<null>,attributes=<null>,authorLogin=<null>,comments=<null>,tags=<null>," +
+ "assigneeUuid=<null>,checksum=<null>,attributes=<null>,authorLogin=<null>,comments=<null>,tags=<null>," +
"locations=<null>,isFromExternalRuleEngine=false,creationDate=<null>,updateDate=<null>,closeDate=<null>,currentChange=<null>,changes=<null>,isNew=true,isCopied=false," +
"beingClosed=false,onDisabledRule=false,isChanged=false,sendNotifications=false,selectedAt=<null>]");
}
.build());
}
- private void addScmUser(String scmAccount, String userName) {
- when(scmAccountToUser.getNullable(scmAccount)).thenReturn(userName);
+ private void addScmUser(String scmAccount, String userUuid) {
+ when(scmAccountToUser.getNullable(scmAccount)).thenReturn(userUuid);
}
}
.setResolution(RESOLUTION_FIXED)
.setStatus(STATUS_CLOSED)
.setSeverity(BLOCKER)
- .setAssignee("base assignee")
+ .setAssigneeUuid("base assignee")
.setAuthorLogin("base author")
.setTags(newArrayList("base tag"))
.setOnDisabledRule(true)
.setResolution(RESOLUTION_FIXED)
.setStatus(STATUS_CLOSED)
.setSeverity(BLOCKER)
- .setAssignee("base assignee")
+ .setAssigneeUuid("base assignee")
.setAuthorLogin("base author")
.setTags(newArrayList("base tag"))
.setOnDisabledRule(true)
import org.sonar.server.user.index.UserIndexer;
import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
ScmAccountToUserLoader underTest = new ScmAccountToUserLoader(index, analysisMetadataHolder);
assertThat(underTest.load("missing")).isNull();
- assertThat(underTest.load("jesuis@charlie.com")).isEqualTo(user.getLogin());
+ assertThat(underTest.load("jesuis@charlie.com")).isEqualTo(user.getUuid());
}
@Test
UserIndex index = new UserIndex(es.client(), System2.INSTANCE);
ScmAccountToUserLoader underTest = new ScmAccountToUserLoader(index, analysisMetadataHolder);
try {
- underTest.loadAll(Collections.emptyList());
+ underTest.loadAll(emptyList());
fail();
} catch (UnsupportedOperationException ignored) {
}
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.sonar.api.issue.Issue.STATUS_OPEN;
+import static org.sonar.api.rules.RuleType.CODE_SMELL;
public class UpdateConflictResolverTest {
public void should_reload_issue_and_resolve_conflict() {
DefaultIssue issue = new DefaultIssue()
.setKey("ABCDE")
- .setType(RuleType.CODE_SMELL)
+ .setType(CODE_SMELL)
.setRuleKey(RuleKey.of("squid", "AvoidCycles"))
.setProjectUuid("U1")
.setComponentUuid("U2")
.setNew(false)
- .setStatus(Issue.STATUS_OPEN);
+ .setStatus(STATUS_OPEN);
// Issue as seen and changed by end-user
IssueMapper mapper = mock(IssueMapper.class);
when(mapper.selectByKey("ABCDE")).thenReturn(
new IssueDto()
.setKee("ABCDE")
- .setType(RuleType.CODE_SMELL)
+ .setType(CODE_SMELL)
.setRuleId(10)
.setRuleKey("squid", "AvoidCycles")
.setProjectUuid("U1")
.setComponentUuid("U2")
.setLine(10)
- .setStatus(Issue.STATUS_OPEN)
+ .setStatus(STATUS_OPEN)
// field changed by user
- .setAssignee("arthur")
+ .setAssigneeUuid("arthur-uuid")
);
new UpdateConflictResolver().resolve(issue, mapper);
verify(mapper).update(argument.capture());
IssueDto updatedIssue = argument.getValue();
assertThat(updatedIssue.getKee()).isEqualTo("ABCDE");
- assertThat(updatedIssue.getAssignee()).isEqualTo("arthur");
+ assertThat(updatedIssue.getAssigneeUuid()).isEqualTo("arthur-uuid");
}
@Test
.setNew(false);
// Before starting scan
- issue.setAssignee(null);
+ issue.setAssigneeUuid(null);
issue.setCreationDate(DateUtils.parseDate("2012-01-01"));
issue.setUpdateDate(DateUtils.parseDate("2012-02-02"));
.setLine(10)
.setResolution(Issue.RESOLUTION_FALSE_POSITIVE)
.setStatus(Issue.STATUS_RESOLVED)
- .setAssignee("arthur")
+ .setAssigneeUuid("arthur")
.setSeverity(Severity.MAJOR)
.setManualSeverity(false);
.setRuleKey(RuleKey.of("squid", "AvoidCycles"))
.setComponentKey("struts:org.apache.struts.Action")
.setNew(false)
- .setStatus(Issue.STATUS_OPEN);
+ .setStatus(STATUS_OPEN);
// Changed by scan
issue.setSeverity(Severity.BLOCKER);
// Issue as seen and changed by end-user
IssueDto dbIssue = new IssueDto()
.setKee("ABCDE")
- .setStatus(Issue.STATUS_OPEN)
+ .setStatus(STATUS_OPEN)
.setSeverity(Severity.INFO)
.setManualSeverity(true);
*/
package org.sonar.server.computation.task.projectanalysis.step;
+import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.sonar.api.utils.Duration;
import org.sonar.api.utils.System2;
import org.sonar.core.issue.DefaultIssue;
+import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.rule.RuleDefinitionDto;
+import org.sonar.db.user.UserDto;
import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
import org.sonar.server.computation.task.projectanalysis.analysis.Branch;
import org.sonar.server.computation.task.projectanalysis.component.Component;
import org.sonar.server.notification.NotificationService;
import org.sonar.server.util.cache.DiskCache;
+import static java.util.Arrays.stream;
+import static java.util.Collections.shuffle;
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Stream.concat;
import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentCaptor.forClass;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto;
import static org.sonar.db.rule.RuleTesting.newRule;
import static org.sonar.server.computation.task.projectanalysis.component.ReportComponent.builder;
+import static org.sonar.server.computation.task.projectanalysis.step.SendIssueNotificationsStep.NOTIF_TYPES;
public class SendIssueNotificationsStepTest extends BaseStepTest {
private static final int FIVE_MINUTES_IN_MS = 1000 * 60 * 5;
private static final Duration ISSUE_DURATION = Duration.create(100L);
- private static final String ISSUE_ASSIGNEE = "John";
private static final Component FILE = builder(Component.Type.FILE, 11).build();
private static final Component PROJECT = builder(Type.PROJECT, 1)
public RuleRepositoryRule ruleRepository = new RuleRepositoryRule();
@Rule
public TemporaryFolder temp = new TemporaryFolder();
+ @Rule
+ public DbTester db = DbTester.create(System2.INSTANCE);
private final Random random = new Random();
private final RuleType randomRuleType = RuleType.values()[random.nextInt(RuleType.values().length)];
public void setUp() throws Exception {
issueCache = new IssueCache(temp.newFile(), System2.INSTANCE);
underTest = new SendIssueNotificationsStep(issueCache, ruleRepository, treeRootHolder, notificationService, analysisMetadataHolder,
- newIssuesNotificationFactory);
+ newIssuesNotificationFactory, db.getDbClient());
when(newIssuesNotificationFactory.newNewIssuesNotification()).thenReturn(newIssuesNotificationMock);
when(newIssuesNotificationFactory.newMyNewIssuesNotification()).thenReturn(myNewIssuesNotificationMock);
@Test
public void do_not_send_notifications_if_no_subscribers() {
- when(notificationService.hasProjectSubscribersForTypes(PROJECT.getUuid(), SendIssueNotificationsStep.NOTIF_TYPES)).thenReturn(false);
+ when(notificationService.hasProjectSubscribersForTypes(PROJECT.getUuid(), NOTIF_TYPES)).thenReturn(false);
underTest.execute();
Random random = new Random();
Integer[] efforts = IntStream.range(0, 1 + random.nextInt(10)).mapToObj(i -> 10_000 * i).toArray(Integer[]::new);
Integer[] backDatedEfforts = IntStream.range(0, 1 + random.nextInt(10)).mapToObj(i -> 10 + random.nextInt(100)).toArray(Integer[]::new);
- Duration expectedEffort = Duration.create(Arrays.stream(efforts).mapToInt(i -> i).sum());
- List<DefaultIssue> issues = Stream.concat(Arrays.stream(efforts)
+ Duration expectedEffort = Duration.create(stream(efforts).mapToInt(i -> i).sum());
+ List<DefaultIssue> issues = concat(stream(efforts)
.map(effort -> new DefaultIssue().setType(randomRuleType).setEffort(Duration.create(effort))
.setCreationDate(new Date(ANALYSE_DATE))),
- Arrays.stream(backDatedEfforts)
+ stream(backDatedEfforts)
.map(effort -> new DefaultIssue().setType(randomRuleType).setEffort(Duration.create(effort))
.setCreationDate(new Date(ANALYSE_DATE - FIVE_MINUTES_IN_MS))))
- .collect(Collectors.toList());
- Collections.shuffle(issues);
+ .collect(toList());
+ shuffle(issues);
DiskCache<DefaultIssue>.DiskAppender issueCache = this.issueCache.newAppender();
issues.forEach(issueCache::append);
- when(notificationService.hasProjectSubscribersForTypes(PROJECT.getUuid(), SendIssueNotificationsStep.NOTIF_TYPES)).thenReturn(true);
+ when(notificationService.hasProjectSubscribersForTypes(PROJECT.getUuid(), NOTIF_TYPES)).thenReturn(true);
underTest.execute();
verify(notificationService).deliver(newIssuesNotificationMock);
- ArgumentCaptor<NewIssuesStatistics.Stats> statsCaptor = ArgumentCaptor.forClass(NewIssuesStatistics.Stats.class);
+ ArgumentCaptor<NewIssuesStatistics.Stats> statsCaptor = forClass(NewIssuesStatistics.Stats.class);
verify(newIssuesNotificationMock).setStatistics(eq(PROJECT.getName()), statsCaptor.capture());
verify(newIssuesNotificationMock).setDebt(expectedEffort);
NewIssuesStatistics.Stats stats = statsCaptor.getValue();
new DefaultIssue().setType(randomRuleType).setEffort(ISSUE_DURATION)
.setCreationDate(new Date(ANALYSE_DATE - FIVE_MINUTES_IN_MS)))
.close();
- when(notificationService.hasProjectSubscribersForTypes(PROJECT.getUuid(), SendIssueNotificationsStep.NOTIF_TYPES)).thenReturn(true);
+ when(notificationService.hasProjectSubscribersForTypes(PROJECT.getUuid(), NOTIF_TYPES)).thenReturn(true);
underTest.execute();
ComponentDto branch = setUpProjectWithBranch();
issueCache.newAppender().append(
new DefaultIssue().setType(randomRuleType).setEffort(ISSUE_DURATION).setCreationDate(new Date(ANALYSE_DATE))).close();
- when(notificationService.hasProjectSubscribersForTypes(branch.uuid(), SendIssueNotificationsStep.NOTIF_TYPES)).thenReturn(true);
+ when(notificationService.hasProjectSubscribersForTypes(branch.uuid(), NOTIF_TYPES)).thenReturn(true);
analysisMetadataHolder.setBranch(newBranch());
underTest.execute();
ComponentDto branch = setUpProjectWithBranch();
issueCache.newAppender().append(
new DefaultIssue().setType(randomRuleType).setEffort(ISSUE_DURATION).setCreationDate(new Date(ANALYSE_DATE))).close();
- when(notificationService.hasProjectSubscribersForTypes(branch.uuid(), SendIssueNotificationsStep.NOTIF_TYPES)).thenReturn(true);
+ when(notificationService.hasProjectSubscribersForTypes(branch.uuid(), NOTIF_TYPES)).thenReturn(true);
analysisMetadataHolder.setBranch(newPullRequest());
analysisMetadataHolder.setPullRequestId(PULL_REQUEST_ID);
ComponentDto branch = setUpProjectWithBranch();
issueCache.newAppender().append(
new DefaultIssue().setType(randomRuleType).setEffort(ISSUE_DURATION).setCreationDate(new Date(ANALYSE_DATE - FIVE_MINUTES_IN_MS))).close();
- when(notificationService.hasProjectSubscribersForTypes(branch.uuid(), SendIssueNotificationsStep.NOTIF_TYPES)).thenReturn(true);
+ when(notificationService.hasProjectSubscribersForTypes(branch.uuid(), NOTIF_TYPES)).thenReturn(true);
analysisMetadataHolder.setBranch(newBranch());
underTest.execute();
@Test
public void send_new_issues_notification_to_user() {
+
+ UserDto user = db.users().insertUser();
+
issueCache.newAppender().append(
- new DefaultIssue().setType(randomRuleType).setEffort(ISSUE_DURATION).setAssignee(ISSUE_ASSIGNEE)
+ new DefaultIssue().setType(randomRuleType).setEffort(ISSUE_DURATION).setAssigneeUuid(user.getUuid())
.setCreationDate(new Date(ANALYSE_DATE)))
.close();
when(notificationService.hasProjectSubscribersForTypes(eq(PROJECT.getUuid()), any())).thenReturn(true);
verify(notificationService).deliver(newIssuesNotificationMock);
verify(notificationService).deliver(myNewIssuesNotificationMock);
- verify(myNewIssuesNotificationMock).setAssignee(ISSUE_ASSIGNEE);
+ verify(myNewIssuesNotificationMock).setAssignee(any(UserDto.class));
verify(myNewIssuesNotificationMock).setProject(PROJECT.getPublicKey(), PROJECT.getName(), null, null);
verify(myNewIssuesNotificationMock).setAnalysisDate(new Date(ANALYSE_DATE));
verify(myNewIssuesNotificationMock).setStatistics(eq(PROJECT.getName()), any(NewIssuesStatistics.Stats.class));
}
@Test
- public void send_new_issues_notification_to_user_only_for_those_assigned_to_her() {
- Random random = new Random();
- Integer[] assigned = IntStream.range(0, 1 + random.nextInt(10)).mapToObj(i -> 10_000 * i).toArray(Integer[]::new);
- Integer[] assignedToOther = IntStream.range(0, 1 + random.nextInt(10)).mapToObj(i -> 10 + random.nextInt(100)).toArray(Integer[]::new);
- Duration expectedEffort = Duration.create(Arrays.stream(assigned).mapToInt(i -> i).sum());
- String assignee = randomAlphanumeric(5);
- String otherAssignee = randomAlphanumeric(5);
- List<DefaultIssue> issues = Stream.concat(Arrays.stream(assigned)
- .map(effort -> new DefaultIssue().setType(randomRuleType).setEffort(Duration.create(effort))
- .setAssignee(assignee)
- .setCreationDate(new Date(ANALYSE_DATE))),
- Arrays.stream(assignedToOther)
+ public void send_new_issues_notification_to_user_only_for_those_assigned_to_her() throws IOException {
+
+ UserDto perceval = db.users().insertUser(u -> u.setLogin("perceval"));
+ Integer[] assigned = IntStream.range(0, 5).mapToObj(i -> 10_000 * i).toArray(Integer[]::new);
+ Duration expectedEffort = Duration.create(stream(assigned).mapToInt(i -> i).sum());
+
+ UserDto arthur = db.users().insertUser(u -> u.setLogin("arthur"));
+ Integer[] assignedToOther = IntStream.range(0, 3).mapToObj(i -> 10).toArray(Integer[]::new);
+
+ List<DefaultIssue> issues = concat(stream(assigned)
.map(effort -> new DefaultIssue().setType(randomRuleType).setEffort(Duration.create(effort))
- .setAssignee(otherAssignee)
+ .setAssigneeUuid(perceval.getUuid())
+ .setCreationDate(new Date(ANALYSE_DATE))),
+ stream(assignedToOther)
+ .map(effort -> new DefaultIssue().setType(randomRuleType).setEffort(Duration.create(effort))
+ .setAssigneeUuid(arthur.getUuid())
.setCreationDate(new Date(ANALYSE_DATE))))
- .collect(Collectors.toList());
- Collections.shuffle(issues);
- DiskCache<DefaultIssue>.DiskAppender issueCache = this.issueCache.newAppender();
- issues.forEach(issueCache::append);
- when(notificationService.hasProjectSubscribersForTypes(PROJECT.getUuid(), SendIssueNotificationsStep.NOTIF_TYPES)).thenReturn(true);
+ .collect(toList());
+ shuffle(issues);
+ IssueCache issueCache = new IssueCache(temp.newFile(), System2.INSTANCE);
+ DiskCache<DefaultIssue>.DiskAppender newIssueCache = issueCache.newAppender();
+ issues.forEach(newIssueCache::append);
+
+ when(notificationService.hasProjectSubscribersForTypes(PROJECT.getUuid(), NOTIF_TYPES)).thenReturn(true);
+
+ NewIssuesNotificationFactory newIssuesNotificationFactory = mock(NewIssuesNotificationFactory.class);
+ NewIssuesNotification newIssuesNotificationMock = createNewIssuesNotificationMock();
+ when(newIssuesNotificationFactory.newNewIssuesNotification()).thenReturn(newIssuesNotificationMock);
+
+ MyNewIssuesNotification myNewIssuesNotificationMock1 = createMyNewIssuesNotificationMock();
MyNewIssuesNotification myNewIssuesNotificationMock2 = createMyNewIssuesNotificationMock();
- when(newIssuesNotificationFactory.newMyNewIssuesNotification())
- .thenReturn(myNewIssuesNotificationMock)
- .thenReturn(myNewIssuesNotificationMock2);
+ when(newIssuesNotificationFactory.newMyNewIssuesNotification()).thenReturn(myNewIssuesNotificationMock1).thenReturn(myNewIssuesNotificationMock2);
- underTest.execute();
+ new SendIssueNotificationsStep(issueCache, ruleRepository, treeRootHolder, notificationService, analysisMetadataHolder, newIssuesNotificationFactory, db.getDbClient()).execute();
+
+ verify(notificationService).deliver(myNewIssuesNotificationMock1);
+ Map<String, MyNewIssuesNotification> myNewIssuesNotificationMocksByUsersName = new HashMap<>();
+ ArgumentCaptor<UserDto> userCaptor1 = forClass(UserDto.class);
+ verify(myNewIssuesNotificationMock1).setAssignee(userCaptor1.capture());
+ myNewIssuesNotificationMocksByUsersName.put(userCaptor1.getValue().getLogin(), myNewIssuesNotificationMock1);
- verify(notificationService).deliver(newIssuesNotificationMock);
- verify(notificationService).deliver(myNewIssuesNotificationMock);
verify(notificationService).deliver(myNewIssuesNotificationMock2);
+ ArgumentCaptor<UserDto> userCaptor2 = forClass(UserDto.class);
+ verify(myNewIssuesNotificationMock2).setAssignee(userCaptor2.capture());
+ myNewIssuesNotificationMocksByUsersName.put(userCaptor2.getValue().getLogin(), myNewIssuesNotificationMock2);
+
+ MyNewIssuesNotification myNewIssuesNotificationMock = myNewIssuesNotificationMocksByUsersName.get("perceval");
+ ArgumentCaptor<NewIssuesStatistics.Stats> statsCaptor = forClass(NewIssuesStatistics.Stats.class);
+ verify(myNewIssuesNotificationMock).setStatistics(eq(PROJECT.getName()), statsCaptor.capture());
+ verify(myNewIssuesNotificationMock).setDebt(expectedEffort);
- MyNewIssuesNotification effectiveMyNewIssuesNotificationMock = this.myNewIssuesNotificationMock;
- try {
- verify(effectiveMyNewIssuesNotificationMock).setAssignee(assignee);
- } catch (ArgumentsAreDifferent e) {
- assertThat(e.getMessage())
- .contains("Wanted:\nmyNewIssuesNotification.setAssignee(\"" + assignee + "\")")
- .contains("Actual invocation has different arguments:\n" +
- "myNewIssuesNotification.setAssignee(\"" + otherAssignee + "\")");
- effectiveMyNewIssuesNotificationMock = myNewIssuesNotificationMock2;
- }
- ArgumentCaptor<NewIssuesStatistics.Stats> statsCaptor = ArgumentCaptor.forClass(NewIssuesStatistics.Stats.class);
- verify(effectiveMyNewIssuesNotificationMock).setStatistics(eq(PROJECT.getName()), statsCaptor.capture());
- verify(effectiveMyNewIssuesNotificationMock).setDebt(expectedEffort);
NewIssuesStatistics.Stats stats = statsCaptor.getValue();
assertThat(stats.hasIssues()).isTrue();
// just checking all issues have been added to the stats
@Test
public void send_new_issues_notification_to_user_only_for_non_backdated_issues() {
+ UserDto user = db.users().insertUser();
Random random = new Random();
Integer[] efforts = IntStream.range(0, 1 + random.nextInt(10)).mapToObj(i -> 10_000 * i).toArray(Integer[]::new);
Integer[] backDatedEfforts = IntStream.range(0, 1 + random.nextInt(10)).mapToObj(i -> 10 + random.nextInt(100)).toArray(Integer[]::new);
- Duration expectedEffort = Duration.create(Arrays.stream(efforts).mapToInt(i -> i).sum());
- List<DefaultIssue> issues = Stream.concat(Arrays.stream(efforts)
+ Duration expectedEffort = Duration.create(stream(efforts).mapToInt(i -> i).sum());
+ List<DefaultIssue> issues = concat(stream(efforts)
.map(effort -> new DefaultIssue().setType(randomRuleType).setEffort(Duration.create(effort))
- .setAssignee(ISSUE_ASSIGNEE)
+ .setAssigneeUuid(user.getUuid())
.setCreationDate(new Date(ANALYSE_DATE))),
- Arrays.stream(backDatedEfforts)
+ stream(backDatedEfforts)
.map(effort -> new DefaultIssue().setType(randomRuleType).setEffort(Duration.create(effort))
- .setAssignee(ISSUE_ASSIGNEE)
+ .setAssigneeUuid(user.getUuid())
.setCreationDate(new Date(ANALYSE_DATE - FIVE_MINUTES_IN_MS))))
- .collect(Collectors.toList());
- Collections.shuffle(issues);
+ .collect(toList());
+ shuffle(issues);
DiskCache<DefaultIssue>.DiskAppender issueCache = this.issueCache.newAppender();
issues.forEach(issueCache::append);
- when(notificationService.hasProjectSubscribersForTypes(PROJECT.getUuid(), SendIssueNotificationsStep.NOTIF_TYPES)).thenReturn(true);
+ when(notificationService.hasProjectSubscribersForTypes(PROJECT.getUuid(), NOTIF_TYPES)).thenReturn(true);
underTest.execute();
verify(notificationService).deliver(newIssuesNotificationMock);
verify(notificationService).deliver(myNewIssuesNotificationMock);
- verify(myNewIssuesNotificationMock).setAssignee(ISSUE_ASSIGNEE);
- ArgumentCaptor<NewIssuesStatistics.Stats> statsCaptor = ArgumentCaptor.forClass(NewIssuesStatistics.Stats.class);
+ verify(myNewIssuesNotificationMock).setAssignee(any(UserDto.class));
+ ArgumentCaptor<NewIssuesStatistics.Stats> statsCaptor = forClass(NewIssuesStatistics.Stats.class);
verify(myNewIssuesNotificationMock).setStatistics(eq(PROJECT.getName()), statsCaptor.capture());
verify(myNewIssuesNotificationMock).setDebt(expectedEffort);
NewIssuesStatistics.Stats stats = statsCaptor.getValue();
@Test
public void do_not_send_new_issues_notification_to_user_if_issue_is_backdated() {
+ UserDto user = db.users().insertUser();
issueCache.newAppender().append(
- new DefaultIssue().setType(randomRuleType).setEffort(ISSUE_DURATION).setAssignee(ISSUE_ASSIGNEE)
+ new DefaultIssue().setType(randomRuleType).setEffort(ISSUE_DURATION).setAssigneeUuid(user.getUuid())
.setCreationDate(new Date(ANALYSE_DATE - FIVE_MINUTES_IN_MS)))
.close();
- when(notificationService.hasProjectSubscribersForTypes(PROJECT.getUuid(), SendIssueNotificationsStep.NOTIF_TYPES)).thenReturn(true);
+ when(notificationService.hasProjectSubscribersForTypes(PROJECT.getUuid(), NOTIF_TYPES)).thenReturn(true);
underTest.execute();
}
private void sendIssueChangeNotification(long issueCreatedAt) {
+ UserDto user = db.users().insertUser();
ComponentDto project = newPrivateProjectDto(newOrganizationDto()).setDbKey(PROJECT.getKey()).setLongName(PROJECT.getName());
ComponentDto file = newFileDto(project).setDbKey(FILE.getKey()).setLongName(FILE.getName());
RuleDefinitionDto ruleDefinitionDto = newRule();
DefaultIssue issue = newIssue(ruleDefinitionDto, project, file).toDefaultIssue()
- .setNew(false).setChanged(true).setSendNotifications(true).setCreationDate(new Date(issueCreatedAt));
+ .setNew(false).setChanged(true).setSendNotifications(true).setCreationDate(new Date(issueCreatedAt)).setAssigneeUuid(user.getUuid());
ruleRepository.add(ruleDefinitionDto.getKey()).setName(ruleDefinitionDto.getName());
issueCache.newAppender().append(issue).close();
- when(notificationService.hasProjectSubscribersForTypes(PROJECT.getUuid(), SendIssueNotificationsStep.NOTIF_TYPES)).thenReturn(true);
+ when(notificationService.hasProjectSubscribersForTypes(PROJECT.getUuid(), NOTIF_TYPES)).thenReturn(true);
underTest.execute();
- ArgumentCaptor<IssueChangeNotification> issueChangeNotificationCaptor = ArgumentCaptor.forClass(IssueChangeNotification.class);
+ ArgumentCaptor<IssueChangeNotification> issueChangeNotificationCaptor = forClass(IssueChangeNotification.class);
verify(notificationService).deliver(issueChangeNotificationCaptor.capture());
IssueChangeNotification issueChangeNotification = issueChangeNotificationCaptor.getValue();
assertThat(issueChangeNotification.getFieldValue("key")).isEqualTo(issue.key());
- assertThat(issueChangeNotification.getFieldValue("assignee")).isEqualTo(issue.assignee());
assertThat(issueChangeNotification.getFieldValue("message")).isEqualTo(issue.message());
assertThat(issueChangeNotification.getFieldValue("ruleName")).isEqualTo(ruleDefinitionDto.getName());
assertThat(issueChangeNotification.getFieldValue("projectName")).isEqualTo(project.longName());
assertThat(issueChangeNotification.getFieldValue("projectKey")).isEqualTo(project.getKey());
assertThat(issueChangeNotification.getFieldValue("componentKey")).isEqualTo(file.getKey());
assertThat(issueChangeNotification.getFieldValue("componentName")).isEqualTo(file.longName());
+ assertThat(issueChangeNotification.getFieldValue("assignee")).isEqualTo(user.getLogin());
}
@Test
.setCreationDate(new Date(issueCreatedAt));
ruleRepository.add(ruleDefinitionDto.getKey()).setName(ruleDefinitionDto.getName());
issueCache.newAppender().append(issue).close();
- when(notificationService.hasProjectSubscribersForTypes(branch.uuid(), SendIssueNotificationsStep.NOTIF_TYPES)).thenReturn(true);
+ when(notificationService.hasProjectSubscribersForTypes(branch.uuid(), NOTIF_TYPES)).thenReturn(true);
analysisMetadataHolder.setBranch(newBranch());
underTest.execute();
- ArgumentCaptor<IssueChangeNotification> issueChangeNotificationCaptor = ArgumentCaptor.forClass(IssueChangeNotification.class);
+ ArgumentCaptor<IssueChangeNotification> issueChangeNotificationCaptor = forClass(IssueChangeNotification.class);
verify(notificationService).deliver(issueChangeNotificationCaptor.capture());
IssueChangeNotification issueChangeNotification = issueChangeNotificationCaptor.getValue();
assertThat(issueChangeNotification.getFieldValue("projectName")).isEqualTo(branch.longName());
private MyNewIssuesNotification createMyNewIssuesNotificationMock() {
MyNewIssuesNotification notification = mock(MyNewIssuesNotification.class);
- when(notification.setAssignee(any())).thenReturn(notification);
+ when(notification.setAssignee(any(UserDto.class))).thenReturn(notification);
when(notification.setProject(any(), any(), any(), any())).thenReturn(notification);
when(notification.setProjectVersion(any())).thenReturn(notification);
when(notification.setAnalysisDate(any())).thenReturn(notification);
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.rules.ExpectedException.none;
+import static org.sonar.server.tester.UserSessionRule.standalone;
public class AssignActionTest {
- private static final String ISSUE_CURRENT_ASSIGNEE = "current assignee";
+ private static final String ISSUE_CURRENT_ASSIGNEE_UUID = "current assignee uuid";
@Rule
- public ExpectedException expectedException = ExpectedException.none();
+ public ExpectedException expectedException = none();
@Rule
- public UserSessionRule userSession = UserSessionRule.standalone();
+ public UserSessionRule userSession = standalone();
@Rule
public DbTester db = DbTester.create();
private IssueChangeContext issueChangeContext = IssueChangeContext.createUser(new Date(), "emmerik");
- private DefaultIssue issue = new DefaultIssue().setKey("ABC").setAssignee(ISSUE_CURRENT_ASSIGNEE);
+ private DefaultIssue issue = new DefaultIssue().setKey("ABC").setAssigneeUuid(ISSUE_CURRENT_ASSIGNEE_UUID);
private ComponentDto project;
private Action.Context context;
private OrganizationDto issueOrganizationDto;
boolean executeResult = underTest.execute(properties, context);
assertThat(executeResult).isTrue();
- assertThat(issue.assignee()).isEqualTo(assignee.getLogin());
+ assertThat(issue.assignee()).isEqualTo(assignee.getUuid());
}
@Test
doc.setKey(Uuids.createFast());
doc.setRuleId(nextInt(1000));
doc.setType(RuleType.CODE_SMELL);
- doc.setAssignee("assignee_" + randomAlphabetic(5));
+ doc.setAssigneeUuid("assignee_uuid_" + randomAlphabetic(26));
doc.setAuthorLogin("author_" + randomAlphabetic(5));
doc.setLanguage("language_" + randomAlphabetic(5));
doc.setComponentUuid(Uuids.createFast());
import org.sonar.db.user.UserDto;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.rules.ExpectedException.none;
import static org.sonar.db.user.UserTesting.newUserDto;
import static org.sonar.server.issue.IssueFieldsSetter.ASSIGNEE;
import static org.sonar.server.issue.IssueFieldsSetter.RESOLUTION;
public class IssueFieldsSetterTest {
@Rule
- public ExpectedException thrown = ExpectedException.none();
+ public ExpectedException thrown = none();
- DefaultIssue issue = new DefaultIssue();
- IssueChangeContext context = IssueChangeContext.createUser(new Date(), "emmerik");
-
- IssueFieldsSetter updater = new IssueFieldsSetter();
+ private DefaultIssue issue = new DefaultIssue();
+ private IssueChangeContext context = IssueChangeContext.createUser(new Date(), "emmerik");
+ private IssueFieldsSetter underTest = new IssueFieldsSetter();
@Test
public void assign() {
UserDto user = newUserDto().setLogin("emmerik").setName("Emmerik");
- boolean updated = updater.assign(issue, user, context);
+ boolean updated = underTest.assign(issue, user, context);
assertThat(updated).isTrue();
- assertThat(issue.assignee()).isEqualTo("emmerik");
+ assertThat(issue.assignee()).isEqualTo(user.getUuid());
assertThat(issue.mustSendNotifications()).isTrue();
FieldDiffs.Diff diff = issue.currentChange().get(ASSIGNEE);
assertThat(diff.oldValue()).isEqualTo(UNUSED);
- assertThat(diff.newValue()).isEqualTo("Emmerik");
+ assertThat(diff.newValue()).isEqualTo(user.getUuid());
}
@Test
public void unassign() {
- issue.setAssignee("morgan");
- boolean updated = updater.assign(issue, null, context);
+ issue.setAssigneeUuid("morgan");
+ boolean updated = underTest.assign(issue, null, context);
assertThat(updated).isTrue();
assertThat(issue.assignee()).isNull();
assertThat(issue.mustSendNotifications()).isTrue();
public void change_assignee() {
UserDto user = newUserDto().setLogin("emmerik").setName("Emmerik");
- issue.setAssignee("morgan");
- boolean updated = updater.assign(issue, user, context);
+ issue.setAssigneeUuid("morgan");
+ boolean updated = underTest.assign(issue, user, context);
assertThat(updated).isTrue();
- assertThat(issue.assignee()).isEqualTo("emmerik");
+ assertThat(issue.assignee()).isEqualTo(user.getUuid());
assertThat(issue.mustSendNotifications()).isTrue();
FieldDiffs.Diff diff = issue.currentChange().get(ASSIGNEE);
assertThat(diff.oldValue()).isEqualTo(UNUSED);
- assertThat(diff.newValue()).isEqualTo("Emmerik");
+ assertThat(diff.newValue()).isEqualTo(user.getUuid());
}
@Test
public void not_change_assignee() {
UserDto user = newUserDto().setLogin("morgan").setName("Morgan");
- issue.setAssignee("morgan");
- boolean updated = updater.assign(issue, user, context);
+ issue.setAssigneeUuid(user.getUuid());
+ boolean updated = underTest.assign(issue, user, context);
assertThat(updated).isFalse();
assertThat(issue.currentChange()).isNull();
assertThat(issue.mustSendNotifications()).isFalse();
@Test
public void set_new_assignee() {
- boolean updated = updater.setNewAssignee(issue, "simon", context);
+ boolean updated = underTest.setNewAssignee(issue, "simon", context);
assertThat(updated).isTrue();
assertThat(issue.assignee()).isEqualTo("simon");
assertThat(issue.mustSendNotifications()).isTrue();
@Test
public void not_set_new_assignee_if_new_assignee_is_null() {
- boolean updated = updater.setNewAssignee(issue, null, context);
+ boolean updated = underTest.setNewAssignee(issue, null, context);
assertThat(updated).isFalse();
assertThat(issue.currentChange()).isNull();
assertThat(issue.mustSendNotifications()).isFalse();
@Test
public void fail_with_ISE_when_setting_new_assignee_on_already_assigned_issue() {
- issue.setAssignee("simon");
+ issue.setAssigneeUuid("simon");
thrown.expect(IllegalStateException.class);
thrown.expectMessage("It's not possible to update the assignee with this method, please use assign()");
- updater.setNewAssignee(issue, "julien", context);
+ underTest.setNewAssignee(issue, "julien", context);
}
@Test
public void set_severity() {
- boolean updated = updater.setSeverity(issue, "BLOCKER", context);
+ boolean updated = underTest.setSeverity(issue, "BLOCKER", context);
assertThat(updated).isTrue();
assertThat(issue.severity()).isEqualTo("BLOCKER");
assertThat(issue.manualSeverity()).isFalse();
@Test
public void set_past_severity() {
issue.setSeverity("BLOCKER");
- boolean updated = updater.setPastSeverity(issue, "INFO", context);
+ boolean updated = underTest.setPastSeverity(issue, "INFO", context);
assertThat(updated).isTrue();
assertThat(issue.severity()).isEqualTo("BLOCKER");
assertThat(issue.mustSendNotifications()).isFalse();
@Test
public void update_severity() {
issue.setSeverity("BLOCKER");
- boolean updated = updater.setSeverity(issue, "MINOR", context);
+ boolean updated = underTest.setSeverity(issue, "MINOR", context);
assertThat(updated).isTrue();
assertThat(issue.severity()).isEqualTo("MINOR");
@Test
public void not_change_severity() {
issue.setSeverity("MINOR");
- boolean updated = updater.setSeverity(issue, "MINOR", context);
+ boolean updated = underTest.setSeverity(issue, "MINOR", context);
assertThat(updated).isFalse();
assertThat(issue.mustSendNotifications()).isFalse();
assertThat(issue.currentChange()).isNull();
public void not_revert_manual_severity() {
issue.setSeverity("MINOR").setManualSeverity(true);
try {
- updater.setSeverity(issue, "MAJOR", context);
+ underTest.setSeverity(issue, "MAJOR", context);
} catch (IllegalStateException e) {
assertThat(e).hasMessage("Severity can't be changed");
}
@Test
public void set_manual_severity() {
issue.setSeverity("BLOCKER");
- boolean updated = updater.setManualSeverity(issue, "MINOR", context);
+ boolean updated = underTest.setManualSeverity(issue, "MINOR", context);
assertThat(updated).isTrue();
assertThat(issue.severity()).isEqualTo("MINOR");
@Test
public void not_change_manual_severity() {
issue.setSeverity("MINOR").setManualSeverity(true);
- boolean updated = updater.setManualSeverity(issue, "MINOR", context);
+ boolean updated = underTest.setManualSeverity(issue, "MINOR", context);
assertThat(updated).isFalse();
assertThat(issue.currentChange()).isNull();
assertThat(issue.mustSendNotifications()).isFalse();
@Test
public void set_line() {
- boolean updated = updater.setLine(issue, 123);
+ boolean updated = underTest.setLine(issue, 123);
assertThat(updated).isTrue();
assertThat(issue.line()).isEqualTo(123);
assertThat(issue.mustSendNotifications()).isFalse();
@Test
public void set_past_line() {
issue.setLine(42);
- boolean updated = updater.setPastLine(issue, 123);
+ boolean updated = underTest.setPastLine(issue, 123);
assertThat(updated).isTrue();
assertThat(issue.line()).isEqualTo(42);
assertThat(issue.mustSendNotifications()).isFalse();
@Test
public void line_is_not_changed() {
issue.setLine(123);
- boolean updated = updater.setLine(issue, 123);
+ boolean updated = underTest.setLine(issue, 123);
assertThat(updated).isFalse();
assertThat(issue.line()).isEqualTo(123);
assertThat(issue.currentChange()).isNull();
@Test
public void change_locations() {
issue.setLocations("[1-3]");
- boolean updated = updater.setLocations(issue, "[1-4]");
+ boolean updated = underTest.setLocations(issue, "[1-4]");
assertThat(updated).isTrue();
assertThat(issue.getLocations().toString()).isEqualTo("[1-4]");
assertThat(issue.currentChange()).isNull();
@Test
public void do_not_change_locations() {
issue.setLocations("[1-3]");
- boolean updated = updater.setLocations(issue, "[1-3]");
+ boolean updated = underTest.setLocations(issue, "[1-3]");
assertThat(updated).isFalse();
assertThat(issue.getLocations().toString()).isEqualTo("[1-3]");
assertThat(issue.currentChange()).isNull();
@Test
public void set_locations_for_the_first_time() {
issue.setLocations(null);
- boolean updated = updater.setLocations(issue, "[1-4]");
+ boolean updated = underTest.setLocations(issue, "[1-4]");
assertThat(updated).isTrue();
assertThat(issue.getLocations().toString()).isEqualTo("[1-4]");
assertThat(issue.currentChange()).isNull();
@Test
public void set_resolution() {
- boolean updated = updater.setResolution(issue, "OPEN", context);
+ boolean updated = underTest.setResolution(issue, "OPEN", context);
assertThat(updated).isTrue();
assertThat(issue.resolution()).isEqualTo("OPEN");
@Test
public void not_change_resolution() {
issue.setResolution("FIXED");
- boolean updated = updater.setResolution(issue, "FIXED", context);
+ boolean updated = underTest.setResolution(issue, "FIXED", context);
assertThat(updated).isFalse();
assertThat(issue.resolution()).isEqualTo("FIXED");
assertThat(issue.currentChange()).isNull();
@Test
public void set_status() {
- boolean updated = updater.setStatus(issue, "OPEN", context);
+ boolean updated = underTest.setStatus(issue, "OPEN", context);
assertThat(updated).isTrue();
assertThat(issue.status()).isEqualTo("OPEN");
@Test
public void not_change_status() {
issue.setStatus("CLOSED");
- boolean updated = updater.setStatus(issue, "CLOSED", context);
+ boolean updated = underTest.setStatus(issue, "CLOSED", context);
assertThat(updated).isFalse();
assertThat(issue.status()).isEqualTo("CLOSED");
assertThat(issue.currentChange()).isNull();
@Test
public void set_new_attribute_value() {
- boolean updated = updater.setAttribute(issue, "JIRA", "FOO-123", context);
+ boolean updated = underTest.setAttribute(issue, "JIRA", "FOO-123", context);
assertThat(updated).isTrue();
assertThat(issue.attribute("JIRA")).isEqualTo("FOO-123");
assertThat(issue.currentChange().diffs()).hasSize(1);
@Test
public void unset_attribute() {
issue.setAttribute("JIRA", "FOO-123");
- boolean updated = updater.setAttribute(issue, "JIRA", null, context);
+ boolean updated = underTest.setAttribute(issue, "JIRA", null, context);
assertThat(updated).isTrue();
assertThat(issue.attribute("JIRA")).isNull();
assertThat(issue.currentChange().diffs()).hasSize(1);
@Test
public void not_update_attribute() {
issue.setAttribute("JIRA", "FOO-123");
- boolean updated = updater.setAttribute(issue, "JIRA", "FOO-123", context);
+ boolean updated = underTest.setAttribute(issue, "JIRA", "FOO-123", context);
assertThat(updated).isFalse();
assertThat(issue.mustSendNotifications()).isFalse();
}
@Test
public void set_effort_to_fix() {
- boolean updated = updater.setGap(issue, 3.14, context);
+ boolean updated = underTest.setGap(issue, 3.14, context);
assertThat(updated).isTrue();
assertThat(issue.isChanged()).isTrue();
assertThat(issue.effortToFix()).isEqualTo(3.14);
@Test
public void not_set_effort_to_fix_if_unchanged() {
issue.setGap(3.14);
- boolean updated = updater.setGap(issue, 3.14, context);
+ boolean updated = underTest.setGap(issue, 3.14, context);
assertThat(updated).isFalse();
assertThat(issue.isChanged()).isFalse();
assertThat(issue.effortToFix()).isEqualTo(3.14);
@Test
public void set_past_effort() {
issue.setGap(3.14);
- boolean updated = updater.setPastGap(issue, 1.0, context);
+ boolean updated = underTest.setPastGap(issue, 1.0, context);
assertThat(updated).isTrue();
assertThat(issue.effortToFix()).isEqualTo(3.14);
Duration newDebt = Duration.create(15 * 8 * 60);
Duration previousDebt = Duration.create(10 * 8 * 60);
issue.setEffort(newDebt);
- boolean updated = updater.setPastEffort(issue, previousDebt, context);
+ boolean updated = underTest.setPastEffort(issue, previousDebt, context);
assertThat(updated).isTrue();
assertThat(issue.debt()).isEqualTo(newDebt);
assertThat(issue.mustSendNotifications()).isFalse();
public void set_past_technical_debt_without_previous_value() {
Duration newDebt = Duration.create(15 * 8 * 60);
issue.setEffort(newDebt);
- boolean updated = updater.setPastEffort(issue, null, context);
+ boolean updated = underTest.setPastEffort(issue, null, context);
assertThat(updated).isTrue();
assertThat(issue.debt()).isEqualTo(newDebt);
assertThat(issue.mustSendNotifications()).isFalse();
public void set_past_technical_debt_with_null_new_value() {
issue.setEffort(null);
Duration previousDebt = Duration.create(10 * 8 * 60);
- boolean updated = updater.setPastEffort(issue, previousDebt, context);
+ boolean updated = underTest.setPastEffort(issue, previousDebt, context);
assertThat(updated).isTrue();
assertThat(issue.debt()).isNull();
assertThat(issue.mustSendNotifications()).isFalse();
@Test
public void set_message() {
- boolean updated = updater.setMessage(issue, "the message", context);
+ boolean updated = underTest.setMessage(issue, "the message", context);
assertThat(updated).isTrue();
assertThat(issue.isChanged()).isTrue();
assertThat(issue.message()).isEqualTo("the message");
@Test
public void set_past_message() {
issue.setMessage("new message");
- boolean updated = updater.setPastMessage(issue, "past message", context);
+ boolean updated = underTest.setPastMessage(issue, "past message", context);
assertThat(updated).isTrue();
assertThat(issue.message()).isEqualTo("new message");
@Test
public void set_author() {
- boolean updated = updater.setAuthorLogin(issue, "eric", context);
+ boolean updated = underTest.setAuthorLogin(issue, "eric", context);
assertThat(updated).isTrue();
assertThat(issue.authorLogin()).isEqualTo("eric");
@Test
public void set_new_author() {
- boolean updated = updater.setNewAuthor(issue, "simon", context);
+ boolean updated = underTest.setNewAuthor(issue, "simon", context);
assertThat(updated).isTrue();
FieldDiffs.Diff diff = issue.currentChange().get("author");
@Test
public void not_set_new_author_if_new_author_is_null() {
- boolean updated = updater.setNewAuthor(issue, null, context);
+ boolean updated = underTest.setNewAuthor(issue, null, context);
assertThat(updated).isFalse();
assertThat(issue.currentChange()).isNull();
assertThat(issue.mustSendNotifications()).isFalse();
thrown.expect(IllegalStateException.class);
thrown.expectMessage("It's not possible to update the author with this method, please use setAuthorLogin()");
- updater.setNewAuthor(issue, "julien", context);
+ underTest.setNewAuthor(issue, "julien", context);
}
@Test
String componentUuid = "a";
issue.setComponentUuid(componentUuid);
- updater.setIssueMoved(issue, componentUuid, context);
+ underTest.setIssueMoved(issue, componentUuid, context);
assertThat(issue.changes()).isEmpty();
assertThat(issue.componentUuid()).isEqualTo(componentUuid);
String newComponentUuid = "b";
issue.setComponentUuid(oldComponentUuid);
- updater.setIssueMoved(issue, newComponentUuid, context);
+ underTest.setIssueMoved(issue, newComponentUuid, context);
assertThat(issue.changes()).hasSize(1);
FieldDiffs fieldDiffs = issue.changes().get(0);
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.rule.RuleDbTester;
import org.sonar.db.rule.RuleDefinitionDto;
+import org.sonar.db.user.UserDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.tester.UserSessionRule;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.guava.api.Assertions.entry;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@Test
public void create_from_parameters() {
+ UserDto user = db.users().insertUser(u -> u.setLogin("joanna"));
OrganizationDto organization = db.organizations().insert();
ComponentDto project = db.components().insertPrivateProject(organization);
ComponentDto module = db.components().insertComponent(newModuleDto(project));
.setModuleUuids(asList(module.uuid()))
.setDirectories(asList("aDirPath"))
.setFileUuids(asList(file.uuid()))
- .setAssignees(asList("joanna"))
+ .setAssigneesUuid(asList(user.getUuid()))
.setLanguages(asList("xoo"))
.setTags(asList("tag1", "tag2"))
.setOrganization(organization.getKey())
assertThat(query.projectUuids()).containsOnly(project.uuid());
assertThat(query.moduleUuids()).containsOnly(module.uuid());
assertThat(query.fileUuids()).containsOnly(file.uuid());
- assertThat(query.assignees()).containsOnly("joanna");
+ assertThat(query.assignees()).containsOnly(user.getUuid());
assertThat(query.languages()).containsOnly("xoo");
assertThat(query.tags()).containsOnly("tag1", "tag2");
assertThat(query.organizationUuid()).isEqualTo(organization.getUuid());
.componentUuids(newArrayList("org/struts/Action.java"))
.moduleUuids(newArrayList("org.struts:core"))
.rules(newArrayList(rule))
- .assignees(newArrayList("gargantua"))
+ .assigneeUuids(newArrayList("gargantua"))
.languages(newArrayList("xoo"))
.tags(newArrayList("tag1", "tag2"))
.types(newArrayList("RELIABILITY", "SECURITY"))
.componentUuids(null)
.moduleUuids(null)
.statuses(null)
- .assignees(null)
+ .assigneeUuids(null)
.resolutions(null)
.rules(null)
.severities(null)
.setEffort(Duration.create(10L))
.setChecksum("FFFFF")
.setAuthorLogin("simon")
- .setAssignee("loic")
+ .setAssigneeUuid("loic")
.setFieldChange(context, "severity", "INFO", "BLOCKER")
.setResolution("FIXED")
.setStatus("RESOLVED")
.setEffort(Duration.create(10L))
.setChecksum("FFFFF")
.setAuthorLogin("simon")
- .setAssignee("loic")
+ .setAssigneeUuid("loic")
.setFieldChange(context, "severity", "INFO", "BLOCKER")
.setResolution("FIXED")
.setStatus("RESOLVED")
import org.sonar.db.rule.RuleDbTester;
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.rule.RuleDto;
+import org.sonar.db.user.UserDto;
import org.sonar.server.es.EsTester;
import org.sonar.server.issue.index.IssueIndexer;
import org.sonar.server.issue.index.IssueIteratorFactory;
@Test
public void verify_notification() {
+ UserDto user = dbTester.users().insertUser();
RuleDto rule = ruleDbTester.insertRule(newRuleDto());
ComponentDto project = componentDbTester.insertPrivateProject();
ComponentDto file = componentDbTester.insertComponent(newFileDto(project));
- DefaultIssue issue = issueDbTester.insertIssue(IssueTesting.newIssue(rule.getDefinition(), project, file)).setSeverity(MAJOR).toDefaultIssue();
+ DefaultIssue issue = issueDbTester.insertIssue(IssueTesting.newIssue(rule.getDefinition(), project, file))
+ .setSeverity(MAJOR)
+ .setAssigneeUuid(user.getUuid())
+ .toDefaultIssue();
IssueChangeContext context = IssueChangeContext.createUser(new Date(), "john");
issueFieldsSetter.setSeverity(issue, BLOCKER, context);
assertThat(issueChangeNotification.getFieldValue("ruleName")).isEqualTo(rule.getName());
assertThat(issueChangeNotification.getFieldValue("changeAuthor")).isEqualTo("john");
assertThat(issueChangeNotification.getFieldValue("comment")).isEqualTo("increase severity");
+ assertThat(issueChangeNotification.getFieldValue("assignee")).isEqualTo(user.getLogin());
}
@Test
@Test
public void should_sort_by_assignee() {
- IssueDto issue1 = new IssueDto().setId(1L).setAssignee("perceval");
- IssueDto issue2 = new IssueDto().setId(2L).setAssignee("arthur");
- IssueDto issue3 = new IssueDto().setId(3L).setAssignee("vincent");
- IssueDto issue4 = new IssueDto().setId(4L).setAssignee(null);
+ IssueDto issue1 = new IssueDto().setId(1L).setAssigneeUuid("perceval");
+ IssueDto issue2 = new IssueDto().setId(2L).setAssigneeUuid("arthur");
+ IssueDto issue3 = new IssueDto().setId(3L).setAssigneeUuid("vincent");
+ IssueDto issue4 = new IssueDto().setId(4L).setAssigneeUuid(null);
List<IssueDto> dtoList = newArrayList(issue1, issue2, issue3, issue4);
IssueQuery query = IssueQuery.builder().sort(IssueQuery.SORT_BY_ASSIGNEE).asc(true).build();
List<IssueDto> result = newArrayList(issuesFinderSort.sort());
assertThat(result).hasSize(4);
- assertThat(result.get(0).getAssignee()).isEqualTo("arthur");
- assertThat(result.get(1).getAssignee()).isEqualTo("perceval");
- assertThat(result.get(2).getAssignee()).isEqualTo("vincent");
- assertThat(result.get(3).getAssignee()).isNull();
+ assertThat(result.get(0).getAssigneeUuid()).isEqualTo("arthur");
+ assertThat(result.get(1).getAssigneeUuid()).isEqualTo("perceval");
+ assertThat(result.get(2).getAssigneeUuid()).isEqualTo("vincent");
+ assertThat(result.get(3).getAssigneeUuid()).isNull();
}
@Test
@Test
public void should_not_sort_with_null_sort() {
- IssueDto issue1 = new IssueDto().setId(1L).setAssignee("perceval");
- IssueDto issue2 = new IssueDto().setId(2L).setAssignee("arthur");
- IssueDto issue3 = new IssueDto().setId(3L).setAssignee("vincent");
- IssueDto issue4 = new IssueDto().setId(4L).setAssignee(null);
+ IssueDto issue1 = new IssueDto().setId(1L).setAssigneeUuid("perceval");
+ IssueDto issue2 = new IssueDto().setId(2L).setAssigneeUuid("arthur");
+ IssueDto issue3 = new IssueDto().setId(3L).setAssigneeUuid("vincent");
+ IssueDto issue4 = new IssueDto().setId(4L).setAssigneeUuid(null);
List<IssueDto> dtoList = newArrayList(issue1, issue2, issue3, issue4);
IssueQuery query = IssueQuery.builder().sort(null).build();
List<IssueDto> result = newArrayList(issuesFinderSort.sort());
assertThat(result).hasSize(4);
- assertThat(result.get(0).getAssignee()).isEqualTo("perceval");
- assertThat(result.get(1).getAssignee()).isEqualTo("arthur");
- assertThat(result.get(2).getAssignee()).isEqualTo("vincent");
- assertThat(result.get(3).getAssignee()).isNull();
+ assertThat(result.get(0).getAssigneeUuid()).isEqualTo("perceval");
+ assertThat(result.get(1).getAssigneeUuid()).isEqualTo("arthur");
+ assertThat(result.get(2).getAssigneeUuid()).isEqualTo("vincent");
+ assertThat(result.get(3).getAssigneeUuid()).isNull();
}
@Test
.setEffort(Duration.create(10L))
.setChecksum("FFFFF")
.setAuthorLogin("simon")
- .setAssignee("loic")
+ .setAssigneeUuid("loic")
.setFieldChange(context, "severity", "INFO", "BLOCKER")
.setResolution("FIXED")
.setStatus("RESOLVED")
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
-import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.internal.TestSystem2;
import org.sonar.db.DbTester;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
+import static org.sonar.api.issue.Issue.STATUS_CLOSED;
+import static org.sonar.api.issue.Issue.STATUS_OPEN;
+import static org.sonar.api.utils.DateUtils.parseDateTime;
import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.DEPRECATED_FACET_MODE_DEBT;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.FACET_MODE_EFFORT;
ComponentDto file = ComponentTesting.newFileDto(project, null);
indexIssues(
- IssueDocTesting.newDoc("I1", file).setStatus(Issue.STATUS_CLOSED).setEffort(10L),
- IssueDocTesting.newDoc("I2", file).setStatus(Issue.STATUS_CLOSED).setEffort(10L),
- IssueDocTesting.newDoc("I3", file).setStatus(Issue.STATUS_OPEN).setEffort(10L));
+ IssueDocTesting.newDoc("I1", file).setStatus(STATUS_CLOSED).setEffort(10L),
+ IssueDocTesting.newDoc("I2", file).setStatus(STATUS_CLOSED).setEffort(10L),
+ IssueDocTesting.newDoc("I3", file).setStatus(STATUS_OPEN).setEffort(10L));
Facets facets = search("statuses");
assertThat(facets.getNames()).containsOnly("statuses", FACET_MODE_EFFORT);
ComponentDto file = ComponentTesting.newFileDto(project, null);
indexIssues(
- IssueDocTesting.newDoc("I1", file).setAssignee("steph").setEffort(10L),
- IssueDocTesting.newDoc("I2", file).setAssignee("simon").setEffort(10L),
- IssueDocTesting.newDoc("I3", file).setAssignee("simon").setEffort(10L),
- IssueDocTesting.newDoc("I4", file).setAssignee(null).setEffort(10L));
+ IssueDocTesting.newDoc("I1", file).setAssigneeUuid("uuid-steph").setEffort(10L),
+ IssueDocTesting.newDoc("I2", file).setAssigneeUuid("uuid-simon").setEffort(10L),
+ IssueDocTesting.newDoc("I3", file).setAssigneeUuid("uuid-simon").setEffort(10L),
+ IssueDocTesting.newDoc("I4", file).setAssigneeUuid(null).setEffort(10L));
Facets facets = new Facets(underTest.search(newQueryBuilder().build(), new SearchOptions().addFacets(asList("assignees"))), system2.getDefaultTimeZone());
assertThat(facets.getNames()).containsOnly("assignees", FACET_MODE_EFFORT);
- assertThat(facets.get("assignees")).containsOnly(entry("steph", 10L), entry("simon", 20L), entry("", 10L));
+ assertThat(facets.get("assignees")).containsOnly(entry("uuid-steph", 10L), entry("uuid-simon", 20L), entry("", 10L));
assertThat(facets.get(FACET_MODE_EFFORT)).containsOnly(entry("total", 40L));
}
public void facet_on_created_at() {
SearchOptions searchOptions = fixtureForCreatedAtFacet();
- Builder query = newQueryBuilder().createdBefore(DateUtils.parseDateTime("2016-01-01T00:00:00+0100"));
+ Builder query = newQueryBuilder().createdBefore(parseDateTime("2016-01-01T00:00:00+0100"));
Map<String, Long> createdAt = new Facets(underTest.search(query.build(), searchOptions), system2.getDefaultTimeZone()).get("createdAt");
assertThat(createdAt).containsOnly(
entry("2011-01-01", 10L),
ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
ComponentDto file = ComponentTesting.newFileDto(project, null);
- IssueDoc issue0 = IssueDocTesting.newDoc("ISSUE0", file).setEffort(10L).setFuncCreationDate(DateUtils.parseDateTime("2011-04-25T01:05:13+0100"));
- IssueDoc issue1 = IssueDocTesting.newDoc("I1", file).setEffort(10L).setFuncCreationDate(DateUtils.parseDateTime("2014-09-01T12:34:56+0100"));
- IssueDoc issue2 = IssueDocTesting.newDoc("I2", file).setEffort(10L).setFuncCreationDate(DateUtils.parseDateTime("2014-09-01T23:46:00+0100"));
- IssueDoc issue3 = IssueDocTesting.newDoc("I3", file).setEffort(10L).setFuncCreationDate(DateUtils.parseDateTime("2014-09-02T12:34:56+0100"));
- IssueDoc issue4 = IssueDocTesting.newDoc("I4", file).setEffort(10L).setFuncCreationDate(DateUtils.parseDateTime("2014-09-05T12:34:56+0100"));
- IssueDoc issue5 = IssueDocTesting.newDoc("I5", file).setEffort(10L).setFuncCreationDate(DateUtils.parseDateTime("2014-09-20T12:34:56+0100"));
- IssueDoc issue6 = IssueDocTesting.newDoc("I6", file).setEffort(10L).setFuncCreationDate(DateUtils.parseDateTime("2015-01-18T12:34:56+0100"));
+ IssueDoc issue0 = IssueDocTesting.newDoc("ISSUE0", file).setEffort(10L).setFuncCreationDate(parseDateTime("2011-04-25T01:05:13+0100"));
+ IssueDoc issue1 = IssueDocTesting.newDoc("I1", file).setEffort(10L).setFuncCreationDate(parseDateTime("2014-09-01T12:34:56+0100"));
+ IssueDoc issue2 = IssueDocTesting.newDoc("I2", file).setEffort(10L).setFuncCreationDate(parseDateTime("2014-09-01T23:46:00+0100"));
+ IssueDoc issue3 = IssueDocTesting.newDoc("I3", file).setEffort(10L).setFuncCreationDate(parseDateTime("2014-09-02T12:34:56+0100"));
+ IssueDoc issue4 = IssueDocTesting.newDoc("I4", file).setEffort(10L).setFuncCreationDate(parseDateTime("2014-09-05T12:34:56+0100"));
+ IssueDoc issue5 = IssueDocTesting.newDoc("I5", file).setEffort(10L).setFuncCreationDate(parseDateTime("2014-09-20T12:34:56+0100"));
+ IssueDoc issue6 = IssueDocTesting.newDoc("I6", file).setEffort(10L).setFuncCreationDate(parseDateTime("2015-01-18T12:34:56+0100"));
indexIssues(issue0, issue1, issue2, issue3, issue4, issue5, issue6);
import org.sonar.api.utils.System2;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.user.UserDto;
import org.sonar.server.es.EsTester;
import org.sonar.server.permission.index.AuthorizationTypeSupport;
import org.sonar.server.permission.index.PermissionIndexerDao;
import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
import static org.sonar.db.component.ComponentTesting.newProjectBranch;
import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto;
+import static org.sonar.db.user.UserTesting.newUserDto;
import static org.sonar.server.issue.IssueDocTesting.newDoc;
public class IssueIndexProjectStatisticsTest {
@Test
public void searchProjectStatistics_returns_something() {
- OrganizationDto org = newOrganizationDto();
- ComponentDto project = newPrivateProjectDto(org);
- String userLogin = randomAlphanumeric(20);
+ OrganizationDto organization = newOrganizationDto();
+ ComponentDto project = newPrivateProjectDto(organization);
+ String userUuid = randomAlphanumeric(40);
long from = 1_111_234_567_890L;
- indexIssues(newDoc("issue1", project).setAssignee(userLogin).setFuncCreationDate(new Date(from + 1L)));
+ indexIssues(newDoc("issue1", project).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from + 1L)));
- List<ProjectStatistics> result = underTest.searchProjectStatistics(singletonList(project.uuid()), singletonList(from), userLogin);
+ List<ProjectStatistics> result = underTest.searchProjectStatistics(singletonList(project.uuid()), singletonList(from), userUuid);
assertThat(result).extracting(ProjectStatistics::getProjectUuid).containsExactly(project.uuid());
}
public void searchProjectStatistics_does_not_return_results_if_assignee_does_not_match() {
OrganizationDto org1 = newOrganizationDto();
ComponentDto project = newPrivateProjectDto(org1);
- String userLogin1 = randomAlphanumeric(20);
- String userLogin2 = randomAlphanumeric(20);
+ String user1Uuid = randomAlphanumeric(40);
+ String user2Uuid = randomAlphanumeric(40);
long from = 1_111_234_567_890L;
- indexIssues(newDoc("issue1", project).setAssignee(userLogin1).setFuncCreationDate(new Date(from + 1L)));
+ indexIssues(newDoc("issue1", project).setAssigneeUuid(user1Uuid).setFuncCreationDate(new Date(from + 1L)));
- List<ProjectStatistics> result = underTest.searchProjectStatistics(singletonList(project.uuid()), singletonList(from), userLogin2);
+ List<ProjectStatistics> result = underTest.searchProjectStatistics(singletonList(project.uuid()), singletonList(from), user2Uuid);
assertThat(result).isEmpty();
}
public void searchProjectStatistics_returns_results_if_assignee_matches() {
OrganizationDto org1 = newOrganizationDto();
ComponentDto project = newPrivateProjectDto(org1);
- String userLogin1 = randomAlphanumeric(20);
+ String user1Uuid = randomAlphanumeric(40);
long from = 1_111_234_567_890L;
- indexIssues(newDoc("issue1", project).setAssignee(userLogin1).setFuncCreationDate(new Date(from + 1L)));
+ indexIssues(newDoc("issue1", project).setAssigneeUuid(user1Uuid).setFuncCreationDate(new Date(from + 1L)));
- List<ProjectStatistics> result = underTest.searchProjectStatistics(singletonList(project.uuid()), singletonList(from), userLogin1);
+ List<ProjectStatistics> result = underTest.searchProjectStatistics(singletonList(project.uuid()), singletonList(from), user1Uuid);
assertThat(result).extracting(ProjectStatistics::getProjectUuid).containsExactly(project.uuid());
}
public void searchProjectStatistics_returns_results_if_functional_date_is_strictly_after_from_date() {
OrganizationDto org1 = newOrganizationDto();
ComponentDto project = newPrivateProjectDto(org1);
- String userLogin1 = randomAlphanumeric(20);
+ String userUuid = randomAlphanumeric(40);
long from = 1_111_234_567_890L;
- indexIssues(newDoc("issue1", project).setAssignee(userLogin1).setFuncCreationDate(new Date(from + 1L)));
+ indexIssues(newDoc("issue1", project).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from + 1L)));
- List<ProjectStatistics> result = underTest.searchProjectStatistics(singletonList(project.uuid()), singletonList(from), userLogin1);
+ List<ProjectStatistics> result = underTest.searchProjectStatistics(singletonList(project.uuid()), singletonList(from), userUuid);
assertThat(result).extracting(ProjectStatistics::getProjectUuid).containsExactly(project.uuid());
}
public void searchProjectStatistics_does_not_return_results_if_functional_date_is_same_as_from_date() {
OrganizationDto org1 = newOrganizationDto();
ComponentDto project = newPrivateProjectDto(org1);
- String userLogin1 = randomAlphanumeric(20);
+ String userUuid = randomAlphanumeric(40);
long from = 1_111_234_567_890L;
- indexIssues(newDoc("issue1", project).setAssignee(userLogin1).setFuncCreationDate(new Date(from)));
+ indexIssues(newDoc("issue1", project).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from)));
- List<ProjectStatistics> result = underTest.searchProjectStatistics(singletonList(project.uuid()), singletonList(from), userLogin1);
+ List<ProjectStatistics> result = underTest.searchProjectStatistics(singletonList(project.uuid()), singletonList(from), userUuid);
assertThat(result).extracting(ProjectStatistics::getProjectUuid).containsExactly(project.uuid());
}
public void searchProjectStatistics_does_not_return_resolved_issues() {
OrganizationDto org1 = newOrganizationDto();
ComponentDto project = newPrivateProjectDto(org1);
- String userLogin1 = randomAlphanumeric(20);
+ String userUuid = randomAlphanumeric(40);
long from = 1_111_234_567_890L;
indexIssues(
- newDoc("issue1", project).setAssignee(userLogin1).setFuncCreationDate(new Date(from + 1L)).setResolution(Issue.RESOLUTION_FALSE_POSITIVE),
- newDoc("issue1", project).setAssignee(userLogin1).setFuncCreationDate(new Date(from + 1L)).setResolution(Issue.RESOLUTION_FIXED),
- newDoc("issue1", project).setAssignee(userLogin1).setFuncCreationDate(new Date(from + 1L)).setResolution(Issue.RESOLUTION_REMOVED),
- newDoc("issue1", project).setAssignee(userLogin1).setFuncCreationDate(new Date(from + 1L)).setResolution(Issue.RESOLUTION_WONT_FIX));
+ newDoc("issue1", project).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from + 1L)).setResolution(Issue.RESOLUTION_FALSE_POSITIVE),
+ newDoc("issue1", project).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from + 1L)).setResolution(Issue.RESOLUTION_FIXED),
+ newDoc("issue1", project).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from + 1L)).setResolution(Issue.RESOLUTION_REMOVED),
+ newDoc("issue1", project).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from + 1L)).setResolution(Issue.RESOLUTION_WONT_FIX));
- List<ProjectStatistics> result = underTest.searchProjectStatistics(singletonList(project.uuid()), singletonList(from), userLogin1);
+ List<ProjectStatistics> result = underTest.searchProjectStatistics(singletonList(project.uuid()), singletonList(from), userUuid);
assertThat(result).isEmpty();
}
public void searchProjectStatistics_does_not_return_results_if_functional_date_is_before_from_date() {
OrganizationDto org1 = newOrganizationDto();
ComponentDto project = newPrivateProjectDto(org1);
- String userLogin1 = randomAlphanumeric(20);
+ String userUuid = randomAlphanumeric(40);
long from = 1_111_234_567_890L;
- indexIssues(newDoc("issue1", project).setAssignee(userLogin1).setFuncCreationDate(new Date(from - 1000L)));
+ indexIssues(newDoc("issue1", project).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from - 1000L)));
- List<ProjectStatistics> result = underTest.searchProjectStatistics(singletonList(project.uuid()), singletonList(from), userLogin1);
+ List<ProjectStatistics> result = underTest.searchProjectStatistics(singletonList(project.uuid()), singletonList(from), userUuid);
assertThat(result).isEmpty();
}
public void searchProjectStatistics_returns_issue_count() {
OrganizationDto org1 = newOrganizationDto();
ComponentDto project = newPrivateProjectDto(org1);
- String userLogin1 = randomAlphanumeric(20);
+ String userUuid = randomAlphanumeric(40);
long from = 1_111_234_567_890L;
indexIssues(
- newDoc("issue1", project).setAssignee(userLogin1).setFuncCreationDate(new Date(from + 1L)),
- newDoc("issue2", project).setAssignee(userLogin1).setFuncCreationDate(new Date(from + 1L)),
- newDoc("issue3", project).setAssignee(userLogin1).setFuncCreationDate(new Date(from + 1L)));
+ newDoc("issue1", project).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from + 1L)),
+ newDoc("issue2", project).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from + 1L)),
+ newDoc("issue3", project).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from + 1L)));
- List<ProjectStatistics> result = underTest.searchProjectStatistics(singletonList(project.uuid()), singletonList(from), userLogin1);
+ List<ProjectStatistics> result = underTest.searchProjectStatistics(singletonList(project.uuid()), singletonList(from), userUuid);
assertThat(result).extracting(ProjectStatistics::getIssueCount).containsExactly(3L);
}
ComponentDto project1 = newPrivateProjectDto(org1);
ComponentDto project2 = newPrivateProjectDto(org1);
ComponentDto project3 = newPrivateProjectDto(org1);
- String userLogin1 = randomAlphanumeric(20);
+ String userUuid = randomAlphanumeric(40);
long from = 1_111_234_567_890L;
indexIssues(
- newDoc("issue1", project1).setAssignee(userLogin1).setFuncCreationDate(new Date(from + 1L)),
- newDoc("issue2", project1).setAssignee(userLogin1).setFuncCreationDate(new Date(from + 1L)),
- newDoc("issue3", project1).setAssignee(userLogin1).setFuncCreationDate(new Date(from + 1L)),
+ newDoc("issue1", project1).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from + 1L)),
+ newDoc("issue2", project1).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from + 1L)),
+ newDoc("issue3", project1).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from + 1L)),
- newDoc("issue4", project3).setAssignee(userLogin1).setFuncCreationDate(new Date(from + 1L)),
- newDoc("issue5", project3).setAssignee(userLogin1).setFuncCreationDate(new Date(from + 1L)));
+ newDoc("issue4", project3).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from + 1L)),
+ newDoc("issue5", project3).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from + 1L)));
List<ProjectStatistics> result = underTest.searchProjectStatistics(
asList(project1.uuid(), project2.uuid(), project3.uuid()),
asList(from, from, from),
- userLogin1);
+ userUuid);
assertThat(result)
.extracting(ProjectStatistics::getProjectUuid, ProjectStatistics::getIssueCount)
ComponentDto project1 = newPrivateProjectDto(org1);
ComponentDto project2 = newPrivateProjectDto(org1);
ComponentDto project3 = newPrivateProjectDto(org1);
- String userLogin1 = randomAlphanumeric(20);
+ String userUuid = randomAlphanumeric(40);
long from = 1_111_234_567_000L;
indexIssues(
- newDoc("issue1", project1).setAssignee(userLogin1).setFuncCreationDate(new Date(from + 1_000L)),
- newDoc("issue2", project1).setAssignee(userLogin1).setFuncCreationDate(new Date(from + 2_000L)),
- newDoc("issue3", project1).setAssignee(userLogin1).setFuncCreationDate(new Date(from + 3_000L)),
+ newDoc("issue1", project1).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from + 1_000L)),
+ newDoc("issue2", project1).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from + 2_000L)),
+ newDoc("issue3", project1).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from + 3_000L)),
- newDoc("issue4", project3).setAssignee(userLogin1).setFuncCreationDate(new Date(from + 4_000L)),
- newDoc("issue5", project3).setAssignee(userLogin1).setFuncCreationDate(new Date(from + 5_000L)));
+ newDoc("issue4", project3).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from + 4_000L)),
+ newDoc("issue5", project3).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from + 5_000L)));
List<ProjectStatistics> result = underTest.searchProjectStatistics(
asList(project1.uuid(), project2.uuid(), project3.uuid()),
asList(from, from, from),
- userLogin1);
+ userUuid);
assertThat(result)
.extracting(ProjectStatistics::getProjectUuid, ProjectStatistics::getLastIssueDate)
OrganizationDto organization = newOrganizationDto();
ComponentDto project = newPrivateProjectDto(organization);
ComponentDto branch = newProjectBranch(project, newBranchDto(project).setKey("branch"));
- String userLogin = randomAlphanumeric(20);
+ String userUuid = randomAlphanumeric(40);
long from = 1_111_234_567_890L;
indexIssues(
- newDoc("issue1", branch).setAssignee(userLogin).setFuncCreationDate(new Date(from + 1L)),
- newDoc("issue2", branch).setAssignee(userLogin).setFuncCreationDate(new Date(from + 2L)),
- newDoc("issue3", project).setAssignee(userLogin).setFuncCreationDate(new Date(from + 1L)));
+ newDoc("issue1", branch).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from + 1L)),
+ newDoc("issue2", branch).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from + 2L)),
+ newDoc("issue3", project).setAssigneeUuid(userUuid).setFuncCreationDate(new Date(from + 1L)));
- List<ProjectStatistics> result = underTest.searchProjectStatistics(singletonList(project.uuid()), singletonList(from), userLogin);
+ List<ProjectStatistics> result = underTest.searchProjectStatistics(singletonList(project.uuid()), singletonList(from), userUuid);
assertThat(result)
.extracting(ProjectStatistics::getIssueCount, ProjectStatistics::getProjectUuid, ProjectStatistics::getLastIssueDate)
import java.util.Date;
import java.util.List;
import java.util.Map;
-import java.util.TimeZone;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.assertj.core.api.Fail;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
+import static java.util.TimeZone.getTimeZone;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import static org.assertj.core.api.Assertions.tuple;
+import static org.junit.rules.ExpectedException.none;
import static org.sonar.api.issue.Issue.RESOLUTION_FIXED;
import static org.sonar.api.rules.RuleType.BUG;
import static org.sonar.api.rules.RuleType.CODE_SMELL;
import static org.sonar.db.user.GroupTesting.newGroupDto;
import static org.sonar.db.user.UserTesting.newUserDto;
import static org.sonar.server.issue.IssueDocTesting.newDoc;
+import static org.sonar.server.tester.UserSessionRule.standalone;
public class IssueIndexTest {
@Rule
public EsTester es = EsTester.create();
@Rule
- public UserSessionRule userSessionRule = UserSessionRule.standalone();
+ public UserSessionRule userSessionRule = standalone();
@Rule
- public ExpectedException expectedException = ExpectedException.none();
- private System2 system2 = new TestSystem2().setNow(1_500_000_000_000L).setDefaultTimeZone(TimeZone.getTimeZone("GMT-01:00"));
+ public ExpectedException expectedException = none();
+ private System2 system2 = new TestSystem2().setNow(1_500_000_000_000L).setDefaultTimeZone(getTimeZone("GMT-01:00"));
@Rule
public DbTester db = DbTester.create(system2);
+
private IssueIndexer issueIndexer = new IssueIndexer(es.client(), db.getDbClient(), new IssueIteratorFactory(db.getDbClient()));
private ViewIndexer viewIndexer = new ViewIndexer(db.getDbClient(), es.client());
private RuleIndexer ruleIndexer = new RuleIndexer(es.client(), db.getDbClient());
ComponentDto file = newFileDto(project, null);
indexIssues(
- newDoc("I1", file).setAssignee("steph"),
- newDoc("I2", file).setAssignee("marcel"),
- newDoc("I3", file).setAssignee(null));
+ newDoc("I1", file).setAssigneeUuid("steph-uuid"),
+ newDoc("I2", file).setAssigneeUuid("marcel-uuid"),
+ newDoc("I3", file).setAssigneeUuid(null));
- assertThatSearchReturnsOnly(IssueQuery.builder().assignees(singletonList("steph")), "I1");
- assertThatSearchReturnsOnly(IssueQuery.builder().assignees(asList("steph", "marcel")), "I1", "I2");
- assertThatSearchReturnsEmpty(IssueQuery.builder().assignees(singletonList("unknown")));
+ assertThatSearchReturnsOnly(IssueQuery.builder().assigneeUuids(singletonList("steph-uuid")), "I1");
+ assertThatSearchReturnsOnly(IssueQuery.builder().assigneeUuids(asList("steph-uuid", "marcel-uuid")), "I1", "I2");
+ assertThatSearchReturnsEmpty(IssueQuery.builder().assigneeUuids(singletonList("unknown")));
}
@Test
ComponentDto file = newFileDto(project, null);
indexIssues(
- newDoc("I1", file).setAssignee("steph"),
- newDoc("I2", file).setAssignee("marcel"),
- newDoc("I3", file).setAssignee("marcel"),
- newDoc("I4", file).setAssignee(null));
+ newDoc("I1", file).setAssigneeUuid("steph-uuid"),
+ newDoc("I2", file).setAssigneeUuid("marcel-uuid"),
+ newDoc("I3", file).setAssigneeUuid("marcel-uuid"),
+ newDoc("I4", file).setAssigneeUuid(null));
- assertThatFacetHasOnly(IssueQuery.builder(), "assignees", entry("steph", 1L), entry("marcel", 2L), entry("", 1L));
+ assertThatFacetHasOnly(IssueQuery.builder(), "assignees", entry("steph-uuid", 1L), entry("marcel-uuid", 2L), entry("", 1L));
}
@Test
ComponentDto file = newFileDto(project, null);
indexIssues(
- newDoc("I1", file).setAssignee("j-b"),
- newDoc("I2", file).setAssignee("marcel"),
- newDoc("I3", file).setAssignee("marcel"),
- newDoc("I4", file).setAssignee(null));
+ newDoc("I1", file).setAssigneeUuid("j-b-uuid"),
+ newDoc("I2", file).setAssigneeUuid("marcel-uuid"),
+ newDoc("I3", file).setAssigneeUuid("marcel-uuid"),
+ newDoc("I4", file).setAssigneeUuid(null));
- assertThatFacetHasOnly(IssueQuery.builder().assignees(singletonList("j-b")), "assignees", entry("j-b", 1L), entry("marcel", 2L), entry("", 1L));
+ assertThatFacetHasOnly(IssueQuery.builder().assigneeUuids(singletonList("j-b")),
+ "assignees", entry("j-b-uuid", 1L), entry("marcel-uuid", 2L), entry("", 1L));
}
@Test
ComponentDto file = newFileDto(project, null);
indexIssues(
- newDoc("I1", file).setAssignee("steph"),
- newDoc("I2", file).setAssignee(null),
- newDoc("I3", file).setAssignee(null));
+ newDoc("I1", file).setAssigneeUuid("steph-uuid"),
+ newDoc("I2", file).setAssigneeUuid(null),
+ newDoc("I3", file).setAssigneeUuid(null));
assertThatSearchReturnsOnly(IssueQuery.builder().assigned(true), "I1");
assertThatSearchReturnsOnly(IssueQuery.builder().assigned(false), "I2", "I3");
indexIssues(
newDoc("I1", file).setAuthorLogin("steph"),
newDoc("I2", file).setAuthorLogin("marcel"),
- newDoc("I3", file).setAssignee(null));
+ newDoc("I3", file).setAssigneeUuid(null));
assertThatSearchReturnsOnly(IssueQuery.builder().authors(singletonList("steph")), "I1");
assertThatSearchReturnsOnly(IssueQuery.builder().authors(asList("steph", "marcel")), "I1", "I2");
ComponentDto file = newFileDto(project, null);
indexIssues(
- newDoc("I1", file).setAssignee("steph"),
- newDoc("I2", file).setAssignee("marcel"));
+ newDoc("I1", file).setAssigneeUuid("steph-uuid"),
+ newDoc("I2", file).setAssigneeUuid("marcel-uuid"));
IssueQuery.Builder query = IssueQuery.builder().sort(IssueQuery.SORT_BY_ASSIGNEE).asc(true);
assertThatSearchReturnsOnly(query, "I2", "I1");
import static java.util.Collections.emptyList;
import static java.util.Collections.emptySet;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.rules.ExpectedException.none;
import static org.sonar.db.component.ComponentTesting.newFileDto;
import static org.sonar.server.issue.IssueDocTesting.newDoc;
import static org.sonar.server.issue.index.IssueIndexDefinition.INDEX_TYPE_ISSUE;
@Rule
public DbTester db = DbTester.create();
@Rule
- public ExpectedException expectedException = ExpectedException.none();
+ public ExpectedException expectedException = none();
@Rule
public LogTester logTester = new LogTester();
IssueDoc doc = es.getDocuments(INDEX_TYPE_ISSUE, IssueDoc.class).get(0);
assertThat(doc.getId()).isEqualTo(issue.getKey());
assertThat(doc.organizationUuid()).isEqualTo(organization.getUuid());
- assertThat(doc.assignee()).isEqualTo(issue.getAssignee());
+ assertThat(doc.assigneeUuid()).isEqualTo(issue.getAssigneeUuid());
assertThat(doc.authorLogin()).isEqualTo(issue.getAuthorLogin());
assertThat(doc.componentUuid()).isEqualTo(file.uuid());
assertThat(doc.projectUuid()).isEqualTo(project.uuid());
assertThat(issue.resolution()).isEqualTo("FIXED");
assertThat(issue.status()).isEqualTo("RESOLVED");
assertThat(issue.severity()).isEqualTo("BLOCKER");
- assertThat(issue.assignee()).isEqualTo("guy1");
+ assertThat(issue.assigneeUuid()).isEqualTo("uuid-of-guy1");
assertThat(issue.authorLogin()).isEqualTo("guy2");
assertThat(issue.line()).isEqualTo(444);
assertThat(issue.ruleId()).isEqualTo(200);
IssueDoc issue = issuesByKey.get("ABC");
assertThat(issue.key()).isEqualTo("ABC");
- assertThat(issue.assignee()).isEqualTo("guy1");
+ assertThat(issue.assigneeUuid()).isEqualTo("uuid-of-guy1");
assertThat(issue.componentUuid()).isEqualTo("FILE1");
assertThat(issue.projectUuid()).isEqualTo("PROJECT1");
assertThat(issue.moduleUuid()).isEqualTo("PROJECT1");
issue = issuesByKey.get("BCD");
assertThat(issue.key()).isEqualTo("BCD");
- assertThat(issue.assignee()).isEqualTo("guy1");
+ assertThat(issue.assigneeUuid()).isEqualTo("uuid-of-guy1");
assertThat(issue.componentUuid()).isEqualTo("MODULE1");
assertThat(issue.projectUuid()).isEqualTo("PROJECT1");
assertThat(issue.moduleUuid()).isEqualTo("MODULE1");
issue = issuesByKey.get("DEF");
assertThat(issue.key()).isEqualTo("DEF");
- assertThat(issue.assignee()).isEqualTo("guy2");
+ assertThat(issue.assigneeUuid()).isEqualTo("uuid-of-guy2");
assertThat(issue.componentUuid()).isEqualTo("FILE1");
assertThat(issue.projectUuid()).isEqualTo("PROJECT1");
assertThat(issue.moduleUuid()).isEqualTo("PROJECT1");
issue = issuesByKey.get("EFG");
assertThat(issue.key()).isEqualTo("EFG");
- assertThat(issue.assignee()).isEqualTo("guy1");
+ assertThat(issue.assigneeUuid()).isEqualTo("uuid-of-guy1");
assertThat(issue.componentUuid()).isEqualTo("DIR1");
assertThat(issue.projectUuid()).isEqualTo("PROJECT1");
assertThat(issue.moduleUuid()).isEqualTo("MODULE1");
import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.issue.FieldDiffs;
import org.sonar.db.component.ComponentDto;
+import org.sonar.db.user.UserDto;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.db.user.UserTesting.newUserDto;
public class IssueChangeNotificationTest {
@Test
public void set_issue() {
+
+ UserDto assignee = newUserDto();
+
DefaultIssue issue = new DefaultIssue()
.setKey("ABCD")
- .setAssignee("simon")
+ .setAssigneeUuid(assignee.getUuid())
.setMessage("Remove this useless method")
.setComponentKey("MyService")
.setCurrentChange(new FieldDiffs().setDiff("resolution", "FALSE-POSITIVE", "FIXED"));
- IssueChangeNotification result = notification.setIssue(issue);
+ IssueChangeNotification result = notification.setIssue(issue).setAssignee(assignee);
assertThat(result.getFieldValue("key")).isEqualTo("ABCD");
- assertThat(result.getFieldValue("assignee")).isEqualTo("simon");
assertThat(result.getFieldValue("message")).isEqualTo("Remove this useless method");
assertThat(result.getFieldValue("old.resolution")).isEqualTo("FALSE-POSITIVE");
assertThat(result.getFieldValue("new.resolution")).isEqualTo("FIXED");
+ assertThat(result.getFieldValue("assignee")).isEqualTo(assignee.getLogin());
}
@Test
public void set_issue_with_current_change_having_no_old_value() {
DefaultIssue issue = new DefaultIssue()
.setKey("ABCD")
- .setAssignee("simon")
+ .setAssigneeUuid("simon")
.setMessage("Remove this useless method")
.setComponentKey("MyService");
public void set_issue_with_current_change_having_no_new_value() {
DefaultIssue issue = new DefaultIssue()
.setKey("ABCD")
- .setAssignee("simon")
+ .setAssigneeUuid("simon")
.setMessage("Remove this useless method")
.setComponentKey("MyService");
import org.junit.Test;
import org.sonar.api.utils.Durations;
import org.sonar.db.DbClient;
+import org.sonar.db.user.UserDto;
+import org.sonar.db.user.UserTesting;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@Test
public void set_assignee() {
- underTest.setAssignee("myAssignee");
+ UserDto user = UserTesting.newUserDto();
- assertThat(underTest.getFieldValue(FIELD_ASSIGNEE)).isEqualTo("myAssignee");
+ underTest.setAssignee(user);
+
+ assertThat(underTest.getFieldValue(FIELD_ASSIGNEE)).isEqualTo(user.getLogin());
}
@Test
public void set_with_a_specific_type() {
assertThat(underTest.getType()).isEqualTo(MyNewIssuesNotification.MY_NEW_ISSUES_NOTIF_TYPE);
-
}
}
@Test
public void set_statistics() {
+ UserDto maynard = db.users().insertUser(u-> u.setLogin("maynard"));
+ UserDto keenan = db.users().insertUser(u-> u.setLogin("keenan"));
+
ComponentDto project = db.components().insertPrivateProject();
ComponentDto directory = db.components().insertComponent(newDirectory(project, "path"));
ComponentDto file = db.components().insertComponent(newFileDto(directory));
RuleDefinitionDto rule1 = db.rules().insert(r -> r.setRepositoryKey("SonarQube").setRuleKey("rule1-the-world").setName("Rule the World").setLanguage("Java"));
RuleDefinitionDto rule2 = db.rules().insert(r -> r.setRepositoryKey("SonarQube").setRuleKey("rule1-the-universe").setName("Rule the Universe").setLanguage("Clojure"));
- IssueDto issue1 = db.issues().insert(rule1, project, file, i -> i.setType(BUG).setAssignee("maynard").setTags(asList("bug", "owasp")));
- IssueDto issue2 = db.issues().insert(rule2, project, directory, i -> i.setType(CODE_SMELL).setAssignee("keenan").setTags(singletonList("owasp")));
+ IssueDto issue1 = db.issues().insert(rule1, project, file, i -> i.setType(BUG).setAssigneeUuid(maynard.getUuid()).setTags(asList("bug", "owasp")));
+ IssueDto issue2 = db.issues().insert(rule2, project, directory, i -> i.setType(CODE_SMELL).setAssigneeUuid(keenan.getUuid()).setTags(singletonList("owasp")));
NewIssuesStatistics.Stats stats = new NewIssuesStatistics.Stats(i -> true);
IntStream.rangeClosed(1, 5).forEach(i -> stats.add(issue1.toDefaultIssue()));
IntStream.rangeClosed(1, 3).forEach(i -> stats.add(issue2.toDefaultIssue()));
assertThat(underTest.getFieldValue(RULE_TYPE + ".BUG.count")).isEqualTo("5");
assertThat(underTest.getFieldValue(RULE_TYPE + ".CODE_SMELL.count")).isEqualTo("3");
- assertThat(underTest.getFieldValue(ASSIGNEE + ".1.label")).isEqualTo("maynard");
+ assertThat(underTest.getFieldValue(ASSIGNEE + ".1.label")).isEqualTo(maynard.getName());
assertThat(underTest.getFieldValue(ASSIGNEE + ".1.count")).isEqualTo("5");
- assertThat(underTest.getFieldValue(ASSIGNEE + ".2.label")).isEqualTo("keenan");
+ assertThat(underTest.getFieldValue(ASSIGNEE + ".2.label")).isEqualTo(keenan.getName());
assertThat(underTest.getFieldValue(ASSIGNEE + ".2.count")).isEqualTo("3");
assertThat(underTest.getFieldValue(TAG + ".1.label")).isEqualTo("owasp");
assertThat(underTest.getFieldValue(TAG + ".1.count")).isEqualTo("8");
ComponentDto file = db.components().insertComponent(newFileDto(project));
RuleDefinitionDto rule = db.rules().insert();
UserDto user = db.users().insertUser();
- IssueDto issue1 = db.issues().insert(rule, project, file, i -> i.setAssignee(user.getLogin()));
- IssueDto issue2 = db.issues().insert(rule, project, file, i -> i.setAssignee("no_user"));
+ IssueDto issue = db.issues().insert(rule, project, file, i -> i.setAssigneeUuid(user.getUuid()));
NewIssuesStatistics.Stats stats = new NewIssuesStatistics.Stats(i -> true);
- IntStream.rangeClosed(1, 5).forEach(i -> stats.add(issue1.toDefaultIssue()));
- IntStream.rangeClosed(1, 3).forEach(i -> stats.add(issue2.toDefaultIssue()));
+ IntStream.rangeClosed(1, 5).forEach(i -> stats.add(issue.toDefaultIssue()));
underTest.setStatistics(project.longName(), stats);
assertThat(underTest.getFieldValue(ASSIGNEE + ".1.label")).isEqualTo(user.getName());
assertThat(underTest.getFieldValue(ASSIGNEE + ".1.count")).isEqualTo("5");
- assertThat(underTest.getFieldValue(ASSIGNEE + ".2.label")).isEqualTo("no_user");
- assertThat(underTest.getFieldValue(ASSIGNEE + ".2.count")).isEqualTo("3");
}
@Test
public void add_only_5_assignees_with_biggest_issue_counts() {
+ UserDto user1 = db.users().insertUser();
+ UserDto user2 = db.users().insertUser();
+ UserDto user3 = db.users().insertUser();
+ UserDto user4 = db.users().insertUser();
+ UserDto user5 = db.users().insertUser();
+ UserDto user6 = db.users().insertUser();
+ UserDto user7 = db.users().insertUser();
+ UserDto user8 = db.users().insertUser();
+
ComponentDto project = db.components().insertPrivateProject();
ComponentDto file = db.components().insertComponent(newFileDto(project));
RuleDefinitionDto rule = db.rules().insert();
NewIssuesStatistics.Stats stats = new NewIssuesStatistics.Stats(i -> true);
- IntStream.rangeClosed(1, 10).forEach(i -> stats.add(db.issues().insert(rule, project, file, issue -> issue.setAssignee("assignee_1")).toDefaultIssue()));
- IntStream.rangeClosed(1, 9).forEach(i -> stats.add(db.issues().insert(rule, project, file, issue -> issue.setAssignee("assignee_2")).toDefaultIssue()));
- IntStream.rangeClosed(1, 8).forEach(i -> stats.add(db.issues().insert(rule, project, file, issue -> issue.setAssignee("assignee_3")).toDefaultIssue()));
- IntStream.rangeClosed(1, 7).forEach(i -> stats.add(db.issues().insert(rule, project, file, issue -> issue.setAssignee("assignee_4")).toDefaultIssue()));
- IntStream.rangeClosed(1, 6).forEach(i -> stats.add(db.issues().insert(rule, project, file, issue -> issue.setAssignee("assignee_5")).toDefaultIssue()));
- IntStream.rangeClosed(1, 5).forEach(i -> stats.add(db.issues().insert(rule, project, file, issue -> issue.setAssignee("assignee_6")).toDefaultIssue()));
- IntStream.rangeClosed(1, 4).forEach(i -> stats.add(db.issues().insert(rule, project, file, issue -> issue.setAssignee("assignee_7")).toDefaultIssue()));
- IntStream.rangeClosed(1, 3).forEach(i -> stats.add(db.issues().insert(rule, project, file, issue -> issue.setAssignee("assignee_8")).toDefaultIssue()));
+ IntStream.rangeClosed(1, 10).forEach(i -> stats.add(db.issues().insert(rule, project, file, issue -> issue.setAssigneeUuid(user1.getUuid())).toDefaultIssue()));
+ IntStream.rangeClosed(1, 9).forEach(i -> stats.add(db.issues().insert(rule, project, file, issue -> issue.setAssigneeUuid(user2.getUuid())).toDefaultIssue()));
+ IntStream.rangeClosed(1, 8).forEach(i -> stats.add(db.issues().insert(rule, project, file, issue -> issue.setAssigneeUuid(user3.getUuid())).toDefaultIssue()));
+ IntStream.rangeClosed(1, 7).forEach(i -> stats.add(db.issues().insert(rule, project, file, issue -> issue.setAssigneeUuid(user4.getUuid())).toDefaultIssue()));
+ IntStream.rangeClosed(1, 6).forEach(i -> stats.add(db.issues().insert(rule, project, file, issue -> issue.setAssigneeUuid(user5.getUuid())).toDefaultIssue()));
+ IntStream.rangeClosed(1, 5).forEach(i -> stats.add(db.issues().insert(rule, project, file, issue -> issue.setAssigneeUuid(user6.getUuid())).toDefaultIssue()));
+ IntStream.rangeClosed(1, 4).forEach(i -> stats.add(db.issues().insert(rule, project, file, issue -> issue.setAssigneeUuid(user7.getUuid())).toDefaultIssue()));
+ IntStream.rangeClosed(1, 3).forEach(i -> stats.add(db.issues().insert(rule, project, file, issue -> issue.setAssigneeUuid(user8.getUuid())).toDefaultIssue()));
underTest.setStatistics(project.longName(), stats);
- assertThat(underTest.getFieldValue(ASSIGNEE + ".1.label")).isEqualTo("assignee_1");
+ assertThat(underTest.getFieldValue(ASSIGNEE + ".1.label")).isEqualTo(user1.getName());
assertThat(underTest.getFieldValue(ASSIGNEE + ".1.count")).isEqualTo("10");
- assertThat(underTest.getFieldValue(ASSIGNEE + ".2.label")).isEqualTo("assignee_2");
+ assertThat(underTest.getFieldValue(ASSIGNEE + ".2.label")).isEqualTo(user2.getName());
assertThat(underTest.getFieldValue(ASSIGNEE + ".2.count")).isEqualTo("9");
- assertThat(underTest.getFieldValue(ASSIGNEE + ".3.label")).isEqualTo("assignee_3");
+ assertThat(underTest.getFieldValue(ASSIGNEE + ".3.label")).isEqualTo(user3.getName());
assertThat(underTest.getFieldValue(ASSIGNEE + ".3.count")).isEqualTo("8");
- assertThat(underTest.getFieldValue(ASSIGNEE + ".4.label")).isEqualTo("assignee_4");
+ assertThat(underTest.getFieldValue(ASSIGNEE + ".4.label")).isEqualTo(user4.getName());
assertThat(underTest.getFieldValue(ASSIGNEE + ".4.count")).isEqualTo("7");
- assertThat(underTest.getFieldValue(ASSIGNEE + ".5.label")).isEqualTo("assignee_5");
+ assertThat(underTest.getFieldValue(ASSIGNEE + ".5.label")).isEqualTo(user5.getName());
assertThat(underTest.getFieldValue(ASSIGNEE + ".5.count")).isEqualTo("6");
assertThat(underTest.getFieldValue(ASSIGNEE + ".6.label")).isNull();
assertThat(underTest.getFieldValue(ASSIGNEE + ".6.count")).isNull();
@Test
public void add_fails_with_NPE_if_RuleType_is_null() {
String assignee = randomAlphanumeric(10);
- DefaultIssue issue = new DefaultIssue().setType(null).setAssignee(assignee).setNew(new Random().nextBoolean());
+ DefaultIssue issue = new DefaultIssue().setType(null).setAssigneeUuid(assignee).setNew(new Random().nextBoolean());
expectedException.expect(NullPointerException.class);
@Test
public void add_issues_with_correct_global_statistics() {
DefaultIssue issue = new DefaultIssue()
- .setAssignee("maynard")
+ .setAssigneeUuid("maynard")
.setComponentUuid("file-uuid")
.setNew(true)
.setType(RuleType.BUG)
.setEffort(Duration.create(5L));
underTest.add(issue);
- underTest.add(issue.setAssignee("james"));
- underTest.add(issue.setAssignee("keenan"));
+ underTest.add(issue.setAssigneeUuid("james"));
+ underTest.add(issue.setAssigneeUuid("keenan"));
assertThat(countDistributionTotal(Metric.ASSIGNEE, "maynard")).isEqualTo(1);
assertThat(countDistributionTotal(Metric.ASSIGNEE, "james")).isEqualTo(1);
public void add_counts_issue_per_RuleType_on_leak_globally_and_per_assignee() {
String assignee = randomAlphanumeric(10);
Arrays.stream(RuleType.values())
- .map(ruleType -> new DefaultIssue().setType(ruleType).setAssignee(assignee).setNew(true))
+ .map(ruleType -> new DefaultIssue().setType(ruleType).setAssigneeUuid(assignee).setNew(true))
.forEach(underTest::add);
DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.RULE_TYPE);
public void add_counts_issue_per_RuleType_off_leak_globally_and_per_assignee() {
String assignee = randomAlphanumeric(10);
Arrays.stream(RuleType.values())
- .map(ruleType -> new DefaultIssue().setType(ruleType).setAssignee(assignee).setNew(false))
+ .map(ruleType -> new DefaultIssue().setType(ruleType).setAssigneeUuid(assignee).setNew(false))
.forEach(underTest::add);
DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.RULE_TYPE);
List<String> componentUuids = IntStream.range(0, 1 + new Random().nextInt(10)).mapToObj(i -> randomAlphabetic(3)).collect(Collectors.toList());
String assignee = randomAlphanumeric(10);
componentUuids.stream()
- .map(componentUuid -> new DefaultIssue().setType(randomRuleType).setComponentUuid(componentUuid).setAssignee(assignee).setNew(true))
+ .map(componentUuid -> new DefaultIssue().setType(randomRuleType).setComponentUuid(componentUuid).setAssigneeUuid(assignee).setNew(true))
.forEach(underTest::add);
DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.COMPONENT);
List<String> componentUuids = IntStream.range(0, 1 + new Random().nextInt(10)).mapToObj(i -> randomAlphabetic(3)).collect(Collectors.toList());
String assignee = randomAlphanumeric(10);
componentUuids.stream()
- .map(componentUuid -> new DefaultIssue().setType(randomRuleType).setComponentUuid(componentUuid).setAssignee(assignee).setNew(false))
+ .map(componentUuid -> new DefaultIssue().setType(randomRuleType).setComponentUuid(componentUuid).setAssigneeUuid(assignee).setNew(false))
.forEach(underTest::add);
DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.COMPONENT);
@Test
public void add_does_not_count_component_if_null_neither_globally_nor_per_assignee() {
String assignee = randomAlphanumeric(10);
- underTest.add(new DefaultIssue().setType(randomRuleType).setComponentUuid(null).setAssignee(assignee).setNew(new Random().nextBoolean()));
+ underTest.add(new DefaultIssue().setType(randomRuleType).setComponentUuid(null).setAssigneeUuid(assignee).setNew(new Random().nextBoolean()));
DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.COMPONENT);
DistributedMetricStatsInt assigneeDistribution = underTest.getAssigneesStatistics().get(assignee).getDistributedMetricStats(Metric.COMPONENT);
List<String> ruleKeys = IntStream.range(0, 1 + new Random().nextInt(10)).mapToObj(i -> randomAlphabetic(3)).collect(Collectors.toList());
String assignee = randomAlphanumeric(10);
ruleKeys.stream()
- .map(ruleKey -> new DefaultIssue().setType(randomRuleType).setRuleKey(RuleKey.of(repository, ruleKey)).setAssignee(assignee).setNew(true))
+ .map(ruleKey -> new DefaultIssue().setType(randomRuleType).setRuleKey(RuleKey.of(repository, ruleKey)).setAssigneeUuid(assignee).setNew(true))
.forEach(underTest::add);
DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.RULE);
List<String> ruleKeys = IntStream.range(0, 1 + new Random().nextInt(10)).mapToObj(i -> randomAlphabetic(3)).collect(Collectors.toList());
String assignee = randomAlphanumeric(10);
ruleKeys.stream()
- .map(ruleKey -> new DefaultIssue().setType(randomRuleType).setRuleKey(RuleKey.of(repository, ruleKey)).setAssignee(assignee).setNew(false))
+ .map(ruleKey -> new DefaultIssue().setType(randomRuleType).setRuleKey(RuleKey.of(repository, ruleKey)).setAssigneeUuid(assignee).setNew(false))
.forEach(underTest::add);
DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.RULE);
@Test
public void add_does_not_count_ruleKey_if_null_neither_globally_nor_per_assignee() {
String assignee = randomAlphanumeric(10);
- underTest.add(new DefaultIssue().setType(randomRuleType).setRuleKey(null).setAssignee(assignee).setNew(new Random().nextBoolean()));
+ underTest.add(new DefaultIssue().setType(randomRuleType).setRuleKey(null).setAssigneeUuid(assignee).setNew(new Random().nextBoolean()));
DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.RULE);
DistributedMetricStatsInt assigneeDistribution = underTest.getAssigneesStatistics().get(assignee).getDistributedMetricStats(Metric.RULE);
public void add_counts_issue_per_assignee_on_leak_globally_and_per_assignee() {
List<String> assignees = IntStream.range(0, 1 + new Random().nextInt(10)).mapToObj(i -> randomAlphabetic(3)).collect(Collectors.toList());
assignees.stream()
- .map(assignee -> new DefaultIssue().setType(randomRuleType).setAssignee(assignee).setNew(true))
+ .map(assignee -> new DefaultIssue().setType(randomRuleType).setAssigneeUuid(assignee).setNew(true))
.forEach(underTest::add);
DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.ASSIGNEE);
public void add_counts_issue_per_assignee_off_leak_globally_and_per_assignee() {
List<String> assignees = IntStream.range(0, 1 + new Random().nextInt(10)).mapToObj(i -> randomAlphabetic(3)).collect(Collectors.toList());
assignees.stream()
- .map(assignee -> new DefaultIssue().setType(randomRuleType).setAssignee(assignee).setNew(false))
+ .map(assignee -> new DefaultIssue().setType(randomRuleType).setAssigneeUuid(assignee).setNew(false))
.forEach(underTest::add);
DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.ASSIGNEE);
@Test
public void add_does_not_assignee_if_empty_neither_globally_nor_per_assignee() {
- underTest.add(new DefaultIssue().setType(randomRuleType).setAssignee(null).setNew(new Random().nextBoolean()));
+ underTest.add(new DefaultIssue().setType(randomRuleType).setAssigneeUuid(null).setNew(new Random().nextBoolean()));
DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.ASSIGNEE);
assertThat(globalDistribution.getTotal()).isEqualTo(0);
public void add_counts_issue_per_tags_on_leak_globally_and_per_assignee() {
List<String> tags = IntStream.range(0, 1 + new Random().nextInt(10)).mapToObj(i -> randomAlphabetic(3)).collect(Collectors.toList());
String assignee = randomAlphanumeric(10);
- underTest.add(new DefaultIssue().setType(randomRuleType).setTags(tags).setAssignee(assignee).setNew(true));
+ underTest.add(new DefaultIssue().setType(randomRuleType).setTags(tags).setAssigneeUuid(assignee).setNew(true));
DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.TAG);
DistributedMetricStatsInt assigneeDistribution = underTest.getAssigneesStatistics().get(assignee).getDistributedMetricStats(Metric.TAG);
public void add_counts_issue_per_tags_off_leak_globally_and_per_assignee() {
List<String> tags = IntStream.range(0, 1 + new Random().nextInt(10)).mapToObj(i -> randomAlphabetic(3)).collect(Collectors.toList());
String assignee = randomAlphanumeric(10);
- underTest.add(new DefaultIssue().setType(randomRuleType).setTags(tags).setAssignee(assignee).setNew(false));
+ underTest.add(new DefaultIssue().setType(randomRuleType).setTags(tags).setAssigneeUuid(assignee).setNew(false));
DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.TAG);
DistributedMetricStatsInt assigneeDistribution = underTest.getAssigneesStatistics().get(assignee).getDistributedMetricStats(Metric.TAG);
@Test
public void add_does_not_count_tags_if_empty_neither_globally_nor_per_assignee() {
String assignee = randomAlphanumeric(10);
- underTest.add(new DefaultIssue().setType(randomRuleType).setTags(Collections.emptyList()).setAssignee(assignee).setNew(new Random().nextBoolean()));
+ underTest.add(new DefaultIssue().setType(randomRuleType).setTags(Collections.emptyList()).setAssigneeUuid(assignee).setNew(new Random().nextBoolean()));
DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.TAG);
DistributedMetricStatsInt assigneeDistribution = underTest.getAssigneesStatistics().get(assignee).getDistributedMetricStats(Metric.TAG);
int expected = efforts.stream().mapToInt(s -> s).sum();
String assignee = randomAlphanumeric(10);
efforts.stream()
- .map(effort -> new DefaultIssue().setType(randomRuleType).setEffort(Duration.create(effort)).setAssignee(assignee).setNew(true))
+ .map(effort -> new DefaultIssue().setType(randomRuleType).setEffort(Duration.create(effort)).setAssigneeUuid(assignee).setNew(true))
.forEach(underTest::add);
MetricStatsLong globalDistribution = underTest.globalStatistics().effort();
int expected = efforts.stream().mapToInt(s -> s).sum();
String assignee = randomAlphanumeric(10);
efforts.stream()
- .map(effort -> new DefaultIssue().setType(randomRuleType).setEffort(Duration.create(effort)).setAssignee(assignee).setNew(false))
+ .map(effort -> new DefaultIssue().setType(randomRuleType).setEffort(Duration.create(effort)).setAssigneeUuid(assignee).setNew(false))
.forEach(underTest::add);
MetricStatsLong globalDistribution = underTest.globalStatistics().effort();
@Test
public void add_does_not_sum_effort_if_null_neither_globally_nor_per_assignee() {
String assignee = randomAlphanumeric(10);
- underTest.add(new DefaultIssue().setType(randomRuleType).setEffort(null).setAssignee(assignee).setNew(new Random().nextBoolean()));
+ underTest.add(new DefaultIssue().setType(randomRuleType).setEffort(null).setAssigneeUuid(assignee).setNew(new Random().nextBoolean()));
MetricStatsLong globalDistribution = underTest.globalStatistics().effort();
MetricStatsLong assigneeDistribution = underTest.getAssigneesStatistics().get(assignee).effort();
.setType(randomRuleType)
.setComponentUuid(componentUuid)
.setTags(ImmutableSet.of(tag))
- .setAssignee(assignee)
+ .setAssigneeUuid(assignee)
.setRuleKey(ruleKey)
.setEffort(Duration.create(effort)));
.setKey("ABCDE")
.setStatus(STATUS_OPEN)
.setRuleKey(RuleKey.of("squid", "AvoidCycle"))
- .setAssignee("morgan");
+ .setAssigneeUuid("morgan");
workflow.start();
workflow.doTransition(issue, DefaultTransitions.FALSE_POSITIVE, IssueChangeContext.createScan(new Date()));
.setKey("ABCDE")
.setStatus(STATUS_OPEN)
.setRuleKey(RuleKey.of("squid", "AvoidCycle"))
- .setAssignee("morgan");
+ .setAssigneeUuid("morgan");
workflow.start();
workflow.doTransition(issue, DefaultTransitions.WONT_FIX, IssueChangeContext.createScan(new Date()));
*/
package org.sonar.server.issue.ws;
+import java.util.Optional;
import javax.annotation.Nullable;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import org.mockito.ArgumentCaptor;
-import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.Response;
import org.sonar.api.utils.internal.TestSystem2;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
-import org.sonar.db.component.ComponentDto;
import org.sonar.db.issue.IssueDto;
import org.sonar.db.organization.OrganizationDto;
-import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.es.EsTester;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.ws.WsActionTester;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
+import static org.junit.rules.ExpectedException.none;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
import static org.sonar.api.web.UserRole.CODEVIEWER;
import static org.sonar.api.web.UserRole.USER;
+import static org.sonar.server.tester.UserSessionRule.standalone;
public class AssignActionTest {
private static final String PREVIOUS_ASSIGNEE = "previous";
private static final String CURRENT_USER_LOGIN = "john";
+ private static final String CURRENT_USER_UUID = "1";
private static final long PAST = 10_000_000_000L;
private static final long NOW = 50_000_000_000L;
private TestSystem2 system2 = new TestSystem2().setNow(NOW);
@Rule
- public ExpectedException expectedException = ExpectedException.none();
+ public ExpectedException expectedException = none();
@Rule
- public UserSessionRule userSession = UserSessionRule.standalone();
+ public UserSessionRule userSession = standalone();
@Rule
public EsTester es = EsTester.create();
@Rule
public DbTester db = DbTester.create(system2);
+ public DbClient dbClient = db.getDbClient();
+ private DbSession session = db.getSession();
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
- private IssueIndexer issueIndexer = new IssueIndexer(es.client(), db.getDbClient(), new IssueIteratorFactory(db.getDbClient()));
+ private IssueIndexer issueIndexer = new IssueIndexer(es.client(), dbClient, new IssueIteratorFactory(dbClient));
private OperationResponseWriter responseWriter = mock(OperationResponseWriter.class);
private TestIssueChangePostProcessor issueChangePostProcessor = new TestIssueChangePostProcessor();
- private AssignAction underTest = new AssignAction(system2, userSession, db.getDbClient(), new IssueFinder(db.getDbClient(), userSession), new IssueFieldsSetter(),
- new IssueUpdater(db.getDbClient(),
- new ServerIssueStorage(system2, new DefaultRuleFinder(db.getDbClient(), defaultOrganizationProvider), db.getDbClient(), issueIndexer),
+ private AssignAction underTest = new AssignAction(system2, userSession, dbClient, new IssueFinder(dbClient, userSession), new IssueFieldsSetter(),
+ new IssueUpdater(dbClient,
+ new ServerIssueStorage(system2, new DefaultRuleFinder(dbClient, defaultOrganizationProvider), dbClient, issueIndexer),
mock(NotificationManager.class), issueChangePostProcessor),
responseWriter);
- private ArgumentCaptor<SearchResponseData> preloadedSearchResponseDataCaptor = ArgumentCaptor.forClass(SearchResponseData.class);
private WsActionTester ws = new WsActionTester(underTest);
@Test
public void assign_to_someone() {
IssueDto issue = newIssueWithBrowsePermission();
- insertUser("arthur");
+ UserDto arthur = insertUser("arthur");
ws.newRequest()
.setParam("issue", issue.getKey())
.setParam("assignee", "arthur")
.execute();
- checkIssueAssignee(issue.getKey(), "arthur");
- verify(responseWriter).write(eq(issue.getKey()), preloadedSearchResponseDataCaptor.capture(), any(Request.class), any(Response.class));
- verifyContentOfPreloadedSearchResponseData(issue);
+ checkIssueAssignee(issue.getKey(), arthur.getUuid());
+ Optional<IssueDto> optionalIssueDto = dbClient.issueDao().selectByKey(session, issue.getKey());
+ assertThat(optionalIssueDto).isPresent();
+ assertThat(optionalIssueDto.get().getAssigneeUuid()).isEqualTo(arthur.getUuid());
assertThat(issueChangePostProcessor.wasCalled()).isFalse();
}
.setParam("assignee", "_me")
.execute();
- checkIssueAssignee(issue.getKey(), CURRENT_USER_LOGIN);
- verify(responseWriter).write(eq(issue.getKey()), preloadedSearchResponseDataCaptor.capture(), any(Request.class), any(Response.class));
- verifyContentOfPreloadedSearchResponseData(issue);
+ checkIssueAssignee(issue.getKey(), CURRENT_USER_UUID);
+ Optional<IssueDto> optionalIssueDto = dbClient.issueDao().selectByKey(session, issue.getKey());
+ assertThat(optionalIssueDto).isPresent();
+ assertThat(optionalIssueDto.get().getAssigneeUuid()).isEqualTo(CURRENT_USER_UUID);
assertThat(issueChangePostProcessor.wasCalled()).isFalse();
}
.setParam("me", "true")
.execute();
- checkIssueAssignee(issue.getKey(), CURRENT_USER_LOGIN);
- verify(responseWriter).write(eq(issue.getKey()), preloadedSearchResponseDataCaptor.capture(), any(Request.class), any(Response.class));
- verifyContentOfPreloadedSearchResponseData(issue);
+ checkIssueAssignee(issue.getKey(), CURRENT_USER_UUID);
+ Optional<IssueDto> optionalIssueDto = dbClient.issueDao().selectByKey(session, issue.getKey());
+ assertThat(optionalIssueDto).isPresent();
+ assertThat(optionalIssueDto.get().getAssigneeUuid()).isEqualTo(CURRENT_USER_UUID);
}
@Test
.execute();
checkIssueAssignee(issue.getKey(), null);
- verify(responseWriter).write(eq(issue.getKey()), preloadedSearchResponseDataCaptor.capture(), any(Request.class), any(Response.class));
- verifyContentOfPreloadedSearchResponseData(issue);
+ Optional<IssueDto> optionalIssueDto = dbClient.issueDao().selectByKey(session, issue.getKey());
+ assertThat(optionalIssueDto).isPresent();
+ assertThat(optionalIssueDto.get().getAssigneeUuid()).isNull();
assertThat(issueChangePostProcessor.wasCalled()).isFalse();
}
.execute();
checkIssueAssignee(issue.getKey(), null);
- verify(responseWriter).write(eq(issue.getKey()), preloadedSearchResponseDataCaptor.capture(), any(Request.class), any(Response.class));
- verifyContentOfPreloadedSearchResponseData(issue);
+ Optional<IssueDto> optionalIssueDto = dbClient.issueDao().selectByKey(session, issue.getKey());
+ assertThat(optionalIssueDto).isPresent();
+ assertThat(optionalIssueDto.get().getAssigneeUuid()).isNull();
+ assertThat(issueChangePostProcessor.wasCalled()).isFalse();
}
@Test
public void nothing_to_do_when_new_assignee_is_same_as_old_one() {
- IssueDto issue = newIssueWithBrowsePermission();
- insertUser(PREVIOUS_ASSIGNEE);
+ UserDto user = insertUser("Bob");
+ IssueDto issue = newIssue(user.getUuid());
+ setUserWithBrowsePermission(issue);
ws.newRequest()
.setParam("issue", issue.getKey())
- .setParam("assignee", PREVIOUS_ASSIGNEE)
+ .setParam("assignee", user.getLogin())
.execute();
- IssueDto issueReloaded = db.getDbClient().issueDao().selectByKey(db.getSession(), issue.getKey()).get();
- assertThat(issueReloaded.getAssignee()).isEqualTo(PREVIOUS_ASSIGNEE);
+ IssueDto issueReloaded = dbClient.issueDao().selectByKey(db.getSession(), issue.getKey()).get();
+ assertThat(issueReloaded.getAssigneeUuid()).isEqualTo(user.getUuid());
assertThat(issueReloaded.getUpdatedAt()).isEqualTo(PAST);
assertThat(issueReloaded.getIssueUpdateTime()).isEqualTo(PAST);
}
@Test
public void fail_when_not_authenticated() {
- IssueDto issue = newIssue();
+ IssueDto issue = newIssue(PREVIOUS_ASSIGNEE);
userSession.anonymous();
expectedException.expect(UnauthorizedException.class);
@Test
public void fail_when_missing_browse_permission() {
- IssueDto issue = newIssue();
+ IssueDto issue = newIssue(PREVIOUS_ASSIGNEE);
setUserWithPermission(issue, CODEVIEWER);
expectedException.expect(ForbiddenException.class);
.execute();
}
- private void verifyContentOfPreloadedSearchResponseData(IssueDto issue) {
- SearchResponseData preloadedSearchResponseData = preloadedSearchResponseDataCaptor.getValue();
- assertThat(preloadedSearchResponseData.getIssues())
- .extracting(IssueDto::getKey)
- .containsOnly(issue.getKey());
- assertThat(preloadedSearchResponseData.getRules())
- .extracting(RuleDefinitionDto::getKey)
- .containsOnly(issue.getRuleKey());
- assertThat(preloadedSearchResponseData.getComponents())
- .extracting(ComponentDto::uuid)
- .containsOnly(issue.getComponentUuid(), issue.getProjectUuid());
- }
-
private UserDto insertUser(String login) {
UserDto user = db.users().insertUser(login);
db.organizations().addMember(db.getDefaultOrganization(), user);
return user;
}
- private IssueDto newIssue() {
- IssueDto issue = db.issues().insertIssue(
+ private IssueDto newIssue(String assignee) {
+ IssueDto issue = db.issues().insertIssue(
issueDto -> issueDto
- .setAssignee(PREVIOUS_ASSIGNEE)
+ .setAssigneeUuid(assignee)
.setCreatedAt(PAST).setIssueCreationTime(PAST)
.setUpdatedAt(PAST).setIssueUpdateTime(PAST));
return issue;
}
private IssueDto newIssueWithBrowsePermission() {
- IssueDto issue = newIssue();
+ IssueDto issue = newIssue(PREVIOUS_ASSIGNEE);
setUserWithBrowsePermission(issue);
return issue;
}
insertUser(CURRENT_USER_LOGIN);
userSession.logIn(CURRENT_USER_LOGIN)
.addProjectPermission(permission,
- db.getDbClient().componentDao().selectByUuid(db.getSession(), issue.getProjectUuid()).get(),
- db.getDbClient().componentDao().selectByUuid(db.getSession(), issue.getComponentUuid()).get());
+ dbClient.componentDao().selectByUuid(db.getSession(), issue.getProjectUuid()).get(),
+ dbClient.componentDao().selectByUuid(db.getSession(), issue.getComponentUuid()).get());
}
private void checkIssueAssignee(String issueKey, @Nullable String expectedAssignee) {
- IssueDto issueReloaded = db.getDbClient().issueDao().selectByKey(db.getSession(), issueKey).get();
- assertThat(issueReloaded.getAssignee()).isEqualTo(expectedAssignee);
+ IssueDto issueReloaded = dbClient.issueDao().selectByKey(db.getSession(), issueKey).get();
+ assertThat(issueReloaded.getAssigneeUuid()).isEqualTo(expectedAssignee);
assertThat(issueReloaded.getIssueUpdateTime()).isEqualTo(NOW);
assertThat(issueReloaded.getUpdatedAt()).isEqualTo(NOW);
}
import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
-import org.sonar.db.component.ComponentDbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.issue.IssueChangeDto;
import org.sonar.db.issue.IssueDbTester;
import org.sonar.db.rule.RuleDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.es.EsTester;
-import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.issue.Action;
import org.sonar.server.issue.IssueFieldsSetter;
@Test
public void remove_assignee() {
setUserProjectPermissions(USER);
- IssueDto issueDto = db.issues().insertIssue(newUnresolvedIssue().setAssignee("arthur"));
+ IssueDto issueDto = db.issues().insertIssue(newUnresolvedIssue().setAssigneeUuid("arthur"));
BulkChangeWsResponse response = call(builder()
.setIssues(singletonList(issueDto.getKey()))
checkResponse(response, 1, 1, 0, 0);
IssueDto reloaded = getIssueByKeys(issueDto.getKey()).get(0);
- assertThat(reloaded.getAssignee()).isNull();
+ assertThat(reloaded.getAssigneeUuid()).isNull();
assertThat(reloaded.getUpdatedAt()).isEqualTo(NOW);
// no need to refresh measures
UserDto userToAssign = db.users().insertUser("arthur");
db.organizations().addMember(organization, user);
db.organizations().addMember(organization, userToAssign);
- IssueDto issue1 = db.issues().insertIssue(newUnresolvedIssue().setAssignee(user.getLogin())).setType(BUG).setSeverity(MINOR);
- IssueDto issue2 = db.issues().insertIssue(newUnresolvedIssue().setAssignee(userToAssign.getLogin())).setType(BUG).setSeverity(MAJOR);
- IssueDto issue3 = db.issues().insertIssue(newUnresolvedIssue().setAssignee(null)).setType(VULNERABILITY).setSeverity(MAJOR);
+ IssueDto issue1 = db.issues().insertIssue(newUnresolvedIssue().setAssigneeUuid(user.getUuid())).setType(BUG).setSeverity(MINOR);
+ IssueDto issue2 = db.issues().insertIssue(newUnresolvedIssue().setAssigneeUuid(userToAssign.getLogin())).setType(BUG).setSeverity(MAJOR);
+ IssueDto issue3 = db.issues().insertIssue(newUnresolvedIssue().setAssigneeUuid(null)).setType(VULNERABILITY).setSeverity(MAJOR);
BulkChangeWsResponse response = call(builder()
.setIssues(asList(issue1.getKey(), issue2.getKey(), issue3.getKey()))
checkResponse(response, 3, 3, 0, 0);
assertThat(getIssueByKeys(issue1.getKey(), issue2.getKey(), issue3.getKey()))
- .extracting(IssueDto::getKey, IssueDto::getAssignee, IssueDto::getType, IssueDto::getSeverity, IssueDto::getUpdatedAt)
+ .extracting(IssueDto::getKey, IssueDto::getAssigneeUuid, IssueDto::getType, IssueDto::getSeverity, IssueDto::getUpdatedAt)
.containsOnly(
- tuple(issue1.getKey(), userToAssign.getLogin(), VULNERABILITY.getDbConstant(), MINOR, NOW),
- tuple(issue2.getKey(), userToAssign.getLogin(), VULNERABILITY.getDbConstant(), MINOR, NOW),
- tuple(issue3.getKey(), userToAssign.getLogin(), VULNERABILITY.getDbConstant(), MINOR, NOW));
+ tuple(issue1.getKey(), userToAssign.getUuid(), VULNERABILITY.getDbConstant(), MINOR, NOW),
+ tuple(issue2.getKey(), userToAssign.getUuid(), VULNERABILITY.getDbConstant(), MINOR, NOW),
+ tuple(issue3.getKey(), userToAssign.getUuid(), VULNERABILITY.getDbConstant(), MINOR, NOW));
verifyPostProcessorCalled(file);
}
.setResolution(null)
.setRuleId(rule.getId())
.setRuleKey(rule.getRuleKey(), rule.getRepositoryKey())
- .setAssignee(user.getLogin())
.setType(BUG)
.setSeverity(MINOR));
.setResolution(null)
.setRuleId(rule.getId())
.setRuleKey(rule.getRuleKey(), rule.getRepositoryKey())
- .setAssignee(user.getLogin())
.setType(BUG)
.setSeverity(MAJOR));
import java.time.Clock;
import java.util.Arrays;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.groups.Tuple.tuple;
+import static org.junit.rules.ExpectedException.none;
+import static org.sonar.api.issue.Issue.RESOLUTION_FIXED;
+import static org.sonar.api.issue.Issue.STATUS_RESOLVED;
+import static org.sonar.api.utils.DateUtils.parseDate;
import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
import static org.sonar.db.component.ComponentTesting.newFileDto;
+import static org.sonar.db.issue.IssueTesting.newDto;
+import static org.sonar.server.tester.UserSessionRule.standalone;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_BRANCH;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.DEPRECATED_FACET_MODE_DEBT;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.FACET_MODE_EFFORT;
public class SearchActionTest {
@Rule
- public UserSessionRule userSessionRule = UserSessionRule.standalone();
+ public UserSessionRule userSessionRule = standalone();
@Rule
public DbTester db = DbTester.create();
@Rule
public EsTester es = EsTester.create();
@Rule
- public ExpectedException expectedException = ExpectedException.none();
+ public ExpectedException expectedException = none();
private DbClient dbClient = db.getDbClient();
private DbSession session = db.getSession();
private SearchResponseFormat searchResponseFormat = new SearchResponseFormat(new Durations(), new WsResponseCommonFormat(languages), languages, new AvatarResolverImpl());
private WsActionTester ws = new WsActionTester(new SearchAction(userSessionRule, issueIndex, issueQueryFactory, searchResponseLoader, searchResponseFormat, System2.INSTANCE,
dbClient));
+ private StartupIndexer permissionIndexer = new PermissionIndexer(dbClient, es.client(), issueIndexer);
+
private OrganizationDto defaultOrganization;
private OrganizationDto otherOrganization1;
private OrganizationDto otherOrganization2;
- private StartupIndexer permissionIndexer = new PermissionIndexer(dbClient, es.client(), issueIndexer);
@Before
public void setUp() {
@Test
public void response_contains_all_fields_except_additional_fields() {
- db.users().insertUser(u -> u.setLogin("simon").setName("Simon").setEmail("simon@email.com"));
- db.users().insertUser(u -> u.setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com"));
+ UserDto simon = db.users().insertUser(u -> u.setLogin("simon").setName("Simon").setEmail("simon@email.com"));
+ UserDto fabrice = db.users().insertUser(u -> u.setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com"));
ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY"));
indexPermissions();
ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
- IssueDto issue = IssueTesting.newDto(newExternalRule(), file, project)
+ IssueDto issue = newDto(newExternalRule(), file, project)
.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
.setEffort(10L)
.setLine(42)
.setChecksum("a227e508d6646b55a086ee11d63b21e9")
.setMessage("the message")
- .setStatus(Issue.STATUS_RESOLVED)
- .setResolution(Issue.RESOLUTION_FIXED)
+ .setStatus(STATUS_RESOLVED)
+ .setResolution(RESOLUTION_FIXED)
.setSeverity("MAJOR")
.setAuthorLogin("John")
- .setAssignee("simon")
+ .setAssigneeUuid(simon.getUuid())
.setTags(asList("bug", "owasp"))
.setIssueCreationDate(DateUtils.parseDateTime("2014-09-04T00:00:00+0100"))
.setIssueUpdateDate(DateUtils.parseDateTime("2017-12-04T00:00:00+0100"));
.setEndOffset(12)
.build())
.build())));
- IssueDto issue = IssueTesting.newDto(newRule(), file, project)
+ IssueDto issue = newDto(newRule(), file, project)
.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
.setEffort(10L)
.setLine(42)
.setChecksum("a227e508d6646b55a086ee11d63b21e9")
.setMessage("the message")
- .setStatus(Issue.STATUS_RESOLVED)
- .setResolution(Issue.RESOLUTION_FIXED)
+ .setStatus(STATUS_RESOLVED)
+ .setResolution(RESOLUTION_FIXED)
.setSeverity("MAJOR")
.setAuthorLogin(fabrice.getLogin())
- .setAssignee(simon.getLogin())
+ .setAssigneeUuid(simon.getUuid())
.setTags(asList("bug", "owasp"))
.setLocations(locations.build())
.setIssueCreationDate(DateUtils.parseDateTime("2014-09-04T00:00:00+0100"))
}
@Test
+ @Ignore // TODO GJT when adressing ticket on IssueChangesUuid
public void issue_with_comments() {
- db.users().insertUser(u -> u.setLogin("john").setName("John"));
- db.users().insertUser(u -> u.setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com"));
+ UserDto john = db.users().insertUser(u -> u.setLogin("john").setName("John"));
+ UserDto fabrice = db.users().insertUser(u -> u.setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com"));
ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY"));
indexPermissions();
ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
- IssueDto issue = IssueTesting.newDto(newRule(), file, project)
+ IssueDto issue = newDto(newRule(), file, project)
.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
dbClient.issueDao().insert(session, issue);
.setKey("COMMENT-ABCD")
.setChangeData("*My comment*")
.setChangeType(IssueChangeDto.TYPE_COMMENT)
- .setUserLogin("john")
+ .setUserLogin(john.getUuid())
.setIssueChangeCreationDate(DateUtils.parseDateTime("2014-09-09T12:00:00+0000").getTime()));
dbClient.issueChangeDao().insert(session,
new IssueChangeDto().setIssueKey(issue.getKey())
.setKey("COMMENT-ABCE")
.setChangeData("Another comment")
.setChangeType(IssueChangeDto.TYPE_COMMENT)
- .setUserLogin("fabrice")
+ .setUserLogin(fabrice.getUuid())
.setIssueChangeCreationDate(DateUtils.parseDateTime("2014-09-10T12:00:00+0000").getTime()));
session.commit();
indexIssues();
- userSessionRule.logIn("john");
+ userSessionRule.logIn(john);
ws.newRequest()
.setParam("additionalFields", "comments,users")
.execute()
ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY"));
indexPermissions();
ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
- IssueDto issue = IssueTesting.newDto(newRule(), file, project)
+ IssueDto issue = newDto(newRule(), file, project)
.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
dbClient.issueDao().insert(session, issue);
@Test
public void load_additional_fields() {
- db.users().insertUser(u -> u.setLogin("simon").setName("Simon").setEmail("simon@email.com"));
- db.users().insertUser(u -> u.setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com"));
+ UserDto simon = db.users().insertUser(u -> u.setLogin("simon").setName("Simon").setEmail("simon@email.com"));
ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY").setLanguage("java"));
indexPermissions();
ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY").setLanguage("js"));
- IssueDto issue = IssueTesting.newDto(newRule(), file, project)
+ IssueDto issue = newDto(newRule(), file, project)
.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
- .setAuthorLogin("John")
- .setAssignee("simon");
+ .setAssigneeUuid(simon.getUuid());
dbClient.issueDao().insert(session, issue);
session.commit();
indexIssues();
@Test
public void load_additional_fields_with_issue_admin_permission() {
- db.users().insertUser(u -> u.setLogin("simon").setName("Simon").setEmail("simon@email.com"));
- db.users().insertUser(u -> u.setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com"));
+ UserDto simon = db.users().insertUser(u -> u.setLogin("simon").setName("Simon").setEmail("simon@email.com"));
+ UserDto fabrice = db.users().insertUser(u -> u.setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com"));
+
ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY").setLanguage("java"));
grantPermissionToAnyone(project, ISSUE_ADMIN);
indexPermissions();
ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY").setLanguage("js"));
- IssueDto issue = IssueTesting.newDto(newRule(), file, project)
+ IssueDto issue = newDto(newRule(), file, project)
.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
- .setAuthorLogin("John")
- .setAssignee("simon");
+ .setAuthorLogin(fabrice.getLogin())
+ .setAssigneeUuid(simon.getUuid());
dbClient.issueDao().insert(session, issue);
session.commit();
indexIssues();
.setDbKey("REMOVED_FILE_KEY")
.setEnabled(false));
- IssueDto issue = IssueTesting.newDto(rule, removedFile, project)
+ IssueDto issue = newDto(rule, removedFile, project)
.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
.setComponent(removedFile)
.setStatus("OPEN").setResolution("OPEN")
indexPermissions();
ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
for (int i = 0; i < SearchOptions.MAX_LIMIT + 1; i++) {
- IssueDto issue = IssueTesting.newDto(rule, file, project);
+ IssueDto issue = newDto(rule, file, project).setAssigneeUuid(null);
dbClient.issueDao().insert(session, issue);
}
session.commit();
indexPermissions();
ComponentDto module = insertComponent(ComponentTesting.newModuleDto(project).setDbKey("ModuleHavingFile"));
ComponentDto file = insertComponent(newFileDto(module, null, "BCDE").setDbKey("FileLinkedToModule"));
- IssueDto issue = IssueTesting.newDto(newRule(), file, project);
+ IssueDto issue = newDto(newRule(), file, project);
dbClient.issueDao().insert(session, issue);
session.commit();
indexIssues();
ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY"));
indexPermissions();
ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
- IssueDto issue = IssueTesting.newDto(newRule(), file, project)
- .setIssueCreationDate(DateUtils.parseDate("2014-09-04"))
- .setIssueUpdateDate(DateUtils.parseDate("2017-12-04"))
+ IssueDto issue = newDto(newRule(), file, project)
+ .setIssueCreationDate(parseDate("2014-09-04"))
+ .setIssueUpdateDate(parseDate("2017-12-04"))
.setEffort(10L)
.setStatus("OPEN")
.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
@Test
public void display_facets_in_effort_mode() {
+ UserDto john = db.users().insertUser(u -> u.setLogin("john").setName("John").setEmail("john@email.com"));
+
ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY"));
indexPermissions();
ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
- IssueDto issue = IssueTesting.newDto(newRule(), file, project)
- .setIssueCreationDate(DateUtils.parseDate("2014-09-04"))
- .setIssueUpdateDate(DateUtils.parseDate("2017-12-04"))
+ IssueDto issue = newDto(newRule(), file, project)
+ .setIssueCreationDate(parseDate("2014-09-04"))
+ .setIssueUpdateDate(parseDate("2017-12-04"))
.setEffort(10L)
.setStatus("OPEN")
.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
session.commit();
indexIssues();
- userSessionRule.logIn("john");
+ userSessionRule.logIn(john);
ws.newRequest()
.setParam("resolved", "false")
.setParam(PARAM_COMPONENT_KEYS, project.getKey())
@Test
public void display_zero_valued_facets_for_selected_items() {
+ UserDto john = db.users().insertUser(u -> u.setLogin("john").setName("John").setEmail("john@email.com"));
+
+
ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY"));
indexPermissions();
ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
- IssueDto issue = IssueTesting.newDto(newRule(), file, project)
- .setIssueCreationDate(DateUtils.parseDate("2014-09-04"))
- .setIssueUpdateDate(DateUtils.parseDate("2017-12-04"))
+ IssueDto issue = newDto(newRule(), file, project)
+ .setIssueCreationDate(parseDate("2014-09-04"))
+ .setIssueUpdateDate(parseDate("2017-12-04"))
.setEffort(10L)
.setStatus("OPEN")
.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
session.commit();
indexIssues();
- userSessionRule.logIn("john");
+ userSessionRule.logIn(john);
ws.newRequest()
.setParam(PARAM_COMPONENT_KEYS, project.getKey())
.setParam("resolved", "false")
@Test
public void assignedToMe_facet_must_escape_login_of_authenticated_user() {
// login looks like an invalid regexp
- userSessionRule.logIn("foo[");
+ UserDto user = db.users().insertUser(u -> u.setLogin("foo[").setName("foo").setEmail("foo@email.com"));
+
+ userSessionRule.logIn(user);
// should not fail
ws.newRequest()
@Test
public void filter_by_assigned_to_me() {
- db.users().insertUser(u -> u.setLogin("john").setName("John").setEmail("john@email.com"));
+ UserDto john = db.users().insertUser(u -> u.setLogin("john").setName("John").setEmail("john@email.com"));
+ UserDto alice = db.users().insertUser(u -> u.setLogin("alice").setName("Alice").setEmail("alice@email.com"));
+
ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "PROJECT_ID").setDbKey("PROJECT_KEY"));
indexPermissions();
ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
RuleDto rule = newRule();
- IssueDto issue1 = IssueTesting.newDto(rule, file, project)
- .setIssueCreationDate(DateUtils.parseDate("2014-09-04"))
- .setIssueUpdateDate(DateUtils.parseDate("2017-12-04"))
+ IssueDto issue1 = newDto(rule, file, project)
+ .setIssueCreationDate(parseDate("2014-09-04"))
+ .setIssueUpdateDate(parseDate("2017-12-04"))
.setEffort(10L)
.setStatus("OPEN")
.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
.setSeverity("MAJOR")
- .setAssignee("john");
- IssueDto issue2 = IssueTesting.newDto(rule, file, project)
- .setIssueCreationDate(DateUtils.parseDate("2014-09-04"))
- .setIssueUpdateDate(DateUtils.parseDate("2017-12-04"))
+ .setAssigneeUuid(john.getUuid());
+ IssueDto issue2 = newDto(rule, file, project)
+ .setIssueCreationDate(parseDate("2014-09-04"))
+ .setIssueUpdateDate(parseDate("2017-12-04"))
.setEffort(10L)
.setStatus("OPEN")
.setKee("7b112bd4-b650-4037-80bc-82fd47d4eac2")
.setSeverity("MAJOR")
- .setAssignee("alice");
- IssueDto issue3 = IssueTesting.newDto(rule, file, project)
- .setIssueCreationDate(DateUtils.parseDate("2014-09-04"))
- .setIssueUpdateDate(DateUtils.parseDate("2017-12-04"))
+ .setAssigneeUuid(alice.getUuid());
+ IssueDto issue3 = newDto(rule, file, project)
+ .setIssueCreationDate(parseDate("2014-09-04"))
+ .setIssueUpdateDate(parseDate("2017-12-04"))
.setEffort(10L)
.setStatus("OPEN")
.setKee("82fd47d4-4037-b650-80bc-7b112bd4eac2")
- .setSeverity("MAJOR");
+ .setSeverity("MAJOR")
+ .setAssigneeUuid(null);
dbClient.issueDao().insert(session, issue1, issue2, issue3);
session.commit();
indexIssues();
- userSessionRule.logIn("john");
+ userSessionRule.logIn(john);
+
ws.newRequest()
.setParam("resolved", "false")
.setParam("assignees", "__me__")
.assertJson(this.getClass(), "filter_by_assigned_to_me.json");
}
+ @Test
+ public void return_empty_when_login_is_unknown() {
+
+ UserDto john = db.users().insertUser(u -> u.setLogin("john").setName("John").setEmail("john@email.com"));
+ UserDto alice = db.users().insertUser(u -> u.setLogin("alice").setName("Alice").setEmail("alice@email.com"));
+
+ ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "PROJECT_ID").setDbKey("PROJECT_KEY"));
+ indexPermissions();
+ ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
+ RuleDto rule = newRule();
+ IssueDto issue1 = newDto(rule, file, project)
+ .setIssueCreationDate(parseDate("2014-09-04"))
+ .setIssueUpdateDate(parseDate("2017-12-04"))
+ .setEffort(10L)
+ .setStatus("OPEN")
+ .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
+ .setSeverity("MAJOR")
+ .setAssigneeUuid(john.getUuid());
+ IssueDto issue2 = newDto(rule, file, project)
+ .setIssueCreationDate(parseDate("2014-09-04"))
+ .setIssueUpdateDate(parseDate("2017-12-04"))
+ .setEffort(10L)
+ .setStatus("OPEN")
+ .setKee("7b112bd4-b650-4037-80bc-82fd47d4eac2")
+ .setSeverity("MAJOR")
+ .setAssigneeUuid(alice.getUuid());
+ IssueDto issue3 = newDto(rule, file, project)
+ .setIssueCreationDate(parseDate("2014-09-04"))
+ .setIssueUpdateDate(parseDate("2017-12-04"))
+ .setEffort(10L)
+ .setStatus("OPEN")
+ .setKee("82fd47d4-4037-b650-80bc-7b112bd4eac2")
+ .setSeverity("MAJOR")
+ .setAssigneeUuid(null);
+ dbClient.issueDao().insert(session, issue1, issue2, issue3);
+ session.commit();
+ indexIssues();
+
+ userSessionRule.logIn(john);
+
+ Issues.SearchWsResponse response = ws.newRequest()
+ .setParam("resolved", "false")
+ .setParam("assignees", "unknown")
+ .setParam(WebService.Param.FACETS, "assignees")
+ .executeProtobuf(Issues.SearchWsResponse.class);
+
+ assertThat(response.getIssuesList()).isEmpty();
+ }
+
@Test
public void filter_by_assigned_to_me_unauthenticated() {
- userSessionRule.logIn();
+ UserDto poy = db.users().insertUser(u -> u.setLogin("poy").setName("poypoy").setEmail("poypoy@email.com"));
+ userSessionRule.logIn(poy);
+
+ // TODO : check test title w julien
+
+
+ UserDto alice = db.users().insertUser(u -> u.setLogin("alice").setName("Alice").setEmail("alice@email.com"));
+ UserDto john = db.users().insertUser(u -> u.setLogin("john").setName("John").setEmail("john@email.com"));
ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY"));
indexPermissions();
ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
RuleDto rule = newRule();
- IssueDto issue1 = IssueTesting.newDto(rule, file, project)
+ IssueDto issue1 = newDto(rule, file, project)
.setStatus("OPEN")
.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
- .setAssignee("john");
- IssueDto issue2 = IssueTesting.newDto(rule, file, project)
+ .setAssigneeUuid(john.getUuid());
+ IssueDto issue2 = newDto(rule, file, project)
.setStatus("OPEN")
.setKee("7b112bd4-b650-4037-80bc-82fd47d4eac2")
- .setAssignee("alice");
- IssueDto issue3 = IssueTesting.newDto(rule, file, project)
+ .setAssigneeUuid(alice.getUuid());
+ IssueDto issue3 = newDto(rule, file, project)
.setStatus("OPEN")
- .setKee("82fd47d4-4037-b650-80bc-7b112bd4eac2");
+ .setKee("82fd47d4-4037-b650-80bc-7b112bd4eac2")
+ .setAssigneeUuid(null);
dbClient.issueDao().insert(session, issue1, issue2, issue3);
session.commit();
indexIssues();
@Test
public void assigned_to_me_facet_is_sticky_relative_to_assignees() {
- db.users().insertUser(u -> u.setLogin("alice").setName("Alice").setEmail("alice@email.com"));
+ UserDto alice = db.users().insertUser(u -> u.setLogin("alice").setName("Alice").setEmail("alice@email.com"));
+ UserDto john = db.users().insertUser(u -> u.setLogin("john-bob.polop").setName("John").setEmail("john@email.com"));
ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY"));
indexPermissions();
ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
RuleDto rule = newRule();
- IssueDto issue1 = IssueTesting.newDto(rule, file, project)
- .setIssueCreationDate(DateUtils.parseDate("2014-09-04"))
- .setIssueUpdateDate(DateUtils.parseDate("2017-12-04"))
+ IssueDto issue1 = newDto(rule, file, project)
+ .setIssueCreationDate(parseDate("2014-09-04"))
+ .setIssueUpdateDate(parseDate("2017-12-04"))
.setEffort(10L)
.setStatus("OPEN")
.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
.setSeverity("MAJOR")
- .setAssignee("john-bob.polop");
- IssueDto issue2 = IssueTesting.newDto(rule, file, project)
- .setIssueCreationDate(DateUtils.parseDate("2014-09-04"))
- .setIssueUpdateDate(DateUtils.parseDate("2017-12-04"))
+ .setAssigneeUuid(john.getUuid());
+ IssueDto issue2 = newDto(rule, file, project)
+ .setIssueCreationDate(parseDate("2014-09-04"))
+ .setIssueUpdateDate(parseDate("2017-12-04"))
.setEffort(10L)
.setStatus("OPEN")
.setKee("7b112bd4-b650-4037-80bc-82fd47d4eac2")
.setSeverity("MAJOR")
- .setAssignee("alice");
- IssueDto issue3 = IssueTesting.newDto(rule, file, project)
- .setIssueCreationDate(DateUtils.parseDate("2014-09-04"))
- .setIssueUpdateDate(DateUtils.parseDate("2017-12-04"))
+ .setAssigneeUuid(alice.getUuid());
+ IssueDto issue3 = newDto(rule, file, project)
+ .setIssueCreationDate(parseDate("2014-09-04"))
+ .setIssueUpdateDate(parseDate("2017-12-04"))
.setEffort(10L)
.setStatus("OPEN")
.setKee("82fd47d4-4037-b650-80bc-7b112bd4eac2")
- .setSeverity("MAJOR");
+ .setSeverity("MAJOR")
+ .setAssigneeUuid(null);
dbClient.issueDao().insert(session, issue1, issue2, issue3);
session.commit();
indexIssues();
- userSessionRule.logIn("john-bob.polop");
+ userSessionRule.logIn(john);
ws.newRequest()
.setParam("resolved", "false")
.setParam("assignees", "alice")
ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY"));
indexPermissions();
ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
- dbClient.issueDao().insert(session, IssueTesting.newDto(rule, file, project)
+ dbClient.issueDao().insert(session, newDto(rule, file, project)
.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac1")
.setIssueUpdateDate(DateUtils.parseDateTime("2014-11-02T00:00:00+0100")));
- dbClient.issueDao().insert(session, IssueTesting.newDto(rule, file, project)
+ dbClient.issueDao().insert(session, newDto(rule, file, project)
.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
.setIssueUpdateDate(DateUtils.parseDateTime("2014-11-01T00:00:00+0100")));
- dbClient.issueDao().insert(session, IssueTesting.newDto(rule, file, project)
+ dbClient.issueDao().insert(session, newDto(rule, file, project)
.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac3")
.setIssueUpdateDate(DateUtils.parseDateTime("2014-11-03T00:00:00+0100")));
session.commit();
indexPermissions();
ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
for (int i = 0; i < 12; i++) {
- IssueDto issue = IssueTesting.newDto(rule, file, project);
+ IssueDto issue = newDto(rule, file, project);
dbClient.issueDao().insert(session, issue);
}
session.commit();
indexPermissions();
ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
for (int i = 0; i < 12; i++) {
- IssueDto issue = IssueTesting.newDto(rule, file, project);
+ IssueDto issue = newDto(rule, file, project);
dbClient.issueDao().insert(session, issue);
}
session.commit();
indexPermissions();
ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
for (int i = 0; i < 12; i++) {
- IssueDto issue = IssueTesting.newDto(rule, file, project);
+ IssueDto issue = newDto(rule, file, project).setAssigneeUuid(null);
dbClient.issueDao().insert(session, issue);
}
session.commit();
ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY"));
indexPermissions();
ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
- IssueDto issue = IssueTesting.newDto(newRule(), file, project)
- .setIssueCreationDate(DateUtils.parseDate("2014-09-04"))
- .setIssueUpdateDate(DateUtils.parseDate("2017-12-04"))
+ IssueDto issue = newDto(newRule(), file, project)
+ .setIssueCreationDate(parseDate("2014-09-04"))
+ .setIssueUpdateDate(parseDate("2017-12-04"))
.setEffort(10L)
.setStatus("OPEN")
.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
return null;
}
+ @Override public String getUuid() {
+ return null;
+ }
+
@Override
public String getName() {
return null;
public class MockUserSession extends AbstractMockUserSession<MockUserSession> {
private final String login;
+ private String uuid;
private boolean root = false;
private Integer userId;
private String name;
super(MockUserSession.class);
checkArgument(!login.isEmpty());
this.login = login;
+ setUuid(login + "uuid");
setUserId(login.hashCode());
setName(login + " name");
}
super(MockUserSession.class);
checkArgument(!userDto.getLogin().isEmpty());
this.login = userDto.getLogin();
+ setUuid(userDto.getUuid());
setUserId(userDto.getId());
setName(userDto.getName());
}
return this.login;
}
+ @Override
+ public String getUuid() {
+ return this.uuid;
+ }
+
+ public MockUserSession setUuid(String uuid) {
+ this.uuid = Objects.requireNonNull(uuid);
+ return this;
+ }
+
@Override
public String getName() {
return this.name;
MockUserSession mock = new MockUserSession("foo").setGroups(group);
assertThat(mock.getLogin()).isEqualTo("foo");
+ assertThat(mock.getUuid()).isEqualTo("foouuid");
assertThat(mock.getGroups()).extracting(GroupDto::getId).containsOnly(group.getId());
assertThat(mock.isLoggedIn()).isTrue();
}
return currentUserSession.getLogin();
}
+ @Override
+ @CheckForNull
+ public String getUuid() {
+ return currentUserSession.getUuid();
+ }
+
@Override
@CheckForNull
public String getName() {
UserSession session = newAnonymousSession();
assertThat(session.getLogin()).isNull();
+ assertThat(session.getUuid()).isNull();
assertThat(session.isLoggedIn()).isFalse();
}
return user != null ? user.getLogin() : null;
}
+ @Override
+ public String getUuid() {
+ return user != null ? user.getUuid() : null;
+ }
+
@Override
public String getName() {
return user != null ? user.getName() : null;
public void get_session_for_user() {
GroupDto group = GroupTesting.newGroupDto();
MockUserSession expected = new MockUserSession("karadoc")
+ .setUuid("karadoc-uuid")
.setUserId(123)
.setGroups(group);
threadLocalUserSession.set(expected);
assertThat(session).isSameAs(expected);
assertThat(threadLocalUserSession.getUserId()).isEqualTo(123);
assertThat(threadLocalUserSession.getLogin()).isEqualTo("karadoc");
+ assertThat(threadLocalUserSession.getUuid()).isEqualTo("karadoc-uuid");
assertThat(threadLocalUserSession.isLoggedIn()).isTrue();
assertThat(threadLocalUserSession.getGroups()).extracting(GroupDto::getId).containsOnly(group.getId());
}
status="RESOLVED"
severity="BLOCKER"
manual_severity="[false]"
- assignee="guy1"
+ assignee="uuid-of-guy1"
author_login="guy2"
checksum="FFFFF"
gap="2"
status="RESOLVED"
severity="BLOCKER"
manual_severity="[false]"
- assignee="guy1"
+ assignee="uuid-of-guy1"
author_login="guy2"
checksum="FFFFF"
gap="[null]"
status="RESOLVED"
severity="BLOCKER"
manual_severity="[false]"
- assignee="guy1"
+ assignee="uuid-of-guy1"
author_login="guy2"
checksum="FFFFF"
gap="[null]"
status="OPEN"
severity="MAJOR"
manual_severity="[false]"
- assignee="guy2"
+ assignee="uuid-of-guy2"
author_login="[null]"
checksum="FFFFF"
gap="[null]"
status="RESOLVED"
severity="BLOCKER"
manual_severity="[false]"
- assignee="guy1"
+ assignee="uuid-of-guy1"
author_login="guy2"
checksum="FFFFF"
gap="[null]"
private Duration effort;
private String status;
private String resolution;
- private String assignee;
+ private String assigneeUuid;
private String checksum;
private Map<String, String> attributes = null;
private String authorLogin = null;
@Override
@CheckForNull
public String assignee() {
- return assignee;
+ return assigneeUuid;
}
- public DefaultIssue setAssignee(@Nullable String s) {
- this.assignee = s;
+ public DefaultIssue setAssigneeUuid(@Nullable String s) {
+ this.assigneeUuid = s;
return this;
}
private String message;
private String severity;
private Double effortToFix;
- private String assignee;
+ private String assigneeUuid;
private RuleType type;
private Map<String, String> attributes;
private boolean isFromExternalRuleEngine;
return this;
}
- public DefaultIssueBuilder assignee(@Nullable String s) {
- this.assignee = s;
+ public DefaultIssueBuilder assigneeUuid(@Nullable String s) {
+ this.assigneeUuid = s;
return this;
}
issue.setManualSeverity(false);
issue.setGap(effortToFix);
issue.setLine(line);
- issue.setAssignee(assignee);
+ issue.setAssigneeUuid(assigneeUuid);
issue.setAttributes(attributes);
issue.setResolution(null);
issue.setStatus(Issue.STATUS_OPEN);
.setEffort(Duration.create(28800L))
.setStatus(Issue.STATUS_CLOSED)
.setResolution(Issue.RESOLUTION_FIXED)
- .setAssignee("julien")
+ .setAssigneeUuid("julien")
.setAuthorLogin("steph")
.setChecksum("c7b5db46591806455cf082bb348631e8")
.setNew(true)
String reporter();
/**
- * Login of the user who is assigned to this issue. Null if the issue is not assigned.
+ * UUID of the user who is assigned to this issue. Null if the issue is not assigned.
*/
@CheckForNull
String assignee();
import java.util.List;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.sonar.wsclient.issue.Issue;
import org.sonarqube.ws.Issues;
}
@Test
+ @Ignore // TODO GJT when adressing ticket on IssueChangesUuid
public void update_changelog_when_assigning_issue_by_user() {
runProjectAnalysis(ORCHESTRATOR, "shared/xoo-sample");
Issue issue = searchRandomIssue();
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.sonarqube.qa.util.Tester;
}
@Test
+ @Ignore // TODO GJT when adressing ticket on IssueChangesUuid
public void notification_for_ChangesOnMyIssue() throws Exception {
String version = RandomStringUtils.randomAlphanumeric(10);
Project project = tester.projects().provision();
import org.junit.Rule;
import org.junit.Test;
import org.sonarqube.qa.util.Tester;
+import org.sonarqube.ws.Issues;
import org.sonarqube.ws.Issues.Issue;
import org.sonarqube.ws.Organizations.Organization;
import org.sonarqube.ws.Projects;
import org.sonarqube.ws.Settings;
import org.sonarqube.ws.Users;
import org.sonarqube.ws.client.GetRequest;
+import org.sonarqube.ws.client.issues.AssignRequest;
import org.sonarqube.ws.client.organizations.AddMemberRequest;
import org.sonarqube.ws.client.organizations.SearchRequest;
import org.sonarqube.ws.client.settings.SetRequest;
.doesNotContain(loginHavingUpperCase);
}
+ @Test
+ public void issue_is_still_assigned_after_login_update() {
+ String oldLogin = tester.users().generateLogin();
+ String providerId = tester.users().generateProviderId();
+
+ // Create user using authentication
+ authenticate(oldLogin, providerId);
+
+ // Set user as member of the organization
+ Organization organization = tester.organizations().generate();
+ tester.organizations().service().addMember(new AddMemberRequest().setOrganization(organization.getKey()).setLogin(oldLogin));
+ Projects.CreateWsResponse.Project project = tester.projects().provision(organization);
+ Qualityprofiles.CreateWsResponse.QualityProfile profile = tester.qProfiles().createXooProfile(organization);
+ tester.qProfiles().assignQProfileToProject(profile, project);
+ tester.qProfiles().activateRule(profile.getKey(), "xoo:OneIssuePerLine");
+
+ // Execute project and assignee an issue to the user
+ orchestrator.executeBuild(SonarScanner.create(projectDir("shared/xoo-sample"),
+ "sonar.organization", organization.getKey(),
+ "sonar.projectKey", project.getKey(),
+ "sonar.login", "admin",
+ "sonar.password", "admin"));
+ Issues.Issue issue = tester.wsClient().issues().search(new org.sonarqube.ws.client.issues.SearchRequest().setOrganization(organization.getKey())).getIssuesList().get(0);
+ tester.wsClient().issues().assign(new AssignRequest().setIssue(issue.getKey()).setAssignee(oldLogin));
+
+ // Update login during authentication, check issue is assigned to new login
+ String newLogin = tester.users().generateLogin();
+ authenticate(newLogin, providerId);
+ tester.wsClient().issues().assign(new AssignRequest().setIssue(issue.getKey()).setAssignee(newLogin));
+ }
+
@Test
public void default_assignee_login_is_updated_after_login_update() {
String oldLogin = tester.users().generateLogin();