From 9049c9ff740cda34330b960cf562f2989063db14 Mon Sep 17 00:00:00 2001 From: spmassot Date: Wed, 17 Oct 2018 15:17:08 -0400 Subject: [PATCH] Instead of baking config into the client, adds a method call that allows options to be passed in --- README.md | 8 ++-- examples/basicauth/main.go | 5 +- examples/create/main.go | 5 +- examples/do/main.go | 5 +- examples/ignorecerts/main.go | 5 +- examples/newclient/main.go | 5 +- examples/renderedfields/main.go | 5 +- issue.go | 39 ++++++++++++--- jira.go | 4 +- jira_test.go | 85 +++++++-------------------------- 10 files changed, 62 insertions(+), 104 deletions(-) diff --git a/README.md b/README.md index 5b2e74f..4197986 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ import ( ) func main() { - jiraClient, _ := jira.NewClient(nil, "https://issues.apache.org/jira/", true) + jiraClient, _ := jira.NewClient(nil, "https://issues.apache.org/jira/") issue, _, _ := jiraClient.Issue.Get("MESOS-3325", nil) fmt.Printf("%s: %+v\n", issue.Key, issue.Fields.Summary) @@ -98,7 +98,7 @@ func main() { Password: "token", } - client, err := jira.NewClient(tp.Client(), "https://my.jira.com", true) + client, err := jira.NewClient(tp.Client(), "https://my.jira.com") u, _, err := client.User.Get("some_user") @@ -136,7 +136,7 @@ func main() { Password: "token", } - jiraClient, err := jira.NewClient(tp.Client(), base, true) + jiraClient, err := jira.NewClient(tp.Client(), base) if err != nil { panic(err) } @@ -189,7 +189,7 @@ func main() { Password: "token", } - jiraClient, err := jira.NewClient(tp.Client(), base, true) + jiraClient, err := jira.NewClient(tp.Client(), base) req, _ := jiraClient.NewRequest("GET", "rest/api/2/project", nil) projects := new([]jira.Project) diff --git a/examples/basicauth/main.go b/examples/basicauth/main.go index d6698cf..54deebc 100644 --- a/examples/basicauth/main.go +++ b/examples/basicauth/main.go @@ -29,10 +29,7 @@ func main() { Password: strings.TrimSpace(password), } - config = jira.ServiceConfig{ - Notify: true, - } - client, err := jira.NewClient(tp.Client(), strings.TrimSpace(jiraURL), config) + client, err := jira.NewClient(tp.Client(), strings.TrimSpace(jiraURL)) if err != nil { fmt.Printf("\nerror: %v\n", err) return diff --git a/examples/create/main.go b/examples/create/main.go index 5ad4f08..3f4d8bb 100644 --- a/examples/create/main.go +++ b/examples/create/main.go @@ -29,10 +29,7 @@ func main() { Password: strings.TrimSpace(password), } - config = jira.ServiceConfig{ - Notify: true, - } - client, err := jira.NewClient(tp.Client(), strings.TrimSpace(jiraURL), config) + client, err := jira.NewClient(tp.Client(), strings.TrimSpace(jiraURL)) if err != nil { fmt.Printf("\nerror: %v\n", err) return diff --git a/examples/do/main.go b/examples/do/main.go index cd6ebea..c6f9a11 100644 --- a/examples/do/main.go +++ b/examples/do/main.go @@ -7,10 +7,7 @@ import ( ) func main() { - config = jira.ServiceConfig{ - Notify: true, - } - jiraClient, _ := jira.NewClient(nil, "https://jira.atlassian.com/", config) + jiraClient, _ := jira.NewClient(nil, "https://jira.atlassian.com/") req, _ := jiraClient.NewRequest("GET", "/rest/api/2/project", nil) projects := new([]jira.Project) diff --git a/examples/ignorecerts/main.go b/examples/ignorecerts/main.go index 2382d9b..6fcc602 100644 --- a/examples/ignorecerts/main.go +++ b/examples/ignorecerts/main.go @@ -14,10 +14,7 @@ func main() { } client := &http.Client{Transport: tr} - config = jira.ServiceConfig{ - Notify: true, - } - jiraClient, _ := jira.NewClient(client, "https://issues.apache.org/jira/", config) + jiraClient, _ := jira.NewClient(client, "https://issues.apache.org/jira/") issue, _, _ := jiraClient.Issue.Get("MESOS-3325", nil) fmt.Printf("%s: %+v\n", issue.Key, issue.Fields.Summary) diff --git a/examples/newclient/main.go b/examples/newclient/main.go index a4e142c..e0bec52 100644 --- a/examples/newclient/main.go +++ b/examples/newclient/main.go @@ -7,10 +7,7 @@ import ( ) func main() { - config = jira.ServiceConfig{ - Notify: true, - } - jiraClient, _ := jira.NewClient(nil, "https://issues.apache.org/jira/", config) + jiraClient, _ := jira.NewClient(nil, "https://issues.apache.org/jira/") issue, _, _ := jiraClient.Issue.Get("MESOS-3325", nil) fmt.Printf("%s: %+v\n", issue.Key, issue.Fields.Summary) diff --git a/examples/renderedfields/main.go b/examples/renderedfields/main.go index 0fd3412..ab23420 100644 --- a/examples/renderedfields/main.go +++ b/examples/renderedfields/main.go @@ -42,10 +42,7 @@ func main() { tp = ba.Client() } - config = jira.ServiceConfig{ - Notify: true, - } - client, err := jira.NewClient(tp, strings.TrimSpace(jiraURL), config) + client, err := jira.NewClient(tp, strings.TrimSpace(jiraURL)) if err != nil { fmt.Printf("\nerror: %v\n", err) return diff --git a/issue.go b/issue.go index 6c3c29c..e427faf 100644 --- a/issue.go +++ b/issue.go @@ -27,12 +27,13 @@ const ( // JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue type IssueService struct { client *Client - Config *ServiceConfig } -// ServiceConfig describes some config options that apply to many/all calls made by the service -type ServiceConfig struct { - Notify bool +// UpdateOptions specifies the optional parameters to the Edit issue +type UpdateOptions struct { + NotifyUsers bool `url:"notifyUsers,omitempty"` + OverrideScreenSecurity bool `url:"overrideScreenSecurity,omitempty"` + OverrideEditableFlag bool `url:"overrideEditableFlag,omitempty"` } // Issue represents a JIRA issue. @@ -655,11 +656,37 @@ func (s *IssueService) Create(issue *Issue) (*Issue, *Response, error) { return responseIssue, resp, nil } +// UpdateWithOptions updates an issue from a JSON representation, +// while also specifiying query params. The issue is found by key. +// +// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-editIssue +func (s *IssueService) UpdateWithOptions(issue *Issue, opts *UpdateOptions) (*Issue, *Response, error) { + apiEndpoint := fmt.Sprintf("rest/api/3/issue/%v", issue.Key) + url, err := addOptions(apiEndpoint, opts) + if err != nil { + return nil, nil, err + } + req, err := s.client.NewRequest("PUT", url, issue) + if err != nil { + return nil, nil, err + } + resp, err := s.client.Do(req, nil) + if err != nil { + jerr := NewJiraError(resp, err) + return nil, resp, jerr + } + + // This is just to follow the rest of the API's convention of returning an issue. + // Returning the same pointer here is pointless, so we return a copy instead. + ret := *issue + return &ret, resp, nil +} + // Update updates an issue from a JSON representation. The issue is found by key. // // JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-editIssue func (s *IssueService) Update(issue *Issue) (*Issue, *Response, error) { - apiEndpoint := fmt.Sprintf("rest/api/3/issue/%v?notifyUsers=%t", issue.Key, s.Config.Notify) + apiEndpoint := fmt.Sprintf("rest/api/3/issue/%v", issue.Key) req, err := s.client.NewRequest("PUT", apiEndpoint, issue) if err != nil { return nil, nil, err @@ -680,7 +707,7 @@ func (s *IssueService) Update(issue *Issue) (*Issue, *Response, error) { // // https://docs.atlassian.com/jira/REST/7.4.0/#api/2/issue-editIssue func (s *IssueService) UpdateIssue(jiraID string, data map[string]interface{}) (*Response, error) { - apiEndpoint := fmt.Sprintf("rest/api/2/issue/%v?notifyUsers=%t", jiraID, s.Config.Notify) + apiEndpoint := fmt.Sprintf("rest/api/2/issue/%v", jiraID) req, err := s.client.NewRequest("PUT", apiEndpoint, data) if err != nil { return nil, err diff --git a/jira.go b/jira.go index 891fe33..d8d247d 100644 --- a/jira.go +++ b/jira.go @@ -50,7 +50,7 @@ type Client struct { // As an alternative you can use Session Cookie based authentication provided by this package as well. // See https://docs.atlassian.com/jira/REST/latest/#authentication // baseURL is the HTTP endpoint of your JIRA instance and should always be specified with a trailing slash. -func NewClient(httpClient *http.Client, baseURL string, config *ServiceConfig) (*Client, error) { +func NewClient(httpClient *http.Client, baseURL string) (*Client, error) { if httpClient == nil { httpClient = http.DefaultClient } @@ -70,7 +70,7 @@ func NewClient(httpClient *http.Client, baseURL string, config *ServiceConfig) ( baseURL: parsedBaseURL, } c.Authentication = &AuthenticationService{client: c} - c.Issue = &IssueService{client: c, Config: config} + c.Issue = &IssueService{client: c} c.Project = &ProjectService{client: c} c.Board = &BoardService{client: c} c.Sprint = &SprintService{client: c} diff --git a/jira_test.go b/jira_test.go index 61a7502..1a3d5b4 100644 --- a/jira_test.go +++ b/jira_test.go @@ -38,10 +38,7 @@ func setup() { testServer = httptest.NewServer(testMux) // jira client configured to use test server - config = ServiceConfig{ - Notify: true, - } - testClient, _ = NewClient(nil, testServer.URL, config) + testClient, _ = NewClient(nil, testServer.URL) } // teardown closes the test HTTP server. @@ -62,10 +59,7 @@ func testRequestURL(t *testing.T, r *http.Request, want string) { } func TestNewClient_WrongUrl(t *testing.T) { - config = ServiceConfig{ - Notify: true, - } - c, err := NewClient(nil, "://issues.apache.org/jira/", config) + c, err := NewClient(nil, "://issues.apache.org/jira/") if err == nil { t.Error("Expected an error. Got none") @@ -78,10 +72,7 @@ func TestNewClient_WrongUrl(t *testing.T) { func TestNewClient_WithHttpClient(t *testing.T) { httpClient := http.DefaultClient httpClient.Timeout = 10 * time.Minute - config = ServiceConfig{ - Notify: true, - } - c, err := NewClient(httpClient, testJIRAInstanceURL, config) + c, err := NewClient(httpClient, testJIRAInstanceURL) if err != nil { t.Errorf("Got an error: %s", err) @@ -95,10 +86,7 @@ func TestNewClient_WithHttpClient(t *testing.T) { } func TestNewClient_WithServices(t *testing.T) { - config = ServiceConfig{ - Notify: true, - } - c, err := NewClient(nil, testJIRAInstanceURL, config) + c, err := NewClient(nil, testJIRAInstanceURL) if err != nil { t.Errorf("Got an error: %s", err) @@ -154,10 +142,7 @@ func TestCheckResponse(t *testing.T) { } func TestClient_NewRequest(t *testing.T) { - config = ServiceConfig{ - Notify: true, - } - c, err := NewClient(nil, testJIRAInstanceURL, config) + c, err := NewClient(nil, testJIRAInstanceURL) if err != nil { t.Errorf("An error occurred. Expected nil. Got %+v.", err) } @@ -179,10 +164,7 @@ func TestClient_NewRequest(t *testing.T) { } func TestClient_NewRawRequest(t *testing.T) { - config = ServiceConfig{ - Notify: true, - } - c, err := NewClient(nil, testJIRAInstanceURL, config) + c, err := NewClient(nil, testJIRAInstanceURL) if err != nil { t.Errorf("An error occurred. Expected nil. Got %+v.", err) } @@ -215,10 +197,7 @@ func testURLParseError(t *testing.T, err error) { } func TestClient_NewRequest_BadURL(t *testing.T) { - config = ServiceConfig{ - Notify: true, - } - c, err := NewClient(nil, testJIRAInstanceURL, config) + c, err := NewClient(nil, testJIRAInstanceURL) if err != nil { t.Errorf("An error occurred. Expected nil. Got %+v.", err) } @@ -227,10 +206,7 @@ func TestClient_NewRequest_BadURL(t *testing.T) { } func TestClient_NewRequest_SessionCookies(t *testing.T) { - config = ServiceConfig{ - Notify: true, - } - c, err := NewClient(nil, testJIRAInstanceURL, config) + c, err := NewClient(nil, testJIRAInstanceURL) if err != nil { t.Errorf("An error occurred. Expected nil. Got %+v.", err) } @@ -259,10 +235,7 @@ func TestClient_NewRequest_SessionCookies(t *testing.T) { } func TestClient_NewRequest_BasicAuth(t *testing.T) { - config = ServiceConfig{ - Notify: true, - } - c, err := NewClient(nil, testJIRAInstanceURL, config) + c, err := NewClient(nil, testJIRAInstanceURL) if err != nil { t.Errorf("An error occurred. Expected nil. Got %+v.", err) } @@ -288,10 +261,7 @@ func TestClient_NewRequest_BasicAuth(t *testing.T) { // since there is no difference between an HTTP request body that is an empty string versus one that is not set at all. // However in certain cases, intermediate systems may treat these differently resulting in subtle errors. func TestClient_NewRequest_EmptyBody(t *testing.T) { - config = ServiceConfig{ - Notify: true, - } - c, err := NewClient(nil, testJIRAInstanceURL, config) + c, err := NewClient(nil, testJIRAInstanceURL) if err != nil { t.Errorf("An error occurred. Expected nil. Got %+v.", err) } @@ -305,10 +275,7 @@ func TestClient_NewRequest_EmptyBody(t *testing.T) { } func TestClient_NewMultiPartRequest(t *testing.T) { - config = ServiceConfig{ - Notify: true, - } - c, err := NewClient(nil, testJIRAInstanceURL, config) + c, err := NewClient(nil, testJIRAInstanceURL) if err != nil { t.Errorf("An error occurred. Expected nil. Got %+v.", err) } @@ -341,10 +308,7 @@ func TestClient_NewMultiPartRequest(t *testing.T) { } func TestClient_NewMultiPartRequest_BasicAuth(t *testing.T) { - config = ServiceConfig{ - Notify: true, - } - c, err := NewClient(nil, testJIRAInstanceURL, config) + c, err := NewClient(nil, testJIRAInstanceURL) if err != nil { t.Errorf("An error occurred. Expected nil. Got %+v.", err) } @@ -463,10 +427,7 @@ func TestClient_GetBaseURL_WithURL(t *testing.T) { t.Errorf("URL parsing -> Got an error: %s", err) } - config = ServiceConfig{ - Notify: true, - } - c, err := NewClient(nil, testJIRAInstanceURL, config) + c, err := NewClient(nil, testJIRAInstanceURL) if err != nil { t.Errorf("Client creation -> Got an error: %s", err) } @@ -503,10 +464,7 @@ func TestBasicAuthTransport(t *testing.T) { Password: password, } - config = ServiceConfig{ - Notify: true, - } - basicAuthClient, _ := NewClient(tp.Client(), testServer.URL, config) + basicAuthClient, _ := NewClient(tp.Client(), testServer.URL) req, _ := basicAuthClient.NewRequest("GET", ".", nil) basicAuthClient.Do(req, nil) } @@ -557,10 +515,7 @@ func TestCookieAuthTransport_SessionObject_Exists(t *testing.T) { SessionObject: []*http.Cookie{testCookie}, } - config = ServiceConfig{ - Notify: true, - } - basicAuthClient, _ := NewClient(tp.Client(), testServer.URL, config) + basicAuthClient, _ := NewClient(tp.Client(), testServer.URL) req, _ := basicAuthClient.NewRequest("GET", ".", nil) basicAuthClient.Do(req, nil) } @@ -596,10 +551,7 @@ func TestCookieAuthTransport_SessionObject_ExistsWithEmptyCookie(t *testing.T) { SessionObject: []*http.Cookie{emptyCookie, testCookie}, } - config = ServiceConfig{ - Notify: true, - } - basicAuthClient, _ := NewClient(tp.Client(), testServer.URL, config) + basicAuthClient, _ := NewClient(tp.Client(), testServer.URL) req, _ := basicAuthClient.NewRequest("GET", ".", nil) basicAuthClient.Do(req, nil) } @@ -640,10 +592,7 @@ func TestCookieAuthTransport_SessionObject_DoesNotExist(t *testing.T) { AuthURL: ts.URL, } - config = ServiceConfig{ - Notify: true, - } - basicAuthClient, _ := NewClient(tp.Client(), testServer.URL, config) + basicAuthClient, _ := NewClient(tp.Client(), testServer.URL) req, _ := basicAuthClient.NewRequest("GET", ".", nil) basicAuthClient.Do(req, nil) }