diff --git a/github/orgs_members.go b/github/orgs_members.go index 80454ada0cd..77f691276c0 100644 --- a/github/orgs_members.go +++ b/github/orgs_members.go @@ -270,3 +270,29 @@ func (s *OrganizationsService) RemoveOrgMembership(user, org string) (*Response, return s.client.Do(req, nil) } + +// ListPendingOrgInvitations returns a list of pending invitations. +// +// GitHub API docs: https://developer.github.com/v3/orgs/members/#list-pending-organization-invitations +func (s *OrganizationsService) ListPendingOrgInvitations(org int, opt *ListOptions) ([]*Invitation, *Response, error) { + u := fmt.Sprintf("orgs/%v/invitations", org) + 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", mediaTypeOrgMembershipPreview) + + pendingInvitations := new([]*Invitation) + resp, err := s.client.Do(req, pendingInvitations) + if err != nil { + return nil, resp, err + } + return *pendingInvitations, resp, err +} diff --git a/github/orgs_members_test.go b/github/orgs_members_test.go index f95e5be6dd5..8a3ff3df560 100644 --- a/github/orgs_members_test.go +++ b/github/orgs_members_test.go @@ -11,6 +11,7 @@ import ( "net/http" "reflect" "testing" + "time" ) func TestOrganizationsService_ListMembers(t *testing.T) { @@ -353,3 +354,81 @@ func TestOrganizationsService_RemoveOrgMembership(t *testing.T) { t.Errorf("Organizations.RemoveOrgMembership returned error: %v", err) } } + +func TestOrganizationsService_ListPendingOrgInvitations(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/orgs/1/invitations", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"page": "1"}) + testHeader(t, r, "Accept", mediaTypeOrgMembershipPreview) + fmt.Fprint(w, `[ + { + "id": 1, + "login": "monalisa", + "email": "octocat@github.com", + "role": "direct_member", + "created_at": "2017-01-21T00:00:00Z", + "inviter": { + "login": "other_user", + "id": 1, + "avatar_url": "https://github.com/images/error/other_user_happy.gif", + "gravatar_id": "", + "url": "https://api.github.com/users/other_user", + "html_url": "https://github.com/other_user", + "followers_url": "https://api.github.com/users/other_user/followers", + "following_url": "https://api.github.com/users/other_user/following/other_user", + "gists_url": "https://api.github.com/users/other_user/gists/gist_id", + "starred_url": "https://api.github.com/users/other_user/starred/owner/repo", + "subscriptions_url": "https://api.github.com/users/other_user/subscriptions", + "organizations_url": "https://api.github.com/users/other_user/orgs", + "repos_url": "https://api.github.com/users/other_user/repos", + "events_url": "https://api.github.com/users/other_user/events/privacy", + "received_events_url": "https://api.github.com/users/other_user/received_events/privacy", + "type": "User", + "site_admin": false + } + } + ]`) + }) + + opt := &ListOptions{Page: 1} + invitations, _, err := client.Organizations.ListPendingOrgInvitations(1, opt) + if err != nil { + t.Errorf("Organizations.ListPendingOrgInvitations returned error: %v", err) + } + + createdAt := time.Date(2017, 01, 21, 0, 0, 0, 0, time.UTC) + want := []*Invitation{ + { + ID: Int(1), + Login: String("monalisa"), + Email: String("octocat@github.com"), + Role: String("direct_member"), + CreatedAt: &createdAt, + Inviter: &User{ + Login: String("other_user"), + ID: Int(1), + AvatarURL: String("https://github.com/images/error/other_user_happy.gif"), + GravatarID: String(""), + URL: String("https://api.github.com/users/other_user"), + HTMLURL: String("https://github.com/other_user"), + FollowersURL: String("https://api.github.com/users/other_user/followers"), + FollowingURL: String("https://api.github.com/users/other_user/following/other_user"), + GistsURL: String("https://api.github.com/users/other_user/gists/gist_id"), + StarredURL: String("https://api.github.com/users/other_user/starred/owner/repo"), + SubscriptionsURL: String("https://api.github.com/users/other_user/subscriptions"), + OrganizationsURL: String("https://api.github.com/users/other_user/orgs"), + ReposURL: String("https://api.github.com/users/other_user/repos"), + EventsURL: String("https://api.github.com/users/other_user/events/privacy"), + ReceivedEventsURL: String("https://api.github.com/users/other_user/received_events/privacy"), + Type: String("User"), + SiteAdmin: Bool(false), + }, + }} + + if !reflect.DeepEqual(invitations, want) { + t.Errorf("Organizations.ListPendingOrgInvitations returned %+v, want %+v", invitations, want) + } +} diff --git a/github/orgs_teams.go b/github/orgs_teams.go index 6afcd1f2ee2..6ef5000b281 100644 --- a/github/orgs_teams.go +++ b/github/orgs_teams.go @@ -44,13 +44,15 @@ func (t Team) String() string { return Stringify(t) } -// Invitation represents a team member's inviation status +// Invitation represents a team member's invitation status. type Invitation struct { - ID *int `json:"id,omitempty"` - Login *string `json:"login,omitempty"` - Email *string `json:"email,omitempty"` + ID *int `json:"id,omitempty"` + Login *string `json:"login,omitempty"` + Email *string `json:"email,omitempty"` + // Role can be one of the values - 'direct_member', 'admin', 'billing_manager', 'hiring_manager', or 'reinstate'. Role *string `json:"role,omitempty"` CreatedAt *time.Time `json:"created_at,omitempty"` + Inviter *User `json:"inviter,omitempty"` } func (i Invitation) String() string { diff --git a/github/orgs_teams_test.go b/github/orgs_teams_test.go index 96cf82d6321..36701f1a456 100644 --- a/github/orgs_teams_test.go +++ b/github/orgs_teams_test.go @@ -11,6 +11,7 @@ import ( "net/http" "reflect" "testing" + "time" ) func TestOrganizationsService_ListTeams(t *testing.T) { @@ -508,7 +509,34 @@ func TestOrganizationsService_ListPendingTeamInvitations(t *testing.T) { testMethod(t, r, "GET") testFormValues(t, r, values{"page": "1"}) testHeader(t, r, "Accept", mediaTypeOrgMembershipPreview) - fmt.Fprint(w, `[{"id":1}]`) + fmt.Fprint(w, `[ + { + "id": 1, + "login": "monalisa", + "email": "octocat@github.com", + "role": "direct_member", + "created_at": "2017-01-21T00:00:00Z", + "inviter": { + "login": "other_user", + "id": 1, + "avatar_url": "https://github.com/images/error/other_user_happy.gif", + "gravatar_id": "", + "url": "https://api.github.com/users/other_user", + "html_url": "https://github.com/other_user", + "followers_url": "https://api.github.com/users/other_user/followers", + "following_url": "https://api.github.com/users/other_user/following/other_user", + "gists_url": "https://api.github.com/users/other_user/gists/gist_id", + "starred_url": "https://api.github.com/users/other_user/starred/owner/repo", + "subscriptions_url": "https://api.github.com/users/other_user/subscriptions", + "organizations_url": "https://api.github.com/users/other_user/orgs", + "repos_url": "https://api.github.com/users/other_user/repos", + "events_url": "https://api.github.com/users/other_user/events/privacy", + "received_events_url": "https://api.github.com/users/other_user/received_events/privacy", + "type": "User", + "site_admin": false + } + } + ]`) }) opt := &ListOptions{Page: 1} @@ -517,7 +545,35 @@ func TestOrganizationsService_ListPendingTeamInvitations(t *testing.T) { t.Errorf("Organizations.ListPendingTeamInvitations returned error: %v", err) } - want := []*Invitation{{ID: Int(1)}} + createdAt := time.Date(2017, 01, 21, 0, 0, 0, 0, time.UTC) + want := []*Invitation{ + { + ID: Int(1), + Login: String("monalisa"), + Email: String("octocat@github.com"), + Role: String("direct_member"), + CreatedAt: &createdAt, + Inviter: &User{ + Login: String("other_user"), + ID: Int(1), + AvatarURL: String("https://github.com/images/error/other_user_happy.gif"), + GravatarID: String(""), + URL: String("https://api.github.com/users/other_user"), + HTMLURL: String("https://github.com/other_user"), + FollowersURL: String("https://api.github.com/users/other_user/followers"), + FollowingURL: String("https://api.github.com/users/other_user/following/other_user"), + GistsURL: String("https://api.github.com/users/other_user/gists/gist_id"), + StarredURL: String("https://api.github.com/users/other_user/starred/owner/repo"), + SubscriptionsURL: String("https://api.github.com/users/other_user/subscriptions"), + OrganizationsURL: String("https://api.github.com/users/other_user/orgs"), + ReposURL: String("https://api.github.com/users/other_user/repos"), + EventsURL: String("https://api.github.com/users/other_user/events/privacy"), + ReceivedEventsURL: String("https://api.github.com/users/other_user/received_events/privacy"), + Type: String("User"), + SiteAdmin: Bool(false), + }, + }} + if !reflect.DeepEqual(invitations, want) { t.Errorf("Organizations.ListPendingTeamInvitations returned %+v, want %+v", invitations, want) }