Skip to content

Commit

Permalink
create comments with any author
Browse files Browse the repository at this point in the history
  • Loading branch information
JensPiegsa committed Mar 22, 2019
1 parent 10a2aaa commit 070cc83
Show file tree
Hide file tree
Showing 7 changed files with 269 additions and 4 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,20 @@ Request body example:

* returns workflow scheme id for given project

### Comments

#### `POST https://example.com/jira/rest/essentials/1.0/comment?issueKey=EXAMPLE-123`

Request body example:

```json
{
"author": "someuser",
"body": "secret comment",
"projectAdminsOnly": true
}
```

---

### Build the Add-on ###
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>jira-rest-essentials</groupId>
<artifactId>jira-rest-essentials</artifactId>
<version>1.0.49</version>
<version>1.0.50</version>

<organization>
<name>Jens Piegsa</name>
Expand Down
96 changes: 96 additions & 0 deletions src/main/java/jira_rest_essentials/CommentResource.java
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();
}
}
53 changes: 53 additions & 0 deletions src/main/java/jira_rest_essentials/SimpleComment.java
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 src/test/java/jira_rest_essentials/CommentResourceTest.java
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());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import static com.github.jenspiegsa.restassuredextension.PostConstructPojoResourceFactory.wired;
import static io.restassured.RestAssured.given;
import static javax.ws.rs.core.Response.Status.OK;
import static org.hamcrest.Matchers.equalTo;
import static org.mockito.BDDMockito.any;
import static org.mockito.BDDMockito.anyString;
import static org.mockito.BDDMockito.given;

import com.atlassian.jira.component.ComponentAccessor;
Expand All @@ -17,7 +17,6 @@
import com.github.jenspiegsa.restassuredextension.ConfigureRestAssured;
import com.github.jenspiegsa.restassuredextension.RestAssuredExtension;
import io.restassured.http.ContentType;
import javax.ws.rs.core.Response;
import org.jboss.resteasy.spi.ResourceFactory;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
Expand Down Expand Up @@ -64,7 +63,7 @@ void testGet() {
.get("/jira/rest/essentials/1.0/workflowscheme?projectKey=NAKO")
.then()
.log().all()
.statusCode(Response.Status.OK.getStatusCode())
.statusCode(OK.getStatusCode())
.body("id", equalTo(42));
}
}
5 changes: 5 additions & 0 deletions src/test/resources/jira_rest_essentials/post_comment.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"author" : "piegsaj",
"body": "secret comment",
"projectAdminsOnly": true
}

0 comments on commit 070cc83

Please sign in to comment.