aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2013-10-31 17:07:50 +0100
committerJulien Lancelot <julien.lancelot@sonarsource.com>2013-10-31 17:07:50 +0100
commitf0f5058c481c3da9e63ff260963fb951182f5122 (patch)
tree3d9c0636f80d2f2f0669cf6ab56c527b4a6a79c5
parentf8b3f731d946a6ae06719cafd5d5ca4f0a471b0c (diff)
downloadsonarqube-f0f5058c481c3da9e63ff260963fb951182f5122.tar.gz
sonarqube-f0f5058c481c3da9e63ff260963fb951182f5122.zip
SONAR-4834 Create a changelog formatter on java side to manage display of changelog in order to integrate more easily technical debt in changelog
-rw-r--r--plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties20
-rw-r--r--sonar-core/src/main/java/org/sonar/core/issue/IssueUpdater.java2
-rw-r--r--sonar-core/src/main/java/org/sonar/core/technicaldebt/TechnicalDebtConverter.java7
-rw-r--r--sonar-core/src/test/java/org/sonar/core/issue/IssueUpdaterTest.java5
-rw-r--r--sonar-core/src/test/java/org/sonar/core/technicaldebt/TechnicalDebtConverterTest.java37
-rw-r--r--sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java9
-rw-r--r--sonar-server/src/main/java/org/sonar/server/issue/IssueChangelogFormatter.java61
-rw-r--r--sonar-server/src/main/java/org/sonar/server/platform/Platform.java61
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/issue/_changelog.html.erb13
-rw-r--r--sonar-server/src/test/java/org/sonar/server/issue/InternalRubyIssueServiceTest.java3
-rw-r--r--sonar-server/src/test/java/org/sonar/server/issue/IssueChangelogFormatterTest.java123
11 files changed, 255 insertions, 86 deletions
diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties b/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties
index 022d33b2eae..e8625f2c44c 100644
--- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties
+++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties
@@ -535,9 +535,6 @@ issue.manual.no_rules.non_admin=At least one manual rule must exist before manua
issue.reported_by=Reported by
issue.authorLogin=Author:
issue.component_deleted=Removed
-issue.changelog.changed_to={0} changed to {1}
-issue.changelog.was=was {0}
-issue.changelog.removed={0} removed
issue.technical_debt=Technical debt:
issue.technical_debt.x_days={0} days
issue.technical_debt.x_hours={0} hours
@@ -546,6 +543,23 @@ issue.technical_debt.x_minutes={0} minutes
#------------------------------------------------------------------------------
#
+# ISSUE CHANGELOG
+#
+#------------------------------------------------------------------------------
+issue.changelog.changed_to={0} changed to {1}
+issue.changelog.was=was {0}
+issue.changelog.removed={0} removed
+issue.changelog.field.severity=Severity
+issue.changelog.field.actionPlan=Action Plan
+issue.changelog.field.assignee=Assignee
+issue.changelog.field.author=Author
+issue.changelog.field.resolution=Resolution
+issue.changelog.field.technicalDebt=Technical Debt
+issue.changelog.field.status=Status
+
+
+#------------------------------------------------------------------------------
+#
# ISSUE FILTERS
#
#------------------------------------------------------------------------------
diff --git a/sonar-core/src/main/java/org/sonar/core/issue/IssueUpdater.java b/sonar-core/src/main/java/org/sonar/core/issue/IssueUpdater.java
index 6149cb65b6c..33ffb6a94d0 100644
--- a/sonar-core/src/main/java/org/sonar/core/issue/IssueUpdater.java
+++ b/sonar-core/src/main/java/org/sonar/core/issue/IssueUpdater.java
@@ -48,6 +48,7 @@ public class IssueUpdater implements BatchComponent, ServerComponent {
public static final String STATUS = "status";
public static final String AUTHOR = "author";
public static final String ACTION_PLAN = "actionPlan";
+ public static final String TECHNICAL_DEBT = "technicalDebt";
public boolean setSeverity(DefaultIssue issue, String severity, IssueChangeContext context) {
if (issue.manualSeverity()) {
@@ -203,6 +204,7 @@ public class IssueUpdater implements BatchComponent, ServerComponent {
TechnicalDebt oldValue = issue.technicalDebt();
if (!Objects.equal(value, oldValue)) {
issue.setTechnicalDebt(value);
+ issue.setFieldChange(context, TECHNICAL_DEBT, oldValue.toLong(), value.toLong());
issue.setUpdateDate(context.date());
issue.setChanged(true);
return true;
diff --git a/sonar-core/src/main/java/org/sonar/core/technicaldebt/TechnicalDebtConverter.java b/sonar-core/src/main/java/org/sonar/core/technicaldebt/TechnicalDebtConverter.java
index 0b0f977e084..4a9415cfebc 100644
--- a/sonar-core/src/main/java/org/sonar/core/technicaldebt/TechnicalDebtConverter.java
+++ b/sonar-core/src/main/java/org/sonar/core/technicaldebt/TechnicalDebtConverter.java
@@ -65,6 +65,13 @@ public class TechnicalDebtConverter implements BatchComponent, ServerComponent {
}
}
+ public double toDays(TechnicalDebt technicalDebt) {
+ double resultDays = technicalDebt.days();
+ resultDays += Double.valueOf(technicalDebt.hours()) / hoursInDay;
+ resultDays += Double.valueOf(technicalDebt.minutes()) / (hoursInDay * 60.0);
+ return resultDays;
+ }
+
public TechnicalDebt fromMinutes(Long inMinutes){
int oneHourInMinute = 60;
int days = 0;
diff --git a/sonar-core/src/test/java/org/sonar/core/issue/IssueUpdaterTest.java b/sonar-core/src/test/java/org/sonar/core/issue/IssueUpdaterTest.java
index 345b7a513ec..1a04d60d4dc 100644
--- a/sonar-core/src/test/java/org/sonar/core/issue/IssueUpdaterTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/issue/IssueUpdaterTest.java
@@ -371,8 +371,11 @@ public class IssueUpdaterTest {
boolean updated = updater.setPastTechnicalDebt(issue, previousDebt, context);
assertThat(updated).isTrue();
assertThat(issue.technicalDebt()).isEqualTo(TechnicalDebt.of(15, 0, 0));
-
assertThat(issue.mustSendNotifications()).isFalse();
+
+ FieldDiffs.Diff diff = issue.currentChange().get(TECHNICAL_DEBT);
+ assertThat(diff.oldValue()).isEqualTo(TechnicalDebt.of(10, 0, 0).toLong());
+ assertThat(diff.newValue()).isEqualTo(TechnicalDebt.of(15, 0, 0).toLong());
}
@Test
diff --git a/sonar-core/src/test/java/org/sonar/core/technicaldebt/TechnicalDebtConverterTest.java b/sonar-core/src/test/java/org/sonar/core/technicaldebt/TechnicalDebtConverterTest.java
index fe86eb80dbf..1c521975f32 100644
--- a/sonar-core/src/test/java/org/sonar/core/technicaldebt/TechnicalDebtConverterTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/technicaldebt/TechnicalDebtConverterTest.java
@@ -19,14 +19,13 @@
*/
package org.sonar.core.technicaldebt;
-import org.fest.assertions.Assertions;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.config.Settings;
import org.sonar.api.technicaldebt.TechnicalDebt;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
+import static org.fest.assertions.Assertions.assertThat;
+
public class TechnicalDebtConverterTest {
@@ -41,17 +40,17 @@ public class TechnicalDebtConverterTest {
}
@Test
- public void convert_to_days() {
- assertThat(converter.toDays(WorkUnit.create(6.0, WorkUnit.DAYS)), is(6.0));
- assertThat(converter.toDays(WorkUnit.create(6.0, WorkUnit.HOURS)), is(6.0 / 12.0));
- assertThat(converter.toDays(WorkUnit.create(60.0, WorkUnit.MINUTES)), is(1.0 / 12.0));
+ public void convert_work_unit_to_days() {
+ assertThat(converter.toDays(WorkUnit.create(6.0, WorkUnit.DAYS))).isEqualTo(6.0);
+ assertThat(converter.toDays(WorkUnit.create(6.0, WorkUnit.HOURS))).isEqualTo(6.0 / 12.0);
+ assertThat(converter.toDays(WorkUnit.create(60.0, WorkUnit.MINUTES))).isEqualTo(1.0 / 12.0);
}
@Test
- public void concert_to_minutes() {
- assertThat(converter.toMinutes(WorkUnit.create(2.0, WorkUnit.DAYS)), is(2 * 12 * 60L));
- assertThat(converter.toMinutes(WorkUnit.create(6.0, WorkUnit.HOURS)), is(6 * 60L));
- assertThat(converter.toMinutes(WorkUnit.create(60.0, WorkUnit.MINUTES)), is(60L));
+ public void concert_work_unit_to_minutes() {
+ assertThat(converter.toMinutes(WorkUnit.create(2.0, WorkUnit.DAYS))).isEqualTo(2 * 12 * 60L);
+ assertThat(converter.toMinutes(WorkUnit.create(6.0, WorkUnit.HOURS))).isEqualTo(6 * 60L);
+ assertThat(converter.toMinutes(WorkUnit.create(60.0, WorkUnit.MINUTES))).isEqualTo(60L);
}
@Test
@@ -68,10 +67,20 @@ public class TechnicalDebtConverterTest {
checkValues(converter.fromMinutes(790L), 10L, 1L, 1L);
}
+ @Test
+ public void convert_technical_debt_to_days() {
+ assertThat(converter.toDays(TechnicalDebt.of(0, 0, 6))).isEqualTo(6.0);
+ assertThat(converter.toDays(TechnicalDebt.of(0, 6, 0))).isEqualTo(0.5);
+ assertThat(converter.toDays(TechnicalDebt.of(360, 0, 0))).isEqualTo(0.5);
+ assertThat(converter.toDays(TechnicalDebt.of(45, 0, 0))).isEqualTo(0.0625);
+
+ assertThat(converter.toDays(TechnicalDebt.of(45, 6, 1))).isEqualTo(1.5625);
+ }
+
private void checkValues(TechnicalDebt technicalDebt, Long expectedMinutes, Long expectedHours, Long expectedDays) {
- Assertions.assertThat(technicalDebt.minutes()).isEqualTo(expectedMinutes);
- Assertions.assertThat(technicalDebt.hours()).isEqualTo(expectedHours);
- Assertions.assertThat(technicalDebt.days()).isEqualTo(expectedDays);
+ assertThat(technicalDebt.minutes()).isEqualTo(expectedMinutes);
+ assertThat(technicalDebt.hours()).isEqualTo(expectedHours);
+ assertThat(technicalDebt.days()).isEqualTo(expectedDays);
}
}
diff --git a/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java b/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java
index 4bfebcd2837..ac571ba5e7d 100644
--- a/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java
+++ b/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java
@@ -32,6 +32,7 @@ import org.sonar.api.issue.IssueComment;
import org.sonar.api.issue.IssueQuery;
import org.sonar.api.issue.action.Action;
import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.api.issue.internal.FieldDiffs;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.api.utils.SonarException;
@@ -81,12 +82,13 @@ public class InternalRubyIssueService implements ServerComponent {
private final ActionService actionService;
private final IssueFilterService issueFilterService;
private final IssueBulkChangeService issueBulkChangeService;
+ private final IssueChangelogFormatter issueChangelogFormatter;
public InternalRubyIssueService(IssueService issueService,
IssueCommentService commentService,
IssueChangelogService changelogService, ActionPlanService actionPlanService,
IssueStatsFinder issueStatsFinder, ResourceDao resourceDao, ActionService actionService,
- IssueFilterService issueFilterService, IssueBulkChangeService issueBulkChangeService) {
+ IssueFilterService issueFilterService, IssueBulkChangeService issueBulkChangeService, IssueChangelogFormatter issueChangelogFormatter) {
this.issueService = issueService;
this.commentService = commentService;
this.changelogService = changelogService;
@@ -96,6 +98,7 @@ public class InternalRubyIssueService implements ServerComponent {
this.actionService = actionService;
this.issueFilterService = issueFilterService;
this.issueBulkChangeService = issueBulkChangeService;
+ this.issueChangelogFormatter = issueChangelogFormatter;
}
public IssueStatsFinder.IssueStatsResult findIssueAssignees(Map<String, Object> params) {
@@ -126,6 +129,10 @@ public class InternalRubyIssueService implements ServerComponent {
return changelogService.changelog(issue);
}
+ public List<String> formatChangelog(FieldDiffs diffs){
+ return issueChangelogFormatter.format(UserSession.get().locale(), diffs);
+ }
+
public Result<Issue> doTransition(String issueKey, String transitionKey) {
Result<Issue> result = Result.of();
try {
diff --git a/sonar-server/src/main/java/org/sonar/server/issue/IssueChangelogFormatter.java b/sonar-server/src/main/java/org/sonar/server/issue/IssueChangelogFormatter.java
new file mode 100644
index 00000000000..1923c026ac4
--- /dev/null
+++ b/sonar-server/src/main/java/org/sonar/server/issue/IssueChangelogFormatter.java
@@ -0,0 +1,61 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.issue;
+
+import org.sonar.api.ServerComponent;
+import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.i18n.I18nManager;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import static com.google.common.collect.Lists.newArrayList;
+
+public class IssueChangelogFormatter implements ServerComponent {
+
+ private final I18nManager i18nManager;
+
+ public IssueChangelogFormatter(I18nManager i18nManager) {
+ this.i18nManager = i18nManager;
+ }
+
+ public List<String> format(Locale locale, FieldDiffs diffs) {
+ List<String> result = newArrayList();
+ for (Map.Entry<String, FieldDiffs.Diff> entry : diffs.diffs().entrySet()) {
+ StringBuilder message = new StringBuilder();
+ String key = entry.getKey();
+ FieldDiffs.Diff diff = entry.getValue();
+ if (diff.newValue() != null && !diff.newValue().equals("")) {
+ message.append(i18nManager.message(locale, "issue.changelog.changed_to", null, i18nManager.message(locale, "issue.changelog.field." + key, null), diff.newValue()));
+ } else {
+ message.append(i18nManager.message(locale, "issue.changelog.removed", null, i18nManager.message(locale, "issue.changelog.field." + key, null)));
+ }
+ if (diff.oldValue() != null && !diff.oldValue().equals("")) {
+ message.append(" (");
+ message.append(i18nManager.message(locale, "issue.changelog.was", null, diff.oldValue()));
+ message.append(")");
+ }
+ result.add(message.toString());
+ }
+ return result;
+ }
+
+}
diff --git a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
index 08809f8c276..9bd3b2071ad 100644
--- a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
+++ b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
@@ -52,13 +52,7 @@ import org.sonar.core.measure.MeasureFilterFactory;
import org.sonar.core.metric.DefaultMetricFinder;
import org.sonar.core.notification.DefaultNotificationManager;
import org.sonar.core.permission.PermissionFacade;
-import org.sonar.core.persistence.DaoUtils;
-import org.sonar.core.persistence.DatabaseVersion;
-import org.sonar.core.persistence.DefaultDatabase;
-import org.sonar.core.persistence.MyBatis;
-import org.sonar.core.persistence.PreviewDatabaseFactory;
-import org.sonar.core.persistence.SemaphoreUpdater;
-import org.sonar.core.persistence.SemaphoresImpl;
+import org.sonar.core.persistence.*;
import org.sonar.core.preview.PreviewCache;
import org.sonar.core.purge.PurgeProfiler;
import org.sonar.core.qualitymodel.DefaultModelFinder;
@@ -90,63 +84,19 @@ import org.sonar.server.db.EmbeddedDatabaseFactory;
import org.sonar.server.db.migrations.DatabaseMigration;
import org.sonar.server.db.migrations.DatabaseMigrations;
import org.sonar.server.db.migrations.DatabaseMigrator;
-import org.sonar.server.issue.ActionPlanService;
-import org.sonar.server.issue.ActionService;
-import org.sonar.server.issue.AssignAction;
-import org.sonar.server.issue.CommentAction;
-import org.sonar.server.issue.DefaultIssueFinder;
-import org.sonar.server.issue.InternalRubyIssueService;
-import org.sonar.server.issue.IssueBulkChangeService;
-import org.sonar.server.issue.IssueChangelogService;
-import org.sonar.server.issue.IssueCommentService;
-import org.sonar.server.issue.IssueFilterService;
-import org.sonar.server.issue.IssueService;
-import org.sonar.server.issue.IssueStatsFinder;
-import org.sonar.server.issue.PlanAction;
-import org.sonar.server.issue.PublicRubyIssueService;
-import org.sonar.server.issue.ServerIssueStorage;
-import org.sonar.server.issue.SetSeverityAction;
-import org.sonar.server.issue.TransitionAction;
+import org.sonar.server.issue.*;
import org.sonar.server.notifications.NotificationCenter;
import org.sonar.server.notifications.NotificationService;
import org.sonar.server.permission.InternalPermissionService;
import org.sonar.server.permission.InternalPermissionTemplateService;
-import org.sonar.server.plugins.ApplicationDeployer;
-import org.sonar.server.plugins.DefaultServerPluginRepository;
-import org.sonar.server.plugins.InstalledPluginReferentialFactory;
-import org.sonar.server.plugins.PluginDeployer;
-import org.sonar.server.plugins.PluginDownloader;
-import org.sonar.server.plugins.ServerExtensionInstaller;
-import org.sonar.server.plugins.UpdateCenterClient;
-import org.sonar.server.plugins.UpdateCenterMatrixFactory;
+import org.sonar.server.plugins.*;
import org.sonar.server.rule.RubyRuleService;
import org.sonar.server.rules.ProfilesConsole;
import org.sonar.server.rules.RulesConsole;
-import org.sonar.server.startup.CleanDryRunCache;
-import org.sonar.server.startup.DeleteDeprecatedMeasures;
-import org.sonar.server.startup.GenerateBootstrapIndex;
-import org.sonar.server.startup.GeneratePluginIndex;
-import org.sonar.server.startup.GwtPublisher;
-import org.sonar.server.startup.JdbcDriverDeployer;
-import org.sonar.server.startup.LogServerId;
-import org.sonar.server.startup.RegisterMetrics;
-import org.sonar.server.startup.RegisterNewDashboards;
-import org.sonar.server.startup.RegisterNewMeasureFilters;
-import org.sonar.server.startup.RegisterNewProfiles;
-import org.sonar.server.startup.RegisterPermissionTemplates;
-import org.sonar.server.startup.RegisterRules;
-import org.sonar.server.startup.RegisterServletFilters;
-import org.sonar.server.startup.RegisterTechnicalDebtModel;
-import org.sonar.server.startup.RenameDeprecatedPropertyKeys;
-import org.sonar.server.startup.ServerMetadataPersister;
-import org.sonar.server.startup.VerifyNoQualityModelsAreDefined;
+import org.sonar.server.startup.*;
import org.sonar.server.text.MacroInterpreter;
import org.sonar.server.text.RubyTextService;
-import org.sonar.server.ui.CodeColorizers;
-import org.sonar.server.ui.JRubyI18n;
-import org.sonar.server.ui.PageDecorations;
-import org.sonar.server.ui.SecurityRealmFactory;
-import org.sonar.server.ui.Views;
+import org.sonar.server.ui.*;
import org.sonar.server.user.DefaultUserService;
import org.sonar.server.user.NewUserNotifier;
@@ -338,6 +288,7 @@ public final class Platform {
servicesContainer.addSingleton(IssueFilterSerializer.class);
servicesContainer.addSingleton(IssueFilterService.class);
servicesContainer.addSingleton(IssueBulkChangeService.class);
+ servicesContainer.addSingleton(IssueChangelogFormatter.class);
// issues actions
servicesContainer.addSingleton(AssignAction.class);
servicesContainer.addSingleton(PlanAction.class);
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/issue/_changelog.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/issue/_changelog.html.erb
index 26c12118c09..4b95f4b330b 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/issue/_changelog.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/issue/_changelog.html.erb
@@ -13,19 +13,10 @@
<td class="thin left top" nowrap><%= h(user.name()) if user -%></td>
<td class="left top">
<%
- change.diffs.entrySet().each_with_index do |entry, index|
- key = entry.getKey()
- diff = entry.getValue()
+ Internal.issues.formatChangelog(change).each_with_index do |message, index|
%>
<% if index>0 %><br/><% end %>
- <% if diff.newValue.present? %>
- <%= message('issue.changelog.changed_to', :params => [message(key), diff.newValue()]) -%>
- <% else %>
- <%= message('issue.changelog.removed', :params => [message(key)]) -%>
- <% end %>
- <% if diff.oldValue.present? %>
- (<%= message('issue.changelog.was', :params => [diff.oldValue]) -%>)
- <% end %>
+ <%= message -%>
<% end %>
</td>
</tr>
diff --git a/sonar-server/src/test/java/org/sonar/server/issue/InternalRubyIssueServiceTest.java b/sonar-server/src/test/java/org/sonar/server/issue/InternalRubyIssueServiceTest.java
index 4c7d8a9a90b..9a8865a5dcc 100644
--- a/sonar-server/src/test/java/org/sonar/server/issue/InternalRubyIssueServiceTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/issue/InternalRubyIssueServiceTest.java
@@ -62,13 +62,14 @@ public class InternalRubyIssueServiceTest {
ActionService actionService = mock(ActionService.class);
IssueFilterService issueFilterService = mock(IssueFilterService.class);
IssueBulkChangeService issueBulkChangeService = mock(IssueBulkChangeService.class);
+ IssueChangelogFormatter issueChangelogFormatter = mock(IssueChangelogFormatter.class);
@Before
public void setUp() {
ResourceDto project = new ResourceDto().setKey("org.sonar.Sample");
when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(project);
service = new InternalRubyIssueService(issueService, commentService, changelogService, actionPlanService, issueStatsFinder, resourceDao, actionService,
- issueFilterService, issueBulkChangeService);
+ issueFilterService, issueBulkChangeService, issueChangelogFormatter);
}
@Test
diff --git a/sonar-server/src/test/java/org/sonar/server/issue/IssueChangelogFormatterTest.java b/sonar-server/src/test/java/org/sonar/server/issue/IssueChangelogFormatterTest.java
new file mode 100644
index 00000000000..6de106c78b8
--- /dev/null
+++ b/sonar-server/src/test/java/org/sonar/server/issue/IssueChangelogFormatterTest.java
@@ -0,0 +1,123 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.issue;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.i18n.I18nManager;
+
+import java.util.List;
+import java.util.Locale;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class IssueChangelogFormatterTest {
+
+ private static final Locale DEFAULT_LOCALE = Locale.getDefault();
+
+ @Mock
+ private I18nManager i18nManager;
+
+ private IssueChangelogFormatter formatter;
+
+ @Before
+ public void before(){
+ formatter = new IssueChangelogFormatter(i18nManager);
+ }
+
+ @Test
+ public void format_field_diffs_with_new_and_old_value(){
+ FieldDiffs diffs = new FieldDiffs();
+ diffs.setDiff("severity", "BLOCKER", "INFO");
+
+ when(i18nManager.message(DEFAULT_LOCALE, "issue.changelog.field.severity", null)).thenReturn("Severity");
+ when(i18nManager.message(DEFAULT_LOCALE, "issue.changelog.changed_to", null, "Severity", "INFO")).thenReturn("Severity changed to INFO");
+ when(i18nManager.message(DEFAULT_LOCALE, "issue.changelog.was", null, "BLOCKER")).thenReturn("was BLOCKER");
+
+ List<String> result = formatter.format(DEFAULT_LOCALE, diffs);
+ assertThat(result).hasSize(1);
+ String message = result.get(0);
+ assertThat(message).isEqualTo("Severity changed to INFO (was BLOCKER)");
+ }
+
+ @Test
+ public void format_field_diffs_with_only_new_value(){
+ FieldDiffs diffs = new FieldDiffs();
+ diffs.setDiff("severity", null, "INFO");
+
+ when(i18nManager.message(DEFAULT_LOCALE, "issue.changelog.field.severity", null)).thenReturn("Severity");
+ when(i18nManager.message(DEFAULT_LOCALE, "issue.changelog.changed_to", null, "Severity", "INFO")).thenReturn("Severity changed to INFO");
+
+ List<String> result = formatter.format(DEFAULT_LOCALE, diffs);
+ assertThat(result).hasSize(1);
+ String message = result.get(0);
+ assertThat(message).isEqualTo("Severity changed to INFO");
+ }
+
+ @Test
+ public void format_field_diffs_with_only_old_value(){
+ FieldDiffs diffs = new FieldDiffs();
+ diffs.setDiff("severity", "BLOCKER", null);
+
+ when(i18nManager.message(DEFAULT_LOCALE, "issue.changelog.field.severity", null)).thenReturn("Severity");
+ when(i18nManager.message(DEFAULT_LOCALE, "issue.changelog.removed", null, "Severity")).thenReturn("Severity removed");
+ when(i18nManager.message(DEFAULT_LOCALE, "issue.changelog.was", null, "BLOCKER")).thenReturn("was BLOCKER");
+
+ List<String> result = formatter.format(DEFAULT_LOCALE, diffs);
+ assertThat(result).hasSize(1);
+ String message = result.get(0);
+ assertThat(message).isEqualTo("Severity removed (was BLOCKER)");
+ }
+
+ @Test
+ public void format_field_diffs_without_value(){
+ FieldDiffs diffs = new FieldDiffs();
+ diffs.setDiff("severity", null, null);
+
+ when(i18nManager.message(DEFAULT_LOCALE, "issue.changelog.field.severity", null)).thenReturn("Severity");
+ when(i18nManager.message(DEFAULT_LOCALE, "issue.changelog.removed", null, "Severity")).thenReturn("Severity removed");
+
+ List<String> result = formatter.format(DEFAULT_LOCALE, diffs);
+ assertThat(result).hasSize(1);
+ String message = result.get(0);
+ assertThat(message).isEqualTo("Severity removed");
+ }
+
+ @Test
+ public void format_field_diffs_with_empty_old_value(){
+ FieldDiffs diffs = new FieldDiffs();
+ diffs.setDiff("severity", "", null);
+
+ when(i18nManager.message(DEFAULT_LOCALE, "issue.changelog.field.severity", null)).thenReturn("Severity");
+ when(i18nManager.message(DEFAULT_LOCALE, "issue.changelog.removed", null, "Severity")).thenReturn("Severity removed");
+
+ List<String> result = formatter.format(DEFAULT_LOCALE, diffs);
+ assertThat(result).hasSize(1);
+ String message = result.get(0);
+ assertThat(message).isEqualTo("Severity removed");
+ }
+
+}