diff options
9 files changed, 94 insertions, 92 deletions
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 8f991f7f24a..f4b3b280064 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 @@ -54,6 +54,7 @@ import org.sonar.server.util.Validation; import javax.annotation.CheckForNull; import javax.annotation.Nullable; + import java.util.Collection; import java.util.Date; import java.util.List; @@ -83,13 +84,12 @@ 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, IssueChangelogFormatter issueChangelogFormatter) { + IssueFilterService issueFilterService, IssueBulkChangeService issueBulkChangeService) { this.issueService = issueService; this.commentService = commentService; this.changelogService = changelogService; @@ -99,7 +99,6 @@ 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) { @@ -131,7 +130,7 @@ public class InternalRubyIssueService implements ServerComponent { } public List<String> formatChangelog(FieldDiffs diffs) { - return issueChangelogFormatter.format(UserSession.get().locale(), diffs); + return changelogService.formatDiffs(diffs); } public Result<Issue> doTransition(String issueKey, String transitionKey) { diff --git a/sonar-server/src/main/java/org/sonar/server/issue/IssueChangelogService.java b/sonar-server/src/main/java/org/sonar/server/issue/IssueChangelogService.java index 64911d65309..60d153626d8 100644 --- a/sonar-server/src/main/java/org/sonar/server/issue/IssueChangelogService.java +++ b/sonar-server/src/main/java/org/sonar/server/issue/IssueChangelogService.java @@ -29,6 +29,7 @@ import org.sonar.api.user.UserFinder; import org.sonar.api.web.UserRole; import org.sonar.core.issue.db.IssueChangeDao; import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.user.UserSession; import java.util.Collection; import java.util.List; @@ -43,11 +44,13 @@ public class IssueChangelogService implements ServerComponent { private final IssueChangeDao changeDao; private final UserFinder userFinder; private final DefaultIssueFinder finder; + private final IssueChangelogFormatter formatter; - public IssueChangelogService(IssueChangeDao changeDao, UserFinder userFinder, DefaultIssueFinder finder) { + public IssueChangelogService(IssueChangeDao changeDao, UserFinder userFinder, DefaultIssueFinder finder, IssueChangelogFormatter formatter) { this.changeDao = changeDao; this.userFinder = userFinder; this.finder = finder; + this.formatter = formatter; } public IssueChangelog changelog(String issueKey) { @@ -76,4 +79,8 @@ public class IssueChangelogService implements ServerComponent { } return result; } + + public List<String> formatDiffs(FieldDiffs diffs) { + return formatter.format(UserSession.get().locale(), diffs); + } } diff --git a/sonar-server/src/main/java/org/sonar/server/issue/ws/IssueShowWsHandler.java b/sonar-server/src/main/java/org/sonar/server/issue/ws/IssueShowWsHandler.java index c103731630b..02fb37c8ee6 100644 --- a/sonar-server/src/main/java/org/sonar/server/issue/ws/IssueShowWsHandler.java +++ b/sonar-server/src/main/java/org/sonar/server/issue/ws/IssueShowWsHandler.java @@ -30,19 +30,18 @@ import org.sonar.api.server.ws.Response; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.text.JsonWriter; import org.sonar.core.issue.workflow.Transition; +import org.sonar.markdown.Markdown; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.issue.ActionService; import org.sonar.server.issue.IssueChangelog; import org.sonar.server.issue.IssueChangelogService; import org.sonar.server.issue.IssueService; -import org.sonar.server.technicaldebt.InternalRubyTechnicalDebtService; -import org.sonar.server.text.RubyTextService; +import org.sonar.server.technicaldebt.TechnicalDebtFormatter; import org.sonar.server.user.UserSession; import java.util.Arrays; import java.util.Date; import java.util.List; -import java.util.Map; import static com.google.common.collect.Lists.newArrayList; @@ -52,17 +51,15 @@ public class IssueShowWsHandler implements RequestHandler { private final IssueService issueService; private final IssueChangelogService issueChangelogService; private final ActionService actionService; - private final InternalRubyTechnicalDebtService technicalDebtService; - private final RubyTextService textService; + private final TechnicalDebtFormatter technicalDebtFormatter; public IssueShowWsHandler(IssueFinder issueFinder, IssueService issueService, IssueChangelogService issueChangelogService, ActionService actionService, - InternalRubyTechnicalDebtService technicalDebtService, RubyTextService textService) { + TechnicalDebtFormatter technicalDebtFormatter) { this.issueFinder = issueFinder; this.issueService = issueService; this.issueChangelogService = issueChangelogService; this.actionService = actionService; - this.technicalDebtService = technicalDebtService; - this.textService = textService; + this.technicalDebtFormatter = technicalDebtFormatter; } @Override @@ -105,6 +102,7 @@ public class IssueShowWsHandler implements RequestHandler { .prop("severity", issue.severity()) .prop("author", issue.authorLogin()) .prop("actionPlan", actionPlanKey) + .prop("debt", technicalDebt != null ? technicalDebtFormatter.format(UserSession.get().locale(), technicalDebt) : null) .prop("actionPlanName", actionPlanKey != null ? result.actionPlan(issue).name() : null) .prop("creationDate", DateUtils.formatDateTime(issue.creationDate())) .prop("updateDate", updateDate != null ? DateUtils.formatDateTime(updateDate) : null) @@ -113,21 +111,6 @@ public class IssueShowWsHandler implements RequestHandler { addUserWithLabel(result, issue.assignee(), "assignee", json); addUserWithLabel(result, issue.reporter(), "reporter", json); - addTechnicalDebt(issue, json); - } - - private void addTechnicalDebt(DefaultIssue issue, JsonWriter json) { - WorkDayDuration technicalDebt = issue.technicalDebt(); - if (technicalDebt != null) { - json.prop("fTechnicalDebt", technicalDebtService.format(technicalDebt)); - json.name("technicalDebt") - .beginObject() - .prop("days", technicalDebt.days()) - .prop("hours", technicalDebt.hours()) - .prop("minutes", technicalDebt.minutes()) - .endObject(); - } - } private void writeTransitions(Issue issue, JsonWriter json) { @@ -172,11 +155,11 @@ public class IssueShowWsHandler implements RequestHandler { json .beginObject() .prop("key", comment.key()) - .prop("userLogin", userLogin) .prop("userName", userLogin != null ? queryResult.user(userLogin).name() : null) - .prop("html", textService.markdownToHtml(comment.markdownText())) - // add markdownText ? + .prop("raw", comment.markdownText()) + .prop("html", Markdown.convertToHtml(comment.markdownText())) .prop("creationDate", DateUtils.formatDateTime(comment.createdAt())) + .prop("updatable", UserSession.get().isLoggedIn() ? UserSession.get().login().equals(comment.userLogin()) : false) // TODO add formatted date .endObject(); } @@ -190,21 +173,14 @@ public class IssueShowWsHandler implements RequestHandler { String userLogin = diffs.userLogin(); json .beginObject() - .prop("userLogin", userLogin) .prop("userName", userLogin != null ? changelog.user(diffs).name() : null) .prop("creationDate", DateUtils.formatDateTime(diffs.creationDate())); // TODO add formatted date json.name("diffs").beginArray(); - for (Map.Entry<String, FieldDiffs.Diff> entry : diffs.diffs().entrySet()) { - FieldDiffs.Diff diff = entry.getValue(); - json - .beginObject() - .prop("key", entry.getKey()) - // TODO convert tech debt - .prop("newValue", (String) diff.newValue()) - .prop("oldValue", (String) diff.oldValue()) - .endObject(); + List<String> diffsFormatted = issueChangelogService.formatDiffs(diffs); + for (String diff : diffsFormatted) { + json.value(diff); } json.endArray(); json.endObject(); 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 534283db21a..08ef61282d0 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 @@ -40,7 +40,6 @@ import org.sonar.server.issue.filter.IssueFilterService; import org.sonar.server.user.UserSession; import java.util.Collections; -import java.util.Locale; import java.util.Map; import static com.google.common.collect.Lists.newArrayList; @@ -64,14 +63,13 @@ 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, issueChangelogFormatter); + issueFilterService, issueBulkChangeService); } @Test @@ -579,7 +577,7 @@ public class InternalRubyIssueServiceTest { public void format_changelog() { FieldDiffs fieldDiffs = new FieldDiffs(); service.formatChangelog(fieldDiffs); - verify(issueChangelogFormatter).format(any(Locale.class), eq(fieldDiffs)); + verify(changelogService).formatDiffs(eq(fieldDiffs)); } private void checkBadRequestException(Exception e, String key, Object... params) { diff --git a/sonar-server/src/test/java/org/sonar/server/issue/IssueChangelogServiceTest.java b/sonar-server/src/test/java/org/sonar/server/issue/IssueChangelogServiceTest.java index 18e20875ed8..d0de9ecbaab 100644 --- a/sonar-server/src/test/java/org/sonar/server/issue/IssueChangelogServiceTest.java +++ b/sonar-server/src/test/java/org/sonar/server/issue/IssueChangelogServiceTest.java @@ -19,8 +19,11 @@ */ package org.sonar.server.issue; -import java.util.Collections; +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.Issue; import org.sonar.api.issue.IssueQuery; import org.sonar.api.issue.IssueQueryResult; @@ -32,8 +35,11 @@ import org.sonar.core.issue.DefaultIssueQueryResult; import org.sonar.core.issue.db.IssueChangeDao; import org.sonar.core.user.DefaultUser; import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.user.MockUserSession; import java.util.Arrays; +import java.util.Collections; +import java.util.Locale; import static com.google.common.collect.Lists.newArrayList; import static org.fest.assertions.Assertions.assertThat; @@ -41,12 +47,27 @@ import static org.fest.assertions.Fail.fail; import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; +@RunWith(MockitoJUnitRunner.class) public class IssueChangelogServiceTest { - IssueChangeDao changeDao = mock(IssueChangeDao.class); - UserFinder userFinder = mock(UserFinder.class); - DefaultIssueFinder issueFinder = mock(DefaultIssueFinder.class); - IssueChangelogService service = new IssueChangelogService(changeDao, userFinder, issueFinder); + @Mock + IssueChangeDao changeDao; + + @Mock + UserFinder userFinder; + + @Mock + DefaultIssueFinder issueFinder; + + @Mock + IssueChangelogFormatter formatter; + + IssueChangelogService service; + + @Before + public void setUp() throws Exception { + service = new IssueChangelogService(changeDao, userFinder, issueFinder, formatter); + } @Test public void load_changelog_and_related_users() throws Exception { @@ -81,4 +102,12 @@ public class IssueChangelogServiceTest { verifyNoMoreInteractions(userFinder); } } + + @Test + public void format_diffs() throws Exception { + FieldDiffs diffs = new FieldDiffs().setUserLogin("arthur").setDiff("severity", "MAJOR", "BLOCKER"); + MockUserSession.set(); + service.formatDiffs(diffs); + verify(formatter).format(any(Locale.class), eq(diffs)); + } } diff --git a/sonar-server/src/test/java/org/sonar/server/issue/ws/IssueShowWsHandlerTest.java b/sonar-server/src/test/java/org/sonar/server/issue/ws/IssueShowWsHandlerTest.java index 98f4aae943b..5ff02ef0273 100644 --- a/sonar-server/src/test/java/org/sonar/server/issue/ws/IssueShowWsHandlerTest.java +++ b/sonar-server/src/test/java/org/sonar/server/issue/ws/IssueShowWsHandlerTest.java @@ -48,14 +48,14 @@ import org.sonar.server.issue.ActionService; import org.sonar.server.issue.IssueChangelog; import org.sonar.server.issue.IssueChangelogService; import org.sonar.server.issue.IssueService; -import org.sonar.server.technicaldebt.InternalRubyTechnicalDebtService; -import org.sonar.server.text.RubyTextService; +import org.sonar.server.technicaldebt.TechnicalDebtFormatter; import org.sonar.server.user.MockUserSession; import org.sonar.server.user.UserSession; import org.sonar.server.ws.WsTester; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import static com.google.common.collect.Lists.newArrayList; import static org.mockito.Matchers.any; @@ -79,10 +79,7 @@ public class IssueShowWsHandlerTest { ActionService actionService; @Mock - InternalRubyTechnicalDebtService technicalDebtService; - - @Mock - RubyTextService textService; + TechnicalDebtFormatter technicalDebtFormatter; List<Issue> issues; DefaultIssueQueryResult result; @@ -101,7 +98,7 @@ public class IssueShowWsHandlerTest { when(issueChangelogService.changelog(any(Issue.class))).thenReturn(mock(IssueChangelog.class)); - tester = new WsTester(new IssuesWs(new IssueShowWsHandler(issueFinder, issueService, issueChangelogService, actionService, technicalDebtService, textService))); + tester = new WsTester(new IssuesWs(new IssueShowWsHandler(issueFinder, issueService, issueChangelogService, actionService, technicalDebtFormatter))); } @Test @@ -164,7 +161,7 @@ public class IssueShowWsHandlerTest { .setTechnicalDebt(technicalDebt); issues.add(issue); - when(technicalDebtService.format(technicalDebt)).thenReturn("2 hours 1 minutes"); + when(technicalDebtFormatter.format(any(Locale.class), eq(technicalDebt))).thenReturn("2 hours 1 minutes"); MockUserSession.set(); SimpleRequest request = new SimpleRequest().setParam("key", issue.key()); @@ -192,14 +189,21 @@ public class IssueShowWsHandlerTest { .setKey("COMMENT-ABCD") .setMarkdownText("*My comment*") .setUserLogin("john") + .setCreatedAt(DateUtils.parseDateTime("2014-01-23T19:10:03+0100"))) + .addComment( + new DefaultIssueComment() + .setKey("COMMENT-ABCE") + .setMarkdownText("Another comment") + .setUserLogin("arthur") .setCreatedAt(DateUtils.parseDateTime("2014-01-23T19:10:03+0100")) ); issues.add(issue); - result.addUsers(newArrayList((User) new DefaultUser().setLogin("john").setName("John"))); - - when(textService.markdownToHtml("*My comment*")).thenReturn("<b>My comment</b>"); + result.addUsers(Lists.<User>newArrayList( + new DefaultUser().setLogin("john").setName("John"), + new DefaultUser().setLogin("arthur").setName("Arthur") + )); - MockUserSession.set(); + MockUserSession.set().setLogin("arthur"); SimpleRequest request = new SimpleRequest().setParam("key", issue.key()); tester.execute("show", request).assertJson(getClass(), "show_issue_with_comments.json"); } @@ -262,13 +266,15 @@ public class IssueShowWsHandlerTest { .setDiff("status", "REOPEN", "RESOLVED") .setCreationDate(DateUtils.parseDateTime("2014-01-23T19:10:03+0100")); when(issueChangelogService.changelog(issue)).thenReturn(new IssueChangelog(newArrayList(userChange, scanChange), users)); + when(issueChangelogService.formatDiffs(userChange)).thenReturn(newArrayList("Action plan updated to 1.0")); + when(issueChangelogService.formatDiffs(scanChange)).thenReturn(newArrayList("Severity updated from Info to Blocker", "Status updated from Reopen to Resolved")); MockUserSession.set(); SimpleRequest request = new SimpleRequest().setParam("key", issue.key()); tester.execute("show", request).assertJson(getClass(), "show_issue_with_changelog.json"); } - private DefaultIssue createStandardIssue(){ + private DefaultIssue createStandardIssue() { return new DefaultIssue() .setKey("ABCD") .setComponentKey("org.sonar.server.issue.IssueClient") diff --git a/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowWsHandlerTest/show_issue_with_changelog.json b/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowWsHandlerTest/show_issue_with_changelog.json index a493b6b9393..c17f85153f1 100644 --- a/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowWsHandlerTest/show_issue_with_changelog.json +++ b/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowWsHandlerTest/show_issue_with_changelog.json @@ -11,30 +11,13 @@ "comments": [], "changelog": [ { - "userLogin": "john", "userName": "John", "creationDate": "2014-01-22T19:10:03+0100", - "diffs": [ - { - "key": "actionPlan", - "newValue": "1.0" - } - ] + "diffs": ["Action plan updated to 1.0"] }, { "creationDate": "2014-01-23T19:10:03+0100", - "diffs": [ - { - "key": "severity", - "newValue": "BLOCKER", - "oldValue": "INFO" - }, - { - "key": "status", - "newValue": "RESOLVED", - "oldValue": "REOPEN" - } - ] + "diffs": ["Severity updated from Info to Blocker", "Status updated from Reopen to Resolved"] } ] } diff --git a/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowWsHandlerTest/show_issue_with_comments.json b/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowWsHandlerTest/show_issue_with_comments.json index a4a5389477e..813b671846d 100644 --- a/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowWsHandlerTest/show_issue_with_comments.json +++ b/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowWsHandlerTest/show_issue_with_comments.json @@ -7,14 +7,23 @@ "ruleName": "Avoid cycle", "creationDate": "2014-01-22T19:10:03+0100", "transitions": [], - "actions": [], + "actions": ["comment", "assign", "plan"], "comments": [ { "key": "COMMENT-ABCD", - "userLogin": "john", "userName": "John", - "html": "<b>My comment</b>", - "creationDate": "2014-01-23T19:10:03+0100" + "raw": "*My comment*", + "html": "<em>My comment</em>", + "creationDate": "2014-01-23T19:10:03+0100", + "updatable": false + }, + { + "key": "COMMENT-ABCE", + "userName": "Arthur", + "raw": "Another comment", + "html": "Another comment", + "creationDate": "2014-01-23T19:10:03+0100", + "updatable": true } ], "changelog": [] diff --git a/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowWsHandlerTest/show_issue_with_technical_debt.json b/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowWsHandlerTest/show_issue_with_technical_debt.json index 255a91d14e5..93d228b17fe 100644 --- a/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowWsHandlerTest/show_issue_with_technical_debt.json +++ b/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowWsHandlerTest/show_issue_with_technical_debt.json @@ -5,12 +5,7 @@ "project": "org.sonar.Sonar", "rule": "squid:AvoidCycle", "ruleName": "Avoid cycle", - "technicalDebt": { - "days": 0, - "hours": 2, - "minutes": 1 - }, - "fTechnicalDebt": "2 hours 1 minutes", + "debt": "2 hours 1 minutes", "creationDate": "2014-01-22T19:10:03+0100", "transitions": [], "actions": [], |