]> source.dussan.org Git - sonarqube.git/blob
edcefd30ed2476d93eb5c5cf213d398d03a506c2
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2017 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
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.
10  *
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.
15  *
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.
19  */
20 package org.sonar.server.issue.notification;
21
22 import com.google.common.collect.ImmutableList;
23 import com.google.common.collect.ImmutableSet;
24 import com.google.common.collect.Lists;
25 import java.util.Arrays;
26 import java.util.Collections;
27 import java.util.Date;
28 import java.util.Random;
29 import java.util.stream.Collectors;
30 import java.util.stream.IntStream;
31 import org.junit.Before;
32 import org.junit.Test;
33 import org.sonar.api.rule.RuleKey;
34 import org.sonar.api.rules.RuleType;
35 import org.sonar.api.utils.DateUtils;
36 import org.sonar.api.utils.Duration;
37 import org.sonar.api.utils.Durations;
38 import org.sonar.core.issue.DefaultIssue;
39 import org.sonar.core.util.stream.MoreCollectors;
40 import org.sonar.db.DbClient;
41 import org.sonar.db.DbSession;
42 import org.sonar.db.component.ComponentDao;
43 import org.sonar.db.component.ComponentDto;
44 import org.sonar.db.rule.RuleDao;
45 import org.sonar.db.rule.RuleDefinitionDto;
46 import org.sonar.server.user.index.UserIndex;
47
48 import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
49 import static org.assertj.core.api.Assertions.assertThat;
50 import static org.mockito.Matchers.any;
51 import static org.mockito.Matchers.anyBoolean;
52 import static org.mockito.Matchers.anyCollection;
53 import static org.mockito.Matchers.same;
54 import static org.mockito.Mockito.mock;
55 import static org.mockito.Mockito.when;
56 import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.ASSIGNEE;
57 import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.COMPONENT;
58 import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.EFFORT;
59 import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.RULE;
60 import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.RULE_TYPE;
61 import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.TAG;
62
63 public class NewIssuesNotificationTest {
64
65   private final Random random = new Random();
66   private final RuleType randomRuleType = RuleType.values()[random.nextInt(RuleType.values().length)];
67   private NewIssuesStatistics.Stats stats = new NewIssuesStatistics.Stats(i -> true);
68   private UserIndex userIndex = mock(UserIndex.class);
69   private DbClient dbClient = mock(DbClient.class);
70   private DbSession dbSession = mock(DbSession.class);
71   private ComponentDao componentDao = mock(ComponentDao.class);
72   private RuleDao ruleDao = mock(RuleDao.class);
73   private Durations durations = mock(Durations.class);
74   private NewIssuesNotification underTest = new NewIssuesNotification(userIndex, dbClient, durations);
75
76   @Before
77   public void setUp() throws Exception {
78     when(dbClient.openSession(anyBoolean())).thenReturn(dbSession);
79     when(dbClient.componentDao()).thenReturn(componentDao);
80     when(dbClient.ruleDao()).thenReturn(ruleDao);
81     when(componentDao.selectByUuids(same(dbSession), anyCollection())).thenReturn(Collections.emptyList());
82   }
83
84   @Test
85   public void set_project_without_branch() {
86     underTest.setProject("project-key", "project-uuid", "project-long-name", null);
87
88     assertThat(underTest.getFieldValue(NewIssuesEmailTemplate.FIELD_PROJECT_NAME)).isEqualTo("project-long-name");
89     assertThat(underTest.getFieldValue(NewIssuesEmailTemplate.FIELD_PROJECT_UUID)).isEqualTo("project-uuid");
90     assertThat(underTest.getFieldValue(NewIssuesEmailTemplate.FIELD_PROJECT_KEY)).isEqualTo("project-key");
91     assertThat(underTest.getFieldValue(NewIssuesEmailTemplate.FIELD_BRANCH)).isNull();
92   }
93
94   @Test
95   public void set_project_with_branch() {
96     underTest.setProject("project-key", "project-uuid", "project-long-name", "feature");
97
98     assertThat(underTest.getFieldValue(NewIssuesEmailTemplate.FIELD_PROJECT_NAME)).isEqualTo("project-long-name");
99     assertThat(underTest.getFieldValue(NewIssuesEmailTemplate.FIELD_PROJECT_UUID)).isEqualTo("project-uuid");
100     assertThat(underTest.getFieldValue(NewIssuesEmailTemplate.FIELD_PROJECT_KEY)).isEqualTo("project-key");
101     assertThat(underTest.getFieldValue(NewIssuesEmailTemplate.FIELD_BRANCH)).isEqualTo("feature");
102   }
103
104   @Test
105   public void set_project_version() {
106     String version = randomAlphanumeric(5);
107
108     underTest.setProjectVersion(version);
109
110     assertThat(underTest.getFieldValue(NewIssuesEmailTemplate.FIELD_PROJECT_VERSION)).isEqualTo(version);
111   }
112
113   @Test
114   public void set_project_version_supports_null() {
115     underTest.setProjectVersion(null);
116
117     assertThat(underTest.getFieldValue(NewIssuesEmailTemplate.FIELD_PROJECT_VERSION)).isNull();
118
119   }
120
121   @Test
122   public void set_date() {
123     Date date = new Date();
124
125     underTest.setAnalysisDate(date);
126
127     assertThat(underTest.getFieldValue(NewIssuesEmailTemplate.FIELD_PROJECT_DATE)).isEqualTo(DateUtils.formatDateTime(date));
128   }
129
130   @Test
131   public void set_statistics() {
132     addIssueNTimes(newIssue1(), 5);
133     addIssueNTimes(newIssue2(), 3);
134     when(componentDao.selectByUuids(dbSession, ImmutableSet.of("file-uuid", "directory-uuid")))
135       .thenReturn(Arrays.asList(
136         new ComponentDto().setUuid("file-uuid").setName("file-name"),
137         new ComponentDto().setUuid("directory-uuid").setName("directory-name")));
138     RuleKey rule1 = RuleKey.of("SonarQube", "rule-the-world");
139     RuleKey rule2 = RuleKey.of("SonarQube", "rule-the-universe");
140     when(ruleDao.selectDefinitionByKeys(dbSession, ImmutableSet.of(rule1, rule2)))
141       .thenReturn(
142         ImmutableList.of(newRule(rule1, "Rule the World", "Java"), newRule(rule2, "Rule the Universe", "Clojure")));
143
144     underTest.setStatistics("project-long-name", stats);
145
146     assertThat(underTest.getFieldValue(RULE_TYPE + ".BUG.count")).isEqualTo("5");
147     assertThat(underTest.getFieldValue(RULE_TYPE + ".CODE_SMELL.count")).isEqualTo("3");
148     assertThat(underTest.getFieldValue(ASSIGNEE + ".1.label")).isEqualTo("maynard");
149     assertThat(underTest.getFieldValue(ASSIGNEE + ".1.count")).isEqualTo("5");
150     assertThat(underTest.getFieldValue(ASSIGNEE + ".2.label")).isEqualTo("keenan");
151     assertThat(underTest.getFieldValue(ASSIGNEE + ".2.count")).isEqualTo("3");
152     assertThat(underTest.getFieldValue(TAG + ".1.label")).isEqualTo("owasp");
153     assertThat(underTest.getFieldValue(TAG + ".1.count")).isEqualTo("8");
154     assertThat(underTest.getFieldValue(TAG + ".2.label")).isEqualTo("bug");
155     assertThat(underTest.getFieldValue(TAG + ".2.count")).isEqualTo("5");
156     assertThat(underTest.getFieldValue(COMPONENT + ".1.label")).isEqualTo("file-name");
157     assertThat(underTest.getFieldValue(COMPONENT + ".1.count")).isEqualTo("5");
158     assertThat(underTest.getFieldValue(COMPONENT + ".2.label")).isEqualTo("directory-name");
159     assertThat(underTest.getFieldValue(COMPONENT + ".2.count")).isEqualTo("3");
160     assertThat(underTest.getFieldValue(RULE + ".1.label")).isEqualTo("Rule the World (Java)");
161     assertThat(underTest.getFieldValue(RULE + ".1.count")).isEqualTo("5");
162     assertThat(underTest.getFieldValue(RULE + ".2.label")).isEqualTo("Rule the Universe (Clojure)");
163     assertThat(underTest.getFieldValue(RULE + ".2.count")).isEqualTo("3");
164     assertThat(underTest.getDefaultMessage()).startsWith("8 new issues on project-long-name");
165   }
166
167   @Test
168   public void add_only_5_assignees_with_biggest_issue_counts() {
169     String[] assignees = IntStream.range(0, 6 + random.nextInt(10)).mapToObj(s -> "assignee" + s).toArray(String[]::new);
170     NewIssuesStatistics.Stats stats = new NewIssuesStatistics.Stats(i -> true);
171     int i = assignees.length;
172     for (String assignee : assignees) {
173       IntStream.range(0, i).mapToObj(j -> new DefaultIssue().setType(randomRuleType).setAssignee(assignee)).forEach(stats::add);
174       i--;
175     }
176
177     underTest.setStatistics(randomAlphanumeric(20), stats);
178
179     for (int j = 0; j < 5; j++) {
180       String fieldBase = ASSIGNEE + "." + (j + 1);
181       assertThat(underTest.getFieldValue(fieldBase + ".label")).as("label of %s", fieldBase).isEqualTo(assignees[j]);
182       assertThat(underTest.getFieldValue(fieldBase + ".count")).as("count of %s", fieldBase).isEqualTo(String.valueOf(assignees.length - j));
183     }
184     assertThat(underTest.getFieldValue(ASSIGNEE + ".6.label")).isNull();
185     assertThat(underTest.getFieldValue(ASSIGNEE + ".6.count")).isNull();
186   }
187
188   @Test
189   public void add_only_5_components_with_biggest_issue_counts() {
190     String[] componentUuids = IntStream.range(0, 6 + random.nextInt(10)).mapToObj(s -> "component_uuid_" + s).toArray(String[]::new);
191     NewIssuesStatistics.Stats stats = new NewIssuesStatistics.Stats(i -> true);
192     int i = componentUuids.length;
193     for (String component : componentUuids) {
194       IntStream.range(0, i).mapToObj(j -> new DefaultIssue().setType(randomRuleType).setComponentUuid(component)).forEach(stats::add);
195       i--;
196     }
197     when(componentDao.selectByUuids(dbSession, Arrays.stream(componentUuids).limit(5).collect(Collectors.toSet())))
198       .thenReturn(
199         Arrays.stream(componentUuids).map(uuid -> new ComponentDto().setUuid(uuid).setName("name_" + uuid)).collect(MoreCollectors.toList()));
200
201     underTest.setStatistics(randomAlphanumeric(20), stats);
202
203     for (int j = 0; j < 5; j++) {
204       String fieldBase = COMPONENT + "." + (j + 1);
205       assertThat(underTest.getFieldValue(fieldBase + ".label")).as("label of %s", fieldBase).isEqualTo("name_" + componentUuids[j]);
206       assertThat(underTest.getFieldValue(fieldBase + ".count")).as("count of %s", fieldBase).isEqualTo(String.valueOf(componentUuids.length - j));
207     }
208     assertThat(underTest.getFieldValue(COMPONENT + ".6.label")).isNull();
209     assertThat(underTest.getFieldValue(COMPONENT + ".6.count")).isNull();
210   }
211
212   @Test
213   public void add_only_5_rules_with_biggest_issue_counts() {
214     String repository = randomAlphanumeric(4);
215     String[] ruleKeys = IntStream.range(0, 6 + random.nextInt(10)).mapToObj(s -> "rule_" + s).toArray(String[]::new);
216     NewIssuesStatistics.Stats stats = new NewIssuesStatistics.Stats(i -> true);
217     int i = ruleKeys.length;
218     for (String ruleKey : ruleKeys) {
219       IntStream.range(0, i).mapToObj(j -> new DefaultIssue().setType(randomRuleType).setRuleKey(RuleKey.of(repository, ruleKey))).forEach(stats::add);
220       i--;
221     }
222     when(ruleDao.selectDefinitionByKeys(dbSession, Arrays.stream(ruleKeys).limit(5).map(s -> RuleKey.of(repository, s)).collect(MoreCollectors.toSet(5))))
223       .thenReturn(
224         Arrays.stream(ruleKeys).limit(5).map(ruleKey -> new RuleDefinitionDto()
225           .setRuleKey(RuleKey.of(repository, ruleKey))
226           .setName("name_" + ruleKey)
227           .setLanguage("language_" + ruleKey))
228           .collect(MoreCollectors.toList(5)));
229
230     underTest.setStatistics(randomAlphanumeric(20), stats);
231
232     for (int j = 0; j < 5; j++) {
233       String fieldBase = RULE + "." + (j + 1);
234       assertThat(underTest.getFieldValue(fieldBase + ".label")).as("label of %s", fieldBase).isEqualTo("name_" + ruleKeys[j] + " (language_" + ruleKeys[j] + ")");
235       assertThat(underTest.getFieldValue(fieldBase + ".count")).as("count of %s", fieldBase).isEqualTo(String.valueOf(ruleKeys.length - j));
236     }
237     assertThat(underTest.getFieldValue(RULE + ".6.label")).isNull();
238     assertThat(underTest.getFieldValue(RULE + ".6.count")).isNull();
239   }
240
241   @Test
242   public void set_debt() {
243     when(durations.format(any(Duration.class))).thenReturn("55 min");
244
245     underTest.setDebt(Duration.create(55));
246
247     assertThat(underTest.getFieldValue(EFFORT + ".count")).isEqualTo("55 min");
248   }
249
250   private void addIssueNTimes(DefaultIssue issue, int times) {
251     for (int i = 0; i < times; i++) {
252       stats.add(issue);
253     }
254   }
255
256   private DefaultIssue newIssue1() {
257     return new DefaultIssue()
258       .setAssignee("maynard")
259       .setComponentUuid("file-uuid")
260       .setType(RuleType.BUG)
261       .setTags(Lists.newArrayList("bug", "owasp"))
262       .setRuleKey(RuleKey.of("SonarQube", "rule-the-world"))
263       .setEffort(Duration.create(5L));
264   }
265
266   private DefaultIssue newIssue2() {
267     return new DefaultIssue()
268       .setAssignee("keenan")
269       .setComponentUuid("directory-uuid")
270       .setType(RuleType.CODE_SMELL)
271       .setTags(Lists.newArrayList("owasp"))
272       .setRuleKey(RuleKey.of("SonarQube", "rule-the-universe"))
273       .setEffort(Duration.create(10L));
274   }
275
276   private RuleDefinitionDto newRule(RuleKey ruleKey, String name, String language) {
277     return new RuleDefinitionDto()
278       .setRuleKey(ruleKey)
279       .setName(name)
280       .setLanguage(language);
281   }
282 }