diff --git a/src/main/java/pl/touk/sputnik/connector/stash/StashFacade.java b/src/main/java/pl/touk/sputnik/connector/stash/StashFacade.java index d8272dd1..753bc9c5 100644 --- a/src/main/java/pl/touk/sputnik/connector/stash/StashFacade.java +++ b/src/main/java/pl/touk/sputnik/connector/stash/StashFacade.java @@ -29,6 +29,7 @@ @Slf4j public class StashFacade implements ConnectorFacade { + private static final int FILE_COMMENT_LINE_POSITION = 0; private StashConnector stashConnector; private ObjectMapper objectMapper = new ObjectMapper(); private final Configuration configuration; @@ -150,14 +151,23 @@ SingleFileChanges changesForSingleFile(String filename) { String response = stashConnector.getDiffByLine(filename); List diffJsonList = JsonPath.read(response, "$.diffs[*].hunks[*].segments[*]"); List lineCommentJsonList = JsonPath.read(response, "$.diffs[*].lineComments[*]['text', 'id']"); + List fileCommentJsonList = JsonPath.read(response, "$.diffs[*].fileComments[*]['text', 'id']"); List segments = transform(diffJsonList, DiffSegment.class); List lineComments = transform(lineCommentJsonList, LineComment.class); + List fileComments = transform(fileCommentJsonList, LineComment.class); SingleFileChanges changes = SingleFileChanges.builder().filename(filename).build(); for (DiffSegment segment : segments) { for (LineSegment line : segment.lines) { changes.addChange(line.destination, ChangeType.valueOf(segment.type), getComment(lineComments, line.commentIds)); } } + if (!fileComments.isEmpty()) { + List comments = new ArrayList<>(); + for (LineComment lineComment : fileComments) { + comments.add(lineComment.text); + } + changes.addChange(FILE_COMMENT_LINE_POSITION, ChangeType.NONE, comments); + } return changes; } catch (URISyntaxException | IOException e) { throw new StashException("Error parsing json strings to objects", e); diff --git a/src/test/java/pl/touk/sputnik/connector/stash/StashFacadeTest.java b/src/test/java/pl/touk/sputnik/connector/stash/StashFacadeTest.java index e75474ba..aacc60b1 100644 --- a/src/test/java/pl/touk/sputnik/connector/stash/StashFacadeTest.java +++ b/src/test/java/pl/touk/sputnik/connector/stash/StashFacadeTest.java @@ -3,9 +3,13 @@ import com.github.tomakehurst.wiremock.junit.WireMockRule; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import junitparams.JUnitParamsRunner; +import junitparams.Parameters; +import junitparams.naming.TestCaseName; import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; import pl.touk.sputnik.HttpConnectorEnv; import pl.touk.sputnik.configuration.Configuration; import pl.touk.sputnik.configuration.ConfigurationSetup; @@ -18,6 +22,7 @@ import static com.github.tomakehurst.wiremock.client.WireMock.*; import static org.assertj.core.api.Assertions.assertThat; +@RunWith(JUnitParamsRunner.class) public class StashFacadeTest extends HttpConnectorEnv { private static String SOME_PULL_REQUEST_ID = "12314"; @@ -108,4 +113,29 @@ public void shouldSkipDeletedFiles() throws Exception { assertThat(files).extracting("reviewFilename").containsOnly("src/main/java/example/App2.java"); } + @Parameters({"/json/stash-diff-no-file-comments.json, 1", + "/json/stash-diff-with-file-comment.json, 0"}) + @TestCaseName("file comment should be send {2} time(s)") + @Test + public void fileComments(String diffFile, int expectedNumberOfCommentsSent) throws Exception { + String pullRequestResourceUrl = String.format("%s/rest/api/1.0/projects/%s/repos/%s/pull-requests/%s", + FacadeConfigUtil.PATH, SOME_PROJECT_KEY, SOME_REPOSITORY, SOME_PULL_REQUEST_ID); + stubGet(urlMatching(pullRequestResourceUrl + "/diff.*"), diffFile); + stubGet(urlEqualTo(pullRequestResourceUrl + "/changes"), "/json/stash-changes-for-file-violation.json"); + stubFor(post(urlEqualTo(pullRequestResourceUrl + "/comments")).willReturn(aResponse().withStatus(200))); + String filename = "src/main/java/com/example/app/Runner.java"; + Review review = new Review(ImmutableList.of(new ReviewFile(filename)), ReviewFormatterFactory.get(config)); + review.addError("Checkstyle", new Violation(filename, 0, "File does not end with a newline.", Severity.WARNING)); + review.getMessages().add("Total 1 violations found"); + + stashFacade.publish(review); + + verify(expectedNumberOfCommentsSent, postRequestedFor(urlEqualTo(pullRequestResourceUrl + "/comments")) + .withRequestBody(equalToJson("{\"text\":\"[Checkstyle] WARNING: File does not end with a newline.\"," + + "\"anchor\":{\"line\":0," + + "\"lineType\":\"CONTEXT\"," + + "\"fileType\":null," + + "\"path\":\"src/main/java/com/example/app/Runner.java\",\n" + + "\"srcPath\":\"src/main/java/com/example/app/Runner.java\"}}"))); + } } diff --git a/src/test/resources/json/stash-changes-for-file-violation.json b/src/test/resources/json/stash-changes-for-file-violation.json new file mode 100644 index 00000000..5ee4aaaf --- /dev/null +++ b/src/test/resources/json/stash-changes-for-file-violation.json @@ -0,0 +1,35 @@ +{ + "fromHash": "f18cca8d4070ad89c4d65bbcee1d74875113819f", + "toHash": "646afa05e6c3487eeceb91efb1adde1d568a0256", + "values": [ + { + "contentId": "e772f87e63e99dc933113accf2d973610929af6a", + "fromContentId": "11ccbe4b07de2e5eaa65fabfb58bfc8bbb32c98c", + "path": { + "components": [ + "src", + "main", + "java", + "com", + "example", + "app", + "Runner.java" + ], + "parent": "src/main/java/com/example/app", + "name": "Runner.java", + "extension": "java", + "toString": "src/main/java/com/example/app/Runner.java" + }, + "executable": false, + "percentUnchanged": -1, + "type": "MODIFY", + "nodeType": "FILE", + "srcExecutable": false + } + ], + "size": 1, + "isLastPage": true, + "start": 0, + "limit": 25, + "nextPageStart": null +} \ No newline at end of file diff --git a/src/test/resources/json/stash-diff-no-file-comments.json b/src/test/resources/json/stash-diff-no-file-comments.json new file mode 100644 index 00000000..c03c625d --- /dev/null +++ b/src/test/resources/json/stash-diff-no-file-comments.json @@ -0,0 +1,106 @@ +{ + "fromHash": "f18cca8d4070ad89c4d65bbcee1d74875113819f", + "toHash": "646afa05e6c3487eeceb91efb1adde1d568a0256", + "contextLines": 10, + "whitespace": "SHOW", + "diffs": [ + { + "source": { + "components": [ + "src", + "main", + "java", + "com", + "example", + "app", + "Runner.java" + ], + "parent": "src/main/java/com/example/app", + "name": "Runner.java", + "extension": "java", + "toString": "src/main/java/com/example/app/Runner.java" + }, + "destination": { + "components": [ + "src", + "main", + "java", + "com", + "example", + "app", + "Runner.java" + ], + "parent": "src/main/java/com/example/app", + "name": "Runner.java", + "extension": "java", + "toString": "src/main/java/com/example/app/Runner.java" + }, + "hunks": [ + { + "sourceLine": 1, + "sourceSpan": 5, + "destinationLine": 1, + "destinationSpan": 5, + "segments": [ + { + "type": "CONTEXT", + "lines": [ + { + "source": 1, + "destination": 1, + "line": "package com.example.app;", + "truncated": false + }, + { + "source": 2, + "destination": 2, + "line": "", + "truncated": false + }, + { + "source": 3, + "destination": 3, + "line": "public interface Runner {", + "truncated": false + }, + { + "source": 4, + "destination": 4, + "line": " void run();", + "truncated": false + } + ], + "truncated": false + }, + { + "type": "REMOVED", + "lines": [ + { + "source": 5, + "destination": 5, + "line": "}", + "truncated": false + } + ], + "truncated": false + }, + { + "type": "ADDED", + "lines": [ + { + "source": 6, + "destination": 5, + "line": "}", + "truncated": false + } + ], + "truncated": false + } + ], + "truncated": false + } + ], + "truncated": false + } + ] +} \ No newline at end of file diff --git a/src/test/resources/json/stash-diff-with-file-comment.json b/src/test/resources/json/stash-diff-with-file-comment.json new file mode 100644 index 00000000..57f5f797 --- /dev/null +++ b/src/test/resources/json/stash-diff-with-file-comment.json @@ -0,0 +1,131 @@ +{ + "fromHash": "f18cca8d4070ad89c4d65bbcee1d74875113819f", + "toHash": "646afa05e6c3487eeceb91efb1adde1d568a0256", + "contextLines": 10, + "whitespace": "SHOW", + "diffs": [ + { + "source": { + "components": [ + "src", + "main", + "java", + "com", + "example", + "app", + "Runner.java" + ], + "parent": "src/main/java/com/example/app", + "name": "Runner.java", + "extension": "java", + "toString": "src/main/java/com/example/app/Runner.java" + }, + "destination": { + "components": [ + "src", + "main", + "java", + "com", + "example", + "app", + "Runner.java" + ], + "parent": "src/main/java/com/example/app", + "name": "Runner.java", + "extension": "java", + "toString": "src/main/java/com/example/app/Runner.java" + }, + "hunks": [ + { + "sourceLine": 1, + "sourceSpan": 5, + "destinationLine": 1, + "destinationSpan": 5, + "segments": [ + { + "type": "CONTEXT", + "lines": [ + { + "source": 1, + "destination": 1, + "line": "package com.example.app;", + "truncated": false + }, + { + "source": 2, + "destination": 2, + "line": "", + "truncated": false + }, + { + "source": 3, + "destination": 3, + "line": "public interface Runner {", + "truncated": false + }, + { + "source": 4, + "destination": 4, + "line": " void run();", + "truncated": false + } + ], + "truncated": false + }, + { + "type": "REMOVED", + "lines": [ + { + "source": 5, + "destination": 5, + "line": "}", + "truncated": false + } + ], + "truncated": false + }, + { + "type": "ADDED", + "lines": [ + { + "source": 6, + "destination": 5, + "line": "}", + "truncated": false + } + ], + "truncated": false + } + ], + "truncated": false + } + ], + "truncated": false, + "fileComments": [ + { + "id": 225, + "version": 0, + "text": "[Checkstyle] WARNING: File does not end with a newline.", + "author": { + "name": "admin", + "emailAddress": "admin@example.com", + "id": 1, + "displayName": "Administrator", + "active": true, + "slug": "admin", + "type": "NORMAL" + }, + "createdDate": 1476558804537, + "updatedDate": 1476558804537, + "comments": [], + "attributes": {}, + "tasks": [], + "permittedOperations": { + "editable": true, + "deletable": true + } + } + ] + } + ] +} \ No newline at end of file