Browse Source

update Membership to keep up with latest API changes

Latest blog post:
https://developer.github.com/changes/2014-08-28-accepting-organization-invitations-from-the-api/

- TeamMembership has been renamed to Membership, since it now covers
  organization membership as well
- Status field renamed to State
- added new methods: ListOrgMemberships, GetOrgMembership,
  EditOrgMembership
Will Norris 11 years ago
parent
commit
56f6b12f8c
5 changed files with 195 additions and 26 deletions
  1. +1
    -1
      github/github.go
  2. +99
    -0
      github/orgs_members.go
  3. +81
    -0
      github/orgs_members_test.go
  4. +7
    -18
      github/orgs_teams.go
  5. +7
    -7
      github/orgs_teams_test.go

+ 1
- 1
github/github.go View File

@ -38,7 +38,7 @@ const (
// Media Type values to access preview APIs // Media Type values to access preview APIs
// https://developer.github.com/changes/2014-08-05-team-memberships-api/ // https://developer.github.com/changes/2014-08-05-team-memberships-api/
mediaTypeTeamMembershipPreview = "application/vnd.github.the-wasp-preview+json"
mediaTypeMembershipPreview = "application/vnd.github.the-wasp-preview+json"
) )
// A Client manages communication with the GitHub API. // A Client manages communication with the GitHub API.


+ 99
- 0
github/orgs_members.go View File

@ -7,6 +7,22 @@ package github
import "fmt" import "fmt"
// Membership represents the status of a user's membership in an organization or team.
type Membership struct {
URL *string `json:"url,omitempty"`
// State is the user's status within the organization or team.
// Possible values are: "active", "pending"
State *string `json:"state,omitempty"`
// For organization membership, the API URL of the organization.
OrganizationURL *string `json:"organization_url,omitempty"`
}
func (m Membership) String() string {
return Stringify(m)
}
// ListMembersOptions specifies optional parameters to the // ListMembersOptions specifies optional parameters to the
// OrganizationsService.ListMembers method. // OrganizationsService.ListMembers method.
type ListMembersOptions struct { type ListMembersOptions struct {
@ -120,3 +136,86 @@ func (s *OrganizationsService) ConcealMembership(org, user string) (*Response, e
return s.client.Do(req, nil) return s.client.Do(req, nil)
} }
// ListOrgMembershipsOptions specifies optional parameters to the
// OrganizationsService.ListOrgMemberships method.
type ListOrgMembershipsOptions struct {
// Filter memberships to include only those withe the specified state.
// Possible values are: "active", "pending".
State string `url:"state,omitempty"`
ListOptions
}
// ListOrgMemberships lists the organization memberships for the authenticated user.
//
// GitHub API docs: https://developer.github.com/v3/orgs/members/#list-your-organization-memberships
func (s *OrganizationsService) ListOrgMemberships(opt *ListOrgMembershipsOptions) ([]Membership, *Response, error) {
u := "user/memberships/orgs"
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", mediaTypeMembershipPreview)
var memberships []Membership
resp, err := s.client.Do(req, &memberships)
if err != nil {
return nil, resp, err
}
return memberships, resp, err
}
// GetOrgMembership gets the membership for the authenticated user for the
// specified organization.
//
// GitHub API docs: https://developer.github.com/v3/orgs/members/#get-your-organization-membership
func (s *OrganizationsService) GetOrgMembership(org string) (*Membership, *Response, error) {
u := fmt.Sprintf("user/memberships/orgs/%v", org)
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", mediaTypeMembershipPreview)
membership := new(Membership)
resp, err := s.client.Do(req, membership)
if err != nil {
return nil, resp, err
}
return membership, resp, err
}
// EditOrgMembership edits the membership for the authenticated user for the
// specified organization.
//
// GitHub API docs: https://developer.github.com/v3/orgs/members/#edit-your-organization-membership
func (s *OrganizationsService) EditOrgMembership(org string, membership *Membership) (*Membership, *Response, error) {
u := fmt.Sprintf("user/memberships/orgs/%v", org)
req, err := s.client.NewRequest("PATCH", u, membership)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypeMembershipPreview)
m := new(Membership)
resp, err := s.client.Do(req, m)
if err != nil {
return nil, resp, err
}
return m, resp, err
}

+ 81
- 0
github/orgs_members_test.go View File

@ -6,6 +6,7 @@
package github package github
import ( import (
"encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"reflect" "reflect"
@ -209,3 +210,83 @@ func TestOrganizationsService_RemoveMember_invalidOrg(t *testing.T) {
_, err := client.Organizations.RemoveMember("%", "u") _, err := client.Organizations.RemoveMember("%", "u")
testURLParseError(t, err) testURLParseError(t, err)
} }
func TestOrganizationsService_ListOrgMemberships(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/user/memberships/orgs", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeMembershipPreview)
testFormValues(t, r, values{
"state": "active",
"page": "2",
})
fmt.Fprint(w, `[{"url":"u"}]`)
})
opt := &ListOrgMembershipsOptions{
State: "active",
ListOptions: ListOptions{Page: 2},
}
memberships, _, err := client.Organizations.ListOrgMemberships(opt)
if err != nil {
t.Errorf("Organizations.ListOrgMemberships returned error: %v", err)
}
want := []Membership{{URL: String("u")}}
if !reflect.DeepEqual(memberships, want) {
t.Errorf("Organizations.ListOrgMemberships returned %+v, want %+v", memberships, want)
}
}
func TestOrganizationsService_GetOrgMembership(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/user/memberships/orgs/o", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeMembershipPreview)
fmt.Fprint(w, `{"url":"u"}`)
})
membership, _, err := client.Organizations.GetOrgMembership("o")
if err != nil {
t.Errorf("Organizations.GetOrgMembership returned error: %v", err)
}
want := &Membership{URL: String("u")}
if !reflect.DeepEqual(membership, want) {
t.Errorf("Organizations.GetOrgMembership returned %+v, want %+v", membership, want)
}
}
func TestOrganizationsService_EditOrgMembership(t *testing.T) {
setup()
defer teardown()
input := &Membership{State: String("active")}
mux.HandleFunc("/user/memberships/orgs/o", func(w http.ResponseWriter, r *http.Request) {
v := new(Membership)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
testHeader(t, r, "Accept", mediaTypeMembershipPreview)
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"url":"u"}`)
})
membership, _, err := client.Organizations.EditOrgMembership("o", input)
if err != nil {
t.Errorf("Organizations.EditOrgMembership returned error: %v", err)
}
want := &Membership{URL: String("u")}
if !reflect.DeepEqual(membership, want) {
t.Errorf("Organizations.EditOrgMembership returned %+v, want %+v", membership, want)
}
}

+ 7
- 18
github/orgs_teams.go View File

@ -23,17 +23,6 @@ func (t Team) String() string {
return Stringify(t) return Stringify(t)
} }
// TeamMembership represents the status an a user's membership in a team.
type TeamMembership struct {
URL *string `json:"url,omitempty"`
// Status is the user's status within the team. Possible values are: "active", "pending"
Status *string `json:"status,omitempty"`
}
func (t TeamMembership) String() string {
return Stringify(t)
}
// ListTeams lists all of the teams for an organization. // ListTeams lists all of the teams for an organization.
// //
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#list-teams // GitHub API docs: http://developer.github.com/v3/orgs/teams/#list-teams
@ -266,7 +255,7 @@ func (s *OrganizationsService) RemoveTeamRepo(team int, owner string, repo strin
// GetTeamMembership returns the membership status for a user in a team. // GetTeamMembership returns the membership status for a user in a team.
// //
// GitHub API docs: https://developer.github.com/v3/orgs/teams/#get-team-membership // GitHub API docs: https://developer.github.com/v3/orgs/teams/#get-team-membership
func (s *OrganizationsService) GetTeamMembership(team int, user string) (*TeamMembership, *Response, error) {
func (s *OrganizationsService) GetTeamMembership(team int, user string) (*Membership, *Response, error) {
u := fmt.Sprintf("teams/%v/memberships/%v", team, user) u := fmt.Sprintf("teams/%v/memberships/%v", team, user)
req, err := s.client.NewRequest("GET", u, nil) req, err := s.client.NewRequest("GET", u, nil)
if err != nil { if err != nil {
@ -274,9 +263,9 @@ func (s *OrganizationsService) GetTeamMembership(team int, user string) (*TeamMe
} }
// TODO: remove custom Accept header when this API fully launches // TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypeTeamMembershipPreview)
req.Header.Set("Accept", mediaTypeMembershipPreview)
t := new(TeamMembership)
t := new(Membership)
resp, err := s.client.Do(req, t) resp, err := s.client.Do(req, t)
if err != nil { if err != nil {
return nil, resp, err return nil, resp, err
@ -303,7 +292,7 @@ func (s *OrganizationsService) GetTeamMembership(team int, user string) (*TeamMe
// added as a member of the team. // added as a member of the team.
// //
// GitHub API docs: https://developer.github.com/v3/orgs/teams/#add-team-membership // GitHub API docs: https://developer.github.com/v3/orgs/teams/#add-team-membership
func (s *OrganizationsService) AddTeamMembership(team int, user string) (*TeamMembership, *Response, error) {
func (s *OrganizationsService) AddTeamMembership(team int, user string) (*Membership, *Response, error) {
u := fmt.Sprintf("teams/%v/memberships/%v", team, user) u := fmt.Sprintf("teams/%v/memberships/%v", team, user)
req, err := s.client.NewRequest("PUT", u, nil) req, err := s.client.NewRequest("PUT", u, nil)
if err != nil { if err != nil {
@ -311,9 +300,9 @@ func (s *OrganizationsService) AddTeamMembership(team int, user string) (*TeamMe
} }
// TODO: remove custom Accept header when this API fully launches // TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypeTeamMembershipPreview)
req.Header.Set("Accept", mediaTypeMembershipPreview)
t := new(TeamMembership)
t := new(Membership)
resp, err := s.client.Do(req, t) resp, err := s.client.Do(req, t)
if err != nil { if err != nil {
return nil, resp, err return nil, resp, err
@ -333,7 +322,7 @@ func (s *OrganizationsService) RemoveTeamMembership(team int, user string) (*Res
} }
// TODO: remove custom Accept header when this API fully launches // TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypeTeamMembershipPreview)
req.Header.Set("Accept", mediaTypeMembershipPreview)
return s.client.Do(req, nil) return s.client.Do(req, nil)
} }

+ 7
- 7
github/orgs_teams_test.go View File

@ -442,8 +442,8 @@ func TestOrganizationsService_GetTeamMembership(t *testing.T) {
mux.HandleFunc("/teams/1/memberships/u", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/teams/1/memberships/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET") testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeTeamMembershipPreview)
fmt.Fprint(w, `{"url":"u", "status":"active"}`)
testHeader(t, r, "Accept", mediaTypeMembershipPreview)
fmt.Fprint(w, `{"url":"u", "state":"active"}`)
}) })
membership, _, err := client.Organizations.GetTeamMembership(1, "u") membership, _, err := client.Organizations.GetTeamMembership(1, "u")
@ -451,7 +451,7 @@ func TestOrganizationsService_GetTeamMembership(t *testing.T) {
t.Errorf("Organizations.GetTeamMembership returned error: %v", err) t.Errorf("Organizations.GetTeamMembership returned error: %v", err)
} }
want := &TeamMembership{URL: String("u"), Status: String("active")}
want := &Membership{URL: String("u"), State: String("active")}
if !reflect.DeepEqual(membership, want) { if !reflect.DeepEqual(membership, want) {
t.Errorf("Organizations.GetTeamMembership returned %+v, want %+v", membership, want) t.Errorf("Organizations.GetTeamMembership returned %+v, want %+v", membership, want)
} }
@ -463,8 +463,8 @@ func TestOrganizationsService_AddTeamMembership(t *testing.T) {
mux.HandleFunc("/teams/1/memberships/u", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/teams/1/memberships/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT") testMethod(t, r, "PUT")
testHeader(t, r, "Accept", mediaTypeTeamMembershipPreview)
fmt.Fprint(w, `{"url":"u", "status":"pending"}`)
testHeader(t, r, "Accept", mediaTypeMembershipPreview)
fmt.Fprint(w, `{"url":"u", "state":"pending"}`)
}) })
membership, _, err := client.Organizations.AddTeamMembership(1, "u") membership, _, err := client.Organizations.AddTeamMembership(1, "u")
@ -472,7 +472,7 @@ func TestOrganizationsService_AddTeamMembership(t *testing.T) {
t.Errorf("Organizations.AddTeamMembership returned error: %v", err) t.Errorf("Organizations.AddTeamMembership returned error: %v", err)
} }
want := &TeamMembership{URL: String("u"), Status: String("pending")}
want := &Membership{URL: String("u"), State: String("pending")}
if !reflect.DeepEqual(membership, want) { if !reflect.DeepEqual(membership, want) {
t.Errorf("Organizations.AddTeamMembership returned %+v, want %+v", membership, want) t.Errorf("Organizations.AddTeamMembership returned %+v, want %+v", membership, want)
} }
@ -484,7 +484,7 @@ func TestOrganizationsService_RemoveTeamMembership(t *testing.T) {
mux.HandleFunc("/teams/1/memberships/u", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/teams/1/memberships/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE") testMethod(t, r, "DELETE")
testHeader(t, r, "Accept", mediaTypeTeamMembershipPreview)
testHeader(t, r, "Accept", mediaTypeMembershipPreview)
w.WriteHeader(http.StatusNoContent) w.WriteHeader(http.StatusNoContent)
}) })


Loading…
Cancel
Save