diff --git a/src/main/java/org/sonar/plugins/stash/StashIssueReportingPostJob.java b/src/main/java/org/sonar/plugins/stash/StashIssueReportingPostJob.java index 6d70d372..a918669c 100755 --- a/src/main/java/org/sonar/plugins/stash/StashIssueReportingPostJob.java +++ b/src/main/java/org/sonar/plugins/stash/StashIssueReportingPostJob.java @@ -46,8 +46,17 @@ public void executeOn(Project project, SensorContext context) { String stashURL = stashRequestFacade.getStashURL(); String stashProject = stashRequestFacade.getStashProject(); String repository = stashRequestFacade.getStashRepository(); + String stashPullRequestId = stashRequestFacade.getStashPullRequestId(); - + String stashCommitId = stashRequestFacade.getStashCommitId(); + + if (stashPullRequestId == null && stashCommitId == null) { + throw new StashConfigurationException("Must specify either Commit ID or Pull Reuquest ID"); + } + if (stashPullRequestId != null && stashCommitId != null) { + throw new StashConfigurationException("Cannot specify both Commit ID and Pull Reuquest ID"); + } + int stashTimeout = config.getStashTimeout(); StashCredentials stashCredentials = stashRequestFacade.getCredentials(); @@ -58,39 +67,53 @@ public void executeOn(Project project, SensorContext context) { LOGGER.error("Process stopped: no SonarQube reviewer identified to publish to Stash the SQ analysis"); } else { - - // Get all changes exposed from Stash differential view of the pull-request - StashDiffReport diffReport = stashRequestFacade.getPullRequestDiffReport(stashProject, repository, stashPullRequestId, stashClient); - if (diffReport == null) { - LOGGER.error("Process stopped: No Stash differential report available to process the SQ analysis"); - } else { - - // if requested, reset all comments linked to the pull-request - if (config.resetComments()) { - stashRequestFacade.resetComments(stashProject, repository, stashPullRequestId, diffReport, stashUser, stashClient); - } - - boolean canApprovePullrequest = config.canApprovePullRequest(); - if (canApprovePullrequest) { - stashRequestFacade.addPullRequestReviewer(stashProject, repository, stashPullRequestId, stashCredentials.getLogin(), stashClient); - } - - // if threshold exceeded, do not push issue list to Stash - if (issueReport.countIssues() >= issueThreshold) { - LOGGER.warn("Too many issues detected ({}/{}): Issues cannot be displayed in Diff view", issueReport.countIssues(), issueThreshold); + if (stashPullRequestId == null) { + // Get all changes exposed from Stash differential view of the commit + StashDiffReport diffReport = stashRequestFacade.getCommitDiffReport(stashProject, repository, stashCommitId, stashClient); + if (diffReport == null) { + LOGGER.error("Process stopped: No Stash differential report available to process the SQ analysis"); } else { - stashRequestFacade.postCommentPerIssue(stashProject, repository, stashPullRequestId, sonarQubeURL, issueReport, diffReport, stashClient); + if (issueReport.countIssues() >= issueThreshold) { + LOGGER.warn("Too many issues detected ({}/{}): Issues cannot be displayed in Diff view", issueReport.countIssues(), issueThreshold); + } else { + stashRequestFacade.postCommitCommentPerIssue(stashProject, repository, stashCommitId, sonarQubeURL, issueReport, diffReport, stashClient); + } + stashRequestFacade.postCommitAnalysisOverview(stashProject, repository, stashCommitId, sonarQubeURL, issueThreshold, issueReport, stashClient); } - - stashRequestFacade.postAnalysisOverview(stashProject, repository, stashPullRequestId, sonarQubeURL, issueThreshold, issueReport, stashClient); - - if (canApprovePullrequest) { - - // if no new issues, plugin approves the pull-request - if (issueReport.countIssues() == 0) { - stashRequestFacade.approvePullRequest(stashProject, repository, stashPullRequestId, stashCredentials.getLogin(), stashClient); + } + else { + // Get all changes exposed from Stash differential view of the pull-request + StashDiffReport diffReport = stashRequestFacade.getPullRequestDiffReport(stashProject, repository, stashPullRequestId, stashClient); + if (diffReport == null) { + LOGGER.error("Process stopped: No Stash differential report available to process the SQ analysis"); + } else { + + // if requested, reset all comments linked to the pull-request + if (config.resetComments()) { + stashRequestFacade.resetComments(stashProject, repository, stashPullRequestId, diffReport, stashUser, stashClient); + } + + boolean canApprovePullrequest = config.canApprovePullRequest(); + if (canApprovePullrequest) { + stashRequestFacade.addPullRequestReviewer(stashProject, repository, stashPullRequestId, stashCredentials.getLogin(), stashClient); + } + + // if threshold exceeded, do not push issue list to Stash + if (issueReport.countIssues() >= issueThreshold) { + LOGGER.warn("Too many issues detected ({}/{}): Issues cannot be displayed in Diff view", issueReport.countIssues(), issueThreshold); } else { - stashRequestFacade.resetPullRequestApproval(stashProject, repository, stashPullRequestId, stashCredentials.getLogin(), stashClient); + stashRequestFacade.postCommentPerIssue(stashProject, repository, stashPullRequestId, sonarQubeURL, issueReport, diffReport, stashClient); + } + stashRequestFacade.postAnalysisOverview(stashProject, repository, stashPullRequestId, sonarQubeURL, issueThreshold, issueReport, stashClient); + + if (canApprovePullrequest) { + + // if no new issues, plugin approves the pull-request + if (issueReport.countIssues() == 0) { + stashRequestFacade.approvePullRequest(stashProject, repository, stashPullRequestId, stashCredentials.getLogin(), stashClient); + } else { + stashRequestFacade.resetPullRequestApproval(stashProject, repository, stashPullRequestId, stashCredentials.getLogin(), stashClient); + } } } } diff --git a/src/main/java/org/sonar/plugins/stash/StashPlugin.java b/src/main/java/org/sonar/plugins/stash/StashPlugin.java index a683bbd7..d47ed104 100755 --- a/src/main/java/org/sonar/plugins/stash/StashPlugin.java +++ b/src/main/java/org/sonar/plugins/stash/StashPlugin.java @@ -38,6 +38,7 @@ public class StashPlugin extends SonarPlugin { public static final String STASH_PROJECT = "sonar.stash.project"; public static final String STASH_REPOSITORY = "sonar.stash.repository"; public static final String STASH_PULL_REQUEST_ID = "sonar.stash.pullrequest.id"; + public static final String STASH_COMMIT_ID = "sonar.stash.commit.id"; public static final String STASH_RESET_COMMENTS = "sonar.stash.comments.reset"; public static final String STASH_URL = "sonar.stash.url"; public static final String STASH_LOGIN = "sonar.stash.login"; @@ -46,7 +47,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"; + public static final String STASH_TASK_SEVERITY_THRESHOLD = "sonar.stash.task.issue.severity.threshold"; @Override public List getExtensions() { @@ -85,15 +86,15 @@ public List getExtensions() { .description("Threshold to limit the number of issues pushed to Stash server") .subCategory(CONFIG_PAGE_SUB_CATEGORY_STASH) .onQualifiers(Qualifiers.PROJECT) - .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) + .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 c2e251ce..6ab634af 100755 --- a/src/main/java/org/sonar/plugins/stash/StashPluginConfiguration.java +++ b/src/main/java/org/sonar/plugins/stash/StashPluginConfiguration.java @@ -29,6 +29,9 @@ public String getPullRequestId() { return settings.getString(StashPlugin.STASH_PULL_REQUEST_ID); } + public String getCommitId() { + return settings.getString(StashPlugin.STASH_COMMIT_ID); + } public String getStashURL() { return settings.getString(StashPlugin.STASH_URL); } @@ -64,4 +67,4 @@ public boolean resetComments() { 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 a6f83766..e4a264e5 100755 --- a/src/main/java/org/sonar/plugins/stash/StashRequestFacade.java +++ b/src/main/java/org/sonar/plugins/stash/StashRequestFacade.java @@ -65,6 +65,24 @@ public void postAnalysisOverview(String project, String repository, String pullR } } + /** + * Post SQ analysis overview on Stash + */ + public void postCommitAnalysisOverview(String project, String repository, String commitId, String sonarQubeURL, int issueThreshold, SonarQubeIssuesReport issueReport, StashClient stashClient){ + try { + stashClient.postCommentOnCommit(project, + repository, + commitId, + MarkdownPrinter.printReportMarkdown(issueReport, sonarQubeURL, issueThreshold)); + + LOGGER.info("SonarQube analysis overview has been reported to Stash."); + + } catch(StashClientException e){ + LOGGER.error("Unable to push SonarQube analysis overview to Stash: {}", e.getMessage()); + LOGGER.debug("Exception stack trace", e); + } + } + /** * Approve pull-request */ @@ -118,6 +136,73 @@ public void addPullRequestReviewer(String project, String repository, String pul } } + /** + * Post one comment on a commit by found issue on Stash. + */ + public void postCommitCommentPerIssue(String project, String repository, String commitId, String sonarQubeURL, SonarQubeIssuesReport issueReport, StashDiffReport diffReport, StashClient stashClient){ + try { + // to optimize request to Stash, builds comment match ordered by filepath + Map commentsByFile = new HashMap<>(); + for (SonarQubeIssue issue : issueReport.getIssues()) { + if (commentsByFile.get(issue.getPath()) == null){ + StashCommentReport comments = stashClient.getCommitComments(project, repository, commitId, issue.getPath()); + + // According to the type of the comment + // if type == CONTEXT, comment.line is set to source line instead of destination line + comments.applyDiffReport(diffReport); + + commentsByFile.put(issue.getPath(), comments); + } + } + + // Severity available to create a task + List taskSeverities = getReportedSeverities(); + + for (SonarQubeIssue issue : issueReport.getIssues()) { + StashCommentReport comments = commentsByFile.get(issue.getPath()); + + // if comment not already pushed to Stash + if ((comments != null) && + (comments.contains(MarkdownPrinter.printIssueMarkdown(issue, sonarQubeURL), issue.getPath(), issue.getLine()))) { + LOGGER.debug("Comment \"{}\" already pushed on file {} ({})", issue.getRule(), issue.getPath(), issue.getLine()); + } else { + + // check if issue belongs to the Stash diff view + String type = diffReport.getType(issue.getPath(), issue.getLine()); + if (type == null){ + LOGGER.info("Comment \"{}\" cannot be pushed to Stash like it does not belong to diff view - {} (line: {})", issue.getRule(), issue.getPath(), issue.getLine()); + } else{ + + long line = diffReport.getLine(issue.getPath(), issue.getLine()); + + StashComment comment = stashClient.postCommentLineOnCommit(project, + repository, + commitId, + 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()); + } + } + } + } + + LOGGER.info("New SonarQube issues have been reported to Stash."); + + } catch (StashClientException e){ + LOGGER.error("Unable to link SonarQube issues to Stash: {}", e.getMessage()); + LOGGER.debug("Exception stack trace", e); + } + } + /** * Post one comment by found issue on Stash. */ @@ -243,16 +328,19 @@ public String getStashRepository() throws StashConfigurationException { } /** - * Mandatory Stash pull-request ID option. + * Stash pull-request ID option. Must specify this or commit ID * @throws StashConfigurationException if unable to get parameter */ - public String getStashPullRequestId() throws StashConfigurationException { - String result = config.getPullRequestId(); - if (result == null){ - throw new StashConfigurationException("Unable to get " + StashPlugin.STASH_PULL_REQUEST_ID + ": value is null"); - } - - return result; + public String getStashPullRequestId() { + return config.getPullRequestId(); + } + + /** + * Stash commit ID option. Must specify this or pull request ID + * @throws StashConfigurationException if unable to get parameter + */ + public String getStashCommitId() { + return config.getCommitId(); } /** @@ -293,6 +381,25 @@ public StashDiffReport getPullRequestDiffReport(String project, String repositor return result; } + /** + * Get all changes exposed through the Stash commit. + */ + public StashDiffReport getCommitDiffReport(String project, String repository, String commitId, StashClient stashClient){ + StashDiffReport result = null; + + try { + result = stashClient.getCommitDiffs(project, repository, commitId); + + LOGGER.debug("Stash differential report retrieved from commit {} #{}", repository, commitId); + + } catch(StashClientException e){ + LOGGER.error("Unable to get Stash differential report from Stash: {}", e.getMessage()); + LOGGER.debug("Exception stack trace", e); + } + + return result; + } + /** * Reset all comments linked to a pull-request. */ 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 8b9c3027..689ad3af 100755 --- a/src/main/java/org/sonar/plugins/stash/client/StashClient.java +++ b/src/main/java/org/sonar/plugins/stash/client/StashClient.java @@ -47,7 +47,12 @@ public class StashClient implements AutoCloseable { 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 COMMITS_API = REPO_API + "commits/"; + private static final String COMMIT_API = COMMITS_API + "{3}"; + private static final String COMMENTS_COMMIT_API = COMMIT_API + "/comments"; + private static final String DIFF_COMMIT_API = COMMIT_API + "/diff"; + private static final String PULL_REQUEST_APPROVAL_POST_ERROR_MESSAGE = "Unable to change status of pull-request {0} #{1}."; private static final String PULL_REQUEST_GET_ERROR_MESSAGE = "Unable to retrieve pull-request {0} #{1}."; private static final String PULL_REQUEST_PUT_ERROR_MESSAGE = "Unable to update pull-request {0} #{1}."; @@ -102,6 +107,31 @@ public StashCommentReport getPullRequestComments(String project, String reposito return result; } + public StashCommentReport getCommitComments(String project, String repository, String commitId, String path) + throws StashClientException { + StashCommentReport result = new StashCommentReport(); + + AsyncHttpClient httpClient = createHttpClient(); + + long start = 0; + boolean isLastPage = false; + + while (! isLastPage){ + try { + String request = MessageFormat.format(COMMENTS_COMMIT_API + "?path={4}&start={5}", baseUrl + REST_API, project, repository, commitId, path, start); + String response = get(request, MessageFormat.format(COMMENT_GET_ERROR_MESSAGE, repository, commitId)); + result.add(StashCollector.extractComments(response)); + // Stash pagination: check if you get all comments linked to the pull-request + isLastPage = StashCollector.isLastPage(response); + start = StashCollector.getNextPageStart(response); + } catch (StashReportExtractionException e) { + throw new StashClientException(e); + } + } + + return result; + } + public void deletePullRequestComment(String project, String repository, String pullRequestId, StashComment comment) throws StashClientException { @@ -126,8 +156,19 @@ public StashDiffReport getPullRequestDiffs(String project, String repository, St } return result; + } + + public StashDiffReport getCommitDiffs(String project, String repository, String commitId) + throws StashClientException { + try { + String request = MessageFormat.format(DIFF_COMMIT_API + "?withComments=true", baseUrl + REST_API, project, repository, commitId); + String response = get(request, MessageFormat.format(COMMENT_GET_ERROR_MESSAGE, repository, commitId)); + return StashCollector.extractDiffs(response); + } catch (StashReportExtractionException e) { + throw new StashClientException(e); + } } - + public StashComment postCommentLineOnPullRequest(String project, String repository, String pullRequestId, String message, String path, long line, String type) throws StashClientException { String request = MessageFormat.format(COMMENTS_PULL_REQUEST_API, baseUrl + REST_API, project, repository, @@ -156,7 +197,48 @@ public StashComment postCommentLineOnPullRequest(String project, String reposito throw new StashClientException(e); } } + + public void postCommentOnCommit(String project, String repository, String commitId, String report) + throws StashClientException { + String request = MessageFormat.format(COMMENTS_COMMIT_API, baseUrl + REST_API, project, repository, commitId); + JSONObject json = new JSONObject(); + json.put("text", report); + + postCreate(request, json, MessageFormat.format(COMMENT_POST_ERROR_MESSAGE, repository, commitId)); + } + + public StashComment postCommentLineOnCommit(String project, String repository, String commitId, String message, String path, long line, String type) + throws StashClientException { + String request = MessageFormat.format(COMMENTS_COMMIT_API, baseUrl + REST_API, project, repository, + commitId); + + JSONObject anchor = new JSONObject(); + anchor.put("line", line); + anchor.put("lineType", type); + + String fileType = "TO"; + if (StringUtils.equals(type, StashPlugin.CONTEXT_ISSUE_TYPE)){ + fileType = "FROM"; + } + anchor.put("fileType", fileType); + + anchor.put("path", path); + + JSONObject json = new JSONObject(); + json.put("text", message); + json.put("anchor", anchor); + + String response = postCreate(request, json, + MessageFormat.format(COMMENT_POST_ERROR_MESSAGE, repository, commitId)); + + try { + return StashCollector.extractComment(response, path, line); + } catch (StashReportExtractionException e) { + throw new StashClientException(e); + } + } + public StashUser getUser(String userSlug) throws StashClientException { String request = MessageFormat.format(USER_API, baseUrl + REST_API, userSlug); diff --git a/src/test/java/org/sonar/plugins/stash/StashIssueReportingPostJobTest.java b/src/test/java/org/sonar/plugins/stash/StashIssueReportingPostJobTest.java index 82ed78b1..de6765a9 100755 --- a/src/test/java/org/sonar/plugins/stash/StashIssueReportingPostJobTest.java +++ b/src/test/java/org/sonar/plugins/stash/StashIssueReportingPostJobTest.java @@ -93,37 +93,37 @@ public void setUp() throws Exception { when(stashRequestFacade.getStashProject()).thenReturn(STASH_PROJECT); when(stashRequestFacade.getStashRepository()).thenReturn(STASH_REPOSITORY); when(stashRequestFacade.getStashPullRequestId()).thenReturn(STASH_PULLREQUEST_ID); - when(stashRequestFacade.getCredentials()).thenReturn(new StashCredentials(STASH_LOGIN, STASH_PASSWORD)); + when(stashRequestFacade.getCredentials()).thenReturn(new StashCredentials(STASH_LOGIN, STASH_PASSWORD)); when(stashRequestFacade.getSonarQubeReviewer(Mockito.anyString(), (StashClient) Mockito.anyObject())).thenReturn(stashUser); - when(stashRequestFacade.getPullRequestDiffReport(eq(STASH_PROJECT), eq(STASH_REPOSITORY), eq(STASH_PULLREQUEST_ID), (StashClient) Mockito.anyObject())).thenReturn(diffReport); - when(stashRequestFacade.getIssueThreshold()).thenReturn(STASH_ISSUE_THRESHOLD); + when(stashRequestFacade.getPullRequestDiffReport(eq(STASH_PROJECT), eq(STASH_REPOSITORY), eq(STASH_PULLREQUEST_ID), (StashClient) Mockito.anyObject())).thenReturn(diffReport); + when(stashRequestFacade.getIssueThreshold()).thenReturn(STASH_ISSUE_THRESHOLD); } @Test - public void testExecuteOn() throws Exception { + public void testExecuteOn() throws Exception { myJob = new StashIssueReportingPostJob(config, projectIssues, inputFileCache, stashRequestFacade); myJob.executeOn(project, context); verify(stashRequestFacade, times(0)).resetComments(eq(STASH_PROJECT), eq(STASH_REPOSITORY), eq(STASH_PULLREQUEST_ID), eq(diffReport), eq(stashUser), (StashClient) Mockito.anyObject()); verify(stashRequestFacade, times(1)).postCommentPerIssue(eq(STASH_PROJECT), eq(STASH_REPOSITORY), eq(STASH_PULLREQUEST_ID), eq(SONARQUBE_URL), eq(sqReport), eq(diffReport), (StashClient) Mockito.anyObject()); - verify(stashRequestFacade, times(1)).postAnalysisOverview(eq(STASH_PROJECT), eq(STASH_REPOSITORY), eq(STASH_PULLREQUEST_ID), eq(SONARQUBE_URL), eq(STASH_ISSUE_THRESHOLD), eq(sqReport), (StashClient) Mockito.anyObject()); + verify(stashRequestFacade, times(1)).postAnalysisOverview(eq(STASH_PROJECT), eq(STASH_REPOSITORY), eq(STASH_PULLREQUEST_ID), eq(SONARQUBE_URL), eq(STASH_ISSUE_THRESHOLD), eq(sqReport), (StashClient) Mockito.anyObject()); verify(stashRequestFacade, times(0)).approvePullRequest(eq(STASH_PROJECT), eq(STASH_REPOSITORY), eq(STASH_PULLREQUEST_ID), eq(STASH_LOGIN), (StashClient) Mockito.anyObject()); verify(stashRequestFacade, times(0)).resetPullRequestApproval(eq(STASH_PROJECT), eq(STASH_REPOSITORY), eq(STASH_PULLREQUEST_ID), eq(STASH_LOGIN), (StashClient) Mockito.anyObject()); } @Test - public void testExecuteOnWithReachedThreshold() throws Exception { + public void testExecuteOnWithReachedThreshold() throws Exception { when(stashRequestFacade.getIssueThreshold()).thenReturn(100); - + SonarQubeIssuesReport report = mock(SonarQubeIssuesReport.class); when(report.countIssues()).thenReturn(101); when(stashRequestFacade.extractIssueReport(projectIssues, inputFileCache)).thenReturn(report); myJob = new StashIssueReportingPostJob(config, projectIssues, inputFileCache, stashRequestFacade); myJob.executeOn(project, context); - + verify(stashRequestFacade, times(0)).resetComments(eq(STASH_PROJECT), eq(STASH_REPOSITORY), eq(STASH_PULLREQUEST_ID), eq(diffReport), eq(stashUser), (StashClient) Mockito.anyObject()); - verify(stashRequestFacade, times(0)).postCommentPerIssue(eq(STASH_PROJECT), eq(STASH_REPOSITORY), eq(STASH_PULLREQUEST_ID), eq(SONARQUBE_URL), eq(report), eq(diffReport), (StashClient) Mockito.anyObject()); + verify(stashRequestFacade, times(0)).postCommentPerIssue(eq(STASH_PROJECT), eq(STASH_REPOSITORY), eq(STASH_PULLREQUEST_ID), eq(SONARQUBE_URL), eq(report), eq(diffReport), (StashClient) Mockito.anyObject()); verify(stashRequestFacade, times(1)).postAnalysisOverview(eq(STASH_PROJECT), eq(STASH_REPOSITORY), eq(STASH_PULLREQUEST_ID), eq(SONARQUBE_URL), eq(STASH_ISSUE_THRESHOLD), eq(report), (StashClient) Mockito.anyObject()); } @@ -147,7 +147,7 @@ public void testExecuteOnWithNoStashUserDefined() throws Exception { myJob = new StashIssueReportingPostJob(config, projectIssues, inputFileCache, stashRequestFacade); myJob.executeOn(project, context); - + verify(stashRequestFacade, times(0)).resetComments(eq(STASH_PROJECT), eq(STASH_REPOSITORY), eq(STASH_PULLREQUEST_ID), eq(diffReport), eq(stashUser), (StashClient) Mockito.anyObject()); verify(stashRequestFacade, times(0)).postCommentPerIssue(eq(STASH_PROJECT), eq(STASH_REPOSITORY), eq(STASH_PULLREQUEST_ID), eq(SONARQUBE_URL), eq(sqReport), eq(diffReport), (StashClient) Mockito.anyObject()); verify(stashRequestFacade, times(0)).postAnalysisOverview(eq(STASH_PROJECT), eq(STASH_REPOSITORY), eq(STASH_PULLREQUEST_ID), eq(SONARQUBE_URL), eq(STASH_ISSUE_THRESHOLD), eq(sqReport), (StashClient) Mockito.anyObject()); @@ -230,6 +230,6 @@ public void testExecuteOnWithoutPullRequestApproval() throws Exception { verify(stashRequestFacade, times(1)).postCommentPerIssue(eq(STASH_PROJECT), eq(STASH_REPOSITORY), eq(STASH_PULLREQUEST_ID), eq(SONARQUBE_URL), eq(report), eq(diffReport), (StashClient) Mockito.anyObject()); verify(stashRequestFacade, times(1)).postAnalysisOverview(eq(STASH_PROJECT), eq(STASH_REPOSITORY), eq(STASH_PULLREQUEST_ID), eq(SONARQUBE_URL), eq(STASH_ISSUE_THRESHOLD), eq(report), (StashClient) Mockito.anyObject()); verify(stashRequestFacade, times(0)).approvePullRequest(eq(STASH_PROJECT), eq(STASH_REPOSITORY), eq(STASH_PULLREQUEST_ID), eq(STASH_LOGIN), (StashClient) Mockito.anyObject()); - verify(stashRequestFacade, times(0)).resetPullRequestApproval(eq(STASH_PROJECT), eq(STASH_REPOSITORY), eq(STASH_PULLREQUEST_ID), eq(STASH_LOGIN), (StashClient) Mockito.anyObject()); + verify(stashRequestFacade, times(0)).resetPullRequestApproval(eq(STASH_PROJECT), eq(STASH_REPOSITORY), eq(STASH_PULLREQUEST_ID), eq(STASH_LOGIN), (StashClient) Mockito.anyObject()); } } diff --git a/src/test/java/org/sonar/plugins/stash/StashRequestFacadeTest.java b/src/test/java/org/sonar/plugins/stash/StashRequestFacadeTest.java index ba98bc84..b07bd977 100755 --- a/src/test/java/org/sonar/plugins/stash/StashRequestFacadeTest.java +++ b/src/test/java/org/sonar/plugins/stash/StashRequestFacadeTest.java @@ -79,6 +79,7 @@ public class StashRequestFacadeTest { private static final String STASH_PROJECT = "Project"; private static final String STASH_REPOSITORY = "Repository"; private static final String STASH_PULLREQUEST_ID = "1"; + private static final String STASH_COMMIT_ID = "2"; private static final String STASH_DIFF_TYPE = "StashDiffType"; private static final String STASH_USER = "SonarQube"; @@ -130,6 +131,7 @@ public void setUp() throws Exception { 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(stashClient.postCommentLineOnCommit(STASH_PROJECT, STASH_REPOSITORY, STASH_COMMIT_ID, stashCommentMessage1, FILE_PATH_1, 1, STASH_DIFF_TYPE)).thenReturn(comment1); when(comment1.getTasks()).thenReturn(taskList1); when(comment1.containsPermanentTasks()).thenReturn(false); @@ -143,6 +145,7 @@ public void setUp() throws Exception { 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(stashClient.postCommentLineOnCommit(STASH_PROJECT, STASH_REPOSITORY, STASH_COMMIT_ID, stashCommentMessage2, FILE_PATH_1, 2, STASH_DIFF_TYPE)).thenReturn(comment2); when(comment2.getTasks()).thenReturn(taskList2); when(comment2.containsPermanentTasks()).thenReturn(false); @@ -156,6 +159,7 @@ public void setUp() throws Exception { 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(stashClient.postCommentLineOnCommit(STASH_PROJECT, STASH_REPOSITORY, STASH_COMMIT_ID, stashCommentMessage3, FILE_PATH_2, 1, STASH_DIFF_TYPE)).thenReturn(comment3); when(comment3.getTasks()).thenReturn(taskList3); when(comment3.containsPermanentTasks()).thenReturn(false); @@ -170,11 +174,13 @@ public void setUp() throws Exception { when(stashCommentsReport1.getComments()).thenReturn(comments); when(stashCommentsReport1.applyDiffReport(diffReport)).thenReturn(stashCommentsReport1); when(stashClient.getPullRequestComments(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, FILE_PATH_1)).thenReturn(stashCommentsReport1); + when(stashClient.getCommitComments(STASH_PROJECT, STASH_REPOSITORY, STASH_COMMIT_ID, FILE_PATH_1)).thenReturn(stashCommentsReport1); stashCommentsReport2 = mock(StashCommentReport.class); 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); + when(stashClient.getCommitComments(STASH_PROJECT, STASH_REPOSITORY, STASH_COMMIT_ID, FILE_PATH_2)).thenReturn(stashCommentsReport2); 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()); @@ -254,10 +260,22 @@ public void testGetStashPullRequestId() throws StashConfigurationException { assertEquals(myFacade.getStashPullRequestId(), "12345"); } - @Test (expected = StashConfigurationException.class) - public void testGetStashPullRequestIdThrowsException() throws StashConfigurationException { + @Test + public void testGetStashPullRequestIdNull() throws StashConfigurationException { + when(config.getPullRequestId()).thenReturn(null); + assertEquals(myFacade.getStashPullRequestId(), null); + } + + @Test + public void testGetStashCommitId() throws StashConfigurationException { + when(config.getCommitId()).thenReturn("12345"); + assertEquals(myFacade.getStashCommitId(), "12345"); + } + + @Test + public void testGetStashiCommitIdNull() throws StashConfigurationException { when(config.getPullRequestId()).thenReturn(null); - myFacade.getStashPullRequestId(); + assertEquals(myFacade.getStashCommitId(), null); } @Test @@ -273,6 +291,19 @@ public void testPostCommentPerIssue() throws Exception{ verify(stashClient, times(1)).postCommentLineOnPullRequest(STASH_PROJECT, STASH_REPOSITORY, STASH_PULLREQUEST_ID, stashCommentMessage3, FILE_PATH_2, 1, STASH_DIFF_TYPE); } + @Test + public void testPostCommitCommentPerIssue() throws Exception{ + when(stashCommentsReport1.contains(stashCommentMessage1, FILE_PATH_1, 1)).thenReturn(true); + when(stashCommentsReport1.contains(stashCommentMessage2, FILE_PATH_1, 2)).thenReturn(false); + when(stashCommentsReport2.contains(stashCommentMessage3, FILE_PATH_2, 1)).thenReturn(false); + + myFacade.postCommitCommentPerIssue(STASH_PROJECT, STASH_REPOSITORY, STASH_COMMIT_ID, SONARQUBE_URL, issueReport, diffReport, stashClient); + + verify(stashClient, times(0)).postCommentLineOnCommit(STASH_PROJECT, STASH_REPOSITORY, STASH_COMMIT_ID, stashCommentMessage1, FILE_PATH_1, 1, STASH_DIFF_TYPE); + verify(stashClient, times(1)).postCommentLineOnCommit(STASH_PROJECT, STASH_REPOSITORY, STASH_COMMIT_ID, stashCommentMessage2, FILE_PATH_1, 2, STASH_DIFF_TYPE); + verify(stashClient, times(1)).postCommentLineOnCommit(STASH_PROJECT, STASH_REPOSITORY, STASH_COMMIT_ID, stashCommentMessage3, FILE_PATH_2, 1, STASH_DIFF_TYPE); + } + @Test public void testPostCommentPerIssueWithNoStashCommentAlreadyPushed() throws Exception{ when(stashCommentsReport1.contains(stashCommentMessage1, FILE_PATH_1, 1)).thenReturn(true); @@ -301,6 +332,21 @@ public void testPostTaskOnComment() throws Exception { verify(stashClient, times(1)).postTaskOnComment("message1", (long) 1111); } + @Test + public void testPostTaskOnCommitComment() throws Exception { + when(config.getTaskIssueSeverityThreshold()).thenReturn(Severity.INFO); + + myFacade.postCommitCommentPerIssue(STASH_PROJECT, STASH_REPOSITORY, STASH_COMMIT_ID, SONARQUBE_URL, issueReport, diffReport, stashClient); + + verify(stashClient, times(1)).postCommentLineOnCommit(STASH_PROJECT, STASH_REPOSITORY, STASH_COMMIT_ID, stashCommentMessage1, FILE_PATH_1, 1, STASH_DIFF_TYPE); + verify(stashClient, times(1)).postCommentLineOnCommit(STASH_PROJECT, STASH_REPOSITORY, STASH_COMMIT_ID, stashCommentMessage2, FILE_PATH_1, 2, STASH_DIFF_TYPE); + verify(stashClient, times(1)).postCommentLineOnCommit(STASH_PROJECT, STASH_REPOSITORY, STASH_COMMIT_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); 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 e756680a..60a92f7f 100755 --- a/src/test/java/org/sonar/plugins/stash/client/StashClientTest.java +++ b/src/test/java/org/sonar/plugins/stash/client/StashClientTest.java @@ -73,7 +73,8 @@ public void setUp() throws Exception { when(httpClient.prepareGet(anyString())).thenReturn(requestBuilder); when(httpClient.prepareDelete(anyString())).thenReturn(requestBuilder); when(httpClient.preparePut(anyString())).thenReturn(requestBuilder); - + doNothing().when(httpClient).close(); + StashClient client = new StashClient("baseUrl", new StashCredentials("login", "password"), 1000); client.setHttpClient(httpClient); spyClient = spy(client); @@ -324,7 +325,7 @@ public void testGetUserWithException() throws Exception { spyClient.getUser("sonarqube"); assertFalse("Exception failure should be catched and convert to StashClientException", true); - + } catch (StashClientException e) { } }