Browse Source

add support for new repository invitations

Fixes #371.

Change-Id: I97f2fc28ce048442ee8af3bd11c48b5b2084e09b
Glenn Lewis 10 years ago
parent
commit
5c1b3a05b4
8 changed files with 282 additions and 6 deletions
  1. +3
    -0
      github/github.go
  2. +5
    -2
      github/repos_collaborators.go
  3. +1
    -0
      github/repos_collaborators_test.go
  4. +91
    -0
      github/repos_invitations.go
  5. +73
    -0
      github/repos_invitations_test.go
  6. +56
    -0
      github/users.go
  7. +2
    -4
      github/users_gpg_keys.go
  8. +51
    -0
      github/users_test.go

+ 3
- 0
github/github.go View File

@ -81,6 +81,9 @@ const (
// https://developer.github.com/changes/2016-05-23-timeline-preview-api/
mediaTypeTimelinePreview = "application/vnd.github.mockingbird-preview+json"
// https://developer.github.com/changes/2016-06-14-repository-invitations/
mediaTypeRepositoryInvitationsPreview = "application/vnd.github.swamp-thing-preview+json"
)
// A Client manages communication with the GitHub API.


+ 5
- 2
github/repos_collaborators.go View File

@ -58,13 +58,13 @@ type RepositoryAddCollaboratorOptions struct {
// push - team members can pull and push, but not administer this repository
// admin - team members can pull, push and administer this repository
//
// Default value is "pull". This option is only valid for organization-owned repositories.
// Default value is "push". This option is only valid for organization-owned repositories.
Permission string `json:"permission,omitempty"`
}
// AddCollaborator adds the specified Github user as collaborator to the given repo.
//
// GitHub API docs: http://developer.github.com/v3/repos/collaborators/#add-collaborator
// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#add-user-as-a-collaborator
func (s *RepositoriesService) AddCollaborator(owner, repo, user string, opt *RepositoryAddCollaboratorOptions) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user)
req, err := s.client.NewRequest("PUT", u, opt)
@ -72,6 +72,9 @@ func (s *RepositoriesService) AddCollaborator(owner, repo, user string, opt *Rep
return nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeRepositoryInvitationsPreview)
return s.client.Do(req, nil)
}


+ 1
- 0
github/repos_collaborators_test.go View File

@ -94,6 +94,7 @@ func TestRepositoriesService_AddCollaborator(t *testing.T) {
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PUT")
testHeader(t, r, "Accept", mediaTypeRepositoryInvitationsPreview)
if !reflect.DeepEqual(v, opt) {
t.Errorf("Request body = %+v, want %+v", v, opt)
}


+ 91
- 0
github/repos_invitations.go View File

@ -0,0 +1,91 @@
// Copyright 2016 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import "fmt"
// RepositoryInvitation represents an invitation to collaborate on a repo.
type RepositoryInvitation struct {
ID *int `json:"id,omitempty"`
Repo *Repository `json:"repository,omitempty"`
Invitee *User `json:"invitee,omitempty"`
Inviter *User `json:"inviter,omitempty"`
// Permissions represents the permissions that the associated user will have
// on the repository. Possible values are: "read", "write", "admin".
Permissions *string `json:"permissions,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
}
// ListInvitations lists all currently-open repository invitations.
//
// GitHub API docs: https://developer.github.com/v3/repos/invitations/#list-invitations-for-a-repository
func (s *RepositoriesService) ListInvitations(repoID int, opt *ListOptions) ([]*RepositoryInvitation, *Response, error) {
u := fmt.Sprintf("repositories/%v/invitations", repoID)
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", mediaTypeRepositoryInvitationsPreview)
invites := []*RepositoryInvitation{}
resp, err := s.client.Do(req, &invites)
if err != nil {
return nil, resp, err
}
return invites, resp, err
}
// DeleteInvitation deletes a repository invitation.
//
// GitHub API docs: https://developer.github.com/v3/repos/invitations/#delete-a-repository-invitation
func (s *RepositoriesService) DeleteInvitation(repoID, invitationID int) (*Response, error) {
u := fmt.Sprintf("repositories/%v/invitations/%v", repoID, invitationID)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeRepositoryInvitationsPreview)
return s.client.Do(req, nil)
}
// UpdateInvitation updates the permissions associated with a repository
// invitation.
//
// permissions represents the permissions that the associated user will have
// on the repository. Possible values are: "read", "write", "admin".
//
// GitHub API docs: https://developer.github.com/v3/repos/invitations/#update-a-repository-invitation
func (s *RepositoriesService) UpdateInvitation(repoID, invitationID int, permissions string) (*RepositoryInvitation, *Response, error) {
opts := &struct {
Permissions string `json:"permissions"`
}{Permissions: permissions}
u := fmt.Sprintf("repositories/%v/invitations/%v", repoID, invitationID)
req, err := s.client.NewRequest("PATCH", u, opts)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeRepositoryInvitationsPreview)
invite := &RepositoryInvitation{}
resp, err := s.client.Do(req, invite)
return invite, resp, err
}

+ 73
- 0
github/repos_invitations_test.go View File

@ -0,0 +1,73 @@
// Copyright 2016 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"net/http"
"reflect"
"testing"
)
func TestRepositoriesService_ListInvitations(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repositories/1/invitations", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeRepositoryInvitationsPreview)
testFormValues(t, r, values{"page": "2"})
fmt.Fprintf(w, `[{"id":1}, {"id":2}]`)
})
opt := &ListOptions{Page: 2}
got, _, err := client.Repositories.ListInvitations(1, opt)
if err != nil {
t.Errorf("Repositories.ListInvitations returned error: %v", err)
}
want := []*RepositoryInvitation{{ID: Int(1)}, {ID: Int(2)}}
if !reflect.DeepEqual(got, want) {
t.Errorf("Repositories.ListInvitations = %+v, want %+v", got, want)
}
}
func TestRepositoriesService_DeleteInvitation(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repositories/1/invitations/2", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testHeader(t, r, "Accept", mediaTypeRepositoryInvitationsPreview)
w.WriteHeader(http.StatusNoContent)
})
_, err := client.Repositories.DeleteInvitation(1, 2)
if err != nil {
t.Errorf("Repositories.DeleteInvitation returned error: %v", err)
}
}
func TestRepositoriesService_UpdateInvitation(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repositories/1/invitations/2", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PATCH")
testHeader(t, r, "Accept", mediaTypeRepositoryInvitationsPreview)
fmt.Fprintf(w, `{"id":1}`)
})
got, _, err := client.Repositories.UpdateInvitation(1, 2, "write")
if err != nil {
t.Errorf("Repositories.UpdateInvitation returned error: %v", err)
}
want := &RepositoryInvitation{ID: Int(1)}
if !reflect.DeepEqual(got, want) {
t.Errorf("Repositories.UpdateInvitation = %+v, want %+v", got, want)
}
}

+ 56
- 0
github/users.go View File

@ -166,3 +166,59 @@ func (s *UsersService) ListAll(opt *UserListOptions) ([]*User, *Response, error)
return *users, resp, err
}
// ListInvitations lists all currently-open repository invitations for the
// authenticated user.
//
// GitHub API docs: https://developer.github.com/v3/repos/invitations/#list-a-users-repository-invitations
func (s *UsersService) ListInvitations() ([]*RepositoryInvitation, *Response, error) {
req, err := s.client.NewRequest("GET", "user/repository_invitations", nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeRepositoryInvitationsPreview)
invites := []*RepositoryInvitation{}
resp, err := s.client.Do(req, &invites)
if err != nil {
return nil, resp, err
}
return invites, resp, err
}
// AcceptInvitation accepts the currently-open repository invitation for the
// authenticated user.
//
// GitHub API docs: https://developer.github.com/v3/repos/invitations/#accept-a-repository-invitation
func (s *UsersService) AcceptInvitation(invitationID int) (*Response, error) {
u := fmt.Sprintf("user/repository_invitations/%v", invitationID)
req, err := s.client.NewRequest("PATCH", u, nil)
if err != nil {
return nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeRepositoryInvitationsPreview)
return s.client.Do(req, nil)
}
// DeclineInvitation declines the currently-open repository invitation for the
// authenticated user.
//
// GitHub API docs: https://developer.github.com/v3/repos/invitations/#decline-a-repository-invitation
func (s *UsersService) DeclineInvitation(invitationID int) (*Response, error) {
u := fmt.Sprintf("user/repository_invitations/%v", invitationID)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeRepositoryInvitationsPreview)
return s.client.Do(req, nil)
}

+ 2
- 4
github/users_gpg_keys.go View File

@ -90,10 +90,8 @@ func (s *UsersService) GetGPGKey(id int) (*GPGKey, *Response, error) {
// GitHub API docs: https://developer.github.com/v3/users/gpg_keys/#create-a-gpg-key
func (s *UsersService) CreateGPGKey(armoredPublicKey string) (*GPGKey, *Response, error) {
gpgKey := &struct {
ArmoredPublicKey *string `json:"armored_public_key,omitempty"`
}{
ArmoredPublicKey: String(armoredPublicKey),
}
ArmoredPublicKey string `json:"armored_public_key"`
}{ArmoredPublicKey: armoredPublicKey}
req, err := s.client.NewRequest("POST", "user/gpg_keys", gpgKey)
if err != nil {
return nil, nil, err


+ 51
- 0
github/users_test.go View File

@ -170,3 +170,54 @@ func TestUsersService_ListAll(t *testing.T) {
t.Errorf("Users.ListAll returned %+v, want %+v", users, want)
}
}
func TestUsersService_ListInvitations(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/user/repository_invitations", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeRepositoryInvitationsPreview)
fmt.Fprintf(w, `[{"id":1}, {"id":2}]`)
})
got, _, err := client.Users.ListInvitations()
if err != nil {
t.Errorf("Users.ListInvitations returned error: %v", err)
}
want := []*RepositoryInvitation{{ID: Int(1)}, {ID: Int(2)}}
if !reflect.DeepEqual(got, want) {
t.Errorf("Users.ListInvitations = %+v, want %+v", got, want)
}
}
func TestUsersService_AcceptInvitation(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/user/repository_invitations/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PATCH")
testHeader(t, r, "Accept", mediaTypeRepositoryInvitationsPreview)
w.WriteHeader(http.StatusNoContent)
})
if _, err := client.Users.AcceptInvitation(1); err != nil {
t.Errorf("Users.AcceptInvitation returned error: %v", err)
}
}
func TestUsersService_DeclineInvitation(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/user/repository_invitations/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testHeader(t, r, "Accept", mediaTypeRepositoryInvitationsPreview)
w.WriteHeader(http.StatusNoContent)
})
if _, err := client.Users.DeclineInvitation(1); err != nil {
t.Errorf("Users.DeclineInvitation returned error: %v", err)
}
}

Loading…
Cancel
Save