Repository: xanzy/go-gitlab
Pull request #623 (2019-05-16 17:02:01)

Update Jira service: change JiraTransitionID from int to string
Hi,

This is an update to https://github.com/xanzy/go-gitlab/pull/547.

This makes *JiraTransitionID* a string while still supporting previous Gitlab version (<11.9) when it was an int (cf. https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CHANGELOG.md#L443).

Best,


Patch:
diff --git a/services.go b/services.go
index bb51e20..c831dcd 100644
--- a/services.go
+++ b/services.go
@@ -17,7 +17,9 @@
 package gitlab
 
 import (
+	"encoding/json"
 	"fmt"
+	"strconv"
 	"time"
 )
 
@@ -396,6 +398,36 @@ type JiraServiceProperties struct {
 	JiraIssueTransitionID string `json:"jira_issue_transition_id,omitempty"`
 }
 
+// UnmarshalJSON decodes the Jira Service Properties.
+//
+// This allows support of JiraIssueTransitionID for both type string (>11.9) and float64 (<11.9)
+func (p *JiraServiceProperties) UnmarshalJSON(b []byte) error {
+	type Alias JiraServiceProperties
+	raw := struct {
+		*Alias
+		JiraIssueTransitionID interface{} `json:"jira_issue_transition_id"`
+	}{
+		Alias: (*Alias)(p),
+	}
+
+	if err := json.Unmarshal(b, &raw); err != nil {
+		return err
+	}
+
+	switch id := raw.JiraIssueTransitionID.(type) {
+	case nil:
+		p.JiraIssueTransitionID = ""
+	case string:
+		p.JiraIssueTransitionID = id
+	case float64:
+		p.JiraIssueTransitionID = strconv.Itoa(int(id))
+	default:
+		return fmt.Errorf("failed to unmarshal JiraTransitionID of type: %T", id)
+	}
+
+	return nil
+}
+
 // GetJiraService gets Jira service settings for a project.
 //
 // GitLab API docs:


Test patch:
diff --git a/services_test.go b/services_test.go
index 5754701..70f14f1 100644
--- a/services_test.go
+++ b/services_test.go
@@ -113,18 +113,60 @@ func TestGetJiraService(t *testing.T) {
 	mux, server, client := setup()
 	defer teardown(server)
 
+	mux.HandleFunc("/api/v4/projects/0/services/jira", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		fmt.Fprint(w, `{"id":1, "properties": {"jira_issue_transition_id": "2"}}`)
+	})
+
 	mux.HandleFunc("/api/v4/projects/1/services/jira", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		fmt.Fprint(w, `{"id":1}`)
+		fmt.Fprint(w, `{"id":1, "properties": {"jira_issue_transition_id": 2}}`)
 	})
-	want := &JiraService{Service: Service{ID: 1}}
 
-	service, _, err := client.Services.GetJiraService(1)
-	if err != nil {
-		t.Fatalf("Services.GetJiraService returns an error: %v", err)
+	mux.HandleFunc("/api/v4/projects/2/services/jira", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		fmt.Fprint(w, `{"id":1, "properties": {"jira_issue_transition_id": "2,3"}}`)
+	})
+
+	mux.HandleFunc("/api/v4/projects/3/services/jira", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		fmt.Fprint(w, `{"id":1, "properties": {}}`)
+	})
+
+	want := []*JiraService{
+		&JiraService{
+			Service: Service{ID: 1},
+			Properties: &JiraServiceProperties{
+				JiraIssueTransitionID: "2",
+			},
+		},
+		&JiraService{
+			Service: Service{ID: 1},
+			Properties: &JiraServiceProperties{
+				JiraIssueTransitionID: "2",
+			},
+		},
+		&JiraService{
+			Service: Service{ID: 1},
+			Properties: &JiraServiceProperties{
+				JiraIssueTransitionID: "2,3",
+			},
+		},
+		&JiraService{
+			Service:    Service{ID: 1},
+			Properties: &JiraServiceProperties{},
+		},
 	}
-	if !reflect.DeepEqual(want, service) {
-		t.Errorf("Services.GetJiraService returned %+v, want %+v", service, want)
+
+	for testcase := 0; testcase < len(want); testcase++ {
+		service, _, err := client.Services.GetJiraService(testcase)
+		if err != nil {
+			t.Fatalf("Services.GetJiraService returns an error: %v", err)
+		}
+
+		if !reflect.DeepEqual(want[testcase], service) {
+			t.Errorf("Services.GetJiraService returned %+v, want %+v", service, want[testcase])
+		}
 	}
 }
 
@@ -142,7 +184,7 @@ func TestSetJiraService(t *testing.T) {
 		ProjectKey:            String("as"),
 		Username:              String("aas"),
 		Password:              String("asd"),
-		JiraIssueTransitionID: String("2"),
+		JiraIssueTransitionID: String("2,3"),
 	}
 
 	_, err := client.Services.SetJiraService(1, opt)