From 461dc3bd1472bc71b6385a01b881b82171268b56 Mon Sep 17 00:00:00 2001 From: Antoine COPET Date: Sat, 19 Dec 2015 14:35:46 +0100 Subject: [PATCH] Option for creating a task on the issue comment. close #7. --- README.md | 11 +- resources/Sonar-plugin-configuration.PNG | Bin 48810 -> 66742 bytes resources/Stash-plugin-task.PNG | Bin 0 -> 14840 bytes .../org/sonar/plugins/stash/StashPlugin.java | 34 +++- .../stash/StashPluginConfiguration.java | 4 + .../plugins/stash/StashRequestFacade.java | 65 +++++- .../plugins/stash/client/StashClient.java | 67 +++++- .../plugins/stash/issue/StashComment.java | 33 ++- .../sonar/plugins/stash/issue/StashTask.java | 32 +++ .../stash/issue/collector/StashCollector.java | 96 +++++++-- .../plugins/stash/StashRequestFacadeTest.java | 192 ++++++++++++++++-- .../plugins/stash/client/StashClientTest.java | 108 +++++++++- .../plugins/stash/issue/StashCommentTest.java | 50 +++++ .../plugins/stash/issue/StashTaskTest.java | 38 ++++ .../issue/collector/DiffReportSample.java | 17 ++ .../issue/collector/StashCollectorTest.java | 102 +++++++++- 16 files changed, 784 insertions(+), 65 deletions(-) create mode 100755 resources/Stash-plugin-task.PNG create mode 100755 src/main/java/org/sonar/plugins/stash/issue/StashTask.java create mode 100755 src/test/java/org/sonar/plugins/stash/issue/StashTaskTest.java diff --git a/README.md b/README.md index 7758f650..db1aa5a0 100755 --- a/README.md +++ b/README.md @@ -38,18 +38,19 @@ Go to Stash general settings screen on SonarQube server to fill: **Stash base URL** (sonar.stash.url): To define Stash instance. -**Stash base user** (sonar.stash.login): To define user to push violations on Stash pull-request. User must have **REPO_READ permission** for the repository. -**Please notice Stash password needs to be provided to sonar-runner through sonar.stash.password in commandline**. +**Stash base user** (sonar.stash.login): To define user to push violations on Stash pull-request. User must have **REPO_READ permission** for the repository. **Please notice Stash password needs to be provided to sonar-runner through sonar.stash.password in commandline**. **Stash issue threshold** (sonar.stash.issue.threshold): To limit the number of issue pushed to Stash. **Stash timeout** (sonar.stash.timeout): To timeout when Stash Rest api does not replied with expected. -**Stash reviewer approval** (sonar.stash.reviewer.approval): SonarQube is able to approve the pull-request if there is no new issue introduced by the change. -By default, this feature is deactivated: if activated, **Stash base user must have REPO_WRITE permission for the repositories.** +**Stash reviewer approval** (sonar.stash.reviewer.approval): SonarQube is able to approve the pull-request if there is no new issue introduced by the change. By default, this feature is deactivated: if activated, **Stash base user must have REPO_WRITE permission for the repositories.** ![Screenshot SonarQube plugin](resources/Sonar-plugin-approver.PNG) +**Stash tasks severity threshold** (sonar.stash.task.issue.severity.threshold): SonarQube is able to create tasks for all issues with a severity higher to the threshold. By default, this feature is deactivated (threshold: NONE). + +![Screenshot SonarQube plugin](resources/Stash-plugin-task.PNG) ## How to run the plugin? @@ -65,4 +66,4 @@ sonar-runner -Dsonar.analysis.mode=incremental -Dsonar.stash.notification -Dsona If needed, you can reset comments published during the previous SonarQube analysis of your pull-request. Please add **sonar.stash.comments.reset** option to your SonarQube analysis. Please notice only comments linked to the **sonar.stash.login** user will be deleted. This reset will be the first action performed by the plugin. ``` sonar-runner -Dsonar.analysis.mode=incremental -Dsonar.stash.notification -Dsonar.stash.comments.reset -Dsonar.stash.project= -Dsonar.stash.repository= -Dsonar.stash.pullrequest.id= -Dsonar.stash.password=... -``` +``` \ No newline at end of file diff --git a/resources/Sonar-plugin-configuration.PNG b/resources/Sonar-plugin-configuration.PNG index 6a964f17b92960486b1044376bdae7a14e091a38..6f253939dc6d6b026401d612bc2d682ffd41580e 100755 GIT binary patch literal 66742 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%0AZP3a+D=q52LFFNGe<8E#Rz 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 literal 48810 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 literal 0 HcmV?d00001 diff --git a/src/main/java/org/sonar/plugins/stash/StashPlugin.java b/src/main/java/org/sonar/plugins/stash/StashPlugin.java index 409d1a7e..a683bbd7 100755 --- a/src/main/java/org/sonar/plugins/stash/StashPlugin.java +++ b/src/main/java/org/sonar/plugins/stash/StashPlugin.java @@ -3,12 +3,14 @@ import java.util.Arrays; import java.util.List; +import org.apache.commons.collections.ListUtils; import org.sonar.api.Properties; import org.sonar.api.Property; import org.sonar.api.PropertyType; import org.sonar.api.SonarPlugin; import org.sonar.api.config.PropertyDefinition; import org.sonar.api.resources.Qualifiers; +import org.sonar.api.rule.Severity; @Properties({ @Property(key = StashPlugin.STASH_NOTIFICATION, name = "Stash Notification", defaultValue = "false", description = "Analysis result will be issued in Stash pull request", global = false), @@ -21,10 +23,13 @@ public class StashPlugin extends SonarPlugin { private static final String DEFAULT_STASH_TIMEOUT_VALUE = "10000"; private static final String DEFAULT_STASH_THRESHOLD_VALUE = "100"; - private static final String CONFIG_PAGE_SUB_CATEGORY_GENERAL = "General"; + private static final String CONFIG_PAGE_SUB_CATEGORY_STASH = "Stash"; + + public static final String SEVERITY_NONE = "NONE"; + + // INFO, MINOR, MAJOR, CRITICAL, BLOCKER + protected static final List SEVERITY_LIST = Severity.ALL; - public static final String INCREMENTAL_MODE = "incremental"; - public static final String CONTEXT_ISSUE_TYPE = "CONTEXT"; public static final String REMOVED_ISSUE_TYPE = "REMOVED"; public static final String ADDED_ISSUE_TYPE = "ADDED"; @@ -41,6 +46,7 @@ public class StashPlugin extends SonarPlugin { public static final String STASH_ISSUE_THRESHOLD = "sonar.stash.issue.threshold"; public static final String STASH_TIMEOUT = "sonar.stash.timeout"; public static final String SONARQUBE_URL = "sonar.host.url"; + public static final String STASH_TASK_SEVERITY_THRESHOLD = "sonar.stash.task.issue.severity.threshold"; @Override public List getExtensions() { @@ -54,32 +60,40 @@ public List getExtensions() { PropertyDefinition.builder(STASH_URL) .name("Stash base URL") .description("HTTP URL of Stash instance, such as http://yourhost.yourdomain/stash") - .subCategory(CONFIG_PAGE_SUB_CATEGORY_GENERAL) + .subCategory(CONFIG_PAGE_SUB_CATEGORY_STASH) .onQualifiers(Qualifiers.PROJECT).build(), PropertyDefinition.builder(STASH_LOGIN) .name("Stash base User") .description("User to push data on Stash instance") - .subCategory(CONFIG_PAGE_SUB_CATEGORY_GENERAL) + .subCategory(CONFIG_PAGE_SUB_CATEGORY_STASH) .onQualifiers(Qualifiers.PROJECT).build(), PropertyDefinition.builder(STASH_TIMEOUT) .name("Stash issue Timeout") .description("Timeout when pushing a new issue to Stash (in ms)") - .subCategory(CONFIG_PAGE_SUB_CATEGORY_GENERAL) + .subCategory(CONFIG_PAGE_SUB_CATEGORY_STASH) .onQualifiers(Qualifiers.PROJECT) .defaultValue(DEFAULT_STASH_TIMEOUT_VALUE).build(), PropertyDefinition.builder(STASH_REVIEWER_APPROVAL) .name("Stash reviewer approval") .description("Does SonarQube approve the pull-request if there is no new issues?") - .subCategory(CONFIG_PAGE_SUB_CATEGORY_GENERAL) + .subCategory(CONFIG_PAGE_SUB_CATEGORY_STASH) .onQualifiers(Qualifiers.PROJECT) .type(PropertyType.BOOLEAN) .defaultValue("false").build(), PropertyDefinition.builder(STASH_ISSUE_THRESHOLD) .name("Stash issue Threshold") .description("Threshold to limit the number of issues pushed to Stash server") - .subCategory(CONFIG_PAGE_SUB_CATEGORY_GENERAL) + .subCategory(CONFIG_PAGE_SUB_CATEGORY_STASH) .onQualifiers(Qualifiers.PROJECT) - .defaultValue(DEFAULT_STASH_THRESHOLD_VALUE).build()); + .defaultValue(DEFAULT_STASH_THRESHOLD_VALUE).build(), + PropertyDefinition.builder(STASH_TASK_SEVERITY_THRESHOLD) + .name("Stash tasks severity threshold") + .description("Only create tasks for issues with the same or higher severity") + .type(PropertyType.SINGLE_SELECT_LIST) + .subCategory(CONFIG_PAGE_SUB_CATEGORY_STASH) + .onQualifiers(Qualifiers.PROJECT) + .defaultValue(SEVERITY_NONE) + .options(ListUtils.sum(Arrays.asList(SEVERITY_NONE), SEVERITY_LIST)).build()); } - } + diff --git a/src/main/java/org/sonar/plugins/stash/StashPluginConfiguration.java b/src/main/java/org/sonar/plugins/stash/StashPluginConfiguration.java index 436ce105..c2e251ce 100755 --- a/src/main/java/org/sonar/plugins/stash/StashPluginConfiguration.java +++ b/src/main/java/org/sonar/plugins/stash/StashPluginConfiguration.java @@ -60,4 +60,8 @@ public boolean canApprovePullRequest() { public boolean resetComments() { return settings.getBoolean(StashPlugin.STASH_RESET_COMMENTS); } + + public String getTaskIssueSeverityThreshold() { + return settings.getString(StashPlugin.STASH_TASK_SEVERITY_THRESHOLD); + } } \ No newline at end of file diff --git a/src/main/java/org/sonar/plugins/stash/StashRequestFacade.java b/src/main/java/org/sonar/plugins/stash/StashRequestFacade.java index 4d0497af..a6f83766 100755 --- a/src/main/java/org/sonar/plugins/stash/StashRequestFacade.java +++ b/src/main/java/org/sonar/plugins/stash/StashRequestFacade.java @@ -3,8 +3,10 @@ import java.io.File; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.BatchComponent; @@ -21,6 +23,7 @@ import org.sonar.plugins.stash.issue.StashCommentReport; import org.sonar.plugins.stash.issue.StashDiffReport; import org.sonar.plugins.stash.issue.StashPullRequest; +import org.sonar.plugins.stash.issue.StashTask; import org.sonar.plugins.stash.issue.StashUser; import org.sonar.plugins.stash.issue.collector.SonarQubeCollector; @@ -134,6 +137,9 @@ public void postCommentPerIssue(String project, String repository, String pullRe } } + // Severity available to create a task + List taskSeverities = getReportedSeverities(); + for (SonarQubeIssue issue : issueReport.getIssues()) { StashCommentReport comments = commentsByFile.get(issue.getPath()); @@ -151,15 +157,22 @@ public void postCommentPerIssue(String project, String repository, String pullRe long line = diffReport.getLine(issue.getPath(), issue.getLine()); - stashClient.postCommentLineOnPullRequest(project, - repository, - pullRequestId, - MarkdownPrinter.printIssueMarkdown(issue, sonarQubeURL), - issue.getPath(), - line, - type); + StashComment comment = stashClient.postCommentLineOnPullRequest(project, + repository, + pullRequestId, + MarkdownPrinter.printIssueMarkdown(issue, sonarQubeURL), + issue.getPath(), + line, + type); LOGGER.debug("Comment \"{}\" has been created ({}) on file {} ({})", issue.getRule(), type, issue.getPath(), line); + + // Create task linked to the comment if configured + if (taskSeverities.contains(issue.getSeverity())) { + stashClient.postTaskOnComment(issue.getMessage(), comment.getId()); + + LOGGER.debug("Comment \"{}\" has been linked to a Stash task", comment.getId()); + } } } } @@ -289,7 +302,19 @@ public void resetComments(String project, String repository, String pullRequestI // delete comment if published by the current SQ user if (sonarUser.getId() == comment.getAuthor().getId()) { - stashClient.deletePullRequestComment(project, repository, pullRequestId, comment); + + // comment contains tasks which cannot be deleted => do nothing + if (comment.containsPermanentTasks()) { + LOGGER.debug("Comment \"{}\" (path:\"{}\", line:\"{}\") CANNOT be deleted because one of its tasks is not deletable.", comment.getId(), comment.getPath(), comment.getLine()); + } else { + + // delete tasks linked to the current comment + for (StashTask task : comment.getTasks()) { + stashClient.deleteTaskOnComment(task); + } + + stashClient.deletePullRequestComment(project, repository, pullRequestId, comment); + } } } @@ -300,4 +325,28 @@ public void resetComments(String project, String repository, String pullRequestI LOGGER.debug("Exception stack trace", e); } } + + /** + * Get reported severities to create a task. + */ + public List getReportedSeverities() { + List result = new ArrayList<>(); + String threshold = config.getTaskIssueSeverityThreshold(); + + // threshold == NONE, no severities reported + if (! StringUtils.equals(threshold, StashPlugin.SEVERITY_NONE)) { + + // INFO, MINOR, MAJOR, CRITICAL, BLOCKER + boolean hit = false; + for (String severity : StashPlugin.SEVERITY_LIST) { + + if (hit || StringUtils.equals(severity, threshold)) { + result.add(severity); + hit = true; + } + } + } + + return result; + } } diff --git a/src/main/java/org/sonar/plugins/stash/client/StashClient.java b/src/main/java/org/sonar/plugins/stash/client/StashClient.java index 5adba90c..fea10bc7 100755 --- a/src/main/java/org/sonar/plugins/stash/client/StashClient.java +++ b/src/main/java/org/sonar/plugins/stash/client/StashClient.java @@ -16,8 +16,9 @@ import org.sonar.plugins.stash.exceptions.StashReportExtractionException; import org.sonar.plugins.stash.issue.StashComment; import org.sonar.plugins.stash.issue.StashCommentReport; -import org.sonar.plugins.stash.issue.StashDiffReport; -import org.sonar.plugins.stash.issue.StashPullRequest; +import org.sonar.plugins.stash.issue.StashDiffReport; +import org.sonar.plugins.stash.issue.StashPullRequest; +import org.sonar.plugins.stash.issue.StashTask; import org.sonar.plugins.stash.issue.StashUser; import org.sonar.plugins.stash.issue.collector.StashCollector; @@ -43,6 +44,7 @@ public class StashClient { private static final String COMMENT_PULL_REQUEST_API = COMMENTS_PULL_REQUEST_API + "/{4}?version={5}"; private static final String DIFF_PULL_REQUEST_API = PULL_REQUEST_API + "/diff"; private static final String APPROVAL_PULL_REQUEST_API = PULL_REQUEST_API + "/approve"; + private static final String TASKS_API = REST_API + "tasks"; private static final String PULL_REQUEST_APPROVAL_POST_ERROR_MESSAGE = "Unable to change status of pull-request {0} #{1}. Received {2} with message {3}."; private static final String PULL_REQUEST_GET_ERROR_MESSAGE = "Unable to retrieve pull-request {0} #{1}. Received {2} with message {3}."; @@ -51,6 +53,8 @@ public class StashClient { private static final String COMMENT_POST_ERROR_MESSAGE = "Unable to post a comment to {0} #{1}. Received {2} with message {3}."; private static final String COMMENT_GET_ERROR_MESSAGE = "Unable to get comment linked to {0} #{1}. Received {2} with message {3}."; private static final String COMMENT_DELETION_ERROR_MESSAGE = "Unable to delete comment {0} from pull-request {1} #{2}. Received {3} with message {4}."; + private static final String TASK_POST_ERROR_MESSAGE = "Unable to post a task on comment {0}. Received {1} with message {2}."; + private static final String TASK_DELETION_ERROR_MESSAGE = "Unable to delete task {0}. Received {1} with message {2}."; public StashClient(String url, StashCredentials credentials, int stashTimeout) { this.baseUrl = url; @@ -171,9 +175,10 @@ public StashDiffReport getPullRequestDiffs(String project, String repository, St return result; } - public void postCommentLineOnPullRequest(String project, String repository, String pullRequestId, String message, String path, long line, String type) + public StashComment postCommentLineOnPullRequest(String project, String repository, String pullRequestId, String message, String path, long line, String type) throws StashClientException { - + StashComment result = null; + String request = MessageFormat.format(COMMENTS_PULL_REQUEST_API, baseUrl + REST_API, project, repository, pullRequestId); @@ -204,11 +209,17 @@ public void postCommentLineOnPullRequest(String project, String repository, Stri String responseMessage = response.getStatusText(); throw new StashClientException(MessageFormat.format(COMMENT_POST_ERROR_MESSAGE, repository, pullRequestId, responseCode, responseMessage)); } - } catch (ExecutionException | TimeoutException | IOException | InterruptedException e) { + + // get generated comment + result = StashCollector.extractComment(response.getResponseBody(), path, line); + + } catch (ExecutionException | TimeoutException | IOException | InterruptedException | StashReportExtractionException e) { throw new StashClientException(e); } finally{ httpClient.close(); } + + return result; } public StashUser getUser(String userSlug) @@ -339,7 +350,53 @@ public void resetPullRequestApproval(String project, String repository, String p httpClient.close(); } } + + public void postTaskOnComment(String message, Long commentId) throws StashClientException { + String request = baseUrl + TASKS_API; + + JSONObject anchor = new JSONObject(); + anchor.put("id", commentId); + anchor.put("type", "COMMENT"); + + JSONObject json = new JSONObject(); + json.put("anchor", anchor); + json.put("text", message); + + try (AsyncHttpClient httpClient = createHttpClient()) { + + BoundRequestBuilder requestBuilder = httpClient.preparePost(request); + requestBuilder.setBody(json.toString()); + + Response response = executeRequest(requestBuilder); + int responseCode = response.getStatusCode(); + if (responseCode != HttpURLConnection.HTTP_CREATED) { + String responseMessage = response.getStatusText(); + throw new StashClientException(MessageFormat.format(TASK_POST_ERROR_MESSAGE, commentId, responseCode, responseMessage)); + } + } catch (ExecutionException | TimeoutException | IOException | InterruptedException e) { + throw new StashClientException(e); + } + } + public void deleteTaskOnComment(StashTask task) throws StashClientException { + String request = baseUrl + TASKS_API + "/" + task.getId(); + + AsyncHttpClient httpClient = createHttpClient(); + BoundRequestBuilder requestBuilder = httpClient.prepareDelete(request); + + try { + Response response = executeRequest(requestBuilder); + int responseCode = response.getStatusCode(); + if (responseCode != HttpURLConnection.HTTP_NO_CONTENT) { + String responseMessage = response.getStatusText(); + throw new StashClientException(MessageFormat.format(TASK_DELETION_ERROR_MESSAGE, task.getId(), responseCode, responseMessage)); + } + } catch (ExecutionException | TimeoutException | InterruptedException | IOException e) { + throw new StashClientException(e); + } finally{ + httpClient.close(); + } + } Response executeRequest(final BoundRequestBuilder requestBuilder) throws InterruptedException, IOException, ExecutionException, TimeoutException { diff --git a/src/main/java/org/sonar/plugins/stash/issue/StashComment.java b/src/main/java/org/sonar/plugins/stash/issue/StashComment.java index 1fe8e07c..fda51d00 100755 --- a/src/main/java/org/sonar/plugins/stash/issue/StashComment.java +++ b/src/main/java/org/sonar/plugins/stash/issue/StashComment.java @@ -1,14 +1,18 @@ package org.sonar.plugins.stash.issue; +import java.util.ArrayList; +import java.util.List; + public class StashComment { private final long id; private final String message; - private final String path; private final StashUser author; private final long version; private long line; + private String path; + private List tasks; public StashComment(long id, String message, String path, Long line, StashUser author, long version) { this.id = id; @@ -23,6 +27,8 @@ public StashComment(long id, String message, String path, Long line, StashUser a } else{ this.line = line.longValue(); } + + tasks = new ArrayList<>(); } public long getId(){ @@ -33,6 +39,10 @@ public void setLine(long line){ this.line = line; } + public void setPath(String path){ + this.path = path; + } + public String getMessage() { return message; } @@ -53,6 +63,27 @@ public long getVersion() { return version; } + public List getTasks() { + return tasks; + } + + public void addTask(StashTask task){ + tasks.add(task); + } + + public boolean containsPermanentTasks() { + boolean result = false; + + for (StashTask task: tasks){ + if (! task.isDeletable()){ + result = true; + break; + } + } + + return result; + } + @Override public boolean equals(Object object) { boolean result = false; diff --git a/src/main/java/org/sonar/plugins/stash/issue/StashTask.java b/src/main/java/org/sonar/plugins/stash/issue/StashTask.java new file mode 100755 index 00000000..77031b2f --- /dev/null +++ b/src/main/java/org/sonar/plugins/stash/issue/StashTask.java @@ -0,0 +1,32 @@ +package org.sonar.plugins.stash.issue; + +public class StashTask { + + private final Long id; + private final String text; + private final String state; + private final boolean deletable; + + public StashTask(Long id, String text, String state, boolean deletable) { + this.id = id; + this.text = text; + this.state = state; + this.deletable = deletable; + } + + public Long getId() { + return id; + } + + public String getText() { + return text; + } + + public String getState() { + return state; + } + + public boolean isDeletable() { + return deletable; + } +} diff --git a/src/main/java/org/sonar/plugins/stash/issue/collector/StashCollector.java b/src/main/java/org/sonar/plugins/stash/issue/collector/StashCollector.java index 4698be4c..a3f862fc 100755 --- a/src/main/java/org/sonar/plugins/stash/issue/collector/StashCollector.java +++ b/src/main/java/org/sonar/plugins/stash/issue/collector/StashCollector.java @@ -12,6 +12,7 @@ import org.sonar.plugins.stash.issue.StashDiff; import org.sonar.plugins.stash.issue.StashDiffReport; import org.sonar.plugins.stash.issue.StashPullRequest; +import org.sonar.plugins.stash.issue.StashTask; import org.sonar.plugins.stash.issue.StashUser; public final class StashCollector { @@ -32,21 +33,8 @@ public static StashCommentReport extractComments(String jsonBody) throws StashRe for (Object obj : jsonValues.toArray()) { JSONObject jsonComment = (JSONObject) obj; - long id = (long) jsonComment.get("id"); - String message = (String) jsonComment.get("text"); - JSONObject jsonAnchor = (JSONObject) jsonComment.get("anchor"); - String path = (String) jsonAnchor.get("path"); - - // can be null if comment is attached to the global file - Long line = (Long) jsonAnchor.get("line"); - - long version = (long) jsonComment.get("version"); - - JSONObject jsonAuthor = (JSONObject) jsonComment.get("author"); - StashUser stashUser = extractUser(jsonAuthor.toJSONString()); - - StashComment comment = new StashComment(id, message, path, line, stashUser, version); + StashComment comment = extractComment(jsonComment.toJSONString()); result.add(comment); } } @@ -56,7 +44,55 @@ public static StashCommentReport extractComments(String jsonBody) throws StashRe return result; } + + public static StashComment extractComment(String jsonBody, String path, Long line) throws StashReportExtractionException { + StashComment result = null; + + try { + JSONObject jsonComment = (JSONObject) new JSONParser().parse(jsonBody); + + long id = (long) jsonComment.get("id"); + String message = (String) jsonComment.get("text"); + + long version = (long) jsonComment.get("version"); + + JSONObject jsonAuthor = (JSONObject) jsonComment.get("author"); + StashUser stashUser = extractUser(jsonAuthor.toJSONString()); + + result = new StashComment(id, message, path, line, stashUser, version); + + } catch (ParseException e) { + throw new StashReportExtractionException(e); + } + + return result; + } + + public static StashComment extractComment(String jsonBody) throws StashReportExtractionException { + StashComment result = null; + + try { + JSONObject jsonComment = (JSONObject) new JSONParser().parse(jsonBody); + + JSONObject jsonAnchor = (JSONObject) jsonComment.get("anchor"); + if (jsonAnchor == null) { + throw new StashReportExtractionException("JSON Comment does not contain any \"anchor\" tag to describe comment \"line\" and \"path\""); + } + + String path = (String) jsonAnchor.get("path"); + + // can be null if comment is attached to the global file + Long line = (Long) jsonAnchor.get("line"); + result = extractComment(jsonBody, path, line); + + } catch (ParseException e) { + throw new StashReportExtractionException(e); + } + + return result; + } + public static StashPullRequest extractPullRequest(String project, String repository, String pullRequestId, String jsonBody) throws StashReportExtractionException { StashPullRequest result = new StashPullRequest(project, repository, pullRequestId); @@ -169,6 +205,16 @@ public static StashDiffReport extractDiffs(String jsonBody) throws StashReportEx StashComment comment = new StashComment(lineCommentId, lineCommentMessage, path, destination, author, lineCommentVersion); diff.addComment(comment); + + // get the tasks linked to the current comment + JSONArray jsonTasks = (JSONArray) jsonLineComment.get("tasks"); + if (jsonTasks != null) { + for (Object objTask : jsonTasks.toArray()) { + JSONObject jsonTask = (JSONObject) objTask; + + comment.addTask(extractTask(jsonTask.toString())); + } + } } } } @@ -220,6 +266,28 @@ public static StashDiffReport extractDiffs(String jsonBody) throws StashReportEx return result; } + public static StashTask extractTask(String jsonBody) throws StashReportExtractionException { + try { + JSONObject jsonTask = (JSONObject) new JSONParser().parse(jsonBody); + + long taskId = (long) jsonTask.get("id"); + String taskText = (String) jsonTask.get("text"); + String taskState = (String) jsonTask.get("state"); + + boolean deletable = true; + + JSONObject objPermission = (JSONObject) jsonTask.get("permittedOperations"); + if (objPermission != null) { + deletable = (boolean) objPermission.get("deletable"); + } + + return new StashTask(taskId, taskText, taskState, deletable); + + } catch (ParseException e) { + throw new StashReportExtractionException(e); + } + } + public static boolean isLastPage(String jsonBody) throws StashReportExtractionException { boolean result = true; diff --git a/src/test/java/org/sonar/plugins/stash/StashRequestFacadeTest.java b/src/test/java/org/sonar/plugins/stash/StashRequestFacadeTest.java index 14dc89c3..ba98bc84 100755 --- a/src/test/java/org/sonar/plugins/stash/StashRequestFacadeTest.java +++ b/src/test/java/org/sonar/plugins/stash/StashRequestFacadeTest.java @@ -13,6 +13,7 @@ import static org.mockito.Mockito.when; import java.util.ArrayList; +import java.util.List; import org.junit.Before; import org.junit.Rule; @@ -20,6 +21,7 @@ import org.junit.rules.ExpectedException; import org.mockito.Mock; import org.mockito.Mockito; +import org.sonar.api.rule.Severity; import org.sonar.plugins.stash.client.StashClient; import org.sonar.plugins.stash.client.StashCredentials; import org.sonar.plugins.stash.exceptions.StashClientException; @@ -31,6 +33,7 @@ import org.sonar.plugins.stash.issue.StashCommentReport; import org.sonar.plugins.stash.issue.StashDiffReport; import org.sonar.plugins.stash.issue.StashPullRequest; +import org.sonar.plugins.stash.issue.StashTask; import org.sonar.plugins.stash.issue.StashUser; public class StashRequestFacadeTest { @@ -55,6 +58,15 @@ public class StashRequestFacadeTest { @Mock StashCommentReport stashCommentsReport2; + @Mock + StashComment comment1; + + @Mock + StashComment comment2; + + @Mock + StashComment comment3; + @Mock StashUser stashUser; @@ -78,6 +90,8 @@ public class StashRequestFacadeTest { @Before public void setUp() throws Exception { config = mock(StashPluginConfiguration.class); + when(config.getTaskIssueSeverityThreshold()).thenReturn(StashPlugin.SEVERITY_NONE); + myFacade = new StashRequestFacade(config); stashClient = mock(StashClient.class); @@ -94,26 +108,64 @@ public void setUp() throws Exception { issueReport = new SonarQubeIssuesReport(); - SonarQubeIssue issue1 = new SonarQubeIssue("key1", "severity1", "message1", "rule1", FILE_PATH_1, 1); + SonarQubeIssue issue1 = new SonarQubeIssue("key1", Severity.CRITICAL, "message1", "rule1", FILE_PATH_1, 1); stashCommentMessage1 = MarkdownPrinter.printIssueMarkdown(issue1, SONARQUBE_URL); issueReport.add(issue1); - SonarQubeIssue issue2 = new SonarQubeIssue("key2", "severity2", "message2", "rule2", FILE_PATH_1, 2); + SonarQubeIssue issue2 = new SonarQubeIssue("key2", Severity.MAJOR, "message2", "rule2", FILE_PATH_1, 2); stashCommentMessage2 = MarkdownPrinter.printIssueMarkdown(issue2, SONARQUBE_URL); issueReport.add(issue2); - SonarQubeIssue issue3 = new SonarQubeIssue("key3", "severity3", "message3", "rule3", FILE_PATH_2, 1); + SonarQubeIssue issue3 = new SonarQubeIssue("key3", Severity.INFO, "message3", "rule3", FILE_PATH_2, 1); stashCommentMessage3 = MarkdownPrinter.printIssueMarkdown(issue3, SONARQUBE_URL); issueReport.add(issue3); - StashComment comment = mock(StashComment.class); - when(comment.getAuthor()).thenReturn(stashUser); + StashTask task1 = mock(StashTask.class); + when(task1.getId()).thenReturn((long) 1111); + + List taskList1 = new ArrayList<>(); + taskList1.add(task1); + + comment1 = mock(StashComment.class); + when(comment1.getId()).thenReturn((long) 1111); + when(comment1.getAuthor()).thenReturn(stashUser); + when(stashClient.postCommentLineOnPullRequest(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, stashCommentMessage1, FILE_PATH_1, 1, STASH_DIFF_TYPE)).thenReturn(comment1); + when(comment1.getTasks()).thenReturn(taskList1); + when(comment1.containsPermanentTasks()).thenReturn(false); + + StashTask task2 = mock(StashTask.class); + when(task1.getId()).thenReturn((long) 2222); + + List taskList2 = new ArrayList<>(); + taskList2.add(task2); + + comment2 = mock(StashComment.class); + when(comment2.getId()).thenReturn((long) 2222); + when(comment2.getAuthor()).thenReturn(stashUser); + when(stashClient.postCommentLineOnPullRequest(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, stashCommentMessage2, FILE_PATH_1, 2, STASH_DIFF_TYPE)).thenReturn(comment2); + when(comment2.getTasks()).thenReturn(taskList2); + when(comment2.containsPermanentTasks()).thenReturn(false); + + StashTask task3 = mock(StashTask.class); + when(task3.getId()).thenReturn((long) 3333); + + List taskList3 = new ArrayList<>(); + taskList3.add(task3); + + comment3 = mock(StashComment.class); + when(comment3.getId()).thenReturn((long) 3333); + when(comment3.getAuthor()).thenReturn(stashUser); + when(stashClient.postCommentLineOnPullRequest(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, stashCommentMessage3, FILE_PATH_2, 1, STASH_DIFF_TYPE)).thenReturn(comment3); + when(comment3.getTasks()).thenReturn(taskList3); + when(comment3.containsPermanentTasks()).thenReturn(false); ArrayList comments = new ArrayList<>(); - comments.add(comment); + comments.add(comment1); + comments.add(comment2); + comments.add(comment3); when(diffReport.getComments()).thenReturn(comments); - + stashCommentsReport1 = mock(StashCommentReport.class); when(stashCommentsReport1.getComments()).thenReturn(comments); when(stashCommentsReport1.applyDiffReport(diffReport)).thenReturn(stashCommentsReport1); @@ -123,11 +175,9 @@ public void setUp() throws Exception { when(stashCommentsReport1.getComments()).thenReturn(comments); when(stashCommentsReport2.applyDiffReport(diffReport)).thenReturn(stashCommentsReport2); when(stashClient.getPullRequestComments(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, FILE_PATH_2)).thenReturn(stashCommentsReport2); - - doNothing().when(stashClient).postCommentLineOnPullRequest(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, stashCommentMessage1, FILE_PATH_1, 1, STASH_DIFF_TYPE); - doNothing().when(stashClient).postCommentLineOnPullRequest(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, stashCommentMessage2, FILE_PATH_1, 2, STASH_DIFF_TYPE); - doNothing().when(stashClient).postCommentLineOnPullRequest(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, stashCommentMessage3, FILE_PATH_2, 1, STASH_DIFF_TYPE); + doNothing().when(stashClient).deletePullRequestComment(Mockito.eq(STASH_PROJECT), Mockito.eq(STASH_REPOSITORY), Mockito.eq(STASH_PULLREQUEST_ID), (StashComment) Mockito.anyObject()); + doNothing().when(stashClient).deleteTaskOnComment((StashTask) Mockito.anyObject()); } @Test @@ -230,11 +280,71 @@ public void testPostCommentPerIssueWithNoStashCommentAlreadyPushed() throws Exce when(stashCommentsReport2.contains(stashCommentMessage3, FILE_PATH_2, 1)).thenReturn(true); myFacade.postCommentPerIssue(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, SONARQUBE_URL, issueReport, diffReport, stashClient); - + verify(stashClient, times(0)).postCommentLineOnPullRequest(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, stashCommentMessage1, FILE_PATH_1, 1, STASH_DIFF_TYPE); verify(stashClient, times(0)).postCommentLineOnPullRequest(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, stashCommentMessage2, FILE_PATH_1, 2, STASH_DIFF_TYPE); verify(stashClient, times(0)).postCommentLineOnPullRequest(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, stashCommentMessage3, FILE_PATH_2, 1, STASH_DIFF_TYPE); } + + @Test + public void testPostTaskOnComment() throws Exception { + when(config.getTaskIssueSeverityThreshold()).thenReturn(Severity.INFO); + + myFacade.postCommentPerIssue(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, SONARQUBE_URL, issueReport, diffReport, stashClient); + + verify(stashClient, times(1)).postCommentLineOnPullRequest(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, stashCommentMessage1, FILE_PATH_1, 1, STASH_DIFF_TYPE); + verify(stashClient, times(1)).postCommentLineOnPullRequest(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, stashCommentMessage2, FILE_PATH_1, 2, STASH_DIFF_TYPE); + verify(stashClient, times(1)).postCommentLineOnPullRequest(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, stashCommentMessage3, FILE_PATH_2, 1, STASH_DIFF_TYPE); + + verify(stashClient, times(1)).postTaskOnComment("message3", (long) 3333); + verify(stashClient, times(1)).postTaskOnComment("message2", (long) 2222); + verify(stashClient, times(1)).postTaskOnComment("message1", (long) 1111); + } + + @Test + public void testPostTaskOnCommentWithRestrictedLevel() throws Exception { + when(config.getTaskIssueSeverityThreshold()).thenReturn(Severity.MAJOR); + + myFacade.postCommentPerIssue(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, SONARQUBE_URL, issueReport, diffReport, stashClient); + + verify(stashClient, times(1)).postCommentLineOnPullRequest(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, stashCommentMessage1, FILE_PATH_1, 1, STASH_DIFF_TYPE); + verify(stashClient, times(1)).postCommentLineOnPullRequest(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, stashCommentMessage2, FILE_PATH_1, 2, STASH_DIFF_TYPE); + verify(stashClient, times(1)).postCommentLineOnPullRequest(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, stashCommentMessage3, FILE_PATH_2, 1, STASH_DIFF_TYPE); + + verify(stashClient, times(0)).postTaskOnComment("message3", (long) 3333); + verify(stashClient, times(1)).postTaskOnComment("message2", (long) 2222); + verify(stashClient, times(1)).postTaskOnComment("message1", (long) 1111); + } + + @Test + public void testPostTaskOnCommentWithNotPresentLevel() throws Exception { + when(config.getTaskIssueSeverityThreshold()).thenReturn(Severity.BLOCKER); + + myFacade.postCommentPerIssue(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, SONARQUBE_URL, issueReport, diffReport, stashClient); + + verify(stashClient, times(1)).postCommentLineOnPullRequest(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, stashCommentMessage1, FILE_PATH_1, 1, STASH_DIFF_TYPE); + verify(stashClient, times(1)).postCommentLineOnPullRequest(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, stashCommentMessage2, FILE_PATH_1, 2, STASH_DIFF_TYPE); + verify(stashClient, times(1)).postCommentLineOnPullRequest(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, stashCommentMessage3, FILE_PATH_2, 1, STASH_DIFF_TYPE); + + verify(stashClient, times(0)).postTaskOnComment("message3", (long) 3333); + verify(stashClient, times(0)).postTaskOnComment("message2", (long) 2222); + verify(stashClient, times(0)).postTaskOnComment("message1", (long) 1111); + } + + @Test + public void testPostTaskOnCommentWithSeverityNone() throws Exception { + when(config.getTaskIssueSeverityThreshold()).thenReturn(StashPlugin.SEVERITY_NONE); + + myFacade.postCommentPerIssue(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, SONARQUBE_URL, issueReport, diffReport, stashClient); + + verify(stashClient, times(1)).postCommentLineOnPullRequest(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, stashCommentMessage1, FILE_PATH_1, 1, STASH_DIFF_TYPE); + verify(stashClient, times(1)).postCommentLineOnPullRequest(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, stashCommentMessage2, FILE_PATH_1, 2, STASH_DIFF_TYPE); + verify(stashClient, times(1)).postCommentLineOnPullRequest(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, stashCommentMessage3, FILE_PATH_2, 1, STASH_DIFF_TYPE); + + verify(stashClient, times(0)).postTaskOnComment("message3", (long) 3333); + verify(stashClient, times(0)).postTaskOnComment("message2", (long) 2222); + verify(stashClient, times(0)).postTaskOnComment("message1", (long) 1111); + } @Test public void testPostCommentPerIssueWithNoType() throws Exception{ @@ -323,7 +433,28 @@ public void testGetPullRequestDiffReportWithException() throws Exception { public void testResetComments() throws Exception { myFacade.resetComments(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, diffReport, stashUser, stashClient); - verify(stashClient, times(1)).deletePullRequestComment(Mockito.eq(STASH_PROJECT), Mockito.eq(STASH_REPOSITORY), Mockito.eq(STASH_PULLREQUEST_ID), (StashComment) Mockito.anyObject()); + verify(stashClient, times(3)).deleteTaskOnComment((StashTask) Mockito.anyObject()); + verify(stashClient, times(3)).deletePullRequestComment(Mockito.eq(STASH_PROJECT), Mockito.eq(STASH_REPOSITORY), Mockito.eq(STASH_PULLREQUEST_ID), (StashComment) Mockito.anyObject()); + } + + @Test + public void testResetCommentsWithNotDeletableTasks() throws Exception { + when(comment1.containsPermanentTasks()).thenReturn(true); + + myFacade.resetComments(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, diffReport, stashUser, stashClient); + + verify(stashClient, times(2)).deleteTaskOnComment((StashTask) Mockito.anyObject()); + verify(stashClient, times(2)).deletePullRequestComment(Mockito.eq(STASH_PROJECT), Mockito.eq(STASH_REPOSITORY), Mockito.eq(STASH_PULLREQUEST_ID), (StashComment) Mockito.anyObject()); + } + + @Test + public void testResetCommentsWithNoTasks() throws Exception { + when(comment1.getTasks()).thenReturn(new ArrayList()); + + myFacade.resetComments(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, diffReport, stashUser, stashClient); + + verify(stashClient, times(2)).deleteTaskOnComment((StashTask) Mockito.anyObject()); + verify(stashClient, times(3)).deletePullRequestComment(Mockito.eq(STASH_PROJECT), Mockito.eq(STASH_REPOSITORY), Mockito.eq(STASH_PULLREQUEST_ID), (StashComment) Mockito.anyObject()); } @Test @@ -400,4 +531,39 @@ public void testAddPullRequestReviewerWithReviewerAlreadyAdded() throws Exceptio verify(stashClient, times(0)).addPullRequestReviewer(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, (long) 1, reviewers); } + + @Test + public void testGetReportedSeverities() { + when(config.getTaskIssueSeverityThreshold()).thenReturn(Severity.INFO); + + List severities = myFacade.getReportedSeverities(); + + assertEquals(5, severities.size()); + assertEquals(StashPlugin.SEVERITY_LIST.get(0), severities.get(0)); + assertEquals(StashPlugin.SEVERITY_LIST.get(1), severities.get(1)); + assertEquals(StashPlugin.SEVERITY_LIST.get(2), severities.get(2)); + assertEquals(StashPlugin.SEVERITY_LIST.get(3), severities.get(3)); + assertEquals(StashPlugin.SEVERITY_LIST.get(4), severities.get(4)); + } + + @Test + public void testGetReportedSeveritiesWithRestriction() { + when(config.getTaskIssueSeverityThreshold()).thenReturn(Severity.MAJOR); + + List severities = myFacade.getReportedSeverities(); + + assertEquals(3, severities.size()); + assertEquals(StashPlugin.SEVERITY_LIST.get(2), severities.get(0)); + assertEquals(StashPlugin.SEVERITY_LIST.get(3), severities.get(1)); + assertEquals(StashPlugin.SEVERITY_LIST.get(4), severities.get(2)); + } + + @Test + public void testGetReportedSeveritiesWithNoSeverity() { + when(config.getTaskIssueSeverityThreshold()).thenReturn(StashPlugin.SEVERITY_NONE); + + List severities = myFacade.getReportedSeverities(); + + assertEquals(0, severities.size()); + } } diff --git a/src/test/java/org/sonar/plugins/stash/client/StashClientTest.java b/src/test/java/org/sonar/plugins/stash/client/StashClientTest.java index 487b41a1..e78fa571 100755 --- a/src/test/java/org/sonar/plugins/stash/client/StashClientTest.java +++ b/src/test/java/org/sonar/plugins/stash/client/StashClientTest.java @@ -26,8 +26,9 @@ import org.sonar.plugins.stash.exceptions.StashClientException; import org.sonar.plugins.stash.issue.StashComment; import org.sonar.plugins.stash.issue.StashCommentReport; -import org.sonar.plugins.stash.issue.StashDiffReport; -import org.sonar.plugins.stash.issue.StashPullRequest; +import org.sonar.plugins.stash.issue.StashDiffReport; +import org.sonar.plugins.stash.issue.StashPullRequest; +import org.sonar.plugins.stash.issue.StashTask; import org.sonar.plugins.stash.issue.StashUser; import org.sonar.plugins.stash.issue.collector.DiffReportSample; @@ -246,9 +247,15 @@ public void testGetPullRequestDiffsWithException() throws Exception { @Test public void testPostCommentLineOnPullRequest() throws Exception { + String stashJsonComment = "{\"id\":1234, \"text\":\"message\", \"anchor\": {\"path\":\"path\", \"line\":5}," + + "\"author\": {\"id\":1, \"name\":\"SonarQube\", \"slug\":\"sonarqube\", \"email\":\"sq@email.com\"}, \"version\": 0}"; + when(response.getStatusCode()).thenReturn(HttpURLConnection.HTTP_CREATED); + when(response.getResponseBody()).thenReturn(stashJsonComment); + + StashComment comment = spyClient.postCommentLineOnPullRequest("Project", "Repository", "1", "message", "path", 5, "type"); - spyClient.postCommentLineOnPullRequest("Project", "Repository", "1", "message", "path", 5, "type"); + assertEquals((long) 1234, comment.getId()); verify(requestBuilder, times(1)).execute(); verify(httpClient, times(1)).close(); } @@ -581,5 +588,98 @@ public void testAddPullRequestReviewerWithException() throws Exception { verify(response, times(0)).getStatusText(); verify(httpClient, times(1)).close(); } - } + } + + @Test + public void testPostTaskOnComment() throws Exception { + when(response.getStatusCode()).thenReturn(HttpURLConnection.HTTP_CREATED); + + spyClient.postTaskOnComment("message", (long) 1111); + + verify(requestBuilder, times(1)).execute(); + verify(httpClient, times(1)).close(); + } + + @Test + public void testPostTaskOnCommentWithWrongHTTPResult() throws Exception { + when(response.getStatusCode()).thenReturn(HttpURLConnection.HTTP_FORBIDDEN); + + try { + spyClient.postTaskOnComment("message", (long) 1111); + + assertFalse("Wrong HTTP result should raised StashClientException", true); + + } catch (StashClientException e) { + verify(response, times(1)).getStatusText(); + verify(httpClient, times(1)).close(); + } + } + + @Test + public void testPostTaskOnCommentWithException() throws Exception { + when(response.getStatusCode()).thenReturn(HttpURLConnection.HTTP_CREATED); + when(listenableFurture.get(anyLong(), eq(TimeUnit.MILLISECONDS))).thenThrow(new TimeoutException("TimeoutException for Test")); + + try { + spyClient.postTaskOnComment("message", (long) 1111); + + assertFalse("Exception failure should be catched and convert to StashClientException", true); + + } catch (StashClientException e) { + verify(response, times(0)).getStatusText(); + verify(httpClient, times(1)).close(); + } + } + + @Test + public void testDeleteTaskOnComment() throws Exception { + StashTask task = mock(StashTask.class); + when(task.getId()).thenReturn((long) 1111); + + when(response.getStatusCode()).thenReturn(HttpURLConnection.HTTP_NO_CONTENT); + + spyClient.deleteTaskOnComment(task); + + verify(requestBuilder, times(1)).execute(); + verify(httpClient, times(1)).close(); + } + + @Test + public void testDeleteTaskOnCommentWithWrongHTTPResult() throws Exception { + StashTask task = mock(StashTask.class); + when(task.getId()).thenReturn((long) 1111); + + when(response.getStatusCode()).thenReturn(HttpURLConnection.HTTP_FORBIDDEN); + + try { + spyClient.deleteTaskOnComment(task); + + assertFalse("Wrong HTTP result should raised StashClientException", true); + + } catch (StashClientException e) { + verify(response, times(1)).getStatusText(); + verify(httpClient, times(1)).close(); + } + } + + @Test + public void testDeleteTaskOnCommentWithException() throws Exception { + StashTask task = mock(StashTask.class); + when(task.getId()).thenReturn((long) 1111); + + when(response.getStatusCode()).thenReturn(HttpURLConnection.HTTP_CREATED); + when(listenableFurture.get(anyLong(), eq(TimeUnit.MILLISECONDS))).thenThrow(new TimeoutException("TimeoutException for Test")); + + try { + spyClient.deleteTaskOnComment(task); + + assertFalse("Exception failure should be catched and convert to StashClientException", true); + + } catch (StashClientException e) { + verify(response, times(0)).getStatusText(); + verify(httpClient, times(1)).close(); + } + } + + } diff --git a/src/test/java/org/sonar/plugins/stash/issue/StashCommentTest.java b/src/test/java/org/sonar/plugins/stash/issue/StashCommentTest.java index 0de12533..bb6feabf 100755 --- a/src/test/java/org/sonar/plugins/stash/issue/StashCommentTest.java +++ b/src/test/java/org/sonar/plugins/stash/issue/StashCommentTest.java @@ -4,6 +4,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertFalse; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import org.junit.Test; import org.mockito.Mock; @@ -35,4 +36,53 @@ public void testEquals(){ StashComment comment3 = new StashComment(1, "message", "path", (long) 1, stashUser, 0); assertTrue(comment1.equals(comment3)); } + + @Test + public void testAddTask() { + StashTask task1 = mock(StashTask.class); + when(task1.getId()).thenReturn((long) 1111); + + StashTask task2 = mock(StashTask.class); + when(task2.getId()).thenReturn((long) 2222); + + StashComment comment = new StashComment(1, "message", "path", (long) 1, stashUser, 0); + assertEquals(0, comment.getTasks().size()); + + comment.addTask(task1); + assertEquals(1, comment.getTasks().size()); + assertTrue(comment.getTasks().get(0).getId() == 1111); + + comment.addTask(task2); + assertEquals(2, comment.getTasks().size()); + assertTrue(comment.getTasks().get(0).getId() == 1111); + assertTrue(comment.getTasks().get(1).getId() == 2222); + } + + @Test + public void testContainsNotDeletableTasks() { + StashComment comment = new StashComment(1, "message", "path", (long) 1, stashUser, 0); + + StashTask task1 = mock(StashTask.class); + when(task1.isDeletable()).thenReturn(true); + comment.addTask(task1); + + StashTask task2 = mock(StashTask.class); + when(task2.isDeletable()).thenReturn(true); + comment.addTask(task2); + + assertFalse(comment.containsPermanentTasks()); + + StashTask task3 = mock(StashTask.class); + when(task3.isDeletable()).thenReturn(false); + comment.addTask(task3); + + assertTrue(comment.containsPermanentTasks()); + } + + @Test + public void testContainsNotDeletableTasksWithoutTasks() { + StashComment comment = new StashComment(1, "message", "path", (long) 1, stashUser, 0); + assertFalse(comment.containsPermanentTasks()); + } + } diff --git a/src/test/java/org/sonar/plugins/stash/issue/StashTaskTest.java b/src/test/java/org/sonar/plugins/stash/issue/StashTaskTest.java new file mode 100755 index 00000000..8f480b76 --- /dev/null +++ b/src/test/java/org/sonar/plugins/stash/issue/StashTaskTest.java @@ -0,0 +1,38 @@ +package org.sonar.plugins.stash.issue; + + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Before; +import org.junit.Test; + +public class StashTaskTest { + + StashTask myTask; + + @Before + public void setUp(){ + myTask = new StashTask((long) 1111, "Text", "State", true); + } + + @Test + public void testGetId() { + assertEquals(1111, (long) myTask.getId()); + } + + @Test + public void testGetState() { + assertEquals("State", myTask.getState()); + } + + @Test + public void testGetText() { + assertEquals("Text", myTask.getText()); + } + + @Test + public void testIsDeletable() { + assertTrue(myTask.isDeletable()); + } +} diff --git a/src/test/java/org/sonar/plugins/stash/issue/collector/DiffReportSample.java b/src/test/java/org/sonar/plugins/stash/issue/collector/DiffReportSample.java index 6869a050..8fb4399e 100755 --- a/src/test/java/org/sonar/plugins/stash/issue/collector/DiffReportSample.java +++ b/src/test/java/org/sonar/plugins/stash/issue/collector/DiffReportSample.java @@ -99,6 +99,23 @@ public class DiffReportSample { + " \"slug\": \"sonarqube\"," + " \"email\": \"sq@email.com\"," + " }," + + " \"tasks\": [" + + " {" + + " \"id\": 12345," + + " \"text\": \"Complete the task associated to this TODO comment.\"," + + " \"state\": \"OPENED\"," + + " \"permittedOperations\": {" + + " \"deletable\": true" + + " }" + + " }," + + " {" + + " \"id\": 54321," + + " \"text\": \"Complete the task associated to this TODO comment.\"," + + " \"state\": \"OPENED\"," + + " \"permittedOperations\": {" + + " \"deletable\": true" + + " }" + + " }]" + " }," + " {" + " \"id\": 54321," diff --git a/src/test/java/org/sonar/plugins/stash/issue/collector/StashCollectorTest.java b/src/test/java/org/sonar/plugins/stash/issue/collector/StashCollectorTest.java index c0a6890b..7b7005e8 100755 --- a/src/test/java/org/sonar/plugins/stash/issue/collector/StashCollectorTest.java +++ b/src/test/java/org/sonar/plugins/stash/issue/collector/StashCollectorTest.java @@ -5,11 +5,13 @@ import static org.junit.Assert.assertTrue; import org.junit.Test; +import org.sonar.plugins.stash.exceptions.StashReportExtractionException; import org.sonar.plugins.stash.issue.StashComment; import org.sonar.plugins.stash.issue.StashCommentReport; import org.sonar.plugins.stash.issue.StashDiff; -import org.sonar.plugins.stash.issue.StashDiffReport; -import org.sonar.plugins.stash.issue.StashPullRequest; +import org.sonar.plugins.stash.issue.StashDiffReport; +import org.sonar.plugins.stash.issue.StashPullRequest; +import org.sonar.plugins.stash.issue.StashTask; import org.sonar.plugins.stash.issue.StashUser; public class StashCollectorTest { @@ -17,7 +19,7 @@ public class StashCollectorTest { private static final long STASH_USER_ID = 1; @Test - public void testExtractSimpleComment() throws Exception { + public void testExtractCommentReport() throws Exception { String commentString = "{\"values\": [{\"id\":1234, \"text\":\"message\", \"anchor\": {\"path\":\"path\", \"line\":5}," + "\"author\": {\"id\":1, \"name\":\"SonarQube\", \"slug\":\"sonarqube\", \"email\":\"sq@email.com\"}, \"version\":0}]}"; StashCommentReport commentReport = StashCollector.extractComments(commentString); @@ -34,7 +36,7 @@ public void testExtractSimpleComment() throws Exception { } @Test - public void testExtractCommentList() throws Exception { + public void testExtractCommentReportWithSeveralComment() throws Exception { String commentString = "{\"values\": [" + "{\"id\":1234, \"text\":\"message1\", \"anchor\": {\"path\":\"path1\", \"line\":1}," + "\"author\": {\"id\":1, \"name\":\"SonarQube\", \"slug\":\"sonarqube\", \"email\":\"sq@email.com\"}, \"version\":1}, " @@ -63,13 +65,58 @@ public void testExtractCommentList() throws Exception { } @Test - public void testExtractEmptyComment() throws Exception { + public void testExtractEmptyCommentReport() throws Exception { String commentString = "{\"values\": []}"; StashCommentReport commentReport = StashCollector.extractComments(commentString); assertEquals(commentReport.size(), 0); } + @Test + public void testExtractComment() throws Exception { + String commentString = "{\"id\":1234, \"text\":\"message\", \"anchor\": {\"path\":\"path\", \"line\":5}," + + "\"author\": {\"id\":1, \"name\":\"SonarQube\", \"slug\":\"sonarqube\", \"email\":\"sq@email.com\"}, \"version\":0}"; + + StashComment comment = StashCollector.extractComment(commentString); + + assertEquals(comment.getId(), 1234); + assertEquals(comment.getMessage(), "message"); + assertEquals(comment.getPath(), "path"); + assertEquals(comment.getVersion(), 0); + assertEquals(comment.getAuthor().getId(), STASH_USER_ID); + assertEquals(comment.getLine(), 5); + } + + @Test + public void testExtractEmptyCommentWithNoAnchor() { + String commentString = "{\"id\":1234, \"text\":\"message\", " + + "\"author\": {\"id\":1, \"name\":\"SonarQube\", \"slug\":\"sonarqube\", \"email\":\"sq@email.com\"}, \"version\":0}"; + + try { + StashCollector.extractComment(commentString); + + assertFalse("No anchor tag: extraction should raised StashReportExtractionException exception", true); + + } catch (StashReportExtractionException e) { + assertTrue("No anchor tag: extraction has raised StashReportExtractionException exception as expected", true); + } + } + + @Test + public void testExtractCommentWithPathAndLineAsParameters() throws Exception { + String commentString = "{\"id\":1234, \"text\":\"message\", \"anchor\": {\"path\":\"path\", \"line\":5}," + + "\"author\": {\"id\":1, \"name\":\"SonarQube\", \"slug\":\"sonarqube\", \"email\":\"sq@email.com\"}, \"version\":0}"; + + StashComment comment = StashCollector.extractComment(commentString, "pathAsParameter", (long) 1111); + + assertEquals(comment.getId(), 1234); + assertEquals(comment.getMessage(), "message"); + assertEquals(comment.getPath(), "pathAsParameter"); + assertEquals(comment.getVersion(), 0); + assertEquals(comment.getAuthor().getId(), STASH_USER_ID); + assertEquals(comment.getLine(), 1111); + } + @Test public void testIsLastPage() throws Exception { String jsonBody = "{\"isLastPage\": true}"; @@ -110,6 +157,16 @@ public void testExtractDiffsWithBaseReport() throws Exception { assertEquals(comment1.getMessage(), "Test comment"); assertEquals(comment1.getVersion(), 1); + StashTask task1 = comment1.getTasks().get(0); + assertEquals(12345, (long) task1.getId()); + assertEquals("Complete the task associated to this TODO comment.", task1.getText()); + assertEquals("OPENED", task1.getState()); + + StashTask task2 = comment1.getTasks().get(1); + assertEquals(54321, (long) task2.getId()); + assertEquals("Complete the task associated to this TODO comment.", task2.getText()); + assertEquals("OPENED", task2.getState()); + StashUser author1 = comment1.getAuthor(); assertEquals(author1.getId(), 12345); assertEquals(author1.getName(), "SonarQube"); @@ -470,4 +527,39 @@ public void testExtractUser() throws Exception { assertEquals(user.getSlug(), userSlug); assertEquals(user.getEmail(), userEmail); } + + @Test + public void testExtractTask() throws Exception { + long id = 1111; + String text = "Text"; + String state = "State"; + boolean deletable = true; + + String jsonTask = "{ \"id\":" + id + ", \"text\":\"" + text + "\", \"state\":\"" + state + "\"," + + "\"permittedOperations\": { \"deletable\":" + deletable + "}}"; + + StashTask task = StashCollector.extractTask(jsonTask); + + assertEquals(id, (long) task.getId()); + assertEquals(text, task.getText()); + assertEquals(state, task.getState()); + assertEquals(deletable, task.isDeletable()); + } + + @Test + public void testExtractTaskWithoutPermittedOperation() throws Exception { + long id = 1111; + String text = "Text"; + String state = "State"; + + String jsonTask = "{ \"id\":" + id + ", \"text\":\"" + text + "\", \"state\": \"" + state + "\"}"; + + StashTask task = StashCollector.extractTask(jsonTask); + + assertEquals(id, (long) task.getId()); + assertEquals(text, task.getText()); + assertEquals(state, task.getState()); + assertEquals(true, task.isDeletable()); + } + }