diff --git a/issue.go b/issue.go index 992139f..e3f58ef 100644 --- a/issue.go +++ b/issue.go @@ -700,13 +700,21 @@ func (s *IssueService) GetTransitions(id string) ([]Transition, *Response, error // // JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-doTransition func (s *IssueService) DoTransition(ticketID, transitionID string) (*Response, error) { - apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/transitions", ticketID) - payload := CreateTransitionPayload{ Transition: TransitionPayload{ ID: transitionID, }, } + return s.DoTransitionWithPayload(ticketID, payload) +} + +// DoTransitionWithPayload performs a transition on an issue using any payload. +// When performing the transition you can update or set other issue fields. +// +// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-doTransition +func (s *IssueService) DoTransitionWithPayload(ticketID, payload interface{}) (*Response, error) { + apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/transitions", ticketID) + req, err := s.client.NewRequest("POST", apiEndpoint, payload) if err != nil { return nil, err diff --git a/issue_test.go b/issue_test.go index 276fbb3..9020cf3 100644 --- a/issue_test.go +++ b/issue_test.go @@ -512,6 +512,65 @@ func TestIssueService_DoTransition(t *testing.T) { } } +func TestIssueService_DoTransitionWithPayload(t *testing.T) { + setup() + defer teardown() + + testAPIEndpoint := "/rest/api/2/issue/123/transitions" + + transitionID := "22" + + customPayload := map[string]interface{}{ + "update": map[string]interface{}{ + "comment": []map[string]interface{}{ + map[string]interface{}{ + "add": map[string]string{ + "body": "Hello World", + }, + }, + }, + }, + "transition": TransitionPayload{ + ID: transitionID, + }, + } + + testMux.HandleFunc(testAPIEndpoint, func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + testRequestURL(t, r, testAPIEndpoint) + + decoder := json.NewDecoder(r.Body) + payload := map[string]interface{}{} + err := decoder.Decode(&payload) + if err != nil { + t.Errorf("Got error: %v", err) + } + + contains := func(key string) bool { + _, ok := payload[key] + return ok + } + + if !contains("update") || !contains("transition") { + t.Fatalf("Excpected update, transition to be in payload, got %s instead", payload) + } + + transition, ok := payload["transition"].(map[string]interface{}) + if !ok { + t.Fatalf("Excpected transition to be in payload, got %s instead", payload["transition"]) + } + + if transition["id"].(string) != transitionID { + t.Errorf("Expected %s to be in payload, got %s instead", transitionID, transition["id"]) + } + }) + _, err := testClient.Issue.DoTransitionWithPayload("123", customPayload) + + if err != nil { + t.Errorf("Got error: %v", err) + } +} + func TestIssueFields_TestMarshalJSON_PopulateUnknownsSuccess(t *testing.T) { data := `{ "customfield_123":"test",