Skip to content

Commit a014314

Browse files
authored
Merge pull request #585 from andygrunwald/pr-412
Cloud/User: Update User struct
2 parents 07a4e5b + 685151c commit a014314

File tree

3 files changed

+164
-42
lines changed

3 files changed

+164
-42
lines changed

cloud/examples/basic_auth/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func main() {
2121
panic(err)
2222
}
2323

24-
u, _, err := client.User.GetSelf(context.Background())
24+
u, _, err := client.User.GetCurrentUser(context.Background())
2525
if err != nil {
2626
panic(err)
2727
}

cloud/user.go

Lines changed: 51 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,20 @@ type UserService service
1414

1515
// User represents a Jira user.
1616
type User struct {
17-
Self string `json:"self,omitempty" structs:"self,omitempty"`
18-
AccountID string `json:"accountId,omitempty" structs:"accountId,omitempty"`
19-
AccountType string `json:"accountType,omitempty" structs:"accountType,omitempty"`
20-
Name string `json:"name,omitempty" structs:"name,omitempty"`
21-
Key string `json:"key,omitempty" structs:"key,omitempty"`
22-
Password string `json:"-"`
23-
EmailAddress string `json:"emailAddress,omitempty" structs:"emailAddress,omitempty"`
24-
AvatarUrls AvatarUrls `json:"avatarUrls,omitempty" structs:"avatarUrls,omitempty"`
25-
DisplayName string `json:"displayName,omitempty" structs:"displayName,omitempty"`
26-
Active bool `json:"active,omitempty" structs:"active,omitempty"`
27-
TimeZone string `json:"timeZone,omitempty" structs:"timeZone,omitempty"`
28-
Locale string `json:"locale,omitempty" structs:"locale,omitempty"`
29-
ApplicationKeys []string `json:"applicationKeys,omitempty" structs:"applicationKeys,omitempty"`
17+
Self string `json:"self,omitempty" structs:"self,omitempty"`
18+
AccountID string `json:"accountId,omitempty" structs:"accountId,omitempty"`
19+
AccountType string `json:"accountType,omitempty" structs:"accountType,omitempty"`
20+
Name string `json:"name,omitempty" structs:"name,omitempty"`
21+
Key string `json:"key,omitempty" structs:"key,omitempty"`
22+
Password string `json:"-"`
23+
EmailAddress string `json:"emailAddress,omitempty" structs:"emailAddress,omitempty"`
24+
AvatarUrls AvatarUrls `json:"avatarUrls,omitempty" structs:"avatarUrls,omitempty"`
25+
DisplayName string `json:"displayName,omitempty" structs:"displayName,omitempty"`
26+
Active bool `json:"active,omitempty" structs:"active,omitempty"`
27+
TimeZone string `json:"timeZone,omitempty" structs:"timeZone,omitempty"`
28+
Locale string `json:"locale,omitempty" structs:"locale,omitempty"`
29+
Groups UserGroups `json:"groups,omitempty" structs:"groups,omitempty"`
30+
ApplicationRoles ApplicationRoles `json:"applicationRoles,omitempty" structs:"applicationRoles,omitempty"`
3031
}
3132

3233
// UserGroup represents the group list
@@ -35,6 +36,37 @@ type UserGroup struct {
3536
Name string `json:"name,omitempty" structs:"name,omitempty"`
3637
}
3738

39+
// Groups is a wrapper for UserGroup
40+
type UserGroups struct {
41+
Size int `json:"size,omitempty" structs:"size,omitempty"`
42+
Items []UserGroup `json:"items,omitempty" structs:"items,omitempty"`
43+
}
44+
45+
// ApplicationRoles is a wrapper for ApplicationRole
46+
type ApplicationRoles struct {
47+
Size int `json:"size,omitempty" structs:"size,omitempty"`
48+
Items []ApplicationRole `json:"items,omitempty" structs:"items,omitempty"`
49+
}
50+
51+
// ApplicationRole represents a role assigned to a user
52+
type ApplicationRole struct {
53+
Key string `json:"key"`
54+
Groups []string `json:"groups"`
55+
Name string `json:"name"`
56+
DefaultGroups []string `json:"defaultGroups"`
57+
SelectedByDefault bool `json:"selectedByDefault"`
58+
Defined bool `json:"defined"`
59+
NumberOfSeats int `json:"numberOfSeats"`
60+
RemainingSeats int `json:"remainingSeats"`
61+
UserCount int `json:"userCount"`
62+
UserCountDescription string `json:"userCountDescription"`
63+
HasUnlimitedSeats bool `json:"hasUnlimitedSeats"`
64+
Platform bool `json:"platform"`
65+
66+
// Key `groupDetails` missing - https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-application-roles/#api-rest-api-3-applicationrole-key-get
67+
// Key `defaultGroupsDetails` missing - https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-application-roles/#api-rest-api-3-applicationrole-key-get
68+
}
69+
3870
type userSearchParam struct {
3971
name string
4072
value string
@@ -158,23 +190,22 @@ func (s *UserService) GetGroups(ctx context.Context, accountId string) (*[]UserG
158190
return userGroups, resp, nil
159191
}
160192

161-
// GetSelf information about the current logged-in user
162-
//
163-
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-myself-get
193+
// GetCurrentUser returns details for the current user.
164194
//
165-
// TODO Double check this method if this works as expected, is using the latest API and the response is complete
166-
// This double check effort is done for v2 - Remove this two lines if this is completed.
167-
func (s *UserService) GetSelf(ctx context.Context) (*User, *Response, error) {
168-
const apiEndpoint = "rest/api/2/myself"
195+
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-myself/#api-rest-api-3-myself-get
196+
func (s *UserService) GetCurrentUser(ctx context.Context) (*User, *Response, error) {
197+
const apiEndpoint = "rest/api/3/myself"
169198
req, err := s.client.NewRequest(ctx, http.MethodGet, apiEndpoint, nil)
170199
if err != nil {
171200
return nil, nil, err
172201
}
202+
173203
var user User
174204
resp, err := s.client.Do(req, &user)
175205
if err != nil {
176206
return nil, resp, NewJiraError(resp, err)
177207
}
208+
178209
return &user, resp, nil
179210
}
180211

cloud/user_test.go

Lines changed: 112 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,89 @@ func TestUserService_Create(t *testing.T) {
6161
testRequestURL(t, r, "/rest/api/2/user")
6262

6363
w.WriteHeader(http.StatusCreated)
64-
fmt.Fprint(w, `{"name":"charlie","password":"abracadabra","emailAddress":"[email protected]",
65-
"displayName":"Charlie of Atlassian","applicationKeys":["jira-core"]}`)
64+
fmt.Fprint(w, `
65+
{
66+
"name": "charlie",
67+
"password": "abracadabra",
68+
"emailAddress": "[email protected]",
69+
"displayName": "Charlie of Atlassian",
70+
"applicationRoles": {
71+
"size": 1,
72+
"max-results": 1,
73+
"items": [{
74+
"key": "jira-software",
75+
"groups": [
76+
"jira-software-users",
77+
"jira-testers"
78+
],
79+
"name": "Jira Software",
80+
"defaultGroups": [
81+
"jira-software-users"
82+
],
83+
"selectedByDefault": false,
84+
"defined": false,
85+
"numberOfSeats": 10,
86+
"remainingSeats": 5,
87+
"userCount": 5,
88+
"userCountDescription": "5 developers",
89+
"hasUnlimitedSeats": false,
90+
"platform": false
91+
}]
92+
},
93+
"groups": {
94+
"size": 2,
95+
"max-results": 2,
96+
"items": [{
97+
"name": "jira-core",
98+
"self": "jira-core"
99+
},
100+
{
101+
"name": "jira-test",
102+
"self": "jira-test"
103+
}
104+
]
105+
}
106+
}
107+
`)
66108
})
67109

68110
u := &User{
69-
Name: "charlie",
70-
Password: "abracadabra",
71-
EmailAddress: "[email protected]",
72-
DisplayName: "Charlie of Atlassian",
73-
ApplicationKeys: []string{"jira-core"},
111+
Name: "charlie",
112+
Password: "abracadabra",
113+
EmailAddress: "[email protected]",
114+
DisplayName: "Charlie of Atlassian",
115+
Groups: UserGroups{
116+
Size: 2,
117+
Items: []UserGroup{
118+
{
119+
Name: "jira-core",
120+
Self: "jira-core",
121+
},
122+
{
123+
Name: "jira-test",
124+
Self: "jira-test",
125+
},
126+
},
127+
},
128+
ApplicationRoles: ApplicationRoles{
129+
Size: 1,
130+
Items: []ApplicationRole{
131+
{
132+
Key: "jira-software",
133+
Groups: []string{"jira-software-users", "jira-testers"},
134+
Name: "Jira Software",
135+
DefaultGroups: []string{"jira-software-users"},
136+
SelectedByDefault: false,
137+
Defined: false,
138+
NumberOfSeats: 10,
139+
RemainingSeats: 5,
140+
UserCount: 5,
141+
UserCountDescription: "5 developers",
142+
HasUnlimitedSeats: false,
143+
Platform: false,
144+
},
145+
},
146+
},
74147
}
75148

76149
if user, _, err := testClient.User.Create(context.Background(), u); err != nil {
@@ -118,30 +191,48 @@ func TestUserService_GetGroups(t *testing.T) {
118191
}
119192
}
120193

121-
func TestUserService_GetSelf(t *testing.T) {
194+
func TestUserService_GetCurrentUser(t *testing.T) {
122195
setup()
123196
defer teardown()
124-
testMux.HandleFunc("/rest/api/2/myself", func(w http.ResponseWriter, r *http.Request) {
197+
testMux.HandleFunc("/rest/api/3/myself", func(w http.ResponseWriter, r *http.Request) {
125198
testMethod(t, r, http.MethodGet)
126-
testRequestURL(t, r, "/rest/api/2/myself")
199+
testRequestURL(t, r, "/rest/api/3/myself")
127200

128201
w.WriteHeader(http.StatusCreated)
129-
fmt.Fprint(w, `{"self":"http://www.example.com/jira/rest/api/2/user?accountId=000000000000000000000000","key":"fred",
130-
"name":"fred","emailAddress":"[email protected]","avatarUrls":{"48x48":"http://www.example.com/jira/secure/useravatar?size=large&ownerId=fred",
131-
"24x24":"http://www.example.com/jira/secure/useravatar?size=small&ownerId=fred","16x16":"http://www.example.com/jira/secure/useravatar?size=xsmall&ownerId=fred",
132-
"32x32":"http://www.example.com/jira/secure/useravatar?size=medium&ownerId=fred"},"displayName":"Fred F. User","active":true,"timeZone":"Australia/Sydney","groups":{"size":3,"items":[
133-
{"name":"jira-user","self":"http://www.example.com/jira/rest/api/2/group?groupname=jira-user"},{"name":"jira-admin",
134-
"self":"http://www.example.com/jira/rest/api/2/group?groupname=jira-admin"},{"name":"important","self":"http://www.example.com/jira/rest/api/2/group?groupname=important"
135-
}]},"applicationRoles":{"size":1,"items":[]},"expand":"groups,applicationRoles"}`)
202+
fmt.Fprint(w, `{
203+
"self": "https://your-domain.atlassian.net/rest/api/3/user?accountId=5b10a2844c20165700ede21g",
204+
"key": "",
205+
"accountId": "5b10a2844c20165700ede21g",
206+
"accountType": "atlassian",
207+
"name": "",
208+
"emailAddress": "[email protected]",
209+
"avatarUrls": {
210+
"48x48": "https://avatar-management--avatars.server-location.prod.public.atl-paas.net/initials/MK-5.png?size=48&s=48",
211+
"24x24": "https://avatar-management--avatars.server-location.prod.public.atl-paas.net/initials/MK-5.png?size=24&s=24",
212+
"16x16": "https://avatar-management--avatars.server-location.prod.public.atl-paas.net/initials/MK-5.png?size=16&s=16",
213+
"32x32": "https://avatar-management--avatars.server-location.prod.public.atl-paas.net/initials/MK-5.png?size=32&s=32"
214+
},
215+
"displayName": "Mia Krystof",
216+
"active": true,
217+
"timeZone": "Australia/Sydney",
218+
"groups": {
219+
"size": 3,
220+
"items": []
221+
},
222+
"applicationRoles": {
223+
"size": 1,
224+
"items": []
225+
}
226+
}`)
136227
})
137228

138-
if user, _, err := testClient.User.GetSelf(context.Background()); err != nil {
229+
if user, _, err := testClient.User.GetCurrentUser(context.Background()); err != nil {
139230
t.Errorf("Error given: %s", err)
231+
140232
} else if user == nil {
141233
t.Error("Expected user groups. []UserGroup is nil")
142-
} else if user.Name != "fred" ||
143-
!user.Active ||
144-
user.DisplayName != "Fred F. User" {
234+
235+
} else if user.EmailAddress != "[email protected]" || !user.Active || user.DisplayName != "Mia Krystof" {
145236
t.Errorf("User JSON deserialized incorrectly")
146237
}
147238
}

0 commit comments

Comments
 (0)