1
0
mirror of https://github.com/interviewstreet/go-jira.git synced 2025-06-14 23:45:03 +02:00

Instead of baking config into the client, adds a method call that allows options to be passed in

This commit is contained in:
spmassot
2018-10-17 15:17:08 -04:00
parent 00a32a0fd7
commit 9049c9ff74
10 changed files with 62 additions and 104 deletions

View File

@ -67,7 +67,7 @@ import (
) )
func main() { 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) issue, _, _ := jiraClient.Issue.Get("MESOS-3325", nil)
fmt.Printf("%s: %+v\n", issue.Key, issue.Fields.Summary) fmt.Printf("%s: %+v\n", issue.Key, issue.Fields.Summary)
@ -98,7 +98,7 @@ func main() {
Password: "token", 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") u, _, err := client.User.Get("some_user")
@ -136,7 +136,7 @@ func main() {
Password: "token", Password: "token",
} }
jiraClient, err := jira.NewClient(tp.Client(), base, true) jiraClient, err := jira.NewClient(tp.Client(), base)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -189,7 +189,7 @@ func main() {
Password: "token", 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) req, _ := jiraClient.NewRequest("GET", "rest/api/2/project", nil)
projects := new([]jira.Project) projects := new([]jira.Project)

View File

@ -29,10 +29,7 @@ func main() {
Password: strings.TrimSpace(password), Password: strings.TrimSpace(password),
} }
config = jira.ServiceConfig{ client, err := jira.NewClient(tp.Client(), strings.TrimSpace(jiraURL))
Notify: true,
}
client, err := jira.NewClient(tp.Client(), strings.TrimSpace(jiraURL), config)
if err != nil { if err != nil {
fmt.Printf("\nerror: %v\n", err) fmt.Printf("\nerror: %v\n", err)
return return

View File

@ -29,10 +29,7 @@ func main() {
Password: strings.TrimSpace(password), Password: strings.TrimSpace(password),
} }
config = jira.ServiceConfig{ client, err := jira.NewClient(tp.Client(), strings.TrimSpace(jiraURL))
Notify: true,
}
client, err := jira.NewClient(tp.Client(), strings.TrimSpace(jiraURL), config)
if err != nil { if err != nil {
fmt.Printf("\nerror: %v\n", err) fmt.Printf("\nerror: %v\n", err)
return return

View File

@ -7,10 +7,7 @@ import (
) )
func main() { func main() {
config = jira.ServiceConfig{ jiraClient, _ := jira.NewClient(nil, "https://jira.atlassian.com/")
Notify: true,
}
jiraClient, _ := jira.NewClient(nil, "https://jira.atlassian.com/", config)
req, _ := jiraClient.NewRequest("GET", "/rest/api/2/project", nil) req, _ := jiraClient.NewRequest("GET", "/rest/api/2/project", nil)
projects := new([]jira.Project) projects := new([]jira.Project)

View File

@ -14,10 +14,7 @@ func main() {
} }
client := &http.Client{Transport: tr} client := &http.Client{Transport: tr}
config = jira.ServiceConfig{ jiraClient, _ := jira.NewClient(client, "https://issues.apache.org/jira/")
Notify: true,
}
jiraClient, _ := jira.NewClient(client, "https://issues.apache.org/jira/", config)
issue, _, _ := jiraClient.Issue.Get("MESOS-3325", nil) issue, _, _ := jiraClient.Issue.Get("MESOS-3325", nil)
fmt.Printf("%s: %+v\n", issue.Key, issue.Fields.Summary) fmt.Printf("%s: %+v\n", issue.Key, issue.Fields.Summary)

View File

@ -7,10 +7,7 @@ import (
) )
func main() { func main() {
config = jira.ServiceConfig{ jiraClient, _ := jira.NewClient(nil, "https://issues.apache.org/jira/")
Notify: true,
}
jiraClient, _ := jira.NewClient(nil, "https://issues.apache.org/jira/", config)
issue, _, _ := jiraClient.Issue.Get("MESOS-3325", nil) issue, _, _ := jiraClient.Issue.Get("MESOS-3325", nil)
fmt.Printf("%s: %+v\n", issue.Key, issue.Fields.Summary) fmt.Printf("%s: %+v\n", issue.Key, issue.Fields.Summary)

View File

@ -42,10 +42,7 @@ func main() {
tp = ba.Client() tp = ba.Client()
} }
config = jira.ServiceConfig{ client, err := jira.NewClient(tp, strings.TrimSpace(jiraURL))
Notify: true,
}
client, err := jira.NewClient(tp, strings.TrimSpace(jiraURL), config)
if err != nil { if err != nil {
fmt.Printf("\nerror: %v\n", err) fmt.Printf("\nerror: %v\n", err)
return return

View File

@ -27,12 +27,13 @@ const (
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue // JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue
type IssueService struct { type IssueService struct {
client *Client client *Client
Config *ServiceConfig
} }
// ServiceConfig describes some config options that apply to many/all calls made by the service // UpdateOptions specifies the optional parameters to the Edit issue
type ServiceConfig struct { type UpdateOptions struct {
Notify bool NotifyUsers bool `url:"notifyUsers,omitempty"`
OverrideScreenSecurity bool `url:"overrideScreenSecurity,omitempty"`
OverrideEditableFlag bool `url:"overrideEditableFlag,omitempty"`
} }
// Issue represents a JIRA issue. // Issue represents a JIRA issue.
@ -655,11 +656,37 @@ func (s *IssueService) Create(issue *Issue) (*Issue, *Response, error) {
return responseIssue, resp, nil 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. // 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 // JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-editIssue
func (s *IssueService) Update(issue *Issue) (*Issue, *Response, error) { 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) req, err := s.client.NewRequest("PUT", apiEndpoint, issue)
if err != nil { if err != nil {
return nil, nil, err 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 // 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) { 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) req, err := s.client.NewRequest("PUT", apiEndpoint, data)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -50,7 +50,7 @@ type Client struct {
// As an alternative you can use Session Cookie based authentication provided by this package as well. // 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 // 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. // 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 { if httpClient == nil {
httpClient = http.DefaultClient httpClient = http.DefaultClient
} }
@ -70,7 +70,7 @@ func NewClient(httpClient *http.Client, baseURL string, config *ServiceConfig) (
baseURL: parsedBaseURL, baseURL: parsedBaseURL,
} }
c.Authentication = &AuthenticationService{client: c} c.Authentication = &AuthenticationService{client: c}
c.Issue = &IssueService{client: c, Config: config} c.Issue = &IssueService{client: c}
c.Project = &ProjectService{client: c} c.Project = &ProjectService{client: c}
c.Board = &BoardService{client: c} c.Board = &BoardService{client: c}
c.Sprint = &SprintService{client: c} c.Sprint = &SprintService{client: c}

View File

@ -38,10 +38,7 @@ func setup() {
testServer = httptest.NewServer(testMux) testServer = httptest.NewServer(testMux)
// jira client configured to use test server // jira client configured to use test server
config = ServiceConfig{ testClient, _ = NewClient(nil, testServer.URL)
Notify: true,
}
testClient, _ = NewClient(nil, testServer.URL, config)
} }
// teardown closes the test HTTP server. // 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) { func TestNewClient_WrongUrl(t *testing.T) {
config = ServiceConfig{ c, err := NewClient(nil, "://issues.apache.org/jira/")
Notify: true,
}
c, err := NewClient(nil, "://issues.apache.org/jira/", config)
if err == nil { if err == nil {
t.Error("Expected an error. Got none") t.Error("Expected an error. Got none")
@ -78,10 +72,7 @@ func TestNewClient_WrongUrl(t *testing.T) {
func TestNewClient_WithHttpClient(t *testing.T) { func TestNewClient_WithHttpClient(t *testing.T) {
httpClient := http.DefaultClient httpClient := http.DefaultClient
httpClient.Timeout = 10 * time.Minute httpClient.Timeout = 10 * time.Minute
config = ServiceConfig{ c, err := NewClient(httpClient, testJIRAInstanceURL)
Notify: true,
}
c, err := NewClient(httpClient, testJIRAInstanceURL, config)
if err != nil { if err != nil {
t.Errorf("Got an error: %s", err) t.Errorf("Got an error: %s", err)
@ -95,10 +86,7 @@ func TestNewClient_WithHttpClient(t *testing.T) {
} }
func TestNewClient_WithServices(t *testing.T) { func TestNewClient_WithServices(t *testing.T) {
config = ServiceConfig{ c, err := NewClient(nil, testJIRAInstanceURL)
Notify: true,
}
c, err := NewClient(nil, testJIRAInstanceURL, config)
if err != nil { if err != nil {
t.Errorf("Got an error: %s", err) t.Errorf("Got an error: %s", err)
@ -154,10 +142,7 @@ func TestCheckResponse(t *testing.T) {
} }
func TestClient_NewRequest(t *testing.T) { func TestClient_NewRequest(t *testing.T) {
config = ServiceConfig{ c, err := NewClient(nil, testJIRAInstanceURL)
Notify: true,
}
c, err := NewClient(nil, testJIRAInstanceURL, config)
if err != nil { if err != nil {
t.Errorf("An error occurred. Expected nil. Got %+v.", err) 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) { func TestClient_NewRawRequest(t *testing.T) {
config = ServiceConfig{ c, err := NewClient(nil, testJIRAInstanceURL)
Notify: true,
}
c, err := NewClient(nil, testJIRAInstanceURL, config)
if err != nil { if err != nil {
t.Errorf("An error occurred. Expected nil. Got %+v.", err) 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) { func TestClient_NewRequest_BadURL(t *testing.T) {
config = ServiceConfig{ c, err := NewClient(nil, testJIRAInstanceURL)
Notify: true,
}
c, err := NewClient(nil, testJIRAInstanceURL, config)
if err != nil { if err != nil {
t.Errorf("An error occurred. Expected nil. Got %+v.", err) 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) { func TestClient_NewRequest_SessionCookies(t *testing.T) {
config = ServiceConfig{ c, err := NewClient(nil, testJIRAInstanceURL)
Notify: true,
}
c, err := NewClient(nil, testJIRAInstanceURL, config)
if err != nil { if err != nil {
t.Errorf("An error occurred. Expected nil. Got %+v.", err) 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) { func TestClient_NewRequest_BasicAuth(t *testing.T) {
config = ServiceConfig{ c, err := NewClient(nil, testJIRAInstanceURL)
Notify: true,
}
c, err := NewClient(nil, testJIRAInstanceURL, config)
if err != nil { if err != nil {
t.Errorf("An error occurred. Expected nil. Got %+v.", err) 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. // 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. // However in certain cases, intermediate systems may treat these differently resulting in subtle errors.
func TestClient_NewRequest_EmptyBody(t *testing.T) { func TestClient_NewRequest_EmptyBody(t *testing.T) {
config = ServiceConfig{ c, err := NewClient(nil, testJIRAInstanceURL)
Notify: true,
}
c, err := NewClient(nil, testJIRAInstanceURL, config)
if err != nil { if err != nil {
t.Errorf("An error occurred. Expected nil. Got %+v.", err) 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) { func TestClient_NewMultiPartRequest(t *testing.T) {
config = ServiceConfig{ c, err := NewClient(nil, testJIRAInstanceURL)
Notify: true,
}
c, err := NewClient(nil, testJIRAInstanceURL, config)
if err != nil { if err != nil {
t.Errorf("An error occurred. Expected nil. Got %+v.", err) 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) { func TestClient_NewMultiPartRequest_BasicAuth(t *testing.T) {
config = ServiceConfig{ c, err := NewClient(nil, testJIRAInstanceURL)
Notify: true,
}
c, err := NewClient(nil, testJIRAInstanceURL, config)
if err != nil { if err != nil {
t.Errorf("An error occurred. Expected nil. Got %+v.", err) 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) t.Errorf("URL parsing -> Got an error: %s", err)
} }
config = ServiceConfig{ c, err := NewClient(nil, testJIRAInstanceURL)
Notify: true,
}
c, err := NewClient(nil, testJIRAInstanceURL, config)
if err != nil { if err != nil {
t.Errorf("Client creation -> Got an error: %s", err) t.Errorf("Client creation -> Got an error: %s", err)
} }
@ -503,10 +464,7 @@ func TestBasicAuthTransport(t *testing.T) {
Password: password, Password: password,
} }
config = ServiceConfig{ basicAuthClient, _ := NewClient(tp.Client(), testServer.URL)
Notify: true,
}
basicAuthClient, _ := NewClient(tp.Client(), testServer.URL, config)
req, _ := basicAuthClient.NewRequest("GET", ".", nil) req, _ := basicAuthClient.NewRequest("GET", ".", nil)
basicAuthClient.Do(req, nil) basicAuthClient.Do(req, nil)
} }
@ -557,10 +515,7 @@ func TestCookieAuthTransport_SessionObject_Exists(t *testing.T) {
SessionObject: []*http.Cookie{testCookie}, SessionObject: []*http.Cookie{testCookie},
} }
config = ServiceConfig{ basicAuthClient, _ := NewClient(tp.Client(), testServer.URL)
Notify: true,
}
basicAuthClient, _ := NewClient(tp.Client(), testServer.URL, config)
req, _ := basicAuthClient.NewRequest("GET", ".", nil) req, _ := basicAuthClient.NewRequest("GET", ".", nil)
basicAuthClient.Do(req, nil) basicAuthClient.Do(req, nil)
} }
@ -596,10 +551,7 @@ func TestCookieAuthTransport_SessionObject_ExistsWithEmptyCookie(t *testing.T) {
SessionObject: []*http.Cookie{emptyCookie, testCookie}, SessionObject: []*http.Cookie{emptyCookie, testCookie},
} }
config = ServiceConfig{ basicAuthClient, _ := NewClient(tp.Client(), testServer.URL)
Notify: true,
}
basicAuthClient, _ := NewClient(tp.Client(), testServer.URL, config)
req, _ := basicAuthClient.NewRequest("GET", ".", nil) req, _ := basicAuthClient.NewRequest("GET", ".", nil)
basicAuthClient.Do(req, nil) basicAuthClient.Do(req, nil)
} }
@ -640,10 +592,7 @@ func TestCookieAuthTransport_SessionObject_DoesNotExist(t *testing.T) {
AuthURL: ts.URL, AuthURL: ts.URL,
} }
config = ServiceConfig{ basicAuthClient, _ := NewClient(tp.Client(), testServer.URL)
Notify: true,
}
basicAuthClient, _ := NewClient(tp.Client(), testServer.URL, config)
req, _ := basicAuthClient.NewRequest("GET", ".", nil) req, _ := basicAuthClient.NewRequest("GET", ".", nil)
basicAuthClient.Do(req, nil) basicAuthClient.Do(req, nil)
} }