Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 73 additions & 4 deletions cloud/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -519,13 +519,15 @@ type CommentVisibility struct {
type SearchOptions struct {
// StartAt: The starting index of the returned projects. Base index: 0.
StartAt int `url:"startAt,omitempty"`
// MaxResults: The maximum number of projects to return per page. Default: 50.
// MaxResults: The maximum number of projects to return per page. Default: 100.
MaxResults int `url:"maxResults,omitempty"`
// Expand: Expand specific sections in the returned issues
Expand string `url:"expand,omitempty"`
Fields []string
// ValidateQuery: The validateQuery param offers control over whether to validate and how strictly to treat the validation. Default: strict.
ValidateQuery string `url:"validateQuery,omitempty"`
// OrderBy: The field to order the results by. Default: null. Valid values: created, -created, +created
OrderBy string `url:"orderBy,omitempty"`
}

// SearchOptionsV2 specifies the parameters for the Jira Cloud-specific
Expand Down Expand Up @@ -960,7 +962,7 @@ func (s *IssueService) UpdateIssue(ctx context.Context, jiraID string, data map[

// AddComment adds a new comment to issueID.
//
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-addComment
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issue-comments/#api-rest-api-2-issue-issueidorkey-comment-post
//
// TODO Double check this method if this works as expected, is using the latest API and the response is complete
// This double check effort is done for v2 - Remove this two lines if this is completed.
Expand All @@ -981,9 +983,76 @@ func (s *IssueService) AddComment(ctx context.Context, issueID string, comment *
return responseComment, resp, nil
}

// GetComment returns a comment for issueID and commentID.
//
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issue-comments/#api-rest-api-2-issue-issueidorkey-comment-id-get
func (s *IssueService) GetComment(ctx context.Context, issueID, commentID string, options *SearchOptions) (*Comment, *Response, error) {
u := url.URL{
Path: fmt.Sprintf("rest/api/2/issue/%s/comment/%s", issueID, commentID),
}
uv := url.Values{}
if options != nil && options.Expand != "" {
uv.Set("expand", options.Expand)
}
u.RawQuery = uv.Encode()

req, err := s.client.NewRequest(ctx, http.MethodGet, u.String(), nil)
if err != nil {
return nil, nil, err
}

responseComment := new(Comment)
resp, err := s.client.Do(req, &responseComment)
if err != nil {
jerr := NewJiraError(resp, err)
return nil, resp, jerr
}

return responseComment, resp, nil
}

// GetComments retrieves all comments for a given issueID.
//
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issue-comments/#api-rest-api-2-issue-issueidorkey-comment-get
func (s *IssueService) GetComments(ctx context.Context, issueID string, options *SearchOptions) (*Comments, *Response, error) {
u := url.URL{
Path: fmt.Sprintf("rest/api/2/issue/%s/comment", issueID),
}
uv := url.Values{}
if options != nil {
if options.StartAt != 0 {
uv.Add("startAt", strconv.Itoa(options.StartAt))
}
if options.MaxResults != 0 {
uv.Add("maxResults", strconv.Itoa(options.MaxResults))
}
if options.Expand != "" {
uv.Add("expand", options.Expand)
}
if options.OrderBy != "" {
uv.Add("orderBy", options.OrderBy)
}
}
u.RawQuery = uv.Encode()

req, err := s.client.NewRequest(ctx, http.MethodGet, u.String(), nil)
if err != nil {
return nil, nil, err
}

responseComments := new(Comments)
resp, err := s.client.Do(req, &responseComments)
if err != nil {
jerr := NewJiraError(resp, err)
return nil, resp, jerr
}

return responseComments, resp, nil
}

// UpdateComment updates the body of a comment, identified by comment.ID, on the issueID.
//
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/issue/{issueIdOrKey}/comment-updateComment
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issue-comments/#api-rest-api-2-issue-issueidorkey-comment-id-put
//
// TODO Double check this method if this works as expected, is using the latest API and the response is complete
// This double check effort is done for v2 - Remove this two lines if this is completed.
Expand All @@ -1010,7 +1079,7 @@ func (s *IssueService) UpdateComment(ctx context.Context, issueID string, commen

// DeleteComment Deletes a comment from an issueID.
//
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-api-3-issue-issueIdOrKey-comment-id-delete
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-comments/#api-rest-api-3-issue-issueidorkey-comment-id-delete
//
// TODO Double check this method if this works as expected, is using the latest API and the response is complete
// This double check effort is done for v2 - Remove this two lines if this is completed.
Expand Down
102 changes: 102 additions & 0 deletions cloud/issue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,108 @@ func TestIssueService_AddComment(t *testing.T) {
}
}

func TestIssueService_GetComment(t *testing.T) {
setup()
defer teardown()
c := &Comment{
ID: "10001",
Body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eget venenatis elit. Duis eu justo eget augue iaculis fermentum. Sed semper quam laoreet nisi egestas at posuere augue semper.",
Visibility: &CommentVisibility{
Type: "role",
Value: "Administrators",
},
}
t.Run("get-comment", func(t *testing.T) {
testMux.HandleFunc("/rest/api/2/issue/10000/comment/10001", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodGet)
testRequestURL(t, r, "/rest/api/2/issue/10000/comment/10001")

w.WriteHeader(http.StatusCreated)
fmt.Fprint(w, `{"self":"http://www.example.com/jira/rest/api/2/issue/10010/comment/10001","id":"10001","author":{"self":"http://www.example.com/jira/rest/api/2/user?username=fred","name":"fred","displayName":"Fred F. User","active":false},"body":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eget venenatis elit. Duis eu justo eget augue iaculis fermentum. Sed semper quam laoreet nisi egestas at posuere augue semper.","updateAuthor":{"self":"http://www.example.com/jira/rest/api/2/user?username=fred","name":"fred","displayName":"Fred F. User","active":false},"created":"2016-03-16T04:22:37.356+0000","updated":"2016-03-16T04:22:37.356+0000","visibility":{"type":"role","value":"Administrators"}}`)
})

comment, _, err := testClient.Issue.GetComment(context.Background(), "10000", c.ID, nil)
if comment == nil {
t.Error("Expected Comment. Comment is nil")
}
if err != nil {
t.Errorf("Error given: %s", err)
}
})
t.Run("get-comment-expanded", func(t *testing.T) {
testMux.HandleFunc("/rest/api/2/issue/10000/comment/10001?expand=renderedBody", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodGet)
testRequestURL(t, r, "/rest/api/2/issue/10000/comment/10001?expand=renderedBody")

w.WriteHeader(http.StatusCreated)
fmt.Fprint(w, `{"self":"http://www.example.com/jira/rest/api/2/issue/10010/comment/10001?expand=renderedBody","id":"10001","author":{"self":"http://www.example.com/jira/rest/api/2/user?username=fred","name":"fred","displayName":"Fred F. User","active":false},"body":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eget venenatis elit. Duis eu justo eget augue iaculis fermentum. Sed semper quam laoreet nisi egestas at posuere augue semper.","updateAuthor":{"self":"http://www.example.com/jira/rest/api/2/user?username=fred","name":"fred","displayName":"Fred F. User","active":false},"created":"2016-03-16T04:22:37.356+0000","updated":"2016-03-16T04:22:37.356+0000","visibility":{"type":"role","value":"Administrators"}}`)
})

comment, _, err := testClient.Issue.GetComment(context.Background(), "10000", c.ID, &SearchOptions{Expand: "renderedBody"})
if comment == nil {
t.Error("Expected Comment. Comment is nil")
}
if err != nil {
t.Errorf("Error given: %s", err)
}
})
}

func TestIssueService_GetComments(t *testing.T) {
setup()
defer teardown()
expected := &Comments{Comments: []*Comment{{
ID: "10001",
Body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eget venenatis elit. Duis eu justo eget augue iaculis fermentum. Sed semper quam laoreet nisi egestas at posuere augue semper.",
Visibility: &CommentVisibility{
Type: "role",
Value: "Administrators",
},
}}}
b, _ := json.Marshal(expected)
str := fmt.Sprintf("%s\n", b)
t.Run("get-comments", func(t *testing.T) {
testMux.HandleFunc("/rest/api/2/issue/10000/comment", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodGet)
testRequestURL(t, r, "/rest/api/2/issue/10000/comment")

w.WriteHeader(http.StatusCreated)
fmt.Fprint(w, str)
})

comments, _, err := testClient.Issue.GetComments(context.Background(), "10000", nil)
if comments == nil {
t.Fatal("Expected Comments. Comments are nil")
}
if len(comments.Comments) != 1 {
t.Errorf("Expected 1 Comment. Comments are %d", len(comments.Comments))
}
if err != nil {
t.Errorf("Error given: %s", err)
}
})
t.Run("get-comments-with-options", func(t *testing.T) {
testMux.HandleFunc("/rest/api/2/issue/10000/comment?expand=renderedBody&maxResults=50&orderBy=created&startAt=10", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodGet)
testRequestURL(t, r, "/rest/api/2/issue/10000/comment?expand=renderedBody&maxResults=50&orderBy=created&startAt=10")

w.WriteHeader(http.StatusCreated)
fmt.Fprint(w, str)
})

comments, _, err := testClient.Issue.GetComments(context.Background(), "10000", &SearchOptions{StartAt: 10, MaxResults: 50, Expand: "renderedBody", OrderBy: "created"})
if comments == nil {
t.Fatal("Expected Comments. Comments are nil")
}
if len(comments.Comments) != 1 {
t.Errorf("Expected 1 Comment. Comments are %d", len(comments.Comments))
}
if err != nil {
t.Errorf("Error given: %s", err)
}
})
}

func TestIssueService_UpdateComment(t *testing.T) {
setup()
defer teardown()
Expand Down
Loading