Loading testdata/get_user_status.json 0 → 100644 +7 −0 Original line number Diff line number Diff line { "emoji": "red_circle", "message": "Duly swamped", "availability": "busy", "message_html": "Duly swamped", "clear_status_at": null } testing/users_mock.go +6 −6 Original line number Diff line number Diff line Loading @@ -1775,9 +1775,9 @@ func (c *MockUsersServiceInterfaceGetUserMembershipsCall) DoAndReturn(f func(int } // GetUserStatus mocks base method. func (m *MockUsersServiceInterface) GetUserStatus(user int, options ...gitlab.RequestOptionFunc) (*gitlab.UserStatus, *gitlab.Response, error) { func (m *MockUsersServiceInterface) GetUserStatus(uid any, options ...gitlab.RequestOptionFunc) (*gitlab.UserStatus, *gitlab.Response, error) { m.ctrl.T.Helper() varargs := []any{user} varargs := []any{uid} for _, a := range options { varargs = append(varargs, a) } Loading @@ -1789,9 +1789,9 @@ func (m *MockUsersServiceInterface) GetUserStatus(user int, options ...gitlab.Re } // GetUserStatus indicates an expected call of GetUserStatus. func (mr *MockUsersServiceInterfaceMockRecorder) GetUserStatus(user any, options ...any) *MockUsersServiceInterfaceGetUserStatusCall { func (mr *MockUsersServiceInterfaceMockRecorder) GetUserStatus(uid any, options ...any) *MockUsersServiceInterfaceGetUserStatusCall { mr.mock.ctrl.T.Helper() varargs := append([]any{user}, options...) varargs := append([]any{uid}, options...) call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserStatus", reflect.TypeOf((*MockUsersServiceInterface)(nil).GetUserStatus), varargs...) return &MockUsersServiceInterfaceGetUserStatusCall{Call: call} } Loading @@ -1808,13 +1808,13 @@ func (c *MockUsersServiceInterfaceGetUserStatusCall) Return(arg0 *gitlab.UserSta } // Do rewrite *gomock.Call.Do func (c *MockUsersServiceInterfaceGetUserStatusCall) Do(f func(int, ...gitlab.RequestOptionFunc) (*gitlab.UserStatus, *gitlab.Response, error)) *MockUsersServiceInterfaceGetUserStatusCall { func (c *MockUsersServiceInterfaceGetUserStatusCall) Do(f func(any, ...gitlab.RequestOptionFunc) (*gitlab.UserStatus, *gitlab.Response, error)) *MockUsersServiceInterfaceGetUserStatusCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn func (c *MockUsersServiceInterfaceGetUserStatusCall) DoAndReturn(f func(int, ...gitlab.RequestOptionFunc) (*gitlab.UserStatus, *gitlab.Response, error)) *MockUsersServiceInterfaceGetUserStatusCall { func (c *MockUsersServiceInterfaceGetUserStatusCall) DoAndReturn(f func(any, ...gitlab.RequestOptionFunc) (*gitlab.UserStatus, *gitlab.Response, error)) *MockUsersServiceInterfaceGetUserStatusCall { c.Call = c.Call.DoAndReturn(f) return c } Loading users.go +13 −4 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import ( "io" "net" "net/http" "strings" "time" "github.com/hashicorp/go-retryablehttp" Loading @@ -37,7 +38,7 @@ type ( DeleteUser(user int, options ...RequestOptionFunc) (*Response, error) CurrentUser(options ...RequestOptionFunc) (*User, *Response, error) CurrentUserStatus(options ...RequestOptionFunc) (*UserStatus, *Response, error) GetUserStatus(user int, options ...RequestOptionFunc) (*UserStatus, *Response, error) GetUserStatus(uid any, options ...RequestOptionFunc) (*UserStatus, *Response, error) SetUserStatus(opt *UserStatusOptions, options ...RequestOptionFunc) (*UserStatus, *Response, error) GetUserAssociationsCount(user int, options ...RequestOptionFunc) (*UserAssociationsCount, *Response, error) ListSSHKeys(opt *ListSSHKeysOptions, options ...RequestOptionFunc) ([]*SSHKey, *Response, error) Loading Loading @@ -482,12 +483,20 @@ func (s *UsersService) CurrentUserStatus(options ...RequestOptionFunc) (*UserSta return status, resp, nil } // GetUserStatus retrieves a user's status // GetUserStatus retrieves a user's status. // // uid can be either a user ID (int) or a username (string); will trim one "@" character off the username, if present. // Other types will cause an error to be returned. // // GitLab API docs: // https://docs.gitlab.com/api/users/#get-the-status-of-a-user func (s *UsersService) GetUserStatus(user int, options ...RequestOptionFunc) (*UserStatus, *Response, error) { u := fmt.Sprintf("users/%d/status", user) func (s *UsersService) GetUserStatus(uid any, options ...RequestOptionFunc) (*UserStatus, *Response, error) { user, err := parseID(uid) if err != nil { return nil, nil, err } u := fmt.Sprintf("users/%s/status", strings.TrimPrefix(user, "@")) req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { Loading users_test.go +60 −0 Original line number Diff line number Diff line Loading @@ -1047,3 +1047,63 @@ func TestDeleteUserIdentity(t *testing.T) { assert.NoError(t, err) assert.NotNil(t, resp) } func TestGetUserStatus(t *testing.T) { t.Parallel() tests := []struct { name string uid any path string wantErr error }{ { name: "numeric user ID", uid: 1, path: "/api/v4/users/1/status", }, { name: "user name", uid: "johndoe", path: "/api/v4/users/johndoe/status", }, { name: "user name with @ prefix", uid: "@johndoe", path: "/api/v4/users/johndoe/status", }, { name: "invalid uid type", uid: User{ID: 1}, path: "/unused", wantErr: ErrInvalidIDType, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { t.Parallel() mux, client := setup(t) mux.HandleFunc(tt.path, func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, http.MethodGet) mustWriteHTTPResponse(t, w, "testdata/get_user_status.json") }) user, _, err := client.Users.GetUserStatus(tt.uid) require.ErrorIs(t, err, tt.wantErr) if tt.wantErr != nil { return } want := &UserStatus{ Emoji: "red_circle", Message: "Duly swamped", Availability: "busy", MessageHTML: "Duly swamped", } require.Equal(t, want, user) }) } } Loading
testdata/get_user_status.json 0 → 100644 +7 −0 Original line number Diff line number Diff line { "emoji": "red_circle", "message": "Duly swamped", "availability": "busy", "message_html": "Duly swamped", "clear_status_at": null }
testing/users_mock.go +6 −6 Original line number Diff line number Diff line Loading @@ -1775,9 +1775,9 @@ func (c *MockUsersServiceInterfaceGetUserMembershipsCall) DoAndReturn(f func(int } // GetUserStatus mocks base method. func (m *MockUsersServiceInterface) GetUserStatus(user int, options ...gitlab.RequestOptionFunc) (*gitlab.UserStatus, *gitlab.Response, error) { func (m *MockUsersServiceInterface) GetUserStatus(uid any, options ...gitlab.RequestOptionFunc) (*gitlab.UserStatus, *gitlab.Response, error) { m.ctrl.T.Helper() varargs := []any{user} varargs := []any{uid} for _, a := range options { varargs = append(varargs, a) } Loading @@ -1789,9 +1789,9 @@ func (m *MockUsersServiceInterface) GetUserStatus(user int, options ...gitlab.Re } // GetUserStatus indicates an expected call of GetUserStatus. func (mr *MockUsersServiceInterfaceMockRecorder) GetUserStatus(user any, options ...any) *MockUsersServiceInterfaceGetUserStatusCall { func (mr *MockUsersServiceInterfaceMockRecorder) GetUserStatus(uid any, options ...any) *MockUsersServiceInterfaceGetUserStatusCall { mr.mock.ctrl.T.Helper() varargs := append([]any{user}, options...) varargs := append([]any{uid}, options...) call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserStatus", reflect.TypeOf((*MockUsersServiceInterface)(nil).GetUserStatus), varargs...) return &MockUsersServiceInterfaceGetUserStatusCall{Call: call} } Loading @@ -1808,13 +1808,13 @@ func (c *MockUsersServiceInterfaceGetUserStatusCall) Return(arg0 *gitlab.UserSta } // Do rewrite *gomock.Call.Do func (c *MockUsersServiceInterfaceGetUserStatusCall) Do(f func(int, ...gitlab.RequestOptionFunc) (*gitlab.UserStatus, *gitlab.Response, error)) *MockUsersServiceInterfaceGetUserStatusCall { func (c *MockUsersServiceInterfaceGetUserStatusCall) Do(f func(any, ...gitlab.RequestOptionFunc) (*gitlab.UserStatus, *gitlab.Response, error)) *MockUsersServiceInterfaceGetUserStatusCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn func (c *MockUsersServiceInterfaceGetUserStatusCall) DoAndReturn(f func(int, ...gitlab.RequestOptionFunc) (*gitlab.UserStatus, *gitlab.Response, error)) *MockUsersServiceInterfaceGetUserStatusCall { func (c *MockUsersServiceInterfaceGetUserStatusCall) DoAndReturn(f func(any, ...gitlab.RequestOptionFunc) (*gitlab.UserStatus, *gitlab.Response, error)) *MockUsersServiceInterfaceGetUserStatusCall { c.Call = c.Call.DoAndReturn(f) return c } Loading
users.go +13 −4 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import ( "io" "net" "net/http" "strings" "time" "github.com/hashicorp/go-retryablehttp" Loading @@ -37,7 +38,7 @@ type ( DeleteUser(user int, options ...RequestOptionFunc) (*Response, error) CurrentUser(options ...RequestOptionFunc) (*User, *Response, error) CurrentUserStatus(options ...RequestOptionFunc) (*UserStatus, *Response, error) GetUserStatus(user int, options ...RequestOptionFunc) (*UserStatus, *Response, error) GetUserStatus(uid any, options ...RequestOptionFunc) (*UserStatus, *Response, error) SetUserStatus(opt *UserStatusOptions, options ...RequestOptionFunc) (*UserStatus, *Response, error) GetUserAssociationsCount(user int, options ...RequestOptionFunc) (*UserAssociationsCount, *Response, error) ListSSHKeys(opt *ListSSHKeysOptions, options ...RequestOptionFunc) ([]*SSHKey, *Response, error) Loading Loading @@ -482,12 +483,20 @@ func (s *UsersService) CurrentUserStatus(options ...RequestOptionFunc) (*UserSta return status, resp, nil } // GetUserStatus retrieves a user's status // GetUserStatus retrieves a user's status. // // uid can be either a user ID (int) or a username (string); will trim one "@" character off the username, if present. // Other types will cause an error to be returned. // // GitLab API docs: // https://docs.gitlab.com/api/users/#get-the-status-of-a-user func (s *UsersService) GetUserStatus(user int, options ...RequestOptionFunc) (*UserStatus, *Response, error) { u := fmt.Sprintf("users/%d/status", user) func (s *UsersService) GetUserStatus(uid any, options ...RequestOptionFunc) (*UserStatus, *Response, error) { user, err := parseID(uid) if err != nil { return nil, nil, err } u := fmt.Sprintf("users/%s/status", strings.TrimPrefix(user, "@")) req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { Loading
users_test.go +60 −0 Original line number Diff line number Diff line Loading @@ -1047,3 +1047,63 @@ func TestDeleteUserIdentity(t *testing.T) { assert.NoError(t, err) assert.NotNil(t, resp) } func TestGetUserStatus(t *testing.T) { t.Parallel() tests := []struct { name string uid any path string wantErr error }{ { name: "numeric user ID", uid: 1, path: "/api/v4/users/1/status", }, { name: "user name", uid: "johndoe", path: "/api/v4/users/johndoe/status", }, { name: "user name with @ prefix", uid: "@johndoe", path: "/api/v4/users/johndoe/status", }, { name: "invalid uid type", uid: User{ID: 1}, path: "/unused", wantErr: ErrInvalidIDType, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { t.Parallel() mux, client := setup(t) mux.HandleFunc(tt.path, func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, http.MethodGet) mustWriteHTTPResponse(t, w, "testdata/get_user_status.json") }) user, _, err := client.Users.GetUserStatus(tt.uid) require.ErrorIs(t, err, tt.wantErr) if tt.wantErr != nil { return } want := &UserStatus{ Emoji: "red_circle", Message: "Duly swamped", Availability: "busy", MessageHTML: "Duly swamped", } require.Equal(t, want, user) }) } }