aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-server
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2016-12-14 11:27:15 +0100
committerJulien Lancelot <julien.lancelot@sonarsource.com>2016-12-15 14:44:17 +0100
commit154e542a066ba371691c569a9921a5a6d9e5fa58 (patch)
tree8eb6d516a8d3e48b70763616dc3f7ff38316498a /server/sonar-server
parent4377c049eab9efbf8ecb56caf1fd3c0c779a0731 (diff)
downloadsonarqube-154e542a066ba371691c569a9921a5a6d9e5fa58.tar.gz
sonarqube-154e542a066ba371691c569a9921a5a6d9e5fa58.zip
SONAR-7292 Replace Ruby WS api/issues/add_comment
Diffstat (limited to 'server/sonar-server')
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java10
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/IssueCommentService.java69
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/ws/AddCommentAction.java101
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/ws/DoTransitionAction.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/ws/IssueWsModule.java1
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/ws/IssuesWs.java19
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/IssueCommentServiceMediumTest.java142
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/IssueCommentServiceTest.java87
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/ws/AddCommentActionTest.java204
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/ws/IssueWsModuleTest.java2
10 files changed, 310 insertions, 327 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java b/server/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java
index 3473dd669cf..34c516b4f69 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java
@@ -51,16 +51,6 @@ public class InternalRubyIssueService {
this.userSession = userSession;
}
- public Result<IssueComment> addComment(String issueKey, String text) {
- Result<IssueComment> result = Result.of();
- try {
- result.set(commentService.addComment(issueKey, text));
- } catch (Exception e) {
- result.addError(e.getMessage());
- }
- return result;
- }
-
public IssueComment deleteComment(String commentKey) {
return commentService.deleteComment(commentKey);
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueCommentService.java b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueCommentService.java
index ddb97357d3f..1cb5dbefd60 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueCommentService.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueCommentService.java
@@ -20,91 +20,30 @@
package org.sonar.server.issue;
import com.google.common.base.Strings;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
import java.util.Objects;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.issue.IssueComment;
import org.sonar.api.utils.System2;
-import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.issue.DefaultIssueComment;
-import org.sonar.core.issue.IssueChangeContext;
import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
import org.sonar.db.issue.IssueChangeDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
-import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.user.UserSession;
-import static com.google.common.collect.Lists.newArrayList;
-
public class IssueCommentService {
private final DbClient dbClient;
private final IssueService issueService;
- private final IssueFieldsSetter updater;
private final UserSession userSession;
- public IssueCommentService(DbClient dbClient, IssueService issueService, IssueFieldsSetter updater, UserSession userSession) {
+ public IssueCommentService(DbClient dbClient, IssueService issueService, UserSession userSession) {
this.dbClient = dbClient;
this.issueService = issueService;
- this.updater = updater;
this.userSession = userSession;
}
- public List<DefaultIssueComment> findComments(String issueKey) {
- return findComments(newArrayList(issueKey));
- }
-
- public List<DefaultIssueComment> findComments(DbSession dbSession, String issueKey) {
- return findComments(dbSession, newArrayList(issueKey));
- }
-
- public List<DefaultIssueComment> findComments(Collection<String> issueKeys) {
- DbSession session = dbClient.openSession(false);
- try {
- return findComments(session, issueKeys);
- } finally {
- session.close();
- }
- }
-
- public List<DefaultIssueComment> findComments(DbSession session, Collection<String> issueKeys) {
- return dbClient.issueChangeDao().selectCommentsByIssues(session, issueKeys);
- }
-
- public IssueComment findComment(String commentKey) {
- return dbClient.issueChangeDao().selectCommentByKey(commentKey);
- }
-
- public IssueComment addComment(String issueKey, String text) {
- verifyLoggedIn(userSession);
- if (StringUtils.isBlank(text)) {
- throw new BadRequestException("Cannot add empty comments to an issue");
- }
-
- DbSession session = dbClient.openSession(false);
- try {
- DefaultIssue issue = issueService.getByKeyForUpdate(session, issueKey).toDefaultIssue();
- IssueChangeContext context = IssueChangeContext.createUser(new Date(), userSession.getLogin());
- updater.addComment(issue, text, context);
-
- issueService.saveIssue(session, issue, context, text);
- session.commit();
-
- List<DefaultIssueComment> comments = findComments(issueKey);
- if (comments.isEmpty()) {
- throw new BadRequestException(String.format("Fail to add a comment on issue %s", issueKey));
- }
- return comments.get(comments.size() - 1);
- } finally {
- session.close();
- }
- }
-
public IssueComment deleteComment(String commentKey) {
DefaultIssueComment comment = dbClient.issueChangeDao().selectCommentByKey(commentKey);
if (comment == null) {
@@ -143,10 +82,4 @@ public class IssueCommentService {
return comment;
}
-
- private void verifyLoggedIn(UserSession userSession) {
- if (!userSession.isLoggedIn()) {
- throw new UnauthorizedException("User is not logged in");
- }
- }
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/AddCommentAction.java b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/AddCommentAction.java
new file mode 100644
index 00000000000..be614172d06
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/AddCommentAction.java
@@ -0,0 +1,101 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.ws;
+
+import java.util.Date;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.utils.System2;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueChangeContext;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.issue.IssueDto;
+import org.sonar.server.issue.IssueFieldsSetter;
+import org.sonar.server.issue.IssueFinder;
+import org.sonar.server.issue.IssueUpdater;
+import org.sonar.server.user.UserSession;
+import org.sonarqube.ws.client.issue.IssuesWsParameters;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Strings.isNullOrEmpty;
+import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
+import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ISSUE;
+import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_TEXT;
+
+public class AddCommentAction implements IssuesWsAction {
+
+ private final System2 system2;
+ private final UserSession userSession;
+ private final DbClient dbClient;
+ private final IssueFinder issueFinder;
+ private final IssueUpdater issueUpdater;
+ private final IssueFieldsSetter issueFieldsSetter;
+ private final OperationResponseWriter responseWriter;
+
+ public AddCommentAction(System2 system2, UserSession userSession, DbClient dbClient, IssueFinder issueFinder, IssueUpdater issueUpdater, IssueFieldsSetter issueFieldsSetter,
+ OperationResponseWriter responseWriter) {
+ this.system2 = system2;
+ this.userSession = userSession;
+ this.dbClient = dbClient;
+ this.issueFinder = issueFinder;
+ this.issueUpdater = issueUpdater;
+ this.issueFieldsSetter = issueFieldsSetter;
+ this.responseWriter = responseWriter;
+ }
+
+ @Override
+ public void define(WebService.NewController context) {
+ WebService.NewAction action = context.createAction(IssuesWsParameters.ACTION_ADD_COMMENT)
+ .setDescription("Add a comment.<br/>" +
+ "Requires authentication and the following permission: 'Browse' on the project of the specified issue.<br/>" +
+ "Since 6.3, the response contains the issue with all details, not only the added comment")
+ .setSince("3.6")
+ .setHandler(this)
+ .setPost(true);
+
+ action.createParam(PARAM_ISSUE)
+ .setDescription("Issue key")
+ .setRequired(true)
+ .setExampleValue(UUID_EXAMPLE_01);
+ action.createParam(PARAM_TEXT)
+ .setDescription("Comment text")
+ .setRequired(true)
+ .setExampleValue("Won't fix because it doesn't apply to the context");
+ }
+
+ @Override
+ public void handle(Request request, Response response) {
+ userSession.checkLoggedIn();
+ String issueKey = request.mandatoryParam(PARAM_ISSUE);
+ String commentText = request.mandatoryParam(PARAM_TEXT);
+ checkArgument(!isNullOrEmpty(commentText), "Cannot add empty comment to an issue");
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ IssueDto issueDto = issueFinder.getByKey(dbSession, issueKey);
+ IssueChangeContext context = IssueChangeContext.createUser(new Date(system2.now()), userSession.getLogin());
+ DefaultIssue defaultIssue = issueDto.toDefaultIssue();
+ issueFieldsSetter.addComment(defaultIssue, commentText, context);
+ issueUpdater.saveIssue(dbSession, defaultIssue, context, commentText);
+ responseWriter.write(issueKey, request, response);
+ }
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/DoTransitionAction.java b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/DoTransitionAction.java
index 0fe6a4bf934..da32cb2a920 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/DoTransitionAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/DoTransitionAction.java
@@ -75,7 +75,7 @@ public class DoTransitionAction implements IssuesWsAction {
}
@Override
- public void handle(Request request, Response response) throws Exception {
+ public void handle(Request request, Response response) {
userSession.checkLoggedIn();
String issue = request.mandatoryParam("issue");
try (DbSession dbSession = dbClient.openSession(false)) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/IssueWsModule.java b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/IssueWsModule.java
index 5e4050afc5c..981c162e3ff 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/IssueWsModule.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/IssueWsModule.java
@@ -57,6 +57,7 @@ public class IssueWsModule extends Module {
SearchResponseFormat.class,
OperationResponseWriter.class,
WsResponseCommonFormat.class,
+ AddCommentAction.class,
AssignAction.class,
DoTransitionAction.class,
SearchAction.class,
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/IssuesWs.java b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/IssuesWs.java
index 2df191f77eb..6a79ea19c69 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/IssuesWs.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/IssuesWs.java
@@ -29,7 +29,6 @@ import static org.sonarqube.ws.client.issue.IssuesWsParameters.CONTROLLER_ISSUES
public class IssuesWs implements WebService {
- public static final String ADD_COMMENT_ACTION = "add_comment";
public static final String DELETE_COMMENT_ACTION = "delete_comment";
public static final String EDIT_COMMENT_ACTION = "edit_comment";
public static final String BULK_CHANGE_ACTION = "bulk_change";
@@ -53,29 +52,11 @@ public class IssuesWs implements WebService {
}
private static void defineRailsActions(NewController controller) {
- defineAddCommentAction(controller);
defineDeleteCommentAction(controller);
defineEditCommentAction(controller);
defineBulkChangeAction(controller);
}
- private static void defineAddCommentAction(NewController controller) {
- WebService.NewAction action = controller.createAction(ADD_COMMENT_ACTION)
- .setDescription("Add a comment. Requires authentication and Browse permission on project")
- .setSince("3.6")
- .setHandler(RailsHandler.INSTANCE)
- .setPost(true);
-
- action.createParam("issue")
- .setDescription("Key of the issue")
- .setRequired(true)
- .setExampleValue("5bccd6e8-f525-43a2-8d76-fcb13dde79ef");
- action.createParam("text")
- .setDescription("Comment")
- .setExampleValue("blabla...");
- RailsHandler.addFormatParam(action);
- }
-
private static void defineDeleteCommentAction(NewController controller) {
WebService.NewAction action = controller.createAction(DELETE_COMMENT_ACTION)
.setDescription("Delete a comment. Requires authentication and Browse permission on project")
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueCommentServiceMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueCommentServiceMediumTest.java
deleted file mode 100644
index 40272299207..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueCommentServiceMediumTest.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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 java.util.List;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rule.RuleStatus;
-import org.sonar.api.web.UserRole;
-import org.sonar.core.issue.DefaultIssueComment;
-import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.component.ComponentDao;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.ComponentTesting;
-import org.sonar.db.component.SnapshotDao;
-import org.sonar.db.component.SnapshotDto;
-import org.sonar.db.component.SnapshotTesting;
-import org.sonar.db.issue.IssueDao;
-import org.sonar.db.issue.IssueDto;
-import org.sonar.db.rule.RuleDao;
-import org.sonar.db.rule.RuleDto;
-import org.sonar.db.rule.RuleTesting;
-import org.sonar.server.issue.index.IssueIndexer;
-import org.sonar.server.permission.GroupPermissionChange;
-import org.sonar.server.permission.PermissionChange;
-import org.sonar.server.permission.PermissionUpdater;
-import org.sonar.server.permission.ProjectId;
-import org.sonar.server.tester.ServerTester;
-import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.usergroups.ws.GroupIdOrAnyone;
-
-import static java.util.Arrays.asList;
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class IssueCommentServiceMediumTest {
-
- @ClassRule
- public static ServerTester tester = new ServerTester().withStartupTasks().withEsIndexes();
-
- @Rule
- public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester);
-
- DbClient db;
- DbSession session;
- IssueCommentService service;
-
- RuleDto rule;
- ComponentDto project;
- ComponentDto file;
-
- @Before
- public void setUp() {
- tester.clearDbAndIndexes();
- db = tester.get(DbClient.class);
- session = db.openSession(false);
- service = tester.get(IssueCommentService.class);
-
- rule = RuleTesting.newXooX1();
- tester.get(RuleDao.class).insert(session, rule);
-
- project = ComponentTesting.newProjectDto();
- tester.get(ComponentDao.class).insert(session, project);
- SnapshotDto projectSnapshot = SnapshotTesting.newAnalysis(project);
- tester.get(SnapshotDao.class).insert(session, projectSnapshot);
-
- file = ComponentTesting.newFileDto(project, null);
- tester.get(ComponentDao.class).insert(session, file);
-
- // project can be seen by anyone
- session.commit();
- userSessionRule.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
- // TODO correctly feed default organization. Not a problem as long as issues search does not support "anyone"
- // for each organization
- GroupPermissionChange permissionChange = new GroupPermissionChange(PermissionChange.Operation.ADD, UserRole.USER, new ProjectId(project), GroupIdOrAnyone.forAnyone("TODO"));
- tester.get(PermissionUpdater.class).apply(session, asList(permissionChange));
-
- userSessionRule.login("gandalf");
-
- session.commit();
- }
-
- @After
- public void after() {
- session.close();
- }
-
- @Test
- public void add_comment() {
- IssueDto issue = IssueTesting.newDto(rule, file, project);
- tester.get(IssueDao.class).insert(session, issue);
- session.commit();
- tester.get(IssueIndexer.class).indexAll();
-
- service.addComment(issue.getKey(), "my comment");
-
- List<DefaultIssueComment> comments = service.findComments(issue.getKey());
- assertThat(comments).hasSize(1);
- assertThat(comments.get(0).markdownText()).isEqualTo("my comment");
- }
-
- @Test
- public void add_comment_on_removed_issue() {
- RuleDto removedRule = RuleTesting.newDto(RuleKey.of("removed", "rule")).setStatus(RuleStatus.REMOVED);
- tester.get(RuleDao.class).insert(session, removedRule);
-
- IssueDto issue = IssueTesting.newDto(removedRule, file, project).setStatus(Issue.STATUS_CLOSED).setResolution(Issue.RESOLUTION_REMOVED);
- tester.get(IssueDao.class).insert(session, issue);
- session.commit();
- tester.get(IssueIndexer.class).indexAll();
-
- service.addComment(issue.getKey(), "my comment");
-
- List<DefaultIssueComment> comments = service.findComments(issue.getKey());
- assertThat(comments).hasSize(1);
- assertThat(comments.get(0).markdownText()).isEqualTo("my comment");
- }
-
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueCommentServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueCommentServiceTest.java
index cc84fb71ed1..fd6ccb153af 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueCommentServiceTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueCommentServiceTest.java
@@ -19,7 +19,6 @@
*/
package org.sonar.server.issue;
-import java.util.Collections;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -27,32 +26,21 @@ import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
-import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.issue.DefaultIssueComment;
-import org.sonar.core.issue.IssueChangeContext;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
-import org.sonar.db.component.ComponentTesting;
import org.sonar.db.issue.IssueChangeDao;
import org.sonar.db.issue.IssueChangeDto;
-import org.sonar.db.issue.IssueDto;
-import org.sonar.db.rule.RuleTesting;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
-import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.tester.UserSessionRule;
-import static com.google.common.collect.Lists.newArrayList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
@@ -68,9 +56,6 @@ public class IssueCommentServiceTest {
private IssueService issueService;
@Mock
- private IssueFieldsSetter updater;
-
- @Mock
private IssueChangeDao changeDao;
@Mock
@@ -86,77 +71,7 @@ public class IssueCommentServiceTest {
when(dbClient.openSession(false)).thenReturn(session);
when(dbClient.issueChangeDao()).thenReturn(changeDao);
- issueCommentService = new IssueCommentService(dbClient, issueService, updater, userSessionRule);
- }
-
- @Test
- public void find_comments() {
- issueCommentService.findComments("ABCD");
- verify(changeDao).selectCommentsByIssues(session, newArrayList("ABCD"));
- }
-
- @Test
- public void should_find_comment() {
- issueCommentService.findComment("ABCD");
- verify(changeDao).selectCommentByKey("ABCD");
- }
-
- @Test
- public void should_add_comment() {
- IssueDto issueDto = IssueTesting.newDto(RuleTesting.newXooX1().setId(500), ComponentTesting.newFileDto(ComponentTesting.newProjectDto(), null), ComponentTesting.newProjectDto());
- when(issueService.getByKeyForUpdate(session, "ABCD")).thenReturn(issueDto);
- when(issueCommentService.findComments(session, "ABCD")).thenReturn(newArrayList(new DefaultIssueComment()));
-
- issueCommentService.addComment("ABCD", "my comment");
-
- verify(updater).addComment(eq(issueDto.toDefaultIssue()), eq("my comment"), any(IssueChangeContext.class));
- verify(issueService).saveIssue(eq(session), eq(issueDto.toDefaultIssue()), any(IssueChangeContext.class), eq("my comment"));
- }
-
- @Test
- public void should_be_logged_when_adding_comment() {
- throwable.expect(UnauthorizedException.class);
- userSessionRule.anonymous();
-
- issueCommentService.addComment("myIssue", "my comment");
-
- verify(updater, never()).addComment(any(DefaultIssue.class), anyString(), any(IssueChangeContext.class));
- verifyZeroInteractions(issueService);
- }
-
- @Test
- public void should_prevent_adding_empty_comment() {
- throwable.expect(BadRequestException.class);
-
- issueCommentService.addComment("myIssue", " ");
-
- verify(updater, never()).addComment(any(DefaultIssue.class), anyString(), any(IssueChangeContext.class));
- verifyZeroInteractions(issueService);
- }
-
- @Test
- public void should_prevent_adding_null_comment() {
- throwable.expect(BadRequestException.class);
-
- issueCommentService.addComment("myIssue", null);
-
- verify(updater, never()).addComment(any(DefaultIssue.class), anyString(), any(IssueChangeContext.class));
- verifyZeroInteractions(issueService);
- }
-
- @Test
- public void fail_if_comment_not_inserted_in_db() {
- IssueDto issueDto = IssueTesting.newDto(RuleTesting.newXooX1().setId(500), ComponentTesting.newFileDto(ComponentTesting.newProjectDto(), null), ComponentTesting.newProjectDto());
- when(issueService.getByKeyForUpdate(session, "ABCD")).thenReturn(issueDto);
- // Comment has not be inserted in db
- when(issueCommentService.findComments(session, "ABCD")).thenReturn(Collections.<DefaultIssueComment>emptyList());
-
- try {
- issueCommentService.addComment("ABCD", "my comment");
- fail();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(BadRequestException.class).hasMessage("Fail to add a comment on issue ABCD");
- }
+ issueCommentService = new IssueCommentService(dbClient, issueService, userSessionRule);
}
@Test
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/AddCommentActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/AddCommentActionTest.java
new file mode 100644
index 00000000000..ab6198e3452
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/AddCommentActionTest.java
@@ -0,0 +1,204 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.ws;
+
+import javax.annotation.Nullable;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.config.MapSettings;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbTester;
+import org.sonar.db.component.ComponentDbTester;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.issue.IssueChangeDto;
+import org.sonar.db.issue.IssueDbTester;
+import org.sonar.db.issue.IssueDto;
+import org.sonar.db.rule.RuleDbTester;
+import org.sonar.db.rule.RuleDto;
+import org.sonar.server.es.EsTester;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.exceptions.UnauthorizedException;
+import org.sonar.server.issue.IssueFieldsSetter;
+import org.sonar.server.issue.IssueFinder;
+import org.sonar.server.issue.IssueUpdater;
+import org.sonar.server.issue.ServerIssueStorage;
+import org.sonar.server.issue.index.IssueIndexDefinition;
+import org.sonar.server.issue.index.IssueIndexer;
+import org.sonar.server.notification.NotificationManager;
+import org.sonar.server.rule.DefaultRuleFinder;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.TestRequest;
+import org.sonar.server.ws.TestResponse;
+import org.sonar.server.ws.WsActionTester;
+
+import static java.util.Collections.singletonList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.sonar.api.issue.Issue.STATUS_OPEN;
+import static org.sonar.api.web.UserRole.CODEVIEWER;
+import static org.sonar.api.web.UserRole.USER;
+import static org.sonar.core.util.Protobuf.setNullable;
+import static org.sonar.db.component.ComponentTesting.newFileDto;
+import static org.sonar.db.issue.IssueChangeDto.TYPE_COMMENT;
+import static org.sonar.db.rule.RuleTesting.newRuleDto;
+import static org.sonar.server.issue.IssueTesting.newDto;
+
+public class AddCommentActionTest {
+
+ private static final long NOW = 10_000_000_000L;
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Rule
+ public DbTester dbTester = DbTester.create();
+
+ @Rule
+ public EsTester esTester = new EsTester(new IssueIndexDefinition(new MapSettings()));
+
+ @Rule
+ public UserSessionRule userSession = UserSessionRule.standalone();
+
+ private System2 system2 = mock(System2.class);
+
+ private DbClient dbClient = dbTester.getDbClient();
+
+ private RuleDbTester ruleDbTester = new RuleDbTester(dbTester);
+ private IssueDbTester issueDbTester = new IssueDbTester(dbTester);
+ private ComponentDbTester componentDbTester = new ComponentDbTester(dbTester);
+
+ private IssueUpdater issueUpdater = new IssueUpdater(dbClient,
+ new ServerIssueStorage(new DefaultRuleFinder(dbClient), dbClient, new IssueIndexer(system2, dbClient, esTester.client())), mock(NotificationManager.class));
+ private OperationResponseWriter responseWriter = mock(OperationResponseWriter.class);
+
+ private WsActionTester tester = new WsActionTester(
+ new AddCommentAction(system2, userSession, dbClient, new IssueFinder(dbClient, userSession), issueUpdater, new IssueFieldsSetter(), responseWriter));
+
+ @Before
+ public void setUp() throws Exception {
+ when(system2.now()).thenReturn(NOW);
+ }
+
+ @Test
+ public void add_comment() throws Exception {
+ IssueDto issueDto = issueDbTester.insertIssue(newIssue().setStatus(STATUS_OPEN).setResolution(null));
+ userSession.login("john").addProjectUuidPermissions(USER, issueDto.getProjectUuid());
+
+ call(issueDto.getKey(), "please fix it");
+
+ verify(responseWriter).write(eq(issueDto.getKey()), any(Request.class), any(Response.class));
+ IssueChangeDto issueComment = dbClient.issueChangeDao().selectByTypeAndIssueKeys(dbTester.getSession(), singletonList(issueDto.getKey()), TYPE_COMMENT).get(0);
+ assertThat(issueComment.getKey()).isNotNull();
+ assertThat(issueComment.getUserLogin()).isEqualTo("john");
+ assertThat(issueComment.getChangeType()).isEqualTo(TYPE_COMMENT);
+ assertThat(issueComment.getChangeData()).isEqualTo("please fix it");
+ assertThat(issueComment.getCreatedAt()).isNotNull();
+ assertThat(issueComment.getUpdatedAt()).isNotNull();
+ assertThat(issueComment.getIssueKey()).isEqualTo(issueDto.getKey());
+ assertThat(issueComment.getIssueChangeCreationDate()).isNotNull();
+
+ IssueDto issueReloaded = dbClient.issueDao().selectByKey(dbTester.getSession(), issueDto.getKey()).get();
+ assertThat(issueReloaded.getIssueUpdateTime()).isEqualTo(NOW);
+ }
+
+ @Test
+ public void fail_when_missing_issue_key() throws Exception {
+ userSession.login("john");
+
+ expectedException.expect(IllegalArgumentException.class);
+ call(null, "please fix it");
+ }
+
+ @Test
+ public void fail_when_issue_does_not_exist() throws Exception {
+ userSession.login("john");
+
+ expectedException.expect(NotFoundException.class);
+ call("ABCD", "please fix it");
+ }
+
+ @Test
+ public void fail_when_missing_comment_text() throws Exception {
+ userSession.login("john");
+
+ expectedException.expect(IllegalArgumentException.class);
+ call("ABCD", null);
+ }
+
+ @Test
+ public void fail_when_empty_comment_text() throws Exception {
+ IssueDto issueDto = issueDbTester.insertIssue(newIssue().setStatus(STATUS_OPEN).setResolution(null));
+ userSession.login("john").addProjectUuidPermissions(USER, issueDto.getProjectUuid());
+
+ expectedException.expect(IllegalArgumentException.class);
+ call(issueDto.getKey(), "");
+ }
+
+ @Test
+ public void fail_when_not_authenticated() throws Exception {
+ expectedException.expect(UnauthorizedException.class);
+ call("ABCD", "please fix it");
+ }
+
+ @Test
+ public void fail_when_not_enough_permission() throws Exception {
+ IssueDto issueDto = issueDbTester.insertIssue(newIssue().setStatus(STATUS_OPEN).setResolution(null));
+ userSession.login("john").addProjectUuidPermissions(CODEVIEWER, issueDto.getProjectUuid());
+
+ expectedException.expect(ForbiddenException.class);
+ call(issueDto.getKey(), "please fix it");
+ }
+
+ @Test
+ public void test_definition() {
+ WebService.Action action = tester.getDef();
+ assertThat(action.key()).isEqualTo("add_comment");
+ assertThat(action.isPost()).isTrue();
+ assertThat(action.isInternal()).isFalse();
+ assertThat(action.params()).hasSize(2);
+ assertThat(action.responseExample()).isNull();
+ }
+
+ private TestResponse call(@Nullable String issueKey, @Nullable String commentText) {
+ TestRequest request = tester.newRequest();
+ setNullable(issueKey, issue -> request.setParam("issue", issue));
+ setNullable(commentText, text -> request.setParam("text", text));
+ return request.execute();
+ }
+
+ private IssueDto newIssue() {
+ RuleDto rule = ruleDbTester.insertRule(newRuleDto());
+ ComponentDto project = componentDbTester.insertProject();
+ ComponentDto file = componentDbTester.insertComponent(newFileDto(project));
+ return newDto(rule, file, project);
+ }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/IssueWsModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/IssueWsModuleTest.java
index 6ae3ed69b16..b873b4be48c 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/IssueWsModuleTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/IssueWsModuleTest.java
@@ -29,6 +29,6 @@ public class IssueWsModuleTest {
public void verify_count_of_added_components() {
ComponentContainer container = new ComponentContainer();
new IssueWsModule().configure(container);
- assertThat(container.size()).isEqualTo(2 + 28);
+ assertThat(container.size()).isEqualTo(2 + 29);
}
}