mirror of
https://github.com/interviewstreet/go-jira.git
synced 2024-11-24 08:22:42 +02:00
Added basic Sprint API handling
This commit is contained in:
parent
9a5ed6f72a
commit
2b74499969
2
jira.go
2
jira.go
@ -29,6 +29,7 @@ type Client struct {
|
|||||||
Project *ProjectService
|
Project *ProjectService
|
||||||
Board *BoardService
|
Board *BoardService
|
||||||
Transition *TransitionService
|
Transition *TransitionService
|
||||||
|
Sprint *SprintService
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClient returns a new JIRA API client.
|
// NewClient returns a new JIRA API client.
|
||||||
@ -57,6 +58,7 @@ func NewClient(httpClient *http.Client, baseURL string) (*Client, error) {
|
|||||||
c.Project = &ProjectService{client: c}
|
c.Project = &ProjectService{client: c}
|
||||||
c.Board = &BoardService{client: c}
|
c.Board = &BoardService{client: c}
|
||||||
c.Transition = &TransitionService{client: c}
|
c.Transition = &TransitionService{client: c}
|
||||||
|
c.Sprint = &SprintService{client: c}
|
||||||
|
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
46
mocks/sprints.json
Normal file
46
mocks/sprints.json
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
{
|
||||||
|
"isLast": true,
|
||||||
|
"maxResults": 50,
|
||||||
|
"startAt": 0,
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
|
"completeDate": "2016-04-28T05:08:48.543-07:00",
|
||||||
|
"endDate": "2016-04-27T08:29:00.000-07:00",
|
||||||
|
"id": 740,
|
||||||
|
"name": "Iteration-10",
|
||||||
|
"originBoardId": 734,
|
||||||
|
"self": "https://jira.com/rest/agile/1.0/sprint/740",
|
||||||
|
"startDate": "2016-04-11T07:29:03.294-07:00",
|
||||||
|
"state": "closed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"completeDate": "2016-05-30T02:45:44.991-07:00",
|
||||||
|
"endDate": "2016-05-26T14:56:00.000-07:00",
|
||||||
|
"id": 776,
|
||||||
|
"name": "Iteration-12-1",
|
||||||
|
"originBoardId": 734,
|
||||||
|
"self": "https://jira.com/rest/agile/1.0/sprint/776",
|
||||||
|
"startDate": "2016-05-19T13:56:00.000-07:00",
|
||||||
|
"state": "closed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"completeDate": "2016-06-08T07:54:13.723-07:00",
|
||||||
|
"endDate": "2016-06-08T01:06:00.000-07:00",
|
||||||
|
"id": 807,
|
||||||
|
"name": "Iteration-12-2",
|
||||||
|
"originBoardId": 734,
|
||||||
|
"self": "https://jira.com/rest/agile/1.0/sprint/807",
|
||||||
|
"startDate": "2016-06-01T00:06:00.000-07:00",
|
||||||
|
"state": "closed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"endDate": "2016-06-28T14:24:00.000-07:00",
|
||||||
|
"id": 832,
|
||||||
|
"name": "Iteration-13-2",
|
||||||
|
"originBoardId": 734,
|
||||||
|
"self": "https://jira.com/rest/agile/1.0/sprint/832",
|
||||||
|
"startDate": "2016-06-20T13:24:39.161-07:00",
|
||||||
|
"state": "active"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
63
sprint.go
Normal file
63
sprint.go
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package jira
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SprintService handles sprints in JIRA Agile API.
|
||||||
|
type SprintService struct {
|
||||||
|
client *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrapper struct for search result
|
||||||
|
type sprintsResult struct {
|
||||||
|
Sprints []Sprint `json:"values"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sprint represents a sprint on JIRA agile board
|
||||||
|
type Sprint struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
CompleteDate *time.Time `json:"completeDate"`
|
||||||
|
EndDate *time.Time `json:"endDate"`
|
||||||
|
StartDate *time.Time `json:"startDate"`
|
||||||
|
OriginBoardID int `json:"originBoardId"`
|
||||||
|
Self string `json:"self"`
|
||||||
|
State string `json:"state"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrapper struct for moving issues to sprint
|
||||||
|
type IssuesWrapper struct {
|
||||||
|
Issues []string `json:"issues"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetList gets sprints for given board
|
||||||
|
//
|
||||||
|
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board/{boardId}/sprint
|
||||||
|
func (s *SprintService) GetList(boardID string) ([]Sprint, *Response, error) {
|
||||||
|
apiEndpoint := fmt.Sprintf("rest/agile/1.0/board/%s/sprint", boardID)
|
||||||
|
req, err := s.client.NewRequest("GET", apiEndpoint, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result := new(sprintsResult)
|
||||||
|
resp, err := s.client.Do(req, result)
|
||||||
|
return result.Sprints, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SprintService) AddIssuesToSprint(sprintID int, issueIDs []string) (*Response, error) {
|
||||||
|
apiEndpoint := fmt.Sprintf("rest/agile/1.0/sprint/%d/issue", sprintID)
|
||||||
|
|
||||||
|
payload := IssuesWrapper{Issues: issueIDs}
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("POST", apiEndpoint, payload)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := s.client.Do(req, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
71
sprint_test.go
Normal file
71
sprint_test.go
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package jira
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSprintGetList(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
testAPIEndpoint := "/rest/agile/1.0/board/123/sprint"
|
||||||
|
|
||||||
|
raw, err := ioutil.ReadFile("./mocks/sprints.json")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
testMux.HandleFunc(testAPIEndpoint, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testRequestURL(t, r, testAPIEndpoint)
|
||||||
|
fmt.Fprint(w, string(raw))
|
||||||
|
})
|
||||||
|
|
||||||
|
sprints, _, err := testClient.Sprint.GetList("123")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Got error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if sprints == nil {
|
||||||
|
t.Error("Expected sprint list. Got nil.")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(sprints) != 4 {
|
||||||
|
t.Errorf("Expected 4 transitions. Got %d", len(sprints))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMoveIssueToSprint(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
testAPIEndpoint := "/rest/agile/1.0/sprint/123/issue"
|
||||||
|
|
||||||
|
issuesToMove := []string{"KEY-1", "KEY-2"}
|
||||||
|
|
||||||
|
testMux.HandleFunc(testAPIEndpoint, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
testRequestURL(t, r, testAPIEndpoint)
|
||||||
|
|
||||||
|
decoder := json.NewDecoder(r.Body)
|
||||||
|
var payload IssuesWrapper
|
||||||
|
err := decoder.Decode(&payload)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("Got error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if payload.Issues[0] != issuesToMove[0] {
|
||||||
|
t.Errorf("Expected %s to be in payload, got %s instead", issuesToMove[0], payload.Issues[0])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
_, err := testClient.Sprint.AddIssuesToSprint(123, issuesToMove)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Error("Got error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user