Skip to content

Commit ff38af3

Browse files
committed
Merge branch 'mcl-de-fk_marshal'
* mcl-de-fk_marshal: (26 commits) Changelog: Internal: Replaced `io.ReadAll` and `json.Unmarshal` with `json.NewDecoder` On premise/Issue: Fix test data On premise/Authentication: Return error where possible CHANGELOG: Workflow status categories: Revisited and fully implemented for Cloud and On Premise (incl. examples) On premise/Status category: Added an additional test check On premise/Status category: Fixed godoc and links to Jira documentation Cloud/Status category: Added empty line to improve readability Cloud/Status category: fixed error message if no status category id is given On premise/Status category: Add comments for usage example Cloud/Status category: Add comments for usage example Cloud/Status category: Added two additional testing checks Cloud/Status Category: Smaller godoc changes Updated changelog with latest changes README.md: fix example URLs ♻️ IssueCategory Service reviewed README: API-Version: Official support for Jira Cloud API in version 3 PersonalAccessToken Auth: Used fmt.Sprintf to concat a string Updated changelog with latest changes README: Add chapter about executing unit tests Makefile: Add commands for testing coverage ...
2 parents 4f97699 + 221b42e commit ff38af3

14 files changed

+174
-228
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ client.Project.GetAll(ctx, &GetQueryOptions{})
357357

358358
* Replace all "GET", "POST", ... with http.MethodGet (and related) constants
359359
* Development: Added `make` commands to collect (unit) test coverage
360+
* Internal: Replaced `io.ReadAll` and `json.Unmarshal` with `json.NewDecoder`
360361

361362
### Changes
362363

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,11 @@ func main() {
223223
}
224224
```
225225
### Get all the issues for JQL with Pagination
226+
226227
Jira API has limit on maxResults it can return. You may have a usecase where you need to get all issues for given JQL.
227-
This example shows reference implementation of GetAllIssues function which does pagination on Jira API to get all the issues for given JQL
228+
This example shows reference implementation of GetAllIssues function which does pagination on Jira API to get all the issues for given JQL.
228229

229-
please look at [Pagination Example](https://github.com/andygrunwald/go-jira/blob/main/cloud/examples/pagination/main.go)
230+
Please look at [Pagination Example](https://github.com/andygrunwald/go-jira/blob/main/cloud/examples/pagination/main.go)
230231

231232
### Call a not implemented API endpoint
232233

cloud/authentication.go

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"context"
55
"encoding/json"
66
"fmt"
7-
"io"
87
"net/http"
98
)
109

@@ -74,17 +73,16 @@ func (s *AuthenticationService) AcquireSessionCookie(ctx context.Context, userna
7473

7574
session := new(Session)
7675
resp, err := s.client.Do(req, session)
77-
78-
if resp != nil {
79-
session.Cookies = resp.Cookies()
80-
}
81-
8276
if err != nil {
83-
return false, fmt.Errorf("auth at Jira instance failed (HTTP(S) request). %s", err)
77+
return false, fmt.Errorf("auth at Jira instance failed (HTTP(S) request). %w", err)
8478
}
79+
8580
if resp != nil && resp.StatusCode != 200 {
8681
return false, fmt.Errorf("auth at Jira instance failed (HTTP(S) request). Status code: %d", resp.StatusCode)
8782
}
83+
if resp != nil {
84+
session.Cookies = resp.Cookies()
85+
}
8886

8987
s.client.session = session
9088
s.authType = authTypeSession
@@ -128,12 +126,12 @@ func (s *AuthenticationService) Logout(ctx context.Context) error {
128126
apiEndpoint := "rest/auth/1/session"
129127
req, err := s.client.NewRequest(ctx, http.MethodDelete, apiEndpoint, nil)
130128
if err != nil {
131-
return fmt.Errorf("creating the request to log the user out failed : %s", err)
129+
return fmt.Errorf("creating the request to log the user out failed : %w", err)
132130
}
133131

134132
resp, err := s.client.Do(req, nil)
135133
if err != nil {
136-
return fmt.Errorf("error sending the logout request: %s", err)
134+
return fmt.Errorf("error sending the logout request: %w", err)
137135
}
138136
defer resp.Body.Close()
139137
if resp.StatusCode != 204 {
@@ -161,27 +159,22 @@ func (s *AuthenticationService) GetCurrentUser(ctx context.Context) (*Session, e
161159
apiEndpoint := "rest/auth/1/session"
162160
req, err := s.client.NewRequest(ctx, http.MethodGet, apiEndpoint, nil)
163161
if err != nil {
164-
return nil, fmt.Errorf("could not create request for getting user info : %s", err)
162+
return nil, fmt.Errorf("could not create request for getting user info: %w", err)
165163
}
166164

167165
resp, err := s.client.Do(req, nil)
168166
if err != nil {
169-
return nil, fmt.Errorf("error sending request to get user info : %s", err)
167+
return nil, fmt.Errorf("error sending request to get user info: %w", err)
170168
}
171169
defer resp.Body.Close()
172170
if resp.StatusCode != 200 {
173171
return nil, fmt.Errorf("getting user info failed with status : %d", resp.StatusCode)
174172
}
175-
ret := new(Session)
176-
data, err := io.ReadAll(resp.Body)
177-
if err != nil {
178-
return nil, fmt.Errorf("couldn't read body from the response : %s", err)
179-
}
180-
181-
err = json.Unmarshal(data, &ret)
182173

174+
ret := new(Session)
175+
err = json.NewDecoder(resp.Body).Decode(&ret)
183176
if err != nil {
184-
return nil, fmt.Errorf("could not unmarshall received user info : %s", err)
177+
return nil, err
185178
}
186179

187180
return ret, nil

cloud/issue.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -785,22 +785,20 @@ func (s *IssueService) Create(ctx context.Context, issue *Issue) (*Issue, *Respo
785785
if err != nil {
786786
return nil, nil, err
787787
}
788+
788789
resp, err := s.client.Do(req, nil)
789790
if err != nil {
790791
// incase of error return the resp for further inspection
791792
return nil, resp, err
792793
}
794+
defer resp.Body.Close()
793795

794796
responseIssue := new(Issue)
795-
defer resp.Body.Close()
796-
data, err := io.ReadAll(resp.Body)
797+
err = json.NewDecoder(resp.Body).Decode(&responseIssue)
797798
if err != nil {
798-
return nil, resp, fmt.Errorf("could not read the returned data")
799-
}
800-
err = json.Unmarshal(data, responseIssue)
801-
if err != nil {
802-
return nil, resp, fmt.Errorf("could not unmarshall the data into struct")
799+
return nil, resp, err
803800
}
801+
804802
return responseIssue, resp, nil
805803
}
806804

cloud/issue_test.go

Lines changed: 56 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -945,70 +945,69 @@ func TestIssueService_DoTransitionWithPayload(t *testing.T) {
945945

946946
func TestIssueFields_TestMarshalJSON_PopulateUnknownsSuccess(t *testing.T) {
947947
data := `{
948-
"customfield_123":"test",
949-
"description":"example bug report",
950-
"project":{
951-
"self":"http://www.example.com/jira/rest/api/2/project/EX",
948+
"customfield_123":"test",
949+
"description":"example bug report",
950+
"project":{
951+
"self":"http://www.example.com/jira/rest/api/2/project/EX",
952+
"id":"10000",
953+
"key":"EX",
954+
"name":"Example",
955+
"avatarUrls":{
956+
"48x48":"http://www.example.com/jira/secure/projectavatar?size=large&pid=10000",
957+
"24x24":"http://www.example.com/jira/secure/projectavatar?size=small&pid=10000",
958+
"16x16":"http://www.example.com/jira/secure/projectavatar?size=xsmall&pid=10000",
959+
"32x32":"http://www.example.com/jira/secure/projectavatar?size=medium&pid=10000"
960+
},
961+
"projectCategory":{
962+
"self":"http://www.example.com/jira/rest/api/2/projectCategory/10000",
963+
"id":"10000",
964+
"name":"FIRST",
965+
"description":"First Project Category"
966+
}
967+
},
968+
"issuelinks":[
969+
{
970+
"id":"10001",
971+
"type":{
952972
"id":"10000",
953-
"key":"EX",
954-
"name":"Example",
955-
"avatarUrls":{
956-
"48x48":"http://www.example.com/jira/secure/projectavatar?size=large&pid=10000",
957-
"24x24":"http://www.example.com/jira/secure/projectavatar?size=small&pid=10000",
958-
"16x16":"http://www.example.com/jira/secure/projectavatar?size=xsmall&pid=10000",
959-
"32x32":"http://www.example.com/jira/secure/projectavatar?size=medium&pid=10000"
973+
"name":"Dependent",
974+
"inward":"depends on",
975+
"outward":"is depended by"
960976
},
961-
"projectCategory":{
962-
"self":"http://www.example.com/jira/rest/api/2/projectCategory/10000",
963-
"id":"10000",
964-
"name":"FIRST",
965-
"description":"First Project Category"
977+
"outwardIssue":{
978+
"id":"10004L",
979+
"key":"PRJ-2",
980+
"self":"http://www.example.com/jira/rest/api/2/issue/PRJ-2",
981+
"fields":{
982+
"status":{
983+
"iconUrl":"http://www.example.com/jira//images/icons/statuses/open.png",
984+
"name":"Open"
985+
}
986+
}
966987
}
967988
},
968-
"issuelinks":[
969-
{
970-
"id":"10001",
971-
"type":{
972-
"id":"10000",
973-
"name":"Dependent",
974-
"inward":"depends on",
975-
"outward":"is depended by"
976-
},
977-
"outwardIssue":{
978-
"id":"10004L",
979-
"key":"PRJ-2",
980-
"self":"http://www.example.com/jira/rest/api/2/issue/PRJ-2",
981-
"fields":{
982-
"status":{
983-
"iconUrl":"http://www.example.com/jira//images/icons/statuses/open.png",
984-
"name":"Open"
985-
}
986-
}
987-
}
989+
{
990+
"id":"10002",
991+
"type":{
992+
"id":"10000",
993+
"name":"Dependent",
994+
"inward":"depends on",
995+
"outward":"is depended by"
988996
},
989-
{
990-
"id":"10002",
991-
"type":{
992-
"id":"10000",
993-
"name":"Dependent",
994-
"inward":"depends on",
995-
"outward":"is depended by"
996-
},
997-
"inwardIssue":{
998-
"id":"10004",
999-
"key":"PRJ-3",
1000-
"self":"http://www.example.com/jira/rest/api/2/issue/PRJ-3",
1001-
"fields":{
1002-
"status":{
1003-
"iconUrl":"http://www.example.com/jira//images/icons/statuses/open.png",
1004-
"name":"Open"
1005-
}
1006-
}
997+
"inwardIssue":{
998+
"id":"10004",
999+
"key":"PRJ-3",
1000+
"self":"http://www.example.com/jira/rest/api/2/issue/PRJ-3",
1001+
"fields":{
1002+
"status":{
1003+
"iconUrl":"http://www.example.com/jira//images/icons/statuses/open.png",
1004+
"name":"Open"
10071005
}
10081006
}
1009-
]
1010-
1011-
}`
1007+
}
1008+
}
1009+
]
1010+
}`
10121011

10131012
i := new(IssueFields)
10141013
err := json.Unmarshal([]byte(data), i)

cloud/issuelinktype.go

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"context"
55
"encoding/json"
66
"fmt"
7-
"io"
87
"net/http"
98
)
109

@@ -63,19 +62,14 @@ func (s *IssueLinkTypeService) Create(ctx context.Context, linkType *IssueLinkTy
6362
if err != nil {
6463
return nil, resp, err
6564
}
65+
defer resp.Body.Close()
6666

6767
responseLinkType := new(IssueLinkType)
68-
defer resp.Body.Close()
69-
data, err := io.ReadAll(resp.Body)
70-
if err != nil {
71-
e := fmt.Errorf("could not read the returned data")
72-
return nil, resp, NewJiraError(resp, e)
73-
}
74-
err = json.Unmarshal(data, responseLinkType)
68+
err = json.NewDecoder(resp.Body).Decode(&responseLinkType)
7569
if err != nil {
76-
e := fmt.Errorf("could no unmarshal the data into struct")
77-
return nil, resp, NewJiraError(resp, e)
70+
return nil, resp, err
7871
}
72+
7973
return linkType, resp, nil
8074
}
8175

cloud/user.go

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"context"
55
"encoding/json"
66
"fmt"
7-
"io"
87
"net/http"
98
)
109

@@ -96,19 +95,14 @@ func (s *UserService) Create(ctx context.Context, user *User) (*User, *Response,
9695
if err != nil {
9796
return nil, resp, err
9897
}
98+
defer resp.Body.Close()
9999

100100
responseUser := new(User)
101-
defer resp.Body.Close()
102-
data, err := io.ReadAll(resp.Body)
103-
if err != nil {
104-
e := fmt.Errorf("could not read the returned data")
105-
return nil, resp, NewJiraError(resp, e)
106-
}
107-
err = json.Unmarshal(data, responseUser)
101+
err = json.NewDecoder(resp.Body).Decode(&responseUser)
108102
if err != nil {
109-
e := fmt.Errorf("could not unmarshall the data into struct")
110-
return nil, resp, NewJiraError(resp, e)
103+
return nil, resp, err
111104
}
105+
112106
return responseUser, resp, nil
113107
}
114108

cloud/version.go

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"context"
55
"encoding/json"
66
"fmt"
7-
"io"
87
"net/http"
98
)
109

@@ -59,19 +58,14 @@ func (s *VersionService) Create(ctx context.Context, version *Version) (*Version
5958
if err != nil {
6059
return nil, resp, err
6160
}
61+
defer resp.Body.Close()
6262

6363
responseVersion := new(Version)
64-
defer resp.Body.Close()
65-
data, err := io.ReadAll(resp.Body)
66-
if err != nil {
67-
e := fmt.Errorf("could not read the returned data")
68-
return nil, resp, NewJiraError(resp, e)
69-
}
70-
err = json.Unmarshal(data, responseVersion)
64+
err = json.NewDecoder(resp.Body).Decode(&responseVersion)
7165
if err != nil {
72-
e := fmt.Errorf("could not unmarshall the data into struct")
73-
return nil, resp, NewJiraError(resp, e)
66+
return nil, resp, err
7467
}
68+
7569
return responseVersion, resp, nil
7670
}
7771

0 commit comments

Comments
 (0)