3 * Copyright (C) 2009-2017 SonarSource SA
4 * mailto:info AT sonarsource DOT com
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 package org.sonar.server.computation.task.projectanalysis.issue;
22 import org.junit.Test;
23 import org.junit.Rule;
24 import org.sonar.api.rules.RuleType;
25 import org.sonar.api.utils.log.LogTester;
26 import org.sonar.api.utils.log.LoggerLevel;
27 import org.sonar.core.issue.DefaultIssue;
28 import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
29 import org.sonar.server.computation.task.projectanalysis.component.Component;
30 import org.sonar.server.computation.task.projectanalysis.scm.Changeset;
31 import org.sonar.server.computation.task.projectanalysis.scm.ScmInfoRepositoryRule;
32 import org.sonar.server.issue.IssueFieldsSetter;
34 import static org.assertj.core.api.Assertions.assertThat;
35 import static org.mockito.Mockito.mock;
36 import static org.mockito.Mockito.when;
37 import static org.sonar.server.computation.task.projectanalysis.component.ReportComponent.builder;
39 public class IssueAssignerTest {
41 static final int FILE_REF = 1;
42 static final Component FILE = builder(Component.Type.FILE, FILE_REF).setKey("FILE_KEY").setUuid("FILE_UUID").build();
45 public LogTester logTester = new LogTester();
48 public ScmInfoRepositoryRule scmInfoRepository = new ScmInfoRepositoryRule();
51 public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule().setAnalysisDate(123456789L);
53 ScmAccountToUser scmAccountToUser = mock(ScmAccountToUser.class);
54 DefaultAssignee defaultAssignee = mock(DefaultAssignee.class);
56 IssueAssigner underTest = new IssueAssigner(analysisMetadataHolder, scmInfoRepository, scmAccountToUser, defaultAssignee, new IssueFieldsSetter());
59 public void nothing_to_do_if_no_changeset() throws Exception {
60 DefaultIssue issue = new DefaultIssue().setLine(1);
62 underTest.onIssue(FILE, issue);
64 assertThat(issue.authorLogin()).isNull();
68 public void set_author_to_issue() throws Exception {
69 setSingleChangeset("john", 123456789L, "rev-1");
70 DefaultIssue issue = new DefaultIssue().setLine(1);
72 underTest.onIssue(FILE, issue);
74 assertThat(issue.authorLogin()).isEqualTo("john");
78 public void does_not_set_author_to_issue_if_already_set() throws Exception {
79 setSingleChangeset("john", 123456789L, "rev-1");
80 DefaultIssue issue = new DefaultIssue()
82 .setAuthorLogin("j1234");
84 underTest.onIssue(FILE, issue);
86 assertThat(issue.authorLogin()).isEqualTo("j1234");
90 public void set_assignee_to_issue() throws Exception {
91 addScmUser("john", "John C");
92 setSingleChangeset("john", 123456789L, "rev-1");
93 DefaultIssue issue = new DefaultIssue().setLine(1);
95 underTest.onIssue(FILE, issue);
97 assertThat(issue.assignee()).isEqualTo("John C");
101 public void set_default_assignee_if_author_not_found() throws Exception {
102 addScmUser("john", null);
103 setSingleChangeset("john", 123456789L, "rev-1");
104 when(defaultAssignee.loadDefaultAssigneeLogin()).thenReturn("John C");
105 DefaultIssue issue = new DefaultIssue().setLine(1);
107 underTest.onIssue(FILE, issue);
109 assertThat(issue.assignee()).isEqualTo("John C");
113 public void doest_not_set_assignee_if_no_author() throws Exception {
114 addScmUser("john", "John C");
115 setSingleChangeset(null, 123456789L, "rev-1");
116 DefaultIssue issue = new DefaultIssue().setLine(1);
118 underTest.onIssue(FILE, issue);
120 assertThat(issue.authorLogin()).isNull();
121 assertThat(issue.assignee()).isNull();
125 public void doest_not_set_assignee_if_author_already_set_and_assignee_null() throws Exception {
126 addScmUser("john", "John C");
127 setSingleChangeset("john", 123456789L, "rev-1");
128 DefaultIssue issue = new DefaultIssue().setLine(1)
129 .setAuthorLogin("john")
132 underTest.onIssue(FILE, issue);
134 assertThat(issue.authorLogin()).isEqualTo("john");
135 assertThat(issue.assignee()).isNull();
139 public void set_last_committer_when_line_is_null() throws Exception {
140 addScmUser("henry", "Henry V");
141 Changeset changeset1 = Changeset.newChangesetBuilder()
144 .setRevision("rev-1")
147 Changeset changeset2 = Changeset.newChangesetBuilder()
149 .setDate(1234567810L)
150 .setRevision("rev-2")
152 scmInfoRepository.setScmInfo(FILE_REF, changeset1, changeset2, changeset1);
154 DefaultIssue issue = new DefaultIssue().setLine(null);
156 underTest.onIssue(FILE, issue);
158 assertThat(issue.assignee()).isEqualTo("Henry V");
162 public void when_noscm_data_is_available_defaultAssignee_should_be_used() throws Exception {
163 DefaultIssue issue = new DefaultIssue().setLine(null);
165 when(defaultAssignee.loadDefaultAssigneeLogin()).thenReturn("DefaultAssignee");
166 underTest.onIssue(FILE, issue);
168 assertThat(issue.assignee()).isEqualTo("DefaultAssignee");
173 public void set_last_committer_when_line_is_bigger_than_changeset_size() throws Exception {
174 addScmUser("john", "John C");
175 Changeset changeset = Changeset.newChangesetBuilder()
178 .setRevision("rev-1")
180 scmInfoRepository.setScmInfo(FILE_REF, changeset, changeset);
181 DefaultIssue issue = new DefaultIssue().setLine(3);
183 underTest.onIssue(FILE, issue);
185 assertThat(issue.assignee()).isEqualTo("John C");
189 public void display_warning_when_line_is_above_max_size() throws Exception {
190 setSingleChangeset("john", 123456789L, "rev-1");
191 DefaultIssue issue = new DefaultIssue().setLine(2).setType(RuleType.VULNERABILITY);
193 underTest.onIssue(FILE, issue);
195 assertThat(logTester.logs(LoggerLevel.WARN)).containsOnly(
196 "No SCM info has been found for issue DefaultIssue[key=<null>,type=VULNERABILITY,componentUuid=<null>,componentKey=<null>," +
197 "moduleUuid=<null>,moduleUuidPath=<null>,projectUuid=<null>,projectKey=<null>,ruleKey=<null>,language=<null>,severity=<null>," +
198 "manualSeverity=false,message=<null>,line=2,gap=<null>,effort=<null>,status=<null>,resolution=<null>," +
199 "assignee=<null>,checksum=<null>,attributes=<null>,authorLogin=<null>,comments=<null>,tags=<null>," +
200 "locations=<null>,creationDate=<null>,updateDate=<null>,closeDate=<null>,currentChange=<null>,changes=<null>,isNew=true,isCopied=false," +
201 "beingClosed=false,onDisabledRule=false,isChanged=false,sendNotifications=false,selectedAt=<null>]");
204 private void setSingleChangeset(String author, Long date, String revision) {
205 scmInfoRepository.setScmInfo(FILE_REF,
206 Changeset.newChangesetBuilder()
209 .setRevision(revision)
213 private void addScmUser(String scmAccount, String userName) {
214 when(scmAccountToUser.getNullable(scmAccount)).thenReturn(userName);