import org.sonar.api.utils.DateUtils;
import org.sonar.plugins.emailnotifications.api.EmailMessage;
import org.sonar.plugins.emailnotifications.api.EmailTemplate;
-import org.sonar.server.issue.notification.NewIssuesStatistics.METRIC;
+import org.sonar.server.issue.notification.NewIssuesStatistics.Metric;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
message.append("Project: ").append(projectName).append(NEW_LINE).append(NEW_LINE);
appendSeverity(message, notification);
appendAssignees(message, notification);
+ appendRules(message, notification);
appendTags(message, notification);
appendComponents(message, notification);
appendFooter(message, notification);
protected String subject(Notification notification, String projectName) {
return String.format("%s: %s new issues (new debt: %s)",
projectName,
- notification.getFieldValue(METRIC.SEVERITY + COUNT),
- notification.getFieldValue(METRIC.DEBT + COUNT));
+ notification.getFieldValue(Metric.SEVERITY + COUNT),
+ notification.getFieldValue(Metric.DEBT + COUNT));
}
- private boolean doNotHaveValue(Notification notification, METRIC metric) {
+ private boolean doNotHaveValue(Notification notification, Metric metric) {
return notification.getFieldValue(metric + DOT + "1" + LABEL) == null;
}
- private void genericAppendOfMetric(METRIC metric, String label, StringBuilder message, Notification notification) {
+ private void genericAppendOfMetric(Metric metric, String label, StringBuilder message, Notification notification) {
if (doNotHaveValue(notification, metric)) {
return;
}
}
protected void appendAssignees(StringBuilder message, Notification notification) {
- genericAppendOfMetric(METRIC.ASSIGNEE, "Assignees", message, notification);
+ genericAppendOfMetric(Metric.ASSIGNEE, "Assignees", message, notification);
}
protected void appendComponents(StringBuilder message, Notification notification) {
- genericAppendOfMetric(METRIC.COMPONENT, "Most impacted files", message, notification);
+ genericAppendOfMetric(Metric.COMPONENT, "Most impacted files", message, notification);
}
protected void appendTags(StringBuilder message, Notification notification) {
- genericAppendOfMetric(METRIC.TAGS, "Tags", message, notification);
+ genericAppendOfMetric(Metric.TAG, "Tags", message, notification);
+ }
+
+ protected void appendRules(StringBuilder message, Notification notification) {
+ genericAppendOfMetric(Metric.RULE, "Rules", message, notification);
}
protected void appendSeverity(StringBuilder message, Notification notification) {
message
.append(String.format("%s new issues (new debt: %s)",
- notification.getFieldValue(METRIC.SEVERITY + COUNT),
- notification.getFieldValue(METRIC.DEBT + COUNT)))
+ notification.getFieldValue(Metric.SEVERITY + COUNT),
+ notification.getFieldValue(Metric.DEBT + COUNT)))
.append(NEW_LINE).append(NEW_LINE)
.append(TAB)
.append("Severity")
.append(TAB)
.append(TAB);
- for (Iterator<String> severityIterator = Lists.reverse(Severity.ALL).iterator(); severityIterator.hasNext();) {
+ for (Iterator<String> severityIterator = Lists.reverse(Severity.ALL).iterator(); severityIterator.hasNext(); ) {
String severity = severityIterator.next();
String severityLabel = i18n.message(getLocale(), "severity." + severity, severity);
- message.append(severityLabel).append(": ").append(notification.getFieldValue(METRIC.SEVERITY + DOT + severity + COUNT));
+ message.append(severityLabel).append(": ").append(notification.getFieldValue(Metric.SEVERITY + DOT + severity + COUNT));
if (severityIterator.hasNext()) {
message.append(TAB);
}
import org.sonar.api.i18n.I18n;
import org.sonar.api.notifications.Notification;
import org.sonar.api.utils.DateUtils;
-import org.sonar.server.issue.notification.NewIssuesStatistics.METRIC;
+import org.sonar.server.issue.notification.NewIssuesStatistics.Metric;
import java.util.Date;
@Override
protected String subject(Notification notification, String projectName) {
return String.format("You have %s new issues on project %s",
- notification.getFieldValue(METRIC.SEVERITY + COUNT),
+ notification.getFieldValue(Metric.SEVERITY + COUNT),
projectName);
}
import org.sonar.api.utils.Durations;
import org.sonar.server.db.DbClient;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.user.index.UserIndex;
import static org.sonar.server.issue.notification.AbstractNewIssuesEmailTemplate.FIELD_ASSIGNEE;
public static final String TYPE = "my-new-issues";
- MyNewIssuesNotification(UserIndex userIndex, DbClient dbClient, Durations durations) {
- super(TYPE, userIndex, dbClient, durations);
+ MyNewIssuesNotification(UserIndex userIndex, RuleIndex ruleIndex, DbClient dbClient, Durations durations) {
+ super(TYPE, userIndex, ruleIndex, dbClient, durations);
}
public MyNewIssuesNotification setAssignee(String assignee) {
import com.google.common.collect.Multiset;
import org.sonar.api.component.Component;
import org.sonar.api.notifications.Notification;
+import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.Duration;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import org.sonar.server.db.DbClient;
-import org.sonar.server.issue.notification.NewIssuesStatistics.METRIC;
+import org.sonar.server.issue.notification.NewIssuesStatistics.Metric;
+import org.sonar.server.rule.Rule;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.user.index.UserDoc;
import org.sonar.server.user.index.UserIndex;
import java.util.List;
import java.util.Locale;
-import static org.sonar.server.issue.notification.NewIssuesEmailTemplate.*;
-import static org.sonar.server.issue.notification.NewIssuesStatistics.METRIC.SEVERITY;
+import static org.sonar.server.issue.notification.NewIssuesEmailTemplate.FIELD_PROJECT_DATE;
+import static org.sonar.server.issue.notification.NewIssuesEmailTemplate.FIELD_PROJECT_KEY;
+import static org.sonar.server.issue.notification.NewIssuesEmailTemplate.FIELD_PROJECT_NAME;
+import static org.sonar.server.issue.notification.NewIssuesEmailTemplate.FIELD_PROJECT_UUID;
+import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.SEVERITY;
public class NewIssuesNotification extends Notification {
private static final long serialVersionUID = -6305871981920103093L;
private static final String COUNT = ".count";
private static final String LABEL = ".label";
+ private static final String DOT = ".";
private final transient UserIndex userIndex;
+ private final transient RuleIndex ruleIndex;
private final transient DbClient dbClient;
private final transient Durations durations;
- NewIssuesNotification(UserIndex userIndex, DbClient dbClient, Durations durations) {
- this(TYPE, userIndex, dbClient, durations);
+ NewIssuesNotification(UserIndex userIndex, RuleIndex ruleIndex, DbClient dbClient, Durations durations) {
+ this(TYPE, userIndex, ruleIndex, dbClient, durations);
}
- protected NewIssuesNotification(String type, UserIndex userIndex, DbClient dbClient, Durations durations) {
+ protected NewIssuesNotification(String type, UserIndex userIndex, RuleIndex ruleIndex, DbClient dbClient, Durations durations) {
super(type);
this.userIndex = userIndex;
+ this.ruleIndex = ruleIndex;
this.dbClient = dbClient;
this.durations = durations;
}
setAssigneesStatistics(stats);
setTagsStatistics(stats);
setComponentsStatistics(stats);
+ setRuleStatistics(stats);
return this;
}
+ protected void setRuleStatistics(NewIssuesStatistics.Stats stats) {
+ Metric metric = Metric.RULE;
+ List<Multiset.Entry<String>> metricStats = stats.statsForMetric(metric);
+ for (int i = 0; i < 5 && i < metricStats.size(); i++) {
+ String ruleKey = metricStats.get(i).getElement();
+ Rule rule = ruleIndex.getByKey(RuleKey.parse(ruleKey));
+ String name = rule.name() + " (" + rule.language() + ")";
+ setFieldValue(metric + DOT + (i + 1) + LABEL, name);
+ setFieldValue(metric + DOT + (i + 1) + COUNT, String.valueOf(metricStats.get(i).getCount()));
+ }
+ }
+
protected void setComponentsStatistics(NewIssuesStatistics.Stats stats) {
- METRIC metric = METRIC.COMPONENT;
+ Metric metric = Metric.COMPONENT;
List<Multiset.Entry<String>> componentStats = stats.statsForMetric(metric);
DbSession dbSession = dbClient.openSession(false);
try {
for (int i = 0; i < 5 && i < componentStats.size(); i++) {
String uuid = componentStats.get(i).getElement();
String componentName = dbClient.componentDao().getByUuid(dbSession, uuid).name();
- setFieldValue(metric + "." + (i + 1) + LABEL, componentName);
- setFieldValue(metric + "." + (i + 1) + COUNT, String.valueOf(componentStats.get(i).getCount()));
+ setFieldValue(metric + DOT + (i + 1) + LABEL, componentName);
+ setFieldValue(metric + DOT + (i + 1) + COUNT, String.valueOf(componentStats.get(i).getCount()));
}
} finally {
MyBatis.closeQuietly(dbSession);
}
protected void setTagsStatistics(NewIssuesStatistics.Stats stats) {
- METRIC metric = METRIC.TAGS;
+ Metric metric = Metric.TAG;
List<Multiset.Entry<String>> metricStats = stats.statsForMetric(metric);
for (int i = 0; i < 5 && i < metricStats.size(); i++) {
- setFieldValue(metric + "." + (i + 1) + COUNT, String.valueOf(metricStats.get(i).getCount()));
- setFieldValue(metric + "." + (i + 1) + ".label", metricStats.get(i).getElement());
+ setFieldValue(metric + DOT + (i + 1) + COUNT, String.valueOf(metricStats.get(i).getCount()));
+ setFieldValue(metric + DOT + (i + 1) + ".label", metricStats.get(i).getElement());
}
}
protected void setAssigneesStatistics(NewIssuesStatistics.Stats stats) {
- METRIC metric = METRIC.ASSIGNEE;
+ Metric metric = Metric.ASSIGNEE;
List<Multiset.Entry<String>> metricStats = stats.statsForMetric(metric);
for (int i = 0; i < 5 && i < metricStats.size(); i++) {
String login = metricStats.get(i).getElement();
UserDoc user = userIndex.getNullableByLogin(login);
String name = user == null ? login : user.name();
- setFieldValue(metric + "." + (i + 1) + LABEL, name);
- setFieldValue(metric + "." + (i + 1) + COUNT, String.valueOf(metricStats.get(i).getCount()));
+ setFieldValue(metric + DOT + (i + 1) + LABEL, name);
+ setFieldValue(metric + DOT + (i + 1) + COUNT, String.valueOf(metricStats.get(i).getCount()));
}
}
public NewIssuesNotification setDebt(Duration debt) {
- setFieldValue(METRIC.DEBT + COUNT, durations.format(Locale.ENGLISH, debt));
+ setFieldValue(Metric.DEBT + COUNT, durations.format(Locale.ENGLISH, debt));
return this;
}
protected void setSeverityStatistics(NewIssuesStatistics.Stats stats) {
setFieldValue(SEVERITY + COUNT, String.valueOf(stats.countForMetric(SEVERITY)));
for (String severity : Severity.ALL) {
- setFieldValue(SEVERITY + "." + severity + COUNT, String.valueOf(stats.countForMetric(SEVERITY, severity)));
+ setFieldValue(SEVERITY + DOT + severity + COUNT, String.valueOf(stats.countForMetric(SEVERITY, severity)));
}
}
import org.sonar.api.ServerComponent;
import org.sonar.api.utils.Durations;
import org.sonar.server.db.DbClient;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.user.index.UserIndex;
public class NewIssuesNotificationFactory implements ServerComponent {
private final UserIndex userIndex;
+ private final RuleIndex ruleIndex;
private final DbClient dbClient;
private final Durations durations;
- public NewIssuesNotificationFactory(UserIndex userIndex, DbClient dbClient, Durations durations) {
+ public NewIssuesNotificationFactory(UserIndex userIndex, RuleIndex ruleIndex, DbClient dbClient, Durations durations) {
this.userIndex = userIndex;
+ this.ruleIndex = ruleIndex;
this.dbClient = dbClient;
this.durations = durations;
}
public MyNewIssuesNotification newMyNewIssuesNotification() {
- return new MyNewIssuesNotification(userIndex, dbClient, durations);
+ return new MyNewIssuesNotification(userIndex, ruleIndex, dbClient, durations);
}
public NewIssuesNotification newNewIssuesNotication() {
- return new NewIssuesNotification(userIndex, dbClient, durations);
+ return new NewIssuesNotification(userIndex, ruleIndex, dbClient, durations);
}
}
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;
import org.sonar.api.issue.Issue;
+import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.Duration;
import org.sonar.core.util.MultiSets;
import java.util.Map;
import static com.google.common.base.Preconditions.checkArgument;
-import static org.sonar.server.issue.notification.NewIssuesStatistics.METRIC.*;
+import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.ASSIGNEE;
+import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.COMPONENT;
+import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.RULE;
+import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.SEVERITY;
+import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.TAG;
public class NewIssuesStatistics {
private Map<String, Stats> assigneesStatistics = new LinkedHashMap<>();
return globalStatistics.hasIssues();
}
- enum METRIC {
- SEVERITY(true), TAGS(true), COMPONENT(true), ASSIGNEE(true), DEBT(false);
+ enum Metric {
+ SEVERITY(true), TAG(true), COMPONENT(true), ASSIGNEE(true), DEBT(false), RULE(true);
private final boolean isComputedByDistribution;
- METRIC(boolean isComputedByDistribution) {
+ Metric(boolean isComputedByDistribution) {
this.isComputedByDistribution = isComputedByDistribution;
}
}
public static class Stats {
- private final Map<METRIC, Multiset<String>> distributions = new EnumMap<>(METRIC.class);
+ private final Map<Metric, Multiset<String>> distributions = new EnumMap<>(Metric.class);
private long debtInMinutes = 0L;
public Stats() {
- for (METRIC metric : METRIC.values()) {
+ for (Metric metric : Metric.values()) {
if (metric.isComputedByDistribution()) {
distributions.put(metric, HashMultiset.<String>create());
}
public void add(Issue issue) {
distributions.get(SEVERITY).add(issue.severity());
distributions.get(COMPONENT).add(issue.componentUuid());
+ RuleKey ruleKey = issue.ruleKey();
+ if (ruleKey != null) {
+ distributions.get(RULE).add(ruleKey.toString());
+ }
if (issue.assignee() != null) {
distributions.get(ASSIGNEE).add(issue.assignee());
}
for (String tag : issue.tags()) {
- distributions.get(TAGS).add(tag);
+ distributions.get(TAG).add(tag);
}
Duration debt = issue.debt();
if (debt != null) {
}
}
- public int countForMetric(METRIC metric) {
+ public int countForMetric(Metric metric) {
return distributionFor(metric).size();
}
- public int countForMetric(METRIC metric, String label) {
+ public int countForMetric(Metric metric, String label) {
return distributionFor(metric).count(label);
}
return !distributionFor(SEVERITY).isEmpty();
}
- public List<Multiset.Entry<String>> statsForMetric(METRIC metric) {
+ public List<Multiset.Entry<String>> statsForMetric(Metric metric) {
return MultiSets.listOrderedByHighestCounts(distributionFor(metric));
}
- private Multiset<String> distributionFor(METRIC metric) {
+ private Multiset<String> distributionFor(Metric metric) {
checkArgument(metric.isComputedByDistribution());
return distributions.get(metric);
}
import java.util.Locale;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.*;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import static org.sonar.server.issue.notification.NewIssuesStatistics.METRIC.*;
+import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.COMPONENT;
+import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.DEBT;
+import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.RULE;
+import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.SEVERITY;
+import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.TAG;
public class MyNewIssuesEmailTemplateTest {
public void format_email_with_all_fields_filled() throws Exception {
Notification notification = newNotification();
addTags(notification);
+ addRules(notification);
addComponents(notification);
EmailMessage message = sut.format(notification);
private void addTags(Notification notification) {
notification
- .setFieldValue(TAGS + ".1.label", "oscar")
- .setFieldValue(TAGS + ".1.count", "3")
- .setFieldValue(TAGS + ".2.label", "cesar")
- .setFieldValue(TAGS + ".2.count", "10");
+ .setFieldValue(TAG + ".1.label", "oscar")
+ .setFieldValue(TAG + ".1.count", "3")
+ .setFieldValue(TAG + ".2.label", "cesar")
+ .setFieldValue(TAG + ".2.count", "10");
}
private void addComponents(Notification notification) {
.setFieldValue(COMPONENT + ".2.label", "/path/to/directory")
.setFieldValue(COMPONENT + ".2.count", "7");
}
+
+ private void addRules(Notification notification) {
+ notification
+ .setFieldValue(RULE + ".1.label", "Rule the Universe (Clojure)")
+ .setFieldValue(RULE + ".1.count", "42")
+ .setFieldValue(RULE + ".2.label", "Rule the World (Java)")
+ .setFieldValue(RULE + ".2.count", "5");
+ }
}
import org.junit.Test;
import org.sonar.api.utils.Durations;
import org.sonar.server.db.DbClient;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.user.index.UserIndex;
import static org.assertj.core.api.Assertions.assertThat;
public class MyNewIssuesNotificationTest {
- MyNewIssuesNotification sut = new MyNewIssuesNotification(mock(UserIndex.class), mock(DbClient.class), mock(Durations.class));
+ MyNewIssuesNotification sut = new MyNewIssuesNotification(mock(UserIndex.class), mock(RuleIndex.class), mock(DbClient.class), mock(Durations.class));
@Test
public void set_assignee() throws Exception {
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import static org.sonar.server.issue.notification.NewIssuesStatistics.METRIC.*;
+import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.*;
public class NewIssuesEmailTemplateTest {
public void format_email_with_all_fields_filled() throws Exception {
Notification notification = newNotification();
addAssignees(notification);
+ addRules(notification);
addTags(notification);
addComponents(notification);
private void addTags(Notification notification) {
notification
- .setFieldValue(TAGS + ".1.label", "oscar")
- .setFieldValue(TAGS + ".1.count", "3")
- .setFieldValue(TAGS + ".2.label", "cesar")
- .setFieldValue(TAGS + ".2.count", "10");
+ .setFieldValue(TAG + ".1.label", "oscar")
+ .setFieldValue(TAG + ".1.count", "3")
+ .setFieldValue(TAG + ".2.label", "cesar")
+ .setFieldValue(TAG + ".2.count", "10");
}
private void addComponents(Notification notification) {
.setFieldValue(COMPONENT + ".2.label", "/path/to/directory")
.setFieldValue(COMPONENT + ".2.count", "7");
}
+
+ private void addRules(Notification notification) {
+ notification
+ .setFieldValue(RULE + ".1.label", "Rule the Universe (Clojure)")
+ .setFieldValue(RULE + ".1.count", "42")
+ .setFieldValue(RULE + ".2.label", "Rule the World (Java)")
+ .setFieldValue(RULE + ".2.count", "5");
+ }
}
package org.sonar.server.issue.notification;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import org.junit.Test;
import org.mockito.Mockito;
import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.Duration;
import org.sonar.core.persistence.DbSession;
import org.sonar.server.component.ComponentTesting;
import org.sonar.server.db.DbClient;
+import org.sonar.server.rule.Rule;
+import org.sonar.server.rule.index.RuleDoc;
+import org.sonar.server.rule.index.RuleIndex;
+import org.sonar.server.rule.index.RuleNormalizer;
import org.sonar.server.user.index.UserIndex;
import java.util.Date;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import static org.sonar.server.issue.notification.NewIssuesStatistics.METRIC.*;
+import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.ASSIGNEE;
+import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.COMPONENT;
+import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.DEBT;
+import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.RULE;
+import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.SEVERITY;
+import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.TAG;
public class NewIssuesNotificationTest {
NewIssuesStatistics.Stats stats = new NewIssuesStatistics.Stats();
UserIndex userIndex = mock(UserIndex.class);
+ RuleIndex ruleIndex = mock(RuleIndex.class);
DbClient dbClient = mock(DbClient.class, Mockito.RETURNS_DEEP_STUBS);
Durations durations = mock(Durations.class);
- NewIssuesNotification sut = new NewIssuesNotification(userIndex, dbClient, durations);
+ NewIssuesNotification sut = new NewIssuesNotification(userIndex, ruleIndex, dbClient, durations);
@Test
public void set_project() throws Exception {
addIssueNTimes(newIssue2(), 3);
when(dbClient.componentDao().getByUuid(any(DbSession.class), eq("file-uuid")).name()).thenReturn("file-name");
when(dbClient.componentDao().getByUuid(any(DbSession.class), eq("directory-uuid")).name()).thenReturn("directory-name");
+ when(ruleIndex.getByKey(RuleKey.of("SonarQube", "rule-the-world"))).thenReturn(newRule("Rule the World", "Java"));
+ when(ruleIndex.getByKey(RuleKey.of("SonarQube", "rule-the-universe"))).thenReturn(newRule("Rule the Universe", "Clojure"));
sut.setStatistics(component, stats);
assertThat(sut.getFieldValue(ASSIGNEE + ".1.count")).isEqualTo("5");
assertThat(sut.getFieldValue(ASSIGNEE + ".2.label")).isEqualTo("keenan");
assertThat(sut.getFieldValue(ASSIGNEE + ".2.count")).isEqualTo("3");
- assertThat(sut.getFieldValue(TAGS + ".1.label")).isEqualTo("owasp");
- assertThat(sut.getFieldValue(TAGS + ".1.count")).isEqualTo("8");
- assertThat(sut.getFieldValue(TAGS + ".2.label")).isEqualTo("bug");
- assertThat(sut.getFieldValue(TAGS + ".2.count")).isEqualTo("5");
+ assertThat(sut.getFieldValue(TAG + ".1.label")).isEqualTo("owasp");
+ assertThat(sut.getFieldValue(TAG + ".1.count")).isEqualTo("8");
+ assertThat(sut.getFieldValue(TAG + ".2.label")).isEqualTo("bug");
+ assertThat(sut.getFieldValue(TAG + ".2.count")).isEqualTo("5");
assertThat(sut.getFieldValue(COMPONENT + ".1.label")).isEqualTo("file-name");
assertThat(sut.getFieldValue(COMPONENT + ".1.count")).isEqualTo("5");
assertThat(sut.getFieldValue(COMPONENT + ".2.label")).isEqualTo("directory-name");
assertThat(sut.getFieldValue(COMPONENT + ".2.count")).isEqualTo("3");
+ assertThat(sut.getFieldValue(RULE + ".1.label")).isEqualTo("Rule the World (Java)");
+ assertThat(sut.getFieldValue(RULE + ".1.count")).isEqualTo("5");
+ assertThat(sut.getFieldValue(RULE + ".2.label")).isEqualTo("Rule the Universe (Clojure)");
+ assertThat(sut.getFieldValue(RULE + ".2.count")).isEqualTo("3");
assertThat(sut.getDefaultMessage()).startsWith("8 new issues on project-long-name");
}
.setComponentUuid("file-uuid")
.setSeverity(Severity.INFO)
.setTags(Lists.newArrayList("bug", "owasp"))
+ .setRuleKey(RuleKey.of("SonarQube", "rule-the-world"))
.setDebt(Duration.create(5L));
}
.setComponentUuid("directory-uuid")
.setSeverity(Severity.BLOCKER)
.setTags(Lists.newArrayList("owasp"))
+ .setRuleKey(RuleKey.of("SonarQube", "rule-the-universe"))
.setDebt(Duration.create(10L));
}
+
+ private Rule newRule(String name, String language) {
+ return new RuleDoc(ImmutableMap.<String, Object>of(
+ RuleNormalizer.RuleField.NAME.field(), name,
+ RuleNormalizer.RuleField.LANGUAGE.field(), language
+ ));
+ }
}
import com.google.common.collect.Lists;
import org.junit.Test;
import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.api.utils.Duration;
-import org.sonar.server.issue.notification.NewIssuesStatistics.METRIC;
+import org.sonar.server.issue.notification.NewIssuesStatistics.Metric;
import static org.assertj.core.api.Assertions.assertThat;
sut.add(issue.setAssignee("james"));
sut.add(issue.setAssignee("keenan"));
- assertThat(countDistribution(METRIC.ASSIGNEE, "maynard")).isEqualTo(1);
- assertThat(countDistribution(METRIC.ASSIGNEE, "james")).isEqualTo(1);
- assertThat(countDistribution(METRIC.ASSIGNEE, "keenan")).isEqualTo(1);
- assertThat(countDistribution(METRIC.ASSIGNEE, "wrong.login")).isEqualTo(0);
- assertThat(countDistribution(METRIC.COMPONENT, "file-uuid")).isEqualTo(3);
- assertThat(countDistribution(METRIC.COMPONENT, "wrong-uuid")).isEqualTo(0);
- assertThat(countDistribution(METRIC.SEVERITY, Severity.INFO)).isEqualTo(3);
- assertThat(countDistribution(METRIC.SEVERITY, Severity.CRITICAL)).isEqualTo(0);
- assertThat(countDistribution(METRIC.TAGS, "owasp")).isEqualTo(3);
- assertThat(countDistribution(METRIC.TAGS, "wrong-tag")).isEqualTo(0);
+ assertThat(countDistribution(Metric.ASSIGNEE, "maynard")).isEqualTo(1);
+ assertThat(countDistribution(Metric.ASSIGNEE, "james")).isEqualTo(1);
+ assertThat(countDistribution(Metric.ASSIGNEE, "keenan")).isEqualTo(1);
+ assertThat(countDistribution(Metric.ASSIGNEE, "wrong.login")).isEqualTo(0);
+ assertThat(countDistribution(Metric.COMPONENT, "file-uuid")).isEqualTo(3);
+ assertThat(countDistribution(Metric.COMPONENT, "wrong-uuid")).isEqualTo(0);
+ assertThat(countDistribution(Metric.SEVERITY, Severity.INFO)).isEqualTo(3);
+ assertThat(countDistribution(Metric.SEVERITY, Severity.CRITICAL)).isEqualTo(0);
+ assertThat(countDistribution(Metric.TAG, "owasp")).isEqualTo(3);
+ assertThat(countDistribution(Metric.TAG, "wrong-tag")).isEqualTo(0);
+ assertThat(countDistribution(Metric.RULE, "SonarQube:rule-the-world")).isEqualTo(3);
+ assertThat(countDistribution(Metric.RULE, "SonarQube:has-a-fake-rule")).isEqualTo(0);
assertThat(sut.globalStatistics().debt().toMinutes()).isEqualTo(15L);
assertThat(sut.globalStatistics().hasIssues()).isTrue();
assertThat(sut.hasIssues()).isTrue();
assertThat(sut.globalStatistics().hasIssues()).isFalse();
}
- private int countDistribution(METRIC metric, String label) {
+ private int countDistribution(Metric metric, String label) {
return sut.globalStatistics().countForMetric(metric, label);
}
.setComponentUuid("file-uuid")
.setNew(true)
.setSeverity(Severity.INFO)
+ .setRuleKey(RuleKey.of("SonarQube", "rule-the-world"))
.setTags(Lists.newArrayList("bug", "owasp"))
.setDebt(Duration.create(5L));
}
Severity
Blocker: 0 Critical: 5 Major: 10 Minor: 3 Info: 1
+ Rules
+ Rule the Universe (Clojure): 42
+ Rule the World (Java): 5
+
Tags
oscar: 3
cesar: 10
robin.williams: 5
al.pacino: 7
+ Rules
+ Rule the Universe (Clojure): 42
+ Rule the World (Java): 5
+
Tags
oscar: 3
cesar: 10