-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
10a2aaa
commit 070cc83
Showing
7 changed files
with
269 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package jira_rest_essentials; | ||
|
||
import static java.util.Collections.singletonMap; | ||
import static javax.ws.rs.core.Response.Status.BAD_REQUEST; | ||
import static javax.ws.rs.core.Response.Status.CREATED; | ||
import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; | ||
import static javax.ws.rs.core.Response.Status.NOT_FOUND; | ||
|
||
import com.atlassian.jira.component.ComponentAccessor; | ||
import com.atlassian.jira.issue.Issue; | ||
import com.atlassian.jira.issue.IssueManager; | ||
import com.atlassian.jira.issue.comments.Comment; | ||
import com.atlassian.jira.issue.comments.CommentManager; | ||
import com.atlassian.jira.security.roles.ProjectRoleManager; | ||
import com.atlassian.jira.user.ApplicationUser; | ||
import com.atlassian.jira.user.util.UserManager; | ||
import javax.ws.rs.Consumes; | ||
import javax.ws.rs.POST; | ||
import javax.ws.rs.Path; | ||
import javax.ws.rs.Produces; | ||
import javax.ws.rs.QueryParam; | ||
import javax.ws.rs.core.MediaType; | ||
import javax.ws.rs.core.Response; | ||
import org.apache.log4j.LogManager; | ||
import org.apache.log4j.Logger; | ||
|
||
/** | ||
* @author Jens Piegsa | ||
*/ | ||
@Path("comment") | ||
public class CommentResource { | ||
|
||
private static final Logger log = LogManager.getLogger("atlassian.plugin"); | ||
|
||
static final String ADMINISTRATORS = "Administrators"; | ||
|
||
private static CommentManager commentManager() { | ||
return ComponentAccessor.getCommentManager(); | ||
} | ||
|
||
private static UserManager userManager() { | ||
return ComponentAccessor.getUserManager(); | ||
} | ||
|
||
private static IssueManager issueManager() { | ||
return ComponentAccessor.getIssueManager(); | ||
} | ||
|
||
private static ProjectRoleManager projectRoleManager() { | ||
return ComponentAccessor.getComponentOfType(ProjectRoleManager.class); | ||
} | ||
|
||
@POST | ||
@Consumes(MediaType.APPLICATION_JSON) | ||
@Produces({MediaType.APPLICATION_JSON}) | ||
public Response createComment(@QueryParam("issueKey") final String issueKey, final SimpleComment simpleComment) { | ||
|
||
log.info("Creating comment for issue " + issueKey + "..."); | ||
|
||
final Issue issue = issueManager().getIssueObject(issueKey); | ||
if (issue == null) { | ||
return error(NOT_FOUND, "No issue found for issueKey " + issueKey); | ||
} | ||
|
||
final ApplicationUser applicationUser = userManager().getUserByName(simpleComment.getAuthor()); | ||
if (applicationUser == null) { | ||
return error(BAD_REQUEST, "No user found with name " + simpleComment.getAuthor()); | ||
} | ||
|
||
final String body = simpleComment.getBody(); | ||
if (body == null) { | ||
return error(BAD_REQUEST, "No \"body\" defined for comment."); | ||
} | ||
|
||
final String groupLevel = null; | ||
final Long roleLevelId = simpleComment.getProjectAdminsOnly() ? projectRoleManager().getProjectRole(ADMINISTRATORS).getId() : null; // 10002L; | ||
final boolean dispatchEvent = true; | ||
|
||
final Comment comment = commentManager().create(issue, applicationUser, body, groupLevel, roleLevelId, dispatchEvent); | ||
if (comment == null || comment.getId() == null) { | ||
return error(INTERNAL_SERVER_ERROR, "Could not create comment for issue " + issueKey + "."); | ||
} | ||
|
||
log.info("Comment created with id " + comment.getId() + " for issue " + issue.getKey() + "."); | ||
|
||
return Response.status(CREATED) | ||
.entity(singletonMap("id", comment.getId())) | ||
.build(); | ||
} | ||
|
||
private static Response error(final Response.Status status, final String message) { | ||
return Response.status(status) | ||
.entity(singletonMap("message", message)) | ||
.build(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package jira_rest_essentials; | ||
|
||
import java.io.Serializable; | ||
import org.codehaus.jackson.annotate.JsonAutoDetect; | ||
import org.codehaus.jackson.annotate.JsonProperty; | ||
|
||
/** | ||
* @author Jens Piegsa | ||
*/ | ||
@JsonAutoDetect | ||
public class SimpleComment implements Serializable { | ||
|
||
@JsonProperty | ||
private String author; | ||
|
||
@JsonProperty | ||
private String body; | ||
|
||
@JsonProperty | ||
private Boolean projectAdminsOnly; | ||
|
||
public String getAuthor() { | ||
return author; | ||
} | ||
|
||
public void setAuthor(final String author) { | ||
this.author = author; | ||
} | ||
|
||
public String getBody() { | ||
return body; | ||
} | ||
|
||
public void setBody(final String body) { | ||
this.body = body; | ||
} | ||
|
||
public Boolean getProjectAdminsOnly() { | ||
return projectAdminsOnly != null && projectAdminsOnly; | ||
} | ||
|
||
public void setProjectAdminsOnly(final Boolean projectAdminsOnly) { | ||
this.projectAdminsOnly = projectAdminsOnly; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "SimpleComment[\n" | ||
+ " author = " + author + "\n" | ||
+ " body = " + body + "\n" | ||
+ "]\n"; | ||
} | ||
} |
98 changes: 98 additions & 0 deletions
98
src/test/java/jira_rest_essentials/CommentResourceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package jira_rest_essentials; | ||
|
||
import static com.github.jenspiegsa.restassuredextension.PostConstructPojoResourceFactory.wired; | ||
import static io.restassured.RestAssured.given; | ||
import static javax.ws.rs.core.Response.Status.CREATED; | ||
import static org.hamcrest.Matchers.equalTo; | ||
import static org.mockito.BDDMockito.nullable; | ||
import static org.mockito.BDDMockito.any; | ||
import static org.mockito.BDDMockito.anyBoolean; | ||
import static org.mockito.BDDMockito.anyString; | ||
import static org.mockito.BDDMockito.given; | ||
import static org.mockito.BDDMockito.times; | ||
import static org.mockito.BDDMockito.verify; | ||
|
||
import com.atlassian.jira.component.ComponentAccessor; | ||
import com.atlassian.jira.issue.Issue; | ||
import com.atlassian.jira.issue.IssueManager; | ||
import com.atlassian.jira.issue.comments.CommentManager; | ||
import com.atlassian.jira.issue.comments.MockComment; | ||
import com.atlassian.jira.mock.MockProjectRoleManager; | ||
import com.atlassian.jira.mock.MockProjectRoleManager.MockProjectRole; | ||
import com.atlassian.jira.mock.component.MockComponentWorker; | ||
import com.atlassian.jira.mock.issue.MockIssue; | ||
import com.atlassian.jira.security.roles.ProjectRoleManager; | ||
import com.atlassian.jira.user.ApplicationUser; | ||
import com.atlassian.jira.user.MockApplicationUser; | ||
import com.atlassian.jira.user.util.MockUserManager; | ||
import com.atlassian.jira.user.util.UserManager; | ||
import com.github.jenspiegsa.restassuredextension.ConfigureRestAssured; | ||
import com.github.jenspiegsa.restassuredextension.RestAssuredExtension; | ||
import io.restassured.http.ContentType; | ||
import java.util.Date; | ||
import org.jboss.resteasy.spi.ResourceFactory; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.ExtendWith; | ||
import org.mockito.Mock; | ||
import org.mockito.junit.jupiter.MockitoExtension; | ||
|
||
/** | ||
* @author Jens Piegsa | ||
*/ | ||
@DisplayName("CommentResource") | ||
@ExtendWith(MockitoExtension.class) | ||
@ExtendWith(RestAssuredExtension.class) | ||
class CommentResourceTest { | ||
|
||
@ConfigureRestAssured(contextPath = "/jira/rest/essentials/1.0", port = 8989) | ||
ResourceFactory[] resourceFactory = {wired(CommentResource.class, nop -> {})}; | ||
|
||
@Mock CommentManager commentManager; | ||
@Mock IssueManager issueManager; | ||
|
||
private MockUserManager userManager = new MockUserManager(); | ||
private MockProjectRoleManager projectRoleManager = new MockProjectRoleManager(); | ||
|
||
@BeforeEach | ||
void setUp() { | ||
|
||
ComponentAccessor.initialiseWorker( | ||
new MockComponentWorker() | ||
.addMock(CommentManager.class, commentManager) | ||
.addMock(UserManager.class, userManager) | ||
.addMock(IssueManager.class, issueManager) | ||
.addMock(ProjectRoleManager.class, projectRoleManager) | ||
); | ||
|
||
final MockIssue issue = new MockIssue(123, "NAKO-109"); | ||
given(issueManager.getIssueObject("NAKO-109")).willReturn(issue); | ||
|
||
final MockApplicationUser user = new MockApplicationUser("piegsaj"); | ||
userManager.addUser(user); | ||
|
||
projectRoleManager.addRole(new MockProjectRole(10002L, CommentResource.ADMINISTRATORS, "project administrators")); | ||
|
||
given(commentManager.create(issue, user, "secret comment", null, 10002L, true)) | ||
.willReturn(new MockComment(5L, "piegsaj", "secret comment", null, 10_002L, new Date(), issue)); | ||
} | ||
|
||
@Test @DisplayName("HTTP POST /comment") | ||
void testPost() { | ||
|
||
given() | ||
.accept(ContentType.JSON) | ||
.when() | ||
.contentType("application/json") | ||
.body(getClass().getResourceAsStream("post_comment.json")) | ||
.post("/jira/rest/essentials/1.0/comment?issueKey=NAKO-109") | ||
.then() | ||
.log().all() | ||
.statusCode(CREATED.getStatusCode()) | ||
.body("id", equalTo(5)); | ||
|
||
verify(commentManager, times(1)) | ||
.create(any(Issue.class), any(ApplicationUser.class), anyString(), nullable(String.class), any(Long.class), anyBoolean()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"author" : "piegsaj", | ||
"body": "secret comment", | ||
"projectAdminsOnly": true | ||
} |