diff --git a/issue.go b/issue.go index 0699e5a..13feb16 100644 --- a/issue.go +++ b/issue.go @@ -35,11 +35,12 @@ type Attachment struct { Id string `json:"id,omitempty"` Filename string `json:"filename,omitempty"` // TODO Missing fields - //Author string `json:"author,omitempty"` - Created string `json:"created,omitempty"` - Size int `json:"size,omitempty"` - MimeType string `json:"mimeType,omitempty"` - Content string `json:"content,omitempty"` + Author *Assignee `json:"author,omitempty"` + Created string `json:"created,omitempty"` + Size int `json:"size,omitempty"` + MimeType string `json:"mimeType,omitempty"` + Content string `json:"content,omitempty"` + Thumbnail string `json:"thumbnail,omitempty"` } // IssueFields represents single fields of a JIRA issue. @@ -272,7 +273,7 @@ func (s *IssueService) DownloadAttachment(attachmentID string) (*http.Response, } // PostAttachment uploads an attachment provided as an io.Reader to a given attachment ID -func (s *IssueService) PostAttachment(attachmentID string, r io.Reader, attachmentName string) (*Issue, *http.Response, error) { +func (s *IssueService) PostAttachment(attachmentID string, r io.Reader, attachmentName string) (*[]Attachment, *http.Response, error) { apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/attachments", attachmentID) b := new(bytes.Buffer) @@ -297,13 +298,14 @@ func (s *IssueService) PostAttachment(attachmentID string, r io.Reader, attachme req.Header.Set("Content-Type", writer.FormDataContentType()) - issue := new(Issue) - resp, err := s.client.Do(req, issue) + // PostAttachment response returns a JSON array (as multiple attachments can be posted) + attachment := new([]Attachment) + resp, err := s.client.Do(req, attachment) if err != nil { return nil, resp, err } - return issue, resp, nil + return attachment, resp, nil } diff --git a/issue_test.go b/issue_test.go index 758d0f0..8063e4a 100644 --- a/issue_test.go +++ b/issue_test.go @@ -2,7 +2,9 @@ package jira import ( "fmt" + "io/ioutil" "net/http" + "strings" "testing" ) @@ -116,3 +118,87 @@ func TestIssueAddLink(t *testing.T) { t.Errorf("Error given: %s", err) } } + +func TestIssueDownloadAttachment(t *testing.T) { + var testAttachment = "Here is an attachment" + + setup() + defer teardown() + testMux.HandleFunc("/secure/attachment/", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testRequestURL(t, r, "/secure/attachment/10000/") + + w.WriteHeader(http.StatusOK) + w.Write([]byte(testAttachment)) + }) + + resp, err := testClient.Issue.DownloadAttachment("10000") + if resp == nil { + t.Error("Expected response. Response is nil") + } + defer resp.Body.Close() + + attachment, err := ioutil.ReadAll(resp.Body) + if err != nil { + t.Error("Expected attachment text", err) + } + if string(attachment) != testAttachment { + t.Errorf("Expecting an attachment", string(attachment)) + } + + if resp.StatusCode != 200 { + t.Errorf("Expected Status code 200. Given %d", resp.StatusCode) + } + if err != nil { + t.Errorf("Error given: %s", err) + } +} + +func TestIssuePostAttachment(t *testing.T) { + var testAttachment = "Here is an attachment" + + setup() + defer teardown() + testMux.HandleFunc("/rest/api/2/issue/10000/attachments", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + testRequestURL(t, r, "/rest/api/2/issue/10000/attachments") + status := http.StatusOK + + file, _, err := r.FormFile("file") + defer file.Close() + if err != nil { + status = http.StatusNotAcceptable + } + if file == nil { + status = http.StatusNoContent + } + + // Read the file into memory + data, err := ioutil.ReadAll(file) + if err != nil { + status = http.StatusInternalServerError + } + if string(data) != testAttachment { + status = http.StatusNotAcceptable + } + + w.WriteHeader(status) + fmt.Fprint(w, `[{"self":"http://jira/jira/rest/api/2/attachment/228924","id":"228924","filename":"example.jpg","author":{"self":"http://jira/jira/rest/api/2/user?username=test","name":"test","emailAddress":"test@test.com","avatarUrls":{"16x16":"http://jira/jira/secure/useravatar?size=small&avatarId=10082","48x48":"http://jira/jira/secure/useravatar?avatarId=10082"},"displayName":"Tester","active":true},"created":"2016-05-24T00:25:17.000-0700","size":32280,"mimeType":"image/jpeg","content":"http://jira/jira/secure/attachment/228924/example.jpg","thumbnail":"http://jira/jira/secure/thumbnail/228924/_thumb_228924.png"}]`) + }) + + reader := strings.NewReader(testAttachment) + + issue, resp, err := testClient.Issue.PostAttachment("10000", reader, "attachment") + + if issue == nil { + t.Error("Expected response. Response is nil") + } + + if resp.StatusCode != 200 { + t.Errorf("Expected Status code 200. Given %d", resp.StatusCode) + } + + if err != nil { + t.Errorf("Error given: %s", err) + } +} diff --git a/jira.go b/jira.go index e8647a7..7b7d66b 100644 --- a/jira.go +++ b/jira.go @@ -143,7 +143,7 @@ func (c *Client) Do(req *http.Request, v interface{}) (*http.Response, error) { // Do sends an API request and returns the API response. // The API response is JSON decoded and stored in the value pointed to by v, or returned as an error if an API error has occurred. -// The caller needs to call Body.Close when the response has been handled +// The caller is expected to consume the Body, and needs to call Body.Close when the response has been handled func (c *Client) DoNoClose(req *http.Request, v interface{}) (*http.Response, error) { resp, err := c.client.Do(req) if err != nil {