Merge pull request #8 from zachgersh/master
Allow Github Resource to Fetch Private Assets
This commit is contained in:
8
Godeps/Godeps.json
generated
8
Godeps/Godeps.json
generated
@@ -15,10 +15,6 @@
|
|||||||
"Comment": "v3.0.0",
|
"Comment": "v3.0.0",
|
||||||
"Rev": "2f3112b6f8f18f9df8743cc75ed51da08094ef6a"
|
"Rev": "2f3112b6f8f18f9df8743cc75ed51da08094ef6a"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"ImportPath": "github.com/google/go-github/github",
|
|
||||||
"Rev": "7ea4ee6d222607c11ea86e99a6f6723beeae785d"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/go-querystring/query",
|
"ImportPath": "github.com/google/go-querystring/query",
|
||||||
"Rev": "d8840cbb2baa915f4836edda4750050a2c0b7aea"
|
"Rev": "d8840cbb2baa915f4836edda4750050a2c0b7aea"
|
||||||
@@ -36,6 +32,10 @@
|
|||||||
"ImportPath": "github.com/onsi/gomega",
|
"ImportPath": "github.com/onsi/gomega",
|
||||||
"Comment": "v1.0-28-g8adf9e1",
|
"Comment": "v1.0-28-g8adf9e1",
|
||||||
"Rev": "8adf9e1730c55cdc590de7d49766cb2acc88d8f2"
|
"Rev": "8adf9e1730c55cdc590de7d49766cb2acc88d8f2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/zachgersh/go-github/github",
|
||||||
|
"Rev": "f47a8b33261f10482dfede3cc839c4fcf34da04f"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,12 @@ package github
|
|||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
|
// StarredRepository is returned by ListStarred.
|
||||||
|
type StarredRepository struct {
|
||||||
|
StarredAt *Timestamp `json:"starred_at,omitempty"`
|
||||||
|
Repository *Repository `json:"repo,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// ListStargazers lists people who have starred the specified repo.
|
// ListStargazers lists people who have starred the specified repo.
|
||||||
//
|
//
|
||||||
// GitHub API Docs: https://developer.github.com/v3/activity/starring/#list-stargazers
|
// GitHub API Docs: https://developer.github.com/v3/activity/starring/#list-stargazers
|
||||||
@@ -49,7 +55,7 @@ type ActivityListStarredOptions struct {
|
|||||||
// will list the starred repositories for the authenticated user.
|
// will list the starred repositories for the authenticated user.
|
||||||
//
|
//
|
||||||
// GitHub API docs: http://developer.github.com/v3/activity/starring/#list-repositories-being-starred
|
// GitHub API docs: http://developer.github.com/v3/activity/starring/#list-repositories-being-starred
|
||||||
func (s *ActivityService) ListStarred(user string, opt *ActivityListStarredOptions) ([]Repository, *Response, error) {
|
func (s *ActivityService) ListStarred(user string, opt *ActivityListStarredOptions) ([]StarredRepository, *Response, error) {
|
||||||
var u string
|
var u string
|
||||||
if user != "" {
|
if user != "" {
|
||||||
u = fmt.Sprintf("users/%v/starred", user)
|
u = fmt.Sprintf("users/%v/starred", user)
|
||||||
@@ -66,7 +72,10 @@ func (s *ActivityService) ListStarred(user string, opt *ActivityListStarredOptio
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
repos := new([]Repository)
|
// TODO: remove custom Accept header when this API fully launches
|
||||||
|
req.Header.Set("Accept", mediaTypeStarringPreview)
|
||||||
|
|
||||||
|
repos := new([]StarredRepository)
|
||||||
resp, err := s.client.Do(req, repos)
|
resp, err := s.client.Do(req, repos)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
@@ -10,6 +10,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestActivityService_ListStargazers(t *testing.T) {
|
func TestActivityService_ListStargazers(t *testing.T) {
|
||||||
@@ -42,7 +43,8 @@ func TestActivityService_ListStarred_authenticatedUser(t *testing.T) {
|
|||||||
|
|
||||||
mux.HandleFunc("/user/starred", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/user/starred", func(w http.ResponseWriter, r *http.Request) {
|
||||||
testMethod(t, r, "GET")
|
testMethod(t, r, "GET")
|
||||||
fmt.Fprint(w, `[{"id":1}]`)
|
testHeader(t, r, "Accept", mediaTypeStarringPreview)
|
||||||
|
fmt.Fprint(w, `[{"starred_at":"2002-02-10T15:30:00Z","repo":{"id":1}}]`)
|
||||||
})
|
})
|
||||||
|
|
||||||
repos, _, err := client.Activity.ListStarred("", nil)
|
repos, _, err := client.Activity.ListStarred("", nil)
|
||||||
@@ -50,7 +52,7 @@ func TestActivityService_ListStarred_authenticatedUser(t *testing.T) {
|
|||||||
t.Errorf("Activity.ListStarred returned error: %v", err)
|
t.Errorf("Activity.ListStarred returned error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
want := []Repository{{ID: Int(1)}}
|
want := []StarredRepository{{StarredAt: &Timestamp{time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC)}, Repository: &Repository{ID: Int(1)}}}
|
||||||
if !reflect.DeepEqual(repos, want) {
|
if !reflect.DeepEqual(repos, want) {
|
||||||
t.Errorf("Activity.ListStarred returned %+v, want %+v", repos, want)
|
t.Errorf("Activity.ListStarred returned %+v, want %+v", repos, want)
|
||||||
}
|
}
|
||||||
@@ -62,12 +64,13 @@ func TestActivityService_ListStarred_specifiedUser(t *testing.T) {
|
|||||||
|
|
||||||
mux.HandleFunc("/users/u/starred", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/users/u/starred", func(w http.ResponseWriter, r *http.Request) {
|
||||||
testMethod(t, r, "GET")
|
testMethod(t, r, "GET")
|
||||||
|
testHeader(t, r, "Accept", mediaTypeStarringPreview)
|
||||||
testFormValues(t, r, values{
|
testFormValues(t, r, values{
|
||||||
"sort": "created",
|
"sort": "created",
|
||||||
"direction": "asc",
|
"direction": "asc",
|
||||||
"page": "2",
|
"page": "2",
|
||||||
})
|
})
|
||||||
fmt.Fprint(w, `[{"id":2}]`)
|
fmt.Fprint(w, `[{"starred_at":"2002-02-10T15:30:00Z","repo":{"id":2}}]`)
|
||||||
})
|
})
|
||||||
|
|
||||||
opt := &ActivityListStarredOptions{"created", "asc", ListOptions{Page: 2}}
|
opt := &ActivityListStarredOptions{"created", "asc", ListOptions{Page: 2}}
|
||||||
@@ -76,7 +79,7 @@ func TestActivityService_ListStarred_specifiedUser(t *testing.T) {
|
|||||||
t.Errorf("Activity.ListStarred returned error: %v", err)
|
t.Errorf("Activity.ListStarred returned error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
want := []Repository{{ID: Int(2)}}
|
want := []StarredRepository{{StarredAt: &Timestamp{time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC)}, Repository: &Repository{ID: Int(2)}}}
|
||||||
if !reflect.DeepEqual(repos, want) {
|
if !reflect.DeepEqual(repos, want) {
|
||||||
t.Errorf("Activity.ListStarred returned %+v, want %+v", repos, want)
|
t.Errorf("Activity.ListStarred returned %+v, want %+v", repos, want)
|
||||||
}
|
}
|
@@ -28,24 +28,25 @@ Authentication
|
|||||||
|
|
||||||
The go-github library does not directly handle authentication. Instead, when
|
The go-github library does not directly handle authentication. Instead, when
|
||||||
creating a new client, pass an http.Client that can handle authentication for
|
creating a new client, pass an http.Client that can handle authentication for
|
||||||
you. The easiest and recommended way to do this is using the goauth2 library,
|
you. The easiest and recommended way to do this is using the golang.org/x/oauth2
|
||||||
but you can always use any other library that provides an http.Client. If you
|
library, but you can always use any other library that provides an http.Client.
|
||||||
have an OAuth2 access token (for example, a personal API token), you can use it
|
If you have an OAuth2 access token (for example, a personal API token), you can
|
||||||
with the goauth2 using:
|
use it with the oauth2 library using:
|
||||||
|
|
||||||
import "code.google.com/p/goauth2/oauth"
|
import "golang.org/x/oauth2"
|
||||||
|
|
||||||
// simple OAuth transport if you already have an access token;
|
func main() {
|
||||||
// see goauth2 library for full usage
|
ts := oauth2.StaticTokenSource(
|
||||||
t := &oauth.Transport{
|
&oauth2.Token{AccessToken: "... your access token ..."},
|
||||||
Token: &oauth.Token{AccessToken: "..."},
|
)
|
||||||
|
tc := oauth2.NewClient(oauth2.NoContext, ts)
|
||||||
|
|
||||||
|
client := github.NewClient(tc)
|
||||||
|
|
||||||
|
// list all repositories for the authenticated user
|
||||||
|
repos, _, err := client.Repositories.List("", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
client := github.NewClient(t.Client())
|
|
||||||
|
|
||||||
// list all repositories for the authenticated user
|
|
||||||
repos, _, err := client.Repositories.List("", nil)
|
|
||||||
|
|
||||||
Note that when using an authenticated Client, all calls made by the client will
|
Note that when using an authenticated Client, all calls made by the client will
|
||||||
include the specified OAuth token. Therefore, authenticated clients should
|
include the specified OAuth token. Therefore, authenticated clients should
|
||||||
almost never be shared between different users.
|
almost never be shared between different users.
|
@@ -157,6 +157,24 @@ func (s *GistsService) Get(id string) (*Gist, *Response, error) {
|
|||||||
return gist, resp, err
|
return gist, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetRevision gets a specific revision of a gist.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/gists/#get-a-specific-revision-of-a-gist
|
||||||
|
func (s *GistsService) GetRevision(id, sha string) (*Gist, *Response, error) {
|
||||||
|
u := fmt.Sprintf("gists/%v/%v", id, sha)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
gist := new(Gist)
|
||||||
|
resp, err := s.client.Do(req, gist)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gist, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
// Create a gist for authenticated user.
|
// Create a gist for authenticated user.
|
||||||
//
|
//
|
||||||
// GitHub API docs: http://developer.github.com/v3/gists/#create-a-gist
|
// GitHub API docs: http://developer.github.com/v3/gists/#create-a-gist
|
@@ -146,6 +146,32 @@ func TestGistsService_Get_invalidID(t *testing.T) {
|
|||||||
testURLParseError(t, err)
|
testURLParseError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGistsService_GetRevision(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/gists/1/s", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"id": "1"}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
gist, _, err := client.Gists.GetRevision("1", "s")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Gists.Get returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Gist{ID: String("1")}
|
||||||
|
if !reflect.DeepEqual(gist, want) {
|
||||||
|
t.Errorf("Gists.Get returned %+v, want %+v", gist, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_GetRevision_invalidID(t *testing.T) {
|
||||||
|
_, _, err := client.Gists.GetRevision("%", "%")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
func TestGistsService_Create(t *testing.T) {
|
func TestGistsService_Create(t *testing.T) {
|
||||||
setup()
|
setup()
|
||||||
defer teardown()
|
defer teardown()
|
@@ -37,11 +37,15 @@ 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/2015-03-09-licenses-api/
|
||||||
mediaTypeMembershipPreview = "application/vnd.github.the-wasp-preview+json"
|
mediaTypeLicensesPreview = "application/vnd.github.drax-preview+json"
|
||||||
|
|
||||||
// https://developer.github.com/changes/2014-01-09-preview-the-new-deployments-api/
|
// https://developer.github.com/changes/2014-12-09-new-attributes-for-stars-api/
|
||||||
mediaTypeDeploymentPreview = "application/vnd.github.cannonball-preview+json"
|
mediaTypeStarringPreview = "application/vnd.github.v3.star+json"
|
||||||
|
|
||||||
|
// https://developer.github.com/changes/2015-06-24-api-enhancements-for-working-with-organization-permissions/
|
||||||
|
mediaTypeOrgPermissionPreview = "application/vnd.github.ironman-preview+json"
|
||||||
|
mediaTypeOrgPermissionRepoPreview = "application/vnd.github.ironman-preview.repository+json"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Client manages communication with the GitHub API.
|
// A Client manages communication with the GitHub API.
|
||||||
@@ -77,6 +81,7 @@ type Client struct {
|
|||||||
Repositories *RepositoriesService
|
Repositories *RepositoriesService
|
||||||
Search *SearchService
|
Search *SearchService
|
||||||
Users *UsersService
|
Users *UsersService
|
||||||
|
Licenses *LicensesService
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListOptions specifies the optional parameters to various List methods that
|
// ListOptions specifies the optional parameters to various List methods that
|
||||||
@@ -119,7 +124,7 @@ func addOptions(s string, opt interface{}) (string, error) {
|
|||||||
// NewClient returns a new GitHub API client. If a nil httpClient is
|
// NewClient returns a new GitHub API client. If a nil httpClient is
|
||||||
// provided, http.DefaultClient will be used. To use API methods which require
|
// provided, http.DefaultClient will be used. To use API methods which require
|
||||||
// authentication, provide an http.Client that will perform the authentication
|
// authentication, provide an http.Client that will perform the authentication
|
||||||
// for you (such as that provided by the goauth2 library).
|
// for you (such as that provided by the golang.org/x/oauth2 library).
|
||||||
func NewClient(httpClient *http.Client) *Client {
|
func NewClient(httpClient *http.Client) *Client {
|
||||||
if httpClient == nil {
|
if httpClient == nil {
|
||||||
httpClient = http.DefaultClient
|
httpClient = http.DefaultClient
|
||||||
@@ -138,6 +143,7 @@ func NewClient(httpClient *http.Client) *Client {
|
|||||||
c.Repositories = &RepositoriesService{client: c}
|
c.Repositories = &RepositoriesService{client: c}
|
||||||
c.Search = &SearchService{client: c}
|
c.Search = &SearchService{client: c}
|
||||||
c.Users = &UsersService{client: c}
|
c.Users = &UsersService{client: c}
|
||||||
|
c.Licenses = &LicensesService{client: c}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,7 +225,7 @@ type Response struct {
|
|||||||
Rate
|
Rate
|
||||||
}
|
}
|
||||||
|
|
||||||
// newResponse creats a new Response for the provided http.Response.
|
// newResponse creates a new Response for the provided http.Response.
|
||||||
func newResponse(r *http.Response) *Response {
|
func newResponse(r *http.Response) *Response {
|
||||||
response := &Response{Response: r}
|
response := &Response{Response: r}
|
||||||
response.populatePageValues()
|
response.populatePageValues()
|
||||||
@@ -333,10 +339,24 @@ type ErrorResponse struct {
|
|||||||
|
|
||||||
func (r *ErrorResponse) Error() string {
|
func (r *ErrorResponse) Error() string {
|
||||||
return fmt.Sprintf("%v %v: %d %v %+v",
|
return fmt.Sprintf("%v %v: %d %v %+v",
|
||||||
r.Response.Request.Method, r.Response.Request.URL,
|
r.Response.Request.Method, sanitizeURL(r.Response.Request.URL),
|
||||||
r.Response.StatusCode, r.Message, r.Errors)
|
r.Response.StatusCode, r.Message, r.Errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sanitizeURL redacts the client_id and client_secret tokens from the URL which
|
||||||
|
// may be exposed to the user, specifically in the ErrorResponse error message.
|
||||||
|
func sanitizeURL(uri *url.URL) *url.URL {
|
||||||
|
if uri == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
params := uri.Query()
|
||||||
|
if len(params.Get("client_secret")) > 0 {
|
||||||
|
params.Set("client_secret", "REDACTED")
|
||||||
|
uri.RawQuery = params.Encode()
|
||||||
|
}
|
||||||
|
return uri
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
An Error reports more details on an individual error in an ErrorResponse.
|
An Error reports more details on an individual error in an ErrorResponse.
|
||||||
These are the possible validation error codes:
|
These are the possible validation error codes:
|
@@ -430,6 +430,25 @@ func TestDo_rateLimit_errorResponse(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSanitizeURL(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
in, want string
|
||||||
|
}{
|
||||||
|
{"/?a=b", "/?a=b"},
|
||||||
|
{"/?a=b&client_secret=secret", "/?a=b&client_secret=REDACTED"},
|
||||||
|
{"/?a=b&client_id=id&client_secret=secret", "/?a=b&client_id=id&client_secret=REDACTED"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
inURL, _ := url.Parse(tt.in)
|
||||||
|
want, _ := url.Parse(tt.want)
|
||||||
|
|
||||||
|
if got := sanitizeURL(inURL); !reflect.DeepEqual(got, want) {
|
||||||
|
t.Errorf("sanitizeURL(%v) returned %v, want %v", tt.in, got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestCheckResponse(t *testing.T) {
|
func TestCheckResponse(t *testing.T) {
|
||||||
res := &http.Response{
|
res := &http.Response{
|
||||||
Request: &http.Request{},
|
Request: &http.Request{},
|
@@ -49,12 +49,12 @@ func (i Issue) String() string {
|
|||||||
// It is separate from Issue above because otherwise Labels
|
// It is separate from Issue above because otherwise Labels
|
||||||
// and Assignee fail to serialize to the correct JSON.
|
// and Assignee fail to serialize to the correct JSON.
|
||||||
type IssueRequest struct {
|
type IssueRequest struct {
|
||||||
Title *string `json:"title,omitempty"`
|
Title *string `json:"title,omitempty"`
|
||||||
Body *string `json:"body,omitempty"`
|
Body *string `json:"body,omitempty"`
|
||||||
Labels []string `json:"labels,omitempty"`
|
Labels *[]string `json:"labels,omitempty"`
|
||||||
Assignee *string `json:"assignee,omitempty"`
|
Assignee *string `json:"assignee,omitempty"`
|
||||||
State *string `json:"state,omitempty"`
|
State *string `json:"state,omitempty"`
|
||||||
Milestone *int `json:"milestone,omitempty"`
|
Milestone *int `json:"milestone,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// IssueListOptions specifies the optional parameters to the IssuesService.List
|
// IssueListOptions specifies the optional parameters to the IssuesService.List
|
||||||
@@ -72,7 +72,7 @@ type IssueListOptions struct {
|
|||||||
Labels []string `url:"labels,comma,omitempty"`
|
Labels []string `url:"labels,comma,omitempty"`
|
||||||
|
|
||||||
// Sort specifies how to sort issues. Possible values are: created, updated,
|
// Sort specifies how to sort issues. Possible values are: created, updated,
|
||||||
// and comments. Default value is "assigned".
|
// and comments. Default value is "created".
|
||||||
Sort string `url:"sort,omitempty"`
|
Sort string `url:"sort,omitempty"`
|
||||||
|
|
||||||
// Direction in which to sort issues. Possible values are: asc, desc.
|
// Direction in which to sort issues. Possible values are: asc, desc.
|
||||||
@@ -166,7 +166,7 @@ type IssueListByRepoOptions struct {
|
|||||||
Labels []string `url:"labels,omitempty,comma"`
|
Labels []string `url:"labels,omitempty,comma"`
|
||||||
|
|
||||||
// Sort specifies how to sort issues. Possible values are: created, updated,
|
// Sort specifies how to sort issues. Possible values are: created, updated,
|
||||||
// and comments. Default value is "assigned".
|
// and comments. Default value is "created".
|
||||||
Sort string `url:"sort,omitempty"`
|
Sort string `url:"sort,omitempty"`
|
||||||
|
|
||||||
// Direction in which to sort issues. Possible values are: asc, desc.
|
// Direction in which to sort issues. Possible values are: asc, desc.
|
@@ -7,7 +7,7 @@ package github
|
|||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
// Label represents a GitHib label on an Issue
|
// Label represents a GitHub label on an Issue
|
||||||
type Label struct {
|
type Label struct {
|
||||||
URL *string `json:"url,omitempty"`
|
URL *string `json:"url,omitempty"`
|
||||||
Name *string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
@@ -176,7 +176,7 @@ func TestIssuesService_Create(t *testing.T) {
|
|||||||
Title: String("t"),
|
Title: String("t"),
|
||||||
Body: String("b"),
|
Body: String("b"),
|
||||||
Assignee: String("a"),
|
Assignee: String("a"),
|
||||||
Labels: []string{"l1", "l2"},
|
Labels: &[]string{"l1", "l2"},
|
||||||
}
|
}
|
||||||
|
|
||||||
mux.HandleFunc("/repos/o/r/issues", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/repos/o/r/issues", func(w http.ResponseWriter, r *http.Request) {
|
81
Godeps/_workspace/src/github.com/zachgersh/go-github/github/licenses.go
generated
vendored
Normal file
81
Godeps/_workspace/src/github.com/zachgersh/go-github/github/licenses.go
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
// Copyright 2013 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"
|
||||||
|
|
||||||
|
// LicensesService handles communication with the license related
|
||||||
|
// methods of the GitHub API.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/pulls/
|
||||||
|
type LicensesService struct {
|
||||||
|
client *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// License represents an open source license.
|
||||||
|
type License struct {
|
||||||
|
Key *string `json:"key,omitempty"`
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
|
||||||
|
HTMLURL *string `json:"html_url,omitempty"`
|
||||||
|
Featured *bool `json:"featured,omitempty"`
|
||||||
|
Description *string `json:"description,omitempty"`
|
||||||
|
Category *string `json:"category,omitempty"`
|
||||||
|
Implementation *string `json:"implementation,omitempty"`
|
||||||
|
Required *[]string `json:"required,omitempty"`
|
||||||
|
Permitted *[]string `json:"permitted,omitempty"`
|
||||||
|
Forbidden *[]string `json:"forbidden,omitempty"`
|
||||||
|
Body *string `json:"body,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l License) String() string {
|
||||||
|
return Stringify(l)
|
||||||
|
}
|
||||||
|
|
||||||
|
// List popular open source licenses.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/licenses/#list-all-licenses
|
||||||
|
func (s *LicensesService) List() ([]License, *Response, error) {
|
||||||
|
req, err := s.client.NewRequest("GET", "licenses", nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: remove custom Accept header when this API fully launches
|
||||||
|
req.Header.Set("Accept", mediaTypeLicensesPreview)
|
||||||
|
|
||||||
|
licenses := new([]License)
|
||||||
|
resp, err := s.client.Do(req, licenses)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *licenses, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get extended metadata for one license.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/licenses/#get-an-individual-license
|
||||||
|
func (s *LicensesService) Get(licenseName string) (*License, *Response, error) {
|
||||||
|
u := fmt.Sprintf("licenses/%s", licenseName)
|
||||||
|
|
||||||
|
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", mediaTypeLicensesPreview)
|
||||||
|
|
||||||
|
license := new(License)
|
||||||
|
resp, err := s.client.Do(req, license)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return license, resp, err
|
||||||
|
}
|
64
Godeps/_workspace/src/github.com/zachgersh/go-github/github/licenses_test.go
generated
vendored
Normal file
64
Godeps/_workspace/src/github.com/zachgersh/go-github/github/licenses_test.go
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
// Copyright 2013 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 TestLicensesService_List(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/licenses", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testHeader(t, r, "Accept", mediaTypeLicensesPreview)
|
||||||
|
fmt.Fprint(w, `[{"key":"mit","name":"MIT","url":"https://api.github.com/licenses/mit"}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
licenses, _, err := client.Licenses.List()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Licenses.List returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []License{{
|
||||||
|
Key: String("mit"),
|
||||||
|
Name: String("MIT"),
|
||||||
|
URL: String("https://api.github.com/licenses/mit"),
|
||||||
|
}}
|
||||||
|
if !reflect.DeepEqual(licenses, want) {
|
||||||
|
t.Errorf("Licenses.List returned %+v, want %+v", licenses, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLicensesService_Get(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/licenses/mit", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testHeader(t, r, "Accept", mediaTypeLicensesPreview)
|
||||||
|
fmt.Fprint(w, `{"key":"mit","name":"MIT"}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
license, _, err := client.Licenses.Get("mit")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Licenses.Get returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &License{Key: String("mit"), Name: String("MIT")}
|
||||||
|
if !reflect.DeepEqual(license, want) {
|
||||||
|
t.Errorf("Licenses.Get returned %+v, want %+v", license, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLicensesService_Get_invalidTemplate(t *testing.T) {
|
||||||
|
_, _, err := client.Licenses.Get("%")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
@@ -98,6 +98,10 @@ type APIMeta struct {
|
|||||||
// username and password, sudo mode, and two-factor authentication are
|
// username and password, sudo mode, and two-factor authentication are
|
||||||
// not supported on these servers.)
|
// not supported on these servers.)
|
||||||
VerifiablePasswordAuthentication *bool `json:"verifiable_password_authentication,omitempty"`
|
VerifiablePasswordAuthentication *bool `json:"verifiable_password_authentication,omitempty"`
|
||||||
|
|
||||||
|
// An array of IP addresses in CIDR format specifying the addresses
|
||||||
|
// which serve GitHub Pages websites.
|
||||||
|
Pages []string `json:"pages,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// APIMeta returns information about GitHub.com, the service. Or, if you access
|
// APIMeta returns information about GitHub.com, the service. Or, if you access
|
||||||
@@ -159,3 +163,35 @@ func (c *Client) Zen() (string, *Response, error) {
|
|||||||
|
|
||||||
return buf.String(), resp, nil
|
return buf.String(), resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ServiceHook represents a hook that has configuration settings, a list of
|
||||||
|
// available events, and default events.
|
||||||
|
type ServiceHook struct {
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
Events []string `json:"events,omitempty"`
|
||||||
|
SupportedEvents []string `json:"supported_events,omitempty"`
|
||||||
|
Schema [][]string `json:"schema,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ServiceHook) String() string {
|
||||||
|
return Stringify(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListServiceHooks lists all of the available service hooks.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/webhooks/#services
|
||||||
|
func (c *Client) ListServiceHooks() ([]ServiceHook, *Response, error) {
|
||||||
|
u := "hooks"
|
||||||
|
req, err := c.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
hooks := new([]ServiceHook)
|
||||||
|
resp, err := c.Do(req, hooks)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *hooks, resp, err
|
||||||
|
}
|
@@ -72,7 +72,7 @@ func TestAPIMeta(t *testing.T) {
|
|||||||
|
|
||||||
mux.HandleFunc("/meta", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/meta", func(w http.ResponseWriter, r *http.Request) {
|
||||||
testMethod(t, r, "GET")
|
testMethod(t, r, "GET")
|
||||||
fmt.Fprint(w, `{"hooks":["h"], "git":["g"], "verifiable_password_authentication": true}`)
|
fmt.Fprint(w, `{"hooks":["h"], "git":["g"], "pages":["p"], "verifiable_password_authentication": true}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
meta, _, err := client.APIMeta()
|
meta, _, err := client.APIMeta()
|
||||||
@@ -83,6 +83,7 @@ func TestAPIMeta(t *testing.T) {
|
|||||||
want := &APIMeta{
|
want := &APIMeta{
|
||||||
Hooks: []string{"h"},
|
Hooks: []string{"h"},
|
||||||
Git: []string{"g"},
|
Git: []string{"g"},
|
||||||
|
Pages: []string{"p"},
|
||||||
VerifiablePasswordAuthentication: Bool(true),
|
VerifiablePasswordAuthentication: Bool(true),
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(want, meta) {
|
if !reflect.DeepEqual(want, meta) {
|
||||||
@@ -135,3 +136,35 @@ func TestZen(t *testing.T) {
|
|||||||
t.Errorf("Zen returned %+v, want %+v", got, want)
|
t.Errorf("Zen returned %+v, want %+v", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListServiceHooks(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/hooks", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `[{
|
||||||
|
"name":"n",
|
||||||
|
"events":["e"],
|
||||||
|
"supported_events":["s"],
|
||||||
|
"schema":[
|
||||||
|
["a", "b"]
|
||||||
|
]
|
||||||
|
}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
hooks, _, err := client.Repositories.ListServiceHooks()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.ListHooks returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []ServiceHook{{
|
||||||
|
Name: String("n"),
|
||||||
|
Events: []string{"e"},
|
||||||
|
SupportedEvents: []string{"s"},
|
||||||
|
Schema: [][]string{{"a", "b"}},
|
||||||
|
}}
|
||||||
|
if !reflect.DeepEqual(hooks, want) {
|
||||||
|
t.Errorf("Repositories.ListServiceHooks returned %+v, want %+v", hooks, want)
|
||||||
|
}
|
||||||
|
}
|
104
Godeps/_workspace/src/github.com/zachgersh/go-github/github/orgs_hooks.go
generated
vendored
Normal file
104
Godeps/_workspace/src/github.com/zachgersh/go-github/github/orgs_hooks.go
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
// Copyright 2015 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"
|
||||||
|
|
||||||
|
// ListHooks lists all Hooks for the specified organization.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#list-hooks
|
||||||
|
func (s *OrganizationsService) ListHooks(org string, opt *ListOptions) ([]Hook, *Response, error) {
|
||||||
|
u := fmt.Sprintf("orgs/%v/hooks", 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
|
||||||
|
}
|
||||||
|
|
||||||
|
hooks := new([]Hook)
|
||||||
|
resp, err := s.client.Do(req, hooks)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *hooks, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetHook returns a single specified Hook.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#get-single-hook
|
||||||
|
func (s *OrganizationsService) GetHook(org string, id int) (*Hook, *Response, error) {
|
||||||
|
u := fmt.Sprintf("orgs/%v/hooks/%d", org, id)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
hook := new(Hook)
|
||||||
|
resp, err := s.client.Do(req, hook)
|
||||||
|
return hook, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateHook creates a Hook for the specified org.
|
||||||
|
// Name and Config are required fields.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#create-a-hook
|
||||||
|
func (s *OrganizationsService) CreateHook(org string, hook *Hook) (*Hook, *Response, error) {
|
||||||
|
u := fmt.Sprintf("orgs/%v/hooks", org)
|
||||||
|
req, err := s.client.NewRequest("POST", u, hook)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
h := new(Hook)
|
||||||
|
resp, err := s.client.Do(req, h)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return h, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditHook updates a specified Hook.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#edit-a-hook
|
||||||
|
func (s *OrganizationsService) EditHook(org string, id int, hook *Hook) (*Hook, *Response, error) {
|
||||||
|
u := fmt.Sprintf("orgs/%v/hooks/%d", org, id)
|
||||||
|
req, err := s.client.NewRequest("PATCH", u, hook)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
h := new(Hook)
|
||||||
|
resp, err := s.client.Do(req, h)
|
||||||
|
return h, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// PingHook triggers a 'ping' event to be sent to the Hook.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#ping-a-hook
|
||||||
|
func (s *OrganizationsService) PingHook(org string, id int) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("orgs/%v/hooks/%d/pings", org, id)
|
||||||
|
req, err := s.client.NewRequest("POST", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteHook deletes a specified Hook.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#delete-a-hook
|
||||||
|
func (s *OrganizationsService) DeleteHook(org string, id int) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("orgs/%v/hooks/%d", org, id)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
134
Godeps/_workspace/src/github.com/zachgersh/go-github/github/orgs_hooks_test.go
generated
vendored
Normal file
134
Godeps/_workspace/src/github.com/zachgersh/go-github/github/orgs_hooks_test.go
generated
vendored
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
// Copyright 2015 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestOrganizationsService_ListHooks(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/hooks", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{"page": "2"})
|
||||||
|
fmt.Fprint(w, `[{"id":1}, {"id":2}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListOptions{Page: 2}
|
||||||
|
|
||||||
|
hooks, _, err := client.Organizations.ListHooks("o", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.ListHooks returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Hook{{ID: Int(1)}, {ID: Int(2)}}
|
||||||
|
if !reflect.DeepEqual(hooks, want) {
|
||||||
|
t.Errorf("Organizations.ListHooks returned %+v, want %+v", hooks, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_ListHooks_invalidOrg(t *testing.T) {
|
||||||
|
_, _, err := client.Organizations.ListHooks("%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_GetHook(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/hooks/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
hook, _, err := client.Organizations.GetHook("o", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.GetHook returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Hook{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(hook, want) {
|
||||||
|
t.Errorf("Organizations.GetHook returned %+v, want %+v", hook, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_GetHook_invalidOrg(t *testing.T) {
|
||||||
|
_, _, err := client.Organizations.GetHook("%", 1)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_EditHook(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &Hook{Name: String("t")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/hooks/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(Hook)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "PATCH")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
hook, _, err := client.Organizations.EditHook("o", 1, input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.EditHook returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Hook{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(hook, want) {
|
||||||
|
t.Errorf("Organizations.EditHook returned %+v, want %+v", hook, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_EditHook_invalidOrg(t *testing.T) {
|
||||||
|
_, _, err := client.Organizations.EditHook("%", 1, nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_PingHook(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/hooks/1/pings", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Organizations.PingHook("o", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.PingHook returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_DeleteHook(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/hooks/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Organizations.DeleteHook("o", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.DeleteHook returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_DeleteHook_invalidOrg(t *testing.T) {
|
||||||
|
_, err := client.Organizations.DeleteHook("%", 1)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
@@ -15,7 +15,16 @@ type Membership struct {
|
|||||||
// Possible values are: "active", "pending"
|
// Possible values are: "active", "pending"
|
||||||
State *string `json:"state,omitempty"`
|
State *string `json:"state,omitempty"`
|
||||||
|
|
||||||
// TODO(willnorris): add docs
|
// Role identifies the user's role within the organization or team.
|
||||||
|
// Possible values for organization membership:
|
||||||
|
// member - non-owner organization member
|
||||||
|
// admin - organization owner
|
||||||
|
//
|
||||||
|
// Possible values for team membership are:
|
||||||
|
// member - a normal member of the team
|
||||||
|
// maintainer - a team maintainer. Able to add/remove other team
|
||||||
|
// members, promote other team members to team
|
||||||
|
// maintainer, and edit the team’s name and description
|
||||||
Role *string `json:"role,omitempty"`
|
Role *string `json:"role,omitempty"`
|
||||||
|
|
||||||
// For organization membership, the API URL of the organization.
|
// For organization membership, the API URL of the organization.
|
||||||
@@ -43,6 +52,15 @@ type ListMembersOptions struct {
|
|||||||
// 2fa_disabled, all. Default is "all".
|
// 2fa_disabled, all. Default is "all".
|
||||||
Filter string `url:"filter,omitempty"`
|
Filter string `url:"filter,omitempty"`
|
||||||
|
|
||||||
|
// Role filters memebers returned by their role in the organization.
|
||||||
|
// Possible values are:
|
||||||
|
// all - all members of the organization, regardless of role
|
||||||
|
// admin - organization owners
|
||||||
|
// member - non-organization members
|
||||||
|
//
|
||||||
|
// Default is "all".
|
||||||
|
Role string `url:"role,omitempty"`
|
||||||
|
|
||||||
ListOptions
|
ListOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,6 +86,10 @@ func (s *OrganizationsService) ListMembers(org string, opt *ListMembersOptions)
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if opt != nil && opt.Role != "" {
|
||||||
|
req.Header.Set("Accept", mediaTypeOrgPermissionPreview)
|
||||||
|
}
|
||||||
|
|
||||||
members := new([]User)
|
members := new([]User)
|
||||||
resp, err := s.client.Do(req, members)
|
resp, err := s.client.Do(req, members)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -120,7 +142,8 @@ func (s *OrganizationsService) RemoveMember(org, user string) (*Response, error)
|
|||||||
return s.client.Do(req, nil)
|
return s.client.Do(req, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicizeMembership publicizes a user's membership in an organization.
|
// PublicizeMembership publicizes a user's membership in an organization. (A
|
||||||
|
// user cannot publicize the membership for another user.)
|
||||||
//
|
//
|
||||||
// GitHub API docs: http://developer.github.com/v3/orgs/members/#publicize-a-users-membership
|
// GitHub API docs: http://developer.github.com/v3/orgs/members/#publicize-a-users-membership
|
||||||
func (s *OrganizationsService) PublicizeMembership(org, user string) (*Response, error) {
|
func (s *OrganizationsService) PublicizeMembership(org, user string) (*Response, error) {
|
||||||
@@ -171,9 +194,6 @@ func (s *OrganizationsService) ListOrgMemberships(opt *ListOrgMembershipsOptions
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove custom Accept header when this API fully launches
|
|
||||||
req.Header.Set("Accept", mediaTypeMembershipPreview)
|
|
||||||
|
|
||||||
var memberships []Membership
|
var memberships []Membership
|
||||||
resp, err := s.client.Do(req, &memberships)
|
resp, err := s.client.Do(req, &memberships)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -183,20 +203,25 @@ func (s *OrganizationsService) ListOrgMemberships(opt *ListOrgMembershipsOptions
|
|||||||
return memberships, resp, err
|
return memberships, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOrgMembership gets the membership for the authenticated user for the
|
// GetOrgMembership gets the membership for a user in a specified organization.
|
||||||
// specified organization.
|
// Passing an empty string for user will get the membership for the
|
||||||
|
// authenticated user.
|
||||||
//
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/orgs/members/#get-organization-membership
|
||||||
// GitHub API docs: https://developer.github.com/v3/orgs/members/#get-your-organization-membership
|
// GitHub API docs: https://developer.github.com/v3/orgs/members/#get-your-organization-membership
|
||||||
func (s *OrganizationsService) GetOrgMembership(org string) (*Membership, *Response, error) {
|
func (s *OrganizationsService) GetOrgMembership(user, org string) (*Membership, *Response, error) {
|
||||||
u := fmt.Sprintf("user/memberships/orgs/%v", org)
|
var u string
|
||||||
|
if user != "" {
|
||||||
|
u = fmt.Sprintf("orgs/%v/memberships/%v", org, user)
|
||||||
|
} else {
|
||||||
|
u = fmt.Sprintf("user/memberships/orgs/%v", org)
|
||||||
|
}
|
||||||
|
|
||||||
req, err := s.client.NewRequest("GET", u, nil)
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove custom Accept header when this API fully launches
|
|
||||||
req.Header.Set("Accept", mediaTypeMembershipPreview)
|
|
||||||
|
|
||||||
membership := new(Membership)
|
membership := new(Membership)
|
||||||
resp, err := s.client.Do(req, membership)
|
resp, err := s.client.Do(req, membership)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -206,20 +231,25 @@ func (s *OrganizationsService) GetOrgMembership(org string) (*Membership, *Respo
|
|||||||
return membership, resp, err
|
return membership, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// EditOrgMembership edits the membership for the authenticated user for the
|
// EditOrgMembership edits the membership for user in specified organization.
|
||||||
// specified organization.
|
// Passing an empty string for user will edit the membership for the
|
||||||
|
// authenticated user.
|
||||||
//
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/orgs/members/#add-or-update-organization-membership
|
||||||
// GitHub API docs: https://developer.github.com/v3/orgs/members/#edit-your-organization-membership
|
// 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) {
|
func (s *OrganizationsService) EditOrgMembership(user, org string, membership *Membership) (*Membership, *Response, error) {
|
||||||
u := fmt.Sprintf("user/memberships/orgs/%v", org)
|
var u string
|
||||||
|
if user != "" {
|
||||||
|
u = fmt.Sprintf("orgs/%v/memberships/%v", org, user)
|
||||||
|
} else {
|
||||||
|
u = fmt.Sprintf("user/memberships/orgs/%v", org)
|
||||||
|
}
|
||||||
|
|
||||||
req, err := s.client.NewRequest("PATCH", u, membership)
|
req, err := s.client.NewRequest("PATCH", u, membership)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove custom Accept header when this API fully launches
|
|
||||||
req.Header.Set("Accept", mediaTypeMembershipPreview)
|
|
||||||
|
|
||||||
m := new(Membership)
|
m := new(Membership)
|
||||||
resp, err := s.client.Do(req, m)
|
resp, err := s.client.Do(req, m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -228,3 +258,17 @@ func (s *OrganizationsService) EditOrgMembership(org string, membership *Members
|
|||||||
|
|
||||||
return m, resp, err
|
return m, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveOrgMembership removes user from the specified organization. If the
|
||||||
|
// user has been invited to the organization, this will cancel their invitation.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/orgs/members/#remove-organization-membership
|
||||||
|
func (s *OrganizationsService) RemoveOrgMembership(user, org string) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("orgs/%v/memberships/%v", org, user)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
@@ -19,8 +19,10 @@ func TestOrganizationsService_ListMembers(t *testing.T) {
|
|||||||
|
|
||||||
mux.HandleFunc("/orgs/o/members", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/orgs/o/members", func(w http.ResponseWriter, r *http.Request) {
|
||||||
testMethod(t, r, "GET")
|
testMethod(t, r, "GET")
|
||||||
|
testHeader(t, r, "Accept", mediaTypeOrgPermissionPreview)
|
||||||
testFormValues(t, r, values{
|
testFormValues(t, r, values{
|
||||||
"filter": "2fa_disabled",
|
"filter": "2fa_disabled",
|
||||||
|
"role": "admin",
|
||||||
"page": "2",
|
"page": "2",
|
||||||
})
|
})
|
||||||
fmt.Fprint(w, `[{"id":1}]`)
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
@@ -29,6 +31,7 @@ func TestOrganizationsService_ListMembers(t *testing.T) {
|
|||||||
opt := &ListMembersOptions{
|
opt := &ListMembersOptions{
|
||||||
PublicOnly: false,
|
PublicOnly: false,
|
||||||
Filter: "2fa_disabled",
|
Filter: "2fa_disabled",
|
||||||
|
Role: "admin",
|
||||||
ListOptions: ListOptions{Page: 2},
|
ListOptions: ListOptions{Page: 2},
|
||||||
}
|
}
|
||||||
members, _, err := client.Organizations.ListMembers("o", opt)
|
members, _, err := client.Organizations.ListMembers("o", opt)
|
||||||
@@ -217,7 +220,6 @@ func TestOrganizationsService_ListOrgMemberships(t *testing.T) {
|
|||||||
|
|
||||||
mux.HandleFunc("/user/memberships/orgs", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/user/memberships/orgs", func(w http.ResponseWriter, r *http.Request) {
|
||||||
testMethod(t, r, "GET")
|
testMethod(t, r, "GET")
|
||||||
testHeader(t, r, "Accept", mediaTypeMembershipPreview)
|
|
||||||
testFormValues(t, r, values{
|
testFormValues(t, r, values{
|
||||||
"state": "active",
|
"state": "active",
|
||||||
"page": "2",
|
"page": "2",
|
||||||
@@ -240,17 +242,16 @@ func TestOrganizationsService_ListOrgMemberships(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOrganizationsService_GetOrgMembership(t *testing.T) {
|
func TestOrganizationsService_GetOrgMembership_AuthenticatedUser(t *testing.T) {
|
||||||
setup()
|
setup()
|
||||||
defer teardown()
|
defer teardown()
|
||||||
|
|
||||||
mux.HandleFunc("/user/memberships/orgs/o", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/user/memberships/orgs/o", func(w http.ResponseWriter, r *http.Request) {
|
||||||
testMethod(t, r, "GET")
|
testMethod(t, r, "GET")
|
||||||
testHeader(t, r, "Accept", mediaTypeMembershipPreview)
|
|
||||||
fmt.Fprint(w, `{"url":"u"}`)
|
fmt.Fprint(w, `{"url":"u"}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
membership, _, err := client.Organizations.GetOrgMembership("o")
|
membership, _, err := client.Organizations.GetOrgMembership("", "o")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Organizations.GetOrgMembership returned error: %v", err)
|
t.Errorf("Organizations.GetOrgMembership returned error: %v", err)
|
||||||
}
|
}
|
||||||
@@ -261,7 +262,27 @@ func TestOrganizationsService_GetOrgMembership(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOrganizationsService_EditOrgMembership(t *testing.T) {
|
func TestOrganizationsService_GetOrgMembership_SpecifiedUser(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/memberships/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"url":"u"}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
membership, _, err := client.Organizations.GetOrgMembership("u", "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_AuthenticatedUser(t *testing.T) {
|
||||||
setup()
|
setup()
|
||||||
defer teardown()
|
defer teardown()
|
||||||
|
|
||||||
@@ -272,7 +293,6 @@ func TestOrganizationsService_EditOrgMembership(t *testing.T) {
|
|||||||
json.NewDecoder(r.Body).Decode(v)
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
testMethod(t, r, "PATCH")
|
testMethod(t, r, "PATCH")
|
||||||
testHeader(t, r, "Accept", mediaTypeMembershipPreview)
|
|
||||||
if !reflect.DeepEqual(v, input) {
|
if !reflect.DeepEqual(v, input) {
|
||||||
t.Errorf("Request body = %+v, want %+v", v, input)
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
}
|
}
|
||||||
@@ -280,7 +300,7 @@ func TestOrganizationsService_EditOrgMembership(t *testing.T) {
|
|||||||
fmt.Fprint(w, `{"url":"u"}`)
|
fmt.Fprint(w, `{"url":"u"}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
membership, _, err := client.Organizations.EditOrgMembership("o", input)
|
membership, _, err := client.Organizations.EditOrgMembership("", "o", input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Organizations.EditOrgMembership returned error: %v", err)
|
t.Errorf("Organizations.EditOrgMembership returned error: %v", err)
|
||||||
}
|
}
|
||||||
@@ -290,3 +310,47 @@ func TestOrganizationsService_EditOrgMembership(t *testing.T) {
|
|||||||
t.Errorf("Organizations.EditOrgMembership returned %+v, want %+v", membership, want)
|
t.Errorf("Organizations.EditOrgMembership returned %+v, want %+v", membership, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_EditOrgMembership_SpecifiedUser(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &Membership{State: String("active")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/memberships/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(Membership)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "PATCH")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"url":"u"}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
membership, _, err := client.Organizations.EditOrgMembership("u", "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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_RemoveOrgMembership(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/memberships/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Organizations.RemoveOrgMembership("u", "o")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.RemoveOrgMembership returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
@@ -10,11 +10,25 @@ import "fmt"
|
|||||||
// Team represents a team within a GitHub organization. Teams are used to
|
// Team represents a team within a GitHub organization. Teams are used to
|
||||||
// manage access to an organization's repositories.
|
// manage access to an organization's repositories.
|
||||||
type Team struct {
|
type Team struct {
|
||||||
ID *int `json:"id,omitempty"`
|
ID *int `json:"id,omitempty"`
|
||||||
Name *string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
URL *string `json:"url,omitempty"`
|
URL *string `json:"url,omitempty"`
|
||||||
Slug *string `json:"slug,omitempty"`
|
Slug *string `json:"slug,omitempty"`
|
||||||
Permission *string `json:"permission,omitempty"`
|
|
||||||
|
// Permission is deprecated when creating or editing a team in an org
|
||||||
|
// using the new GitHub permission model. It no longer identifies the
|
||||||
|
// permission a team has on its repos, but only specifies the default
|
||||||
|
// permission a repo is initially added with. Avoid confusion by
|
||||||
|
// specifying a permission value when calling AddTeamRepo.
|
||||||
|
Permission *string `json:"permission,omitempty"`
|
||||||
|
|
||||||
|
// Privacy identifies the level of privacy this team should have.
|
||||||
|
// Possible values are:
|
||||||
|
// secret - only visible to organization owners and members of this team
|
||||||
|
// closed - visible to all members of this organization
|
||||||
|
// Default is "secret".
|
||||||
|
Privacy *string `json:"privacy,omitempty"`
|
||||||
|
|
||||||
MembersCount *int `json:"members_count,omitempty"`
|
MembersCount *int `json:"members_count,omitempty"`
|
||||||
ReposCount *int `json:"repos_count,omitempty"`
|
ReposCount *int `json:"repos_count,omitempty"`
|
||||||
Organization *Organization `json:"organization,omitempty"`
|
Organization *Organization `json:"organization,omitempty"`
|
||||||
@@ -77,6 +91,10 @@ func (s *OrganizationsService) CreateTeam(org string, team *Team) (*Team, *Respo
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if team.Privacy != nil {
|
||||||
|
req.Header.Set("Accept", mediaTypeOrgPermissionPreview)
|
||||||
|
}
|
||||||
|
|
||||||
t := new(Team)
|
t := new(Team)
|
||||||
resp, err := s.client.Do(req, t)
|
resp, err := s.client.Do(req, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -96,6 +114,10 @@ func (s *OrganizationsService) EditTeam(id int, team *Team) (*Team, *Response, e
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if team.Privacy != nil {
|
||||||
|
req.Header.Set("Accept", mediaTypeOrgPermissionPreview)
|
||||||
|
}
|
||||||
|
|
||||||
t := new(Team)
|
t := new(Team)
|
||||||
resp, err := s.client.Do(req, t)
|
resp, err := s.client.Do(req, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -118,11 +140,21 @@ func (s *OrganizationsService) DeleteTeam(team int) (*Response, error) {
|
|||||||
return s.client.Do(req, nil)
|
return s.client.Do(req, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OrganizationListTeamMembersOptions specifies the optional parameters to the
|
||||||
|
// OrganizationsService.ListTeamMembers method.
|
||||||
|
type OrganizationListTeamMembersOptions struct {
|
||||||
|
// Role filters members returned by their role in the team. Possible
|
||||||
|
// values are "all", "member", "maintainer". Default is "all".
|
||||||
|
Role string `url:"role,omitempty"`
|
||||||
|
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
// ListTeamMembers lists all of the users who are members of the specified
|
// ListTeamMembers lists all of the users who are members of the specified
|
||||||
// team.
|
// team.
|
||||||
//
|
//
|
||||||
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#list-team-members
|
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#list-team-members
|
||||||
func (s *OrganizationsService) ListTeamMembers(team int, opt *ListOptions) ([]User, *Response, error) {
|
func (s *OrganizationsService) ListTeamMembers(team int, opt *OrganizationListTeamMembersOptions) ([]User, *Response, error) {
|
||||||
u := fmt.Sprintf("teams/%v/members", team)
|
u := fmt.Sprintf("teams/%v/members", team)
|
||||||
u, err := addOptions(u, opt)
|
u, err := addOptions(u, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -134,6 +166,10 @@ func (s *OrganizationsService) ListTeamMembers(team int, opt *ListOptions) ([]Us
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if opt != nil && opt.Role != "" {
|
||||||
|
req.Header.Set("Accept", mediaTypeOrgPermissionPreview)
|
||||||
|
}
|
||||||
|
|
||||||
members := new([]User)
|
members := new([]User)
|
||||||
resp, err := s.client.Do(req, members)
|
resp, err := s.client.Do(req, members)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -158,32 +194,6 @@ func (s *OrganizationsService) IsTeamMember(team int, user string) (bool, *Respo
|
|||||||
return member, resp, err
|
return member, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddTeamMember adds a user to a team.
|
|
||||||
//
|
|
||||||
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#add-team-member
|
|
||||||
func (s *OrganizationsService) AddTeamMember(team int, user string) (*Response, error) {
|
|
||||||
u := fmt.Sprintf("teams/%v/members/%v", team, user)
|
|
||||||
req, err := s.client.NewRequest("PUT", u, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.client.Do(req, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveTeamMember removes a user from a team.
|
|
||||||
//
|
|
||||||
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#remove-team-member
|
|
||||||
func (s *OrganizationsService) RemoveTeamMember(team int, user string) (*Response, error) {
|
|
||||||
u := fmt.Sprintf("teams/%v/members/%v", team, user)
|
|
||||||
req, err := s.client.NewRequest("DELETE", u, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.client.Do(req, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListTeamRepos lists the repositories that the specified team has access to.
|
// ListTeamRepos lists the repositories that the specified team has access to.
|
||||||
//
|
//
|
||||||
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#list-team-repos
|
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#list-team-repos
|
||||||
@@ -208,19 +218,40 @@ func (s *OrganizationsService) ListTeamRepos(team int, opt *ListOptions) ([]Repo
|
|||||||
return *repos, resp, err
|
return *repos, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsTeamRepo checks if a team manages the specified repository.
|
// IsTeamRepo checks if a team manages the specified repository. If the
|
||||||
|
// repository is managed by team, a Repository is returned which includes the
|
||||||
|
// permissions team has for that repo.
|
||||||
//
|
//
|
||||||
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#get-team-repo
|
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#get-team-repo
|
||||||
func (s *OrganizationsService) IsTeamRepo(team int, owner string, repo string) (bool, *Response, error) {
|
func (s *OrganizationsService) IsTeamRepo(team int, owner string, repo string) (*Repository, *Response, error) {
|
||||||
u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo)
|
u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo)
|
||||||
req, err := s.client.NewRequest("GET", u, nil)
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := s.client.Do(req, nil)
|
req.Header.Set("Accept", mediaTypeOrgPermissionRepoPreview)
|
||||||
manages, err := parseBoolResponse(err)
|
|
||||||
return manages, resp, err
|
repository := new(Repository)
|
||||||
|
resp, err := s.client.Do(req, repository)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return repository, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrganizationAddTeamRepoOptions specifies the optional parameters to the
|
||||||
|
// OrganizationsService.AddTeamRepo method.
|
||||||
|
type OrganizationAddTeamRepoOptions struct {
|
||||||
|
// Permission specifies the permission to grant the team on this repository.
|
||||||
|
// Possible values are:
|
||||||
|
// pull - team members can pull, but not push to or administer this repository
|
||||||
|
// push - team members can pull and push, but not administer this repository
|
||||||
|
// admin - team members can pull, push and administer this repository
|
||||||
|
//
|
||||||
|
// If not specified, the team's permission attribute will be used.
|
||||||
|
Permission string `json:"permission,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddTeamRepo adds a repository to be managed by the specified team. The
|
// AddTeamRepo adds a repository to be managed by the specified team. The
|
||||||
@@ -228,13 +259,17 @@ func (s *OrganizationsService) IsTeamRepo(team int, owner string, repo string) (
|
|||||||
// belongs, or a direct fork of a repository owned by the organization.
|
// belongs, or a direct fork of a repository owned by the organization.
|
||||||
//
|
//
|
||||||
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#add-team-repo
|
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#add-team-repo
|
||||||
func (s *OrganizationsService) AddTeamRepo(team int, owner string, repo string) (*Response, error) {
|
func (s *OrganizationsService) AddTeamRepo(team int, owner string, repo string, opt *OrganizationAddTeamRepoOptions) (*Response, error) {
|
||||||
u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo)
|
u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo)
|
||||||
req, err := s.client.NewRequest("PUT", u, nil)
|
req, err := s.client.NewRequest("PUT", u, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if opt != nil {
|
||||||
|
req.Header.Set("Accept", mediaTypeOrgPermissionPreview)
|
||||||
|
}
|
||||||
|
|
||||||
return s.client.Do(req, nil)
|
return s.client.Do(req, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,9 +321,6 @@ func (s *OrganizationsService) GetTeamMembership(team int, user string) (*Member
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove custom Accept header when this API fully launches
|
|
||||||
req.Header.Set("Accept", mediaTypeMembershipPreview)
|
|
||||||
|
|
||||||
t := new(Membership)
|
t := new(Membership)
|
||||||
resp, err := s.client.Do(req, t)
|
resp, err := s.client.Do(req, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -298,6 +330,20 @@ func (s *OrganizationsService) GetTeamMembership(team int, user string) (*Member
|
|||||||
return t, resp, err
|
return t, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OrganizationAddTeamMembershipOptions does stuff specifies the optional
|
||||||
|
// parameters to the OrganizationsService.AddTeamMembership method.
|
||||||
|
type OrganizationAddTeamMembershipOptions struct {
|
||||||
|
// Role specifies the role the user should have in the team. Possible
|
||||||
|
// values are:
|
||||||
|
// member - a normal member of the team
|
||||||
|
// maintainer - a team maintainer. Able to add/remove other team
|
||||||
|
// members, promote other team members to team
|
||||||
|
// maintainer, and edit the team’s name and description
|
||||||
|
//
|
||||||
|
// Default value is "member".
|
||||||
|
Role string `json:"role,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// AddTeamMembership adds or invites a user to a team.
|
// AddTeamMembership adds or invites a user to a team.
|
||||||
//
|
//
|
||||||
// In order to add a membership between a user and a team, the authenticated
|
// In order to add a membership between a user and a team, the authenticated
|
||||||
@@ -316,15 +362,16 @@ func (s *OrganizationsService) GetTeamMembership(team int, user string) (*Member
|
|||||||
// 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) (*Membership, *Response, error) {
|
func (s *OrganizationsService) AddTeamMembership(team int, user string, opt *OrganizationAddTeamMembershipOptions) (*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, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove custom Accept header when this API fully launches
|
if opt != nil {
|
||||||
req.Header.Set("Accept", mediaTypeMembershipPreview)
|
req.Header.Set("Accept", mediaTypeOrgPermissionPreview)
|
||||||
|
}
|
||||||
|
|
||||||
t := new(Membership)
|
t := new(Membership)
|
||||||
resp, err := s.client.Do(req, t)
|
resp, err := s.client.Do(req, t)
|
||||||
@@ -345,8 +392,5 @@ func (s *OrganizationsService) RemoveTeamMembership(team int, user string) (*Res
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove custom Accept header when this API fully launches
|
|
||||||
req.Header.Set("Accept", mediaTypeMembershipPreview)
|
|
||||||
|
|
||||||
return s.client.Do(req, nil)
|
return s.client.Do(req, nil)
|
||||||
}
|
}
|
@@ -64,13 +64,14 @@ func TestOrganizationsService_CreateTeam(t *testing.T) {
|
|||||||
setup()
|
setup()
|
||||||
defer teardown()
|
defer teardown()
|
||||||
|
|
||||||
input := &Team{Name: String("n")}
|
input := &Team{Name: String("n"), Privacy: String("closed")}
|
||||||
|
|
||||||
mux.HandleFunc("/orgs/o/teams", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/orgs/o/teams", func(w http.ResponseWriter, r *http.Request) {
|
||||||
v := new(Team)
|
v := new(Team)
|
||||||
json.NewDecoder(r.Body).Decode(v)
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
testMethod(t, r, "POST")
|
testMethod(t, r, "POST")
|
||||||
|
testHeader(t, r, "Accept", mediaTypeOrgPermissionPreview)
|
||||||
if !reflect.DeepEqual(v, input) {
|
if !reflect.DeepEqual(v, input) {
|
||||||
t.Errorf("Request body = %+v, want %+v", v, input)
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
}
|
}
|
||||||
@@ -98,13 +99,14 @@ func TestOrganizationsService_EditTeam(t *testing.T) {
|
|||||||
setup()
|
setup()
|
||||||
defer teardown()
|
defer teardown()
|
||||||
|
|
||||||
input := &Team{Name: String("n")}
|
input := &Team{Name: String("n"), Privacy: String("closed")}
|
||||||
|
|
||||||
mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
v := new(Team)
|
v := new(Team)
|
||||||
json.NewDecoder(r.Body).Decode(v)
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
testMethod(t, r, "PATCH")
|
testMethod(t, r, "PATCH")
|
||||||
|
testHeader(t, r, "Accept", mediaTypeOrgPermissionPreview)
|
||||||
if !reflect.DeepEqual(v, input) {
|
if !reflect.DeepEqual(v, input) {
|
||||||
t.Errorf("Request body = %+v, want %+v", v, input)
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
}
|
}
|
||||||
@@ -143,11 +145,12 @@ func TestOrganizationsService_ListTeamMembers(t *testing.T) {
|
|||||||
|
|
||||||
mux.HandleFunc("/teams/1/members", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/teams/1/members", func(w http.ResponseWriter, r *http.Request) {
|
||||||
testMethod(t, r, "GET")
|
testMethod(t, r, "GET")
|
||||||
testFormValues(t, r, values{"page": "2"})
|
testHeader(t, r, "Accept", mediaTypeOrgPermissionPreview)
|
||||||
|
testFormValues(t, r, values{"role": "member", "page": "2"})
|
||||||
fmt.Fprint(w, `[{"id":1}]`)
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
})
|
})
|
||||||
|
|
||||||
opt := &ListOptions{Page: 2}
|
opt := &OrganizationListTeamMembersOptions{Role: "member", ListOptions: ListOptions{Page: 2}}
|
||||||
members, _, err := client.Organizations.ListTeamMembers(1, opt)
|
members, _, err := client.Organizations.ListTeamMembers(1, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Organizations.ListTeamMembers returned error: %v", err)
|
t.Errorf("Organizations.ListTeamMembers returned error: %v", err)
|
||||||
@@ -220,46 +223,6 @@ func TestOrganizationsService_IsTeamMember_invalidUser(t *testing.T) {
|
|||||||
testURLParseError(t, err)
|
testURLParseError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOrganizationsService_AddTeamMember(t *testing.T) {
|
|
||||||
setup()
|
|
||||||
defer teardown()
|
|
||||||
|
|
||||||
mux.HandleFunc("/teams/1/members/u", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
testMethod(t, r, "PUT")
|
|
||||||
w.WriteHeader(http.StatusNoContent)
|
|
||||||
})
|
|
||||||
|
|
||||||
_, err := client.Organizations.AddTeamMember(1, "u")
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Organizations.AddTeamMember returned error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestOrganizationsService_AddTeamMember_invalidUser(t *testing.T) {
|
|
||||||
_, err := client.Organizations.AddTeamMember(1, "%")
|
|
||||||
testURLParseError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestOrganizationsService_RemoveTeamMember(t *testing.T) {
|
|
||||||
setup()
|
|
||||||
defer teardown()
|
|
||||||
|
|
||||||
mux.HandleFunc("/teams/1/members/u", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
testMethod(t, r, "DELETE")
|
|
||||||
w.WriteHeader(http.StatusNoContent)
|
|
||||||
})
|
|
||||||
|
|
||||||
_, err := client.Organizations.RemoveTeamMember(1, "u")
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Organizations.RemoveTeamMember returned error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestOrganizationsService_RemoveTeamMember_invalidUser(t *testing.T) {
|
|
||||||
_, err := client.Organizations.RemoveTeamMember(1, "%")
|
|
||||||
testURLParseError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestOrganizationsService_PublicizeMembership(t *testing.T) {
|
func TestOrganizationsService_PublicizeMembership(t *testing.T) {
|
||||||
setup()
|
setup()
|
||||||
defer teardown()
|
defer teardown()
|
||||||
@@ -328,15 +291,18 @@ func TestOrganizationsService_IsTeamRepo_true(t *testing.T) {
|
|||||||
|
|
||||||
mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
|
||||||
testMethod(t, r, "GET")
|
testMethod(t, r, "GET")
|
||||||
w.WriteHeader(http.StatusNoContent)
|
testHeader(t, r, "Accept", mediaTypeOrgPermissionRepoPreview)
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
managed, _, err := client.Organizations.IsTeamRepo(1, "o", "r")
|
repo, _, err := client.Organizations.IsTeamRepo(1, "o", "r")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Organizations.IsTeamRepo returned error: %v", err)
|
t.Errorf("Organizations.IsTeamRepo returned error: %v", err)
|
||||||
}
|
}
|
||||||
if want := true; managed != want {
|
|
||||||
t.Errorf("Organizations.IsTeamRepo returned %+v, want %+v", managed, want)
|
want := &Repository{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(repo, want) {
|
||||||
|
t.Errorf("Organizations.IsTeamRepo returned %+v, want %+v", repo, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,12 +315,15 @@ func TestOrganizationsService_IsTeamRepo_false(t *testing.T) {
|
|||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
})
|
})
|
||||||
|
|
||||||
managed, _, err := client.Organizations.IsTeamRepo(1, "o", "r")
|
repo, resp, err := client.Organizations.IsTeamRepo(1, "o", "r")
|
||||||
if err != nil {
|
if err == nil {
|
||||||
t.Errorf("Organizations.IsTeamRepo returned error: %v", err)
|
t.Errorf("Expected HTTP 404 response")
|
||||||
}
|
}
|
||||||
if want := false; managed != want {
|
if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want {
|
||||||
t.Errorf("Organizations.IsTeamRepo returned %+v, want %+v", managed, want)
|
t.Errorf("Organizations.IsTeamRepo returned status %d, want %d", got, want)
|
||||||
|
}
|
||||||
|
if repo != nil {
|
||||||
|
t.Errorf("Organizations.IsTeamRepo returned %+v, want nil", repo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,12 +336,15 @@ func TestOrganizationsService_IsTeamRepo_error(t *testing.T) {
|
|||||||
http.Error(w, "BadRequest", http.StatusBadRequest)
|
http.Error(w, "BadRequest", http.StatusBadRequest)
|
||||||
})
|
})
|
||||||
|
|
||||||
managed, _, err := client.Organizations.IsTeamRepo(1, "o", "r")
|
repo, resp, err := client.Organizations.IsTeamRepo(1, "o", "r")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected HTTP 400 response")
|
t.Errorf("Expected HTTP 400 response")
|
||||||
}
|
}
|
||||||
if want := false; managed != want {
|
if got, want := resp.Response.StatusCode, http.StatusBadRequest; got != want {
|
||||||
t.Errorf("Organizations.IsTeamRepo returned %+v, want %+v", managed, want)
|
t.Errorf("Organizations.IsTeamRepo returned status %d, want %d", got, want)
|
||||||
|
}
|
||||||
|
if repo != nil {
|
||||||
|
t.Errorf("Organizations.IsTeamRepo returned %+v, want nil", repo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -385,12 +357,22 @@ func TestOrganizationsService_AddTeamRepo(t *testing.T) {
|
|||||||
setup()
|
setup()
|
||||||
defer teardown()
|
defer teardown()
|
||||||
|
|
||||||
|
opt := &OrganizationAddTeamRepoOptions{Permission: "admin"}
|
||||||
|
|
||||||
mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(OrganizationAddTeamRepoOptions)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
testMethod(t, r, "PUT")
|
testMethod(t, r, "PUT")
|
||||||
|
testHeader(t, r, "Accept", mediaTypeOrgPermissionPreview)
|
||||||
|
if !reflect.DeepEqual(v, opt) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, opt)
|
||||||
|
}
|
||||||
|
|
||||||
w.WriteHeader(http.StatusNoContent)
|
w.WriteHeader(http.StatusNoContent)
|
||||||
})
|
})
|
||||||
|
|
||||||
_, err := client.Organizations.AddTeamRepo(1, "o", "r")
|
_, err := client.Organizations.AddTeamRepo(1, "o", "r", opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Organizations.AddTeamRepo returned error: %v", err)
|
t.Errorf("Organizations.AddTeamRepo returned error: %v", err)
|
||||||
}
|
}
|
||||||
@@ -405,14 +387,14 @@ func TestOrganizationsService_AddTeamRepo_noAccess(t *testing.T) {
|
|||||||
w.WriteHeader(422)
|
w.WriteHeader(422)
|
||||||
})
|
})
|
||||||
|
|
||||||
_, err := client.Organizations.AddTeamRepo(1, "o", "r")
|
_, err := client.Organizations.AddTeamRepo(1, "o", "r", nil)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expcted error to be returned")
|
t.Errorf("Expcted error to be returned")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOrganizationsService_AddTeamRepo_invalidOwner(t *testing.T) {
|
func TestOrganizationsService_AddTeamRepo_invalidOwner(t *testing.T) {
|
||||||
_, err := client.Organizations.AddTeamRepo(1, "%", "r")
|
_, err := client.Organizations.AddTeamRepo(1, "%", "r", nil)
|
||||||
testURLParseError(t, err)
|
testURLParseError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,7 +424,6 @@ 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", mediaTypeMembershipPreview)
|
|
||||||
fmt.Fprint(w, `{"url":"u", "state":"active"}`)
|
fmt.Fprint(w, `{"url":"u", "state":"active"}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -461,13 +442,22 @@ func TestOrganizationsService_AddTeamMembership(t *testing.T) {
|
|||||||
setup()
|
setup()
|
||||||
defer teardown()
|
defer teardown()
|
||||||
|
|
||||||
|
opt := &OrganizationAddTeamMembershipOptions{Role: "maintainer"}
|
||||||
|
|
||||||
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) {
|
||||||
|
v := new(OrganizationAddTeamMembershipOptions)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
testMethod(t, r, "PUT")
|
testMethod(t, r, "PUT")
|
||||||
testHeader(t, r, "Accept", mediaTypeMembershipPreview)
|
testHeader(t, r, "Accept", mediaTypeOrgPermissionPreview)
|
||||||
|
if !reflect.DeepEqual(v, opt) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, opt)
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Fprint(w, `{"url":"u", "state":"pending"}`)
|
fmt.Fprint(w, `{"url":"u", "state":"pending"}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
membership, _, err := client.Organizations.AddTeamMembership(1, "u")
|
membership, _, err := client.Organizations.AddTeamMembership(1, "u", opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Organizations.AddTeamMembership returned error: %v", err)
|
t.Errorf("Organizations.AddTeamMembership returned error: %v", err)
|
||||||
}
|
}
|
||||||
@@ -484,7 +474,6 @@ 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", mediaTypeMembershipPreview)
|
|
||||||
w.WriteHeader(http.StatusNoContent)
|
w.WriteHeader(http.StatusNoContent)
|
||||||
})
|
})
|
||||||
|
|
@@ -41,6 +41,8 @@ type PullRequest struct {
|
|||||||
HTMLURL *string `json:"html_url,omitempty"`
|
HTMLURL *string `json:"html_url,omitempty"`
|
||||||
IssueURL *string `json:"issue_url,omitempty"`
|
IssueURL *string `json:"issue_url,omitempty"`
|
||||||
StatusesURL *string `json:"statuses_url,omitempty"`
|
StatusesURL *string `json:"statuses_url,omitempty"`
|
||||||
|
DiffURL *string `json:"diff_url,omitempty"`
|
||||||
|
PatchURL *string `json:"patch_url,omitempty"`
|
||||||
|
|
||||||
Head *PullRequestBranch `json:"head,omitempty"`
|
Head *PullRequestBranch `json:"head,omitempty"`
|
||||||
Base *PullRequestBranch `json:"base,omitempty"`
|
Base *PullRequestBranch `json:"base,omitempty"`
|
||||||
@@ -73,6 +75,15 @@ type PullRequestListOptions struct {
|
|||||||
// Base filters pull requests by base branch name.
|
// Base filters pull requests by base branch name.
|
||||||
Base string `url:"base,omitempty"`
|
Base string `url:"base,omitempty"`
|
||||||
|
|
||||||
|
// Sort specifies how to sort pull requests. Possible values are: created,
|
||||||
|
// updated, popularity, long-running. Default is "created".
|
||||||
|
Sort string `url:"sort,omitempty"`
|
||||||
|
|
||||||
|
// Direction in which to sort pull requests. Possible values are: asc, desc.
|
||||||
|
// If Sort is "created" or not specified, Default is "desc", otherwise Default
|
||||||
|
// is "asc"
|
||||||
|
Direction string `url:"direction,omitempty"`
|
||||||
|
|
||||||
ListOptions
|
ListOptions
|
||||||
}
|
}
|
||||||
|
|
@@ -93,7 +93,7 @@ func (s *PullRequestsService) GetComment(owner string, repo string, number int)
|
|||||||
|
|
||||||
// CreateComment creates a new comment on the specified pull request.
|
// CreateComment creates a new comment on the specified pull request.
|
||||||
//
|
//
|
||||||
// GitHub API docs: https://developer.github.com/v3/pulls/comments/#get-a-single-comment
|
// GitHub API docs: https://developer.github.com/v3/pulls/comments/#create-a-comment
|
||||||
func (s *PullRequestsService) CreateComment(owner string, repo string, number int, comment *PullRequestComment) (*PullRequestComment, *Response, error) {
|
func (s *PullRequestsService) CreateComment(owner string, repo string, number int, comment *PullRequestComment) (*PullRequestComment, *Response, error) {
|
||||||
u := fmt.Sprintf("repos/%v/%v/pulls/%d/comments", owner, repo, number)
|
u := fmt.Sprintf("repos/%v/%v/pulls/%d/comments", owner, repo, number)
|
||||||
req, err := s.client.NewRequest("POST", u, comment)
|
req, err := s.client.NewRequest("POST", u, comment)
|
@@ -20,15 +20,17 @@ func TestPullRequestsService_List(t *testing.T) {
|
|||||||
mux.HandleFunc("/repos/o/r/pulls", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/repos/o/r/pulls", func(w http.ResponseWriter, r *http.Request) {
|
||||||
testMethod(t, r, "GET")
|
testMethod(t, r, "GET")
|
||||||
testFormValues(t, r, values{
|
testFormValues(t, r, values{
|
||||||
"state": "closed",
|
"state": "closed",
|
||||||
"head": "h",
|
"head": "h",
|
||||||
"base": "b",
|
"base": "b",
|
||||||
"page": "2",
|
"sort": "created",
|
||||||
|
"direction": "desc",
|
||||||
|
"page": "2",
|
||||||
})
|
})
|
||||||
fmt.Fprint(w, `[{"number":1}]`)
|
fmt.Fprint(w, `[{"number":1}]`)
|
||||||
})
|
})
|
||||||
|
|
||||||
opt := &PullRequestListOptions{"closed", "h", "b", ListOptions{Page: 2}}
|
opt := &PullRequestListOptions{"closed", "h", "b", "created", "desc", ListOptions{Page: 2}}
|
||||||
pulls, _, err := client.PullRequests.List("o", "r", opt)
|
pulls, _, err := client.PullRequests.List("o", "r", opt)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -98,6 +100,29 @@ func TestPullRequestsService_Get_headAndBase(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPullRequestService_Get_DiffURLAndPatchURL(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/pulls/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"number":1,
|
||||||
|
"diff_url": "https://github.com/octocat/Hello-World/pull/1347.diff",
|
||||||
|
"patch_url": "https://github.com/octocat/Hello-World/pull/1347.patch"}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
pull, _, err := client.PullRequests.Get("o", "r", 1)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("PullRequests.Get returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &PullRequest{Number: Int(1), DiffURL: String("https://github.com/octocat/Hello-World/pull/1347.diff"), PatchURL: String("https://github.com/octocat/Hello-World/pull/1347.patch")}
|
||||||
|
if !reflect.DeepEqual(pull, want) {
|
||||||
|
t.Errorf("PullRequests.Get returned %+v, want %+v", pull, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestPullRequestsService_Get_invalidOwner(t *testing.T) {
|
func TestPullRequestsService_Get_invalidOwner(t *testing.T) {
|
||||||
_, _, err := client.PullRequests.Get("%", "r", 1)
|
_, _, err := client.PullRequests.Get("%", "r", 1)
|
||||||
testURLParseError(t, err)
|
testURLParseError(t, err)
|
@@ -49,6 +49,9 @@ type Repository struct {
|
|||||||
Organization *Organization `json:"organization,omitempty"`
|
Organization *Organization `json:"organization,omitempty"`
|
||||||
Permissions *map[string]bool `json:"permissions,omitempty"`
|
Permissions *map[string]bool `json:"permissions,omitempty"`
|
||||||
|
|
||||||
|
// Only provided when using RepositoriesService.Get while in preview
|
||||||
|
License *License `json:"license,omitempty"`
|
||||||
|
|
||||||
// Additional mutable fields when creating and editing a repository
|
// Additional mutable fields when creating and editing a repository
|
||||||
Private *bool `json:"private"`
|
Private *bool `json:"private"`
|
||||||
HasIssues *bool `json:"has_issues"`
|
HasIssues *bool `json:"has_issues"`
|
||||||
@@ -255,6 +258,10 @@ func (s *RepositoriesService) Get(owner, repo string) (*Repository, *Response, e
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: remove custom Accept header when the license support fully launches
|
||||||
|
// https://developer.github.com/v3/licenses/#get-a-repositorys-license
|
||||||
|
req.Header.Set("Accept", mediaTypeLicensesPreview)
|
||||||
|
|
||||||
repository := new(Repository)
|
repository := new(Repository)
|
||||||
resp, err := s.client.Do(req, repository)
|
resp, err := s.client.Do(req, repository)
|
||||||
if err != nil {
|
if err != nil {
|
@@ -22,6 +22,8 @@ func (s *RepositoriesService) ListCollaborators(owner, repo string, opt *ListOpt
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Accept", mediaTypeOrgPermissionPreview)
|
||||||
|
|
||||||
users := new([]User)
|
users := new([]User)
|
||||||
resp, err := s.client.Do(req, users)
|
resp, err := s.client.Do(req, users)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -49,15 +51,33 @@ func (s *RepositoriesService) IsCollaborator(owner, repo, user string) (bool, *R
|
|||||||
return isCollab, resp, err
|
return isCollab, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RepositoryAddCollaboratorOptions specifies the optional parameters to the
|
||||||
|
// RepositoriesService.AddCollaborator method.
|
||||||
|
type RepositoryAddCollaboratorOptions struct {
|
||||||
|
// Permission specifies the permission to grant the user on this repository.
|
||||||
|
// Possible values are:
|
||||||
|
// pull - team members can pull, but not push to or administer this repository
|
||||||
|
// 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.
|
||||||
|
Permission string `json:"permission,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// AddCollaborator adds the specified Github user as collaborator to the given repo.
|
// 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: http://developer.github.com/v3/repos/collaborators/#add-collaborator
|
||||||
func (s *RepositoriesService) AddCollaborator(owner, repo, user string) (*Response, error) {
|
func (s *RepositoriesService) AddCollaborator(owner, repo, user string, opt *RepositoryAddCollaboratorOptions) (*Response, error) {
|
||||||
u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user)
|
u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user)
|
||||||
req, err := s.client.NewRequest("PUT", u, nil)
|
req, err := s.client.NewRequest("PUT", u, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if opt != nil {
|
||||||
|
req.Header.Set("Accept", mediaTypeOrgPermissionPreview)
|
||||||
|
}
|
||||||
|
|
||||||
return s.client.Do(req, nil)
|
return s.client.Do(req, nil)
|
||||||
}
|
}
|
||||||
|
|
@@ -6,6 +6,7 @@
|
|||||||
package github
|
package github
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
@@ -18,6 +19,7 @@ func TestRepositoriesService_ListCollaborators(t *testing.T) {
|
|||||||
|
|
||||||
mux.HandleFunc("/repos/o/r/collaborators", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/repos/o/r/collaborators", func(w http.ResponseWriter, r *http.Request) {
|
||||||
testMethod(t, r, "GET")
|
testMethod(t, r, "GET")
|
||||||
|
testHeader(t, r, "Accept", mediaTypeOrgPermissionPreview)
|
||||||
testFormValues(t, r, values{"page": "2"})
|
testFormValues(t, r, values{"page": "2"})
|
||||||
fmt.Fprintf(w, `[{"id":1}, {"id":2}]`)
|
fmt.Fprintf(w, `[{"id":1}, {"id":2}]`)
|
||||||
})
|
})
|
||||||
@@ -86,19 +88,29 @@ func TestRepositoriesService_AddCollaborator(t *testing.T) {
|
|||||||
setup()
|
setup()
|
||||||
defer teardown()
|
defer teardown()
|
||||||
|
|
||||||
|
opt := &RepositoryAddCollaboratorOptions{Permission: "admin"}
|
||||||
|
|
||||||
mux.HandleFunc("/repos/o/r/collaborators/u", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/repos/o/r/collaborators/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(RepositoryAddCollaboratorOptions)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
testMethod(t, r, "PUT")
|
testMethod(t, r, "PUT")
|
||||||
|
testHeader(t, r, "Accept", mediaTypeOrgPermissionPreview)
|
||||||
|
if !reflect.DeepEqual(v, opt) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, opt)
|
||||||
|
}
|
||||||
|
|
||||||
w.WriteHeader(http.StatusNoContent)
|
w.WriteHeader(http.StatusNoContent)
|
||||||
})
|
})
|
||||||
|
|
||||||
_, err := client.Repositories.AddCollaborator("o", "r", "u")
|
_, err := client.Repositories.AddCollaborator("o", "r", "u", opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Repositories.AddCollaborator returned error: %v", err)
|
t.Errorf("Repositories.AddCollaborator returned error: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRepositoriesService_AddCollaborator_invalidUser(t *testing.T) {
|
func TestRepositoriesService_AddCollaborator_invalidUser(t *testing.T) {
|
||||||
_, err := client.Repositories.AddCollaborator("%", "%", "%")
|
_, err := client.Repositories.AddCollaborator("%", "%", "%", nil)
|
||||||
testURLParseError(t, err)
|
testURLParseError(t, err)
|
||||||
}
|
}
|
||||||
|
|
@@ -61,7 +61,8 @@ func (c CommitFile) String() string {
|
|||||||
// CommitsComparison is the result of comparing two commits.
|
// CommitsComparison is the result of comparing two commits.
|
||||||
// See CompareCommits() for details.
|
// See CompareCommits() for details.
|
||||||
type CommitsComparison struct {
|
type CommitsComparison struct {
|
||||||
BaseCommit *RepositoryCommit `json:"base_commit,omitempty"`
|
BaseCommit *RepositoryCommit `json:"base_commit,omitempty"`
|
||||||
|
MergeBaseCommit *RepositoryCommit `json:"merge_base_commit,omitempty"`
|
||||||
|
|
||||||
// Head can be 'behind' or 'ahead'
|
// Head can be 'behind' or 'ahead'
|
||||||
Status *string `json:"status,omitempty"`
|
Status *string `json:"status,omitempty"`
|
@@ -13,22 +13,25 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"path"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RepositoryContent represents a file or directory in a github repository.
|
// RepositoryContent represents a file or directory in a github repository.
|
||||||
type RepositoryContent struct {
|
type RepositoryContent struct {
|
||||||
Type *string `json:"type,omitempty"`
|
Type *string `json:"type,omitempty"`
|
||||||
Encoding *string `json:"encoding,omitempty"`
|
Encoding *string `json:"encoding,omitempty"`
|
||||||
Size *int `json:"size,omitempty"`
|
Size *int `json:"size,omitempty"`
|
||||||
Name *string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
Path *string `json:"path,omitempty"`
|
Path *string `json:"path,omitempty"`
|
||||||
Content *string `json:"content,omitempty"`
|
Content *string `json:"content,omitempty"`
|
||||||
SHA *string `json:"sha,omitempty"`
|
SHA *string `json:"sha,omitempty"`
|
||||||
URL *string `json:"url,omitempty"`
|
URL *string `json:"url,omitempty"`
|
||||||
GitURL *string `json:"giturl,omitempty"`
|
GitURL *string `json:"git_url,omitempty"`
|
||||||
HTMLURL *string `json:"htmlurl,omitempty"`
|
HTMLURL *string `json:"html_url,omitempty"`
|
||||||
|
DownloadURL *string `json:"download_url,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// RepositoryContentResponse holds the parsed response from CreateFile, UpdateFile, and DeleteFile.
|
// RepositoryContentResponse holds the parsed response from CreateFile, UpdateFile, and DeleteFile.
|
||||||
@@ -90,6 +93,32 @@ func (s *RepositoriesService) GetReadme(owner, repo string, opt *RepositoryConte
|
|||||||
return readme, resp, err
|
return readme, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DownloadContents returns an io.ReadCloser that reads the contents of the
|
||||||
|
// specified file. This function will work with files of any size, as opposed
|
||||||
|
// to GetContents which is limited to 1 Mb files. It is the caller's
|
||||||
|
// responsibility to close the ReadCloser.
|
||||||
|
func (s *RepositoriesService) DownloadContents(owner, repo, filepath string, opt *RepositoryContentGetOptions) (io.ReadCloser, error) {
|
||||||
|
dir := path.Dir(filepath)
|
||||||
|
filename := path.Base(filepath)
|
||||||
|
_, dirContents, _, err := s.GetContents(owner, repo, dir, opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, contents := range dirContents {
|
||||||
|
if *contents.Name == filename {
|
||||||
|
if contents.DownloadURL == nil || *contents.DownloadURL == "" {
|
||||||
|
return nil, fmt.Errorf("No download link found for %s", filepath)
|
||||||
|
}
|
||||||
|
resp, err := s.client.client.Get(*contents.DownloadURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp.Body, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("No file named %s found in %s", filename, dir)
|
||||||
|
}
|
||||||
|
|
||||||
// GetContents can return either the metadata and content of a single file
|
// GetContents can return either the metadata and content of a single file
|
||||||
// (when path references a file) or the metadata of all the files and/or
|
// (when path references a file) or the metadata of all the files and/or
|
||||||
// subdirectories of a directory (when path references a directory). To make it
|
// subdirectories of a directory (when path references a directory). To make it
|
@@ -2,6 +2,7 @@ package github
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -54,7 +55,70 @@ func TestRepositoriesService_GetReadme(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRepositoriesService_GetContent_File(t *testing.T) {
|
func TestRepositoriesService_DownloadContents_Success(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `[{
|
||||||
|
"type": "file",
|
||||||
|
"name": "f",
|
||||||
|
"download_url": "`+server.URL+`/download/f"
|
||||||
|
}]`)
|
||||||
|
})
|
||||||
|
mux.HandleFunc("/download/f", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, "foo")
|
||||||
|
})
|
||||||
|
|
||||||
|
r, err := client.Repositories.DownloadContents("o", "r", "d/f", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.DownloadContents returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes, err := ioutil.ReadAll(r)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Error reading response body: %v", err)
|
||||||
|
}
|
||||||
|
r.Close()
|
||||||
|
|
||||||
|
if got, want := string(bytes), "foo"; got != want {
|
||||||
|
t.Errorf("Repositories.DownloadContents returned %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_DownloadContents_NoDownloadURL(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `[{
|
||||||
|
"type": "file",
|
||||||
|
"name": "f",
|
||||||
|
}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Repositories.DownloadContents("o", "r", "d/f", nil)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Repositories.DownloadContents did not return expected error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_DownloadContents_NoFile(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `[]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Repositories.DownloadContents("o", "r", "d/f", nil)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Repositories.DownloadContents did not return expected error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_GetContents_File(t *testing.T) {
|
||||||
setup()
|
setup()
|
||||||
defer teardown()
|
defer teardown()
|
||||||
mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -69,7 +133,7 @@ func TestRepositoriesService_GetContent_File(t *testing.T) {
|
|||||||
})
|
})
|
||||||
fileContents, _, _, err := client.Repositories.GetContents("o", "r", "p", &RepositoryContentGetOptions{})
|
fileContents, _, _, err := client.Repositories.GetContents("o", "r", "p", &RepositoryContentGetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Repositories.GetContents_File returned error: %v", err)
|
t.Errorf("Repositories.GetContents returned error: %v", err)
|
||||||
}
|
}
|
||||||
want := &RepositoryContent{Type: String("file"), Name: String("LICENSE"), Size: Int(20678), Encoding: String("base64"), Path: String("LICENSE")}
|
want := &RepositoryContent{Type: String("file"), Name: String("LICENSE"), Size: Int(20678), Encoding: String("base64"), Path: String("LICENSE")}
|
||||||
if !reflect.DeepEqual(fileContents, want) {
|
if !reflect.DeepEqual(fileContents, want) {
|
||||||
@@ -77,7 +141,7 @@ func TestRepositoriesService_GetContent_File(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRepositoriesService_GetContent_Directory(t *testing.T) {
|
func TestRepositoriesService_GetContents_Directory(t *testing.T) {
|
||||||
setup()
|
setup()
|
||||||
defer teardown()
|
defer teardown()
|
||||||
mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -88,7 +152,7 @@ func TestRepositoriesService_GetContent_Directory(t *testing.T) {
|
|||||||
"path": "lib"
|
"path": "lib"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "file",
|
"type": "file",
|
||||||
"size": 20678,
|
"size": 20678,
|
||||||
"name": "LICENSE",
|
"name": "LICENSE",
|
||||||
"path": "LICENSE"
|
"path": "LICENSE"
|
||||||
@@ -96,7 +160,7 @@ func TestRepositoriesService_GetContent_Directory(t *testing.T) {
|
|||||||
})
|
})
|
||||||
_, directoryContents, _, err := client.Repositories.GetContents("o", "r", "p", &RepositoryContentGetOptions{})
|
_, directoryContents, _, err := client.Repositories.GetContents("o", "r", "p", &RepositoryContentGetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Repositories.GetContents_Directory returned error: %v", err)
|
t.Errorf("Repositories.GetContents returned error: %v", err)
|
||||||
}
|
}
|
||||||
want := []*RepositoryContent{{Type: String("dir"), Name: String("lib"), Path: String("lib")},
|
want := []*RepositoryContent{{Type: String("dir"), Name: String("lib"), Path: String("lib")},
|
||||||
{Type: String("file"), Name: String("LICENSE"), Size: Int(20678), Path: String("LICENSE")}}
|
{Type: String("file"), Name: String("LICENSE"), Size: Int(20678), Path: String("LICENSE")}}
|
@@ -27,13 +27,13 @@ type Deployment struct {
|
|||||||
|
|
||||||
// DeploymentRequest represents a deployment request
|
// DeploymentRequest represents a deployment request
|
||||||
type DeploymentRequest struct {
|
type DeploymentRequest struct {
|
||||||
Ref *string `json:"ref,omitempty"`
|
Ref *string `json:"ref,omitempty"`
|
||||||
Task *string `json:"task,omitempty"`
|
Task *string `json:"task,omitempty"`
|
||||||
AutoMerge *bool `json:"auto_merge,omitempty"`
|
AutoMerge *bool `json:"auto_merge,omitempty"`
|
||||||
RequiredContexts []string `json:"required_contexts,omitempty"`
|
RequiredContexts *[]string `json:"required_contexts,omitempty"`
|
||||||
Payload *string `json:"payload,omitempty"`
|
Payload *string `json:"payload,omitempty"`
|
||||||
Environment *string `json:"environment,omitempty"`
|
Environment *string `json:"environment,omitempty"`
|
||||||
Description *string `json:"description,omitempty"`
|
Description *string `json:"description,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeploymentsListOptions specifies the optional parameters to the
|
// DeploymentsListOptions specifies the optional parameters to the
|
||||||
@@ -69,9 +69,6 @@ func (s *RepositoriesService) ListDeployments(owner, repo string, opt *Deploymen
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove custom Accept header when this API fully launches
|
|
||||||
req.Header.Set("Accept", mediaTypeDeploymentPreview)
|
|
||||||
|
|
||||||
deployments := new([]Deployment)
|
deployments := new([]Deployment)
|
||||||
resp, err := s.client.Do(req, deployments)
|
resp, err := s.client.Do(req, deployments)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -92,9 +89,6 @@ func (s *RepositoriesService) CreateDeployment(owner, repo string, request *Depl
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove custom Accept header when this API fully launches
|
|
||||||
req.Header.Set("Accept", mediaTypeDeploymentPreview)
|
|
||||||
|
|
||||||
d := new(Deployment)
|
d := new(Deployment)
|
||||||
resp, err := s.client.Do(req, d)
|
resp, err := s.client.Do(req, d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -138,9 +132,6 @@ func (s *RepositoriesService) ListDeploymentStatuses(owner, repo string, deploym
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove custom Accept header when this API fully launches
|
|
||||||
req.Header.Set("Accept", mediaTypeDeploymentPreview)
|
|
||||||
|
|
||||||
statuses := new([]DeploymentStatus)
|
statuses := new([]DeploymentStatus)
|
||||||
resp, err := s.client.Do(req, statuses)
|
resp, err := s.client.Do(req, statuses)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -161,9 +152,6 @@ func (s *RepositoriesService) CreateDeploymentStatus(owner, repo string, deploym
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove custom Accept header when this API fully launches
|
|
||||||
req.Header.Set("Accept", mediaTypeDeploymentPreview)
|
|
||||||
|
|
||||||
d := new(DeploymentStatus)
|
d := new(DeploymentStatus)
|
||||||
resp, err := s.client.Do(req, d)
|
resp, err := s.client.Do(req, d)
|
||||||
if err != nil {
|
if err != nil {
|
@@ -164,6 +164,18 @@ func (s *RepositoriesService) DeleteHook(owner, repo string, id int) (*Response,
|
|||||||
return s.client.Do(req, nil)
|
return s.client.Do(req, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PingHook triggers a 'ping' event to be sent to the Hook.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/repos/hooks/#ping-a-hook
|
||||||
|
func (s *RepositoriesService) PingHook(owner, repo string, id int) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/hooks/%d/pings", owner, repo, id)
|
||||||
|
req, err := s.client.NewRequest("POST", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
// TestHook triggers a test Hook by github.
|
// TestHook triggers a test Hook by github.
|
||||||
//
|
//
|
||||||
// GitHub API docs: http://developer.github.com/v3/repos/hooks/#test-a-push-hook
|
// GitHub API docs: http://developer.github.com/v3/repos/hooks/#test-a-push-hook
|
||||||
@@ -176,34 +188,7 @@ func (s *RepositoriesService) TestHook(owner, repo string, id int) (*Response, e
|
|||||||
return s.client.Do(req, nil)
|
return s.client.Do(req, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServiceHook represents a hook that has configuration settings, a list of
|
// ListServiceHooks is deprecated. Use Client.ListServiceHooks instead.
|
||||||
// available events, and default events.
|
|
||||||
type ServiceHook struct {
|
|
||||||
Name *string `json:"name,omitempty"`
|
|
||||||
Events []string `json:"events,omitempty"`
|
|
||||||
SupportedEvents []string `json:"supported_events,omitempty"`
|
|
||||||
Schema [][]string `json:"schema,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ServiceHook) String() string {
|
|
||||||
return Stringify(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListServiceHooks lists all of the available service hooks.
|
|
||||||
//
|
|
||||||
// GitHub API docs: https://developer.github.com/webhooks/#services
|
|
||||||
func (s *RepositoriesService) ListServiceHooks() ([]ServiceHook, *Response, error) {
|
func (s *RepositoriesService) ListServiceHooks() ([]ServiceHook, *Response, error) {
|
||||||
u := "hooks"
|
return s.client.ListServiceHooks()
|
||||||
req, err := s.client.NewRequest("GET", u, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
hooks := new([]ServiceHook)
|
|
||||||
resp, err := s.client.Do(req, hooks)
|
|
||||||
if err != nil {
|
|
||||||
return nil, resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return *hooks, resp, err
|
|
||||||
}
|
}
|
@@ -153,6 +153,20 @@ func TestRepositoriesService_DeleteHook_invalidOwner(t *testing.T) {
|
|||||||
testURLParseError(t, err)
|
testURLParseError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_PingHook(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/hooks/1/pings", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Repositories.PingHook("o", "r", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.PingHook returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestRepositoriesService_TestHook(t *testing.T) {
|
func TestRepositoriesService_TestHook(t *testing.T) {
|
||||||
setup()
|
setup()
|
||||||
defer teardown()
|
defer teardown()
|
||||||
@@ -171,35 +185,3 @@ func TestRepositoriesService_TestHook_invalidOwner(t *testing.T) {
|
|||||||
_, err := client.Repositories.TestHook("%", "%", 1)
|
_, err := client.Repositories.TestHook("%", "%", 1)
|
||||||
testURLParseError(t, err)
|
testURLParseError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRepositoriesService_ListServiceHooks(t *testing.T) {
|
|
||||||
setup()
|
|
||||||
defer teardown()
|
|
||||||
|
|
||||||
mux.HandleFunc("/hooks", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
testMethod(t, r, "GET")
|
|
||||||
fmt.Fprint(w, `[{
|
|
||||||
"name":"n",
|
|
||||||
"events":["e"],
|
|
||||||
"supported_events":["s"],
|
|
||||||
"schema":[
|
|
||||||
["a", "b"]
|
|
||||||
]
|
|
||||||
}]`)
|
|
||||||
})
|
|
||||||
|
|
||||||
hooks, _, err := client.Repositories.ListServiceHooks()
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Repositories.ListHooks returned error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
want := []ServiceHook{{
|
|
||||||
Name: String("n"),
|
|
||||||
Events: []string{"e"},
|
|
||||||
SupportedEvents: []string{"s"},
|
|
||||||
Schema: [][]string{{"a", "b"}},
|
|
||||||
}}
|
|
||||||
if !reflect.DeepEqual(hooks, want) {
|
|
||||||
t.Errorf("Repositories.ListServiceHooks returned %+v, want %+v", hooks, want)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -8,7 +8,9 @@ package github
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"mime"
|
"mime"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
@@ -85,8 +87,27 @@ func (s *RepositoriesService) ListReleases(owner, repo string, opt *ListOptions)
|
|||||||
// GitHub API docs: http://developer.github.com/v3/repos/releases/#get-a-single-release
|
// GitHub API docs: http://developer.github.com/v3/repos/releases/#get-a-single-release
|
||||||
func (s *RepositoriesService) GetRelease(owner, repo string, id int) (*RepositoryRelease, *Response, error) {
|
func (s *RepositoriesService) GetRelease(owner, repo string, id int) (*RepositoryRelease, *Response, error) {
|
||||||
u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id)
|
u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id)
|
||||||
|
return s.getSingleRelease(u)
|
||||||
|
}
|
||||||
|
|
||||||
req, err := s.client.NewRequest("GET", u, nil)
|
// GetLatestRelease fetches the latest published release for the repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-the-latest-release
|
||||||
|
func (s *RepositoriesService) GetLatestRelease(owner, repo string) (*RepositoryRelease, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%s/%s/releases/latest", owner, repo)
|
||||||
|
return s.getSingleRelease(u)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetReleaseByTag fetches a release with the specified tag.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-release-by-tag-name
|
||||||
|
func (s *RepositoriesService) GetReleaseByTag(owner, repo, tag string) (*RepositoryRelease, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%s/%s/releases/tags/%s", owner, repo, tag)
|
||||||
|
return s.getSingleRelease(u)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *RepositoriesService) getSingleRelease(url string) (*RepositoryRelease, *Response, error) {
|
||||||
|
req, err := s.client.NewRequest("GET", url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@@ -192,6 +213,54 @@ func (s *RepositoriesService) GetReleaseAsset(owner, repo string, id int) (*Rele
|
|||||||
return asset, resp, err
|
return asset, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DowloadReleaseAsset downloads a release asset.
|
||||||
|
//
|
||||||
|
// DowloadReleaseAsset returns an io.ReadCloser that reads the contents of the
|
||||||
|
// specified release asset. It is the caller's responsibility to close the ReadCloser.
|
||||||
|
//
|
||||||
|
// GitHub API docs : http://developer.github.com/v3/repos/releases/#get-a-single-release-asset
|
||||||
|
func (s *RepositoriesService) DownloadReleaseAsset(owner, repo string, id int) (io.ReadCloser, error) {
|
||||||
|
u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.Header.Set("Accept", defaultMediaType)
|
||||||
|
|
||||||
|
var resp *http.Response
|
||||||
|
if s.client.client.Transport == nil {
|
||||||
|
resp, err = http.DefaultTransport.RoundTrip(req)
|
||||||
|
} else {
|
||||||
|
resp, err = s.client.client.Transport.RoundTrip(req)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GitHub API streamed the asset directly
|
||||||
|
if resp.StatusCode == http.StatusOK {
|
||||||
|
return resp.Body, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusFound {
|
||||||
|
return nil, fmt.Errorf("Expected status code 200 or 302, got %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GitHub API redirected to pre-signed S3 URL
|
||||||
|
downloadURL, err := resp.Location()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err = http.Get(downloadURL.String())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.Body, nil
|
||||||
|
}
|
||||||
|
|
||||||
// EditReleaseAsset edits a repository release asset.
|
// EditReleaseAsset edits a repository release asset.
|
||||||
//
|
//
|
||||||
// GitHub API docs : http://developer.github.com/v3/repos/releases/#edit-a-release-asset
|
// GitHub API docs : http://developer.github.com/v3/repos/releases/#edit-a-release-asset
|
@@ -6,8 +6,10 @@
|
|||||||
package github
|
package github
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
@@ -55,6 +57,46 @@ func TestRepositoriesService_GetRelease(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_GetLatestRelease(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/releases/latest", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"id":3}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
release, resp, err := client.Repositories.GetLatestRelease("o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.GetLatestRelease returned error: %v\n%v", err, resp.Body)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &RepositoryRelease{ID: Int(3)}
|
||||||
|
if !reflect.DeepEqual(release, want) {
|
||||||
|
t.Errorf("Repositories.GetLatestRelease returned %+v, want %+v", release, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_GetReleaseByTag(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/releases/tags/foo", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"id":13}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
release, resp, err := client.Repositories.GetReleaseByTag("o", "r", "foo")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.GetReleaseByTag returned error: %v\n%v", err, resp.Body)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &RepositoryRelease{ID: Int(13)}
|
||||||
|
if !reflect.DeepEqual(release, want) {
|
||||||
|
t.Errorf("Repositories.GetReleaseByTag returned %+v, want %+v", release, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestRepositoriesService_CreateRelease(t *testing.T) {
|
func TestRepositoriesService_CreateRelease(t *testing.T) {
|
||||||
setup()
|
setup()
|
||||||
defer teardown()
|
defer teardown()
|
||||||
@@ -164,6 +206,64 @@ func TestRepositoriesService_GetReleaseAsset(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_DownloadReleaseAsset_Stream(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/releases/assets/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testHeader(t, r, "Accept", defaultMediaType)
|
||||||
|
w.Header().Set("Content-Type", "application/octet-stream")
|
||||||
|
w.Header().Set("Content-Disposition", "attachment; filename=hello-world.txt")
|
||||||
|
fmt.Fprint(w, "Hello World")
|
||||||
|
})
|
||||||
|
|
||||||
|
reader, err := client.Repositories.DowloadReleaseAsset("o", "r", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.DowloadReleaseAsset returned error: %v", err)
|
||||||
|
}
|
||||||
|
want := []byte("Hello World")
|
||||||
|
content, err := ioutil.ReadAll(reader)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.DowloadReleaseAsset returned bad reader: %v", err)
|
||||||
|
}
|
||||||
|
if !bytes.Equal(want, content) {
|
||||||
|
t.Errorf("Repositories.DowloadReleaseAsset returned %+v, want %+v", content, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_DownloadReleaseAsset_Redirect(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/releases/assets/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testHeader(t, r, "Accept", defaultMediaType)
|
||||||
|
w.Header().Set("Location", server.URL+"/github-cloud/releases/1/hello-world.txt")
|
||||||
|
w.WriteHeader(http.StatusFound)
|
||||||
|
})
|
||||||
|
|
||||||
|
mux.HandleFunc("/github-cloud/releases/1/hello-world.txt", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
w.Header().Set("Content-Type", "application/octet-stream")
|
||||||
|
w.Header().Set("Content-Disposition", "attachment; filename=hello-world.txt")
|
||||||
|
fmt.Fprint(w, "Hello World")
|
||||||
|
})
|
||||||
|
|
||||||
|
reader, err := client.Repositories.DowloadReleaseAsset("o", "r", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.DowloadReleaseAsset returned error: %v", err)
|
||||||
|
}
|
||||||
|
want := []byte("Hello World")
|
||||||
|
content, err := ioutil.ReadAll(reader)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.DowloadReleaseAsset returned bad reader: %v", err)
|
||||||
|
}
|
||||||
|
if !bytes.Equal(want, content) {
|
||||||
|
t.Errorf("Repositories.DowloadReleaseAsset returned %+v, want %+v", content, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestRepositoriesService_EditReleaseAsset(t *testing.T) {
|
func TestRepositoriesService_EditReleaseAsset(t *testing.T) {
|
||||||
setup()
|
setup()
|
||||||
defer teardown()
|
defer teardown()
|
@@ -45,7 +45,6 @@ func TestRepositoriesService_List_specifiedUser(t *testing.T) {
|
|||||||
"direction": "asc",
|
"direction": "asc",
|
||||||
"page": "2",
|
"page": "2",
|
||||||
})
|
})
|
||||||
|
|
||||||
fmt.Fprint(w, `[{"id":1}]`)
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -191,7 +190,8 @@ func TestRepositoriesService_Get(t *testing.T) {
|
|||||||
|
|
||||||
mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
|
||||||
testMethod(t, r, "GET")
|
testMethod(t, r, "GET")
|
||||||
fmt.Fprint(w, `{"id":1,"name":"n","description":"d","owner":{"login":"l"}}`)
|
testHeader(t, r, "Accept", mediaTypeLicensesPreview)
|
||||||
|
fmt.Fprint(w, `{"id":1,"name":"n","description":"d","owner":{"login":"l"},"license":{"key":"mit"}}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
repo, _, err := client.Repositories.Get("o", "r")
|
repo, _, err := client.Repositories.Get("o", "r")
|
||||||
@@ -199,7 +199,7 @@ func TestRepositoriesService_Get(t *testing.T) {
|
|||||||
t.Errorf("Repositories.Get returned error: %v", err)
|
t.Errorf("Repositories.Get returned error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
want := &Repository{ID: Int(1), Name: String("n"), Description: String("d"), Owner: &User{Login: String("l")}}
|
want := &Repository{ID: Int(1), Name: String("n"), Description: String("d"), Owner: &User{Login: String("l")}, License: &License{Key: String("mit")}}
|
||||||
if !reflect.DeepEqual(repo, want) {
|
if !reflect.DeepEqual(repo, want) {
|
||||||
t.Errorf("Repositories.Get returned %+v, want %+v", repo, want)
|
t.Errorf("Repositories.Get returned %+v, want %+v", repo, want)
|
||||||
}
|
}
|
@@ -59,6 +59,10 @@ type User struct {
|
|||||||
// TextMatches is only populated from search results that request text matches
|
// TextMatches is only populated from search results that request text matches
|
||||||
// See: search.go and https://developer.github.com/v3/search/#text-match-metadata
|
// See: search.go and https://developer.github.com/v3/search/#text-match-metadata
|
||||||
TextMatches []TextMatch `json:"text_matches,omitempty"`
|
TextMatches []TextMatch `json:"text_matches,omitempty"`
|
||||||
|
|
||||||
|
// Permissions identifies the permissions that a user has on a given
|
||||||
|
// repository. This is only populated when calling Repositories.ListCollaborators.
|
||||||
|
Permissions *map[string]bool `json:"permissions,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u User) String() string {
|
func (u User) String() string {
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user