diff --git a/github/github-accessors.go b/github/github-accessors.go index ec35f2761ed..5094ca66160 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -11340,6 +11340,22 @@ func (u *User) GetURL() string { return *u.URL } +// GetMessage returns the Message field if it's non-nil, zero value otherwise. +func (u *UserContext) GetMessage() string { + if u == nil || u.Message == nil { + return "" + } + return *u.Message +} + +// GetOcticon returns the Octicon field if it's non-nil, zero value otherwise. +func (u *UserContext) GetOcticon() string { + if u == nil || u.Octicon == nil { + return "" + } + return *u.Octicon +} + // GetEmail returns the Email field if it's non-nil, zero value otherwise. func (u *UserEmail) GetEmail() string { if u == nil || u.Email == nil { diff --git a/github/github.go b/github/github.go index 1244e3ec1ab..5e9a671c63a 100644 --- a/github/github.go +++ b/github/github.go @@ -111,6 +111,9 @@ const ( // https://developer.github.com/changes/2018-02-07-team-discussions-api/ mediaTypeTeamDiscussionsPreview = "application/vnd.github.echo-preview+json" + // https://developer.github.com/changes/2018-03-21-hovercard-api-preview/ + mediaTypeHovercardPreview = "application/vnd.github.hagar-preview+json" + // https://developer.github.com/changes/2018-01-10-lock-reason-api-preview/ mediaTypeLockReasonPreview = "application/vnd.github.sailor-v-preview+json" diff --git a/github/users.go b/github/users.go index 7a9d98c546a..5630af173af 100644 --- a/github/users.go +++ b/github/users.go @@ -135,6 +135,57 @@ func (s *UsersService) Edit(ctx context.Context, user *User) (*User, *Response, return uResp, resp, nil } +// HovercardOptions specifies optional parameters to the UsersService.GetHovercard +// method. +type HovercardOptions struct { + // SubjectType specifies the additional information to be received about the hovercard. + // Possible values are: organization, repository, issue, pull_request. (Required when using subject_id.) + SubjectType string `url:"subject_type"` + + // SubjectID specifies the ID for the SubjectType. (Required when using subject_type.) + SubjectID string `url:"subject_id"` +} + + +// Hovercard represents hovercard information about a user. +type Hovercard struct { + Contexts []*UserContext `json:"contexts,omitempty"` +} + +// UserContext represents the contextual information about user. +type UserContext struct { + Message *string `json:"message,omitempty"` + Octicon *string `json:"octicon,omitempty"` +} + +// GetHovercard fetches contextual information about user. It requires authentication +// via Basic Auth or via OAuth with the repo scope. +// +// GitHub API docs: https://developer.github.com/v3/users/#get-contextual-information-about-a-user +func (s *UsersService) GetHovercard(ctx context.Context, user string, opt *HovercardOptions) (*Hovercard, *Response, error) { + u := fmt.Sprintf("users/%v/hovercard", user) + u, err := addOptions(u, opt) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeHovercardPreview) + + hc := new(Hovercard) + resp, err := s.client.Do(ctx, req, hc) + if err != nil { + return nil, resp, err + } + + return hc, resp, nil +} + // UserListOptions specifies optional parameters to the UsersService.ListAll // method. type UserListOptions struct { diff --git a/github/users_test.go b/github/users_test.go index 750b6733de3..b01190871ef 100644 --- a/github/users_test.go +++ b/github/users_test.go @@ -153,6 +153,29 @@ func TestUsersService_Edit(t *testing.T) { } } +func TestUsersService_GetHovercard(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/users/u/hovercard", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeHovercardPreview) + testFormValues(t, r, values{"subject_type": "repository", "subject_id": "20180408"}) + fmt.Fprint(w, `{"contexts": [{"message":"Owns this repository", "octicon": "repo"}]}`) + }) + + opt := &HovercardOptions{SubjectType: "repository", SubjectID: "20180408"} + hovercard, _, err := client.Users.GetHovercard(context.Background(), "u", opt) + if err != nil { + t.Errorf("Users.GetHovercard returned error: %v", err) + } + + want := &Hovercard{Contexts: []*UserContext{{Message: String("Owns this repository"), Octicon: String("repo")}}} + if !reflect.DeepEqual(hovercard, want) { + t.Errorf("Users.GetHovercard returned %+v, want %+v", hovercard, want) + } +} + func TestUsersService_ListAll(t *testing.T) { client, mux, _, teardown := setup() defer teardown()