Add 'vote' and 'unvote'

This adds support for voting on issues via CmdVote() and CmdUnvote()

Voting on issues is always done as the logged in user, it appears you
can't case a vote for another user:

https://docs.atlassian.com/jira/REST/latest/#api/2/issue-addVote

This required adding a cli.delete() handler, naturally with no content
(as per RFC2616)

This is ripe for DRY-ing out, but I will leave that for a future PR.

Worth noting is that you cannot vote for your own issues, this results in:

    2016-01-13T21:35:41.315Z ERROR [cli.go:184] response status: 404 Not Found
    2016-01-13T21:35:41.315Z ERROR [commands.go:439] Unexpected Response From POST:
    {snip}
    {"errorMessages":["You cannot vote for an issue you have reported."],"errors":{}}
This commit is contained in:
Mike Pountney
2016-01-13 21:41:34 +00:00
parent 8712b4af6b
commit c95e66e081
3 changed files with 82 additions and 0 deletions
+18
View File
@@ -106,6 +106,24 @@ func (c *Cli) put(uri string, content string) (*http.Response, error) {
return c.makeRequestWithContent("PUT", uri, content)
}
func (c *Cli) delete(uri string) (*http.Response, error) {
method := "DELETE"
req, _ := http.NewRequest(method, uri, nil)
log.Info("%s %s", req.Method, req.URL.String())
if resp, err := c.makeRequest(req); err != nil {
return nil, err
} else {
if resp.StatusCode == 401 {
if err := c.CmdLogin(); err != nil {
return nil, err
}
req, _ = http.NewRequest(method, uri, nil)
return c.makeRequest(req)
}
return resp, err
}
}
func (c *Cli) makeRequestWithContent(method string, uri string, content string) (*http.Response, error) {
buffer := bytes.NewBufferString(content)
req, _ := http.NewRequest(method, uri, buffer)
+56
View File
@@ -414,6 +414,62 @@ func (c *Cli) CmdWatch(issue string) error {
return nil
}
func (c *Cli) CmdVote(issue string) error {
log.Debug("vote called")
uri := fmt.Sprintf("%s/rest/api/2/issue/%s/votes", c.endpoint, issue)
if c.getOptBool("dryrun", false) {
log.Debug("POST: %s", "")
log.Debug("Dryrun mode, skipping POST")
return nil
}
resp, err := c.post(uri, "")
if err != nil {
return err
}
if resp.StatusCode == 204 {
c.Browse(issue)
if !c.opts["quiet"].(bool) {
fmt.Printf("OK %s %s/browse/%s\n", issue, c.endpoint, issue)
}
} else {
logBuffer := bytes.NewBuffer(make([]byte, 0))
resp.Write(logBuffer)
err := fmt.Errorf("Unexpected Response From POST")
log.Error("%s:\n%s", err, logBuffer)
return err
}
return nil
}
func (c *Cli) CmdUnvote(issue string) error {
log.Debug("unvote called")
uri := fmt.Sprintf("%s/rest/api/2/issue/%s/votes", c.endpoint, issue)
if c.getOptBool("dryrun", false) {
log.Debug("DELETE: %s", "")
log.Debug("Dryrun mode, skipping DELETE")
return nil
}
resp, err := c.delete(uri)
if err != nil {
return err
}
if resp.StatusCode == 204 {
c.Browse(issue)
if !c.opts["quiet"].(bool) {
fmt.Printf("OK %s %s/browse/%s\n", issue, c.endpoint, issue)
}
} else {
logBuffer := bytes.NewBuffer(make([]byte, 0))
resp.Write(logBuffer)
err := fmt.Errorf("Unexpected Response From DELETE")
log.Error("%s:\n%s", err, logBuffer)
return err
}
return nil
}
func (c *Cli) CmdTransition(issue string, trans string) error {
log.Debug("transition called")
uri := fmt.Sprintf("%s/rest/api/2/issue/%s/transitions?expand=transitions.fields", c.endpoint, issue)
+8
View File
@@ -151,6 +151,8 @@ Command Options:
"login": "login",
"req": "request",
"request": "request",
"vote": "vote",
"unvote": "unvote",
}
defaults := map[string]interface{}{
@@ -392,6 +394,12 @@ Command Options:
case "view":
requireArgs(1)
err = c.CmdView(args[0])
case "vote":
requireArgs(1)
err = c.CmdVote(args[0])
case "unvote":
requireArgs(1)
err = c.CmdUnvote(args[0])
case "request":
requireArgs(1)
data := ""