diff --git a/pkg/jira/sprint.go b/pkg/jira/sprint.go index cd468dac..b054409d 100644 --- a/pkg/jira/sprint.go +++ b/pkg/jira/sprint.go @@ -88,8 +88,11 @@ func (c *Client) EndSprint(sprintID int) error { if err != nil { return err } + if sprint.Status == SprintStateClosed { + return fmt.Errorf("sprint %d is already closed", sprintID) + } - // update to closed and format for PUT + // Update to closed and format for PUT. sprint.Status = SprintStateClosed body, err := json.Marshal(sprint) if err != nil { diff --git a/pkg/jira/sprint_test.go b/pkg/jira/sprint_test.go index a872e42f..6f8336df 100644 --- a/pkg/jira/sprint_test.go +++ b/pkg/jira/sprint_test.go @@ -342,3 +342,77 @@ func TestSprintIssuesAdd(t *testing.T) { err = client.SprintIssuesAdd("5", "TEST-1") assert.Error(t, &ErrUnexpectedResponse{}, err) } + +func TestGetSprint(t *testing.T) { + var unexpectedStatusCode bool + + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "/rest/agile/1.0/sprint/5", r.URL.Path) + + if unexpectedStatusCode { + w.WriteHeader(400) + } else { + assert.Equal(t, "GET", r.Method) + + resp, err := os.ReadFile("./testdata/sprint-get.json") + assert.NoError(t, err) + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, _ = w.Write(resp) + } + })) + defer server.Close() + + client := NewClient(Config{Server: server.URL}, WithTimeout(3*time.Second)) + + sprint, err := client.GetSprint(5) + assert.NoError(t, err) + assert.Equal(t, sprint.ID, 5) + assert.Equal(t, sprint.Status, "active") + + unexpectedStatusCode = true + + _, err = client.GetSprint(5) + assert.Error(t, &ErrUnexpectedResponse{}, err) +} + +func TestEndSprint(t *testing.T) { + var unexpectedStatusCode bool + + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + assert.NotNilf(t, r.Method, "invalid request method") + + if r.Method == "GET" { + assert.Equal(t, "/rest/agile/1.0/sprint/5", r.URL.Path) + + resp, err := os.ReadFile("./testdata/sprint-get.json") + assert.NoError(t, err) + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, _ = w.Write(resp) + } else { + if unexpectedStatusCode { + w.WriteHeader(400) + } else if r.Method == "PUT" { + assert.Equal(t, "PUT", r.Method) + assert.Equal(t, "application/json", r.Header.Get("Accept")) + assert.Equal(t, "application/json", r.Header.Get("Content-Type")) + + w.WriteHeader(200) + } + } + })) + defer server.Close() + + client := NewClient(Config{Server: server.URL}, WithTimeout(3*time.Second)) + + err := client.EndSprint(5) + assert.NoError(t, err) + + unexpectedStatusCode = true + + err = client.EndSprint(5) + assert.Error(t, &ErrUnexpectedResponse{}, err) +} diff --git a/pkg/jira/testdata/sprint-get.json b/pkg/jira/testdata/sprint-get.json new file mode 100644 index 00000000..9dd3f95e --- /dev/null +++ b/pkg/jira/testdata/sprint-get.json @@ -0,0 +1,11 @@ +{ + "id": 5, + "self": "https://demo.atlassian.net/rest/agile/1.0/sprint/5", + "state": "active", + "name": "sprint 1", + "startDate": "2025-04-11T15:22:00.000+10:00", + "endDate": "2025-04-20T01:22:00.000+10:00", + "completeDate": "2025-04-20T11:04:00.000+10:00", + "originBoardId": 3, + "goal": "sprint 1 goal" +}