godeps
This commit is contained in:
36
Godeps/Godeps.json
generated
Normal file
36
Godeps/Godeps.json
generated
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"ImportPath": "github.com/concourse/github-release-resource",
|
||||||
|
"GoVersion": "go1.4.1",
|
||||||
|
"Packages": [
|
||||||
|
"./..."
|
||||||
|
],
|
||||||
|
"Deps": [
|
||||||
|
{
|
||||||
|
"ImportPath": "code.google.com/p/goauth2/oauth",
|
||||||
|
"Comment": "weekly-43",
|
||||||
|
"Rev": "d4571a95014ff1fdd0055dc0f6b7e977a42b1e5a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/google/go-github/github",
|
||||||
|
"Rev": "32eadd61120c7a84b8eeac3ac3795cb453a33054"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/google/go-querystring/query",
|
||||||
|
"Rev": "ec0a78e0f4db229b7897be36596a8944230b857a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/mitchellh/colorstring",
|
||||||
|
"Rev": "9797cb57e314a5a2c4d735ff060d5c6dcba57749"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/onsi/ginkgo",
|
||||||
|
"Comment": "v1.1.0-33-g17ea479",
|
||||||
|
"Rev": "17ea479729ee427265ac1e913443018350946ddf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/onsi/gomega",
|
||||||
|
"Comment": "v1.0-28-g8adf9e1",
|
||||||
|
"Rev": "8adf9e1730c55cdc590de7d49766cb2acc88d8f2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
5
Godeps/Readme
generated
Normal file
5
Godeps/Readme
generated
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
This directory tree is generated automatically by godep.
|
||||||
|
|
||||||
|
Please do not edit.
|
||||||
|
|
||||||
|
See https://github.com/tools/godep for more information.
|
||||||
2
Godeps/_workspace/.gitignore
generated
vendored
Normal file
2
Godeps/_workspace/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/pkg
|
||||||
|
/bin
|
||||||
100
Godeps/_workspace/src/code.google.com/p/goauth2/oauth/example/oauthreq.go
generated
vendored
Normal file
100
Godeps/_workspace/src/code.google.com/p/goauth2/oauth/example/oauthreq.go
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
// Copyright 2011 The goauth2 Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// This program makes a call to the specified API, authenticated with OAuth2.
|
||||||
|
// a list of example APIs can be found at https://code.google.com/oauthplayground/
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"code.google.com/p/goauth2/oauth"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
clientId = flag.String("id", "", "Client ID")
|
||||||
|
clientSecret = flag.String("secret", "", "Client Secret")
|
||||||
|
scope = flag.String("scope", "https://www.googleapis.com/auth/userinfo.profile", "OAuth scope")
|
||||||
|
redirectURL = flag.String("redirect_url", "oob", "Redirect URL")
|
||||||
|
authURL = flag.String("auth_url", "https://accounts.google.com/o/oauth2/auth", "Authentication URL")
|
||||||
|
tokenURL = flag.String("token_url", "https://accounts.google.com/o/oauth2/token", "Token URL")
|
||||||
|
requestURL = flag.String("request_url", "https://www.googleapis.com/oauth2/v1/userinfo", "API request")
|
||||||
|
code = flag.String("code", "", "Authorization Code")
|
||||||
|
cachefile = flag.String("cache", "cache.json", "Token cache file")
|
||||||
|
)
|
||||||
|
|
||||||
|
const usageMsg = `
|
||||||
|
To obtain a request token you must specify both -id and -secret.
|
||||||
|
|
||||||
|
To obtain Client ID and Secret, see the "OAuth 2 Credentials" section under
|
||||||
|
the "API Access" tab on this page: https://code.google.com/apis/console/
|
||||||
|
|
||||||
|
Once you have completed the OAuth flow, the credentials should be stored inside
|
||||||
|
the file specified by -cache and you may run without the -id and -secret flags.
|
||||||
|
`
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
// Set up a configuration.
|
||||||
|
config := &oauth.Config{
|
||||||
|
ClientId: *clientId,
|
||||||
|
ClientSecret: *clientSecret,
|
||||||
|
RedirectURL: *redirectURL,
|
||||||
|
Scope: *scope,
|
||||||
|
AuthURL: *authURL,
|
||||||
|
TokenURL: *tokenURL,
|
||||||
|
TokenCache: oauth.CacheFile(*cachefile),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up a Transport using the config.
|
||||||
|
transport := &oauth.Transport{Config: config}
|
||||||
|
|
||||||
|
// Try to pull the token from the cache; if this fails, we need to get one.
|
||||||
|
token, err := config.TokenCache.Token()
|
||||||
|
if err != nil {
|
||||||
|
if *clientId == "" || *clientSecret == "" {
|
||||||
|
flag.Usage()
|
||||||
|
fmt.Fprint(os.Stderr, usageMsg)
|
||||||
|
os.Exit(2)
|
||||||
|
}
|
||||||
|
if *code == "" {
|
||||||
|
// Get an authorization code from the data provider.
|
||||||
|
// ("Please ask the user if I can access this resource.")
|
||||||
|
url := config.AuthCodeURL("")
|
||||||
|
fmt.Println("Visit this URL to get a code, then run again with -code=YOUR_CODE\n")
|
||||||
|
fmt.Println(url)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Exchange the authorization code for an access token.
|
||||||
|
// ("Here's the code you gave the user, now give me a token!")
|
||||||
|
token, err = transport.Exchange(*code)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Exchange:", err)
|
||||||
|
}
|
||||||
|
// (The Exchange method will automatically cache the token.)
|
||||||
|
fmt.Printf("Token is cached in %v\n", config.TokenCache)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the actual request using the cached token to authenticate.
|
||||||
|
// ("Here's the token, let me in!")
|
||||||
|
transport.Token = token
|
||||||
|
|
||||||
|
// Make the request.
|
||||||
|
r, err := transport.Client().Get(*requestURL)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Get:", err)
|
||||||
|
}
|
||||||
|
defer r.Body.Close()
|
||||||
|
|
||||||
|
// Write the response to standard output.
|
||||||
|
io.Copy(os.Stdout, r.Body)
|
||||||
|
|
||||||
|
// Send final carriage return, just to be neat.
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
1
Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/example/example.client_secrets.json
generated
vendored
Normal file
1
Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/example/example.client_secrets.json
generated
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"web":{"auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://accounts.google.com/o/oauth2/token","client_email":"XXXXXXXXXXXX@developer.gserviceaccount.com","client_x509_cert_url":"https://www.googleapis.com/robot/v1/metadata/x509/XXXXXXXXXXXX@developer.gserviceaccount.com","client_id":"XXXXXXXXXXXX.apps.googleusercontent.com","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs"}}
|
||||||
20
Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/example/example.pem
generated
vendored
Normal file
20
Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/example/example.pem
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
Bag Attributes
|
||||||
|
friendlyName: privatekey
|
||||||
|
localKeyID: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
Key Attributes: <No Attributes>
|
||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
XXXXxyXXXXXXXxxyxxxX9y0XXYXXXXYXXxXyxxXxXxXXXyXXXXx4yx1xy1xyYxxY
|
||||||
|
1XxYy38YxXxxxyXxyyxx+xxxxyx1Y1xYx7yx2/Y1XyyXYYYxY5YXxX0xY/Y642yX
|
||||||
|
zYYxYXzXYxY0Y8y9YxyYXxxX40YyXxxXX4XXxx7XxXxxXyXxYYXxXyxX5XY0Yy2X
|
||||||
|
1YX0XXyy6YXyXx9XxXxyXX9XXYXxXxXXXXXXxYXYY3Y8Yy311XYYY81XyY14Xyyx
|
||||||
|
xXyx7xxXXXxxxxyyyX4YYYXyYyYXyxX4XYXYyxXYyx9xy23xXYyXyxYxXxx1XXXY
|
||||||
|
y98yX6yYxyyyX4Xyx1Xy/0yxxYxXxYYx2xx7yYXXXxYXXXxyXyyYYxx5XX2xxyxy
|
||||||
|
y6Yyyx0XX3YYYyx9YYXXXX7y0yxXXy+90XYz1y2xyx7yXxX+8X0xYxXXYxxyxYYy
|
||||||
|
YXx8Yy4yX0Xyxxx6yYX92yxy1YYYzyyyyxy55x/yyXXXYYXYXXzXXxYYxyXY8XXX
|
||||||
|
+y9+yXxX7XxxyYYxxXYxyY623xxXxYX59x5Y6yYyXYY4YxXXYXXXYxXYxXxXXx6x
|
||||||
|
YXX7XxXX2X0XY7YXyYy1XXxYXxXxYY1xXXxxxyy+07zXYxYxxXyyxxyxXx1XYy5X
|
||||||
|
5XYzyxYxXXYyX9XX7xX8xXxx+XXYyYXXXX5YY1x8Yxyx54Xy/1XXyyYXY5YxYyxY
|
||||||
|
XyyxXyX/YxxXXXxXXYXxyxx63xX/xxyYXXyYzx0XY+YxX5xyYyyxxxXXYX/94XXy
|
||||||
|
Xx63xYxXyXY3/XXxyyXX15XXXyz08XYY5YYXY/YXy/96x68XyyXXxYyXy4xYXx5x
|
||||||
|
7yxxyxxYxXxyx3y=
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
114
Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/example/main.go
generated
vendored
Normal file
114
Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/example/main.go
generated
vendored
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
// Copyright 2011 The goauth2 Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// This program makes a read only call to the Google Cloud Storage API,
|
||||||
|
// authenticated with OAuth2. A list of example APIs can be found at
|
||||||
|
// https://code.google.com/oauthplayground/
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"code.google.com/p/goauth2/oauth/jwt"
|
||||||
|
)
|
||||||
|
|
||||||
|
const scope = "https://www.googleapis.com/auth/devstorage.read_only"
|
||||||
|
|
||||||
|
var (
|
||||||
|
secretsFile = flag.String("s", "", "JSON encoded secrets for the service account")
|
||||||
|
pemFile = flag.String("k", "", "private pem key file for the service account")
|
||||||
|
)
|
||||||
|
|
||||||
|
const usageMsg = `
|
||||||
|
You must specify -k and -s.
|
||||||
|
|
||||||
|
To obtain client secrets and pem, see the "OAuth 2 Credentials" section under
|
||||||
|
the "API Access" tab on this page: https://code.google.com/apis/console/
|
||||||
|
|
||||||
|
Google Cloud Storage must also be turned on in the API console.
|
||||||
|
`
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
if *secretsFile == "" || *pemFile == "" {
|
||||||
|
flag.Usage()
|
||||||
|
fmt.Println(usageMsg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the secret file bytes into the config.
|
||||||
|
secretBytes, err := ioutil.ReadFile(*secretsFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("error reading secerets file:", err)
|
||||||
|
}
|
||||||
|
var config struct {
|
||||||
|
Web struct {
|
||||||
|
ClientEmail string `json:"client_email"`
|
||||||
|
ClientID string `json:"client_id"`
|
||||||
|
TokenURI string `json:"token_uri"`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(secretBytes, &config)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("error unmarshalling secerets:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the project ID from the client ID.
|
||||||
|
projectID := strings.SplitN(config.Web.ClientID, "-", 2)[0]
|
||||||
|
|
||||||
|
// Read the pem file bytes for the private key.
|
||||||
|
keyBytes, err := ioutil.ReadFile(*pemFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("error reading private key file:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Craft the ClaimSet and JWT token.
|
||||||
|
t := jwt.NewToken(config.Web.ClientEmail, scope, keyBytes)
|
||||||
|
t.ClaimSet.Aud = config.Web.TokenURI
|
||||||
|
|
||||||
|
// We need to provide a client.
|
||||||
|
c := &http.Client{}
|
||||||
|
|
||||||
|
// Get the access token.
|
||||||
|
o, err := t.Assert(c)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("assertion error:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh token will be missing, but this access_token will be good
|
||||||
|
// for one hour.
|
||||||
|
fmt.Printf("access_token = %v\n", o.AccessToken)
|
||||||
|
fmt.Printf("refresh_token = %v\n", o.RefreshToken)
|
||||||
|
fmt.Printf("expires %v\n", o.Expiry)
|
||||||
|
|
||||||
|
// Form the request to list Google Cloud Storage buckets.
|
||||||
|
req, err := http.NewRequest("GET", "https://storage.googleapis.com/", nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("http.NewRequest:", err)
|
||||||
|
}
|
||||||
|
req.Header.Set("Authorization", "OAuth "+o.AccessToken)
|
||||||
|
req.Header.Set("x-goog-api-version", "2")
|
||||||
|
req.Header.Set("x-goog-project-id", projectID)
|
||||||
|
|
||||||
|
// Make the request.
|
||||||
|
r, err := c.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("API request error:", err)
|
||||||
|
}
|
||||||
|
defer r.Body.Close()
|
||||||
|
|
||||||
|
// Write the response to standard output.
|
||||||
|
res, err := ioutil.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("error reading API request results:", err)
|
||||||
|
}
|
||||||
|
fmt.Printf("\nRESULT:\n%s\n", res)
|
||||||
|
}
|
||||||
511
Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/jwt.go
generated
vendored
Normal file
511
Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/jwt.go
generated
vendored
Normal file
@@ -0,0 +1,511 @@
|
|||||||
|
// Copyright 2012 The goauth2 Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// The jwt package provides support for creating credentials for OAuth2 service
|
||||||
|
// account requests.
|
||||||
|
//
|
||||||
|
// For examples of the package usage please see jwt_test.go.
|
||||||
|
// Example usage (error handling omitted for brevity):
|
||||||
|
//
|
||||||
|
// // Craft the ClaimSet and JWT token.
|
||||||
|
// iss := "XXXXXXXXXXXX@developer.gserviceaccount.com"
|
||||||
|
// scope := "https://www.googleapis.com/auth/devstorage.read_only"
|
||||||
|
// t := jwt.NewToken(iss, scope, pemKeyBytes)
|
||||||
|
//
|
||||||
|
// // We need to provide a client.
|
||||||
|
// c := &http.Client{}
|
||||||
|
//
|
||||||
|
// // Get the access token.
|
||||||
|
// o, _ := t.Assert(c)
|
||||||
|
//
|
||||||
|
// // Form the request to the service.
|
||||||
|
// req, _ := http.NewRequest("GET", "https://storage.googleapis.com/", nil)
|
||||||
|
// req.Header.Set("Authorization", "OAuth "+o.AccessToken)
|
||||||
|
// req.Header.Set("x-goog-api-version", "2")
|
||||||
|
// req.Header.Set("x-goog-project-id", "XXXXXXXXXXXX")
|
||||||
|
//
|
||||||
|
// // Make the request.
|
||||||
|
// result, _ := c.Do(req)
|
||||||
|
//
|
||||||
|
// For info on OAuth2 service accounts please see the online documentation.
|
||||||
|
// https://developers.google.com/accounts/docs/OAuth2ServiceAccount
|
||||||
|
//
|
||||||
|
package jwt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/sha256"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"encoding/pem"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"code.google.com/p/goauth2/oauth"
|
||||||
|
)
|
||||||
|
|
||||||
|
// These are the default/standard values for this to work for Google service accounts.
|
||||||
|
const (
|
||||||
|
stdAlgorithm = "RS256"
|
||||||
|
stdType = "JWT"
|
||||||
|
stdAssertionType = "http://oauth.net/grant_type/jwt/1.0/bearer"
|
||||||
|
stdGrantType = "urn:ietf:params:oauth:grant-type:jwt-bearer"
|
||||||
|
stdAud = "https://accounts.google.com/o/oauth2/token"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrInvalidKey = errors.New("Invalid Key")
|
||||||
|
)
|
||||||
|
|
||||||
|
// base64Encode returns and Base64url encoded version of the input string with any
|
||||||
|
// trailing "=" stripped.
|
||||||
|
func base64Encode(b []byte) string {
|
||||||
|
return strings.TrimRight(base64.URLEncoding.EncodeToString(b), "=")
|
||||||
|
}
|
||||||
|
|
||||||
|
// base64Decode decodes the Base64url encoded string
|
||||||
|
func base64Decode(s string) ([]byte, error) {
|
||||||
|
// add back missing padding
|
||||||
|
switch len(s) % 4 {
|
||||||
|
case 2:
|
||||||
|
s += "=="
|
||||||
|
case 3:
|
||||||
|
s += "="
|
||||||
|
}
|
||||||
|
return base64.URLEncoding.DecodeString(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The JWT claim set contains information about the JWT including the
|
||||||
|
// permissions being requested (scopes), the target of the token, the issuer,
|
||||||
|
// the time the token was issued, and the lifetime of the token.
|
||||||
|
//
|
||||||
|
// Aud is usually https://accounts.google.com/o/oauth2/token
|
||||||
|
type ClaimSet struct {
|
||||||
|
Iss string `json:"iss"` // email address of the client_id of the application making the access token request
|
||||||
|
Scope string `json:"scope,omitempty"` // space-delimited list of the permissions the application requests
|
||||||
|
Aud string `json:"aud"` // descriptor of the intended target of the assertion (Optional).
|
||||||
|
Prn string `json:"prn,omitempty"` // email for which the application is requesting delegated access (Optional).
|
||||||
|
Exp int64 `json:"exp"`
|
||||||
|
Iat int64 `json:"iat"`
|
||||||
|
Typ string `json:"typ,omitempty"`
|
||||||
|
Sub string `json:"sub,omitempty"` // Add support for googleapi delegation support
|
||||||
|
|
||||||
|
// See http://tools.ietf.org/html/draft-jones-json-web-token-10#section-4.3
|
||||||
|
// This array is marshalled using custom code (see (c *ClaimSet) encode()).
|
||||||
|
PrivateClaims map[string]interface{} `json:"-"`
|
||||||
|
|
||||||
|
exp time.Time
|
||||||
|
iat time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
// setTimes sets iat and exp to time.Now() and iat.Add(time.Hour) respectively.
|
||||||
|
//
|
||||||
|
// Note that these times have nothing to do with the expiration time for the
|
||||||
|
// access_token returned by the server. These have to do with the lifetime of
|
||||||
|
// the encoded JWT.
|
||||||
|
//
|
||||||
|
// A JWT can be re-used for up to one hour after it was encoded. The access
|
||||||
|
// token that is granted will also be good for one hour so there is little point
|
||||||
|
// in trying to use the JWT a second time.
|
||||||
|
func (c *ClaimSet) setTimes(t time.Time) {
|
||||||
|
c.iat = t
|
||||||
|
c.exp = c.iat.Add(time.Hour)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
jsonStart = []byte{'{'}
|
||||||
|
jsonEnd = []byte{'}'}
|
||||||
|
)
|
||||||
|
|
||||||
|
// encode returns the Base64url encoded form of the Signature.
|
||||||
|
func (c *ClaimSet) encode() string {
|
||||||
|
if c.exp.IsZero() || c.iat.IsZero() {
|
||||||
|
c.setTimes(time.Now())
|
||||||
|
}
|
||||||
|
if c.Aud == "" {
|
||||||
|
c.Aud = stdAud
|
||||||
|
}
|
||||||
|
c.Exp = c.exp.Unix()
|
||||||
|
c.Iat = c.iat.Unix()
|
||||||
|
|
||||||
|
b, err := json.Marshal(c)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(c.PrivateClaims) == 0 {
|
||||||
|
return base64Encode(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marshal private claim set and then append it to b.
|
||||||
|
prv, err := json.Marshal(c.PrivateClaims)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Errorf("Invalid map of private claims %v", c.PrivateClaims))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Concatenate public and private claim JSON objects.
|
||||||
|
if !bytes.HasSuffix(b, jsonEnd) {
|
||||||
|
panic(fmt.Errorf("Invalid JSON %s", b))
|
||||||
|
}
|
||||||
|
if !bytes.HasPrefix(prv, jsonStart) {
|
||||||
|
panic(fmt.Errorf("Invalid JSON %s", prv))
|
||||||
|
}
|
||||||
|
b[len(b)-1] = ',' // Replace closing curly brace with a comma.
|
||||||
|
b = append(b, prv[1:]...) // Append private claims.
|
||||||
|
|
||||||
|
return base64Encode(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Header describes the algorithm and type of token being generated,
|
||||||
|
// and optionally a KeyID describing additional parameters for the
|
||||||
|
// signature.
|
||||||
|
type Header struct {
|
||||||
|
Algorithm string `json:"alg"`
|
||||||
|
Type string `json:"typ"`
|
||||||
|
KeyId string `json:"kid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Header) encode() string {
|
||||||
|
b, err := json.Marshal(h)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return base64Encode(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// A JWT is composed of three parts: a header, a claim set, and a signature.
|
||||||
|
// The well formed and encoded JWT can then be exchanged for an access token.
|
||||||
|
//
|
||||||
|
// The Token is not a JWT, but is is encoded to produce a well formed JWT.
|
||||||
|
//
|
||||||
|
// When obtaining a key from the Google API console it will be downloaded in a
|
||||||
|
// PKCS12 encoding. To use this key you will need to convert it to a PEM file.
|
||||||
|
// This can be achieved with openssl.
|
||||||
|
//
|
||||||
|
// $ openssl pkcs12 -in <key.p12> -nocerts -passin pass:notasecret -nodes -out <key.pem>
|
||||||
|
//
|
||||||
|
// The contents of this file can then be used as the Key.
|
||||||
|
type Token struct {
|
||||||
|
ClaimSet *ClaimSet // claim set used to construct the JWT
|
||||||
|
Header *Header // header used to construct the JWT
|
||||||
|
Key []byte // PEM printable encoding of the private key
|
||||||
|
pKey *rsa.PrivateKey
|
||||||
|
|
||||||
|
header string
|
||||||
|
claim string
|
||||||
|
sig string
|
||||||
|
|
||||||
|
useExternalSigner bool
|
||||||
|
signer Signer
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewToken returns a filled in *Token based on the standard header,
|
||||||
|
// and sets the Iat and Exp times based on when the call to Assert is
|
||||||
|
// made.
|
||||||
|
func NewToken(iss, scope string, key []byte) *Token {
|
||||||
|
c := &ClaimSet{
|
||||||
|
Iss: iss,
|
||||||
|
Scope: scope,
|
||||||
|
Aud: stdAud,
|
||||||
|
}
|
||||||
|
h := &Header{
|
||||||
|
Algorithm: stdAlgorithm,
|
||||||
|
Type: stdType,
|
||||||
|
}
|
||||||
|
t := &Token{
|
||||||
|
ClaimSet: c,
|
||||||
|
Header: h,
|
||||||
|
Key: key,
|
||||||
|
}
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signer is an interface that given a JWT token, returns the header &
|
||||||
|
// claim (serialized and urlEncoded to a byte slice), along with the
|
||||||
|
// signature and an error (if any occured). It could modify any data
|
||||||
|
// to sign (typically the KeyID).
|
||||||
|
//
|
||||||
|
// Example usage where a SHA256 hash of the original url-encoded token
|
||||||
|
// with an added KeyID and secret data is used as a signature:
|
||||||
|
//
|
||||||
|
// var privateData = "secret data added to hash, indexed by KeyID"
|
||||||
|
//
|
||||||
|
// type SigningService struct{}
|
||||||
|
//
|
||||||
|
// func (ss *SigningService) Sign(in *jwt.Token) (newTokenData, sig []byte, err error) {
|
||||||
|
// in.Header.KeyID = "signing service"
|
||||||
|
// newTokenData = in.EncodeWithoutSignature()
|
||||||
|
// dataToSign := fmt.Sprintf("%s.%s", newTokenData, privateData)
|
||||||
|
// h := sha256.New()
|
||||||
|
// _, err := h.Write([]byte(dataToSign))
|
||||||
|
// sig = h.Sum(nil)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
type Signer interface {
|
||||||
|
Sign(in *Token) (tokenData, signature []byte, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSignerToken returns a *Token, using an external signer function
|
||||||
|
func NewSignerToken(iss, scope string, signer Signer) *Token {
|
||||||
|
t := NewToken(iss, scope, nil)
|
||||||
|
t.useExternalSigner = true
|
||||||
|
t.signer = signer
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expired returns a boolean value letting us know if the token has expired.
|
||||||
|
func (t *Token) Expired() bool {
|
||||||
|
return t.ClaimSet.exp.Before(time.Now())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode constructs and signs a Token returning a JWT ready to use for
|
||||||
|
// requesting an access token.
|
||||||
|
func (t *Token) Encode() (string, error) {
|
||||||
|
var tok string
|
||||||
|
t.header = t.Header.encode()
|
||||||
|
t.claim = t.ClaimSet.encode()
|
||||||
|
err := t.sign()
|
||||||
|
if err != nil {
|
||||||
|
return tok, err
|
||||||
|
}
|
||||||
|
tok = fmt.Sprintf("%s.%s.%s", t.header, t.claim, t.sig)
|
||||||
|
return tok, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodeWithoutSignature returns the url-encoded value of the Token
|
||||||
|
// before signing has occured (typically for use by external signers).
|
||||||
|
func (t *Token) EncodeWithoutSignature() string {
|
||||||
|
t.header = t.Header.encode()
|
||||||
|
t.claim = t.ClaimSet.encode()
|
||||||
|
return fmt.Sprintf("%s.%s", t.header, t.claim)
|
||||||
|
}
|
||||||
|
|
||||||
|
// sign computes the signature for a Token. The details for this can be found
|
||||||
|
// in the OAuth2 Service Account documentation.
|
||||||
|
// https://developers.google.com/accounts/docs/OAuth2ServiceAccount#computingsignature
|
||||||
|
func (t *Token) sign() error {
|
||||||
|
if t.useExternalSigner {
|
||||||
|
fulldata, sig, err := t.signer.Sign(t)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
split := strings.Split(string(fulldata), ".")
|
||||||
|
if len(split) != 2 {
|
||||||
|
return errors.New("no token returned")
|
||||||
|
}
|
||||||
|
t.header = split[0]
|
||||||
|
t.claim = split[1]
|
||||||
|
t.sig = base64Encode(sig)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ss := fmt.Sprintf("%s.%s", t.header, t.claim)
|
||||||
|
if t.pKey == nil {
|
||||||
|
err := t.parsePrivateKey()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
h := sha256.New()
|
||||||
|
h.Write([]byte(ss))
|
||||||
|
b, err := rsa.SignPKCS1v15(rand.Reader, t.pKey, crypto.SHA256, h.Sum(nil))
|
||||||
|
t.sig = base64Encode(b)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// parsePrivateKey converts the Token's Key ([]byte) into a parsed
|
||||||
|
// rsa.PrivateKey. If the key is not well formed this method will return an
|
||||||
|
// ErrInvalidKey error.
|
||||||
|
func (t *Token) parsePrivateKey() error {
|
||||||
|
block, _ := pem.Decode(t.Key)
|
||||||
|
if block == nil {
|
||||||
|
return ErrInvalidKey
|
||||||
|
}
|
||||||
|
parsedKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var ok bool
|
||||||
|
t.pKey, ok = parsedKey.(*rsa.PrivateKey)
|
||||||
|
if !ok {
|
||||||
|
return ErrInvalidKey
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert obtains an *oauth.Token from the remote server by encoding and sending
|
||||||
|
// a JWT. The access_token will expire in one hour (3600 seconds) and cannot be
|
||||||
|
// refreshed (no refresh_token is returned with the response). Once this token
|
||||||
|
// expires call this method again to get a fresh one.
|
||||||
|
func (t *Token) Assert(c *http.Client) (*oauth.Token, error) {
|
||||||
|
var o *oauth.Token
|
||||||
|
t.ClaimSet.setTimes(time.Now())
|
||||||
|
u, v, err := t.buildRequest()
|
||||||
|
if err != nil {
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
resp, err := c.PostForm(u, v)
|
||||||
|
if err != nil {
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
o, err = handleResponse(resp)
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// buildRequest sets up the URL values and the proper URL string for making our
|
||||||
|
// access_token request.
|
||||||
|
func (t *Token) buildRequest() (string, url.Values, error) {
|
||||||
|
v := url.Values{}
|
||||||
|
j, err := t.Encode()
|
||||||
|
if err != nil {
|
||||||
|
return t.ClaimSet.Aud, v, err
|
||||||
|
}
|
||||||
|
v.Set("grant_type", stdGrantType)
|
||||||
|
v.Set("assertion", j)
|
||||||
|
return t.ClaimSet.Aud, v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used for decoding the response body.
|
||||||
|
type respBody struct {
|
||||||
|
IdToken string `json:"id_token"`
|
||||||
|
Access string `json:"access_token"`
|
||||||
|
Type string `json:"token_type"`
|
||||||
|
ExpiresIn time.Duration `json:"expires_in"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleResponse returns a filled in *oauth.Token given the *http.Response from
|
||||||
|
// a *http.Request created by buildRequest.
|
||||||
|
func handleResponse(r *http.Response) (*oauth.Token, error) {
|
||||||
|
o := &oauth.Token{}
|
||||||
|
defer r.Body.Close()
|
||||||
|
if r.StatusCode != 200 {
|
||||||
|
return o, errors.New("invalid response: " + r.Status)
|
||||||
|
}
|
||||||
|
b := &respBody{}
|
||||||
|
err := json.NewDecoder(r.Body).Decode(b)
|
||||||
|
if err != nil {
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
o.AccessToken = b.Access
|
||||||
|
if b.IdToken != "" {
|
||||||
|
// decode returned id token to get expiry
|
||||||
|
o.AccessToken = b.IdToken
|
||||||
|
s := strings.Split(b.IdToken, ".")
|
||||||
|
if len(s) < 2 {
|
||||||
|
return nil, errors.New("invalid token received")
|
||||||
|
}
|
||||||
|
d, err := base64Decode(s[1])
|
||||||
|
if err != nil {
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
c := &ClaimSet{}
|
||||||
|
err = json.NewDecoder(bytes.NewBuffer(d)).Decode(c)
|
||||||
|
if err != nil {
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
o.Expiry = time.Unix(c.Exp, 0)
|
||||||
|
return o, nil
|
||||||
|
}
|
||||||
|
o.Expiry = time.Now().Add(b.ExpiresIn * time.Second)
|
||||||
|
return o, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transport implements http.RoundTripper. When configured with a valid
|
||||||
|
// JWT and OAuth tokens it can be used to make authenticated HTTP requests.
|
||||||
|
//
|
||||||
|
// t := &jwt.Transport{jwtToken, oauthToken}
|
||||||
|
// r, _, err := t.Client().Get("http://example.org/url/requiring/auth")
|
||||||
|
//
|
||||||
|
// It will automatically refresh the OAuth token if it can, updating in place.
|
||||||
|
type Transport struct {
|
||||||
|
JWTToken *Token
|
||||||
|
OAuthToken *oauth.Token
|
||||||
|
|
||||||
|
// Transport is the HTTP transport to use when making requests.
|
||||||
|
// It will default to http.DefaultTransport if nil.
|
||||||
|
Transport http.RoundTripper
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a new authenticated transport.
|
||||||
|
func NewTransport(token *Token) (*Transport, error) {
|
||||||
|
oa, err := token.Assert(new(http.Client))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Transport{
|
||||||
|
JWTToken: token,
|
||||||
|
OAuthToken: oa,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client returns an *http.Client that makes OAuth-authenticated requests.
|
||||||
|
func (t *Transport) Client() *http.Client {
|
||||||
|
return &http.Client{Transport: t}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetches the internal transport.
|
||||||
|
func (t *Transport) transport() http.RoundTripper {
|
||||||
|
if t.Transport != nil {
|
||||||
|
return t.Transport
|
||||||
|
}
|
||||||
|
return http.DefaultTransport
|
||||||
|
}
|
||||||
|
|
||||||
|
// RoundTrip executes a single HTTP transaction using the Transport's
|
||||||
|
// OAuthToken as authorization headers.
|
||||||
|
//
|
||||||
|
// This method will attempt to renew the token if it has expired and may return
|
||||||
|
// an error related to that token renewal before attempting the client request.
|
||||||
|
// If the token cannot be renewed a non-nil os.Error value will be returned.
|
||||||
|
// If the token is invalid callers should expect HTTP-level errors,
|
||||||
|
// as indicated by the Response's StatusCode.
|
||||||
|
func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
|
// Sanity check the two tokens
|
||||||
|
if t.JWTToken == nil {
|
||||||
|
return nil, fmt.Errorf("no JWT token supplied")
|
||||||
|
}
|
||||||
|
if t.OAuthToken == nil {
|
||||||
|
return nil, fmt.Errorf("no OAuth token supplied")
|
||||||
|
}
|
||||||
|
// Refresh the OAuth token if it has expired
|
||||||
|
if t.OAuthToken.Expired() {
|
||||||
|
if oa, err := t.JWTToken.Assert(new(http.Client)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
t.OAuthToken = oa
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// To set the Authorization header, we must make a copy of the Request
|
||||||
|
// so that we don't modify the Request we were given.
|
||||||
|
// This is required by the specification of http.RoundTripper.
|
||||||
|
req = cloneRequest(req)
|
||||||
|
req.Header.Set("Authorization", "Bearer "+t.OAuthToken.AccessToken)
|
||||||
|
|
||||||
|
// Make the HTTP request.
|
||||||
|
return t.transport().RoundTrip(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// cloneRequest returns a clone of the provided *http.Request.
|
||||||
|
// The clone is a shallow copy of the struct and its Header map.
|
||||||
|
func cloneRequest(r *http.Request) *http.Request {
|
||||||
|
// shallow copy of the struct
|
||||||
|
r2 := new(http.Request)
|
||||||
|
*r2 = *r
|
||||||
|
// deep copy of the Header
|
||||||
|
r2.Header = make(http.Header)
|
||||||
|
for k, s := range r.Header {
|
||||||
|
r2.Header[k] = s
|
||||||
|
}
|
||||||
|
return r2
|
||||||
|
}
|
||||||
486
Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/jwt_test.go
generated
vendored
Normal file
486
Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/jwt_test.go
generated
vendored
Normal file
@@ -0,0 +1,486 @@
|
|||||||
|
// Copyright 2012 The goauth2 Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// For package documentation please see jwt.go.
|
||||||
|
//
|
||||||
|
package jwt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/sha256"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/json"
|
||||||
|
"encoding/pem"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
stdHeaderStr = `{"alg":"RS256","typ":"JWT"}`
|
||||||
|
iss = "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com"
|
||||||
|
scope = "https://www.googleapis.com/auth/prediction"
|
||||||
|
exp = 1328554385
|
||||||
|
iat = 1328550785 // exp + 1 hour
|
||||||
|
)
|
||||||
|
|
||||||
|
// Base64url encoded Header
|
||||||
|
const headerEnc = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9"
|
||||||
|
|
||||||
|
// Base64url encoded ClaimSet
|
||||||
|
const claimSetEnc = "eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU1NDM4NSwiaWF0IjoxMzI4NTUwNzg1fQ"
|
||||||
|
|
||||||
|
// Base64url encoded Signature
|
||||||
|
const sigEnc = "olukbHreNiYrgiGCTEmY3eWGeTvYDSUHYoE84Jz3BRPBSaMdZMNOn_0CYK7UHPO7OdvUofjwft1dH59UxE9GWS02pjFti1uAQoImaqjLZoTXr8qiF6O_kDa9JNoykklWlRAIwGIZkDupCS-8cTAnM_ksSymiH1coKJrLDUX_BM0x2f4iMFQzhL5vT1ll-ZipJ0lNlxb5QsyXxDYcxtHYguF12-vpv3ItgT0STfcXoWzIGQoEbhwB9SBp9JYcQ8Ygz6pYDjm0rWX9LrchmTyDArCodpKLFtutNgcIFUP9fWxvwd1C2dNw5GjLcKr9a_SAERyoJ2WnCR1_j9N0wD2o0g"
|
||||||
|
|
||||||
|
// Base64url encoded Token
|
||||||
|
const tokEnc = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU1NDM4NSwiaWF0IjoxMzI4NTUwNzg1fQ.olukbHreNiYrgiGCTEmY3eWGeTvYDSUHYoE84Jz3BRPBSaMdZMNOn_0CYK7UHPO7OdvUofjwft1dH59UxE9GWS02pjFti1uAQoImaqjLZoTXr8qiF6O_kDa9JNoykklWlRAIwGIZkDupCS-8cTAnM_ksSymiH1coKJrLDUX_BM0x2f4iMFQzhL5vT1ll-ZipJ0lNlxb5QsyXxDYcxtHYguF12-vpv3ItgT0STfcXoWzIGQoEbhwB9SBp9JYcQ8Ygz6pYDjm0rWX9LrchmTyDArCodpKLFtutNgcIFUP9fWxvwd1C2dNw5GjLcKr9a_SAERyoJ2WnCR1_j9N0wD2o0g"
|
||||||
|
|
||||||
|
// Private key for testing
|
||||||
|
const privateKeyPem = `-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEpAIBAAKCAQEA4ej0p7bQ7L/r4rVGUz9RN4VQWoej1Bg1mYWIDYslvKrk1gpj
|
||||||
|
7wZgkdmM7oVK2OfgrSj/FCTkInKPqaCR0gD7K80q+mLBrN3PUkDrJQZpvRZIff3/
|
||||||
|
xmVU1WeruQLFJjnFb2dqu0s/FY/2kWiJtBCakXvXEOb7zfbINuayL+MSsCGSdVYs
|
||||||
|
SliS5qQpgyDap+8b5fpXZVJkq92hrcNtbkg7hCYUJczt8n9hcCTJCfUpApvaFQ18
|
||||||
|
pe+zpyl4+WzkP66I28hniMQyUlA1hBiskT7qiouq0m8IOodhv2fagSZKjOTTU2xk
|
||||||
|
SBc//fy3ZpsL7WqgsZS7Q+0VRK8gKfqkxg5OYQIDAQABAoIBAQDGGHzQxGKX+ANk
|
||||||
|
nQi53v/c6632dJKYXVJC+PDAz4+bzU800Y+n/bOYsWf/kCp94XcG4Lgsdd0Gx+Zq
|
||||||
|
HD9CI1IcqqBRR2AFscsmmX6YzPLTuEKBGMW8twaYy3utlFxElMwoUEsrSWRcCA1y
|
||||||
|
nHSDzTt871c7nxCXHxuZ6Nm/XCL7Bg8uidRTSC1sQrQyKgTPhtQdYrPQ4WZ1A4J9
|
||||||
|
IisyDYmZodSNZe5P+LTJ6M1SCgH8KH9ZGIxv3diMwzNNpk3kxJc9yCnja4mjiGE2
|
||||||
|
YCNusSycU5IhZwVeCTlhQGcNeV/skfg64xkiJE34c2y2ttFbdwBTPixStGaF09nU
|
||||||
|
Z422D40BAoGBAPvVyRRsC3BF+qZdaSMFwI1yiXY7vQw5+JZh01tD28NuYdRFzjcJ
|
||||||
|
vzT2n8LFpj5ZfZFvSMLMVEFVMgQvWnN0O6xdXvGov6qlRUSGaH9u+TCPNnIldjMP
|
||||||
|
B8+xTwFMqI7uQr54wBB+Poq7dVRP+0oHb0NYAwUBXoEuvYo3c/nDoRcZAoGBAOWl
|
||||||
|
aLHjMv4CJbArzT8sPfic/8waSiLV9Ixs3Re5YREUTtnLq7LoymqB57UXJB3BNz/2
|
||||||
|
eCueuW71avlWlRtE/wXASj5jx6y5mIrlV4nZbVuyYff0QlcG+fgb6pcJQuO9DxMI
|
||||||
|
aqFGrWP3zye+LK87a6iR76dS9vRU+bHZpSVvGMKJAoGAFGt3TIKeQtJJyqeUWNSk
|
||||||
|
klORNdcOMymYMIlqG+JatXQD1rR6ThgqOt8sgRyJqFCVT++YFMOAqXOBBLnaObZZ
|
||||||
|
CFbh1fJ66BlSjoXff0W+SuOx5HuJJAa5+WtFHrPajwxeuRcNa8jwxUsB7n41wADu
|
||||||
|
UqWWSRedVBg4Ijbw3nWwYDECgYB0pLew4z4bVuvdt+HgnJA9n0EuYowVdadpTEJg
|
||||||
|
soBjNHV4msLzdNqbjrAqgz6M/n8Ztg8D2PNHMNDNJPVHjJwcR7duSTA6w2p/4k28
|
||||||
|
bvvk/45Ta3XmzlxZcZSOct3O31Cw0i2XDVc018IY5be8qendDYM08icNo7vQYkRH
|
||||||
|
504kQQKBgQDjx60zpz8ozvm1XAj0wVhi7GwXe+5lTxiLi9Fxq721WDxPMiHDW2XL
|
||||||
|
YXfFVy/9/GIMvEiGYdmarK1NW+VhWl1DC5xhDg0kvMfxplt4tynoq1uTsQTY31Mx
|
||||||
|
BeF5CT/JuNYk3bEBF0H/Q3VGO1/ggVS+YezdFbLWIRoMnLj6XCFEGg==
|
||||||
|
-----END RSA PRIVATE KEY-----`
|
||||||
|
|
||||||
|
// Public key to go with the private key for testing
|
||||||
|
const publicKeyPem = `-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDIzCCAgugAwIBAgIJAMfISuBQ5m+5MA0GCSqGSIb3DQEBBQUAMBUxEzARBgNV
|
||||||
|
BAMTCnVuaXQtdGVzdHMwHhcNMTExMjA2MTYyNjAyWhcNMjExMjAzMTYyNjAyWjAV
|
||||||
|
MRMwEQYDVQQDEwp1bml0LXRlc3RzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||||
|
CgKCAQEA4ej0p7bQ7L/r4rVGUz9RN4VQWoej1Bg1mYWIDYslvKrk1gpj7wZgkdmM
|
||||||
|
7oVK2OfgrSj/FCTkInKPqaCR0gD7K80q+mLBrN3PUkDrJQZpvRZIff3/xmVU1Wer
|
||||||
|
uQLFJjnFb2dqu0s/FY/2kWiJtBCakXvXEOb7zfbINuayL+MSsCGSdVYsSliS5qQp
|
||||||
|
gyDap+8b5fpXZVJkq92hrcNtbkg7hCYUJczt8n9hcCTJCfUpApvaFQ18pe+zpyl4
|
||||||
|
+WzkP66I28hniMQyUlA1hBiskT7qiouq0m8IOodhv2fagSZKjOTTU2xkSBc//fy3
|
||||||
|
ZpsL7WqgsZS7Q+0VRK8gKfqkxg5OYQIDAQABo3YwdDAdBgNVHQ4EFgQU2RQ8yO+O
|
||||||
|
gN8oVW2SW7RLrfYd9jEwRQYDVR0jBD4wPIAU2RQ8yO+OgN8oVW2SW7RLrfYd9jGh
|
||||||
|
GaQXMBUxEzARBgNVBAMTCnVuaXQtdGVzdHOCCQDHyErgUOZvuTAMBgNVHRMEBTAD
|
||||||
|
AQH/MA0GCSqGSIb3DQEBBQUAA4IBAQBRv+M/6+FiVu7KXNjFI5pSN17OcW5QUtPr
|
||||||
|
odJMlWrJBtynn/TA1oJlYu3yV5clc/71Vr/AxuX5xGP+IXL32YDF9lTUJXG/uUGk
|
||||||
|
+JETpKmQviPbRsvzYhz4pf6ZIOZMc3/GIcNq92ECbseGO+yAgyWUVKMmZM0HqXC9
|
||||||
|
ovNslqe0M8C1sLm1zAR5z/h/litE7/8O2ietija3Q/qtl2TOXJdCA6sgjJX2WUql
|
||||||
|
ybrC55ct18NKf3qhpcEkGQvFU40rVYApJpi98DiZPYFdx1oBDp/f4uZ3ojpxRVFT
|
||||||
|
cDwcJLfNRCPUhormsY7fDS9xSyThiHsW9mjJYdcaKQkwYZ0F11yB
|
||||||
|
-----END CERTIFICATE-----`
|
||||||
|
|
||||||
|
var (
|
||||||
|
privateKeyPemBytes = []byte(privateKeyPem)
|
||||||
|
publicKeyPemBytes = []byte(publicKeyPem)
|
||||||
|
stdHeader = &Header{Algorithm: stdAlgorithm, Type: stdType}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Testing the urlEncode function.
|
||||||
|
func TestUrlEncode(t *testing.T) {
|
||||||
|
enc := base64Encode([]byte(stdHeaderStr))
|
||||||
|
b := []byte(enc)
|
||||||
|
if b[len(b)-1] == 61 {
|
||||||
|
t.Error("TestUrlEncode: last chat == \"=\"")
|
||||||
|
}
|
||||||
|
if enc != headerEnc {
|
||||||
|
t.Error("TestUrlEncode: enc != headerEnc")
|
||||||
|
t.Errorf(" enc = %s", enc)
|
||||||
|
t.Errorf(" headerEnc = %s", headerEnc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that the times are set properly.
|
||||||
|
func TestClaimSetSetTimes(t *testing.T) {
|
||||||
|
c := &ClaimSet{
|
||||||
|
Iss: iss,
|
||||||
|
Scope: scope,
|
||||||
|
}
|
||||||
|
iat := time.Unix(iat, 0)
|
||||||
|
c.setTimes(iat)
|
||||||
|
if c.exp.Unix() != exp {
|
||||||
|
t.Error("TestClaimSetSetTimes: c.exp != exp")
|
||||||
|
t.Errorf(" c.Exp = %d", c.exp.Unix())
|
||||||
|
t.Errorf(" exp = %d", exp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given a well formed ClaimSet, test for proper encoding.
|
||||||
|
func TestClaimSetEncode(t *testing.T) {
|
||||||
|
c := &ClaimSet{
|
||||||
|
Iss: iss,
|
||||||
|
Scope: scope,
|
||||||
|
exp: time.Unix(exp, 0),
|
||||||
|
iat: time.Unix(iat, 0),
|
||||||
|
}
|
||||||
|
enc := c.encode()
|
||||||
|
re, err := base64Decode(enc)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error decoding encoded claim set: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
wa, err := base64Decode(claimSetEnc)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error decoding encoded expected claim set: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if enc != claimSetEnc {
|
||||||
|
t.Error("TestClaimSetEncode: enc != claimSetEnc")
|
||||||
|
t.Errorf(" enc = %s", string(re))
|
||||||
|
t.Errorf(" claimSetEnc = %s", string(wa))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that claim sets with private claim names are encoded correctly.
|
||||||
|
func TestClaimSetWithPrivateNameEncode(t *testing.T) {
|
||||||
|
iatT := time.Unix(iat, 0)
|
||||||
|
expT := time.Unix(exp, 0)
|
||||||
|
|
||||||
|
i, err := json.Marshal(iatT.Unix())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error marshaling iatT value of %v: %v", iatT.Unix(), err)
|
||||||
|
}
|
||||||
|
iatStr := string(i)
|
||||||
|
e, err := json.Marshal(expT.Unix())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error marshaling expT value of %v: %v", expT.Unix(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expStr := string(e)
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
input map[string]interface{}
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
// Test a simple int field.
|
||||||
|
{
|
||||||
|
"single simple field",
|
||||||
|
map[string]interface{}{"amount": 22},
|
||||||
|
`{` +
|
||||||
|
`"iss":"` + iss + `",` +
|
||||||
|
`"scope":"` + scope + `",` +
|
||||||
|
`"aud":"` + stdAud + `",` +
|
||||||
|
`"exp":` + expStr + `,` +
|
||||||
|
`"iat":` + iatStr + `,` +
|
||||||
|
`"amount":22` +
|
||||||
|
`}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"multiple simple fields",
|
||||||
|
map[string]interface{}{"tracking_code": "axZf", "amount": 22},
|
||||||
|
`{` +
|
||||||
|
`"iss":"` + iss + `",` +
|
||||||
|
`"scope":"` + scope + `",` +
|
||||||
|
`"aud":"` + stdAud + `",` +
|
||||||
|
`"exp":` + expStr + `,` +
|
||||||
|
`"iat":` + iatStr + `,` +
|
||||||
|
`"amount":22,` +
|
||||||
|
`"tracking_code":"axZf"` +
|
||||||
|
`}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"nested struct fields",
|
||||||
|
map[string]interface{}{
|
||||||
|
"tracking_code": "axZf",
|
||||||
|
"purchase": struct {
|
||||||
|
Description string `json:"desc"`
|
||||||
|
Quantity int32 `json:"q"`
|
||||||
|
Time int64 `json:"t"`
|
||||||
|
}{
|
||||||
|
"toaster",
|
||||||
|
5,
|
||||||
|
iat,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
`{` +
|
||||||
|
`"iss":"` + iss + `",` +
|
||||||
|
`"scope":"` + scope + `",` +
|
||||||
|
`"aud":"` + stdAud + `",` +
|
||||||
|
`"exp":` + expStr + `,` +
|
||||||
|
`"iat":` + iatStr + `,` +
|
||||||
|
`"purchase":{"desc":"toaster","q":5,"t":` + iatStr + `},` +
|
||||||
|
`"tracking_code":"axZf"` +
|
||||||
|
`}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
c := &ClaimSet{
|
||||||
|
Iss: iss,
|
||||||
|
Scope: scope,
|
||||||
|
Aud: stdAud,
|
||||||
|
iat: iatT,
|
||||||
|
exp: expT,
|
||||||
|
PrivateClaims: testCase.input,
|
||||||
|
}
|
||||||
|
cJSON, err := base64Decode(c.encode())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error decoding claim set: %v", err)
|
||||||
|
}
|
||||||
|
if string(cJSON) != testCase.want {
|
||||||
|
t.Errorf("TestClaimSetWithPrivateNameEncode: enc != want in case %s", testCase.desc)
|
||||||
|
t.Errorf(" enc = %s", cJSON)
|
||||||
|
t.Errorf(" want = %s", testCase.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test the NewToken constructor.
|
||||||
|
func TestNewToken(t *testing.T) {
|
||||||
|
tok := NewToken(iss, scope, privateKeyPemBytes)
|
||||||
|
if tok.ClaimSet.Iss != iss {
|
||||||
|
t.Error("TestNewToken: tok.ClaimSet.Iss != iss")
|
||||||
|
t.Errorf(" tok.ClaimSet.Iss = %s", tok.ClaimSet.Iss)
|
||||||
|
t.Errorf(" iss = %s", iss)
|
||||||
|
}
|
||||||
|
if tok.ClaimSet.Scope != scope {
|
||||||
|
t.Error("TestNewToken: tok.ClaimSet.Scope != scope")
|
||||||
|
t.Errorf(" tok.ClaimSet.Scope = %s", tok.ClaimSet.Scope)
|
||||||
|
t.Errorf(" scope = %s", scope)
|
||||||
|
}
|
||||||
|
if tok.ClaimSet.Aud != stdAud {
|
||||||
|
t.Error("TestNewToken: tok.ClaimSet.Aud != stdAud")
|
||||||
|
t.Errorf(" tok.ClaimSet.Aud = %s", tok.ClaimSet.Aud)
|
||||||
|
t.Errorf(" stdAud = %s", stdAud)
|
||||||
|
}
|
||||||
|
if !bytes.Equal(tok.Key, privateKeyPemBytes) {
|
||||||
|
t.Error("TestNewToken: tok.Key != privateKeyPemBytes")
|
||||||
|
t.Errorf(" tok.Key = %s", tok.Key)
|
||||||
|
t.Errorf(" privateKeyPemBytes = %s", privateKeyPemBytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the private key parsing functions work.
|
||||||
|
func TestParsePrivateKey(t *testing.T) {
|
||||||
|
tok := &Token{
|
||||||
|
Key: privateKeyPemBytes,
|
||||||
|
}
|
||||||
|
err := tok.parsePrivateKey()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("TestParsePrivateKey:tok.parsePrivateKey: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that the token signature generated matches the golden standard.
|
||||||
|
func TestTokenSign(t *testing.T) {
|
||||||
|
tok := &Token{
|
||||||
|
Key: privateKeyPemBytes,
|
||||||
|
claim: claimSetEnc,
|
||||||
|
header: headerEnc,
|
||||||
|
}
|
||||||
|
err := tok.parsePrivateKey()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("TestTokenSign:tok.parsePrivateKey: %v", err)
|
||||||
|
}
|
||||||
|
err = tok.sign()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("TestTokenSign:tok.sign: %v", err)
|
||||||
|
}
|
||||||
|
if tok.sig != sigEnc {
|
||||||
|
t.Error("TestTokenSign: tok.sig != sigEnc")
|
||||||
|
t.Errorf(" tok.sig = %s", tok.sig)
|
||||||
|
t.Errorf(" sigEnc = %s", sigEnc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that the token expiration function is working.
|
||||||
|
func TestTokenExpired(t *testing.T) {
|
||||||
|
c := &ClaimSet{}
|
||||||
|
tok := &Token{
|
||||||
|
ClaimSet: c,
|
||||||
|
}
|
||||||
|
now := time.Now()
|
||||||
|
c.setTimes(now)
|
||||||
|
if tok.Expired() != false {
|
||||||
|
t.Error("TestTokenExpired: tok.Expired != false")
|
||||||
|
}
|
||||||
|
// Set the times as if they were set 2 hours ago.
|
||||||
|
c.setTimes(now.Add(-2 * time.Hour))
|
||||||
|
if tok.Expired() != true {
|
||||||
|
t.Error("TestTokenExpired: tok.Expired != true")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given a well formed Token, test for proper encoding.
|
||||||
|
func TestTokenEncode(t *testing.T) {
|
||||||
|
c := &ClaimSet{
|
||||||
|
Iss: iss,
|
||||||
|
Scope: scope,
|
||||||
|
exp: time.Unix(exp, 0),
|
||||||
|
iat: time.Unix(iat, 0),
|
||||||
|
}
|
||||||
|
tok := &Token{
|
||||||
|
ClaimSet: c,
|
||||||
|
Header: stdHeader,
|
||||||
|
Key: privateKeyPemBytes,
|
||||||
|
}
|
||||||
|
enc, err := tok.Encode()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("TestTokenEncode:tok.Assertion: %v", err)
|
||||||
|
}
|
||||||
|
if enc != tokEnc {
|
||||||
|
t.Error("TestTokenEncode: enc != tokEnc")
|
||||||
|
t.Errorf(" enc = %s", enc)
|
||||||
|
t.Errorf(" tokEnc = %s", tokEnc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given a well formed Token we should get back a well formed request.
|
||||||
|
func TestBuildRequest(t *testing.T) {
|
||||||
|
c := &ClaimSet{
|
||||||
|
Iss: iss,
|
||||||
|
Scope: scope,
|
||||||
|
exp: time.Unix(exp, 0),
|
||||||
|
iat: time.Unix(iat, 0),
|
||||||
|
}
|
||||||
|
tok := &Token{
|
||||||
|
ClaimSet: c,
|
||||||
|
Header: stdHeader,
|
||||||
|
Key: privateKeyPemBytes,
|
||||||
|
}
|
||||||
|
u, v, err := tok.buildRequest()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("TestBuildRequest:BuildRequest: %v", err)
|
||||||
|
}
|
||||||
|
if u != c.Aud {
|
||||||
|
t.Error("TestBuildRequest: u != c.Aud")
|
||||||
|
t.Errorf(" u = %s", u)
|
||||||
|
t.Errorf(" c.Aud = %s", c.Aud)
|
||||||
|
}
|
||||||
|
if v.Get("grant_type") != stdGrantType {
|
||||||
|
t.Error("TestBuildRequest: grant_type != stdGrantType")
|
||||||
|
t.Errorf(" grant_type = %s", v.Get("grant_type"))
|
||||||
|
t.Errorf(" stdGrantType = %s", stdGrantType)
|
||||||
|
}
|
||||||
|
if v.Get("assertion") != tokEnc {
|
||||||
|
t.Error("TestBuildRequest: assertion != tokEnc")
|
||||||
|
t.Errorf(" assertion = %s", v.Get("assertion"))
|
||||||
|
t.Errorf(" tokEnc = %s", tokEnc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given a well formed access request response we should get back a oauth.Token.
|
||||||
|
func TestHandleResponse(t *testing.T) {
|
||||||
|
rb := &respBody{
|
||||||
|
Access: "1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M",
|
||||||
|
Type: "Bearer",
|
||||||
|
ExpiresIn: 3600,
|
||||||
|
}
|
||||||
|
b, err := json.Marshal(rb)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("TestHandleResponse:json.Marshal: %v", err)
|
||||||
|
}
|
||||||
|
r := &http.Response{
|
||||||
|
Status: "200 OK",
|
||||||
|
StatusCode: 200,
|
||||||
|
Body: ioutil.NopCloser(bytes.NewReader(b)),
|
||||||
|
}
|
||||||
|
o, err := handleResponse(r)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("TestHandleResponse:handleResponse: %v", err)
|
||||||
|
}
|
||||||
|
if o.AccessToken != rb.Access {
|
||||||
|
t.Error("TestHandleResponse: o.AccessToken != rb.Access")
|
||||||
|
t.Errorf(" o.AccessToken = %s", o.AccessToken)
|
||||||
|
t.Errorf(" rb.Access = %s", rb.Access)
|
||||||
|
}
|
||||||
|
if o.Expired() {
|
||||||
|
t.Error("TestHandleResponse: o.Expired == true")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// passthrough signature for test
|
||||||
|
type FakeSigner struct{}
|
||||||
|
|
||||||
|
func (f FakeSigner) Sign(tok *Token) ([]byte, []byte, error) {
|
||||||
|
block, _ := pem.Decode(privateKeyPemBytes)
|
||||||
|
pKey, _ := x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||||
|
ss := headerEnc + "." + claimSetEnc
|
||||||
|
h := sha256.New()
|
||||||
|
h.Write([]byte(ss))
|
||||||
|
b, _ := rsa.SignPKCS1v15(rand.Reader, pKey, crypto.SHA256, h.Sum(nil))
|
||||||
|
return []byte(ss), b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given an external signer, get back a valid and signed JWT
|
||||||
|
func TestExternalSigner(t *testing.T) {
|
||||||
|
tok := NewSignerToken(iss, scope, FakeSigner{})
|
||||||
|
enc, _ := tok.Encode()
|
||||||
|
if enc != tokEnc {
|
||||||
|
t.Errorf("TestExternalSigner: enc != tokEnc")
|
||||||
|
t.Errorf(" enc = %s", enc)
|
||||||
|
t.Errorf(" tokEnc = %s", tokEnc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandleResponseWithNewExpiry(t *testing.T) {
|
||||||
|
rb := &respBody{
|
||||||
|
IdToken: tokEnc,
|
||||||
|
}
|
||||||
|
b, err := json.Marshal(rb)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("TestHandleResponse:json.Marshal: %v", err)
|
||||||
|
}
|
||||||
|
r := &http.Response{
|
||||||
|
Status: "200 OK",
|
||||||
|
StatusCode: 200,
|
||||||
|
Body: ioutil.NopCloser(bytes.NewReader(b)),
|
||||||
|
}
|
||||||
|
o, err := handleResponse(r)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("TestHandleResponse:handleResponse: %v", err)
|
||||||
|
}
|
||||||
|
if o.Expiry != time.Unix(exp, 0) {
|
||||||
|
t.Error("TestHandleResponse: o.Expiry != exp")
|
||||||
|
t.Errorf(" o.Expiry = %s", o.Expiry)
|
||||||
|
t.Errorf(" exp = %s", time.Unix(exp, 0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Placeholder for future Assert tests.
|
||||||
|
func TestAssert(t *testing.T) {
|
||||||
|
// Since this method makes a call to BuildRequest, an htttp.Client, and
|
||||||
|
// finally HandleResponse there is not much more to test. This is here
|
||||||
|
// as a placeholder if that changes.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Benchmark for the end-to-end encoding of a well formed token.
|
||||||
|
func BenchmarkTokenEncode(b *testing.B) {
|
||||||
|
b.StopTimer()
|
||||||
|
c := &ClaimSet{
|
||||||
|
Iss: iss,
|
||||||
|
Scope: scope,
|
||||||
|
exp: time.Unix(exp, 0),
|
||||||
|
iat: time.Unix(iat, 0),
|
||||||
|
}
|
||||||
|
tok := &Token{
|
||||||
|
ClaimSet: c,
|
||||||
|
Key: privateKeyPemBytes,
|
||||||
|
}
|
||||||
|
b.StartTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
tok.Encode()
|
||||||
|
}
|
||||||
|
}
|
||||||
378
Godeps/_workspace/src/code.google.com/p/goauth2/oauth/oauth.go
generated
vendored
Normal file
378
Godeps/_workspace/src/code.google.com/p/goauth2/oauth/oauth.go
generated
vendored
Normal file
@@ -0,0 +1,378 @@
|
|||||||
|
// Copyright 2011 The goauth2 Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// The oauth package provides support for making
|
||||||
|
// OAuth2-authenticated HTTP requests.
|
||||||
|
//
|
||||||
|
// Example usage:
|
||||||
|
//
|
||||||
|
// // Specify your configuration. (typically as a global variable)
|
||||||
|
// var config = &oauth.Config{
|
||||||
|
// ClientId: YOUR_CLIENT_ID,
|
||||||
|
// ClientSecret: YOUR_CLIENT_SECRET,
|
||||||
|
// Scope: "https://www.googleapis.com/auth/buzz",
|
||||||
|
// AuthURL: "https://accounts.google.com/o/oauth2/auth",
|
||||||
|
// TokenURL: "https://accounts.google.com/o/oauth2/token",
|
||||||
|
// RedirectURL: "http://you.example.org/handler",
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // A landing page redirects to the OAuth provider to get the auth code.
|
||||||
|
// func landing(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// http.Redirect(w, r, config.AuthCodeURL("foo"), http.StatusFound)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // The user will be redirected back to this handler, that takes the
|
||||||
|
// // "code" query parameter and Exchanges it for an access token.
|
||||||
|
// func handler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// t := &oauth.Transport{Config: config}
|
||||||
|
// t.Exchange(r.FormValue("code"))
|
||||||
|
// // The Transport now has a valid Token. Create an *http.Client
|
||||||
|
// // with which we can make authenticated API requests.
|
||||||
|
// c := t.Client()
|
||||||
|
// c.Post(...)
|
||||||
|
// // ...
|
||||||
|
// // btw, r.FormValue("state") == "foo"
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
package oauth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io/ioutil"
|
||||||
|
"mime"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OAuthError struct {
|
||||||
|
prefix string
|
||||||
|
msg string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (oe OAuthError) Error() string {
|
||||||
|
return "OAuthError: " + oe.prefix + ": " + oe.msg
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache specifies the methods that implement a Token cache.
|
||||||
|
type Cache interface {
|
||||||
|
Token() (*Token, error)
|
||||||
|
PutToken(*Token) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// CacheFile implements Cache. Its value is the name of the file in which
|
||||||
|
// the Token is stored in JSON format.
|
||||||
|
type CacheFile string
|
||||||
|
|
||||||
|
func (f CacheFile) Token() (*Token, error) {
|
||||||
|
file, err := os.Open(string(f))
|
||||||
|
if err != nil {
|
||||||
|
return nil, OAuthError{"CacheFile.Token", err.Error()}
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
tok := &Token{}
|
||||||
|
if err := json.NewDecoder(file).Decode(tok); err != nil {
|
||||||
|
return nil, OAuthError{"CacheFile.Token", err.Error()}
|
||||||
|
}
|
||||||
|
return tok, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f CacheFile) PutToken(tok *Token) error {
|
||||||
|
file, err := os.OpenFile(string(f), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
|
||||||
|
if err != nil {
|
||||||
|
return OAuthError{"CacheFile.PutToken", err.Error()}
|
||||||
|
}
|
||||||
|
if err := json.NewEncoder(file).Encode(tok); err != nil {
|
||||||
|
file.Close()
|
||||||
|
return OAuthError{"CacheFile.PutToken", err.Error()}
|
||||||
|
}
|
||||||
|
if err := file.Close(); err != nil {
|
||||||
|
return OAuthError{"CacheFile.PutToken", err.Error()}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Config is the configuration of an OAuth consumer.
|
||||||
|
type Config struct {
|
||||||
|
// ClientId is the OAuth client identifier used when communicating with
|
||||||
|
// the configured OAuth provider.
|
||||||
|
ClientId string
|
||||||
|
|
||||||
|
// ClientSecret is the OAuth client secret used when communicating with
|
||||||
|
// the configured OAuth provider.
|
||||||
|
ClientSecret string
|
||||||
|
|
||||||
|
// Scope identifies the level of access being requested. Multiple scope
|
||||||
|
// values should be provided as a space-delimited string.
|
||||||
|
Scope string
|
||||||
|
|
||||||
|
// AuthURL is the URL the user will be directed to in order to grant
|
||||||
|
// access.
|
||||||
|
AuthURL string
|
||||||
|
|
||||||
|
// TokenURL is the URL used to retrieve OAuth tokens.
|
||||||
|
TokenURL string
|
||||||
|
|
||||||
|
// RedirectURL is the URL to which the user will be returned after
|
||||||
|
// granting (or denying) access.
|
||||||
|
RedirectURL string
|
||||||
|
|
||||||
|
// TokenCache allows tokens to be cached for subsequent requests.
|
||||||
|
TokenCache Cache
|
||||||
|
|
||||||
|
AccessType string // Optional, "online" (default) or "offline", no refresh token if "online"
|
||||||
|
|
||||||
|
// ApprovalPrompt indicates whether the user should be
|
||||||
|
// re-prompted for consent. If set to "auto" (default) the
|
||||||
|
// user will be prompted only if they haven't previously
|
||||||
|
// granted consent and the code can only be exchanged for an
|
||||||
|
// access token.
|
||||||
|
// If set to "force" the user will always be prompted, and the
|
||||||
|
// code can be exchanged for a refresh token.
|
||||||
|
ApprovalPrompt string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Token contains an end-user's tokens.
|
||||||
|
// This is the data you must store to persist authentication.
|
||||||
|
type Token struct {
|
||||||
|
AccessToken string
|
||||||
|
RefreshToken string
|
||||||
|
Expiry time.Time // If zero the token has no (known) expiry time.
|
||||||
|
Extra map[string]string // May be nil.
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Token) Expired() bool {
|
||||||
|
if t.Expiry.IsZero() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return t.Expiry.Before(time.Now())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transport implements http.RoundTripper. When configured with a valid
|
||||||
|
// Config and Token it can be used to make authenticated HTTP requests.
|
||||||
|
//
|
||||||
|
// t := &oauth.Transport{config}
|
||||||
|
// t.Exchange(code)
|
||||||
|
// // t now contains a valid Token
|
||||||
|
// r, _, err := t.Client().Get("http://example.org/url/requiring/auth")
|
||||||
|
//
|
||||||
|
// It will automatically refresh the Token if it can,
|
||||||
|
// updating the supplied Token in place.
|
||||||
|
type Transport struct {
|
||||||
|
*Config
|
||||||
|
*Token
|
||||||
|
|
||||||
|
// Transport is the HTTP transport to use when making requests.
|
||||||
|
// It will default to http.DefaultTransport if nil.
|
||||||
|
// (It should never be an oauth.Transport.)
|
||||||
|
Transport http.RoundTripper
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client returns an *http.Client that makes OAuth-authenticated requests.
|
||||||
|
func (t *Transport) Client() *http.Client {
|
||||||
|
return &http.Client{Transport: t}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Transport) transport() http.RoundTripper {
|
||||||
|
if t.Transport != nil {
|
||||||
|
return t.Transport
|
||||||
|
}
|
||||||
|
return http.DefaultTransport
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthCodeURL returns a URL that the end-user should be redirected to,
|
||||||
|
// so that they may obtain an authorization code.
|
||||||
|
func (c *Config) AuthCodeURL(state string) string {
|
||||||
|
url_, err := url.Parse(c.AuthURL)
|
||||||
|
if err != nil {
|
||||||
|
panic("AuthURL malformed: " + err.Error())
|
||||||
|
}
|
||||||
|
q := url.Values{
|
||||||
|
"response_type": {"code"},
|
||||||
|
"client_id": {c.ClientId},
|
||||||
|
"redirect_uri": {c.RedirectURL},
|
||||||
|
"scope": {c.Scope},
|
||||||
|
"state": {state},
|
||||||
|
"access_type": {c.AccessType},
|
||||||
|
"approval_prompt": {c.ApprovalPrompt},
|
||||||
|
}.Encode()
|
||||||
|
if url_.RawQuery == "" {
|
||||||
|
url_.RawQuery = q
|
||||||
|
} else {
|
||||||
|
url_.RawQuery += "&" + q
|
||||||
|
}
|
||||||
|
return url_.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exchange takes a code and gets access Token from the remote server.
|
||||||
|
func (t *Transport) Exchange(code string) (*Token, error) {
|
||||||
|
if t.Config == nil {
|
||||||
|
return nil, OAuthError{"Exchange", "no Config supplied"}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the transport or the cache already has a token, it is
|
||||||
|
// passed to `updateToken` to preserve existing refresh token.
|
||||||
|
tok := t.Token
|
||||||
|
if tok == nil && t.TokenCache != nil {
|
||||||
|
tok, _ = t.TokenCache.Token()
|
||||||
|
}
|
||||||
|
if tok == nil {
|
||||||
|
tok = new(Token)
|
||||||
|
}
|
||||||
|
err := t.updateToken(tok, url.Values{
|
||||||
|
"grant_type": {"authorization_code"},
|
||||||
|
"redirect_uri": {t.RedirectURL},
|
||||||
|
"scope": {t.Scope},
|
||||||
|
"code": {code},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
t.Token = tok
|
||||||
|
if t.TokenCache != nil {
|
||||||
|
return tok, t.TokenCache.PutToken(tok)
|
||||||
|
}
|
||||||
|
return tok, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RoundTrip executes a single HTTP transaction using the Transport's
|
||||||
|
// Token as authorization headers.
|
||||||
|
//
|
||||||
|
// This method will attempt to renew the Token if it has expired and may return
|
||||||
|
// an error related to that Token renewal before attempting the client request.
|
||||||
|
// If the Token cannot be renewed a non-nil os.Error value will be returned.
|
||||||
|
// If the Token is invalid callers should expect HTTP-level errors,
|
||||||
|
// as indicated by the Response's StatusCode.
|
||||||
|
func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
|
if t.Token == nil {
|
||||||
|
if t.Config == nil {
|
||||||
|
return nil, OAuthError{"RoundTrip", "no Config supplied"}
|
||||||
|
}
|
||||||
|
if t.TokenCache == nil {
|
||||||
|
return nil, OAuthError{"RoundTrip", "no Token supplied"}
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
t.Token, err = t.TokenCache.Token()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh the Token if it has expired.
|
||||||
|
if t.Expired() {
|
||||||
|
if err := t.Refresh(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// To set the Authorization header, we must make a copy of the Request
|
||||||
|
// so that we don't modify the Request we were given.
|
||||||
|
// This is required by the specification of http.RoundTripper.
|
||||||
|
req = cloneRequest(req)
|
||||||
|
req.Header.Set("Authorization", "Bearer "+t.AccessToken)
|
||||||
|
|
||||||
|
// Make the HTTP request.
|
||||||
|
return t.transport().RoundTrip(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// cloneRequest returns a clone of the provided *http.Request.
|
||||||
|
// The clone is a shallow copy of the struct and its Header map.
|
||||||
|
func cloneRequest(r *http.Request) *http.Request {
|
||||||
|
// shallow copy of the struct
|
||||||
|
r2 := new(http.Request)
|
||||||
|
*r2 = *r
|
||||||
|
// deep copy of the Header
|
||||||
|
r2.Header = make(http.Header)
|
||||||
|
for k, s := range r.Header {
|
||||||
|
r2.Header[k] = s
|
||||||
|
}
|
||||||
|
return r2
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh renews the Transport's AccessToken using its RefreshToken.
|
||||||
|
func (t *Transport) Refresh() error {
|
||||||
|
if t.Token == nil {
|
||||||
|
return OAuthError{"Refresh", "no existing Token"}
|
||||||
|
}
|
||||||
|
if t.RefreshToken == "" {
|
||||||
|
return OAuthError{"Refresh", "Token expired; no Refresh Token"}
|
||||||
|
}
|
||||||
|
if t.Config == nil {
|
||||||
|
return OAuthError{"Refresh", "no Config supplied"}
|
||||||
|
}
|
||||||
|
|
||||||
|
err := t.updateToken(t.Token, url.Values{
|
||||||
|
"grant_type": {"refresh_token"},
|
||||||
|
"refresh_token": {t.RefreshToken},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if t.TokenCache != nil {
|
||||||
|
return t.TokenCache.PutToken(t.Token)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Transport) updateToken(tok *Token, v url.Values) error {
|
||||||
|
v.Set("client_id", t.ClientId)
|
||||||
|
v.Set("client_secret", t.ClientSecret)
|
||||||
|
r, err := (&http.Client{Transport: t.transport()}).PostForm(t.TokenURL, v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer r.Body.Close()
|
||||||
|
if r.StatusCode != 200 {
|
||||||
|
return OAuthError{"updateToken", r.Status}
|
||||||
|
}
|
||||||
|
var b struct {
|
||||||
|
Access string `json:"access_token"`
|
||||||
|
Refresh string `json:"refresh_token"`
|
||||||
|
ExpiresIn time.Duration `json:"expires_in"`
|
||||||
|
Id string `json:"id_token"`
|
||||||
|
}
|
||||||
|
|
||||||
|
content, _, _ := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||||
|
switch content {
|
||||||
|
case "application/x-www-form-urlencoded", "text/plain":
|
||||||
|
body, err := ioutil.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
vals, err := url.ParseQuery(string(body))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
b.Access = vals.Get("access_token")
|
||||||
|
b.Refresh = vals.Get("refresh_token")
|
||||||
|
b.ExpiresIn, _ = time.ParseDuration(vals.Get("expires_in") + "s")
|
||||||
|
b.Id = vals.Get("id_token")
|
||||||
|
default:
|
||||||
|
if err = json.NewDecoder(r.Body).Decode(&b); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// The JSON parser treats the unitless ExpiresIn like 'ns' instead of 's' as above,
|
||||||
|
// so compensate here.
|
||||||
|
b.ExpiresIn *= time.Second
|
||||||
|
}
|
||||||
|
tok.AccessToken = b.Access
|
||||||
|
// Don't overwrite `RefreshToken` with an empty value
|
||||||
|
if len(b.Refresh) > 0 {
|
||||||
|
tok.RefreshToken = b.Refresh
|
||||||
|
}
|
||||||
|
if b.ExpiresIn == 0 {
|
||||||
|
tok.Expiry = time.Time{}
|
||||||
|
} else {
|
||||||
|
tok.Expiry = time.Now().Add(b.ExpiresIn)
|
||||||
|
}
|
||||||
|
if b.Id != "" {
|
||||||
|
if tok.Extra == nil {
|
||||||
|
tok.Extra = make(map[string]string)
|
||||||
|
}
|
||||||
|
tok.Extra["id_token"] = b.Id
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
186
Godeps/_workspace/src/code.google.com/p/goauth2/oauth/oauth_test.go
generated
vendored
Normal file
186
Godeps/_workspace/src/code.google.com/p/goauth2/oauth/oauth_test.go
generated
vendored
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
// Copyright 2011 The goauth2 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 oauth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var requests = []struct {
|
||||||
|
path, query, auth string // request
|
||||||
|
contenttype, body string // response
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
path: "/token",
|
||||||
|
query: "grant_type=authorization_code&code=c0d3&client_id=cl13nt1d",
|
||||||
|
contenttype: "application/json",
|
||||||
|
body: `
|
||||||
|
{
|
||||||
|
"access_token":"token1",
|
||||||
|
"refresh_token":"refreshtoken1",
|
||||||
|
"id_token":"idtoken1",
|
||||||
|
"expires_in":3600
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{path: "/secure", auth: "Bearer token1", body: "first payload"},
|
||||||
|
{
|
||||||
|
path: "/token",
|
||||||
|
query: "grant_type=refresh_token&refresh_token=refreshtoken1&client_id=cl13nt1d",
|
||||||
|
contenttype: "application/json",
|
||||||
|
body: `
|
||||||
|
{
|
||||||
|
"access_token":"token2",
|
||||||
|
"refresh_token":"refreshtoken2",
|
||||||
|
"id_token":"idtoken2",
|
||||||
|
"expires_in":3600
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{path: "/secure", auth: "Bearer token2", body: "second payload"},
|
||||||
|
{
|
||||||
|
path: "/token",
|
||||||
|
query: "grant_type=refresh_token&refresh_token=refreshtoken2&client_id=cl13nt1d",
|
||||||
|
contenttype: "application/x-www-form-urlencoded",
|
||||||
|
body: "access_token=token3&refresh_token=refreshtoken3&id_token=idtoken3&expires_in=3600",
|
||||||
|
},
|
||||||
|
{path: "/secure", auth: "Bearer token3", body: "third payload"},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOAuth(t *testing.T) {
|
||||||
|
// Set up test server.
|
||||||
|
n := 0
|
||||||
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if n >= len(requests) {
|
||||||
|
t.Errorf("too many requests: %d", n)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req := requests[n]
|
||||||
|
n++
|
||||||
|
|
||||||
|
// Check request.
|
||||||
|
if g, w := r.URL.Path, req.path; g != w {
|
||||||
|
t.Errorf("request[%d] got path %s, want %s", n, g, w)
|
||||||
|
}
|
||||||
|
want, _ := url.ParseQuery(req.query)
|
||||||
|
for k := range want {
|
||||||
|
if g, w := r.FormValue(k), want.Get(k); g != w {
|
||||||
|
t.Errorf("query[%s] = %s, want %s", k, g, w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if g, w := r.Header.Get("Authorization"), req.auth; w != "" && g != w {
|
||||||
|
t.Errorf("Authorization: %v, want %v", g, w)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send response.
|
||||||
|
w.Header().Set("Content-Type", req.contenttype)
|
||||||
|
io.WriteString(w, req.body)
|
||||||
|
}
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(handler))
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
config := &Config{
|
||||||
|
ClientId: "cl13nt1d",
|
||||||
|
ClientSecret: "s3cr3t",
|
||||||
|
Scope: "https://example.net/scope",
|
||||||
|
AuthURL: server.URL + "/auth",
|
||||||
|
TokenURL: server.URL + "/token",
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(adg): test AuthCodeURL
|
||||||
|
|
||||||
|
transport := &Transport{Config: config}
|
||||||
|
_, err := transport.Exchange("c0d3")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Exchange: %v", err)
|
||||||
|
}
|
||||||
|
checkToken(t, transport.Token, "token1", "refreshtoken1", "idtoken1")
|
||||||
|
|
||||||
|
c := transport.Client()
|
||||||
|
resp, err := c.Get(server.URL + "/secure")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Get: %v", err)
|
||||||
|
}
|
||||||
|
checkBody(t, resp, "first payload")
|
||||||
|
|
||||||
|
// test automatic refresh
|
||||||
|
transport.Expiry = time.Now().Add(-time.Hour)
|
||||||
|
resp, err = c.Get(server.URL + "/secure")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Get: %v", err)
|
||||||
|
}
|
||||||
|
checkBody(t, resp, "second payload")
|
||||||
|
checkToken(t, transport.Token, "token2", "refreshtoken2", "idtoken2")
|
||||||
|
|
||||||
|
// refresh one more time, but get URL-encoded token instead of JSON
|
||||||
|
transport.Expiry = time.Now().Add(-time.Hour)
|
||||||
|
resp, err = c.Get(server.URL + "/secure")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Get: %v", err)
|
||||||
|
}
|
||||||
|
checkBody(t, resp, "third payload")
|
||||||
|
checkToken(t, transport.Token, "token3", "refreshtoken3", "idtoken3")
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkToken(t *testing.T, tok *Token, access, refresh, id string) {
|
||||||
|
if g, w := tok.AccessToken, access; g != w {
|
||||||
|
t.Errorf("AccessToken = %q, want %q", g, w)
|
||||||
|
}
|
||||||
|
if g, w := tok.RefreshToken, refresh; g != w {
|
||||||
|
t.Errorf("RefreshToken = %q, want %q", g, w)
|
||||||
|
}
|
||||||
|
if g, w := tok.Extra["id_token"], id; g != w {
|
||||||
|
t.Errorf("Extra['id_token'] = %q, want %q", g, w)
|
||||||
|
}
|
||||||
|
exp := tok.Expiry.Sub(time.Now())
|
||||||
|
if (time.Hour-time.Second) > exp || exp > time.Hour {
|
||||||
|
t.Errorf("Expiry = %v, want ~1 hour", exp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkBody(t *testing.T, r *http.Response, body string) {
|
||||||
|
b, err := ioutil.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("reading reponse body: %v, want %q", err, body)
|
||||||
|
}
|
||||||
|
if g, w := string(b), body; g != w {
|
||||||
|
t.Errorf("request body mismatch: got %q, want %q", g, w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCachePermissions(t *testing.T) {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
// Windows doesn't support file mode bits.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
td, err := ioutil.TempDir("", "oauth-test")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ioutil.TempDir: %v", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(td)
|
||||||
|
tempFile := filepath.Join(td, "cache-file")
|
||||||
|
|
||||||
|
cf := CacheFile(tempFile)
|
||||||
|
if err := cf.PutToken(new(Token)); err != nil {
|
||||||
|
t.Fatalf("PutToken: %v", err)
|
||||||
|
}
|
||||||
|
fi, err := os.Stat(tempFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("os.Stat: %v", err)
|
||||||
|
}
|
||||||
|
if fi.Mode()&0077 != 0 {
|
||||||
|
t.Errorf("Created cache file has mode %#o, want non-accessible to group+other", fi.Mode())
|
||||||
|
}
|
||||||
|
}
|
||||||
14
Godeps/_workspace/src/github.com/google/go-github/github/activity.go
generated
vendored
Normal file
14
Godeps/_workspace/src/github.com/google/go-github/github/activity.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// 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
|
||||||
|
|
||||||
|
// ActivityService handles communication with the activity related
|
||||||
|
// methods of the GitHub API.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/activity/
|
||||||
|
type ActivityService struct {
|
||||||
|
client *Client
|
||||||
|
}
|
||||||
273
Godeps/_workspace/src/github.com/google/go-github/github/activity_events.go
generated
vendored
Normal file
273
Godeps/_workspace/src/github.com/google/go-github/github/activity_events.go
generated
vendored
Normal file
@@ -0,0 +1,273 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Event represents a GitHub event.
|
||||||
|
type Event struct {
|
||||||
|
Type *string `json:"type,omitempty"`
|
||||||
|
Public *bool `json:"public"`
|
||||||
|
RawPayload *json.RawMessage `json:"payload,omitempty"`
|
||||||
|
Repo *Repository `json:"repo,omitempty"`
|
||||||
|
Actor *User `json:"actor,omitempty"`
|
||||||
|
Org *Organization `json:"org,omitempty"`
|
||||||
|
CreatedAt *time.Time `json:"created_at,omitempty"`
|
||||||
|
ID *string `json:"id,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Event) String() string {
|
||||||
|
return Stringify(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Payload returns the parsed event payload. For recognized event types
|
||||||
|
// (PushEvent), a value of the corresponding struct type will be returned.
|
||||||
|
func (e *Event) Payload() (payload interface{}) {
|
||||||
|
switch *e.Type {
|
||||||
|
case "PushEvent":
|
||||||
|
payload = &PushEvent{}
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(*e.RawPayload, &payload); err != nil {
|
||||||
|
panic(err.Error())
|
||||||
|
}
|
||||||
|
return payload
|
||||||
|
}
|
||||||
|
|
||||||
|
// PushEvent represents a git push to a GitHub repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/activity/events/types/#pushevent
|
||||||
|
type PushEvent struct {
|
||||||
|
PushID *int `json:"push_id,omitempty"`
|
||||||
|
Head *string `json:"head,omitempty"`
|
||||||
|
Ref *string `json:"ref,omitempty"`
|
||||||
|
Size *int `json:"ref,omitempty"`
|
||||||
|
Commits []PushEventCommit `json:"commits,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p PushEvent) String() string {
|
||||||
|
return Stringify(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PushEventCommit represents a git commit in a GitHub PushEvent.
|
||||||
|
type PushEventCommit struct {
|
||||||
|
SHA *string `json:"sha,omitempty"`
|
||||||
|
Message *string `json:"message,omitempty"`
|
||||||
|
Author *CommitAuthor `json:"author,omitempty"`
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
Distinct *bool `json:"distinct"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p PushEventCommit) String() string {
|
||||||
|
return Stringify(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListEvents drinks from the firehose of all public events across GitHub.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/activity/events/#list-public-events
|
||||||
|
func (s *ActivityService) ListEvents(opt *ListOptions) ([]Event, *Response, error) {
|
||||||
|
u, err := addOptions("events", opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
events := new([]Event)
|
||||||
|
resp, err := s.client.Do(req, events)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *events, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRepositoryEvents lists events for a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/activity/events/#list-repository-events
|
||||||
|
func (s *ActivityService) ListRepositoryEvents(owner, repo string, opt *ListOptions) ([]Event, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/events", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
events := new([]Event)
|
||||||
|
resp, err := s.client.Do(req, events)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *events, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListIssueEventsForRepository lists issue events for a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/activity/events/#list-issue-events-for-a-repository
|
||||||
|
func (s *ActivityService) ListIssueEventsForRepository(owner, repo string, opt *ListOptions) ([]Event, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/issues/events", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
events := new([]Event)
|
||||||
|
resp, err := s.client.Do(req, events)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *events, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListEventsForRepoNetwork lists public events for a network of repositories.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/activity/events/#list-public-events-for-a-network-of-repositories
|
||||||
|
func (s *ActivityService) ListEventsForRepoNetwork(owner, repo string, opt *ListOptions) ([]Event, *Response, error) {
|
||||||
|
u := fmt.Sprintf("networks/%v/%v/events", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
events := new([]Event)
|
||||||
|
resp, err := s.client.Do(req, events)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *events, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListEventsForOrganization lists public events for an organization.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/activity/events/#list-public-events-for-an-organization
|
||||||
|
func (s *ActivityService) ListEventsForOrganization(org string, opt *ListOptions) ([]Event, *Response, error) {
|
||||||
|
u := fmt.Sprintf("orgs/%v/events", 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
|
||||||
|
}
|
||||||
|
|
||||||
|
events := new([]Event)
|
||||||
|
resp, err := s.client.Do(req, events)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *events, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListEventsPerformedByUser lists the events performed by a user. If publicOnly is
|
||||||
|
// true, only public events will be returned.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/activity/events/#list-events-performed-by-a-user
|
||||||
|
func (s *ActivityService) ListEventsPerformedByUser(user string, publicOnly bool, opt *ListOptions) ([]Event, *Response, error) {
|
||||||
|
var u string
|
||||||
|
if publicOnly {
|
||||||
|
u = fmt.Sprintf("users/%v/events/public", user)
|
||||||
|
} else {
|
||||||
|
u = fmt.Sprintf("users/%v/events", user)
|
||||||
|
}
|
||||||
|
u, err := addOptions(u, opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
events := new([]Event)
|
||||||
|
resp, err := s.client.Do(req, events)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *events, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListEventsRecievedByUser lists the events recieved by a user. If publicOnly is
|
||||||
|
// true, only public events will be returned.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/activity/events/#list-events-that-a-user-has-received
|
||||||
|
func (s *ActivityService) ListEventsRecievedByUser(user string, publicOnly bool, opt *ListOptions) ([]Event, *Response, error) {
|
||||||
|
var u string
|
||||||
|
if publicOnly {
|
||||||
|
u = fmt.Sprintf("users/%v/received_events/public", user)
|
||||||
|
} else {
|
||||||
|
u = fmt.Sprintf("users/%v/received_events", user)
|
||||||
|
}
|
||||||
|
u, err := addOptions(u, opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
events := new([]Event)
|
||||||
|
resp, err := s.client.Do(req, events)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *events, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListUserEventsForOrganization provides the user’s organization dashboard. You
|
||||||
|
// must be authenticated as the user to view this.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/activity/events/#list-events-for-an-organization
|
||||||
|
func (s *ActivityService) ListUserEventsForOrganization(org, user string, opt *ListOptions) ([]Event, *Response, error) {
|
||||||
|
u := fmt.Sprintf("users/%v/events/orgs/%v", user, 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
|
||||||
|
}
|
||||||
|
|
||||||
|
events := new([]Event)
|
||||||
|
resp, err := s.client.Do(req, events)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *events, resp, err
|
||||||
|
}
|
||||||
305
Godeps/_workspace/src/github.com/google/go-github/github/activity_events_test.go
generated
vendored
Normal file
305
Godeps/_workspace/src/github.com/google/go-github/github/activity_events_test.go
generated
vendored
Normal file
@@ -0,0 +1,305 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestActivityService_ListEvents(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/events", 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}
|
||||||
|
events, _, err := client.Activity.ListEvents(opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activities.ListEvents returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Event{{ID: String("1")}, {ID: String("2")}}
|
||||||
|
if !reflect.DeepEqual(events, want) {
|
||||||
|
t.Errorf("Activities.ListEvents returned %+v, want %+v", events, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_ListRepositoryEvents(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/events", 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}
|
||||||
|
events, _, err := client.Activity.ListRepositoryEvents("o", "r", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activities.ListRepositoryEvents returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Event{{ID: String("1")}, {ID: String("2")}}
|
||||||
|
if !reflect.DeepEqual(events, want) {
|
||||||
|
t.Errorf("Activities.ListRepositoryEvents returned %+v, want %+v", events, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_ListRepositoryEvents_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Activity.ListRepositoryEvents("%", "%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_ListIssueEventsForRepository(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/issues/events", 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}
|
||||||
|
events, _, err := client.Activity.ListIssueEventsForRepository("o", "r", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activities.ListIssueEventsForRepository returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Event{{ID: String("1")}, {ID: String("2")}}
|
||||||
|
if !reflect.DeepEqual(events, want) {
|
||||||
|
t.Errorf("Activities.ListIssueEventsForRepository returned %+v, want %+v", events, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_ListIssueEventsForRepository_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Activity.ListIssueEventsForRepository("%", "%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_ListEventsForRepoNetwork(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/networks/o/r/events", 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}
|
||||||
|
events, _, err := client.Activity.ListEventsForRepoNetwork("o", "r", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activities.ListEventsForRepoNetwork returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Event{{ID: String("1")}, {ID: String("2")}}
|
||||||
|
if !reflect.DeepEqual(events, want) {
|
||||||
|
t.Errorf("Activities.ListEventsForRepoNetwork returned %+v, want %+v", events, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_ListEventsForRepoNetwork_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Activity.ListEventsForRepoNetwork("%", "%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_ListEventsForOrganization(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/events", 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}
|
||||||
|
events, _, err := client.Activity.ListEventsForOrganization("o", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activities.ListEventsForOrganization returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Event{{ID: String("1")}, {ID: String("2")}}
|
||||||
|
if !reflect.DeepEqual(events, want) {
|
||||||
|
t.Errorf("Activities.ListEventsForOrganization returned %+v, want %+v", events, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_ListEventsForOrganization_invalidOrg(t *testing.T) {
|
||||||
|
_, _, err := client.Activity.ListEventsForOrganization("%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_ListEventsPerformedByUser_all(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/users/u/events", 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}
|
||||||
|
events, _, err := client.Activity.ListEventsPerformedByUser("u", false, opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Events.ListPerformedByUser returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Event{{ID: String("1")}, {ID: String("2")}}
|
||||||
|
if !reflect.DeepEqual(events, want) {
|
||||||
|
t.Errorf("Events.ListPerformedByUser returned %+v, want %+v", events, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_ListEventsPerformedByUser_publicOnly(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/users/u/events/public", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `[{"id":"1"},{"id":"2"}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
events, _, err := client.Activity.ListEventsPerformedByUser("u", true, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Events.ListPerformedByUser returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Event{{ID: String("1")}, {ID: String("2")}}
|
||||||
|
if !reflect.DeepEqual(events, want) {
|
||||||
|
t.Errorf("Events.ListPerformedByUser returned %+v, want %+v", events, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_ListEventsPerformedByUser_invalidUser(t *testing.T) {
|
||||||
|
_, _, err := client.Activity.ListEventsPerformedByUser("%", false, nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_ListEventsRecievedByUser_all(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/users/u/received_events", 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}
|
||||||
|
events, _, err := client.Activity.ListEventsRecievedByUser("u", false, opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Events.ListRecievedByUser returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Event{{ID: String("1")}, {ID: String("2")}}
|
||||||
|
if !reflect.DeepEqual(events, want) {
|
||||||
|
t.Errorf("Events.ListRecievedUser returned %+v, want %+v", events, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_ListEventsRecievedByUser_publicOnly(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/users/u/received_events/public", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `[{"id":"1"},{"id":"2"}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
events, _, err := client.Activity.ListEventsRecievedByUser("u", true, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Events.ListRecievedByUser returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Event{{ID: String("1")}, {ID: String("2")}}
|
||||||
|
if !reflect.DeepEqual(events, want) {
|
||||||
|
t.Errorf("Events.ListRecievedByUser returned %+v, want %+v", events, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_ListEventsRecievedByUser_invalidUser(t *testing.T) {
|
||||||
|
_, _, err := client.Activity.ListEventsRecievedByUser("%", false, nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_ListUserEventsForOrganization(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/users/u/events/orgs/o", 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}
|
||||||
|
events, _, err := client.Activity.ListUserEventsForOrganization("o", "u", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activities.ListUserEventsForOrganization returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Event{{ID: String("1")}, {ID: String("2")}}
|
||||||
|
if !reflect.DeepEqual(events, want) {
|
||||||
|
t.Errorf("Activities.ListUserEventsForOrganization returned %+v, want %+v", events, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivity_EventPayload_typed(t *testing.T) {
|
||||||
|
raw := []byte(`{"type": "PushEvent","payload":{"push_id": 1}}`)
|
||||||
|
var event *Event
|
||||||
|
if err := json.Unmarshal(raw, &event); err != nil {
|
||||||
|
t.Fatalf("Unmarshal Event returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &PushEvent{PushID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(event.Payload(), want) {
|
||||||
|
t.Errorf("Event Payload returned %+v, want %+v", event.Payload(), want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestEvent_Payload_untyped checks that unrecognized events are parsed to an
|
||||||
|
// interface{} value (instead of being discarded or throwing an error), for
|
||||||
|
// forward compatibility with new event types.
|
||||||
|
func TestActivity_EventPayload_untyped(t *testing.T) {
|
||||||
|
raw := []byte(`{"type": "UnrecognizedEvent","payload":{"field": "val"}}`)
|
||||||
|
var event *Event
|
||||||
|
if err := json.Unmarshal(raw, &event); err != nil {
|
||||||
|
t.Fatalf("Unmarshal Event returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := map[string]interface{}{"field": "val"}
|
||||||
|
if !reflect.DeepEqual(event.Payload(), want) {
|
||||||
|
t.Errorf("Event Payload returned %+v, want %+v", event.Payload(), want)
|
||||||
|
}
|
||||||
|
}
|
||||||
224
Godeps/_workspace/src/github.com/google/go-github/github/activity_notifications.go
generated
vendored
Normal file
224
Godeps/_workspace/src/github.com/google/go-github/github/activity_notifications.go
generated
vendored
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
// Copyright 2014 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"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Notification identifies a GitHub notification for a user.
|
||||||
|
type Notification struct {
|
||||||
|
ID *string `json:"id,omitempty"`
|
||||||
|
Repository *Repository `json:"repository,omitempty"`
|
||||||
|
Subject *NotificationSubject `json:"subject,omitempty"`
|
||||||
|
|
||||||
|
// Reason identifies the event that triggered the notification.
|
||||||
|
//
|
||||||
|
// GitHub API Docs: https://developer.github.com/v3/activity/notifications/#notification-reasons
|
||||||
|
Reason *string `json:"reason,omitempty"`
|
||||||
|
|
||||||
|
Unread *bool `json:"unread,omitempty"`
|
||||||
|
UpdatedAt *time.Time `json:"updated_at,omitempty"`
|
||||||
|
LastReadAt *time.Time `json:"last_read_at,omitempty"`
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotificationSubject identifies the subject of a notification.
|
||||||
|
type NotificationSubject struct {
|
||||||
|
Title *string `json:"title,omitempty"`
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
LatestCommentURL *string `json:"latest_comment_url,omitempty"`
|
||||||
|
Type *string `json:"type,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotificationListOptions specifies the optional parameters to the
|
||||||
|
// ActivityService.ListNotifications method.
|
||||||
|
type NotificationListOptions struct {
|
||||||
|
All bool `url:"all,omitempty"`
|
||||||
|
Participating bool `url:"participating,omitempty"`
|
||||||
|
Since time.Time `url:"since,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListNotifications lists all notifications for the authenticated user.
|
||||||
|
//
|
||||||
|
// GitHub API Docs: https://developer.github.com/v3/activity/notifications/#list-your-notifications
|
||||||
|
func (s *ActivityService) ListNotifications(opt *NotificationListOptions) ([]Notification, *Response, error) {
|
||||||
|
u := fmt.Sprintf("notifications")
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
var notifications []Notification
|
||||||
|
resp, err := s.client.Do(req, ¬ifications)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return notifications, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRepositoryNotifications lists all notifications in a given repository
|
||||||
|
// for the authenticated user.
|
||||||
|
//
|
||||||
|
// GitHub API Docs: https://developer.github.com/v3/activity/notifications/#list-your-notifications-in-a-repository
|
||||||
|
func (s *ActivityService) ListRepositoryNotifications(owner, repo string, opt *NotificationListOptions) ([]Notification, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/notifications", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
var notifications []Notification
|
||||||
|
resp, err := s.client.Do(req, ¬ifications)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return notifications, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type markReadOptions struct {
|
||||||
|
LastReadAt time.Time `url:"last_read_at,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkNotificationsRead marks all notifications up to lastRead as read.
|
||||||
|
//
|
||||||
|
// GitHub API Docs: https://developer.github.com/v3/activity/notifications/#mark-as-read
|
||||||
|
func (s *ActivityService) MarkNotificationsRead(lastRead time.Time) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("notifications")
|
||||||
|
u, err := addOptions(u, markReadOptions{lastRead})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("PUT", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkRepositoryNotificationsRead marks all notifications up to lastRead in
|
||||||
|
// the specified repository as read.
|
||||||
|
//
|
||||||
|
// GitHub API Docs: https://developer.github.com/v3/activity/notifications/#mark-notifications-as-read-in-a-repository
|
||||||
|
func (s *ActivityService) MarkRepositoryNotificationsRead(owner, repo string, lastRead time.Time) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/notifications", owner, repo)
|
||||||
|
u, err := addOptions(u, markReadOptions{lastRead})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("PUT", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetThread gets the specified notification thread.
|
||||||
|
//
|
||||||
|
// GitHub API Docs: https://developer.github.com/v3/activity/notifications/#view-a-single-thread
|
||||||
|
func (s *ActivityService) GetThread(id string) (*Notification, *Response, error) {
|
||||||
|
u := fmt.Sprintf("notifications/threads/%v", id)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
notification := new(Notification)
|
||||||
|
resp, err := s.client.Do(req, notification)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return notification, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkThreadRead marks the specified thread as read.
|
||||||
|
//
|
||||||
|
// GitHub API Docs: https://developer.github.com/v3/activity/notifications/#mark-a-thread-as-read
|
||||||
|
func (s *ActivityService) MarkThreadRead(id string) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("notifications/threads/%v", id)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("PATCH", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetThreadSubscription checks to see if the authenticated user is subscribed
|
||||||
|
// to a thread.
|
||||||
|
//
|
||||||
|
// GitHub API Docs: https://developer.github.com/v3/activity/notifications/#get-a-thread-subscription
|
||||||
|
func (s *ActivityService) GetThreadSubscription(id string) (*Subscription, *Response, error) {
|
||||||
|
u := fmt.Sprintf("notifications/threads/%v/subscription", id)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sub := new(Subscription)
|
||||||
|
resp, err := s.client.Do(req, sub)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return sub, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetThreadSubscription sets the subscription for the specified thread for the
|
||||||
|
// authenticated user.
|
||||||
|
//
|
||||||
|
// GitHub API Docs: https://developer.github.com/v3/activity/notifications/#set-a-thread-subscription
|
||||||
|
func (s *ActivityService) SetThreadSubscription(id string, subscription *Subscription) (*Subscription, *Response, error) {
|
||||||
|
u := fmt.Sprintf("notifications/threads/%v/subscription", id)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("PUT", u, subscription)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sub := new(Subscription)
|
||||||
|
resp, err := s.client.Do(req, sub)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return sub, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteThreadSubscription deletes the subscription for the specified thread
|
||||||
|
// for the authenticated user.
|
||||||
|
//
|
||||||
|
// GitHub API Docs: https://developer.github.com/v3/activity/notifications/#delete-a-thread-subscription
|
||||||
|
func (s *ActivityService) DeleteThreadSubscription(id string) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("notifications/threads/%v/subscription", id)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
203
Godeps/_workspace/src/github.com/google/go-github/github/activity_notifications_test.go
generated
vendored
Normal file
203
Godeps/_workspace/src/github.com/google/go-github/github/activity_notifications_test.go
generated
vendored
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
// Copyright 2014 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"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestActivityService_ListNotification(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/notifications", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"all": "true",
|
||||||
|
"participating": "true",
|
||||||
|
"since": "2006-01-02T15:04:05Z",
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Fprint(w, `[{"id":"1", "subject":{"title":"t"}}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &NotificationListOptions{
|
||||||
|
All: true,
|
||||||
|
Participating: true,
|
||||||
|
Since: time.Date(2006, 01, 02, 15, 04, 05, 0, time.UTC),
|
||||||
|
}
|
||||||
|
notifications, _, err := client.Activity.ListNotifications(opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.ListNotifications returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Notification{{ID: String("1"), Subject: &NotificationSubject{Title: String("t")}}}
|
||||||
|
if !reflect.DeepEqual(notifications, want) {
|
||||||
|
t.Errorf("Activity.ListNotifications returned %+v, want %+v", notifications, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_ListRepositoryNotification(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/notifications", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `[{"id":"1"}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
notifications, _, err := client.Activity.ListRepositoryNotifications("o", "r", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.ListRepositoryNotifications returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Notification{{ID: String("1")}}
|
||||||
|
if !reflect.DeepEqual(notifications, want) {
|
||||||
|
t.Errorf("Activity.ListRepositoryNotifications returned %+v, want %+v", notifications, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_MarkNotificationsRead(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/notifications", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "PUT")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"last_read_at": "2006-01-02T15:04:05Z",
|
||||||
|
})
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusResetContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Activity.MarkNotificationsRead(time.Date(2006, 01, 02, 15, 04, 05, 0, time.UTC))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.MarkNotificationsRead returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_MarkRepositoryNotificationsRead(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/notifications", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "PUT")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"last_read_at": "2006-01-02T15:04:05Z",
|
||||||
|
})
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusResetContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Activity.MarkRepositoryNotificationsRead("o", "r", time.Date(2006, 01, 02, 15, 04, 05, 0, time.UTC))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.MarkRepositoryNotificationsRead returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_GetThread(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/notifications/threads/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"id":"1"}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
notification, _, err := client.Activity.GetThread("1")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.GetThread returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Notification{ID: String("1")}
|
||||||
|
if !reflect.DeepEqual(notification, want) {
|
||||||
|
t.Errorf("Activity.GetThread returned %+v, want %+v", notification, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_MarkThreadRead(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/notifications/threads/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "PATCH")
|
||||||
|
w.WriteHeader(http.StatusResetContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Activity.MarkThreadRead("1")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.MarkThreadRead returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_GetThreadSubscription(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/notifications/threads/1/subscription", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"subscribed":true}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
sub, _, err := client.Activity.GetThreadSubscription("1")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.GetThreadSubscription returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Subscription{Subscribed: Bool(true)}
|
||||||
|
if !reflect.DeepEqual(sub, want) {
|
||||||
|
t.Errorf("Activity.GetThreadSubscription returned %+v, want %+v", sub, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_SetThreadSubscription(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &Subscription{Subscribed: Bool(true)}
|
||||||
|
|
||||||
|
mux.HandleFunc("/notifications/threads/1/subscription", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(Subscription)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "PUT")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"ignored":true}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
sub, _, err := client.Activity.SetThreadSubscription("1", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.SetThreadSubscription returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Subscription{Ignored: Bool(true)}
|
||||||
|
if !reflect.DeepEqual(sub, want) {
|
||||||
|
t.Errorf("Activity.SetThreadSubscription returned %+v, want %+v", sub, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_DeleteThreadSubscription(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/notifications/threads/1/subscription", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Activity.DeleteThreadSubscription("1")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.DeleteThreadSubscription returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
114
Godeps/_workspace/src/github.com/google/go-github/github/activity_star.go
generated
vendored
Normal file
114
Godeps/_workspace/src/github.com/google/go-github/github/activity_star.go
generated
vendored
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
// 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"
|
||||||
|
|
||||||
|
// ListStargazers lists people who have starred the specified repo.
|
||||||
|
//
|
||||||
|
// GitHub API Docs: https://developer.github.com/v3/activity/starring/#list-stargazers
|
||||||
|
func (s *ActivityService) ListStargazers(owner, repo string, opt *ListOptions) ([]User, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%s/%s/stargazers", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
stargazers := new([]User)
|
||||||
|
resp, err := s.client.Do(req, stargazers)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *stargazers, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActivityListStarredOptions specifies the optional parameters to the
|
||||||
|
// ActivityService.ListStarred method.
|
||||||
|
type ActivityListStarredOptions struct {
|
||||||
|
// How to sort the repository list. Possible values are: created, updated,
|
||||||
|
// pushed, full_name. Default is "full_name".
|
||||||
|
Sort string `url:"sort,omitempty"`
|
||||||
|
|
||||||
|
// Direction in which to sort repositories. Possible values are: asc, desc.
|
||||||
|
// Default is "asc" when sort is "full_name", otherwise default is "desc".
|
||||||
|
Direction string `url:"direction,omitempty"`
|
||||||
|
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListStarred lists all the repos starred by a user. Passing the empty string
|
||||||
|
// will list the starred repositories for the authenticated user.
|
||||||
|
//
|
||||||
|
// 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) {
|
||||||
|
var u string
|
||||||
|
if user != "" {
|
||||||
|
u = fmt.Sprintf("users/%v/starred", user)
|
||||||
|
} else {
|
||||||
|
u = "user/starred"
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
repos := new([]Repository)
|
||||||
|
resp, err := s.client.Do(req, repos)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *repos, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsStarred checks if a repository is starred by authenticated user.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/activity/starring/#check-if-you-are-starring-a-repository
|
||||||
|
func (s *ActivityService) IsStarred(owner, repo string) (bool, *Response, error) {
|
||||||
|
u := fmt.Sprintf("user/starred/%v/%v", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
resp, err := s.client.Do(req, nil)
|
||||||
|
starred, err := parseBoolResponse(err)
|
||||||
|
return starred, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Star a repository as the authenticated user.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/activity/starring/#star-a-repository
|
||||||
|
func (s *ActivityService) Star(owner, repo string) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("user/starred/%v/%v", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("PUT", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unstar a repository as the authenticated user.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/activity/starring/#unstar-a-repository
|
||||||
|
func (s *ActivityService) Unstar(owner, repo string) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("user/starred/%v/%v", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
167
Godeps/_workspace/src/github.com/google/go-github/github/activity_star_test.go
generated
vendored
Normal file
167
Godeps/_workspace/src/github.com/google/go-github/github/activity_star_test.go
generated
vendored
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
// 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 TestActivityService_ListStargazers(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/stargazers", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"page": "2",
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
stargazers, _, err := client.Activity.ListStargazers("o", "r", &ListOptions{Page: 2})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.ListStargazers returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []User{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(stargazers, want) {
|
||||||
|
t.Errorf("Activity.ListStargazers returned %+v, want %+v", stargazers, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_ListStarred_authenticatedUser(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/user/starred", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
repos, _, err := client.Activity.ListStarred("", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.ListStarred returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Repository{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(repos, want) {
|
||||||
|
t.Errorf("Activity.ListStarred returned %+v, want %+v", repos, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_ListStarred_specifiedUser(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/users/u/starred", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"sort": "created",
|
||||||
|
"direction": "asc",
|
||||||
|
"page": "2",
|
||||||
|
})
|
||||||
|
fmt.Fprint(w, `[{"id":2}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ActivityListStarredOptions{"created", "asc", ListOptions{Page: 2}}
|
||||||
|
repos, _, err := client.Activity.ListStarred("u", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.ListStarred returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Repository{{ID: Int(2)}}
|
||||||
|
if !reflect.DeepEqual(repos, want) {
|
||||||
|
t.Errorf("Activity.ListStarred returned %+v, want %+v", repos, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_ListStarred_invalidUser(t *testing.T) {
|
||||||
|
_, _, err := client.Activity.ListStarred("%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_IsStarred_hasStar(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/user/starred/o/r", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
star, _, err := client.Activity.IsStarred("o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.IsStarred returned error: %v", err)
|
||||||
|
}
|
||||||
|
if want := true; star != want {
|
||||||
|
t.Errorf("Activity.IsStarred returned %+v, want %+v", star, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_IsStarred_noStar(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/user/starred/o/r", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
})
|
||||||
|
|
||||||
|
star, _, err := client.Activity.IsStarred("o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.IsStarred returned error: %v", err)
|
||||||
|
}
|
||||||
|
if want := false; star != want {
|
||||||
|
t.Errorf("Activity.IsStarred returned %+v, want %+v", star, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_IsStarred_invalidID(t *testing.T) {
|
||||||
|
_, _, err := client.Activity.IsStarred("%", "%")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_Star(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/user/starred/o/r", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "PUT")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Activity.Star("o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.Star returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_Star_invalidID(t *testing.T) {
|
||||||
|
_, err := client.Activity.Star("%", "%")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_Unstar(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/user/starred/o/r", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Activity.Unstar("o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.Unstar returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_Unstar_invalidID(t *testing.T) {
|
||||||
|
_, err := client.Activity.Unstar("%", "%")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
131
Godeps/_workspace/src/github.com/google/go-github/github/activity_watching.go
generated
vendored
Normal file
131
Godeps/_workspace/src/github.com/google/go-github/github/activity_watching.go
generated
vendored
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
// Copyright 2014 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"
|
||||||
|
|
||||||
|
// Subscription identifies a repository or thread subscription.
|
||||||
|
type Subscription struct {
|
||||||
|
Subscribed *bool `json:"subscribed,omitempty"`
|
||||||
|
Ignored *bool `json:"ignored,omitempty"`
|
||||||
|
Reason *string `json:"reason,omitempty"`
|
||||||
|
CreatedAt *Timestamp `json:"created_at,omitempty"`
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
|
||||||
|
// only populated for repository subscriptions
|
||||||
|
RepositoryURL *string `json:"repository_url,omitempty"`
|
||||||
|
|
||||||
|
// only populated for thread subscriptions
|
||||||
|
ThreadURL *string `json:"thread_url,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListWatchers lists watchers of a particular repo.
|
||||||
|
//
|
||||||
|
// GitHub API Docs: http://developer.github.com/v3/activity/watching/#list-watchers
|
||||||
|
func (s *ActivityService) ListWatchers(owner, repo string, opt *ListOptions) ([]User, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%s/%s/subscribers", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
watchers := new([]User)
|
||||||
|
resp, err := s.client.Do(req, watchers)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *watchers, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListWatched lists the repositories the specified user is watching. Passing
|
||||||
|
// the empty string will fetch watched repos for the authenticated user.
|
||||||
|
//
|
||||||
|
// GitHub API Docs: https://developer.github.com/v3/activity/watching/#list-repositories-being-watched
|
||||||
|
func (s *ActivityService) ListWatched(user string) ([]Repository, *Response, error) {
|
||||||
|
var u string
|
||||||
|
if user != "" {
|
||||||
|
u = fmt.Sprintf("users/%v/subscriptions", user)
|
||||||
|
} else {
|
||||||
|
u = "user/subscriptions"
|
||||||
|
}
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
watched := new([]Repository)
|
||||||
|
resp, err := s.client.Do(req, watched)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *watched, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRepositorySubscription returns the subscription for the specified
|
||||||
|
// repository for the authenticated user. If the authenticated user is not
|
||||||
|
// watching the repository, a nil Subscription is returned.
|
||||||
|
//
|
||||||
|
// GitHub API Docs: https://developer.github.com/v3/activity/watching/#get-a-repository-subscription
|
||||||
|
func (s *ActivityService) GetRepositorySubscription(owner, repo string) (*Subscription, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%s/%s/subscription", owner, repo)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sub := new(Subscription)
|
||||||
|
resp, err := s.client.Do(req, sub)
|
||||||
|
if err != nil {
|
||||||
|
// if it's just a 404, don't return that as an error
|
||||||
|
_, err = parseBoolResponse(err)
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return sub, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRepositorySubscription sets the subscription for the specified repository
|
||||||
|
// for the authenticated user.
|
||||||
|
//
|
||||||
|
// GitHub API Docs: https://developer.github.com/v3/activity/watching/#set-a-repository-subscription
|
||||||
|
func (s *ActivityService) SetRepositorySubscription(owner, repo string, subscription *Subscription) (*Subscription, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%s/%s/subscription", owner, repo)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("PUT", u, subscription)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sub := new(Subscription)
|
||||||
|
resp, err := s.client.Do(req, sub)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return sub, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRepositorySubscription deletes the subscription for the specified
|
||||||
|
// repository for the authenticated user.
|
||||||
|
//
|
||||||
|
// GitHub API Docs: https://developer.github.com/v3/activity/watching/#delete-a-repository-subscription
|
||||||
|
func (s *ActivityService) DeleteRepositorySubscription(owner, repo string) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%s/%s/subscription", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
177
Godeps/_workspace/src/github.com/google/go-github/github/activity_watching_test.go
generated
vendored
Normal file
177
Godeps/_workspace/src/github.com/google/go-github/github/activity_watching_test.go
generated
vendored
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
// Copyright 2014 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 TestActivityService_ListWatchers(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/subscribers", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"page": "2",
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
watchers, _, err := client.Activity.ListWatchers("o", "r", &ListOptions{Page: 2})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.ListWatchers returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []User{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(watchers, want) {
|
||||||
|
t.Errorf("Activity.ListWatchers returned %+v, want %+v", watchers, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_ListWatched_authenticatedUser(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/user/subscriptions", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
watched, _, err := client.Activity.ListWatched("")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.ListWatched returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Repository{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(watched, want) {
|
||||||
|
t.Errorf("Activity.ListWatched returned %+v, want %+v", watched, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_ListWatched_specifiedUser(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/users/u/subscriptions", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
watched, _, err := client.Activity.ListWatched("u")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.ListWatched returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Repository{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(watched, want) {
|
||||||
|
t.Errorf("Activity.ListWatched returned %+v, want %+v", watched, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_GetRepositorySubscription_true(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/subscription", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"subscribed":true}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
sub, _, err := client.Activity.GetRepositorySubscription("o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.GetRepositorySubscription returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Subscription{Subscribed: Bool(true)}
|
||||||
|
if !reflect.DeepEqual(sub, want) {
|
||||||
|
t.Errorf("Activity.GetRepositorySubscription returned %+v, want %+v", sub, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_GetRepositorySubscription_false(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/subscription", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
})
|
||||||
|
|
||||||
|
sub, _, err := client.Activity.GetRepositorySubscription("o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.GetRepositorySubscription returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var want *Subscription
|
||||||
|
if !reflect.DeepEqual(sub, want) {
|
||||||
|
t.Errorf("Activity.GetRepositorySubscription returned %+v, want %+v", sub, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_GetRepositorySubscription_error(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/subscription", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, _, err := client.Activity.GetRepositorySubscription("o", "r")
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected HTTP 400 response")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_SetRepositorySubscription(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &Subscription{Subscribed: Bool(true)}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/subscription", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(Subscription)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "PUT")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"ignored":true}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
sub, _, err := client.Activity.SetRepositorySubscription("o", "r", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.SetRepositorySubscription returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Subscription{Ignored: Bool(true)}
|
||||||
|
if !reflect.DeepEqual(sub, want) {
|
||||||
|
t.Errorf("Activity.SetRepositorySubscription returned %+v, want %+v", sub, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestActivityService_DeleteRepositorySubscription(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/subscription", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Activity.DeleteRepositorySubscription("o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Activity.DeleteRepositorySubscription returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
99
Godeps/_workspace/src/github.com/google/go-github/github/doc.go
generated
vendored
Normal file
99
Godeps/_workspace/src/github.com/google/go-github/github/doc.go
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
// 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 provides a client for using the GitHub API.
|
||||||
|
|
||||||
|
Construct a new GitHub client, then use the various services on the client to
|
||||||
|
access different parts of the GitHub API. For example:
|
||||||
|
|
||||||
|
client := github.NewClient(nil)
|
||||||
|
|
||||||
|
// list all organizations for user "willnorris"
|
||||||
|
orgs, _, err := client.Organizations.List("willnorris", nil)
|
||||||
|
|
||||||
|
Set optional parameters for an API method by passing an Options object.
|
||||||
|
|
||||||
|
// list recently updated repositories for org "github"
|
||||||
|
opt := &github.RepositoryListByOrgOptions{Sort: "updated"}
|
||||||
|
repos, _, err := client.Repositories.ListByOrg("github", opt)
|
||||||
|
|
||||||
|
The services of a client divide the API into logical chunks and correspond to
|
||||||
|
the structure of the GitHub API documentation at
|
||||||
|
http://developer.github.com/v3/.
|
||||||
|
|
||||||
|
Authentication
|
||||||
|
|
||||||
|
The go-github library does not directly handle authentication. Instead, when
|
||||||
|
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,
|
||||||
|
but you can always use any other library that provides an http.Client. If you
|
||||||
|
have an OAuth2 access token (for example, a personal API token), you can use it
|
||||||
|
with the goauth2 using:
|
||||||
|
|
||||||
|
import "code.google.com/p/goauth2/oauth"
|
||||||
|
|
||||||
|
// simple OAuth transport if you already have an access token;
|
||||||
|
// see goauth2 library for full usage
|
||||||
|
t := &oauth.Transport{
|
||||||
|
Token: &oauth.Token{AccessToken: "..."},
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
include the specified OAuth token. Therefore, authenticated clients should
|
||||||
|
almost never be shared between different users.
|
||||||
|
|
||||||
|
Rate Limiting
|
||||||
|
|
||||||
|
GitHub imposes a rate limit on all API clients. Unauthenticated clients are
|
||||||
|
limited to 60 requests per hour, while authenticated clients can make up to
|
||||||
|
5,000 requests per hour. To receive the higher rate limit when making calls
|
||||||
|
that are not issued on behalf of a user, use the
|
||||||
|
UnauthenticatedRateLimitedTransport.
|
||||||
|
|
||||||
|
The Rate field on a client tracks the rate limit information based on the most
|
||||||
|
recent API call. This is updated on every call, but may be out of date if it's
|
||||||
|
been some time since the last API call and other clients have made subsequent
|
||||||
|
requests since then. You can always call RateLimit() directly to get the most
|
||||||
|
up-to-date rate limit data for the client.
|
||||||
|
|
||||||
|
Learn more about GitHub rate limiting at
|
||||||
|
http://developer.github.com/v3/#rate-limiting.
|
||||||
|
|
||||||
|
Conditional Requests
|
||||||
|
|
||||||
|
The GitHub API has good support for conditional requests which will help
|
||||||
|
prevent you from burning through your rate limit, as well as help speed up your
|
||||||
|
application. go-github does not handle conditional requests directly, but is
|
||||||
|
instead designed to work with a caching http.Transport. We recommend using
|
||||||
|
https://github.com/gregjones/httpcache, which can be used in conjuction with
|
||||||
|
https://github.com/sourcegraph/apiproxy to provide additional flexibility and
|
||||||
|
control of caching rules.
|
||||||
|
|
||||||
|
Learn more about GitHub conditional requests at
|
||||||
|
https://developer.github.com/v3/#conditional-requests.
|
||||||
|
|
||||||
|
Creating and Updating Resources
|
||||||
|
|
||||||
|
All structs for GitHub resources use pointer values for all non-repeated fields.
|
||||||
|
This allows distinguishing between unset fields and those set to a zero-value.
|
||||||
|
Helper functions have been provided to easily create these pointers for string,
|
||||||
|
bool, and int values. For example:
|
||||||
|
|
||||||
|
// create a new private repository named "foo"
|
||||||
|
repo := &github.Repository{
|
||||||
|
Name: github.String("foo"),
|
||||||
|
Private: github.Bool(true),
|
||||||
|
}
|
||||||
|
client.Repositories.Create("", repo)
|
||||||
|
|
||||||
|
Users who have worked with protocol buffers should find this pattern familiar.
|
||||||
|
*/
|
||||||
|
package github
|
||||||
262
Godeps/_workspace/src/github.com/google/go-github/github/gists.go
generated
vendored
Normal file
262
Godeps/_workspace/src/github.com/google/go-github/github/gists.go
generated
vendored
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
// Copyright 2013 The go-github AUTHORS. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GistsService handles communication with the Gist related
|
||||||
|
// methods of the GitHub API.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/gists/
|
||||||
|
type GistsService struct {
|
||||||
|
client *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gist represents a GitHub's gist.
|
||||||
|
type Gist struct {
|
||||||
|
ID *string `json:"id,omitempty"`
|
||||||
|
Description *string `json:"description,omitempty"`
|
||||||
|
Public *bool `json:"public,omitempty"`
|
||||||
|
Owner *User `json:"owner,omitempty"`
|
||||||
|
Files map[GistFilename]GistFile `json:"files,omitempty"`
|
||||||
|
Comments *int `json:"comments,omitempty"`
|
||||||
|
HTMLURL *string `json:"html_url,omitempty"`
|
||||||
|
GitPullURL *string `json:"git_pull_url,omitempty"`
|
||||||
|
GitPushURL *string `json:"git_push_url,omitempty"`
|
||||||
|
CreatedAt *time.Time `json:"created_at,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g Gist) String() string {
|
||||||
|
return Stringify(g)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GistFilename represents filename on a gist.
|
||||||
|
type GistFilename string
|
||||||
|
|
||||||
|
// GistFile represents a file on a gist.
|
||||||
|
type GistFile struct {
|
||||||
|
Size *int `json:"size,omitempty"`
|
||||||
|
Filename *string `json:"filename,omitempty"`
|
||||||
|
RawURL *string `json:"raw_url,omitempty"`
|
||||||
|
Content *string `json:"content,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g GistFile) String() string {
|
||||||
|
return Stringify(g)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GistListOptions specifies the optional parameters to the
|
||||||
|
// GistsService.List, GistsService.ListAll, and GistsService.ListStarred methods.
|
||||||
|
type GistListOptions struct {
|
||||||
|
// Since filters Gists by time.
|
||||||
|
Since time.Time `url:"since,omitempty"`
|
||||||
|
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// List gists for a user. Passing the empty string will list
|
||||||
|
// all public gists if called anonymously. However, if the call
|
||||||
|
// is authenticated, it will returns all gists for the authenticated
|
||||||
|
// user.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/gists/#list-gists
|
||||||
|
func (s *GistsService) List(user string, opt *GistListOptions) ([]Gist, *Response, error) {
|
||||||
|
var u string
|
||||||
|
if user != "" {
|
||||||
|
u = fmt.Sprintf("users/%v/gists", user)
|
||||||
|
} else {
|
||||||
|
u = "gists"
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
gists := new([]Gist)
|
||||||
|
resp, err := s.client.Do(req, gists)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *gists, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListAll lists all public gists.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/gists/#list-gists
|
||||||
|
func (s *GistsService) ListAll(opt *GistListOptions) ([]Gist, *Response, error) {
|
||||||
|
u, err := addOptions("gists/public", opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
gists := new([]Gist)
|
||||||
|
resp, err := s.client.Do(req, gists)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *gists, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListStarred lists starred gists of authenticated user.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/gists/#list-gists
|
||||||
|
func (s *GistsService) ListStarred(opt *GistListOptions) ([]Gist, *Response, error) {
|
||||||
|
u, err := addOptions("gists/starred", opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
gists := new([]Gist)
|
||||||
|
resp, err := s.client.Do(req, gists)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *gists, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a single gist.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/gists/#get-a-single-gist
|
||||||
|
func (s *GistsService) Get(id string) (*Gist, *Response, error) {
|
||||||
|
u := fmt.Sprintf("gists/%v", id)
|
||||||
|
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.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/gists/#create-a-gist
|
||||||
|
func (s *GistsService) Create(gist *Gist) (*Gist, *Response, error) {
|
||||||
|
u := "gists"
|
||||||
|
req, err := s.client.NewRequest("POST", u, gist)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
g := new(Gist)
|
||||||
|
resp, err := s.client.Do(req, g)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return g, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Edit a gist.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/gists/#edit-a-gist
|
||||||
|
func (s *GistsService) Edit(id string, gist *Gist) (*Gist, *Response, error) {
|
||||||
|
u := fmt.Sprintf("gists/%v", id)
|
||||||
|
req, err := s.client.NewRequest("PATCH", u, gist)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
g := new(Gist)
|
||||||
|
resp, err := s.client.Do(req, g)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return g, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete a gist.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/gists/#delete-a-gist
|
||||||
|
func (s *GistsService) Delete(id string) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("gists/%v", id)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Star a gist on behalf of authenticated user.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/gists/#star-a-gist
|
||||||
|
func (s *GistsService) Star(id string) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("gists/%v/star", id)
|
||||||
|
req, err := s.client.NewRequest("PUT", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unstar a gist on a behalf of authenticated user.
|
||||||
|
//
|
||||||
|
// Github API docs: http://developer.github.com/v3/gists/#unstar-a-gist
|
||||||
|
func (s *GistsService) Unstar(id string) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("gists/%v/star", id)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsStarred checks if a gist is starred by authenticated user.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/gists/#check-if-a-gist-is-starred
|
||||||
|
func (s *GistsService) IsStarred(id string) (bool, *Response, error) {
|
||||||
|
u := fmt.Sprintf("gists/%v/star", id)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
resp, err := s.client.Do(req, nil)
|
||||||
|
starred, err := parseBoolResponse(err)
|
||||||
|
return starred, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fork a gist.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/gists/#fork-a-gist
|
||||||
|
func (s *GistsService) Fork(id string) (*Gist, *Response, error) {
|
||||||
|
u := fmt.Sprintf("gists/%v/forks", id)
|
||||||
|
req, err := s.client.NewRequest("POST", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
g := new(Gist)
|
||||||
|
resp, err := s.client.Do(req, g)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return g, resp, err
|
||||||
|
}
|
||||||
118
Godeps/_workspace/src/github.com/google/go-github/github/gists_comments.go
generated
vendored
Normal file
118
Godeps/_workspace/src/github.com/google/go-github/github/gists_comments.go
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
// 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"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GistComment represents a Gist comment.
|
||||||
|
type GistComment struct {
|
||||||
|
ID *int `json:"id,omitempty"`
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
Body *string `json:"body,omitempty"`
|
||||||
|
User *User `json:"user,omitempty"`
|
||||||
|
CreatedAt *time.Time `json:"created_at,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g GistComment) String() string {
|
||||||
|
return Stringify(g)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListComments lists all comments for a gist.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/gists/comments/#list-comments-on-a-gist
|
||||||
|
func (s *GistsService) ListComments(gistID string, opt *ListOptions) ([]GistComment, *Response, error) {
|
||||||
|
u := fmt.Sprintf("gists/%v/comments", gistID)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
comments := new([]GistComment)
|
||||||
|
resp, err := s.client.Do(req, comments)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *comments, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetComment retrieves a single comment from a gist.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/gists/comments/#get-a-single-comment
|
||||||
|
func (s *GistsService) GetComment(gistID string, commentID int) (*GistComment, *Response, error) {
|
||||||
|
u := fmt.Sprintf("gists/%v/comments/%v", gistID, commentID)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
c := new(GistComment)
|
||||||
|
resp, err := s.client.Do(req, c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateComment creates a comment for a gist.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/gists/comments/#create-a-comment
|
||||||
|
func (s *GistsService) CreateComment(gistID string, comment *GistComment) (*GistComment, *Response, error) {
|
||||||
|
u := fmt.Sprintf("gists/%v/comments", gistID)
|
||||||
|
req, err := s.client.NewRequest("POST", u, comment)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
c := new(GistComment)
|
||||||
|
resp, err := s.client.Do(req, c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditComment edits an existing gist comment.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/gists/comments/#edit-a-comment
|
||||||
|
func (s *GistsService) EditComment(gistID string, commentID int, comment *GistComment) (*GistComment, *Response, error) {
|
||||||
|
u := fmt.Sprintf("gists/%v/comments/%v", gistID, commentID)
|
||||||
|
req, err := s.client.NewRequest("PATCH", u, comment)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
c := new(GistComment)
|
||||||
|
resp, err := s.client.Do(req, c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteComment deletes a gist comment.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/gists/comments/#delete-a-comment
|
||||||
|
func (s *GistsService) DeleteComment(gistID string, commentID int) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("gists/%v/comments/%v", gistID, commentID)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
155
Godeps/_workspace/src/github.com/google/go-github/github/gists_comments_test.go
generated
vendored
Normal file
155
Godeps/_workspace/src/github.com/google/go-github/github/gists_comments_test.go
generated
vendored
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGistsService_ListComments(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/gists/1/comments", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{"page": "2"})
|
||||||
|
fmt.Fprint(w, `[{"id": 1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListOptions{Page: 2}
|
||||||
|
comments, _, err := client.Gists.ListComments("1", opt)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Gists.Comments returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []GistComment{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(comments, want) {
|
||||||
|
t.Errorf("Gists.ListComments returned %+v, want %+v", comments, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_ListComments_invalidID(t *testing.T) {
|
||||||
|
_, _, err := client.Gists.ListComments("%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_GetComment(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/gists/1/comments/2", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"id": 1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
comment, _, err := client.Gists.GetComment("1", 2)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Gists.GetComment returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &GistComment{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(comment, want) {
|
||||||
|
t.Errorf("Gists.GetComment returned %+v, want %+v", comment, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_GetComment_invalidID(t *testing.T) {
|
||||||
|
_, _, err := client.Gists.GetComment("%", 1)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_CreateComment(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &GistComment{ID: Int(1), Body: String("b")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/gists/1/comments", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(GistComment)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
comment, _, err := client.Gists.CreateComment("1", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Gists.CreateComment returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &GistComment{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(comment, want) {
|
||||||
|
t.Errorf("Gists.CreateComment returned %+v, want %+v", comment, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_CreateComment_invalidID(t *testing.T) {
|
||||||
|
_, _, err := client.Gists.CreateComment("%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_EditComment(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &GistComment{ID: Int(1), Body: String("b")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/gists/1/comments/2", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(GistComment)
|
||||||
|
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}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
comment, _, err := client.Gists.EditComment("1", 2, input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Gists.EditComment returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &GistComment{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(comment, want) {
|
||||||
|
t.Errorf("Gists.EditComment returned %+v, want %+v", comment, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_EditComment_invalidID(t *testing.T) {
|
||||||
|
_, _, err := client.Gists.EditComment("%", 1, nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_DeleteComment(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/gists/1/comments/2", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Gists.DeleteComment("1", 2)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Gists.Delete returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_DeleteComment_invalidID(t *testing.T) {
|
||||||
|
_, err := client.Gists.DeleteComment("%", 1)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
385
Godeps/_workspace/src/github.com/google/go-github/github/gists_test.go
generated
vendored
Normal file
385
Godeps/_workspace/src/github.com/google/go-github/github/gists_test.go
generated
vendored
Normal file
@@ -0,0 +1,385 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGistsService_List_specifiedUser(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
since := "2013-01-01T00:00:00Z"
|
||||||
|
|
||||||
|
mux.HandleFunc("/users/u/gists", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"since": since,
|
||||||
|
})
|
||||||
|
fmt.Fprint(w, `[{"id": "1"}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &GistListOptions{Since: time.Date(2013, time.January, 1, 0, 0, 0, 0, time.UTC)}
|
||||||
|
gists, _, err := client.Gists.List("u", opt)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Gists.List returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Gist{{ID: String("1")}}
|
||||||
|
if !reflect.DeepEqual(gists, want) {
|
||||||
|
t.Errorf("Gists.List returned %+v, want %+v", gists, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_List_authenticatedUser(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/gists", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `[{"id": "1"}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
gists, _, err := client.Gists.List("", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Gists.List returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Gist{{ID: String("1")}}
|
||||||
|
if !reflect.DeepEqual(gists, want) {
|
||||||
|
t.Errorf("Gists.List returned %+v, want %+v", gists, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_List_invalidUser(t *testing.T) {
|
||||||
|
_, _, err := client.Gists.List("%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_ListAll(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
since := "2013-01-01T00:00:00Z"
|
||||||
|
|
||||||
|
mux.HandleFunc("/gists/public", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"since": since,
|
||||||
|
})
|
||||||
|
fmt.Fprint(w, `[{"id": "1"}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &GistListOptions{Since: time.Date(2013, time.January, 1, 0, 0, 0, 0, time.UTC)}
|
||||||
|
gists, _, err := client.Gists.ListAll(opt)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Gists.ListAll returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Gist{{ID: String("1")}}
|
||||||
|
if !reflect.DeepEqual(gists, want) {
|
||||||
|
t.Errorf("Gists.ListAll returned %+v, want %+v", gists, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_ListStarred(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
since := "2013-01-01T00:00:00Z"
|
||||||
|
|
||||||
|
mux.HandleFunc("/gists/starred", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"since": since,
|
||||||
|
})
|
||||||
|
fmt.Fprint(w, `[{"id": "1"}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &GistListOptions{Since: time.Date(2013, time.January, 1, 0, 0, 0, 0, time.UTC)}
|
||||||
|
gists, _, err := client.Gists.ListStarred(opt)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Gists.ListStarred returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Gist{{ID: String("1")}}
|
||||||
|
if !reflect.DeepEqual(gists, want) {
|
||||||
|
t.Errorf("Gists.ListStarred returned %+v, want %+v", gists, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_Get(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/gists/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"id": "1"}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
gist, _, err := client.Gists.Get("1")
|
||||||
|
|
||||||
|
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_Get_invalidID(t *testing.T) {
|
||||||
|
_, _, err := client.Gists.Get("%")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_Create(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &Gist{
|
||||||
|
Description: String("Gist description"),
|
||||||
|
Public: Bool(false),
|
||||||
|
Files: map[GistFilename]GistFile{
|
||||||
|
"test.txt": {Content: String("Gist file content")},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
mux.HandleFunc("/gists", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(Gist)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w,
|
||||||
|
`
|
||||||
|
{
|
||||||
|
"id": "1",
|
||||||
|
"description": "Gist description",
|
||||||
|
"public": false,
|
||||||
|
"files": {
|
||||||
|
"test.txt": {
|
||||||
|
"filename": "test.txt"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
gist, _, err := client.Gists.Create(input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Gists.Create returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Gist{
|
||||||
|
ID: String("1"),
|
||||||
|
Description: String("Gist description"),
|
||||||
|
Public: Bool(false),
|
||||||
|
Files: map[GistFilename]GistFile{
|
||||||
|
"test.txt": {Filename: String("test.txt")},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(gist, want) {
|
||||||
|
t.Errorf("Gists.Create returned %+v, want %+v", gist, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_Edit(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &Gist{
|
||||||
|
Description: String("New description"),
|
||||||
|
Files: map[GistFilename]GistFile{
|
||||||
|
"new.txt": {Content: String("new file content")},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
mux.HandleFunc("/gists/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(Gist)
|
||||||
|
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",
|
||||||
|
"description": "new description",
|
||||||
|
"public": false,
|
||||||
|
"files": {
|
||||||
|
"test.txt": {
|
||||||
|
"filename": "test.txt"
|
||||||
|
},
|
||||||
|
"new.txt": {
|
||||||
|
"filename": "new.txt"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
gist, _, err := client.Gists.Edit("1", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Gists.Edit returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Gist{
|
||||||
|
ID: String("1"),
|
||||||
|
Description: String("new description"),
|
||||||
|
Public: Bool(false),
|
||||||
|
Files: map[GistFilename]GistFile{
|
||||||
|
"test.txt": {Filename: String("test.txt")},
|
||||||
|
"new.txt": {Filename: String("new.txt")},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(gist, want) {
|
||||||
|
t.Errorf("Gists.Edit returned %+v, want %+v", gist, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_Edit_invalidID(t *testing.T) {
|
||||||
|
_, _, err := client.Gists.Edit("%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_Delete(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/gists/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Gists.Delete("1")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Gists.Delete returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_Delete_invalidID(t *testing.T) {
|
||||||
|
_, err := client.Gists.Delete("%")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_Star(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/gists/1/star", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "PUT")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Gists.Star("1")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Gists.Star returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_Star_invalidID(t *testing.T) {
|
||||||
|
_, err := client.Gists.Star("%")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_Unstar(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/gists/1/star", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Gists.Unstar("1")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Gists.Unstar returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_Unstar_invalidID(t *testing.T) {
|
||||||
|
_, err := client.Gists.Unstar("%")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_IsStarred_hasStar(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/gists/1/star", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
star, _, err := client.Gists.IsStarred("1")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Gists.Starred returned error: %v", err)
|
||||||
|
}
|
||||||
|
if want := true; star != want {
|
||||||
|
t.Errorf("Gists.Starred returned %+v, want %+v", star, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_IsStarred_noStar(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/gists/1/star", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
})
|
||||||
|
|
||||||
|
star, _, err := client.Gists.IsStarred("1")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Gists.Starred returned error: %v", err)
|
||||||
|
}
|
||||||
|
if want := false; star != want {
|
||||||
|
t.Errorf("Gists.Starred returned %+v, want %+v", star, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_IsStarred_invalidID(t *testing.T) {
|
||||||
|
_, _, err := client.Gists.IsStarred("%")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_Fork(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/gists/1/forks", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
fmt.Fprint(w, `{"id": "2"}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
gist, _, err := client.Gists.Fork("1")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Gists.Fork returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Gist{ID: String("2")}
|
||||||
|
if !reflect.DeepEqual(gist, want) {
|
||||||
|
t.Errorf("Gists.Fork returned %+v, want %+v", gist, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGistsService_Fork_invalidID(t *testing.T) {
|
||||||
|
_, _, err := client.Gists.Fork("%")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
14
Godeps/_workspace/src/github.com/google/go-github/github/git.go
generated
vendored
Normal file
14
Godeps/_workspace/src/github.com/google/go-github/github/git.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// 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
|
||||||
|
|
||||||
|
// GitService handles communication with the git data related
|
||||||
|
// methods of the GitHub API.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/git/
|
||||||
|
type GitService struct {
|
||||||
|
client *Client
|
||||||
|
}
|
||||||
47
Godeps/_workspace/src/github.com/google/go-github/github/git_blobs.go
generated
vendored
Normal file
47
Godeps/_workspace/src/github.com/google/go-github/github/git_blobs.go
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
// 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"
|
||||||
|
|
||||||
|
// Blob represents a blob object.
|
||||||
|
type Blob struct {
|
||||||
|
Content *string `json:"content,omitempty"`
|
||||||
|
Encoding *string `json:"encoding,omitempty"`
|
||||||
|
SHA *string `json:"sha,omitempty"`
|
||||||
|
Size *int `json:"size,omitempty"`
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBlob fetchs a blob from a repo given a SHA.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/git/blobs/#get-a-blob
|
||||||
|
func (s *GitService) GetBlob(owner string, repo string, sha string) (*Blob, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/git/blobs/%v", owner, repo, sha)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
blob := new(Blob)
|
||||||
|
resp, err := s.client.Do(req, blob)
|
||||||
|
return blob, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateBlob creates a blob object.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/git/blobs/#create-a-blob
|
||||||
|
func (s *GitService) CreateBlob(owner string, repo string, blob *Blob) (*Blob, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/git/blobs", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("POST", u, blob)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
t := new(Blob)
|
||||||
|
resp, err := s.client.Do(req, t)
|
||||||
|
return t, resp, err
|
||||||
|
}
|
||||||
92
Godeps/_workspace/src/github.com/google/go-github/github/git_blobs_test.go
generated
vendored
Normal file
92
Godeps/_workspace/src/github.com/google/go-github/github/git_blobs_test.go
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGitService_GetBlob(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/git/blobs/s", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if m := "GET"; m != r.Method {
|
||||||
|
t.Errorf("Request method = %v, want %v", r.Method, m)
|
||||||
|
}
|
||||||
|
fmt.Fprint(w, `{
|
||||||
|
"sha": "s",
|
||||||
|
"content": "blob content"
|
||||||
|
}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
blob, _, err := client.Git.GetBlob("o", "r", "s")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Git.GetBlob returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := Blob{
|
||||||
|
SHA: String("s"),
|
||||||
|
Content: String("blob content"),
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(*blob, want) {
|
||||||
|
t.Errorf("Blob.Get returned %+v, want %+v", *blob, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGitService_GetBlob_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Git.GetBlob("%", "%", "%")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGitService_CreateBlob(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &Blob{
|
||||||
|
SHA: String("s"),
|
||||||
|
Content: String("blob content"),
|
||||||
|
Encoding: String("utf-8"),
|
||||||
|
Size: Int(12),
|
||||||
|
}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/git/blobs", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(Blob)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
if m := "POST"; m != r.Method {
|
||||||
|
t.Errorf("Request method = %v, want %v", r.Method, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := input
|
||||||
|
if !reflect.DeepEqual(v, want) {
|
||||||
|
t.Errorf("Git.CreateBlob request body: %+v, want %+v", v, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{
|
||||||
|
"sha": "s",
|
||||||
|
"content": "blob content",
|
||||||
|
"encoding": "utf-8",
|
||||||
|
"size": 12
|
||||||
|
}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
blob, _, err := client.Git.CreateBlob("o", "r", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Git.CreateBlob returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := input
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(*blob, *want) {
|
||||||
|
t.Errorf("Git.CreateBlob returned %+v, want %+v", *blob, *want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGitService_CreateBlob_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Git.CreateBlob("%", "%", &Blob{})
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
81
Godeps/_workspace/src/github.com/google/go-github/github/git_commits.go
generated
vendored
Normal file
81
Godeps/_workspace/src/github.com/google/go-github/github/git_commits.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"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Commit represents a GitHub commit.
|
||||||
|
type Commit struct {
|
||||||
|
SHA *string `json:"sha,omitempty"`
|
||||||
|
Author *CommitAuthor `json:"author,omitempty"`
|
||||||
|
Committer *CommitAuthor `json:"committer,omitempty"`
|
||||||
|
Message *string `json:"message,omitempty"`
|
||||||
|
Tree *Tree `json:"tree,omitempty"`
|
||||||
|
Parents []Commit `json:"parents,omitempty"`
|
||||||
|
Stats *CommitStats `json:"stats,omitempty"`
|
||||||
|
URL *string `json:url,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Commit) String() string {
|
||||||
|
return Stringify(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommitAuthor represents the author or committer of a commit. The commit
|
||||||
|
// author may not correspond to a GitHub User.
|
||||||
|
type CommitAuthor struct {
|
||||||
|
Date *time.Time `json:"date,omitempty"`
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
Email *string `json:"email,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CommitAuthor) String() string {
|
||||||
|
return Stringify(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCommit fetchs the Commit object for a given SHA.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/git/commits/#get-a-commit
|
||||||
|
func (s *GitService) GetCommit(owner string, repo string, sha string) (*Commit, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/git/commits/%v", owner, repo, sha)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
c := new(Commit)
|
||||||
|
resp, err := s.client.Do(req, c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateCommit creates a new commit in a repository.
|
||||||
|
//
|
||||||
|
// The commit.Committer is optional and will be filled with the commit.Author
|
||||||
|
// data if omitted. If the commit.Author is omitted, it will be filled in with
|
||||||
|
// the authenticated user’s information and the current date.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/git/commits/#create-a-commit
|
||||||
|
func (s *GitService) CreateCommit(owner string, repo string, commit *Commit) (*Commit, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/git/commits", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("POST", u, commit)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
c := new(Commit)
|
||||||
|
resp, err := s.client.Do(req, c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, resp, err
|
||||||
|
}
|
||||||
72
Godeps/_workspace/src/github.com/google/go-github/github/git_commits_test.go
generated
vendored
Normal file
72
Godeps/_workspace/src/github.com/google/go-github/github/git_commits_test.go
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGitService_GetCommit(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/git/commits/s", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"sha":"s","message":"m","author":{"name":"n"}}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
commit, _, err := client.Git.GetCommit("o", "r", "s")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Git.GetCommit returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Commit{SHA: String("s"), Message: String("m"), Author: &CommitAuthor{Name: String("n")}}
|
||||||
|
if !reflect.DeepEqual(commit, want) {
|
||||||
|
t.Errorf("Git.GetCommit returned %+v, want %+v", commit, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGitService_GetCommit_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Git.GetCommit("%", "%", "%")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGitService_CreateCommit(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &Commit{Message: String("m"), Tree: &Tree{SHA: String("t")}}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/git/commits", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(Commit)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
fmt.Fprint(w, `{"sha":"s"}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
commit, _, err := client.Git.CreateCommit("o", "r", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Git.CreateCommit returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Commit{SHA: String("s")}
|
||||||
|
if !reflect.DeepEqual(commit, want) {
|
||||||
|
t.Errorf("Git.CreateCommit returned %+v, want %+v", commit, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGitService_CreateCommit_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Git.CreateCommit("%", "%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
157
Godeps/_workspace/src/github.com/google/go-github/github/git_refs.go
generated
vendored
Normal file
157
Godeps/_workspace/src/github.com/google/go-github/github/git_refs.go
generated
vendored
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
// 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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Reference represents a GitHub reference.
|
||||||
|
type Reference struct {
|
||||||
|
Ref *string `json:"ref"`
|
||||||
|
URL *string `json:"url"`
|
||||||
|
Object *GitObject `json:"object"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r Reference) String() string {
|
||||||
|
return Stringify(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GitObject represents a Git object.
|
||||||
|
type GitObject struct {
|
||||||
|
Type *string `json:"type"`
|
||||||
|
SHA *string `json:"sha"`
|
||||||
|
URL *string `json:"url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o GitObject) String() string {
|
||||||
|
return Stringify(o)
|
||||||
|
}
|
||||||
|
|
||||||
|
// createRefRequest represents the payload for creating a reference.
|
||||||
|
type createRefRequest struct {
|
||||||
|
Ref *string `json:"ref"`
|
||||||
|
SHA *string `json:"sha"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// updateRefRequest represents the payload for updating a reference.
|
||||||
|
type updateRefRequest struct {
|
||||||
|
SHA *string `json:"sha"`
|
||||||
|
Force *bool `json:"force"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRef fetches the Reference object for a given Git ref.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/git/refs/#get-a-reference
|
||||||
|
func (s *GitService) GetRef(owner string, repo string, ref string) (*Reference, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, ref)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := new(Reference)
|
||||||
|
resp, err := s.client.Do(req, r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return r, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReferenceListOptions specifies optional parameters to the
|
||||||
|
// GitService.ListRefs method.
|
||||||
|
type ReferenceListOptions struct {
|
||||||
|
Type string `url:"-"`
|
||||||
|
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRefs lists all refs in a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/git/refs/#get-all-references
|
||||||
|
func (s *GitService) ListRefs(owner, repo string, opt *ReferenceListOptions) ([]Reference, *Response, error) {
|
||||||
|
var u string
|
||||||
|
if opt != nil && opt.Type != "" {
|
||||||
|
u = fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, opt.Type)
|
||||||
|
} else {
|
||||||
|
u = fmt.Sprintf("repos/%v/%v/git/refs", owner, repo)
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
var rs []Reference
|
||||||
|
resp, err := s.client.Do(req, &rs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return rs, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRef creates a new ref in a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/git/refs/#create-a-reference
|
||||||
|
func (s *GitService) CreateRef(owner string, repo string, ref *Reference) (*Reference, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/git/refs", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("POST", u, &createRefRequest{
|
||||||
|
Ref: String("refs/" + *ref.Ref),
|
||||||
|
SHA: ref.Object.SHA,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := new(Reference)
|
||||||
|
resp, err := s.client.Do(req, r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return r, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateRef updates an existing ref in a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/git/refs/#update-a-reference
|
||||||
|
func (s *GitService) UpdateRef(owner string, repo string, ref *Reference, force bool) (*Reference, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, *ref.Ref)
|
||||||
|
req, err := s.client.NewRequest("PATCH", u, &updateRefRequest{
|
||||||
|
SHA: ref.Object.SHA,
|
||||||
|
Force: &force,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := new(Reference)
|
||||||
|
resp, err := s.client.Do(req, r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return r, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRef deletes a ref from a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/git/refs/#delete-a-reference
|
||||||
|
func (s *GitService) DeleteRef(owner string, repo string, ref string) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, ref)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
250
Godeps/_workspace/src/github.com/google/go-github/github/git_refs_test.go
generated
vendored
Normal file
250
Godeps/_workspace/src/github.com/google/go-github/github/git_refs_test.go
generated
vendored
Normal file
@@ -0,0 +1,250 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGitService_GetRef(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/git/refs/heads/b", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `
|
||||||
|
{
|
||||||
|
"ref": "refs/heads/b",
|
||||||
|
"url": "https://api.github.com/repos/o/r/git/refs/heads/b",
|
||||||
|
"object": {
|
||||||
|
"type": "commit",
|
||||||
|
"sha": "aa218f56b14c9653891f9e74264a383fa43fefbd",
|
||||||
|
"url": "https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd"
|
||||||
|
}
|
||||||
|
}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
ref, _, err := client.Git.GetRef("o", "r", "heads/b")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Git.GetRef returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Reference{
|
||||||
|
Ref: String("refs/heads/b"),
|
||||||
|
URL: String("https://api.github.com/repos/o/r/git/refs/heads/b"),
|
||||||
|
Object: &GitObject{
|
||||||
|
Type: String("commit"),
|
||||||
|
SHA: String("aa218f56b14c9653891f9e74264a383fa43fefbd"),
|
||||||
|
URL: String("https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(ref, want) {
|
||||||
|
t.Errorf("Git.GetRef returned %+v, want %+v", ref, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGitService_ListRefs(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/git/refs", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"ref": "refs/heads/branchA",
|
||||||
|
"url": "https://api.github.com/repos/o/r/git/refs/heads/branchA",
|
||||||
|
"object": {
|
||||||
|
"type": "commit",
|
||||||
|
"sha": "aa218f56b14c9653891f9e74264a383fa43fefbd",
|
||||||
|
"url": "https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ref": "refs/heads/branchB",
|
||||||
|
"url": "https://api.github.com/repos/o/r/git/refs/heads/branchB",
|
||||||
|
"object": {
|
||||||
|
"type": "commit",
|
||||||
|
"sha": "aa218f56b14c9653891f9e74264a383fa43fefbd",
|
||||||
|
"url": "https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
refs, _, err := client.Git.ListRefs("o", "r", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Git.ListRefs returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Reference{
|
||||||
|
{
|
||||||
|
Ref: String("refs/heads/branchA"),
|
||||||
|
URL: String("https://api.github.com/repos/o/r/git/refs/heads/branchA"),
|
||||||
|
Object: &GitObject{
|
||||||
|
Type: String("commit"),
|
||||||
|
SHA: String("aa218f56b14c9653891f9e74264a383fa43fefbd"),
|
||||||
|
URL: String("https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Ref: String("refs/heads/branchB"),
|
||||||
|
URL: String("https://api.github.com/repos/o/r/git/refs/heads/branchB"),
|
||||||
|
Object: &GitObject{
|
||||||
|
Type: String("commit"),
|
||||||
|
SHA: String("aa218f56b14c9653891f9e74264a383fa43fefbd"),
|
||||||
|
URL: String("https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(refs, want) {
|
||||||
|
t.Errorf("Git.ListRefs returned %+v, want %+v", refs, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGitService_ListRefs_options(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/git/refs/t", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{"page": "2"})
|
||||||
|
fmt.Fprint(w, `[{"ref": "r"}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ReferenceListOptions{Type: "t", ListOptions: ListOptions{Page: 2}}
|
||||||
|
refs, _, err := client.Git.ListRefs("o", "r", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Git.ListRefs returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Reference{{Ref: String("r")}}
|
||||||
|
if !reflect.DeepEqual(refs, want) {
|
||||||
|
t.Errorf("Git.ListRefs returned %+v, want %+v", refs, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGitService_CreateRef(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
args := &createRefRequest{
|
||||||
|
Ref: String("refs/heads/b"),
|
||||||
|
SHA: String("aa218f56b14c9653891f9e74264a383fa43fefbd"),
|
||||||
|
}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/git/refs", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(createRefRequest)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(v, args) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, args)
|
||||||
|
}
|
||||||
|
fmt.Fprint(w, `
|
||||||
|
{
|
||||||
|
"ref": "refs/heads/b",
|
||||||
|
"url": "https://api.github.com/repos/o/r/git/refs/heads/b",
|
||||||
|
"object": {
|
||||||
|
"type": "commit",
|
||||||
|
"sha": "aa218f56b14c9653891f9e74264a383fa43fefbd",
|
||||||
|
"url": "https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd"
|
||||||
|
}
|
||||||
|
}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
ref, _, err := client.Git.CreateRef("o", "r", &Reference{
|
||||||
|
Ref: String("heads/b"),
|
||||||
|
Object: &GitObject{
|
||||||
|
SHA: String("aa218f56b14c9653891f9e74264a383fa43fefbd"),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Git.CreateRef returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Reference{
|
||||||
|
Ref: String("refs/heads/b"),
|
||||||
|
URL: String("https://api.github.com/repos/o/r/git/refs/heads/b"),
|
||||||
|
Object: &GitObject{
|
||||||
|
Type: String("commit"),
|
||||||
|
SHA: String("aa218f56b14c9653891f9e74264a383fa43fefbd"),
|
||||||
|
URL: String("https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(ref, want) {
|
||||||
|
t.Errorf("Git.CreateRef returned %+v, want %+v", ref, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGitService_UpdateRef(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
args := &updateRefRequest{
|
||||||
|
SHA: String("aa218f56b14c9653891f9e74264a383fa43fefbd"),
|
||||||
|
Force: Bool(true),
|
||||||
|
}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/git/refs/heads/b", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(updateRefRequest)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "PATCH")
|
||||||
|
if !reflect.DeepEqual(v, args) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, args)
|
||||||
|
}
|
||||||
|
fmt.Fprint(w, `
|
||||||
|
{
|
||||||
|
"ref": "refs/heads/b",
|
||||||
|
"url": "https://api.github.com/repos/o/r/git/refs/heads/b",
|
||||||
|
"object": {
|
||||||
|
"type": "commit",
|
||||||
|
"sha": "aa218f56b14c9653891f9e74264a383fa43fefbd",
|
||||||
|
"url": "https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd"
|
||||||
|
}
|
||||||
|
}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
ref, _, err := client.Git.UpdateRef("o", "r", &Reference{
|
||||||
|
Ref: String("heads/b"),
|
||||||
|
Object: &GitObject{SHA: String("aa218f56b14c9653891f9e74264a383fa43fefbd")},
|
||||||
|
}, true)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Git.UpdateRef returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Reference{
|
||||||
|
Ref: String("refs/heads/b"),
|
||||||
|
URL: String("https://api.github.com/repos/o/r/git/refs/heads/b"),
|
||||||
|
Object: &GitObject{
|
||||||
|
Type: String("commit"),
|
||||||
|
SHA: String("aa218f56b14c9653891f9e74264a383fa43fefbd"),
|
||||||
|
URL: String("https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(ref, want) {
|
||||||
|
t.Errorf("Git.UpdateRef returned %+v, want %+v", ref, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGitService_DeleteRef(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/git/refs/heads/b", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Git.DeleteRef("o", "r", "heads/b")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Git.DeleteRef returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
73
Godeps/_workspace/src/github.com/google/go-github/github/git_tags.go
generated
vendored
Normal file
73
Godeps/_workspace/src/github.com/google/go-github/github/git_tags.go
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
// 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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Tag represents a tag object.
|
||||||
|
type Tag struct {
|
||||||
|
Tag *string `json:"tag,omitempty"`
|
||||||
|
SHA *string `json:"sha,omitempty"`
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
Message *string `json:"message,omitempty"`
|
||||||
|
Tagger *CommitAuthor `json:"tagger,omitempty"`
|
||||||
|
Object *GitObject `json:"object,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// createTagRequest represents the body of a CreateTag request. This is mostly
|
||||||
|
// identical to Tag with the exception that the object SHA and Type are
|
||||||
|
// top-level fields, rather than being nested inside a JSON object.
|
||||||
|
type createTagRequest struct {
|
||||||
|
Tag *string `json:"tag,omitempty"`
|
||||||
|
Message *string `json:"message,omitempty"`
|
||||||
|
Object *string `json:"object,omitempty"`
|
||||||
|
Type *string `json:"type,omitempty"`
|
||||||
|
Tagger *CommitAuthor `json:"tagger,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTag fetchs a tag from a repo given a SHA.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/git/tags/#get-a-tag
|
||||||
|
func (s *GitService) GetTag(owner string, repo string, sha string) (*Tag, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/git/tags/%v", owner, repo, sha)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tag := new(Tag)
|
||||||
|
resp, err := s.client.Do(req, tag)
|
||||||
|
return tag, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateTag creates a tag object.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/git/tags/#create-a-tag-object
|
||||||
|
func (s *GitService) CreateTag(owner string, repo string, tag *Tag) (*Tag, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/git/tags", owner, repo)
|
||||||
|
|
||||||
|
// convert Tag into a createTagRequest
|
||||||
|
tagRequest := &createTagRequest{
|
||||||
|
Tag: tag.Tag,
|
||||||
|
Message: tag.Message,
|
||||||
|
Tagger: tag.Tagger,
|
||||||
|
}
|
||||||
|
if tag.Object != nil {
|
||||||
|
tagRequest.Object = tag.Object.SHA
|
||||||
|
tagRequest.Type = tag.Object.Type
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("POST", u, tagRequest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
t := new(Tag)
|
||||||
|
resp, err := s.client.Do(req, t)
|
||||||
|
return t, resp, err
|
||||||
|
}
|
||||||
68
Godeps/_workspace/src/github.com/google/go-github/github/git_tags_test.go
generated
vendored
Normal file
68
Godeps/_workspace/src/github.com/google/go-github/github/git_tags_test.go
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGitService_GetTag(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/git/tags/s", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"tag": "t"}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
tag, _, err := client.Git.GetTag("o", "r", "s")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Git.GetTag returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Tag{Tag: String("t")}
|
||||||
|
if !reflect.DeepEqual(tag, want) {
|
||||||
|
t.Errorf("Git.GetTag returned %+v, want %+v", tag, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGitService_CreateTag(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &createTagRequest{Tag: String("t"), Object: String("s")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/git/tags", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(createTagRequest)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"tag": "t"}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
tag, _, err := client.Git.CreateTag("o", "r", &Tag{
|
||||||
|
Tag: input.Tag,
|
||||||
|
Object: &GitObject{SHA: input.Object},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Git.CreateTag returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Tag{Tag: String("t")}
|
||||||
|
if !reflect.DeepEqual(tag, want) {
|
||||||
|
t.Errorf("Git.GetTag returned %+v, want %+v", tag, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
88
Godeps/_workspace/src/github.com/google/go-github/github/git_trees.go
generated
vendored
Normal file
88
Godeps/_workspace/src/github.com/google/go-github/github/git_trees.go
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
// 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"
|
||||||
|
|
||||||
|
// Tree represents a GitHub tree.
|
||||||
|
type Tree struct {
|
||||||
|
SHA *string `json:"sha,omitempty"`
|
||||||
|
Entries []TreeEntry `json:"tree,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t Tree) String() string {
|
||||||
|
return Stringify(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TreeEntry represents the contents of a tree structure. TreeEntry can
|
||||||
|
// represent either a blob, a commit (in the case of a submodule), or another
|
||||||
|
// tree.
|
||||||
|
type TreeEntry struct {
|
||||||
|
SHA *string `json:"sha,omitempty"`
|
||||||
|
Path *string `json:"path,omitempty"`
|
||||||
|
Mode *string `json:"mode,omitempty"`
|
||||||
|
Type *string `json:"type,omitempty"`
|
||||||
|
Size *int `json:"size,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t TreeEntry) String() string {
|
||||||
|
return Stringify(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTree fetches the Tree object for a given sha hash from a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/git/trees/#get-a-tree
|
||||||
|
func (s *GitService) GetTree(owner string, repo string, sha string, recursive bool) (*Tree, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/git/trees/%v", owner, repo, sha)
|
||||||
|
if recursive {
|
||||||
|
u += "?recursive=1"
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
t := new(Tree)
|
||||||
|
resp, err := s.client.Do(req, t)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return t, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// createTree represents the body of a CreateTree request.
|
||||||
|
type createTree struct {
|
||||||
|
BaseTree string `json:"base_tree"`
|
||||||
|
Entries []TreeEntry `json:"tree"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateTree creates a new tree in a repository. If both a tree and a nested
|
||||||
|
// path modifying that tree are specified, it will overwrite the contents of
|
||||||
|
// that tree with the new path contents and write a new tree out.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/git/trees/#create-a-tree
|
||||||
|
func (s *GitService) CreateTree(owner string, repo string, baseTree string, entries []TreeEntry) (*Tree, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/git/trees", owner, repo)
|
||||||
|
|
||||||
|
body := &createTree{
|
||||||
|
BaseTree: baseTree,
|
||||||
|
Entries: entries,
|
||||||
|
}
|
||||||
|
req, err := s.client.NewRequest("POST", u, body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
t := new(Tree)
|
||||||
|
resp, err := s.client.Do(req, t)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return t, resp, err
|
||||||
|
}
|
||||||
122
Godeps/_workspace/src/github.com/google/go-github/github/git_trees_test.go
generated
vendored
Normal file
122
Godeps/_workspace/src/github.com/google/go-github/github/git_trees_test.go
generated
vendored
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGitService_GetTree(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/git/trees/s", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if m := "GET"; m != r.Method {
|
||||||
|
t.Errorf("Request method = %v, want %v", r.Method, m)
|
||||||
|
}
|
||||||
|
fmt.Fprint(w, `{
|
||||||
|
"sha": "s",
|
||||||
|
"tree": [ { "type": "blob" } ]
|
||||||
|
}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
tree, _, err := client.Git.GetTree("o", "r", "s", true)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Git.GetTree returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := Tree{
|
||||||
|
SHA: String("s"),
|
||||||
|
Entries: []TreeEntry{
|
||||||
|
{
|
||||||
|
Type: String("blob"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(*tree, want) {
|
||||||
|
t.Errorf("Tree.Get returned %+v, want %+v", *tree, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGitService_GetTree_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Git.GetTree("%", "%", "%", false)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGitService_CreateTree(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := []TreeEntry{
|
||||||
|
{
|
||||||
|
Path: String("file.rb"),
|
||||||
|
Mode: String("100644"),
|
||||||
|
Type: String("blob"),
|
||||||
|
SHA: String("7c258a9869f33c1e1e1f74fbb32f07c86cb5a75b"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/git/trees", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(createTree)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
if m := "POST"; m != r.Method {
|
||||||
|
t.Errorf("Request method = %v, want %v", r.Method, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &createTree{
|
||||||
|
BaseTree: "b",
|
||||||
|
Entries: input,
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(v, want) {
|
||||||
|
t.Errorf("Git.CreateTree request body: %+v, want %+v", v, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{
|
||||||
|
"sha": "cd8274d15fa3ae2ab983129fb037999f264ba9a7",
|
||||||
|
"tree": [
|
||||||
|
{
|
||||||
|
"path": "file.rb",
|
||||||
|
"mode": "100644",
|
||||||
|
"type": "blob",
|
||||||
|
"size": 132,
|
||||||
|
"sha": "7c258a9869f33c1e1e1f74fbb32f07c86cb5a75b"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
tree, _, err := client.Git.CreateTree("o", "r", "b", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Git.CreateTree returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := Tree{
|
||||||
|
String("cd8274d15fa3ae2ab983129fb037999f264ba9a7"),
|
||||||
|
[]TreeEntry{
|
||||||
|
{
|
||||||
|
Path: String("file.rb"),
|
||||||
|
Mode: String("100644"),
|
||||||
|
Type: String("blob"),
|
||||||
|
Size: Int(132),
|
||||||
|
SHA: String("7c258a9869f33c1e1e1f74fbb32f07c86cb5a75b"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(*tree, want) {
|
||||||
|
t.Errorf("Git.CreateTree returned %+v, want %+v", *tree, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGitService_CreateTree_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Git.CreateTree("%", "%", "", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
557
Godeps/_workspace/src/github.com/google/go-github/github/github.go
generated
vendored
Normal file
557
Godeps/_workspace/src/github.com/google/go-github/github/github.go
generated
vendored
Normal file
@@ -0,0 +1,557 @@
|
|||||||
|
// 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 (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
libraryVersion = "0.1"
|
||||||
|
defaultBaseURL = "https://api.github.com/"
|
||||||
|
uploadBaseURL = "https://uploads.github.com/"
|
||||||
|
userAgent = "go-github/" + libraryVersion
|
||||||
|
|
||||||
|
headerRateLimit = "X-RateLimit-Limit"
|
||||||
|
headerRateRemaining = "X-RateLimit-Remaining"
|
||||||
|
headerRateReset = "X-RateLimit-Reset"
|
||||||
|
|
||||||
|
mediaTypeV3 = "application/vnd.github.v3+json"
|
||||||
|
defaultMediaType = "application/octet-stream"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Client manages communication with the GitHub API.
|
||||||
|
type Client struct {
|
||||||
|
// HTTP client used to communicate with the API.
|
||||||
|
client *http.Client
|
||||||
|
|
||||||
|
// Base URL for API requests. Defaults to the public GitHub API, but can be
|
||||||
|
// set to a domain endpoint to use with GitHub Enterprise. BaseURL should
|
||||||
|
// always be specified with a trailing slash.
|
||||||
|
BaseURL *url.URL
|
||||||
|
|
||||||
|
// Base URL for uploading files.
|
||||||
|
UploadURL *url.URL
|
||||||
|
|
||||||
|
// User agent used when communicating with the GitHub API.
|
||||||
|
UserAgent string
|
||||||
|
|
||||||
|
// Rate specifies the current rate limit for the client as determined by the
|
||||||
|
// most recent API call. If the client is used in a multi-user application,
|
||||||
|
// this rate may not always be up-to-date. Call RateLimit() to check the
|
||||||
|
// current rate.
|
||||||
|
Rate Rate
|
||||||
|
|
||||||
|
// Services used for talking to different parts of the GitHub API.
|
||||||
|
Activity *ActivityService
|
||||||
|
Gists *GistsService
|
||||||
|
Git *GitService
|
||||||
|
Gitignores *GitignoresService
|
||||||
|
Issues *IssuesService
|
||||||
|
Organizations *OrganizationsService
|
||||||
|
PullRequests *PullRequestsService
|
||||||
|
Repositories *RepositoriesService
|
||||||
|
Search *SearchService
|
||||||
|
Users *UsersService
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOptions specifies the optional parameters to various List methods that
|
||||||
|
// support pagination.
|
||||||
|
type ListOptions struct {
|
||||||
|
// For paginated result sets, page of results to retrieve.
|
||||||
|
Page int `url:"page,omitempty"`
|
||||||
|
|
||||||
|
// For paginated result sets, the number of results to include per page.
|
||||||
|
PerPage int `url:"per_page,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UploadOptions specifies the parameters to methods that support uploads.
|
||||||
|
type UploadOptions struct {
|
||||||
|
Name string `url:"name,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// addOptions adds the parameters in opt as URL query parameters to s. opt
|
||||||
|
// must be a struct whose fields may contain "url" tags.
|
||||||
|
func addOptions(s string, opt interface{}) (string, error) {
|
||||||
|
v := reflect.ValueOf(opt)
|
||||||
|
if v.Kind() == reflect.Ptr && v.IsNil() {
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(s)
|
||||||
|
if err != nil {
|
||||||
|
return s, err
|
||||||
|
}
|
||||||
|
|
||||||
|
qs, err := query.Values(opt)
|
||||||
|
if err != nil {
|
||||||
|
return s, err
|
||||||
|
}
|
||||||
|
|
||||||
|
u.RawQuery = qs.Encode()
|
||||||
|
return u.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClient returns a new GitHub API client. If a nil httpClient is
|
||||||
|
// provided, http.DefaultClient will be used. To use API methods which require
|
||||||
|
// authentication, provide an http.Client that will perform the authentication
|
||||||
|
// for you (such as that provided by the goauth2 library).
|
||||||
|
func NewClient(httpClient *http.Client) *Client {
|
||||||
|
if httpClient == nil {
|
||||||
|
httpClient = http.DefaultClient
|
||||||
|
}
|
||||||
|
baseURL, _ := url.Parse(defaultBaseURL)
|
||||||
|
uploadURL, _ := url.Parse(uploadBaseURL)
|
||||||
|
|
||||||
|
c := &Client{client: httpClient, BaseURL: baseURL, UserAgent: userAgent, UploadURL: uploadURL}
|
||||||
|
c.Activity = &ActivityService{client: c}
|
||||||
|
c.Gists = &GistsService{client: c}
|
||||||
|
c.Git = &GitService{client: c}
|
||||||
|
c.Gitignores = &GitignoresService{client: c}
|
||||||
|
c.Issues = &IssuesService{client: c}
|
||||||
|
c.Organizations = &OrganizationsService{client: c}
|
||||||
|
c.PullRequests = &PullRequestsService{client: c}
|
||||||
|
c.Repositories = &RepositoriesService{client: c}
|
||||||
|
c.Search = &SearchService{client: c}
|
||||||
|
c.Users = &UsersService{client: c}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRequest creates an API request. A relative URL can be provided in urlStr,
|
||||||
|
// in which case it is resolved relative to the BaseURL of the Client.
|
||||||
|
// Relative URLs should always be specified without a preceding slash. If
|
||||||
|
// specified, the value pointed to by body is JSON encoded and included as the
|
||||||
|
// request body.
|
||||||
|
func (c *Client) NewRequest(method, urlStr string, body interface{}) (*http.Request, error) {
|
||||||
|
rel, err := url.Parse(urlStr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
u := c.BaseURL.ResolveReference(rel)
|
||||||
|
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
if body != nil {
|
||||||
|
err := json.NewEncoder(buf).Encode(body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest(method, u.String(), buf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Add("Accept", mediaTypeV3)
|
||||||
|
req.Header.Add("User-Agent", c.UserAgent)
|
||||||
|
return req, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUploadRequest creates an upload request. A relative URL can be provided in
|
||||||
|
// urlStr, in which case it is resolved relative to the UploadURL of the Client.
|
||||||
|
// Relative URLs should always be specified without a preceding slash.
|
||||||
|
func (c *Client) NewUploadRequest(urlStr string, reader io.Reader, size int64, mediaType string) (*http.Request, error) {
|
||||||
|
rel, err := url.Parse(urlStr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
u := c.UploadURL.ResolveReference(rel)
|
||||||
|
req, err := http.NewRequest("POST", u.String(), reader)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.ContentLength = size
|
||||||
|
|
||||||
|
if len(mediaType) == 0 {
|
||||||
|
mediaType = defaultMediaType
|
||||||
|
}
|
||||||
|
req.Header.Add("Content-Type", mediaType)
|
||||||
|
req.Header.Add("Accept", mediaTypeV3)
|
||||||
|
req.Header.Add("User-Agent", c.UserAgent)
|
||||||
|
return req, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Response is a GitHub API response. This wraps the standard http.Response
|
||||||
|
// returned from GitHub and provides convenient access to things like
|
||||||
|
// pagination links.
|
||||||
|
type Response struct {
|
||||||
|
*http.Response
|
||||||
|
|
||||||
|
// These fields provide the page values for paginating through a set of
|
||||||
|
// results. Any or all of these may be set to the zero value for
|
||||||
|
// responses that are not part of a paginated set, or for which there
|
||||||
|
// are no additional pages.
|
||||||
|
|
||||||
|
NextPage int
|
||||||
|
PrevPage int
|
||||||
|
FirstPage int
|
||||||
|
LastPage int
|
||||||
|
|
||||||
|
Rate
|
||||||
|
}
|
||||||
|
|
||||||
|
// newResponse creats a new Response for the provided http.Response.
|
||||||
|
func newResponse(r *http.Response) *Response {
|
||||||
|
response := &Response{Response: r}
|
||||||
|
response.populatePageValues()
|
||||||
|
response.populateRate()
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
// populatePageValues parses the HTTP Link response headers and populates the
|
||||||
|
// various pagination link values in the Reponse.
|
||||||
|
func (r *Response) populatePageValues() {
|
||||||
|
if links, ok := r.Response.Header["Link"]; ok && len(links) > 0 {
|
||||||
|
for _, link := range strings.Split(links[0], ",") {
|
||||||
|
segments := strings.Split(strings.TrimSpace(link), ";")
|
||||||
|
|
||||||
|
// link must at least have href and rel
|
||||||
|
if len(segments) < 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure href is properly formatted
|
||||||
|
if !strings.HasPrefix(segments[0], "<") || !strings.HasSuffix(segments[0], ">") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to pull out page parameter
|
||||||
|
url, err := url.Parse(segments[0][1 : len(segments[0])-1])
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
page := url.Query().Get("page")
|
||||||
|
if page == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, segment := range segments[1:] {
|
||||||
|
switch strings.TrimSpace(segment) {
|
||||||
|
case `rel="next"`:
|
||||||
|
r.NextPage, _ = strconv.Atoi(page)
|
||||||
|
case `rel="prev"`:
|
||||||
|
r.PrevPage, _ = strconv.Atoi(page)
|
||||||
|
case `rel="first"`:
|
||||||
|
r.FirstPage, _ = strconv.Atoi(page)
|
||||||
|
case `rel="last"`:
|
||||||
|
r.LastPage, _ = strconv.Atoi(page)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// populateRate parses the rate related headers and populates the response Rate.
|
||||||
|
func (r *Response) populateRate() {
|
||||||
|
if limit := r.Header.Get(headerRateLimit); limit != "" {
|
||||||
|
r.Rate.Limit, _ = strconv.Atoi(limit)
|
||||||
|
}
|
||||||
|
if remaining := r.Header.Get(headerRateRemaining); remaining != "" {
|
||||||
|
r.Rate.Remaining, _ = strconv.Atoi(remaining)
|
||||||
|
}
|
||||||
|
if reset := r.Header.Get(headerRateReset); reset != "" {
|
||||||
|
if v, _ := strconv.ParseInt(reset, 10, 64); v != 0 {
|
||||||
|
r.Rate.Reset = Timestamp{time.Unix(v, 0)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do sends an API request and returns the API response. The API response is
|
||||||
|
// JSON decoded and stored in the value pointed to by v, or returned as an
|
||||||
|
// error if an API error has occurred. If v implements the io.Writer
|
||||||
|
// interface, the raw response body will be written to v, without attempting to
|
||||||
|
// first decode it.
|
||||||
|
func (c *Client) Do(req *http.Request, v interface{}) (*Response, error) {
|
||||||
|
resp, err := c.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
response := newResponse(resp)
|
||||||
|
|
||||||
|
c.Rate = response.Rate
|
||||||
|
|
||||||
|
err = CheckResponse(resp)
|
||||||
|
if err != nil {
|
||||||
|
// even though there was an error, we still return the response
|
||||||
|
// in case the caller wants to inspect it further
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if v != nil {
|
||||||
|
if w, ok := v.(io.Writer); ok {
|
||||||
|
io.Copy(w, resp.Body)
|
||||||
|
} else {
|
||||||
|
err = json.NewDecoder(resp.Body).Decode(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
An ErrorResponse reports one or more errors caused by an API request.
|
||||||
|
|
||||||
|
GitHub API docs: http://developer.github.com/v3/#client-errors
|
||||||
|
*/
|
||||||
|
type ErrorResponse struct {
|
||||||
|
Response *http.Response // HTTP response that caused this error
|
||||||
|
Message string `json:"message"` // error message
|
||||||
|
Errors []Error `json:"errors"` // more detail on individual errors
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ErrorResponse) Error() string {
|
||||||
|
return fmt.Sprintf("%v %v: %d %v %+v",
|
||||||
|
r.Response.Request.Method, r.Response.Request.URL,
|
||||||
|
r.Response.StatusCode, r.Message, r.Errors)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
An Error reports more details on an individual error in an ErrorResponse.
|
||||||
|
These are the possible validation error codes:
|
||||||
|
|
||||||
|
missing:
|
||||||
|
resource does not exist
|
||||||
|
missing_field:
|
||||||
|
a required field on a resource has not been set
|
||||||
|
invalid:
|
||||||
|
the formatting of a field is invalid
|
||||||
|
already_exists:
|
||||||
|
another resource has the same valid as this field
|
||||||
|
|
||||||
|
GitHub API docs: http://developer.github.com/v3/#client-errors
|
||||||
|
*/
|
||||||
|
type Error struct {
|
||||||
|
Resource string `json:"resource"` // resource on which the error occurred
|
||||||
|
Field string `json:"field"` // field on which the error occurred
|
||||||
|
Code string `json:"code"` // validation error code
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Error) Error() string {
|
||||||
|
return fmt.Sprintf("%v error caused by %v field on %v resource",
|
||||||
|
e.Code, e.Field, e.Resource)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckResponse checks the API response for errors, and returns them if
|
||||||
|
// present. A response is considered an error if it has a status code outside
|
||||||
|
// the 200 range. API error responses are expected to have either no response
|
||||||
|
// body, or a JSON response body that maps to ErrorResponse. Any other
|
||||||
|
// response body will be silently ignored.
|
||||||
|
func CheckResponse(r *http.Response) error {
|
||||||
|
if c := r.StatusCode; 200 <= c && c <= 299 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
errorResponse := &ErrorResponse{Response: r}
|
||||||
|
data, err := ioutil.ReadAll(r.Body)
|
||||||
|
if err == nil && data != nil {
|
||||||
|
json.Unmarshal(data, errorResponse)
|
||||||
|
}
|
||||||
|
return errorResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseBoolResponse determines the boolean result from a GitHub API response.
|
||||||
|
// Several GitHub API methods return boolean responses indicated by the HTTP
|
||||||
|
// status code in the response (true indicated by a 204, false indicated by a
|
||||||
|
// 404). This helper function will determine that result and hide the 404
|
||||||
|
// error if present. Any other error will be returned through as-is.
|
||||||
|
func parseBoolResponse(err error) (bool, error) {
|
||||||
|
if err == nil {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err, ok := err.(*ErrorResponse); ok && err.Response.StatusCode == http.StatusNotFound {
|
||||||
|
// Simply false. In this one case, we do not pass the error through.
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// some other real error occurred
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rate represents the rate limit for the current client.
|
||||||
|
type Rate struct {
|
||||||
|
// The number of requests per hour the client is currently limited to.
|
||||||
|
Limit int `json:"limit"`
|
||||||
|
|
||||||
|
// The number of remaining requests the client can make this hour.
|
||||||
|
Remaining int `json:"remaining"`
|
||||||
|
|
||||||
|
// The time at which the current rate limit will reset.
|
||||||
|
Reset Timestamp `json:"reset"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r Rate) String() string {
|
||||||
|
return Stringify(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RateLimits represents the rate limits for the current client.
|
||||||
|
type RateLimits struct {
|
||||||
|
// The rate limit for non-search API requests. Unauthenticated
|
||||||
|
// requests are limited to 60 per hour. Authenticated requests are
|
||||||
|
// limited to 5,000 per hour.
|
||||||
|
Core *Rate `json:"core"`
|
||||||
|
|
||||||
|
// The rate limit for search API requests. Unauthenticated requests
|
||||||
|
// are limited to 5 requests per minutes. Authenticated requests are
|
||||||
|
// limited to 20 per minute.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/search/#rate-limit
|
||||||
|
Search *Rate `json:"search"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r RateLimits) String() string {
|
||||||
|
return Stringify(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RateLimit is deprecated. Use RateLimits instead.
|
||||||
|
func (c *Client) RateLimit() (*Rate, *Response, error) {
|
||||||
|
limits, resp, err := c.RateLimits()
|
||||||
|
if limits == nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return limits.Core, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RateLimits returns the rate limits for the current client.
|
||||||
|
func (c *Client) RateLimits() (*RateLimits, *Response, error) {
|
||||||
|
req, err := c.NewRequest("GET", "rate_limit", nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
response := new(struct {
|
||||||
|
Resources *RateLimits `json:"resources"`
|
||||||
|
})
|
||||||
|
resp, err := c.Do(req, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.Resources, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
UnauthenticatedRateLimitedTransport allows you to make unauthenticated calls
|
||||||
|
that need to use a higher rate limit associated with your OAuth application.
|
||||||
|
|
||||||
|
t := &github.UnauthenticatedRateLimitedTransport{
|
||||||
|
ClientID: "your app's client ID",
|
||||||
|
ClientSecret: "your app's client secret",
|
||||||
|
}
|
||||||
|
client := github.NewClient(t.Client())
|
||||||
|
|
||||||
|
This will append the querystring params client_id=xxx&client_secret=yyy to all
|
||||||
|
requests.
|
||||||
|
|
||||||
|
See http://developer.github.com/v3/#unauthenticated-rate-limited-requests for
|
||||||
|
more information.
|
||||||
|
*/
|
||||||
|
type UnauthenticatedRateLimitedTransport struct {
|
||||||
|
// ClientID is the GitHub OAuth client ID of the current application, which
|
||||||
|
// can be found by selecting its entry in the list at
|
||||||
|
// https://github.com/settings/applications.
|
||||||
|
ClientID string
|
||||||
|
|
||||||
|
// ClientSecret is the GitHub OAuth client secret of the current
|
||||||
|
// application.
|
||||||
|
ClientSecret string
|
||||||
|
|
||||||
|
// Transport is the underlying HTTP transport to use when making requests.
|
||||||
|
// It will default to http.DefaultTransport if nil.
|
||||||
|
Transport http.RoundTripper
|
||||||
|
}
|
||||||
|
|
||||||
|
// RoundTrip implements the RoundTripper interface.
|
||||||
|
func (t *UnauthenticatedRateLimitedTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
|
if t.ClientID == "" {
|
||||||
|
return nil, errors.New("ClientID is empty")
|
||||||
|
}
|
||||||
|
if t.ClientSecret == "" {
|
||||||
|
return nil, errors.New("ClientSecret is empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
// To set extra querystring params, we must make a copy of the Request so
|
||||||
|
// that we don't modify the Request we were given. This is required by the
|
||||||
|
// specification of http.RoundTripper.
|
||||||
|
req = cloneRequest(req)
|
||||||
|
q := req.URL.Query()
|
||||||
|
q.Set("client_id", t.ClientID)
|
||||||
|
q.Set("client_secret", t.ClientSecret)
|
||||||
|
req.URL.RawQuery = q.Encode()
|
||||||
|
|
||||||
|
// Make the HTTP request.
|
||||||
|
return t.transport().RoundTrip(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client returns an *http.Client that makes requests which are subject to the
|
||||||
|
// rate limit of your OAuth application.
|
||||||
|
func (t *UnauthenticatedRateLimitedTransport) Client() *http.Client {
|
||||||
|
return &http.Client{Transport: t}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *UnauthenticatedRateLimitedTransport) transport() http.RoundTripper {
|
||||||
|
if t.Transport != nil {
|
||||||
|
return t.Transport
|
||||||
|
}
|
||||||
|
return http.DefaultTransport
|
||||||
|
}
|
||||||
|
|
||||||
|
// cloneRequest returns a clone of the provided *http.Request. The clone is a
|
||||||
|
// shallow copy of the struct and its Header map.
|
||||||
|
func cloneRequest(r *http.Request) *http.Request {
|
||||||
|
// shallow copy of the struct
|
||||||
|
r2 := new(http.Request)
|
||||||
|
*r2 = *r
|
||||||
|
// deep copy of the Header
|
||||||
|
r2.Header = make(http.Header)
|
||||||
|
for k, s := range r.Header {
|
||||||
|
r2.Header[k] = s
|
||||||
|
}
|
||||||
|
return r2
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bool is a helper routine that allocates a new bool value
|
||||||
|
// to store v and returns a pointer to it.
|
||||||
|
func Bool(v bool) *bool {
|
||||||
|
p := new(bool)
|
||||||
|
*p = v
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int is a helper routine that allocates a new int32 value
|
||||||
|
// to store v and returns a pointer to it, but unlike Int32
|
||||||
|
// its argument value is an int.
|
||||||
|
func Int(v int) *int {
|
||||||
|
p := new(int)
|
||||||
|
*p = v
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// String is a helper routine that allocates a new string value
|
||||||
|
// to store v and returns a pointer to it.
|
||||||
|
func String(v string) *string {
|
||||||
|
p := new(string)
|
||||||
|
*p = v
|
||||||
|
return p
|
||||||
|
}
|
||||||
635
Godeps/_workspace/src/github.com/google/go-github/github/github_test.go
generated
vendored
Normal file
635
Godeps/_workspace/src/github.com/google/go-github/github/github_test.go
generated
vendored
Normal file
@@ -0,0 +1,635 @@
|
|||||||
|
// 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 (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// mux is the HTTP request multiplexer used with the test server.
|
||||||
|
mux *http.ServeMux
|
||||||
|
|
||||||
|
// client is the GitHub client being tested.
|
||||||
|
client *Client
|
||||||
|
|
||||||
|
// server is a test HTTP server used to provide mock API responses.
|
||||||
|
server *httptest.Server
|
||||||
|
)
|
||||||
|
|
||||||
|
// setup sets up a test HTTP server along with a github.Client that is
|
||||||
|
// configured to talk to that test server. Tests should register handlers on
|
||||||
|
// mux which provide mock responses for the API method being tested.
|
||||||
|
func setup() {
|
||||||
|
// test server
|
||||||
|
mux = http.NewServeMux()
|
||||||
|
server = httptest.NewServer(mux)
|
||||||
|
|
||||||
|
// github client configured to use test server
|
||||||
|
client = NewClient(nil)
|
||||||
|
url, _ := url.Parse(server.URL)
|
||||||
|
client.BaseURL = url
|
||||||
|
client.UploadURL = url
|
||||||
|
}
|
||||||
|
|
||||||
|
// teardown closes the test HTTP server.
|
||||||
|
func teardown() {
|
||||||
|
server.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// openTestFile creates a new file with the given name and content for testing.
|
||||||
|
// In order to ensure the exact file name, this function will create a new temp
|
||||||
|
// directory, and create the file in that directory. It is the caller's
|
||||||
|
// responsibility to remove the directy and its contents when no longer needed.
|
||||||
|
func openTestFile(name, content string) (file *os.File, dir string, err error) {
|
||||||
|
dir, err = ioutil.TempDir("", "go-github")
|
||||||
|
if err != nil {
|
||||||
|
return nil, dir, err
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err = os.OpenFile(path.Join(dir, name), os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
|
||||||
|
if err != nil {
|
||||||
|
return nil, dir, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(file, content)
|
||||||
|
|
||||||
|
// close and re-open the file to keep file.Stat() happy
|
||||||
|
file.Close()
|
||||||
|
file, err = os.Open(file.Name())
|
||||||
|
if err != nil {
|
||||||
|
return nil, dir, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return file, dir, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func testMethod(t *testing.T, r *http.Request, want string) {
|
||||||
|
if want != r.Method {
|
||||||
|
t.Errorf("Request method = %v, want %v", r.Method, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type values map[string]string
|
||||||
|
|
||||||
|
func testFormValues(t *testing.T, r *http.Request, values values) {
|
||||||
|
want := url.Values{}
|
||||||
|
for k, v := range values {
|
||||||
|
want.Add(k, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
r.ParseForm()
|
||||||
|
if !reflect.DeepEqual(want, r.Form) {
|
||||||
|
t.Errorf("Request parameters = %v, want %v", r.Form, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testHeader(t *testing.T, r *http.Request, header string, want string) {
|
||||||
|
if value := r.Header.Get(header); want != value {
|
||||||
|
t.Errorf("Header %s = %s, want: %s", header, value, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testURLParseError(t *testing.T, err error) {
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected error to be returned")
|
||||||
|
}
|
||||||
|
if err, ok := err.(*url.Error); !ok || err.Op != "parse" {
|
||||||
|
t.Errorf("Expected URL parse error, got %+v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testBody(t *testing.T, r *http.Request, want string) {
|
||||||
|
b, err := ioutil.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unable to read body")
|
||||||
|
}
|
||||||
|
str := string(b)
|
||||||
|
if want != str {
|
||||||
|
t.Errorf("Body = %s, want: %s", str, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to test that a value is marshalled to JSON as expected.
|
||||||
|
func testJSONMarshal(t *testing.T, v interface{}, want string) {
|
||||||
|
j, err := json.Marshal(v)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unable to marshal JSON for %v", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
w := new(bytes.Buffer)
|
||||||
|
err = json.Compact(w, []byte(want))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("String is not valid json: %s", want)
|
||||||
|
}
|
||||||
|
|
||||||
|
if w.String() != string(j) {
|
||||||
|
t.Errorf("json.Marshal(%q) returned %s, want %s", v, j, w)
|
||||||
|
}
|
||||||
|
|
||||||
|
// now go the other direction and make sure things unmarshal as expected
|
||||||
|
u := reflect.ValueOf(v).Interface()
|
||||||
|
if err := json.Unmarshal([]byte(want), u); err != nil {
|
||||||
|
t.Errorf("Unable to unmarshal JSON for %v", want)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(v, u) {
|
||||||
|
t.Errorf("json.Unmarshal(%q) returned %s, want %s", want, u, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewClient(t *testing.T) {
|
||||||
|
c := NewClient(nil)
|
||||||
|
|
||||||
|
if c.BaseURL.String() != defaultBaseURL {
|
||||||
|
t.Errorf("NewClient BaseURL = %v, want %v", c.BaseURL.String(), defaultBaseURL)
|
||||||
|
}
|
||||||
|
if c.UserAgent != userAgent {
|
||||||
|
t.Errorf("NewClient UserAgent = %v, want %v", c.UserAgent, userAgent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewRequest(t *testing.T) {
|
||||||
|
c := NewClient(nil)
|
||||||
|
|
||||||
|
inURL, outURL := "/foo", defaultBaseURL+"foo"
|
||||||
|
inBody, outBody := &User{Login: String("l")}, `{"login":"l"}`+"\n"
|
||||||
|
req, _ := c.NewRequest("GET", inURL, inBody)
|
||||||
|
|
||||||
|
// test that relative URL was expanded
|
||||||
|
if req.URL.String() != outURL {
|
||||||
|
t.Errorf("NewRequest(%v) URL = %v, want %v", inURL, req.URL, outURL)
|
||||||
|
}
|
||||||
|
|
||||||
|
// test that body was JSON encoded
|
||||||
|
body, _ := ioutil.ReadAll(req.Body)
|
||||||
|
if string(body) != outBody {
|
||||||
|
t.Errorf("NewRequest(%v) Body = %v, want %v", inBody, string(body), outBody)
|
||||||
|
}
|
||||||
|
|
||||||
|
// test that default user-agent is attached to the request
|
||||||
|
userAgent := req.Header.Get("User-Agent")
|
||||||
|
if c.UserAgent != userAgent {
|
||||||
|
t.Errorf("NewRequest() User-Agent = %v, want %v", userAgent, c.UserAgent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewRequest_invalidJSON(t *testing.T) {
|
||||||
|
c := NewClient(nil)
|
||||||
|
|
||||||
|
type T struct {
|
||||||
|
A map[int]interface{}
|
||||||
|
}
|
||||||
|
_, err := c.NewRequest("GET", "/", &T{})
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
t.Error("Expected error to be returned.")
|
||||||
|
}
|
||||||
|
if err, ok := err.(*json.UnsupportedTypeError); !ok {
|
||||||
|
t.Errorf("Expected a JSON error; got %#v.", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewRequest_badURL(t *testing.T) {
|
||||||
|
c := NewClient(nil)
|
||||||
|
_, err := c.NewRequest("GET", ":", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResponse_populatePageValues(t *testing.T) {
|
||||||
|
r := http.Response{
|
||||||
|
Header: http.Header{
|
||||||
|
"Link": {`<https://api.github.com/?page=1>; rel="first",` +
|
||||||
|
` <https://api.github.com/?page=2>; rel="prev",` +
|
||||||
|
` <https://api.github.com/?page=4>; rel="next",` +
|
||||||
|
` <https://api.github.com/?page=5>; rel="last"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
response := newResponse(&r)
|
||||||
|
if want, got := 1, response.FirstPage; want != got {
|
||||||
|
t.Errorf("response.FirstPage: %v, want %v", want, got)
|
||||||
|
}
|
||||||
|
if want, got := 2, response.PrevPage; want != got {
|
||||||
|
t.Errorf("response.PrevPage: %v, want %v", want, got)
|
||||||
|
}
|
||||||
|
if want, got := 4, response.NextPage; want != got {
|
||||||
|
t.Errorf("response.NextPage: %v, want %v", want, got)
|
||||||
|
}
|
||||||
|
if want, got := 5, response.LastPage; want != got {
|
||||||
|
t.Errorf("response.LastPage: %v, want %v", want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResponse_populatePageValues_invalid(t *testing.T) {
|
||||||
|
r := http.Response{
|
||||||
|
Header: http.Header{
|
||||||
|
"Link": {`<https://api.github.com/?page=1>,` +
|
||||||
|
`<https://api.github.com/?page=abc>; rel="first",` +
|
||||||
|
`https://api.github.com/?page=2; rel="prev",` +
|
||||||
|
`<https://api.github.com/>; rel="next",` +
|
||||||
|
`<https://api.github.com/?page=>; rel="last"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
response := newResponse(&r)
|
||||||
|
if want, got := 0, response.FirstPage; want != got {
|
||||||
|
t.Errorf("response.FirstPage: %v, want %v", want, got)
|
||||||
|
}
|
||||||
|
if want, got := 0, response.PrevPage; want != got {
|
||||||
|
t.Errorf("response.PrevPage: %v, want %v", want, got)
|
||||||
|
}
|
||||||
|
if want, got := 0, response.NextPage; want != got {
|
||||||
|
t.Errorf("response.NextPage: %v, want %v", want, got)
|
||||||
|
}
|
||||||
|
if want, got := 0, response.LastPage; want != got {
|
||||||
|
t.Errorf("response.LastPage: %v, want %v", want, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
// more invalid URLs
|
||||||
|
r = http.Response{
|
||||||
|
Header: http.Header{
|
||||||
|
"Link": {`<https://api.github.com/%?page=2>; rel="first"`},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
response = newResponse(&r)
|
||||||
|
if want, got := 0, response.FirstPage; want != got {
|
||||||
|
t.Errorf("response.FirstPage: %v, want %v", want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDo(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
type foo struct {
|
||||||
|
A string
|
||||||
|
}
|
||||||
|
|
||||||
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if m := "GET"; m != r.Method {
|
||||||
|
t.Errorf("Request method = %v, want %v", r.Method, m)
|
||||||
|
}
|
||||||
|
fmt.Fprint(w, `{"A":"a"}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
req, _ := client.NewRequest("GET", "/", nil)
|
||||||
|
body := new(foo)
|
||||||
|
client.Do(req, body)
|
||||||
|
|
||||||
|
want := &foo{"a"}
|
||||||
|
if !reflect.DeepEqual(body, want) {
|
||||||
|
t.Errorf("Response body = %v, want %v", body, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDo_httpError(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
http.Error(w, "Bad Request", 400)
|
||||||
|
})
|
||||||
|
|
||||||
|
req, _ := client.NewRequest("GET", "/", nil)
|
||||||
|
_, err := client.Do(req, nil)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
t.Error("Expected HTTP 400 error.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test handling of an error caused by the internal http client's Do()
|
||||||
|
// function. A redirect loop is pretty unlikely to occur within the GitHub
|
||||||
|
// API, but does allow us to exercise the right code path.
|
||||||
|
func TestDo_redirectLoop(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
http.Redirect(w, r, "/", http.StatusFound)
|
||||||
|
})
|
||||||
|
|
||||||
|
req, _ := client.NewRequest("GET", "/", nil)
|
||||||
|
_, err := client.Do(req, nil)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
t.Error("Expected error to be returned.")
|
||||||
|
}
|
||||||
|
if err, ok := err.(*url.Error); !ok {
|
||||||
|
t.Errorf("Expected a URL error; got %#v.", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDo_rateLimit(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Add(headerRateLimit, "60")
|
||||||
|
w.Header().Add(headerRateRemaining, "59")
|
||||||
|
w.Header().Add(headerRateReset, "1372700873")
|
||||||
|
})
|
||||||
|
|
||||||
|
var want int
|
||||||
|
|
||||||
|
if want = 0; client.Rate.Limit != want {
|
||||||
|
t.Errorf("Client rate limit = %v, want %v", client.Rate.Limit, want)
|
||||||
|
}
|
||||||
|
if want = 0; client.Rate.Limit != want {
|
||||||
|
t.Errorf("Client rate remaining = %v, got %v", client.Rate.Remaining, want)
|
||||||
|
}
|
||||||
|
if !client.Rate.Reset.IsZero() {
|
||||||
|
t.Errorf("Client rate reset not initialized to zero value")
|
||||||
|
}
|
||||||
|
|
||||||
|
req, _ := client.NewRequest("GET", "/", nil)
|
||||||
|
client.Do(req, nil)
|
||||||
|
|
||||||
|
if want = 60; client.Rate.Limit != want {
|
||||||
|
t.Errorf("Client rate limit = %v, want %v", client.Rate.Limit, want)
|
||||||
|
}
|
||||||
|
if want = 59; client.Rate.Remaining != want {
|
||||||
|
t.Errorf("Client rate remaining = %v, want %v", client.Rate.Remaining, want)
|
||||||
|
}
|
||||||
|
reset := time.Date(2013, 7, 1, 17, 47, 53, 0, time.UTC)
|
||||||
|
if client.Rate.Reset.UTC() != reset {
|
||||||
|
t.Errorf("Client rate reset = %v, want %v", client.Rate.Reset, reset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDo_rateLimit_errorResponse(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Add(headerRateLimit, "60")
|
||||||
|
w.Header().Add(headerRateRemaining, "59")
|
||||||
|
w.Header().Add(headerRateReset, "1372700873")
|
||||||
|
http.Error(w, "Bad Request", 400)
|
||||||
|
})
|
||||||
|
|
||||||
|
var want int
|
||||||
|
|
||||||
|
req, _ := client.NewRequest("GET", "/", nil)
|
||||||
|
client.Do(req, nil)
|
||||||
|
|
||||||
|
if want = 60; client.Rate.Limit != want {
|
||||||
|
t.Errorf("Client rate limit = %v, want %v", client.Rate.Limit, want)
|
||||||
|
}
|
||||||
|
if want = 59; client.Rate.Remaining != want {
|
||||||
|
t.Errorf("Client rate remaining = %v, want %v", client.Rate.Remaining, want)
|
||||||
|
}
|
||||||
|
reset := time.Date(2013, 7, 1, 17, 47, 53, 0, time.UTC)
|
||||||
|
if client.Rate.Reset.UTC() != reset {
|
||||||
|
t.Errorf("Client rate reset = %v, want %v", client.Rate.Reset, reset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckResponse(t *testing.T) {
|
||||||
|
res := &http.Response{
|
||||||
|
Request: &http.Request{},
|
||||||
|
StatusCode: http.StatusBadRequest,
|
||||||
|
Body: ioutil.NopCloser(strings.NewReader(`{"message":"m",
|
||||||
|
"errors": [{"resource": "r", "field": "f", "code": "c"}]}`)),
|
||||||
|
}
|
||||||
|
err := CheckResponse(res).(*ErrorResponse)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected error response.")
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &ErrorResponse{
|
||||||
|
Response: res,
|
||||||
|
Message: "m",
|
||||||
|
Errors: []Error{{Resource: "r", Field: "f", Code: "c"}},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(err, want) {
|
||||||
|
t.Errorf("Error = %#v, want %#v", err, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure that we properly handle API errors that do not contain a response
|
||||||
|
// body
|
||||||
|
func TestCheckResponse_noBody(t *testing.T) {
|
||||||
|
res := &http.Response{
|
||||||
|
Request: &http.Request{},
|
||||||
|
StatusCode: http.StatusBadRequest,
|
||||||
|
Body: ioutil.NopCloser(strings.NewReader("")),
|
||||||
|
}
|
||||||
|
err := CheckResponse(res).(*ErrorResponse)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected error response.")
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &ErrorResponse{
|
||||||
|
Response: res,
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(err, want) {
|
||||||
|
t.Errorf("Error = %#v, want %#v", err, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseBooleanResponse_true(t *testing.T) {
|
||||||
|
result, err := parseBoolResponse(nil)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("parseBoolResponse returned error: %+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if want := true; result != want {
|
||||||
|
t.Errorf("parseBoolResponse returned %+v, want: %+v", result, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseBooleanResponse_false(t *testing.T) {
|
||||||
|
v := &ErrorResponse{Response: &http.Response{StatusCode: http.StatusNotFound}}
|
||||||
|
result, err := parseBoolResponse(v)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("parseBoolResponse returned error: %+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if want := false; result != want {
|
||||||
|
t.Errorf("parseBoolResponse returned %+v, want: %+v", result, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseBooleanResponse_error(t *testing.T) {
|
||||||
|
v := &ErrorResponse{Response: &http.Response{StatusCode: http.StatusBadRequest}}
|
||||||
|
result, err := parseBoolResponse(v)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected error to be returned.")
|
||||||
|
}
|
||||||
|
|
||||||
|
if want := false; result != want {
|
||||||
|
t.Errorf("parseBoolResponse returned %+v, want: %+v", result, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestErrorResponse_Error(t *testing.T) {
|
||||||
|
res := &http.Response{Request: &http.Request{}}
|
||||||
|
err := ErrorResponse{Message: "m", Response: res}
|
||||||
|
if err.Error() == "" {
|
||||||
|
t.Errorf("Expected non-empty ErrorResponse.Error()")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestError_Error(t *testing.T) {
|
||||||
|
err := Error{}
|
||||||
|
if err.Error() == "" {
|
||||||
|
t.Errorf("Expected non-empty Error.Error()")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRateLimit(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/rate_limit", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if m := "GET"; m != r.Method {
|
||||||
|
t.Errorf("Request method = %v, want %v", r.Method, m)
|
||||||
|
}
|
||||||
|
//fmt.Fprint(w, `{"resources":{"core": {"limit":2,"remaining":1,"reset":1372700873}}}`)
|
||||||
|
fmt.Fprint(w, `{"resources":{
|
||||||
|
"core": {"limit":2,"remaining":1,"reset":1372700873},
|
||||||
|
"search": {"limit":3,"remaining":2,"reset":1372700874}
|
||||||
|
}}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
rate, _, err := client.RateLimit()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Rate limit returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Rate{
|
||||||
|
Limit: 2,
|
||||||
|
Remaining: 1,
|
||||||
|
Reset: Timestamp{time.Date(2013, 7, 1, 17, 47, 53, 0, time.UTC).Local()},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(rate, want) {
|
||||||
|
t.Errorf("RateLimit returned %+v, want %+v", rate, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRateLimits(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/rate_limit", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if m := "GET"; m != r.Method {
|
||||||
|
t.Errorf("Request method = %v, want %v", r.Method, m)
|
||||||
|
}
|
||||||
|
fmt.Fprint(w, `{"resources":{
|
||||||
|
"core": {"limit":2,"remaining":1,"reset":1372700873},
|
||||||
|
"search": {"limit":3,"remaining":2,"reset":1372700874}
|
||||||
|
}}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
rate, _, err := client.RateLimits()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("RateLimits returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &RateLimits{
|
||||||
|
Core: &Rate{
|
||||||
|
Limit: 2,
|
||||||
|
Remaining: 1,
|
||||||
|
Reset: Timestamp{time.Date(2013, 7, 1, 17, 47, 53, 0, time.UTC).Local()},
|
||||||
|
},
|
||||||
|
Search: &Rate{
|
||||||
|
Limit: 3,
|
||||||
|
Remaining: 2,
|
||||||
|
Reset: Timestamp{time.Date(2013, 7, 1, 17, 47, 54, 0, time.UTC).Local()},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(rate, want) {
|
||||||
|
t.Errorf("RateLimits returned %+v, want %+v", rate, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnauthenticatedRateLimitedTransport(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var v, want string
|
||||||
|
q := r.URL.Query()
|
||||||
|
if v, want = q.Get("client_id"), "id"; v != want {
|
||||||
|
t.Errorf("OAuth Client ID = %v, want %v", v, want)
|
||||||
|
}
|
||||||
|
if v, want = q.Get("client_secret"), "secret"; v != want {
|
||||||
|
t.Errorf("OAuth Client Secret = %v, want %v", v, want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
tp := &UnauthenticatedRateLimitedTransport{
|
||||||
|
ClientID: "id",
|
||||||
|
ClientSecret: "secret",
|
||||||
|
}
|
||||||
|
unauthedClient := NewClient(tp.Client())
|
||||||
|
unauthedClient.BaseURL = client.BaseURL
|
||||||
|
req, _ := unauthedClient.NewRequest("GET", "/", nil)
|
||||||
|
unauthedClient.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnauthenticatedRateLimitedTransport_missingFields(t *testing.T) {
|
||||||
|
// missing ClientID
|
||||||
|
tp := &UnauthenticatedRateLimitedTransport{
|
||||||
|
ClientSecret: "secret",
|
||||||
|
}
|
||||||
|
_, err := tp.RoundTrip(nil)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected error to be returned")
|
||||||
|
}
|
||||||
|
|
||||||
|
// missing ClientSecret
|
||||||
|
tp = &UnauthenticatedRateLimitedTransport{
|
||||||
|
ClientID: "id",
|
||||||
|
}
|
||||||
|
_, err = tp.RoundTrip(nil)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected error to be returned")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnauthenticatedRateLimitedTransport_transport(t *testing.T) {
|
||||||
|
// default transport
|
||||||
|
tp := &UnauthenticatedRateLimitedTransport{
|
||||||
|
ClientID: "id",
|
||||||
|
ClientSecret: "secret",
|
||||||
|
}
|
||||||
|
if tp.transport() != http.DefaultTransport {
|
||||||
|
t.Errorf("Expected http.DefaultTransport to be used.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// custom transport
|
||||||
|
tp = &UnauthenticatedRateLimitedTransport{
|
||||||
|
ClientID: "id",
|
||||||
|
ClientSecret: "secret",
|
||||||
|
Transport: &http.Transport{},
|
||||||
|
}
|
||||||
|
if tp.transport() == http.DefaultTransport {
|
||||||
|
t.Errorf("Expected custom transport to be used.")
|
||||||
|
}
|
||||||
|
}
|
||||||
63
Godeps/_workspace/src/github.com/google/go-github/github/gitignore.go
generated
vendored
Normal file
63
Godeps/_workspace/src/github.com/google/go-github/github/gitignore.go
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
// 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"
|
||||||
|
|
||||||
|
// GitignoresService provides access to the gitignore related functions in the
|
||||||
|
// GitHub API.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/gitignore/
|
||||||
|
type GitignoresService struct {
|
||||||
|
client *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// Represents a .gitignore file as returned by the GitHub API.
|
||||||
|
type Gitignore struct {
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
Source *string `json:"source,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g Gitignore) String() string {
|
||||||
|
return Stringify(g)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetches a list of all available Gitignore templates.
|
||||||
|
//
|
||||||
|
// http://developer.github.com/v3/gitignore/#listing-available-templates
|
||||||
|
func (s GitignoresService) List() ([]string, *Response, error) {
|
||||||
|
req, err := s.client.NewRequest("GET", "gitignore/templates", nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
availableTemplates := new([]string)
|
||||||
|
resp, err := s.client.Do(req, availableTemplates)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *availableTemplates, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetches a Gitignore by name.
|
||||||
|
//
|
||||||
|
// http://developer.github.com/v3/gitignore/#get-a-single-template
|
||||||
|
func (s GitignoresService) Get(name string) (*Gitignore, *Response, error) {
|
||||||
|
u := fmt.Sprintf("gitignore/templates/%v", name)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
gitignore := new(Gitignore)
|
||||||
|
resp, err := s.client.Do(req, gitignore)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gitignore, resp, err
|
||||||
|
}
|
||||||
58
Godeps/_workspace/src/github.com/google/go-github/github/gitignore_test.go
generated
vendored
Normal file
58
Godeps/_workspace/src/github.com/google/go-github/github/gitignore_test.go
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
// 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 TestGitignoresService_List(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/gitignore/templates", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `["C", "Go"]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
available, _, err := client.Gitignores.List()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Gitignores.List returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []string{"C", "Go"}
|
||||||
|
if !reflect.DeepEqual(available, want) {
|
||||||
|
t.Errorf("Gitignores.List returned %+v, want %+v", available, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGitignoresService_Get(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/gitignore/templates/name", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"name":"Name","source":"template source"}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
gitignore, _, err := client.Gitignores.Get("name")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Gitignores.List returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Gitignore{Name: String("Name"), Source: String("template source")}
|
||||||
|
if !reflect.DeepEqual(gitignore, want) {
|
||||||
|
t.Errorf("Gitignores.Get returned %+v, want %+v", gitignore, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGitignoresService_Get_invalidTemplate(t *testing.T) {
|
||||||
|
_, _, err := client.Gitignores.Get("%")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
247
Godeps/_workspace/src/github.com/google/go-github/github/issues.go
generated
vendored
Normal file
247
Godeps/_workspace/src/github.com/google/go-github/github/issues.go
generated
vendored
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
// 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"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IssuesService handles communication with the issue related
|
||||||
|
// methods of the GitHub API.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/
|
||||||
|
type IssuesService struct {
|
||||||
|
client *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// Issue represents a GitHub issue on a repository.
|
||||||
|
type Issue struct {
|
||||||
|
Number *int `json:"number,omitempty"`
|
||||||
|
State *string `json:"state,omitempty"`
|
||||||
|
Title *string `json:"title,omitempty"`
|
||||||
|
Body *string `json:"body,omitempty"`
|
||||||
|
User *User `json:"user,omitempty"`
|
||||||
|
Labels []Label `json:"labels,omitempty"`
|
||||||
|
Assignee *User `json:"assignee,omitempty"`
|
||||||
|
Comments *int `json:"comments,omitempty"`
|
||||||
|
ClosedAt *time.Time `json:"closed_at,omitempty"`
|
||||||
|
CreatedAt *time.Time `json:"created_at,omitempty"`
|
||||||
|
UpdatedAt *time.Time `json:"updated_at,omitempty"`
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
HTMLURL *string `json:"html_url,omitempty"`
|
||||||
|
Milestone *Milestone `json:"milestone,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i Issue) String() string {
|
||||||
|
return Stringify(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IssueRequest represents a request to create/edit an issue.
|
||||||
|
// It is separate from Issue above because otherwise Labels
|
||||||
|
// and Assignee fail to serialize to the correct JSON.
|
||||||
|
type IssueRequest struct {
|
||||||
|
Title *string `json:"title,omitempty"`
|
||||||
|
Body *string `json:"body,omitempty"`
|
||||||
|
Labels []string `json:"labels,omitempty"`
|
||||||
|
Assignee *string `json:"assignee,omitempty"`
|
||||||
|
State *string `json:"state,omitempty"`
|
||||||
|
Milestone *int `json:"milestone,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// IssueListOptions specifies the optional parameters to the IssuesService.List
|
||||||
|
// and IssuesService.ListByOrg methods.
|
||||||
|
type IssueListOptions struct {
|
||||||
|
// Filter specifies which issues to list. Possible values are: assigned,
|
||||||
|
// created, mentioned, subscribed, all. Default is "assigned".
|
||||||
|
Filter string `url:"filter,omitempty"`
|
||||||
|
|
||||||
|
// State filters issues based on their state. Possible values are: open,
|
||||||
|
// closed. Default is "open".
|
||||||
|
State string `url:"state,omitempty"`
|
||||||
|
|
||||||
|
// Labels filters issues based on their label.
|
||||||
|
Labels []string `url:"labels,comma,omitempty"`
|
||||||
|
|
||||||
|
// Sort specifies how to sort issues. Possible values are: created, updated,
|
||||||
|
// and comments. Default value is "assigned".
|
||||||
|
Sort string `url:"sort,omitempty"`
|
||||||
|
|
||||||
|
// Direction in which to sort issues. Possible values are: asc, desc.
|
||||||
|
// Default is "asc".
|
||||||
|
Direction string `url:"direction,omitempty"`
|
||||||
|
|
||||||
|
// Since filters issues by time.
|
||||||
|
Since time.Time `url:"since,omitempty"`
|
||||||
|
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// List the issues for the authenticated user. If all is true, list issues
|
||||||
|
// across all the user's visible repositories including owned, member, and
|
||||||
|
// organization repositories; if false, list only owned and member
|
||||||
|
// repositories.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/#list-issues
|
||||||
|
func (s *IssuesService) List(all bool, opt *IssueListOptions) ([]Issue, *Response, error) {
|
||||||
|
var u string
|
||||||
|
if all {
|
||||||
|
u = "issues"
|
||||||
|
} else {
|
||||||
|
u = "user/issues"
|
||||||
|
}
|
||||||
|
return s.listIssues(u, opt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListByOrg fetches the issues in the specified organization for the
|
||||||
|
// authenticated user.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/#list-issues
|
||||||
|
func (s *IssuesService) ListByOrg(org string, opt *IssueListOptions) ([]Issue, *Response, error) {
|
||||||
|
u := fmt.Sprintf("orgs/%v/issues", org)
|
||||||
|
return s.listIssues(u, opt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *IssuesService) listIssues(u string, opt *IssueListOptions) ([]Issue, *Response, error) {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
issues := new([]Issue)
|
||||||
|
resp, err := s.client.Do(req, issues)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *issues, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// IssueListByRepoOptions specifies the optional parameters to the
|
||||||
|
// IssuesService.ListByRepo method.
|
||||||
|
type IssueListByRepoOptions struct {
|
||||||
|
// Milestone limits issues for the specified milestone. Possible values are
|
||||||
|
// a milestone number, "none" for issues with no milestone, "*" for issues
|
||||||
|
// with any milestone.
|
||||||
|
Milestone string `url:"milestone,omitempty"`
|
||||||
|
|
||||||
|
// State filters issues based on their state. Possible values are: open,
|
||||||
|
// closed. Default is "open".
|
||||||
|
State string `url:"state,omitempty"`
|
||||||
|
|
||||||
|
// Assignee filters issues based on their assignee. Possible values are a
|
||||||
|
// user name, "none" for issues that are not assigned, "*" for issues with
|
||||||
|
// any assigned user.
|
||||||
|
Assignee string `url:"assignee,omitempty"`
|
||||||
|
|
||||||
|
// Assignee filters issues based on their creator.
|
||||||
|
Creator string `url:"creator,omitempty"`
|
||||||
|
|
||||||
|
// Assignee filters issues to those mentioned a specific user.
|
||||||
|
Mentioned string `url:"mentioned,omitempty"`
|
||||||
|
|
||||||
|
// Labels filters issues based on their label.
|
||||||
|
Labels []string `url:"labels,omitempty,comma"`
|
||||||
|
|
||||||
|
// Sort specifies how to sort issues. Possible values are: created, updated,
|
||||||
|
// and comments. Default value is "assigned".
|
||||||
|
Sort string `url:"sort,omitempty"`
|
||||||
|
|
||||||
|
// Direction in which to sort issues. Possible values are: asc, desc.
|
||||||
|
// Default is "asc".
|
||||||
|
Direction string `url:"direction,omitempty"`
|
||||||
|
|
||||||
|
// Since filters issues by time.
|
||||||
|
Since time.Time `url:"since,omitempty"`
|
||||||
|
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListByRepo lists the issues for the specified repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/#list-issues-for-a-repository
|
||||||
|
func (s *IssuesService) ListByRepo(owner string, repo string, opt *IssueListByRepoOptions) ([]Issue, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/issues", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
issues := new([]Issue)
|
||||||
|
resp, err := s.client.Do(req, issues)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *issues, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a single issue.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/#get-a-single-issue
|
||||||
|
func (s *IssuesService) Get(owner string, repo string, number int) (*Issue, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/issues/%d", owner, repo, number)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
issue := new(Issue)
|
||||||
|
resp, err := s.client.Do(req, issue)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return issue, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new issue on the specified repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/#create-an-issue
|
||||||
|
func (s *IssuesService) Create(owner string, repo string, issue *IssueRequest) (*Issue, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/issues", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("POST", u, issue)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
i := new(Issue)
|
||||||
|
resp, err := s.client.Do(req, i)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return i, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Edit an issue.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/#edit-an-issue
|
||||||
|
func (s *IssuesService) Edit(owner string, repo string, number int, issue *IssueRequest) (*Issue, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/issues/%d", owner, repo, number)
|
||||||
|
req, err := s.client.NewRequest("PATCH", u, issue)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
i := new(Issue)
|
||||||
|
resp, err := s.client.Do(req, i)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return i, resp, err
|
||||||
|
}
|
||||||
46
Godeps/_workspace/src/github.com/google/go-github/github/issues_assignees.go
generated
vendored
Normal file
46
Godeps/_workspace/src/github.com/google/go-github/github/issues_assignees.go
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
// 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"
|
||||||
|
|
||||||
|
// ListAssignees fetches all available assignees (owners and collaborators) to
|
||||||
|
// which issues may be assigned.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/assignees/#list-assignees
|
||||||
|
func (s *IssuesService) ListAssignees(owner string, repo string, opt *ListOptions) ([]User, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/assignees", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
assignees := new([]User)
|
||||||
|
resp, err := s.client.Do(req, assignees)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *assignees, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsAssignee checks if a user is an assignee for the specified repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/assignees/#check-assignee
|
||||||
|
func (s *IssuesService) IsAssignee(owner string, repo string, user string) (bool, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/assignees/%v", owner, repo, user)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
resp, err := s.client.Do(req, nil)
|
||||||
|
assignee, err := parseBoolResponse(err)
|
||||||
|
return assignee, resp, err
|
||||||
|
}
|
||||||
98
Godeps/_workspace/src/github.com/google/go-github/github/issues_assignees_test.go
generated
vendored
Normal file
98
Godeps/_workspace/src/github.com/google/go-github/github/issues_assignees_test.go
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
// 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 TestIssuesService_ListAssignees(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/assignees", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{"page": "2"})
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListOptions{Page: 2}
|
||||||
|
assignees, _, err := client.Issues.ListAssignees("o", "r", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.List returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []User{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(assignees, want) {
|
||||||
|
t.Errorf("Issues.ListAssignees returned %+v, want %+v", assignees, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_ListAssignees_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.ListAssignees("%", "r", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_IsAssignee_true(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/assignees/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
})
|
||||||
|
|
||||||
|
assignee, _, err := client.Issues.IsAssignee("o", "r", "u")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.IsAssignee returned error: %v", err)
|
||||||
|
}
|
||||||
|
if want := true; assignee != want {
|
||||||
|
t.Errorf("Issues.IsAssignee returned %+v, want %+v", assignee, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_IsAssignee_false(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/assignees/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
})
|
||||||
|
|
||||||
|
assignee, _, err := client.Issues.IsAssignee("o", "r", "u")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.IsAssignee returned error: %v", err)
|
||||||
|
}
|
||||||
|
if want := false; assignee != want {
|
||||||
|
t.Errorf("Issues.IsAssignee returned %+v, want %+v", assignee, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_IsAssignee_error(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/assignees/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
http.Error(w, "BadRequest", http.StatusBadRequest)
|
||||||
|
})
|
||||||
|
|
||||||
|
assignee, _, err := client.Issues.IsAssignee("o", "r", "u")
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected HTTP 400 response")
|
||||||
|
}
|
||||||
|
if want := false; assignee != want {
|
||||||
|
t.Errorf("Issues.IsAssignee returned %+v, want %+v", assignee, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_IsAssignee_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.IsAssignee("%", "r", "u")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
133
Godeps/_workspace/src/github.com/google/go-github/github/issues_comments.go
generated
vendored
Normal file
133
Godeps/_workspace/src/github.com/google/go-github/github/issues_comments.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
// 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"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IssueComment represents a comment left on an issue.
|
||||||
|
type IssueComment struct {
|
||||||
|
ID *int `json:"id,omitempty"`
|
||||||
|
Body *string `json:"body,omitempty"`
|
||||||
|
User *User `json:"user,omitempty"`
|
||||||
|
CreatedAt *time.Time `json:"created_at,omitempty"`
|
||||||
|
UpdatedAt *time.Time `json:"updated_at,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i IssueComment) String() string {
|
||||||
|
return Stringify(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IssueListCommentsOptions specifies the optional parameters to the
|
||||||
|
// IssuesService.ListComments method.
|
||||||
|
type IssueListCommentsOptions struct {
|
||||||
|
// Sort specifies how to sort comments. Possible values are: created, updated.
|
||||||
|
Sort string `url:"sort,omitempty"`
|
||||||
|
|
||||||
|
// Direction in which to sort comments. Possible values are: asc, desc.
|
||||||
|
Direction string `url:"direction,omitempty"`
|
||||||
|
|
||||||
|
// Since filters comments by time.
|
||||||
|
Since time.Time `url:"since,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListComments lists all comments on the specified issue. Specifying an issue
|
||||||
|
// number of 0 will return all comments on all issues for the repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/comments/#list-comments-on-an-issue
|
||||||
|
func (s *IssuesService) ListComments(owner string, repo string, number int, opt *IssueListCommentsOptions) ([]IssueComment, *Response, error) {
|
||||||
|
var u string
|
||||||
|
if number == 0 {
|
||||||
|
u = fmt.Sprintf("repos/%v/%v/issues/comments", owner, repo)
|
||||||
|
} else {
|
||||||
|
u = fmt.Sprintf("repos/%v/%v/issues/%d/comments", owner, repo, number)
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
comments := new([]IssueComment)
|
||||||
|
resp, err := s.client.Do(req, comments)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *comments, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetComment fetches the specified issue comment.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/comments/#get-a-single-comment
|
||||||
|
func (s *IssuesService) GetComment(owner string, repo string, id int) (*IssueComment, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/issues/comments/%d", owner, repo, id)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
comment := new(IssueComment)
|
||||||
|
resp, err := s.client.Do(req, comment)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return comment, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateComment creates a new comment on the specified issue.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/comments/#create-a-comment
|
||||||
|
func (s *IssuesService) CreateComment(owner string, repo string, number int, comment *IssueComment) (*IssueComment, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/issues/%d/comments", owner, repo, number)
|
||||||
|
req, err := s.client.NewRequest("POST", u, comment)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
c := new(IssueComment)
|
||||||
|
resp, err := s.client.Do(req, c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditComment updates an issue comment.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/comments/#edit-a-comment
|
||||||
|
func (s *IssuesService) EditComment(owner string, repo string, id int, comment *IssueComment) (*IssueComment, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/issues/comments/%d", owner, repo, id)
|
||||||
|
req, err := s.client.NewRequest("PATCH", u, comment)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
c := new(IssueComment)
|
||||||
|
resp, err := s.client.Do(req, c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteComment deletes an issue comment.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/comments/#delete-a-comment
|
||||||
|
func (s *IssuesService) DeleteComment(owner string, repo string, id int) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/issues/comments/%d", owner, repo, id)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
180
Godeps/_workspace/src/github.com/google/go-github/github/issues_comments_test.go
generated
vendored
Normal file
180
Godeps/_workspace/src/github.com/google/go-github/github/issues_comments_test.go
generated
vendored
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestIssuesService_ListComments_allIssues(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/issues/comments", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"sort": "updated",
|
||||||
|
"direction": "desc",
|
||||||
|
"since": "2002-02-10T15:30:00Z",
|
||||||
|
})
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &IssueListCommentsOptions{"updated", "desc",
|
||||||
|
time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC),
|
||||||
|
}
|
||||||
|
comments, _, err := client.Issues.ListComments("o", "r", 0, opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.ListComments returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []IssueComment{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(comments, want) {
|
||||||
|
t.Errorf("Issues.ListComments returned %+v, want %+v", comments, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_ListComments_specificIssue(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/issues/1/comments", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
comments, _, err := client.Issues.ListComments("o", "r", 1, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.ListComments returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []IssueComment{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(comments, want) {
|
||||||
|
t.Errorf("Issues.ListComments returned %+v, want %+v", comments, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_ListComments_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.ListComments("%", "r", 1, nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_GetComment(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/issues/comments/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
comment, _, err := client.Issues.GetComment("o", "r", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.GetComment returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &IssueComment{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(comment, want) {
|
||||||
|
t.Errorf("Issues.GetComment returned %+v, want %+v", comment, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_GetComment_invalidOrg(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.GetComment("%", "r", 1)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_CreateComment(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &IssueComment{Body: String("b")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/issues/1/comments", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(IssueComment)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
comment, _, err := client.Issues.CreateComment("o", "r", 1, input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.CreateComment returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &IssueComment{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(comment, want) {
|
||||||
|
t.Errorf("Issues.CreateComment returned %+v, want %+v", comment, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_CreateComment_invalidOrg(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.CreateComment("%", "r", 1, nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_EditComment(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &IssueComment{Body: String("b")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/issues/comments/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(IssueComment)
|
||||||
|
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}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
comment, _, err := client.Issues.EditComment("o", "r", 1, input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.EditComment returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &IssueComment{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(comment, want) {
|
||||||
|
t.Errorf("Issues.EditComment returned %+v, want %+v", comment, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_EditComment_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.EditComment("%", "r", 1, nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_DeleteComment(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/issues/comments/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Issues.DeleteComment("o", "r", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.DeleteComments returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_DeleteComment_invalidOwner(t *testing.T) {
|
||||||
|
_, err := client.Issues.DeleteComment("%", "r", 1)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
127
Godeps/_workspace/src/github.com/google/go-github/github/issues_events.go
generated
vendored
Normal file
127
Godeps/_workspace/src/github.com/google/go-github/github/issues_events.go
generated
vendored
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
// Copyright 2014 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"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IssueEvent represents an event that occurred around an Issue or Pull Request.
|
||||||
|
type IssueEvent struct {
|
||||||
|
ID *int `json:"id,omitempty"`
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
|
||||||
|
// The User that generated this event.
|
||||||
|
Actor *User `json:"actor,omitempty"`
|
||||||
|
|
||||||
|
// Event identifies the actual type of Event that occurred. Possible
|
||||||
|
// values are:
|
||||||
|
//
|
||||||
|
// closed
|
||||||
|
// The issue was closed by the actor. When the commit_id is
|
||||||
|
// present, it identifies the commit that closed the issue using
|
||||||
|
// “closes / fixes #NN” syntax.
|
||||||
|
//
|
||||||
|
// reopened
|
||||||
|
// The issue was reopened by the actor.
|
||||||
|
//
|
||||||
|
// subscribed
|
||||||
|
// The actor subscribed to receive notifications for an issue.
|
||||||
|
//
|
||||||
|
// merged
|
||||||
|
// The issue was merged by the actor. The commit_id attribute is the SHA1 of the HEAD commit that was merged.
|
||||||
|
//
|
||||||
|
// referenced
|
||||||
|
// The issue was referenced from a commit message. The commit_id attribute is the commit SHA1 of where that happened.
|
||||||
|
//
|
||||||
|
// mentioned
|
||||||
|
// The actor was @mentioned in an issue body.
|
||||||
|
//
|
||||||
|
// assigned
|
||||||
|
// The issue was assigned to the actor.
|
||||||
|
//
|
||||||
|
// head_ref_deleted
|
||||||
|
// The pull request’s branch was deleted.
|
||||||
|
//
|
||||||
|
// head_ref_restored
|
||||||
|
// The pull request’s branch was restored.
|
||||||
|
Event *string `json:"event,omitempty"`
|
||||||
|
|
||||||
|
// The SHA of the commit that referenced this commit, if applicable.
|
||||||
|
CommitID *string `json:"commit_id,omitempty"`
|
||||||
|
|
||||||
|
CreatedAt *time.Time `json:"created_at,omitempty"`
|
||||||
|
Issue *Issue `json:"issue,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListIssueEvents lists events for the specified issue.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/issues/events/#list-events-for-an-issue
|
||||||
|
func (s *IssuesService) ListIssueEvents(owner, repo string, number int, opt *ListOptions) ([]IssueEvent, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/issues/%v/events", owner, repo, number)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
var events []IssueEvent
|
||||||
|
resp, err := s.client.Do(req, &events)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return events, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRepositoryEvents lists events for the specified repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/issues/events/#list-events-for-a-repository
|
||||||
|
func (s *IssuesService) ListRepositoryEvents(owner, repo string, opt *ListOptions) ([]IssueEvent, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/issues/events", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
var events []IssueEvent
|
||||||
|
resp, err := s.client.Do(req, &events)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return events, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetEvent returns the specified issue event.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/issues/events/#get-a-single-event
|
||||||
|
func (s *IssuesService) GetEvent(owner, repo string, id int) (*IssueEvent, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/issues/events/%v", owner, repo, id)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
event := new(IssueEvent)
|
||||||
|
resp, err := s.client.Do(req, event)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return event, resp, err
|
||||||
|
}
|
||||||
86
Godeps/_workspace/src/github.com/google/go-github/github/issues_events_test.go
generated
vendored
Normal file
86
Godeps/_workspace/src/github.com/google/go-github/github/issues_events_test.go
generated
vendored
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
// Copyright 2014 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 TestIssuesService_ListIssueEvents(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/issues/1/events", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"page": "1",
|
||||||
|
"per_page": "2",
|
||||||
|
})
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListOptions{Page: 1, PerPage: 2}
|
||||||
|
events, _, err := client.Issues.ListIssueEvents("o", "r", 1, opt)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.ListIssueEvents returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []IssueEvent{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(events, want) {
|
||||||
|
t.Errorf("Issues.ListIssueEvents returned %+v, want %+v", events, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_ListRepositoryEvents(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/issues/events", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"page": "1",
|
||||||
|
"per_page": "2",
|
||||||
|
})
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListOptions{Page: 1, PerPage: 2}
|
||||||
|
events, _, err := client.Issues.ListRepositoryEvents("o", "r", opt)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.ListRepositoryEvents returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []IssueEvent{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(events, want) {
|
||||||
|
t.Errorf("Issues.ListRepositoryEvents returned %+v, want %+v", events, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_GetEvent(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/issues/events/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
event, _, err := client.Issues.GetEvent("o", "r", 1)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.GetEvent returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &IssueEvent{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(event, want) {
|
||||||
|
t.Errorf("Issues.GetEvent returned %+v, want %+v", event, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
222
Godeps/_workspace/src/github.com/google/go-github/github/issues_labels.go
generated
vendored
Normal file
222
Godeps/_workspace/src/github.com/google/go-github/github/issues_labels.go
generated
vendored
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
// 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"
|
||||||
|
|
||||||
|
// Label represents a GitHib label on an Issue
|
||||||
|
type Label struct {
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
Color *string `json:"color,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l Label) String() string {
|
||||||
|
return fmt.Sprint(*l.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListLabels lists all labels for a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/labels/#list-all-labels-for-this-repository
|
||||||
|
func (s *IssuesService) ListLabels(owner string, repo string, opt *ListOptions) ([]Label, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/labels", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
labels := new([]Label)
|
||||||
|
resp, err := s.client.Do(req, labels)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *labels, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLabel gets a single label.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/labels/#get-a-single-label
|
||||||
|
func (s *IssuesService) GetLabel(owner string, repo string, name string) (*Label, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/labels/%v", owner, repo, name)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
label := new(Label)
|
||||||
|
resp, err := s.client.Do(req, label)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return label, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateLabel creates a new label on the specified repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/labels/#create-a-label
|
||||||
|
func (s *IssuesService) CreateLabel(owner string, repo string, label *Label) (*Label, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/labels", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("POST", u, label)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
l := new(Label)
|
||||||
|
resp, err := s.client.Do(req, l)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return l, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditLabel edits a label.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/labels/#update-a-label
|
||||||
|
func (s *IssuesService) EditLabel(owner string, repo string, name string, label *Label) (*Label, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/labels/%v", owner, repo, name)
|
||||||
|
req, err := s.client.NewRequest("PATCH", u, label)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
l := new(Label)
|
||||||
|
resp, err := s.client.Do(req, l)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return l, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteLabel deletes a label.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/labels/#delete-a-label
|
||||||
|
func (s *IssuesService) DeleteLabel(owner string, repo string, name string) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/labels/%v", owner, repo, name)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListLabelsByIssue lists all labels for an issue.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/labels/#list-all-labels-for-this-repository
|
||||||
|
func (s *IssuesService) ListLabelsByIssue(owner string, repo string, number int, opt *ListOptions) ([]Label, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
labels := new([]Label)
|
||||||
|
resp, err := s.client.Do(req, labels)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *labels, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddLabelsToIssue adds labels to an issue.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/labels/#list-all-labels-for-this-repository
|
||||||
|
func (s *IssuesService) AddLabelsToIssue(owner string, repo string, number int, labels []string) ([]Label, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number)
|
||||||
|
req, err := s.client.NewRequest("POST", u, labels)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
l := new([]Label)
|
||||||
|
resp, err := s.client.Do(req, l)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *l, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveLabelForIssue removes a label for an issue.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/labels/#remove-a-label-from-an-issue
|
||||||
|
func (s *IssuesService) RemoveLabelForIssue(owner string, repo string, number int, label string) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/issues/%d/labels/%v", owner, repo, number, label)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReplaceLabelsForIssue replaces all labels for an issue.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/labels/#replace-all-labels-for-an-issue
|
||||||
|
func (s *IssuesService) ReplaceLabelsForIssue(owner string, repo string, number int, labels []string) ([]Label, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number)
|
||||||
|
req, err := s.client.NewRequest("PUT", u, labels)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
l := new([]Label)
|
||||||
|
resp, err := s.client.Do(req, l)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *l, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveLabelsForIssue removes all labels for an issue.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/labels/#remove-all-labels-from-an-issue
|
||||||
|
func (s *IssuesService) RemoveLabelsForIssue(owner string, repo string, number int) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListLabelsForMilestone lists labels for every issue in a milestone.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/issues/labels/#get-labels-for-every-issue-in-a-milestone
|
||||||
|
func (s *IssuesService) ListLabelsForMilestone(owner string, repo string, number int, opt *ListOptions) ([]Label, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/milestones/%d/labels", owner, repo, number)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
labels := new([]Label)
|
||||||
|
resp, err := s.client.Do(req, labels)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *labels, resp, err
|
||||||
|
}
|
||||||
313
Godeps/_workspace/src/github.com/google/go-github/github/issues_labels_test.go
generated
vendored
Normal file
313
Godeps/_workspace/src/github.com/google/go-github/github/issues_labels_test.go
generated
vendored
Normal file
@@ -0,0 +1,313 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestIssuesService_ListLabels(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/labels", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{"page": "2"})
|
||||||
|
fmt.Fprint(w, `[{"name": "a"},{"name": "b"}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListOptions{Page: 2}
|
||||||
|
labels, _, err := client.Issues.ListLabels("o", "r", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.ListLabels returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Label{{Name: String("a")}, {Name: String("b")}}
|
||||||
|
if !reflect.DeepEqual(labels, want) {
|
||||||
|
t.Errorf("Issues.ListLabels returned %+v, want %+v", labels, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_ListLabels_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.ListLabels("%", "%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_GetLabel(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/labels/n", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"url":"u", "name": "n", "color": "c"}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
label, _, err := client.Issues.GetLabel("o", "r", "n")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.GetLabel returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Label{URL: String("u"), Name: String("n"), Color: String("c")}
|
||||||
|
if !reflect.DeepEqual(label, want) {
|
||||||
|
t.Errorf("Issues.GetLabel returned %+v, want %+v", label, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_GetLabel_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.GetLabel("%", "%", "%")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_CreateLabel(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &Label{Name: String("n")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/labels", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(Label)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"url":"u"}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
label, _, err := client.Issues.CreateLabel("o", "r", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.CreateLabel returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Label{URL: String("u")}
|
||||||
|
if !reflect.DeepEqual(label, want) {
|
||||||
|
t.Errorf("Issues.CreateLabel returned %+v, want %+v", label, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_CreateLabel_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.CreateLabel("%", "%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_EditLabel(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &Label{Name: String("z")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/labels/n", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(Label)
|
||||||
|
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"}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
label, _, err := client.Issues.EditLabel("o", "r", "n", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.EditLabel returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Label{URL: String("u")}
|
||||||
|
if !reflect.DeepEqual(label, want) {
|
||||||
|
t.Errorf("Issues.EditLabel returned %+v, want %+v", label, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_EditLabel_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.EditLabel("%", "%", "%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_DeleteLabel(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/labels/n", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Issues.DeleteLabel("o", "r", "n")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.DeleteLabel returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_DeleteLabel_invalidOwner(t *testing.T) {
|
||||||
|
_, err := client.Issues.DeleteLabel("%", "%", "%")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_ListLabelsByIssue(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/issues/1/labels", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{"page": "2"})
|
||||||
|
fmt.Fprint(w, `[{"name": "a"},{"name": "b"}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListOptions{Page: 2}
|
||||||
|
labels, _, err := client.Issues.ListLabelsByIssue("o", "r", 1, opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.ListLabelsByIssue returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Label{{Name: String("a")}, {Name: String("b")}}
|
||||||
|
if !reflect.DeepEqual(labels, want) {
|
||||||
|
t.Errorf("Issues.ListLabelsByIssue returned %+v, want %+v", labels, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_ListLabelsByIssue_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.ListLabelsByIssue("%", "%", 1, nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_AddLabelsToIssue(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := []string{"a", "b"}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/issues/1/labels", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new([]string)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(*v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `[{"url":"u"}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
labels, _, err := client.Issues.AddLabelsToIssue("o", "r", 1, input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.AddLabelsToIssue returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Label{{URL: String("u")}}
|
||||||
|
if !reflect.DeepEqual(labels, want) {
|
||||||
|
t.Errorf("Issues.AddLabelsToIssue returned %+v, want %+v", labels, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_AddLabelsToIssue_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.AddLabelsToIssue("%", "%", 1, nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_RemoveLabelForIssue(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/issues/1/labels/l", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Issues.RemoveLabelForIssue("o", "r", 1, "l")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.RemoveLabelForIssue returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_RemoveLabelForIssue_invalidOwner(t *testing.T) {
|
||||||
|
_, err := client.Issues.RemoveLabelForIssue("%", "%", 1, "%")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_ReplaceLabelsForIssue(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := []string{"a", "b"}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/issues/1/labels", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new([]string)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "PUT")
|
||||||
|
if !reflect.DeepEqual(*v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `[{"url":"u"}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
labels, _, err := client.Issues.ReplaceLabelsForIssue("o", "r", 1, input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.ReplaceLabelsForIssue returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Label{{URL: String("u")}}
|
||||||
|
if !reflect.DeepEqual(labels, want) {
|
||||||
|
t.Errorf("Issues.ReplaceLabelsForIssue returned %+v, want %+v", labels, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_ReplaceLabelsForIssue_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.ReplaceLabelsForIssue("%", "%", 1, nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_RemoveLabelsForIssue(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/issues/1/labels", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Issues.RemoveLabelsForIssue("o", "r", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.RemoveLabelsForIssue returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_RemoveLabelsForIssue_invalidOwner(t *testing.T) {
|
||||||
|
_, err := client.Issues.RemoveLabelsForIssue("%", "%", 1)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_ListLabelsForMilestone(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/milestones/1/labels", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{"page": "2"})
|
||||||
|
fmt.Fprint(w, `[{"name": "a"},{"name": "b"}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListOptions{Page: 2}
|
||||||
|
labels, _, err := client.Issues.ListLabelsForMilestone("o", "r", 1, opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.ListLabelsForMilestone returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Label{{Name: String("a")}, {Name: String("b")}}
|
||||||
|
if !reflect.DeepEqual(labels, want) {
|
||||||
|
t.Errorf("Issues.ListLabelsForMilestone returned %+v, want %+v", labels, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_ListLabelsForMilestone_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.ListLabelsForMilestone("%", "%", 1, nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
140
Godeps/_workspace/src/github.com/google/go-github/github/issues_milestones.go
generated
vendored
Normal file
140
Godeps/_workspace/src/github.com/google/go-github/github/issues_milestones.go
generated
vendored
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
// Copyright 2014 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"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Milestone represents a Github repository milestone.
|
||||||
|
type Milestone struct {
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
Number *int `json:"number,omitempty"`
|
||||||
|
State *string `json:"state,omitempty"`
|
||||||
|
Title *string `json:"title,omitempty"`
|
||||||
|
Description *string `json:"description,omitempty"`
|
||||||
|
Creator *User `json:"creator,omitempty"`
|
||||||
|
OpenIssues *int `json:"open_issues,omitempty"`
|
||||||
|
ClosedIssues *int `json:"closed_issues,omitempty"`
|
||||||
|
CreatedAt *time.Time `json:"created_at,omitempty"`
|
||||||
|
UpdatedAt *time.Time `json:"updated_at,omitempty"`
|
||||||
|
DueOn *time.Time `json:"due_on,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Milestone) String() string {
|
||||||
|
return Stringify(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MilestoneListOptions specifies the optional parameters to the
|
||||||
|
// IssuesService.ListMilestones method.
|
||||||
|
type MilestoneListOptions struct {
|
||||||
|
// State filters milestones based on their state. Possible values are:
|
||||||
|
// open, closed. Default is "open".
|
||||||
|
State string `url:"state,omitempty"`
|
||||||
|
|
||||||
|
// Sort specifies how to sort milestones. Possible values are: due_date, completeness.
|
||||||
|
// Default value is "due_date".
|
||||||
|
Sort string `url:"sort,omitempty"`
|
||||||
|
|
||||||
|
// Direction in which to sort milestones. Possible values are: asc, desc.
|
||||||
|
// Default is "asc".
|
||||||
|
Direction string `url:"direction,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListMilestones lists all milestones for a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/issues/milestones/#list-milestones-for-a-repository
|
||||||
|
func (s *IssuesService) ListMilestones(owner string, repo string, opt *MilestoneListOptions) ([]Milestone, *Response, error) {
|
||||||
|
u := fmt.Sprintf("/repos/%v/%v/milestones", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
milestones := new([]Milestone)
|
||||||
|
resp, err := s.client.Do(req, milestones)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *milestones, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMilestone gets a single milestone.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/issues/milestones/#get-a-single-milestone
|
||||||
|
func (s *IssuesService) GetMilestone(owner string, repo string, number int) (*Milestone, *Response, error) {
|
||||||
|
u := fmt.Sprintf("/repos/%v/%v/milestones/%d", owner, repo, number)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
milestone := new(Milestone)
|
||||||
|
resp, err := s.client.Do(req, milestone)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return milestone, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateMilestone creates a new milestone on the specified repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/issues/milestones/#create-a-milestone
|
||||||
|
func (s *IssuesService) CreateMilestone(owner string, repo string, milestone *Milestone) (*Milestone, *Response, error) {
|
||||||
|
u := fmt.Sprintf("/repos/%v/%v/milestones", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("POST", u, milestone)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
m := new(Milestone)
|
||||||
|
resp, err := s.client.Do(req, m)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return m, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditMilestone edits a milestone.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/issues/milestones/#update-a-milestone
|
||||||
|
func (s *IssuesService) EditMilestone(owner string, repo string, number int, milestone *Milestone) (*Milestone, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/milestones/%d", owner, repo, number)
|
||||||
|
req, err := s.client.NewRequest("PATCH", u, milestone)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
m := new(Milestone)
|
||||||
|
resp, err := s.client.Do(req, m)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return m, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteMilestone deletes a milestone.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/issues/milestones/#delete-a-milestone
|
||||||
|
func (s *IssuesService) DeleteMilestone(owner string, repo string, number int) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/milestones/%d", owner, repo, number)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
157
Godeps/_workspace/src/github.com/google/go-github/github/issues_milestones_test.go
generated
vendored
Normal file
157
Godeps/_workspace/src/github.com/google/go-github/github/issues_milestones_test.go
generated
vendored
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
// Copyright 2014 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 TestIssuesService_ListMilestones(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/milestones", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"state": "closed",
|
||||||
|
"sort": "due_date",
|
||||||
|
"direction": "asc",
|
||||||
|
})
|
||||||
|
fmt.Fprint(w, `[{"number":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &MilestoneListOptions{"closed", "due_date", "asc"}
|
||||||
|
milestones, _, err := client.Issues.ListMilestones("o", "r", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("IssuesService.ListMilestones returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Milestone{{Number: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(milestones, want) {
|
||||||
|
t.Errorf("IssuesService.ListMilestones returned %+v, want %+v", milestones, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_ListMilestones_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.ListMilestones("%", "r", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_GetMilestone(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/milestones/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"number":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
milestone, _, err := client.Issues.GetMilestone("o", "r", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("IssuesService.GetMilestone returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Milestone{Number: Int(1)}
|
||||||
|
if !reflect.DeepEqual(milestone, want) {
|
||||||
|
t.Errorf("IssuesService.GetMilestone returned %+v, want %+v", milestone, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_GetMilestone_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.GetMilestone("%", "r", 1)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_CreateMilestone(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &Milestone{Title: String("t")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/milestones", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(Milestone)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"number":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
milestone, _, err := client.Issues.CreateMilestone("o", "r", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("IssuesService.CreateMilestone returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Milestone{Number: Int(1)}
|
||||||
|
if !reflect.DeepEqual(milestone, want) {
|
||||||
|
t.Errorf("IssuesService.CreateMilestone returned %+v, want %+v", milestone, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_CreateMilestone_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.CreateMilestone("%", "r", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_EditMilestone(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &Milestone{Title: String("t")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/milestones/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(Milestone)
|
||||||
|
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, `{"number":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
milestone, _, err := client.Issues.EditMilestone("o", "r", 1, input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("IssuesService.EditMilestone returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Milestone{Number: Int(1)}
|
||||||
|
if !reflect.DeepEqual(milestone, want) {
|
||||||
|
t.Errorf("IssuesService.EditMilestone returned %+v, want %+v", milestone, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_EditMilestone_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.EditMilestone("%", "r", 1, nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_DeleteMilestone(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/milestones/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Issues.DeleteMilestone("o", "r", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("IssuesService.DeleteMilestone returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_DeleteMilestone_invalidOwner(t *testing.T) {
|
||||||
|
_, err := client.Issues.DeleteMilestone("%", "r", 1)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
242
Godeps/_workspace/src/github.com/google/go-github/github/issues_test.go
generated
vendored
Normal file
242
Godeps/_workspace/src/github.com/google/go-github/github/issues_test.go
generated
vendored
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestIssuesService_List_all(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/issues", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"filter": "all",
|
||||||
|
"state": "closed",
|
||||||
|
"labels": "a,b",
|
||||||
|
"sort": "updated",
|
||||||
|
"direction": "asc",
|
||||||
|
"since": "2002-02-10T15:30:00Z",
|
||||||
|
"page": "1",
|
||||||
|
"per_page": "2",
|
||||||
|
})
|
||||||
|
fmt.Fprint(w, `[{"number":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &IssueListOptions{
|
||||||
|
"all", "closed", []string{"a", "b"}, "updated", "asc",
|
||||||
|
time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC),
|
||||||
|
ListOptions{Page: 1, PerPage: 2},
|
||||||
|
}
|
||||||
|
issues, _, err := client.Issues.List(true, opt)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.List returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Issue{{Number: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(issues, want) {
|
||||||
|
t.Errorf("Issues.List returned %+v, want %+v", issues, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_List_owned(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/user/issues", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `[{"number":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
issues, _, err := client.Issues.List(false, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.List returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Issue{{Number: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(issues, want) {
|
||||||
|
t.Errorf("Issues.List returned %+v, want %+v", issues, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_ListByOrg(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/issues", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `[{"number":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
issues, _, err := client.Issues.ListByOrg("o", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.ListByOrg returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Issue{{Number: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(issues, want) {
|
||||||
|
t.Errorf("Issues.List returned %+v, want %+v", issues, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_ListByOrg_invalidOrg(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.ListByOrg("%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_ListByRepo(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/issues", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"milestone": "*",
|
||||||
|
"state": "closed",
|
||||||
|
"assignee": "a",
|
||||||
|
"creator": "c",
|
||||||
|
"mentioned": "m",
|
||||||
|
"labels": "a,b",
|
||||||
|
"sort": "updated",
|
||||||
|
"direction": "asc",
|
||||||
|
"since": "2002-02-10T15:30:00Z",
|
||||||
|
})
|
||||||
|
fmt.Fprint(w, `[{"number":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &IssueListByRepoOptions{
|
||||||
|
"*", "closed", "a", "c", "m", []string{"a", "b"}, "updated", "asc",
|
||||||
|
time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC),
|
||||||
|
ListOptions{0, 0},
|
||||||
|
}
|
||||||
|
issues, _, err := client.Issues.ListByRepo("o", "r", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.ListByOrg returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Issue{{Number: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(issues, want) {
|
||||||
|
t.Errorf("Issues.List returned %+v, want %+v", issues, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_ListByRepo_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.ListByRepo("%", "r", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_Get(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/issues/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"number":1, "labels": [{"url": "u", "name": "n", "color": "c"}]}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
issue, _, err := client.Issues.Get("o", "r", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.Get returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Issue{
|
||||||
|
Number: Int(1),
|
||||||
|
Labels: []Label{{
|
||||||
|
URL: String("u"),
|
||||||
|
Name: String("n"),
|
||||||
|
Color: String("c"),
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(issue, want) {
|
||||||
|
t.Errorf("Issues.Get returned %+v, want %+v", issue, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_Get_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.Get("%", "r", 1)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_Create(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &IssueRequest{
|
||||||
|
Title: String("t"),
|
||||||
|
Body: String("b"),
|
||||||
|
Assignee: String("a"),
|
||||||
|
Labels: []string{"l1", "l2"},
|
||||||
|
}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/issues", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(IssueRequest)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"number":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
issue, _, err := client.Issues.Create("o", "r", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.Create returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Issue{Number: Int(1)}
|
||||||
|
if !reflect.DeepEqual(issue, want) {
|
||||||
|
t.Errorf("Issues.Create returned %+v, want %+v", issue, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_Create_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.Create("%", "r", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_Edit(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &IssueRequest{Title: String("t")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/issues/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(IssueRequest)
|
||||||
|
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, `{"number":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
issue, _, err := client.Issues.Edit("o", "r", 1, input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Issues.Edit returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Issue{Number: Int(1)}
|
||||||
|
if !reflect.DeepEqual(issue, want) {
|
||||||
|
t.Errorf("Issues.Edit returned %+v, want %+v", issue, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssuesService_Edit_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Issues.Edit("%", "r", 1, nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
119
Godeps/_workspace/src/github.com/google/go-github/github/misc.go
generated
vendored
Normal file
119
Godeps/_workspace/src/github.com/google/go-github/github/misc.go
generated
vendored
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
// Copyright 2014 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 (
|
||||||
|
"bytes"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MarkdownOptions specifies optional parameters to the Markdown method.
|
||||||
|
type MarkdownOptions struct {
|
||||||
|
// Mode identifies the rendering mode. Possible values are:
|
||||||
|
// markdown - render a document as plain Markdown, just like
|
||||||
|
// README files are rendered.
|
||||||
|
//
|
||||||
|
// gfm - to render a document as user-content, e.g. like user
|
||||||
|
// comments or issues are rendered. In GFM mode, hard line breaks are
|
||||||
|
// always taken into account, and issue and user mentions are linked
|
||||||
|
// accordingly.
|
||||||
|
//
|
||||||
|
// Default is "markdown".
|
||||||
|
Mode string
|
||||||
|
|
||||||
|
// Context identifies the repository context. Only taken into account
|
||||||
|
// when rendering as "gfm".
|
||||||
|
Context string
|
||||||
|
}
|
||||||
|
|
||||||
|
type markdownRequest struct {
|
||||||
|
Text *string `json:"text,omitempty"`
|
||||||
|
Mode *string `json:"mode,omitempty"`
|
||||||
|
Context *string `json:"context,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Markdown renders an arbitrary Markdown document.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/markdown/
|
||||||
|
func (c *Client) Markdown(text string, opt *MarkdownOptions) (string, *Response, error) {
|
||||||
|
request := &markdownRequest{Text: String(text)}
|
||||||
|
if opt != nil {
|
||||||
|
if opt.Mode != "" {
|
||||||
|
request.Mode = String(opt.Mode)
|
||||||
|
}
|
||||||
|
if opt.Context != "" {
|
||||||
|
request.Context = String(opt.Context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := c.NewRequest("POST", "/markdown", request)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
resp, err := c.Do(req, buf)
|
||||||
|
if err != nil {
|
||||||
|
return "", resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.String(), resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListEmojis returns the emojis available to use on GitHub.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/emojis/
|
||||||
|
func (c *Client) ListEmojis() (map[string]string, *Response, error) {
|
||||||
|
req, err := c.NewRequest("GET", "/emojis", nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var emoji map[string]string
|
||||||
|
resp, err := c.Do(req, &emoji)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return emoji, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// APIMeta represents metadata about the GitHub API.
|
||||||
|
type APIMeta struct {
|
||||||
|
// An Array of IP addresses in CIDR format specifying the addresses
|
||||||
|
// that incoming service hooks will originate from on GitHub.com.
|
||||||
|
Hooks []string `json:"hooks,omitempty"`
|
||||||
|
|
||||||
|
// An Array of IP addresses in CIDR format specifying the Git servers
|
||||||
|
// for GitHub.com.
|
||||||
|
Git []string `json:"git,omitempty"`
|
||||||
|
|
||||||
|
// Whether authentication with username and password is supported.
|
||||||
|
// (GitHub Enterprise instances using CAS or OAuth for authentication
|
||||||
|
// will return false. Features like Basic Authentication with a
|
||||||
|
// username and password, sudo mode, and two-factor authentication are
|
||||||
|
// not supported on these servers.)
|
||||||
|
VerifiablePasswordAuthentication *bool `json:"verifiable_password_authentication,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// APIMeta returns information about GitHub.com, the service. Or, if you access
|
||||||
|
// this endpoint on your organization’s GitHub Enterprise installation, this
|
||||||
|
// endpoint provides information about that installation.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/meta/
|
||||||
|
func (c *Client) APIMeta() (*APIMeta, *Response, error) {
|
||||||
|
req, err := c.NewRequest("GET", "/meta", nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
meta := new(APIMeta)
|
||||||
|
resp, err := c.Do(req, meta)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return meta, resp, nil
|
||||||
|
}
|
||||||
91
Godeps/_workspace/src/github.com/google/go-github/github/misc_test.go
generated
vendored
Normal file
91
Godeps/_workspace/src/github.com/google/go-github/github/misc_test.go
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
// Copyright 2014 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 TestMarkdown(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &markdownRequest{
|
||||||
|
Text: String("# text #"),
|
||||||
|
Mode: String("gfm"),
|
||||||
|
Context: String("google/go-github"),
|
||||||
|
}
|
||||||
|
mux.HandleFunc("/markdown", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(markdownRequest)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
fmt.Fprint(w, `<h1>text</h1>`)
|
||||||
|
})
|
||||||
|
|
||||||
|
md, _, err := client.Markdown("# text #", &MarkdownOptions{
|
||||||
|
Mode: "gfm",
|
||||||
|
Context: "google/go-github",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Markdown returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if want := "<h1>text</h1>"; want != md {
|
||||||
|
t.Errorf("Markdown returned %+v, want %+v", md, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListEmojis(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/emojis", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"+1": "+1.png"}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
emoji, _, err := client.ListEmojis()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("ListEmojis returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := map[string]string{"+1": "+1.png"}
|
||||||
|
if !reflect.DeepEqual(want, emoji) {
|
||||||
|
t.Errorf("ListEmojis returned %+v, want %+v", emoji, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAPIMeta(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/meta", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"hooks":["h"], "git":["g"], "verifiable_password_authentication": true}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
meta, _, err := client.APIMeta()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("APIMeta returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &APIMeta{
|
||||||
|
Hooks: []string{"h"},
|
||||||
|
Git: []string{"g"},
|
||||||
|
VerifiablePasswordAuthentication: Bool(true),
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(want, meta) {
|
||||||
|
t.Errorf("APIMeta returned %+v, want %+v", meta, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
137
Godeps/_workspace/src/github.com/google/go-github/github/orgs.go
generated
vendored
Normal file
137
Godeps/_workspace/src/github.com/google/go-github/github/orgs.go
generated
vendored
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
// 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"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// OrganizationsService provides access to the organization related functions
|
||||||
|
// in the GitHub API.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/orgs/
|
||||||
|
type OrganizationsService struct {
|
||||||
|
client *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// Organization represents a GitHub organization account.
|
||||||
|
type Organization struct {
|
||||||
|
Login *string `json:"login,omitempty"`
|
||||||
|
ID *int `json:"id,omitempty"`
|
||||||
|
AvatarURL *string `json:"avatar_url,omitempty"`
|
||||||
|
HTMLURL *string `json:"html_url,omitempty"`
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
Company *string `json:"company,omitempty"`
|
||||||
|
Blog *string `json:"blog,omitempty"`
|
||||||
|
Location *string `json:"location,omitempty"`
|
||||||
|
Email *string `json:"email,omitempty"`
|
||||||
|
PublicRepos *int `json:"public_repos,omitempty"`
|
||||||
|
PublicGists *int `json:"public_gists,omitempty"`
|
||||||
|
Followers *int `json:"followers,omitempty"`
|
||||||
|
Following *int `json:"following,omitempty"`
|
||||||
|
CreatedAt *time.Time `json:"created_at,omitempty"`
|
||||||
|
UpdatedAt *time.Time `json:"updated_at,omitempty"`
|
||||||
|
TotalPrivateRepos *int `json:"total_private_repos,omitempty"`
|
||||||
|
OwnedPrivateRepos *int `json:"owned_private_repos,omitempty"`
|
||||||
|
PrivateGists *int `json:"private_gists,omitempty"`
|
||||||
|
DiskUsage *int `json:"disk_usage,omitempty"`
|
||||||
|
Collaborators *int `json:"collaborators,omitempty"`
|
||||||
|
BillingEmail *string `json:"billing_email,omitempty"`
|
||||||
|
Type *string `json:"type,omitempty"`
|
||||||
|
Plan *Plan `json:"plan,omitempty"`
|
||||||
|
|
||||||
|
// API URLs
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
EventsURL *string `json:"events_url,omitempty"`
|
||||||
|
MembersURL *string `json:"members_url,omitempty"`
|
||||||
|
PublicMembersURL *string `json:"public_members_url,omitempty"`
|
||||||
|
ReposURL *string `json:"repos_url,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Organization) String() string {
|
||||||
|
return Stringify(o)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Plan represents the payment plan for an account. See plans at https://github.com/plans.
|
||||||
|
type Plan struct {
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
Space *int `json:"space,omitempty"`
|
||||||
|
Collaborators *int `json:"collaborators,omitempty"`
|
||||||
|
PrivateRepos *int `json:"private_repos,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Plan) String() string {
|
||||||
|
return Stringify(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// List the organizations for a user. Passing the empty string will list
|
||||||
|
// organizations for the authenticated user.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/orgs/#list-user-organizations
|
||||||
|
func (s *OrganizationsService) List(user string, opt *ListOptions) ([]Organization, *Response, error) {
|
||||||
|
var u string
|
||||||
|
if user != "" {
|
||||||
|
u = fmt.Sprintf("users/%v/orgs", user)
|
||||||
|
} else {
|
||||||
|
u = "user/orgs"
|
||||||
|
}
|
||||||
|
u, err := addOptions(u, opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
orgs := new([]Organization)
|
||||||
|
resp, err := s.client.Do(req, orgs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *orgs, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get fetches an organization by name.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/orgs/#get-an-organization
|
||||||
|
func (s *OrganizationsService) Get(org string) (*Organization, *Response, error) {
|
||||||
|
u := fmt.Sprintf("orgs/%v", org)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
organization := new(Organization)
|
||||||
|
resp, err := s.client.Do(req, organization)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return organization, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Edit an organization.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/orgs/#edit-an-organization
|
||||||
|
func (s *OrganizationsService) Edit(name string, org *Organization) (*Organization, *Response, error) {
|
||||||
|
u := fmt.Sprintf("orgs/%v", name)
|
||||||
|
req, err := s.client.NewRequest("PATCH", u, org)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
o := new(Organization)
|
||||||
|
resp, err := s.client.Do(req, o)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return o, resp, err
|
||||||
|
}
|
||||||
122
Godeps/_workspace/src/github.com/google/go-github/github/orgs_members.go
generated
vendored
Normal file
122
Godeps/_workspace/src/github.com/google/go-github/github/orgs_members.go
generated
vendored
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
// 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"
|
||||||
|
|
||||||
|
// ListMembersOptions specifies optional parameters to the
|
||||||
|
// OrganizationsService.ListMembers method.
|
||||||
|
type ListMembersOptions struct {
|
||||||
|
// If true (or if the authenticated user is not an owner of the
|
||||||
|
// organization), list only publicly visible members.
|
||||||
|
PublicOnly bool `url:"-"`
|
||||||
|
|
||||||
|
// Filter members returned in the list. Possible values are:
|
||||||
|
// 2fa_disabled, all. Default is "all".
|
||||||
|
Filter string `url:"filter,omitempty"`
|
||||||
|
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListMembers lists the members for an organization. If the authenticated
|
||||||
|
// user is an owner of the organization, this will return both concealed and
|
||||||
|
// public members, otherwise it will only return public members.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/orgs/members/#members-list
|
||||||
|
func (s *OrganizationsService) ListMembers(org string, opt *ListMembersOptions) ([]User, *Response, error) {
|
||||||
|
var u string
|
||||||
|
if opt != nil && opt.PublicOnly {
|
||||||
|
u = fmt.Sprintf("orgs/%v/public_members", org)
|
||||||
|
} else {
|
||||||
|
u = fmt.Sprintf("orgs/%v/members", 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
|
||||||
|
}
|
||||||
|
|
||||||
|
members := new([]User)
|
||||||
|
resp, err := s.client.Do(req, members)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *members, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsMember checks if a user is a member of an organization.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/orgs/members/#check-membership
|
||||||
|
func (s *OrganizationsService) IsMember(org, user string) (bool, *Response, error) {
|
||||||
|
u := fmt.Sprintf("orgs/%v/members/%v", org, user)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := s.client.Do(req, nil)
|
||||||
|
member, err := parseBoolResponse(err)
|
||||||
|
return member, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsPublicMember checks if a user is a public member of an organization.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/orgs/members/#check-public-membership
|
||||||
|
func (s *OrganizationsService) IsPublicMember(org, user string) (bool, *Response, error) {
|
||||||
|
u := fmt.Sprintf("orgs/%v/public_members/%v", org, user)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := s.client.Do(req, nil)
|
||||||
|
member, err := parseBoolResponse(err)
|
||||||
|
return member, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveMember removes a user from all teams of an organization.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/orgs/members/#remove-a-member
|
||||||
|
func (s *OrganizationsService) RemoveMember(org, user string) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("orgs/%v/members/%v", org, user)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PublicizeMembership publicizes a user's membership in an organization.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/orgs/members/#publicize-a-users-membership
|
||||||
|
func (s *OrganizationsService) PublicizeMembership(org, user string) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("orgs/%v/public_members/%v", org, user)
|
||||||
|
req, err := s.client.NewRequest("PUT", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConcealMembership conceals a user's membership in an organization.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/orgs/members/#conceal-a-users-membership
|
||||||
|
func (s *OrganizationsService) ConcealMembership(org, user string) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("orgs/%v/public_members/%v", org, user)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
211
Godeps/_workspace/src/github.com/google/go-github/github/orgs_members_test.go
generated
vendored
Normal file
211
Godeps/_workspace/src/github.com/google/go-github/github/orgs_members_test.go
generated
vendored
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
// 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 TestOrganizationsService_ListMembers(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/members", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"filter": "2fa_disabled",
|
||||||
|
"page": "2",
|
||||||
|
})
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListMembersOptions{
|
||||||
|
PublicOnly: false,
|
||||||
|
Filter: "2fa_disabled",
|
||||||
|
ListOptions: ListOptions{Page: 2},
|
||||||
|
}
|
||||||
|
members, _, err := client.Organizations.ListMembers("o", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.ListMembers returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []User{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(members, want) {
|
||||||
|
t.Errorf("Organizations.ListMembers returned %+v, want %+v", members, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_ListMembers_invalidOrg(t *testing.T) {
|
||||||
|
_, _, err := client.Organizations.ListMembers("%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_ListMembers_public(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/public_members", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListMembersOptions{PublicOnly: true}
|
||||||
|
members, _, err := client.Organizations.ListMembers("o", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.ListMembers returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []User{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(members, want) {
|
||||||
|
t.Errorf("Organizations.ListMembers returned %+v, want %+v", members, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_IsMember(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/members/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
member, _, err := client.Organizations.IsMember("o", "u")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.IsMember returned error: %v", err)
|
||||||
|
}
|
||||||
|
if want := true; member != want {
|
||||||
|
t.Errorf("Organizations.IsMember returned %+v, want %+v", member, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure that a 404 response is interpreted as "false" and not an error
|
||||||
|
func TestOrganizationsService_IsMember_notMember(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/members/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
})
|
||||||
|
|
||||||
|
member, _, err := client.Organizations.IsMember("o", "u")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.IsMember returned error: %+v", err)
|
||||||
|
}
|
||||||
|
if want := false; member != want {
|
||||||
|
t.Errorf("Organizations.IsMember returned %+v, want %+v", member, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure that a 400 response is interpreted as an actual error, and not simply
|
||||||
|
// as "false" like the above case of a 404
|
||||||
|
func TestOrganizationsService_IsMember_error(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/members/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
http.Error(w, "BadRequest", http.StatusBadRequest)
|
||||||
|
})
|
||||||
|
|
||||||
|
member, _, err := client.Organizations.IsMember("o", "u")
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected HTTP 400 response")
|
||||||
|
}
|
||||||
|
if want := false; member != want {
|
||||||
|
t.Errorf("Organizations.IsMember returned %+v, want %+v", member, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_IsMember_invalidOrg(t *testing.T) {
|
||||||
|
_, _, err := client.Organizations.IsMember("%", "u")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_IsPublicMember(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/public_members/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
member, _, err := client.Organizations.IsPublicMember("o", "u")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.IsPublicMember returned error: %v", err)
|
||||||
|
}
|
||||||
|
if want := true; member != want {
|
||||||
|
t.Errorf("Organizations.IsPublicMember returned %+v, want %+v", member, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure that a 404 response is interpreted as "false" and not an error
|
||||||
|
func TestOrganizationsService_IsPublicMember_notMember(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/public_members/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
})
|
||||||
|
|
||||||
|
member, _, err := client.Organizations.IsPublicMember("o", "u")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.IsPublicMember returned error: %v", err)
|
||||||
|
}
|
||||||
|
if want := false; member != want {
|
||||||
|
t.Errorf("Organizations.IsPublicMember returned %+v, want %+v", member, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure that a 400 response is interpreted as an actual error, and not simply
|
||||||
|
// as "false" like the above case of a 404
|
||||||
|
func TestOrganizationsService_IsPublicMember_error(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/public_members/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
http.Error(w, "BadRequest", http.StatusBadRequest)
|
||||||
|
})
|
||||||
|
|
||||||
|
member, _, err := client.Organizations.IsPublicMember("o", "u")
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected HTTP 400 response")
|
||||||
|
}
|
||||||
|
if want := false; member != want {
|
||||||
|
t.Errorf("Organizations.IsPublicMember returned %+v, want %+v", member, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_IsPublicMember_invalidOrg(t *testing.T) {
|
||||||
|
_, _, err := client.Organizations.IsPublicMember("%", "u")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_RemoveMember(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/members/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Organizations.RemoveMember("o", "u")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.RemoveMember returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_RemoveMember_invalidOrg(t *testing.T) {
|
||||||
|
_, err := client.Organizations.RemoveMember("%", "u")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
253
Godeps/_workspace/src/github.com/google/go-github/github/orgs_teams.go
generated
vendored
Normal file
253
Godeps/_workspace/src/github.com/google/go-github/github/orgs_teams.go
generated
vendored
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
// 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"
|
||||||
|
|
||||||
|
// Team represents a team within a GitHub organization. Teams are used to
|
||||||
|
// manage access to an organization's repositories.
|
||||||
|
type Team struct {
|
||||||
|
ID *int `json:"id,omitempty"`
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
Slug *string `json:"slug,omitempty"`
|
||||||
|
Permission *string `json:"permission,omitempty"`
|
||||||
|
MembersCount *int `json:"members_count,omitempty"`
|
||||||
|
ReposCount *int `json:"repos_count,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t Team) String() string {
|
||||||
|
return Stringify(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListTeams lists all of the teams for an organization.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#list-teams
|
||||||
|
func (s *OrganizationsService) ListTeams(org string, opt *ListOptions) ([]Team, *Response, error) {
|
||||||
|
u := fmt.Sprintf("orgs/%v/teams", 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
|
||||||
|
}
|
||||||
|
|
||||||
|
teams := new([]Team)
|
||||||
|
resp, err := s.client.Do(req, teams)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *teams, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTeam fetches a team by ID.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#get-team
|
||||||
|
func (s *OrganizationsService) GetTeam(team int) (*Team, *Response, error) {
|
||||||
|
u := fmt.Sprintf("teams/%v", team)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
t := new(Team)
|
||||||
|
resp, err := s.client.Do(req, t)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return t, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateTeam creates a new team within an organization.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#create-team
|
||||||
|
func (s *OrganizationsService) CreateTeam(org string, team *Team) (*Team, *Response, error) {
|
||||||
|
u := fmt.Sprintf("orgs/%v/teams", org)
|
||||||
|
req, err := s.client.NewRequest("POST", u, team)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
t := new(Team)
|
||||||
|
resp, err := s.client.Do(req, t)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return t, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditTeam edits a team.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#edit-team
|
||||||
|
func (s *OrganizationsService) EditTeam(id int, team *Team) (*Team, *Response, error) {
|
||||||
|
u := fmt.Sprintf("teams/%v", id)
|
||||||
|
req, err := s.client.NewRequest("PATCH", u, team)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
t := new(Team)
|
||||||
|
resp, err := s.client.Do(req, t)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return t, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteTeam deletes a team.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#delete-team
|
||||||
|
func (s *OrganizationsService) DeleteTeam(team int) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("teams/%v", team)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListTeamMembers lists all of the users who are members of the specified
|
||||||
|
// team.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#list-team-members
|
||||||
|
func (s *OrganizationsService) ListTeamMembers(team int, opt *ListOptions) ([]User, *Response, error) {
|
||||||
|
u := fmt.Sprintf("teams/%v/members", team)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
members := new([]User)
|
||||||
|
resp, err := s.client.Do(req, members)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *members, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsTeamMember checks if a user is a member of the specified team.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#get-team-member
|
||||||
|
func (s *OrganizationsService) IsTeamMember(team int, user string) (bool, *Response, error) {
|
||||||
|
u := fmt.Sprintf("teams/%v/members/%v", team, user)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := s.client.Do(req, nil)
|
||||||
|
member, err := parseBoolResponse(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.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#list-team-repos
|
||||||
|
func (s *OrganizationsService) ListTeamRepos(team int, opt *ListOptions) ([]Repository, *Response, error) {
|
||||||
|
u := fmt.Sprintf("teams/%v/repos", team)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
repos := new([]Repository)
|
||||||
|
resp, err := s.client.Do(req, repos)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *repos, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsTeamRepo checks if a team manages the specified repository.
|
||||||
|
//
|
||||||
|
// 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) {
|
||||||
|
u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := s.client.Do(req, nil)
|
||||||
|
manages, err := parseBoolResponse(err)
|
||||||
|
return manages, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddTeamRepo adds a repository to be managed by the specified team. The
|
||||||
|
// specified repository must be owned by the organization to which the team
|
||||||
|
// 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
|
||||||
|
func (s *OrganizationsService) AddTeamRepo(team int, owner string, repo string) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo)
|
||||||
|
req, err := s.client.NewRequest("PUT", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveTeamRepo removes a repository from being managed by the specified
|
||||||
|
// team. Note that this does not delete the repository, it just removes it
|
||||||
|
// from the team.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#remove-team-repo
|
||||||
|
func (s *OrganizationsService) RemoveTeamRepo(team int, owner string, repo string) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
437
Godeps/_workspace/src/github.com/google/go-github/github/orgs_teams_test.go
generated
vendored
Normal file
437
Godeps/_workspace/src/github.com/google/go-github/github/orgs_teams_test.go
generated
vendored
Normal file
@@ -0,0 +1,437 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestOrganizationsService_ListTeams(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/teams", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{"page": "2"})
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListOptions{Page: 2}
|
||||||
|
teams, _, err := client.Organizations.ListTeams("o", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.ListTeams returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Team{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(teams, want) {
|
||||||
|
t.Errorf("Organizations.ListTeams returned %+v, want %+v", teams, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_ListTeams_invalidOrg(t *testing.T) {
|
||||||
|
_, _, err := client.Organizations.ListTeams("%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_GetTeam(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"id":1, "name":"n", "url":"u", "slug": "s", "permission":"p"}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
team, _, err := client.Organizations.GetTeam(1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.GetTeam returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Team{ID: Int(1), Name: String("n"), URL: String("u"), Slug: String("s"), Permission: String("p")}
|
||||||
|
if !reflect.DeepEqual(team, want) {
|
||||||
|
t.Errorf("Organizations.GetTeam returned %+v, want %+v", team, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_CreateTeam(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &Team{Name: String("n")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/teams", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(Team)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
team, _, err := client.Organizations.CreateTeam("o", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.CreateTeam returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Team{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(team, want) {
|
||||||
|
t.Errorf("Organizations.CreateTeam returned %+v, want %+v", team, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_CreateTeam_invalidOrg(t *testing.T) {
|
||||||
|
_, _, err := client.Organizations.CreateTeam("%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_EditTeam(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &Team{Name: String("n")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(Team)
|
||||||
|
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}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
team, _, err := client.Organizations.EditTeam(1, input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.EditTeam returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Team{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(team, want) {
|
||||||
|
t.Errorf("Organizations.EditTeam returned %+v, want %+v", team, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_DeleteTeam(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Organizations.DeleteTeam(1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.DeleteTeam returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_ListTeamMembers(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/teams/1/members", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{"page": "2"})
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListOptions{Page: 2}
|
||||||
|
members, _, err := client.Organizations.ListTeamMembers(1, opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.ListTeamMembers returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []User{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(members, want) {
|
||||||
|
t.Errorf("Organizations.ListTeamMembers returned %+v, want %+v", members, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_IsTeamMember_true(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/teams/1/members/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
})
|
||||||
|
|
||||||
|
member, _, err := client.Organizations.IsTeamMember(1, "u")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.IsTeamMember returned error: %v", err)
|
||||||
|
}
|
||||||
|
if want := true; member != want {
|
||||||
|
t.Errorf("Organizations.IsTeamMember returned %+v, want %+v", member, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure that a 404 response is interpreted as "false" and not an error
|
||||||
|
func TestOrganizationsService_IsTeamMember_false(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/teams/1/members/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
})
|
||||||
|
|
||||||
|
member, _, err := client.Organizations.IsTeamMember(1, "u")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.IsTeamMember returned error: %+v", err)
|
||||||
|
}
|
||||||
|
if want := false; member != want {
|
||||||
|
t.Errorf("Organizations.IsTeamMember returned %+v, want %+v", member, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure that a 400 response is interpreted as an actual error, and not simply
|
||||||
|
// as "false" like the above case of a 404
|
||||||
|
func TestOrganizationsService_IsTeamMember_error(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/teams/1/members/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
http.Error(w, "BadRequest", http.StatusBadRequest)
|
||||||
|
})
|
||||||
|
|
||||||
|
member, _, err := client.Organizations.IsTeamMember(1, "u")
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected HTTP 400 response")
|
||||||
|
}
|
||||||
|
if want := false; member != want {
|
||||||
|
t.Errorf("Organizations.IsTeamMember returned %+v, want %+v", member, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_IsTeamMember_invalidUser(t *testing.T) {
|
||||||
|
_, _, err := client.Organizations.IsTeamMember(1, "%")
|
||||||
|
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) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/public_members/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "PUT")
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Organizations.PublicizeMembership("o", "u")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.PublicizeMembership returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_PublicizeMembership_invalidOrg(t *testing.T) {
|
||||||
|
_, err := client.Organizations.PublicizeMembership("%", "u")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_ConcealMembership(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/public_members/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Organizations.ConcealMembership("o", "u")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.ConcealMembership returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_ConcealMembership_invalidOrg(t *testing.T) {
|
||||||
|
_, err := client.Organizations.ConcealMembership("%", "u")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_ListTeamRepos(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/teams/1/repos", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{"page": "2"})
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListOptions{Page: 2}
|
||||||
|
members, _, err := client.Organizations.ListTeamRepos(1, opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.ListTeamRepos returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Repository{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(members, want) {
|
||||||
|
t.Errorf("Organizations.ListTeamRepos returned %+v, want %+v", members, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_IsTeamRepo_true(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
managed, _, err := client.Organizations.IsTeamRepo(1, "o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.IsTeamRepo returned error: %v", err)
|
||||||
|
}
|
||||||
|
if want := true; managed != want {
|
||||||
|
t.Errorf("Organizations.IsTeamRepo returned %+v, want %+v", managed, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_IsTeamRepo_false(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
})
|
||||||
|
|
||||||
|
managed, _, err := client.Organizations.IsTeamRepo(1, "o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.IsTeamRepo returned error: %v", err)
|
||||||
|
}
|
||||||
|
if want := false; managed != want {
|
||||||
|
t.Errorf("Organizations.IsTeamRepo returned %+v, want %+v", managed, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_IsTeamRepo_error(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
http.Error(w, "BadRequest", http.StatusBadRequest)
|
||||||
|
})
|
||||||
|
|
||||||
|
managed, _, err := client.Organizations.IsTeamRepo(1, "o", "r")
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected HTTP 400 response")
|
||||||
|
}
|
||||||
|
if want := false; managed != want {
|
||||||
|
t.Errorf("Organizations.IsTeamRepo returned %+v, want %+v", managed, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_IsTeamRepo_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Organizations.IsTeamRepo(1, "%", "r")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_AddTeamRepo(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "PUT")
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Organizations.AddTeamRepo(1, "o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.AddTeamRepo returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_AddTeamRepo_noAccess(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "PUT")
|
||||||
|
w.WriteHeader(422)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Organizations.AddTeamRepo(1, "o", "r")
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expcted error to be returned")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_AddTeamRepo_invalidOwner(t *testing.T) {
|
||||||
|
_, err := client.Organizations.AddTeamRepo(1, "%", "r")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_RemoveTeamRepo(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Organizations.RemoveTeamRepo(1, "o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.RemoveTeamRepo returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_RemoveTeamRepo_invalidOwner(t *testing.T) {
|
||||||
|
_, err := client.Organizations.RemoveTeamRepo(1, "%", "r")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
120
Godeps/_workspace/src/github.com/google/go-github/github/orgs_test.go
generated
vendored
Normal file
120
Godeps/_workspace/src/github.com/google/go-github/github/orgs_test.go
generated
vendored
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestOrganizationsService_List_authenticatedUser(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/user/orgs", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `[{"id":1},{"id":2}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
orgs, _, err := client.Organizations.List("", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.List returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Organization{{ID: Int(1)}, {ID: Int(2)}}
|
||||||
|
if !reflect.DeepEqual(orgs, want) {
|
||||||
|
t.Errorf("Organizations.List returned %+v, want %+v", orgs, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_List_specifiedUser(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/users/u/orgs", 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}
|
||||||
|
orgs, _, err := client.Organizations.List("u", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.List returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Organization{{ID: Int(1)}, {ID: Int(2)}}
|
||||||
|
if !reflect.DeepEqual(orgs, want) {
|
||||||
|
t.Errorf("Organizations.List returned %+v, want %+v", orgs, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_List_invalidUser(t *testing.T) {
|
||||||
|
_, _, err := client.Organizations.List("%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_Get(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"id":1, "login":"l", "url":"u", "avatar_url": "a", "location":"l"}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
org, _, err := client.Organizations.Get("o")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.Get returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Organization{ID: Int(1), Login: String("l"), URL: String("u"), AvatarURL: String("a"), Location: String("l")}
|
||||||
|
if !reflect.DeepEqual(org, want) {
|
||||||
|
t.Errorf("Organizations.Get returned %+v, want %+v", org, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_Get_invalidOrg(t *testing.T) {
|
||||||
|
_, _, err := client.Organizations.Get("%")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_Edit(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &Organization{Login: String("l")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(Organization)
|
||||||
|
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}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
org, _, err := client.Organizations.Edit("o", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Organizations.Edit returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Organization{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(org, want) {
|
||||||
|
t.Errorf("Organizations.Edit returned %+v, want %+v", org, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrganizationsService_Edit_invalidOrg(t *testing.T) {
|
||||||
|
_, _, err := client.Organizations.Edit("%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
243
Godeps/_workspace/src/github.com/google/go-github/github/pulls.go
generated
vendored
Normal file
243
Godeps/_workspace/src/github.com/google/go-github/github/pulls.go
generated
vendored
Normal file
@@ -0,0 +1,243 @@
|
|||||||
|
// 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"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PullRequestsService handles communication with the pull request related
|
||||||
|
// methods of the GitHub API.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/pulls/
|
||||||
|
type PullRequestsService struct {
|
||||||
|
client *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// PullRequest represents a GitHub pull request on a repository.
|
||||||
|
type PullRequest struct {
|
||||||
|
Number *int `json:"number,omitempty"`
|
||||||
|
State *string `json:"state,omitempty"`
|
||||||
|
Title *string `json:"title,omitempty"`
|
||||||
|
Body *string `json:"body,omitempty"`
|
||||||
|
CreatedAt *time.Time `json:"created_at,omitempty"`
|
||||||
|
UpdatedAt *time.Time `json:"updated_at,omitempty"`
|
||||||
|
ClosedAt *time.Time `json:"closed_at,omitempty"`
|
||||||
|
MergedAt *time.Time `json:"merged_at,omitempty"`
|
||||||
|
User *User `json:"user,omitempty"`
|
||||||
|
Merged *bool `json:"merged,omitempty"`
|
||||||
|
Mergeable *bool `json:"mergeable,omitempty"`
|
||||||
|
MergedBy *User `json:"merged_by,omitempty"`
|
||||||
|
Comments *int `json:"comments,omitempty"`
|
||||||
|
Commits *int `json:"commits,omitempty"`
|
||||||
|
Additions *int `json:"additions,omitempty"`
|
||||||
|
Deletions *int `json:"deletions,omitempty"`
|
||||||
|
ChangedFiles *int `json:"changed_files,omitempty"`
|
||||||
|
HTMLURL *string `json:"html_url,omitempty"`
|
||||||
|
StatusesURL *string `json:"statuses_url,omitempty"`
|
||||||
|
|
||||||
|
// TODO(willnorris): add head and base once we have a Commit struct defined somewhere
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p PullRequest) String() string {
|
||||||
|
return Stringify(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PullRequestListOptions specifies the optional parameters to the
|
||||||
|
// PullRequestsService.List method.
|
||||||
|
type PullRequestListOptions struct {
|
||||||
|
// State filters pull requests based on their state. Possible values are:
|
||||||
|
// open, closed. Default is "open".
|
||||||
|
State string `url:"state,omitempty"`
|
||||||
|
|
||||||
|
// Head filters pull requests by head user and branch name in the format of:
|
||||||
|
// "user:ref-name".
|
||||||
|
Head string `url:"head,omitempty"`
|
||||||
|
|
||||||
|
// Base filters pull requests by base branch name.
|
||||||
|
Base string `url:"base,omitempty"`
|
||||||
|
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// List the pull requests for the specified repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/pulls/#list-pull-requests
|
||||||
|
func (s *PullRequestsService) List(owner string, repo string, opt *PullRequestListOptions) ([]PullRequest, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/pulls", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
pulls := new([]PullRequest)
|
||||||
|
resp, err := s.client.Do(req, pulls)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *pulls, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a single pull request.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/pulls/#get-a-single-pull-request
|
||||||
|
func (s *PullRequestsService) Get(owner string, repo string, number int) (*PullRequest, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pull := new(PullRequest)
|
||||||
|
resp, err := s.client.Do(req, pull)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return pull, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new pull request on the specified repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/pulls/#create-a-pull-request
|
||||||
|
func (s *PullRequestsService) Create(owner string, repo string, pull *PullRequest) (*PullRequest, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/pulls", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("POST", u, pull)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
p := new(PullRequest)
|
||||||
|
resp, err := s.client.Do(req, p)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return p, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Edit a pull request.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/pulls/#update-a-pull-request
|
||||||
|
func (s *PullRequestsService) Edit(owner string, repo string, number int, pull *PullRequest) (*PullRequest, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number)
|
||||||
|
req, err := s.client.NewRequest("PATCH", u, pull)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
p := new(PullRequest)
|
||||||
|
resp, err := s.client.Do(req, p)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return p, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListCommits lists the commits in a pull request.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/pulls/#list-commits-on-a-pull-request
|
||||||
|
func (s *PullRequestsService) ListCommits(owner string, repo string, number int, opt *ListOptions) (*[]Commit, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/pulls/%d/commits", owner, repo, number)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
commits := new([]Commit)
|
||||||
|
resp, err := s.client.Do(req, commits)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return commits, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListFiles lists the files in a pull request.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/pulls/#list-pull-requests-files
|
||||||
|
func (s *PullRequestsService) ListFiles(owner string, repo string, number int, opt *ListOptions) (*[]CommitFile, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/pulls/%d/files", owner, repo, number)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
commitFiles := new([]CommitFile)
|
||||||
|
resp, err := s.client.Do(req, commitFiles)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return commitFiles, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsMerged checks if a pull request has been merged.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/pulls/#get-if-a-pull-request-has-been-merged
|
||||||
|
func (s *PullRequestsService) IsMerged(owner string, repo string, number int) (bool, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/pulls/%d/merge", owner, repo, number)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := s.client.Do(req, nil)
|
||||||
|
merged, err := parseBoolResponse(err)
|
||||||
|
return merged, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// PullRequestMergeResult represents the result of merging a pull request.
|
||||||
|
type PullRequestMergeResult struct {
|
||||||
|
SHA *string `json:"sha,omitempty"`
|
||||||
|
Merged *bool `json:"merged,omitempty"`
|
||||||
|
Message *string `json:"message,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type pullRequestMergeRequest struct {
|
||||||
|
CommitMessage *string `json:"commit_message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge a pull request (Merge Button™).
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-buttontrade
|
||||||
|
func (s *PullRequestsService) Merge(owner string, repo string, number int, commitMessage string) (*PullRequestMergeResult, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/pulls/%d/merge", owner, repo, number)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("PUT", u, &pullRequestMergeRequest{
|
||||||
|
CommitMessage: &commitMessage,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
mergeResult := new(PullRequestMergeResult)
|
||||||
|
resp, err := s.client.Do(req, mergeResult)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return mergeResult, resp, err
|
||||||
|
}
|
||||||
140
Godeps/_workspace/src/github.com/google/go-github/github/pulls_comments.go
generated
vendored
Normal file
140
Godeps/_workspace/src/github.com/google/go-github/github/pulls_comments.go
generated
vendored
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
// 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"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PullRequestComment represents a comment left on a pull request.
|
||||||
|
type PullRequestComment struct {
|
||||||
|
ID *int `json:"id,omitempty"`
|
||||||
|
Body *string `json:"body,omitempty"`
|
||||||
|
Path *string `json:"path,omitempty"`
|
||||||
|
Position *int `json:"position,omitempty"`
|
||||||
|
CommitID *string `json:"commit_id,omitempty"`
|
||||||
|
User *User `json:"user,omitempty"`
|
||||||
|
CreatedAt *time.Time `json:"created_at,omitempty"`
|
||||||
|
UpdatedAt *time.Time `json:"updated_at,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p PullRequestComment) String() string {
|
||||||
|
return Stringify(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PullRequestListCommentsOptions specifies the optional parameters to the
|
||||||
|
// PullRequestsService.ListComments method.
|
||||||
|
type PullRequestListCommentsOptions struct {
|
||||||
|
// Sort specifies how to sort comments. Possible values are: created, updated.
|
||||||
|
Sort string `url:"sort,omitempty"`
|
||||||
|
|
||||||
|
// Direction in which to sort comments. Possible values are: asc, desc.
|
||||||
|
Direction string `url:"direction,omitempty"`
|
||||||
|
|
||||||
|
// Since filters comments by time.
|
||||||
|
Since time.Time `url:"since,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListComments lists all comments on the specified pull request. Specifying a
|
||||||
|
// pull request number of 0 will return all comments on all pull requests for
|
||||||
|
// the repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/pulls/comments/#list-comments-on-a-pull-request
|
||||||
|
func (s *PullRequestsService) ListComments(owner string, repo string, number int, opt *PullRequestListCommentsOptions) ([]PullRequestComment, *Response, error) {
|
||||||
|
var u string
|
||||||
|
if number == 0 {
|
||||||
|
u = fmt.Sprintf("repos/%v/%v/pulls/comments", owner, repo)
|
||||||
|
} else {
|
||||||
|
u = fmt.Sprintf("repos/%v/%v/pulls/%d/comments", owner, repo, number)
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
comments := new([]PullRequestComment)
|
||||||
|
resp, err := s.client.Do(req, comments)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *comments, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetComment fetches the specified pull request comment.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/pulls/comments/#get-a-single-comment
|
||||||
|
func (s *PullRequestsService) GetComment(owner string, repo string, number int) (*PullRequestComment, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/pulls/comments/%d", owner, repo, number)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
comment := new(PullRequestComment)
|
||||||
|
resp, err := s.client.Do(req, comment)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return comment, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateComment creates a new comment on the specified pull request.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/pulls/comments/#get-a-single-comment
|
||||||
|
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)
|
||||||
|
req, err := s.client.NewRequest("POST", u, comment)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
c := new(PullRequestComment)
|
||||||
|
resp, err := s.client.Do(req, c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditComment updates a pull request comment.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/pulls/comments/#edit-a-comment
|
||||||
|
func (s *PullRequestsService) EditComment(owner string, repo string, number int, comment *PullRequestComment) (*PullRequestComment, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/pulls/comments/%d", owner, repo, number)
|
||||||
|
req, err := s.client.NewRequest("PATCH", u, comment)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
c := new(PullRequestComment)
|
||||||
|
resp, err := s.client.Do(req, c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteComment deletes a pull request comment.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/pulls/comments/#delete-a-comment
|
||||||
|
func (s *PullRequestsService) DeleteComment(owner string, repo string, number int) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/pulls/comments/%d", owner, repo, number)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
185
Godeps/_workspace/src/github.com/google/go-github/github/pulls_comments_test.go
generated
vendored
Normal file
185
Godeps/_workspace/src/github.com/google/go-github/github/pulls_comments_test.go
generated
vendored
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPullRequestsService_ListComments_allPulls(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/pulls/comments", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"sort": "updated",
|
||||||
|
"direction": "desc",
|
||||||
|
"since": "2002-02-10T15:30:00Z",
|
||||||
|
})
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &PullRequestListCommentsOptions{"updated", "desc",
|
||||||
|
time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC),
|
||||||
|
}
|
||||||
|
pulls, _, err := client.PullRequests.ListComments("o", "r", 0, opt)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("PullRequests.ListComments returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []PullRequestComment{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(pulls, want) {
|
||||||
|
t.Errorf("PullRequests.ListComments returned %+v, want %+v", pulls, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullRequestsService_ListComments_specificPull(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/pulls/1/comments", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
pulls, _, err := client.PullRequests.ListComments("o", "r", 1, nil)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("PullRequests.ListComments returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []PullRequestComment{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(pulls, want) {
|
||||||
|
t.Errorf("PullRequests.ListComments returned %+v, want %+v", pulls, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullRequestsService_ListComments_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.PullRequests.ListComments("%", "r", 1, nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullRequestsService_GetComment(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/pulls/comments/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
comment, _, err := client.PullRequests.GetComment("o", "r", 1)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("PullRequests.GetComment returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &PullRequestComment{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(comment, want) {
|
||||||
|
t.Errorf("PullRequests.GetComment returned %+v, want %+v", comment, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullRequestsService_GetComment_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.PullRequests.GetComment("%", "r", 1)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullRequestsService_CreateComment(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &PullRequestComment{Body: String("b")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/pulls/1/comments", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(PullRequestComment)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
comment, _, err := client.PullRequests.CreateComment("o", "r", 1, input)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("PullRequests.CreateComment returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &PullRequestComment{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(comment, want) {
|
||||||
|
t.Errorf("PullRequests.CreateComment returned %+v, want %+v", comment, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullRequestsService_CreateComment_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.PullRequests.CreateComment("%", "r", 1, nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullRequestsService_EditComment(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &PullRequestComment{Body: String("b")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/pulls/comments/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(PullRequestComment)
|
||||||
|
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}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
comment, _, err := client.PullRequests.EditComment("o", "r", 1, input)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("PullRequests.EditComment returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &PullRequestComment{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(comment, want) {
|
||||||
|
t.Errorf("PullRequests.EditComment returned %+v, want %+v", comment, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullRequestsService_EditComment_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.PullRequests.EditComment("%", "r", 1, nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullRequestsService_DeleteComment(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/pulls/comments/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.PullRequests.DeleteComment("o", "r", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("PullRequests.DeleteComment returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullRequestsService_DeleteComment_invalidOwner(t *testing.T) {
|
||||||
|
_, err := client.PullRequests.DeleteComment("%", "r", 1)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
309
Godeps/_workspace/src/github.com/google/go-github/github/pulls_test.go
generated
vendored
Normal file
309
Godeps/_workspace/src/github.com/google/go-github/github/pulls_test.go
generated
vendored
Normal file
@@ -0,0 +1,309 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPullRequestsService_List(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/pulls", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"state": "closed",
|
||||||
|
"head": "h",
|
||||||
|
"base": "b",
|
||||||
|
"page": "2",
|
||||||
|
})
|
||||||
|
fmt.Fprint(w, `[{"number":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &PullRequestListOptions{"closed", "h", "b", ListOptions{Page: 2}}
|
||||||
|
pulls, _, err := client.PullRequests.List("o", "r", opt)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("PullRequests.List returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []PullRequest{{Number: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(pulls, want) {
|
||||||
|
t.Errorf("PullRequests.List returned %+v, want %+v", pulls, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullRequestsService_List_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.PullRequests.List("%", "r", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullRequestsService_Get(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}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
pull, _, err := client.PullRequests.Get("o", "r", 1)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("PullRequests.Get returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &PullRequest{Number: Int(1)}
|
||||||
|
if !reflect.DeepEqual(pull, want) {
|
||||||
|
t.Errorf("PullRequests.Get returned %+v, want %+v", pull, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullRequestsService_Get_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.PullRequests.Get("%", "r", 1)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullRequestsService_Create(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &PullRequest{Title: String("t")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/pulls", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(PullRequest)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"number":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
pull, _, err := client.PullRequests.Create("o", "r", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("PullRequests.Create returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &PullRequest{Number: Int(1)}
|
||||||
|
if !reflect.DeepEqual(pull, want) {
|
||||||
|
t.Errorf("PullRequests.Create returned %+v, want %+v", pull, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullRequestsService_Create_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.PullRequests.Create("%", "r", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullRequestsService_Edit(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &PullRequest{Title: String("t")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/pulls/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(PullRequest)
|
||||||
|
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, `{"number":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
pull, _, err := client.PullRequests.Edit("o", "r", 1, input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("PullRequests.Edit returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &PullRequest{Number: Int(1)}
|
||||||
|
if !reflect.DeepEqual(pull, want) {
|
||||||
|
t.Errorf("PullRequests.Edit returned %+v, want %+v", pull, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullRequestsService_Edit_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.PullRequests.Edit("%", "r", 1, nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullRequestsService_ListCommits(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/pulls/1/commits", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{"page": "2"})
|
||||||
|
fmt.Fprint(w, `
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"sha": "3",
|
||||||
|
"parents": [
|
||||||
|
{
|
||||||
|
"sha": "2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "2",
|
||||||
|
"parents": [
|
||||||
|
{
|
||||||
|
"sha": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListOptions{Page: 2}
|
||||||
|
commits, _, err := client.PullRequests.ListCommits("o", "r", 1, opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("PullRequests.ListCommits returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &[]Commit{
|
||||||
|
Commit{
|
||||||
|
SHA: String("3"),
|
||||||
|
Parents: []Commit{
|
||||||
|
Commit{
|
||||||
|
SHA: String("2"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Commit{
|
||||||
|
SHA: String("2"),
|
||||||
|
Parents: []Commit{
|
||||||
|
Commit{
|
||||||
|
SHA: String("1"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(commits, want) {
|
||||||
|
t.Errorf("PullRequests.ListCommits returned %+v, want %+v", commits, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullRequestsService_ListFiles(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/pulls/1/files", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{"page": "2"})
|
||||||
|
fmt.Fprint(w, `
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
||||||
|
"filename": "file1.txt",
|
||||||
|
"status": "added",
|
||||||
|
"additions": 103,
|
||||||
|
"deletions": 21,
|
||||||
|
"changes": 124,
|
||||||
|
"patch": "@@ -132,7 +132,7 @@ module Test @@ -1000,7 +1000,7 @@ module Test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "f61aebed695e2e4193db5e6dcb09b5b57875f334",
|
||||||
|
"filename": "file2.txt",
|
||||||
|
"status": "modified",
|
||||||
|
"additions": 5,
|
||||||
|
"deletions": 3,
|
||||||
|
"changes": 103,
|
||||||
|
"patch": "@@ -132,7 +132,7 @@ module Test @@ -1000,7 +1000,7 @@ module Test"
|
||||||
|
}
|
||||||
|
]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListOptions{Page: 2}
|
||||||
|
commitFiles, _, err := client.PullRequests.ListFiles("o", "r", 1, opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("PullRequests.ListFiles returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &[]CommitFile{
|
||||||
|
CommitFile{
|
||||||
|
SHA: String("6dcb09b5b57875f334f61aebed695e2e4193db5e"),
|
||||||
|
Filename: String("file1.txt"),
|
||||||
|
Additions: Int(103),
|
||||||
|
Deletions: Int(21),
|
||||||
|
Changes: Int(124),
|
||||||
|
Status: String("added"),
|
||||||
|
Patch: String("@@ -132,7 +132,7 @@ module Test @@ -1000,7 +1000,7 @@ module Test"),
|
||||||
|
},
|
||||||
|
CommitFile{
|
||||||
|
SHA: String("f61aebed695e2e4193db5e6dcb09b5b57875f334"),
|
||||||
|
Filename: String("file2.txt"),
|
||||||
|
Additions: Int(5),
|
||||||
|
Deletions: Int(3),
|
||||||
|
Changes: Int(103),
|
||||||
|
Status: String("modified"),
|
||||||
|
Patch: String("@@ -132,7 +132,7 @@ module Test @@ -1000,7 +1000,7 @@ module Test"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(commitFiles, want) {
|
||||||
|
t.Errorf("PullRequests.ListFiles returned %+v, want %+v", commitFiles, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullRequestsService_IsMerged(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/pulls/1/merge", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
isMerged, _, err := client.PullRequests.IsMerged("o", "r", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("PullRequests.IsMerged returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := true
|
||||||
|
if !reflect.DeepEqual(isMerged, want) {
|
||||||
|
t.Errorf("PullRequests.IsMerged returned %+v, want %+v", isMerged, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullRequestsService_Merge(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/pulls/1/merge", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "PUT")
|
||||||
|
fmt.Fprint(w, `
|
||||||
|
{
|
||||||
|
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
||||||
|
"merged": true,
|
||||||
|
"message": "Pull Request successfully merged"
|
||||||
|
}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
merge, _, err := client.PullRequests.Merge("o", "r", 1, "merging pull request")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("PullRequests.Merge returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &PullRequestMergeResult{
|
||||||
|
SHA: String("6dcb09b5b57875f334f61aebed695e2e4193db5e"),
|
||||||
|
Merged: Bool(true),
|
||||||
|
Message: String("Pull Request successfully merged"),
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(merge, want) {
|
||||||
|
t.Errorf("PullRequests.Merge returned %+v, want %+v", merge, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
476
Godeps/_workspace/src/github.com/google/go-github/github/repos.go
generated
vendored
Normal file
476
Godeps/_workspace/src/github.com/google/go-github/github/repos.go
generated
vendored
Normal file
@@ -0,0 +1,476 @@
|
|||||||
|
// 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"
|
||||||
|
|
||||||
|
// RepositoriesService handles communication with the repository related
|
||||||
|
// methods of the GitHub API.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/
|
||||||
|
type RepositoriesService struct {
|
||||||
|
client *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// Repository represents a GitHub repository.
|
||||||
|
type Repository struct {
|
||||||
|
ID *int `json:"id,omitempty"`
|
||||||
|
Owner *User `json:"owner,omitempty"`
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
FullName *string `json:"full_name,omitempty"`
|
||||||
|
Description *string `json:"description,omitempty"`
|
||||||
|
Homepage *string `json:"homepage,omitempty"`
|
||||||
|
DefaultBranch *string `json:"default_branch,omitempty"`
|
||||||
|
MasterBranch *string `json:"master_branch,omitempty"`
|
||||||
|
CreatedAt *Timestamp `json:"created_at,omitempty"`
|
||||||
|
PushedAt *Timestamp `json:"pushed_at,omitempty"`
|
||||||
|
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
|
||||||
|
HTMLURL *string `json:"html_url,omitempty"`
|
||||||
|
CloneURL *string `json:"clone_url,omitempty"`
|
||||||
|
GitURL *string `json:"git_url,omitempty"`
|
||||||
|
MirrorURL *string `json:"mirror_url,omitempty"`
|
||||||
|
SSHURL *string `json:"ssh_url,omitempty"`
|
||||||
|
SVNURL *string `json:"svn_url,omitempty"`
|
||||||
|
Language *string `json:"language,omitempty"`
|
||||||
|
Fork *bool `json:"fork"`
|
||||||
|
ForksCount *int `json:"forks_count,omitempty"`
|
||||||
|
NetworkCount *int `json:"network_count,omitempty"`
|
||||||
|
OpenIssuesCount *int `json:"open_issues_count,omitempty"`
|
||||||
|
StargazersCount *int `json:"stargazers_count,omitempty"`
|
||||||
|
SubscribersCount *int `json:"subscribers_count,omitempty"`
|
||||||
|
WatchersCount *int `json:"watchers_count,omitempty"`
|
||||||
|
Size *int `json:"size,omitempty"`
|
||||||
|
Parent *Repository `json:"parent,omitempty"`
|
||||||
|
Source *Repository `json:"source,omitempty"`
|
||||||
|
Organization *Organization `json:"organization,omitempty"`
|
||||||
|
Permissions *map[string]bool `json:"permissions,omitempty"`
|
||||||
|
|
||||||
|
// Additional mutable fields when creating and editing a repository
|
||||||
|
Private *bool `json:"private"`
|
||||||
|
HasIssues *bool `json:"has_issues"`
|
||||||
|
HasWiki *bool `json:"has_wiki"`
|
||||||
|
HasDownloads *bool `json:"has_downloads"`
|
||||||
|
|
||||||
|
// API URLs
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
ArchiveURL *string `json:"archive_url,omitempty"`
|
||||||
|
AssigneesURL *string `json:"assignees_url,omitempty"`
|
||||||
|
BlobsURL *string `json:"blobs_url,omitempty"`
|
||||||
|
BranchesURL *string `json:"branches_url,omitempty"`
|
||||||
|
CollaboratorsURL *string `json:"collaborators_url,omitempty"`
|
||||||
|
CommentsURL *string `json:"comments_url,omitempty"`
|
||||||
|
CommitsURL *string `json:"commits_url,omitempty"`
|
||||||
|
CompareURL *string `json:"compare_url,omitempty"`
|
||||||
|
ContentsURL *string `json:"contents_url,omitempty"`
|
||||||
|
ContributorsURL *string `json:"contributors_url,omitempty"`
|
||||||
|
DownloadsURL *string `json:"downloads_url,omitempty"`
|
||||||
|
EventsURL *string `json:"events_url,omitempty"`
|
||||||
|
ForksURL *string `json:"forks_url,omitempty"`
|
||||||
|
GitCommitsURL *string `json:"git_commits_url,omitempty"`
|
||||||
|
GitRefsURL *string `json:"git_refs_url,omitempty"`
|
||||||
|
GitTagsURL *string `json:"git_tags_url,omitempty"`
|
||||||
|
HooksURL *string `json:"hooks_url,omitempty"`
|
||||||
|
IssueCommentURL *string `json:"issue_comment_url,omitempty"`
|
||||||
|
IssueEventsURL *string `json:"issue_events_url,omitempty"`
|
||||||
|
IssuesURL *string `json:"issues_url,omitempty"`
|
||||||
|
KeysURL *string `json:"keys_url,omitempty"`
|
||||||
|
LabelsURL *string `json:"labels_url,omitempty"`
|
||||||
|
LanguagesURL *string `json:"languages_url,omitempty"`
|
||||||
|
MergesURL *string `json:"merges_url,omitempty"`
|
||||||
|
MilestonesURL *string `json:"milestones_url,omitempty"`
|
||||||
|
NotificationsURL *string `json:"notifications_url,omitempty"`
|
||||||
|
PullsURL *string `json:"pulls_url,omitempty"`
|
||||||
|
ReleasesURL *string `json:"releases_url,omitempty"`
|
||||||
|
StargazersURL *string `json:"stargazers_url,omitempty"`
|
||||||
|
StatusesURL *string `json:"statuses_url,omitempty"`
|
||||||
|
SubscribersURL *string `json:"subscribers_url,omitempty"`
|
||||||
|
SubscriptionURL *string `json:"subscription_url,omitempty"`
|
||||||
|
TagsURL *string `json:"tags_url,omitempty"`
|
||||||
|
TreesURL *string `json:"trees_url,omitempty"`
|
||||||
|
TeamsURL *string `json:"teams_url,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r Repository) String() string {
|
||||||
|
return Stringify(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepositoryListOptions specifies the optional parameters to the
|
||||||
|
// RepositoriesService.List method.
|
||||||
|
type RepositoryListOptions struct {
|
||||||
|
// Type of repositories to list. Possible values are: all, owner, public,
|
||||||
|
// private, member. Default is "all".
|
||||||
|
Type string `url:"type,omitempty"`
|
||||||
|
|
||||||
|
// How to sort the repository list. Possible values are: created, updated,
|
||||||
|
// pushed, full_name. Default is "full_name".
|
||||||
|
Sort string `url:"sort,omitempty"`
|
||||||
|
|
||||||
|
// Direction in which to sort repositories. Possible values are: asc, desc.
|
||||||
|
// Default is "asc" when sort is "full_name", otherwise default is "desc".
|
||||||
|
Direction string `url:"direction,omitempty"`
|
||||||
|
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// List the repositories for a user. Passing the empty string will list
|
||||||
|
// repositories for the authenticated user.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/#list-user-repositories
|
||||||
|
func (s *RepositoriesService) List(user string, opt *RepositoryListOptions) ([]Repository, *Response, error) {
|
||||||
|
var u string
|
||||||
|
if user != "" {
|
||||||
|
u = fmt.Sprintf("users/%v/repos", user)
|
||||||
|
} else {
|
||||||
|
u = "user/repos"
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
repos := new([]Repository)
|
||||||
|
resp, err := s.client.Do(req, repos)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *repos, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepositoryListByOrgOptions specifies the optional parameters to the
|
||||||
|
// RepositoriesService.ListByOrg method.
|
||||||
|
type RepositoryListByOrgOptions struct {
|
||||||
|
// Type of repositories to list. Possible values are: all, public, private,
|
||||||
|
// forks, sources, member. Default is "all".
|
||||||
|
Type string `url:"type,omitempty"`
|
||||||
|
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListByOrg lists the repositories for an organization.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/#list-organization-repositories
|
||||||
|
func (s *RepositoriesService) ListByOrg(org string, opt *RepositoryListByOrgOptions) ([]Repository, *Response, error) {
|
||||||
|
u := fmt.Sprintf("orgs/%v/repos", 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
|
||||||
|
}
|
||||||
|
|
||||||
|
repos := new([]Repository)
|
||||||
|
resp, err := s.client.Do(req, repos)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *repos, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepositoryListAllOptions specifies the optional parameters to the
|
||||||
|
// RepositoriesService.ListAll method.
|
||||||
|
type RepositoryListAllOptions struct {
|
||||||
|
// ID of the last repository seen
|
||||||
|
Since int `url:"since,omitempty"`
|
||||||
|
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListAll lists all GitHub repositories in the order that they were created.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/#list-all-public-repositories
|
||||||
|
func (s *RepositoriesService) ListAll(opt *RepositoryListAllOptions) ([]Repository, *Response, error) {
|
||||||
|
u, err := addOptions("repositories", opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
repos := new([]Repository)
|
||||||
|
resp, err := s.client.Do(req, repos)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *repos, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new repository. If an organization is specified, the new
|
||||||
|
// repository will be created under that org. If the empty string is
|
||||||
|
// specified, it will be created for the authenticated user.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/#create
|
||||||
|
func (s *RepositoriesService) Create(org string, repo *Repository) (*Repository, *Response, error) {
|
||||||
|
var u string
|
||||||
|
if org != "" {
|
||||||
|
u = fmt.Sprintf("orgs/%v/repos", org)
|
||||||
|
} else {
|
||||||
|
u = "user/repos"
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("POST", u, repo)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := new(Repository)
|
||||||
|
resp, err := s.client.Do(req, r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return r, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get fetches a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/#get
|
||||||
|
func (s *RepositoriesService) Get(owner, repo string) (*Repository, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
repository := new(Repository)
|
||||||
|
resp, err := s.client.Do(req, repository)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return repository, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Edit updates a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/#edit
|
||||||
|
func (s *RepositoriesService) Edit(owner, repo string, repository *Repository) (*Repository, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("PATCH", u, repository)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := new(Repository)
|
||||||
|
resp, err := s.client.Do(req, r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return r, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/repos/#delete-a-repository
|
||||||
|
func (s *RepositoriesService) Delete(owner, repo string) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contributor represents a repository contributor
|
||||||
|
type Contributor struct {
|
||||||
|
Login *string `json:"login,omitempty"`
|
||||||
|
ID *int `json:"id,omitempty"`
|
||||||
|
AvatarURL *string `json:"avatar_url,omitempty"`
|
||||||
|
GravatarID *string `json:"gravatar_id,omitempty"`
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
HTMLURL *string `json:"html_url,omitempty"`
|
||||||
|
FollowersURL *string `json:"followers_url,omitempty"`
|
||||||
|
FollowingURL *string `json:"following_url,omitempty"`
|
||||||
|
GistsURL *string `json:"gists_url,omitempty"`
|
||||||
|
StarredURL *string `json:"starred_url,omitempty"`
|
||||||
|
SubscriptionsURL *string `json:"subscriptions_url,omitempty"`
|
||||||
|
OrganizationsURL *string `json:"organizations_url,omitempty"`
|
||||||
|
ReposURL *string `json:"repos_url,omitempty"`
|
||||||
|
EventsURL *string `json:"events_url,omitempty"`
|
||||||
|
ReceivedEventsURL *string `json:"received_events_url,omitempty"`
|
||||||
|
Type *string `json:"type,omitempty"`
|
||||||
|
SiteAdmin *bool `json:"site_admin"`
|
||||||
|
Contributions *int `json:"contributions,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListContributorsOptions specifies the optional parameters to the
|
||||||
|
// RepositoriesService.ListContributors method.
|
||||||
|
type ListContributorsOptions struct {
|
||||||
|
// Include anonymous contributors in results or not
|
||||||
|
Anon string `url:"anon,omitempty"`
|
||||||
|
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListContributors lists contributors for a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/#list-contributors
|
||||||
|
func (s *RepositoriesService) ListContributors(owner string, repository string, opt *ListContributorsOptions) ([]Contributor, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/contributors", owner, repository)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
contributor := new([]Contributor)
|
||||||
|
resp, err := s.client.Do(req, contributor)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *contributor, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListLanguages lists languages for the specified repository. The returned map
|
||||||
|
// specifies the languages and the number of bytes of code written in that
|
||||||
|
// language. For example:
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// "C": 78769,
|
||||||
|
// "Python": 7769
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// GitHub API Docs: http://developer.github.com/v3/repos/#list-languages
|
||||||
|
func (s *RepositoriesService) ListLanguages(owner string, repo string) (map[string]int, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/languages", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
languages := make(map[string]int)
|
||||||
|
resp, err := s.client.Do(req, &languages)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return languages, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListTeams lists the teams for the specified repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/repos/#list-teams
|
||||||
|
func (s *RepositoriesService) ListTeams(owner string, repo string, opt *ListOptions) ([]Team, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/teams", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
teams := new([]Team)
|
||||||
|
resp, err := s.client.Do(req, teams)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *teams, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepositoryTag represents a repository tag.
|
||||||
|
type RepositoryTag struct {
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
Commit *Commit `json:"commit,omitempty"`
|
||||||
|
ZipballURL *string `json:"zipball_url,omitempty"`
|
||||||
|
TarballURL *string `json:"tarball_url,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListTags lists tags for the specified repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/repos/#list-tags
|
||||||
|
func (s *RepositoriesService) ListTags(owner string, repo string, opt *ListOptions) ([]RepositoryTag, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/tags", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
tags := new([]RepositoryTag)
|
||||||
|
resp, err := s.client.Do(req, tags)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *tags, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Branch represents a repository branch
|
||||||
|
type Branch struct {
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
Commit *Commit `json:"commit,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListBranches lists branches for the specified repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/#list-branches
|
||||||
|
func (s *RepositoriesService) ListBranches(owner string, repo string, opt *ListOptions) ([]Branch, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/branches", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
branches := new([]Branch)
|
||||||
|
resp, err := s.client.Do(req, branches)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *branches, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBranch gets the specified branch for a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/repos/#get-branch
|
||||||
|
func (s *RepositoriesService) GetBranch(owner, repo, branch string) (*Branch, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/branches/%v", owner, repo, branch)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
b := new(Branch)
|
||||||
|
resp, err := s.client.Do(req, b)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return b, resp, err
|
||||||
|
}
|
||||||
75
Godeps/_workspace/src/github.com/google/go-github/github/repos_collaborators.go
generated
vendored
Normal file
75
Godeps/_workspace/src/github.com/google/go-github/github/repos_collaborators.go
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
// 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"
|
||||||
|
|
||||||
|
// ListCollaborators lists the Github users that have access to the repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/collaborators/#list
|
||||||
|
func (s *RepositoriesService) ListCollaborators(owner, repo string, opt *ListOptions) ([]User, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/collaborators", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
users := new([]User)
|
||||||
|
resp, err := s.client.Do(req, users)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *users, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsCollaborator checks whether the specified Github user has collaborator
|
||||||
|
// access to the given repo.
|
||||||
|
// Note: This will return false if the user is not a collaborator OR the user
|
||||||
|
// is not a GitHub user.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/collaborators/#get
|
||||||
|
func (s *RepositoriesService) IsCollaborator(owner, repo, user string) (bool, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := s.client.Do(req, nil)
|
||||||
|
isCollab, err := parseBoolResponse(err)
|
||||||
|
return isCollab, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddCollaborator adds the specified Github user as collaborator to the given repo.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/collaborators/#add-collaborator
|
||||||
|
func (s *RepositoriesService) AddCollaborator(owner, repo, user string) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user)
|
||||||
|
req, err := s.client.NewRequest("PUT", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveCollaborator removes the specified Github user as collaborator from the given repo.
|
||||||
|
// Note: Does not return error if a valid user that is not a collaborator is removed.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/collaborators/#remove-collaborator
|
||||||
|
func (s *RepositoriesService) RemoveCollaborator(owner, repo, user string) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
123
Godeps/_workspace/src/github.com/google/go-github/github/repos_collaborators_test.go
generated
vendored
Normal file
123
Godeps/_workspace/src/github.com/google/go-github/github/repos_collaborators_test.go
generated
vendored
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
// 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 TestRepositoriesService_ListCollaborators(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/collaborators", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{"page": "2"})
|
||||||
|
fmt.Fprintf(w, `[{"id":1}, {"id":2}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListOptions{Page: 2}
|
||||||
|
users, _, err := client.Repositories.ListCollaborators("o", "r", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.ListCollaborators returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []User{{ID: Int(1)}, {ID: Int(2)}}
|
||||||
|
if !reflect.DeepEqual(users, want) {
|
||||||
|
t.Errorf("Repositories.ListCollaborators returned %+v, want %+v", users, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListCollaborators_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.ListCollaborators("%", "%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_IsCollaborator_True(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/collaborators/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
isCollab, _, err := client.Repositories.IsCollaborator("o", "r", "u")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.IsCollaborator returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !isCollab {
|
||||||
|
t.Errorf("Repositories.IsCollaborator returned false, want true")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_IsCollaborator_False(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/collaborators/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
})
|
||||||
|
|
||||||
|
isCollab, _, err := client.Repositories.IsCollaborator("o", "r", "u")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.IsCollaborator returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if isCollab {
|
||||||
|
t.Errorf("Repositories.IsCollaborator returned true, want false")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_IsCollaborator_invalidUser(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.IsCollaborator("%", "%", "%")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_AddCollaborator(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/collaborators/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "PUT")
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Repositories.AddCollaborator("o", "r", "u")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.AddCollaborator returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_AddCollaborator_invalidUser(t *testing.T) {
|
||||||
|
_, err := client.Repositories.AddCollaborator("%", "%", "%")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_RemoveCollaborator(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/collaborators/u", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Repositories.RemoveCollaborator("o", "r", "u")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.RemoveCollaborator returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_RemoveCollaborator_invalidUser(t *testing.T) {
|
||||||
|
_, err := client.Repositories.RemoveCollaborator("%", "%", "%")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
150
Godeps/_workspace/src/github.com/google/go-github/github/repos_comments.go
generated
vendored
Normal file
150
Godeps/_workspace/src/github.com/google/go-github/github/repos_comments.go
generated
vendored
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
// 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"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RepositoryComment represents a comment for a commit, file, or line in a repository.
|
||||||
|
type RepositoryComment struct {
|
||||||
|
HTMLURL *string `json:"html_url,omitempty"`
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
ID *int `json:"id,omitempty"`
|
||||||
|
CommitID *string `json:"commit_id,omitempty"`
|
||||||
|
User *User `json:"user,omitempty"`
|
||||||
|
CreatedAt *time.Time `json:"created_at,omitempty"`
|
||||||
|
UpdatedAt *time.Time `json:"updated_at,omitempty"`
|
||||||
|
|
||||||
|
// User-mutable fields
|
||||||
|
Body *string `json:"body"`
|
||||||
|
// User-initialized fields
|
||||||
|
Path *string `json:"path,omitempty"`
|
||||||
|
Position *int `json:"position,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r RepositoryComment) String() string {
|
||||||
|
return Stringify(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListComments lists all the comments for the repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/comments/#list-commit-comments-for-a-repository
|
||||||
|
func (s *RepositoriesService) ListComments(owner, repo string, opt *ListOptions) ([]RepositoryComment, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/comments", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
comments := new([]RepositoryComment)
|
||||||
|
resp, err := s.client.Do(req, comments)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *comments, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListCommitComments lists all the comments for a given commit SHA.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/comments/#list-comments-for-a-single-commit
|
||||||
|
func (s *RepositoriesService) ListCommitComments(owner, repo, sha string, opt *ListOptions) ([]RepositoryComment, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/commits/%v/comments", owner, repo, sha)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
comments := new([]RepositoryComment)
|
||||||
|
resp, err := s.client.Do(req, comments)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *comments, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateComment creates a comment for the given commit.
|
||||||
|
// Note: GitHub allows for comments to be created for non-existing files and positions.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/comments/#create-a-commit-comment
|
||||||
|
func (s *RepositoriesService) CreateComment(owner, repo, sha string, comment *RepositoryComment) (*RepositoryComment, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/commits/%v/comments", owner, repo, sha)
|
||||||
|
req, err := s.client.NewRequest("POST", u, comment)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
c := new(RepositoryComment)
|
||||||
|
resp, err := s.client.Do(req, c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetComment gets a single comment from a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/comments/#get-a-single-commit-comment
|
||||||
|
func (s *RepositoriesService) GetComment(owner, repo string, id int) (*RepositoryComment, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/comments/%v", owner, repo, id)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
c := new(RepositoryComment)
|
||||||
|
resp, err := s.client.Do(req, c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateComment updates the body of a single comment.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/comments/#update-a-commit-comment
|
||||||
|
func (s *RepositoriesService) UpdateComment(owner, repo string, id int, comment *RepositoryComment) (*RepositoryComment, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/comments/%v", owner, repo, id)
|
||||||
|
req, err := s.client.NewRequest("PATCH", u, comment)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
c := new(RepositoryComment)
|
||||||
|
resp, err := s.client.Do(req, c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteComment deletes a single comment from a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/comments/#delete-a-commit-comment
|
||||||
|
func (s *RepositoriesService) DeleteComment(owner, repo string, id int) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/comments/%v", owner, repo, id)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
180
Godeps/_workspace/src/github.com/google/go-github/github/repos_comments_test.go
generated
vendored
Normal file
180
Godeps/_workspace/src/github.com/google/go-github/github/repos_comments_test.go
generated
vendored
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListComments(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/comments", 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}
|
||||||
|
comments, _, err := client.Repositories.ListComments("o", "r", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.ListComments returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []RepositoryComment{{ID: Int(1)}, {ID: Int(2)}}
|
||||||
|
if !reflect.DeepEqual(comments, want) {
|
||||||
|
t.Errorf("Repositories.ListComments returned %+v, want %+v", comments, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListComments_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.ListComments("%", "%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListCommitComments(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/commits/s/comments", 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}
|
||||||
|
comments, _, err := client.Repositories.ListCommitComments("o", "r", "s", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.ListCommitComments returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []RepositoryComment{{ID: Int(1)}, {ID: Int(2)}}
|
||||||
|
if !reflect.DeepEqual(comments, want) {
|
||||||
|
t.Errorf("Repositories.ListCommitComments returned %+v, want %+v", comments, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListCommitComments_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.ListCommitComments("%", "%", "%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_CreateComment(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &RepositoryComment{Body: String("b")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/commits/s/comments", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(RepositoryComment)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
comment, _, err := client.Repositories.CreateComment("o", "r", "s", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.CreateComment returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &RepositoryComment{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(comment, want) {
|
||||||
|
t.Errorf("Repositories.CreateComment returned %+v, want %+v", comment, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_CreateComment_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.CreateComment("%", "%", "%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_GetComment(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/comments/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
comment, _, err := client.Repositories.GetComment("o", "r", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.GetComment returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &RepositoryComment{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(comment, want) {
|
||||||
|
t.Errorf("Repositories.GetComment returned %+v, want %+v", comment, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_GetComment_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.GetComment("%", "%", 1)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_UpdateComment(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &RepositoryComment{Body: String("b")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/comments/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(RepositoryComment)
|
||||||
|
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}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
comment, _, err := client.Repositories.UpdateComment("o", "r", 1, input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.UpdateComment returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &RepositoryComment{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(comment, want) {
|
||||||
|
t.Errorf("Repositories.UpdateComment returned %+v, want %+v", comment, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_UpdateComment_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.UpdateComment("%", "%", 1, nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_DeleteComment(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/comments/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Repositories.DeleteComment("o", "r", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.DeleteComment returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_DeleteComment_invalidOwner(t *testing.T) {
|
||||||
|
_, err := client.Repositories.DeleteComment("%", "%", 1)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
164
Godeps/_workspace/src/github.com/google/go-github/github/repos_commits.go
generated
vendored
Normal file
164
Godeps/_workspace/src/github.com/google/go-github/github/repos_commits.go
generated
vendored
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
// 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"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RepositoryCommit represents a commit in a repo.
|
||||||
|
// Note that it's wrapping a Commit, so author/committer information is in two places,
|
||||||
|
// but contain different details about them: in RepositoryCommit "github details", in Commit - "git details".
|
||||||
|
type RepositoryCommit struct {
|
||||||
|
SHA *string `json:"sha,omitempty"`
|
||||||
|
Commit *Commit `json:"commit,omitempty"`
|
||||||
|
Author *User `json:"author,omitempty"`
|
||||||
|
Committer *User `json:"committer,omitempty"`
|
||||||
|
Parents []Commit `json:"parents,omitempty"`
|
||||||
|
Message *string `json:"message,omitempty"`
|
||||||
|
|
||||||
|
// Details about how many changes were made in this commit. Only filled in during GetCommit!
|
||||||
|
Stats *CommitStats `json:"stats,omitempty"`
|
||||||
|
// Details about which files, and how this commit touched. Only filled in during GetCommit!
|
||||||
|
Files []CommitFile `json:"files,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r RepositoryCommit) String() string {
|
||||||
|
return Stringify(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommitStats represents the number of additions / deletions from a file in a given RepositoryCommit.
|
||||||
|
type CommitStats struct {
|
||||||
|
Additions *int `json:"additions,omitempty"`
|
||||||
|
Deletions *int `json:"deletions,omitempty"`
|
||||||
|
Total *int `json:"total,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CommitStats) String() string {
|
||||||
|
return Stringify(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommitFile represents a file modified in a commit.
|
||||||
|
type CommitFile struct {
|
||||||
|
SHA *string `json:"sha,omitempty"`
|
||||||
|
Filename *string `json:"filename,omitempty"`
|
||||||
|
Additions *int `json:"additions,omitempty"`
|
||||||
|
Deletions *int `json:"deletions,omitempty"`
|
||||||
|
Changes *int `json:"changes,omitempty"`
|
||||||
|
Status *string `json:"status,omitempty"`
|
||||||
|
Patch *string `json:"patch,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CommitFile) String() string {
|
||||||
|
return Stringify(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommitsComparison is the result of comparing two commits.
|
||||||
|
// See CompareCommits() for details.
|
||||||
|
type CommitsComparison struct {
|
||||||
|
BaseCommit *RepositoryCommit `json:"base_commit,omitempty"`
|
||||||
|
|
||||||
|
// Head can be 'behind' or 'ahead'
|
||||||
|
Status *string `json:"status,omitempty"`
|
||||||
|
AheadBy *int `json:"ahead_by,omitempty"`
|
||||||
|
BehindBy *int `json:"behind_by,omitempty"`
|
||||||
|
TotalCommits *int `json:"total_commits,omitempty"`
|
||||||
|
|
||||||
|
Commits []RepositoryCommit `json:"commits,omitempty"`
|
||||||
|
|
||||||
|
Files []CommitFile `json:"files,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CommitsComparison) String() string {
|
||||||
|
return Stringify(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommitsListOptions specifies the optional parameters to the
|
||||||
|
// RepositoriesService.ListCommits method.
|
||||||
|
type CommitsListOptions struct {
|
||||||
|
// SHA or branch to start listing Commits from.
|
||||||
|
SHA string `url:"sha,omitempty"`
|
||||||
|
|
||||||
|
// Path that should be touched by the returned Commits.
|
||||||
|
Path string `url:"path,omitempty"`
|
||||||
|
|
||||||
|
// Author of by which to filter Commits.
|
||||||
|
Author string `url:"author,omitempty"`
|
||||||
|
|
||||||
|
// Since when should Commits be included in the response.
|
||||||
|
Since time.Time `url:"since,omitempty"`
|
||||||
|
|
||||||
|
// Until when should Commits be included in the response.
|
||||||
|
Until time.Time `url:"until,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListCommits lists the commits of a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/commits/#list
|
||||||
|
func (s *RepositoriesService) ListCommits(owner, repo string, opt *CommitsListOptions) ([]RepositoryCommit, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/commits", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
commits := new([]RepositoryCommit)
|
||||||
|
resp, err := s.client.Do(req, commits)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *commits, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCommit fetches the specified commit, including all details about it.
|
||||||
|
// todo: support media formats - https://github.com/google/go-github/issues/6
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/commits/#get-a-single-commit
|
||||||
|
// See also: http://developer.github.com//v3/git/commits/#get-a-single-commit provides the same functionality
|
||||||
|
func (s *RepositoriesService) GetCommit(owner, repo, sha string) (*RepositoryCommit, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, sha)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
commit := new(RepositoryCommit)
|
||||||
|
resp, err := s.client.Do(req, commit)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return commit, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CompareCommits compares a range of commits with each other.
|
||||||
|
// todo: support media formats - https://github.com/google/go-github/issues/6
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/commits/index.html#compare-two-commits
|
||||||
|
func (s *RepositoriesService) CompareCommits(owner, repo string, base, head string) (*CommitsComparison, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/compare/%v...%v", owner, repo, base, head)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
comp := new(CommitsComparison)
|
||||||
|
resp, err := s.client.Do(req, comp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return comp, resp, err
|
||||||
|
}
|
||||||
191
Godeps/_workspace/src/github.com/google/go-github/github/repos_commits_test.go
generated
vendored
Normal file
191
Godeps/_workspace/src/github.com/google/go-github/github/repos_commits_test.go
generated
vendored
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
// 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"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListCommits(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
// given
|
||||||
|
mux.HandleFunc("/repos/o/r/commits", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r,
|
||||||
|
values{
|
||||||
|
"sha": "s",
|
||||||
|
"path": "p",
|
||||||
|
"author": "a",
|
||||||
|
"since": "2013-08-01T00:00:00Z",
|
||||||
|
"until": "2013-09-03T00:00:00Z",
|
||||||
|
})
|
||||||
|
fmt.Fprintf(w, `[{"sha": "s"}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &CommitsListOptions{
|
||||||
|
SHA: "s",
|
||||||
|
Path: "p",
|
||||||
|
Author: "a",
|
||||||
|
Since: time.Date(2013, time.August, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
Until: time.Date(2013, time.September, 3, 0, 0, 0, 0, time.UTC),
|
||||||
|
}
|
||||||
|
commits, _, err := client.Repositories.ListCommits("o", "r", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.ListCommits returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []RepositoryCommit{{SHA: String("s")}}
|
||||||
|
if !reflect.DeepEqual(commits, want) {
|
||||||
|
t.Errorf("Repositories.ListCommits returned %+v, want %+v", commits, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_GetCommit(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/commits/s", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprintf(w, `{
|
||||||
|
"sha": "s",
|
||||||
|
"commit": { "message": "m" },
|
||||||
|
"author": { "login": "l" },
|
||||||
|
"committer": { "login": "l" },
|
||||||
|
"parents": [ { "sha": "s" } ],
|
||||||
|
"stats": { "additions": 104, "deletions": 4, "total": 108 },
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"filename": "f",
|
||||||
|
"additions": 10,
|
||||||
|
"deletions": 2,
|
||||||
|
"changes": 12,
|
||||||
|
"status": "s",
|
||||||
|
"raw_url": "r",
|
||||||
|
"blob_url": "b",
|
||||||
|
"patch": "p"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
commit, _, err := client.Repositories.GetCommit("o", "r", "s")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.GetCommit returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &RepositoryCommit{
|
||||||
|
SHA: String("s"),
|
||||||
|
Commit: &Commit{
|
||||||
|
Message: String("m"),
|
||||||
|
},
|
||||||
|
Author: &User{
|
||||||
|
Login: String("l"),
|
||||||
|
},
|
||||||
|
Committer: &User{
|
||||||
|
Login: String("l"),
|
||||||
|
},
|
||||||
|
Parents: []Commit{
|
||||||
|
{
|
||||||
|
SHA: String("s"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Stats: &CommitStats{
|
||||||
|
Additions: Int(104),
|
||||||
|
Deletions: Int(4),
|
||||||
|
Total: Int(108),
|
||||||
|
},
|
||||||
|
Files: []CommitFile{
|
||||||
|
{
|
||||||
|
Filename: String("f"),
|
||||||
|
Additions: Int(10),
|
||||||
|
Deletions: Int(2),
|
||||||
|
Changes: Int(12),
|
||||||
|
Status: String("s"),
|
||||||
|
Patch: String("p"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(commit, want) {
|
||||||
|
t.Errorf("Repositories.GetCommit returned \n%+v, want \n%+v", commit, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_CompareCommits(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/compare/b...h", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprintf(w, `{
|
||||||
|
"base_commit": {
|
||||||
|
"sha": "s",
|
||||||
|
"commit": {
|
||||||
|
"author": { "name": "n" },
|
||||||
|
"committer": { "name": "n" },
|
||||||
|
"message": "m",
|
||||||
|
"tree": { "sha": "t" }
|
||||||
|
},
|
||||||
|
"author": { "login": "n" },
|
||||||
|
"committer": { "login": "l" },
|
||||||
|
"parents": [ { "sha": "s" } ]
|
||||||
|
},
|
||||||
|
"status": "s",
|
||||||
|
"ahead_by": 1,
|
||||||
|
"behind_by": 2,
|
||||||
|
"total_commits": 1,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"sha": "s",
|
||||||
|
"commit": { "author": { "name": "n" } },
|
||||||
|
"author": { "login": "l" },
|
||||||
|
"committer": { "login": "l" },
|
||||||
|
"parents": [ { "sha": "s" } ]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"files": [ { "filename": "f" } ]
|
||||||
|
}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
got, _, err := client.Repositories.CompareCommits("o", "r", "b", "h")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.CompareCommits returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &CommitsComparison{
|
||||||
|
Status: String("s"),
|
||||||
|
AheadBy: Int(1),
|
||||||
|
BehindBy: Int(2),
|
||||||
|
TotalCommits: Int(1),
|
||||||
|
BaseCommit: &RepositoryCommit{
|
||||||
|
Commit: &Commit{
|
||||||
|
Author: &CommitAuthor{Name: String("n")},
|
||||||
|
},
|
||||||
|
Author: &User{Login: String("l")},
|
||||||
|
Committer: &User{Login: String("l")},
|
||||||
|
Message: String("m"),
|
||||||
|
},
|
||||||
|
Commits: []RepositoryCommit{
|
||||||
|
{
|
||||||
|
SHA: String("s"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Files: []CommitFile{
|
||||||
|
{
|
||||||
|
Filename: String("f"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if reflect.DeepEqual(got, want) {
|
||||||
|
t.Errorf("Repositories.CompareCommits returned \n%+v, want \n%+v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
219
Godeps/_workspace/src/github.com/google/go-github/github/repos_contents.go
generated
vendored
Normal file
219
Godeps/_workspace/src/github.com/google/go-github/github/repos_contents.go
generated
vendored
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
// Repository contents API methods.
|
||||||
|
// http://developer.github.com/v3/repos/contents/
|
||||||
|
|
||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RepositoryContent represents a file or directory in a github repository.
|
||||||
|
type RepositoryContent struct {
|
||||||
|
Type *string `json:"type,omitempty"`
|
||||||
|
Encoding *string `json:"encoding,omitempty"`
|
||||||
|
Size *int `json:"size,omitempty"`
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
Path *string `json:"path,omitempty"`
|
||||||
|
Content *string `json:"content,omitempty"`
|
||||||
|
SHA *string `json:"sha,omitempty"`
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
GitURL *string `json:"giturl,omitempty"`
|
||||||
|
HTMLURL *string `json:"htmlurl,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepositoryContentResponse holds the parsed response from CreateFile, UpdateFile, and DeleteFile.
|
||||||
|
type RepositoryContentResponse struct {
|
||||||
|
Content *RepositoryContent `json:"content,omitempty"`
|
||||||
|
Commit `json:"commit,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepositoryContentFileOptions specifies optional parameters for CreateFile, UpdateFile, and DeleteFile.
|
||||||
|
type RepositoryContentFileOptions struct {
|
||||||
|
Message *string `json:"message,omitempty"`
|
||||||
|
Content []byte `json:"content,omitempty"`
|
||||||
|
SHA *string `json:"sha,omitempty"`
|
||||||
|
Branch *string `json:"branch,omitempty"`
|
||||||
|
Author *CommitAuthor `json:"author,omitempty"`
|
||||||
|
Committer *CommitAuthor `json:"committer,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepositoryContentGetOptions represents an optional ref parameter, which can be a SHA,
|
||||||
|
// branch, or tag
|
||||||
|
type RepositoryContentGetOptions struct {
|
||||||
|
Ref string `url:"ref,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r RepositoryContent) String() string {
|
||||||
|
return Stringify(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode decodes the file content if it is base64 encoded.
|
||||||
|
func (c *RepositoryContent) Decode() ([]byte, error) {
|
||||||
|
if *c.Encoding != "base64" {
|
||||||
|
return nil, errors.New("Cannot decode non-base64")
|
||||||
|
}
|
||||||
|
o, err := base64.StdEncoding.DecodeString(*c.Content)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return o, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetReadme gets the Readme file for the repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/contents/#get-the-readme
|
||||||
|
func (s *RepositoriesService) GetReadme(owner, repo string, opt *RepositoryContentGetOptions) (*RepositoryContent, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/readme", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
readme := new(RepositoryContent)
|
||||||
|
resp, err := s.client.Do(req, readme)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
return readme, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// subdirectories of a directory (when path references a directory). To make it
|
||||||
|
// easy to distinguish between both result types and to mimic the API as much
|
||||||
|
// as possible, both result types will be returned but only one will contain a
|
||||||
|
// value and the other will be nil.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/contents/#get-contents
|
||||||
|
func (s *RepositoriesService) GetContents(owner, repo, path string, opt *RepositoryContentGetOptions) (fileContent *RepositoryContent,
|
||||||
|
directoryContent []*RepositoryContent, resp *Response, err error) {
|
||||||
|
u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path)
|
||||||
|
u, err = addOptions(u, opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
var rawJSON json.RawMessage
|
||||||
|
resp, err = s.client.Do(req, &rawJSON)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, resp, err
|
||||||
|
}
|
||||||
|
fileUnmarshalError := json.Unmarshal(rawJSON, &fileContent)
|
||||||
|
if fileUnmarshalError == nil {
|
||||||
|
return fileContent, nil, resp, fileUnmarshalError
|
||||||
|
}
|
||||||
|
directoryUnmarshalError := json.Unmarshal(rawJSON, &directoryContent)
|
||||||
|
if directoryUnmarshalError == nil {
|
||||||
|
return nil, directoryContent, resp, directoryUnmarshalError
|
||||||
|
}
|
||||||
|
return nil, nil, resp, fmt.Errorf("Unmarshalling failed for both file and directory content: %s and %s ", fileUnmarshalError, directoryUnmarshalError)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateFile creates a new file in a repository at the given path and returns
|
||||||
|
// the commit and file metadata.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/contents/#create-a-file
|
||||||
|
func (s *RepositoriesService) CreateFile(owner, repo, path string, opt *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path)
|
||||||
|
req, err := s.client.NewRequest("PUT", u, opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
createResponse := new(RepositoryContentResponse)
|
||||||
|
resp, err := s.client.Do(req, createResponse)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
return createResponse, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateFile updates a file in a repository at the given path and returns the
|
||||||
|
// commit and file metadata. Requires the blob SHA of the file being updated.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/contents/#update-a-file
|
||||||
|
func (s *RepositoriesService) UpdateFile(owner, repo, path string, opt *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path)
|
||||||
|
req, err := s.client.NewRequest("PUT", u, opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
updateResponse := new(RepositoryContentResponse)
|
||||||
|
resp, err := s.client.Do(req, updateResponse)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
return updateResponse, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteFile deletes a file from a repository and returns the commit.
|
||||||
|
// Requires the blob SHA of the file to be deleted.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/contents/#delete-a-file
|
||||||
|
func (s *RepositoriesService) DeleteFile(owner, repo, path string, opt *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
deleteResponse := new(RepositoryContentResponse)
|
||||||
|
resp, err := s.client.Do(req, deleteResponse)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
return deleteResponse, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// archiveFormat is used to define the archive type when calling GetArchiveLink.
|
||||||
|
type archiveFormat string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Tarball specifies an archive in gzipped tar format.
|
||||||
|
Tarball archiveFormat = "tarball"
|
||||||
|
|
||||||
|
// Zipball specifies an archive in zip format.
|
||||||
|
Zipball archiveFormat = "zipball"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetArchiveLink returns an URL to download a tarball or zipball archive for a
|
||||||
|
// repository. The archiveFormat can be specified by either the github.Tarball
|
||||||
|
// or github.Zipball constant.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/contents/#get-archive-link
|
||||||
|
func (s *RepositoriesService) GetArchiveLink(owner, repo string, archiveformat archiveFormat, opt *RepositoryContentGetOptions) (*url.URL, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%s/%s/%s", owner, repo, archiveformat)
|
||||||
|
if opt != nil && opt.Ref != "" {
|
||||||
|
u += fmt.Sprintf("/%s", opt.Ref)
|
||||||
|
}
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
var resp *http.Response
|
||||||
|
// Use http.DefaultTransport if no custom Transport is configured
|
||||||
|
if s.client.client.Transport == nil {
|
||||||
|
resp, err = http.DefaultTransport.RoundTrip(req)
|
||||||
|
} else {
|
||||||
|
resp, err = s.client.client.Transport.RoundTrip(req)
|
||||||
|
}
|
||||||
|
if err != nil || resp.StatusCode != http.StatusFound {
|
||||||
|
return nil, newResponse(resp), err
|
||||||
|
}
|
||||||
|
parsedURL, err := url.Parse(resp.Header.Get("Location"))
|
||||||
|
return parsedURL, newResponse(resp), err
|
||||||
|
}
|
||||||
240
Godeps/_workspace/src/github.com/google/go-github/github/repos_contents_test.go
generated
vendored
Normal file
240
Godeps/_workspace/src/github.com/google/go-github/github/repos_contents_test.go
generated
vendored
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDecode(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
r := RepositoryContent{Encoding: String("base64"), Content: String("aGVsbG8=")}
|
||||||
|
o, err := r.Decode()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Failed to decode content.")
|
||||||
|
}
|
||||||
|
want := "hello"
|
||||||
|
if string(o) != want {
|
||||||
|
t.Errorf("RepositoryContent.Decode returned %+v, want %+v", string(o), want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDecodeBadEncoding(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
r := RepositoryContent{Encoding: String("bad")}
|
||||||
|
_, err := r.Decode()
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Should fail to decode non-base64")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_GetReadme(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
mux.HandleFunc("/repos/o/r/readme", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{
|
||||||
|
"type": "file",
|
||||||
|
"encoding": "base64",
|
||||||
|
"size": 5362,
|
||||||
|
"name": "README.md",
|
||||||
|
"path": "README.md"
|
||||||
|
}`)
|
||||||
|
})
|
||||||
|
readme, _, err := client.Repositories.GetReadme("o", "r", &RepositoryContentGetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.GetReadme returned error: %v", err)
|
||||||
|
}
|
||||||
|
want := &RepositoryContent{Type: String("file"), Name: String("README.md"), Size: Int(5362), Encoding: String("base64"), Path: String("README.md")}
|
||||||
|
if !reflect.DeepEqual(readme, want) {
|
||||||
|
t.Errorf("Repositories.GetReadme returned %+v, want %+v", readme, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_GetContent_File(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{
|
||||||
|
"type": "file",
|
||||||
|
"encoding": "base64",
|
||||||
|
"size": 20678,
|
||||||
|
"name": "LICENSE",
|
||||||
|
"path": "LICENSE"
|
||||||
|
}`)
|
||||||
|
})
|
||||||
|
fileContents, _, _, err := client.Repositories.GetContents("o", "r", "p", &RepositoryContentGetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.GetContents_File returned error: %v", err)
|
||||||
|
}
|
||||||
|
want := &RepositoryContent{Type: String("file"), Name: String("LICENSE"), Size: Int(20678), Encoding: String("base64"), Path: String("LICENSE")}
|
||||||
|
if !reflect.DeepEqual(fileContents, want) {
|
||||||
|
t.Errorf("Repositories.GetContents returned %+v, want %+v", fileContents, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_GetContent_Directory(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `[{
|
||||||
|
"type": "dir",
|
||||||
|
"name": "lib",
|
||||||
|
"path": "lib"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"size": 20678,
|
||||||
|
"name": "LICENSE",
|
||||||
|
"path": "LICENSE"
|
||||||
|
}]`)
|
||||||
|
})
|
||||||
|
_, directoryContents, _, err := client.Repositories.GetContents("o", "r", "p", &RepositoryContentGetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.GetContents_Directory returned error: %v", err)
|
||||||
|
}
|
||||||
|
want := []*RepositoryContent{{Type: String("dir"), Name: String("lib"), Path: String("lib")},
|
||||||
|
{Type: String("file"), Name: String("LICENSE"), Size: Int(20678), Path: String("LICENSE")}}
|
||||||
|
if !reflect.DeepEqual(directoryContents, want) {
|
||||||
|
t.Errorf("Repositories.GetContents_Directory returned %+v, want %+v", directoryContents, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_CreateFile(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "PUT")
|
||||||
|
fmt.Fprint(w, `{
|
||||||
|
"content":{
|
||||||
|
"name":"p"
|
||||||
|
},
|
||||||
|
"commit":{
|
||||||
|
"message":"m",
|
||||||
|
"sha":"f5f369044773ff9c6383c087466d12adb6fa0828"
|
||||||
|
}
|
||||||
|
}`)
|
||||||
|
})
|
||||||
|
message := "m"
|
||||||
|
content := []byte("c")
|
||||||
|
repositoryContentsOptions := &RepositoryContentFileOptions{
|
||||||
|
Message: &message,
|
||||||
|
Content: content,
|
||||||
|
Committer: &CommitAuthor{Name: String("n"), Email: String("e")},
|
||||||
|
}
|
||||||
|
createResponse, _, err := client.Repositories.CreateFile("o", "r", "p", repositoryContentsOptions)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.CreateFile returned error: %v", err)
|
||||||
|
}
|
||||||
|
want := &RepositoryContentResponse{
|
||||||
|
Content: &RepositoryContent{Name: String("p")},
|
||||||
|
Commit: Commit{
|
||||||
|
Message: String("m"),
|
||||||
|
SHA: String("f5f369044773ff9c6383c087466d12adb6fa0828"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(createResponse, want) {
|
||||||
|
t.Errorf("Repositories.CreateFile returned %+v, want %+v", createResponse, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_UpdateFile(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "PUT")
|
||||||
|
fmt.Fprint(w, `{
|
||||||
|
"content":{
|
||||||
|
"name":"p"
|
||||||
|
},
|
||||||
|
"commit":{
|
||||||
|
"message":"m",
|
||||||
|
"sha":"f5f369044773ff9c6383c087466d12adb6fa0828"
|
||||||
|
}
|
||||||
|
}`)
|
||||||
|
})
|
||||||
|
message := "m"
|
||||||
|
content := []byte("c")
|
||||||
|
sha := "f5f369044773ff9c6383c087466d12adb6fa0828"
|
||||||
|
repositoryContentsOptions := &RepositoryContentFileOptions{
|
||||||
|
Message: &message,
|
||||||
|
Content: content,
|
||||||
|
SHA: &sha,
|
||||||
|
Committer: &CommitAuthor{Name: String("n"), Email: String("e")},
|
||||||
|
}
|
||||||
|
updateResponse, _, err := client.Repositories.UpdateFile("o", "r", "p", repositoryContentsOptions)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.UpdateFile returned error: %v", err)
|
||||||
|
}
|
||||||
|
want := &RepositoryContentResponse{
|
||||||
|
Content: &RepositoryContent{Name: String("p")},
|
||||||
|
Commit: Commit{
|
||||||
|
Message: String("m"),
|
||||||
|
SHA: String("f5f369044773ff9c6383c087466d12adb6fa0828"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(updateResponse, want) {
|
||||||
|
t.Errorf("Repositories.UpdateFile returned %+v, want %+v", updateResponse, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_DeleteFile(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
fmt.Fprint(w, `{
|
||||||
|
"content": null,
|
||||||
|
"commit":{
|
||||||
|
"message":"m",
|
||||||
|
"sha":"f5f369044773ff9c6383c087466d12adb6fa0828"
|
||||||
|
}
|
||||||
|
}`)
|
||||||
|
})
|
||||||
|
message := "m"
|
||||||
|
sha := "f5f369044773ff9c6383c087466d12adb6fa0828"
|
||||||
|
repositoryContentsOptions := &RepositoryContentFileOptions{
|
||||||
|
Message: &message,
|
||||||
|
SHA: &sha,
|
||||||
|
Committer: &CommitAuthor{Name: String("n"), Email: String("e")},
|
||||||
|
}
|
||||||
|
deleteResponse, _, err := client.Repositories.DeleteFile("o", "r", "p", repositoryContentsOptions)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.DeleteFile returned error: %v", err)
|
||||||
|
}
|
||||||
|
want := &RepositoryContentResponse{
|
||||||
|
Content: nil,
|
||||||
|
Commit: Commit{
|
||||||
|
Message: String("m"),
|
||||||
|
SHA: String("f5f369044773ff9c6383c087466d12adb6fa0828"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(deleteResponse, want) {
|
||||||
|
t.Errorf("Repositories.DeleteFile returned %+v, want %+v", deleteResponse, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_GetArchiveLink(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
mux.HandleFunc("/repos/o/r/tarball", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
http.Redirect(w, r, "http://github.com/a", http.StatusFound)
|
||||||
|
})
|
||||||
|
url, resp, err := client.Repositories.GetArchiveLink("o", "r", Tarball, &RepositoryContentGetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.GetArchiveLink returned error: %v", err)
|
||||||
|
}
|
||||||
|
if resp.StatusCode != http.StatusFound {
|
||||||
|
t.Errorf("Repositories.GetArchiveLink returned status: %d, want %d", resp.StatusCode, http.StatusFound)
|
||||||
|
}
|
||||||
|
want := "http://github.com/a"
|
||||||
|
if url.String() != want {
|
||||||
|
t.Errorf("Repositories.GetArchiveLink returned %+v, want %+v", url.String(), want)
|
||||||
|
}
|
||||||
|
}
|
||||||
71
Godeps/_workspace/src/github.com/google/go-github/github/repos_forks.go
generated
vendored
Normal file
71
Godeps/_workspace/src/github.com/google/go-github/github/repos_forks.go
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
// 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"
|
||||||
|
|
||||||
|
// RepositoryListForksOptions specifies the optional parameters to the
|
||||||
|
// RepositoriesService.ListForks method.
|
||||||
|
type RepositoryListForksOptions struct {
|
||||||
|
// How to sort the forks list. Possible values are: newest, oldest,
|
||||||
|
// watchers. Default is "newest".
|
||||||
|
Sort string `url:"sort,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListForks lists the forks of the specified repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/forks/#list-forks
|
||||||
|
func (s *RepositoriesService) ListForks(owner, repo string, opt *RepositoryListForksOptions) ([]Repository, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/forks", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
repos := new([]Repository)
|
||||||
|
resp, err := s.client.Do(req, repos)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *repos, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepositoryCreateForkOptions specifies the optional parameters to the
|
||||||
|
// RepositoriesService.CreateFork method.
|
||||||
|
type RepositoryCreateForkOptions struct {
|
||||||
|
// The organization to fork the repository into.
|
||||||
|
Organization string `url:"organization,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateFork creates a fork of the specified repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/forks/#list-forks
|
||||||
|
func (s *RepositoriesService) CreateFork(owner, repo string, opt *RepositoryCreateForkOptions) (*Repository, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/forks", owner, repo)
|
||||||
|
u, err := addOptions(u, opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("POST", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fork := new(Repository)
|
||||||
|
resp, err := s.client.Do(req, fork)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return fork, resp, err
|
||||||
|
}
|
||||||
67
Godeps/_workspace/src/github.com/google/go-github/github/repos_forks_test.go
generated
vendored
Normal file
67
Godeps/_workspace/src/github.com/google/go-github/github/repos_forks_test.go
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
// 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 TestRepositoriesService_ListForks(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/forks", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{"sort": "newest"})
|
||||||
|
fmt.Fprint(w, `[{"id":1},{"id":2}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &RepositoryListForksOptions{Sort: "newest"}
|
||||||
|
repos, _, err := client.Repositories.ListForks("o", "r", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.ListForks returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Repository{{ID: Int(1)}, {ID: Int(2)}}
|
||||||
|
if !reflect.DeepEqual(repos, want) {
|
||||||
|
t.Errorf("Repositories.ListForks returned %+v, want %+v", repos, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListForks_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.ListForks("%", "r", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_CreateFork(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/forks", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
testFormValues(t, r, values{"organization": "o"})
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &RepositoryCreateForkOptions{Organization: "o"}
|
||||||
|
repo, _, err := client.Repositories.CreateFork("o", "r", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.CreateFork returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Repository{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(repo, want) {
|
||||||
|
t.Errorf("Repositories.CreateFork returned %+v, want %+v", repo, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_CreateFork_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.CreateFork("%", "r", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
209
Godeps/_workspace/src/github.com/google/go-github/github/repos_hooks.go
generated
vendored
Normal file
209
Godeps/_workspace/src/github.com/google/go-github/github/repos_hooks.go
generated
vendored
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
// 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"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WebHookPayload represents the data that is received from GitHub when a push
|
||||||
|
// event hook is triggered. The format of these payloads pre-date most of the
|
||||||
|
// GitHub v3 API, so there are lots of minor incompatibilities with the types
|
||||||
|
// defined in the rest of the API. Therefore, several types are duplicated
|
||||||
|
// here to account for these differences.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://help.github.com/articles/post-receive-hooks
|
||||||
|
type WebHookPayload struct {
|
||||||
|
After *string `json:"after,omitempty"`
|
||||||
|
Before *string `json:"before,omitempty"`
|
||||||
|
Commits []WebHookCommit `json:"commits,omitempty"`
|
||||||
|
Compare *string `json:"compare,omitempty"`
|
||||||
|
Created *bool `json:"created,omitempty"`
|
||||||
|
Deleted *bool `json:"deleted,omitempty"`
|
||||||
|
Forced *bool `json:"forced,omitempty"`
|
||||||
|
HeadCommit *WebHookCommit `json:"head_commit,omitempty"`
|
||||||
|
Pusher *User `json:"pusher,omitempty"`
|
||||||
|
Ref *string `json:"ref,omitempty"`
|
||||||
|
Repo *Repository `json:"repository,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WebHookPayload) String() string {
|
||||||
|
return Stringify(w)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WebHookCommit represents the commit variant we receive from GitHub in a
|
||||||
|
// WebHookPayload.
|
||||||
|
type WebHookCommit struct {
|
||||||
|
Added []string `json:"added,omitempty"`
|
||||||
|
Author *WebHookAuthor `json:"author,omitempty"`
|
||||||
|
Committer *WebHookAuthor `json:"committer,omitempty"`
|
||||||
|
Distinct *bool `json:"distinct,omitempty"`
|
||||||
|
ID *string `json:"id,omitempty"`
|
||||||
|
Message *string `json:"message,omitempty"`
|
||||||
|
Modified []string `json:"modified,omitempty"`
|
||||||
|
Removed []string `json:"removed,omitempty"`
|
||||||
|
Timestamp *time.Time `json:"timestamp,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WebHookCommit) String() string {
|
||||||
|
return Stringify(w)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WebHookAuthor represents the author or committer of a commit, as specified
|
||||||
|
// in a WebHookCommit. The commit author may not correspond to a GitHub User.
|
||||||
|
type WebHookAuthor struct {
|
||||||
|
Email *string `json:"email,omitempty"`
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
Username *string `json:"username,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WebHookAuthor) String() string {
|
||||||
|
return Stringify(w)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hook represents a GitHub (web and service) hook for a repository.
|
||||||
|
type Hook struct {
|
||||||
|
CreatedAt *time.Time `json:"created_at,omitempty"`
|
||||||
|
UpdatedAt *time.Time `json:"updated_at,omitempty"`
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
Events []string `json:"events,omitempty"`
|
||||||
|
Active *bool `json:"active,omitempty"`
|
||||||
|
Config map[string]interface{} `json:"config,omitempty"`
|
||||||
|
ID *int `json:"id,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h Hook) String() string {
|
||||||
|
return Stringify(h)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateHook creates a Hook for the specified repository.
|
||||||
|
// Name and Config are required fields.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/hooks/#create-a-hook
|
||||||
|
func (s *RepositoriesService) CreateHook(owner, repo string, hook *Hook) (*Hook, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/hooks", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListHooks lists all Hooks for the specified repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/hooks/#list
|
||||||
|
func (s *RepositoriesService) ListHooks(owner, repo string, opt *ListOptions) ([]Hook, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/hooks", owner, repo)
|
||||||
|
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: http://developer.github.com/v3/repos/hooks/#get-single-hook
|
||||||
|
func (s *RepositoriesService) GetHook(owner, repo string, id int) (*Hook, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditHook updates a specified Hook.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/hooks/#edit-a-hook
|
||||||
|
func (s *RepositoriesService) EditHook(owner, repo string, id int, hook *Hook) (*Hook, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteHook deletes a specified Hook.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/hooks/#delete-a-hook
|
||||||
|
func (s *RepositoriesService) DeleteHook(owner, repo string, id int) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, id)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestHook triggers a test Hook by github.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/hooks/#test-a-push-hook
|
||||||
|
func (s *RepositoriesService) TestHook(owner, repo string, id int) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/hooks/%d/tests", owner, repo, id)
|
||||||
|
req, err := s.client.NewRequest("POST", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.client.Do(req, 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 (s *RepositoriesService) ListServiceHooks() ([]ServiceHook, *Response, error) {
|
||||||
|
u := "hooks"
|
||||||
|
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
|
||||||
|
}
|
||||||
205
Godeps/_workspace/src/github.com/google/go-github/github/repos_hooks_test.go
generated
vendored
Normal file
205
Godeps/_workspace/src/github.com/google/go-github/github/repos_hooks_test.go
generated
vendored
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRepositoriesService_CreateHook(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &Hook{Name: String("t")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/hooks", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(Hook)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
hook, _, err := client.Repositories.CreateHook("o", "r", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.CreateHook returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Hook{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(hook, want) {
|
||||||
|
t.Errorf("Repositories.CreateHook returned %+v, want %+v", hook, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_CreateHook_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.CreateHook("%", "%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListHooks(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/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.Repositories.ListHooks("o", "r", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.ListHooks returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Hook{{ID: Int(1)}, {ID: Int(2)}}
|
||||||
|
if !reflect.DeepEqual(hooks, want) {
|
||||||
|
t.Errorf("Repositories.ListHooks returned %+v, want %+v", hooks, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListHooks_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.ListHooks("%", "%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_GetHook(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/hooks/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
hook, _, err := client.Repositories.GetHook("o", "r", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.GetHook returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Hook{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(hook, want) {
|
||||||
|
t.Errorf("Repositories.GetHook returned %+v, want %+v", hook, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_GetHook_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.GetHook("%", "%", 1)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_EditHook(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &Hook{Name: String("t")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/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.Repositories.EditHook("o", "r", 1, input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.EditHook returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Hook{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(hook, want) {
|
||||||
|
t.Errorf("Repositories.EditHook returned %+v, want %+v", hook, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_EditHook_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.EditHook("%", "%", 1, nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_DeleteHook(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/hooks/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Repositories.DeleteHook("o", "r", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.DeleteHook returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_DeleteHook_invalidOwner(t *testing.T) {
|
||||||
|
_, err := client.Repositories.DeleteHook("%", "%", 1)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_TestHook(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/hooks/1/tests", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Repositories.TestHook("o", "r", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.TestHook returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_TestHook_invalidOwner(t *testing.T) {
|
||||||
|
_, err := client.Repositories.TestHook("%", "%", 1)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
108
Godeps/_workspace/src/github.com/google/go-github/github/repos_keys.go
generated
vendored
Normal file
108
Godeps/_workspace/src/github.com/google/go-github/github/repos_keys.go
generated
vendored
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
// 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"
|
||||||
|
|
||||||
|
// The Key type is defined in users_keys.go
|
||||||
|
|
||||||
|
// ListKeys lists the deploy keys for a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/keys/#list
|
||||||
|
func (s *RepositoriesService) ListKeys(owner string, repo string, opt *ListOptions) ([]Key, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/keys", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
keys := new([]Key)
|
||||||
|
resp, err := s.client.Do(req, keys)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *keys, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetKey fetches a single deploy key.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/keys/#get
|
||||||
|
func (s *RepositoriesService) GetKey(owner string, repo string, id int) (*Key, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/keys/%v", owner, repo, id)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
key := new(Key)
|
||||||
|
resp, err := s.client.Do(req, key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return key, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateKey adds a deploy key for a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/keys/#create
|
||||||
|
func (s *RepositoriesService) CreateKey(owner string, repo string, key *Key) (*Key, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/keys", owner, repo)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("POST", u, key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
k := new(Key)
|
||||||
|
resp, err := s.client.Do(req, k)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return k, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditKey edits a deploy key.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/keys/#edit
|
||||||
|
func (s *RepositoriesService) EditKey(owner string, repo string, id int, key *Key) (*Key, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/keys/%v", owner, repo, id)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("PATCH", u, key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
k := new(Key)
|
||||||
|
resp, err := s.client.Do(req, k)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return k, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteKey deletes a deploy key.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/keys/#delete
|
||||||
|
func (s *RepositoriesService) DeleteKey(owner string, repo string, id int) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/keys/%v", owner, repo, id)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
153
Godeps/_workspace/src/github.com/google/go-github/github/repos_keys_test.go
generated
vendored
Normal file
153
Godeps/_workspace/src/github.com/google/go-github/github/repos_keys_test.go
generated
vendored
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListKeys(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/keys", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{"page": "2"})
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListOptions{Page: 2}
|
||||||
|
keys, _, err := client.Repositories.ListKeys("o", "r", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.ListKeys returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Key{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(keys, want) {
|
||||||
|
t.Errorf("Repositories.ListKeys returned %+v, want %+v", keys, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListKeys_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.ListKeys("%", "%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_GetKey(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/keys/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
key, _, err := client.Repositories.GetKey("o", "r", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.GetKey returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Key{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(key, want) {
|
||||||
|
t.Errorf("Repositories.GetKey returned %+v, want %+v", key, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_GetKey_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.GetKey("%", "%", 1)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_CreateKey(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &Key{Key: String("k"), Title: String("t")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/keys", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(Key)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
key, _, err := client.Repositories.CreateKey("o", "r", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.GetKey returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Key{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(key, want) {
|
||||||
|
t.Errorf("Repositories.GetKey returned %+v, want %+v", key, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_CreateKey_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.CreateKey("%", "%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_EditKey(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &Key{Key: String("k"), Title: String("t")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/keys/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(Key)
|
||||||
|
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}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
key, _, err := client.Repositories.EditKey("o", "r", 1, input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.EditKey returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Key{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(key, want) {
|
||||||
|
t.Errorf("Repositories.EditKey returned %+v, want %+v", key, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_EditKey_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.EditKey("%", "%", 1, nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_DeleteKey(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/keys/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Repositories.DeleteKey("o", "r", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.DeleteKey returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_DeleteKey_invalidOwner(t *testing.T) {
|
||||||
|
_, err := client.Repositories.DeleteKey("%", "%", 1)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
37
Godeps/_workspace/src/github.com/google/go-github/github/repos_merging.go
generated
vendored
Normal file
37
Godeps/_workspace/src/github.com/google/go-github/github/repos_merging.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
// Copyright 2014 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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RepositoryMergeRequest represents a request to merge a branch in a
|
||||||
|
// repository.
|
||||||
|
type RepositoryMergeRequest struct {
|
||||||
|
Base *string `json:"base,omitempty"`
|
||||||
|
Head *string `json:"head,omitempty"`
|
||||||
|
CommitMessage *string `json:"commit_message,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge a branch in the specified repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/repos/merging/#perform-a-merge
|
||||||
|
func (s *RepositoriesService) Merge(owner, repo string, request *RepositoryMergeRequest) (*RepositoryCommit, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/merges", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("POST", u, request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
commit := new(RepositoryCommit)
|
||||||
|
resp, err := s.client.Do(req, commit)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return commit, resp, err
|
||||||
|
}
|
||||||
47
Godeps/_workspace/src/github.com/google/go-github/github/repos_merging_test.go
generated
vendored
Normal file
47
Godeps/_workspace/src/github.com/google/go-github/github/repos_merging_test.go
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 2014 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 TestRepositoriesService_Merge(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &RepositoryMergeRequest{
|
||||||
|
Base: String("b"),
|
||||||
|
Head: String("h"),
|
||||||
|
CommitMessage: String("c"),
|
||||||
|
}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/merges", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(RepositoryMergeRequest)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"sha":"s"}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
commit, _, err := client.Repositories.Merge("o", "r", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.Merge returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &RepositoryCommit{SHA: String("s")}
|
||||||
|
if !reflect.DeepEqual(commit, want) {
|
||||||
|
t.Errorf("Repositories.Merge returned %+v, want %+v", commit, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
90
Godeps/_workspace/src/github.com/google/go-github/github/repos_pages.go
generated
vendored
Normal file
90
Godeps/_workspace/src/github.com/google/go-github/github/repos_pages.go
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
// Copyright 2014 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"
|
||||||
|
|
||||||
|
// Pages represents a GitHub Pages site configuration.
|
||||||
|
type Pages struct {
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
Status *string `json:"status,omitempty"`
|
||||||
|
CNAME *string `json:"cname,omitempty"`
|
||||||
|
Custom404 *bool `json:"custom_404,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PagesError represents a build error for a GitHub Pages site.
|
||||||
|
type PagesError struct {
|
||||||
|
Message *string `json:"message,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PagesBuild represents the build information for a GitHub Pages site.
|
||||||
|
type PagesBuild struct {
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
Status *string `json:"status,omitempty"`
|
||||||
|
Error *PagesError `json:"error,omitempty"`
|
||||||
|
Pusher *User `json:"pusher,omitempty"`
|
||||||
|
Commit *string `json:"commit,omitempty"`
|
||||||
|
Duration *int `json:"duration,omitempty"`
|
||||||
|
CreatedAt *Timestamp `json:"created_at,omitempty"`
|
||||||
|
UpdatedAt *Timestamp `json:"created_at,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPagesInfo fetches information about a GitHub Pages site.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/repos/pages/#get-information-about-a-pages-site
|
||||||
|
func (s *RepositoriesService) GetPagesInfo(owner string, repo string) (*Pages, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/pages", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
site := new(Pages)
|
||||||
|
resp, err := s.client.Do(req, site)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return site, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPagesBuilds lists the builds for a GitHub Pages site.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/repos/pages/#list-pages-builds
|
||||||
|
func (s *RepositoriesService) ListPagesBuilds(owner string, repo string) ([]PagesBuild, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/pages/builds", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var pages []PagesBuild
|
||||||
|
resp, err := s.client.Do(req, &pages)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return pages, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLatestPagesBuild fetches the latest build information for a GitHub pages site.
|
||||||
|
//
|
||||||
|
// GitHub API docs: https://developer.github.com/v3/repos/pages/#list-latest-pages-build
|
||||||
|
func (s *RepositoriesService) GetLatestPagesBuild(owner string, repo string) (*PagesBuild, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/pages/builds/latest", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
build := new(PagesBuild)
|
||||||
|
resp, err := s.client.Do(req, build)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return build, resp, err
|
||||||
|
}
|
||||||
73
Godeps/_workspace/src/github.com/google/go-github/github/repos_pages_test.go
generated
vendored
Normal file
73
Godeps/_workspace/src/github.com/google/go-github/github/repos_pages_test.go
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
// Copyright 2014 The go-github AUTHORS. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRepositoriesService_GetPagesInfo(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/pages", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"url":"u","status":"s","cname":"c","custom_404":false}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
page, _, err := client.Repositories.GetPagesInfo("o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.GetPagesInfo returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Pages{URL: String("u"), Status: String("s"), CNAME: String("c"), Custom404: Bool(false)}
|
||||||
|
if !reflect.DeepEqual(page, want) {
|
||||||
|
t.Errorf("Repositories.GetPagesInfo returned %+v, want %+v", page, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListPagesBuilds(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/pages/builds", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `[{"url":"u","status":"s","commit":"c"}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
pages, _, err := client.Repositories.ListPagesBuilds("o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.ListPagesBuilds returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []PagesBuild{{URL: String("u"), Status: String("s"), Commit: String("c")}}
|
||||||
|
if !reflect.DeepEqual(pages, want) {
|
||||||
|
t.Errorf("Repositories.ListPagesBuilds returned %+v, want %+v", pages, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_GetLatestPagesBuild(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/pages/builds/latest", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"url":"u","status":"s","commit":"c"}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
build, _, err := client.Repositories.GetLatestPagesBuild("o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.GetLatestPagesBuild returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &PagesBuild{URL: String("u"), Status: String("s"), Commit: String("c")}
|
||||||
|
if !reflect.DeepEqual(build, want) {
|
||||||
|
t.Errorf("Repositories.GetLatestPagesBuild returned %+v, want %+v", build, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
253
Godeps/_workspace/src/github.com/google/go-github/github/repos_releases.go
generated
vendored
Normal file
253
Godeps/_workspace/src/github.com/google/go-github/github/repos_releases.go
generated
vendored
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
// 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 (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"mime"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RepositoryRelease represents a GitHub release in a repository.
|
||||||
|
type RepositoryRelease struct {
|
||||||
|
ID *int `json:"id,omitempty"`
|
||||||
|
TagName *string `json:"tag_name,omitempty"`
|
||||||
|
TargetCommitish *string `json:"target_commitish,omitempty"`
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
Body *string `json:"body,omitempty"`
|
||||||
|
Draft *bool `json:"draft,omitempty"`
|
||||||
|
Prerelease *bool `json:"prerelease,omitempty"`
|
||||||
|
CreatedAt *Timestamp `json:"created_at,omitempty"`
|
||||||
|
PublishedAt *Timestamp `json:"published_at,omitempty"`
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
HTMLURL *string `json:"html_url,omitempty"`
|
||||||
|
AssetsURL *string `json:"assets_url,omitempty"`
|
||||||
|
UploadURL *string `json:"upload_url,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r RepositoryRelease) String() string {
|
||||||
|
return Stringify(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReleaseAsset represents a Github release asset in a repository.
|
||||||
|
type ReleaseAsset struct {
|
||||||
|
ID *int `json:"id,omitempty"`
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
Label *string `json:"label,omitempty"`
|
||||||
|
State *string `json:"state,omitempty"`
|
||||||
|
ContentType *string `json:"content_type,omitempty"`
|
||||||
|
Size *int `json:"size,omitempty"`
|
||||||
|
DownloadCount *int `json:"download_count,omitempty"`
|
||||||
|
CreatedAt *Timestamp `json:"created_at,omitempty"`
|
||||||
|
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r ReleaseAsset) String() string {
|
||||||
|
return Stringify(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListReleases lists the releases for a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/releases/#list-releases-for-a-repository
|
||||||
|
func (s *RepositoriesService) ListReleases(owner, repo string, opt *ListOptions) ([]RepositoryRelease, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%s/%s/releases", owner, repo)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
releases := new([]RepositoryRelease)
|
||||||
|
resp, err := s.client.Do(req, releases)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
return *releases, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRelease fetches 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) {
|
||||||
|
u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
release := new(RepositoryRelease)
|
||||||
|
resp, err := s.client.Do(req, release)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
return release, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRelease adds a new release for a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs : http://developer.github.com/v3/repos/releases/#create-a-release
|
||||||
|
func (s *RepositoriesService) CreateRelease(owner, repo string, release *RepositoryRelease) (*RepositoryRelease, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%s/%s/releases", owner, repo)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("POST", u, release)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := new(RepositoryRelease)
|
||||||
|
resp, err := s.client.Do(req, r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
return r, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditRelease edits a repository release.
|
||||||
|
//
|
||||||
|
// GitHub API docs : http://developer.github.com/v3/repos/releases/#edit-a-release
|
||||||
|
func (s *RepositoriesService) EditRelease(owner, repo string, id int, release *RepositoryRelease) (*RepositoryRelease, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("PATCH", u, release)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := new(RepositoryRelease)
|
||||||
|
resp, err := s.client.Do(req, r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
return r, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRelease delete a single release from a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs : http://developer.github.com/v3/repos/releases/#delete-a-release
|
||||||
|
func (s *RepositoriesService) DeleteRelease(owner, repo string, id int) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListReleaseAssets lists the release's assets.
|
||||||
|
//
|
||||||
|
// GitHub API docs : http://developer.github.com/v3/repos/releases/#list-assets-for-a-release
|
||||||
|
func (s *RepositoriesService) ListReleaseAssets(owner, repo string, id int, opt *ListOptions) ([]ReleaseAsset, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%s/%s/releases/%d/assets", owner, repo, id)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
assets := new([]ReleaseAsset)
|
||||||
|
resp, err := s.client.Do(req, assets)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, nil
|
||||||
|
}
|
||||||
|
return *assets, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetReleaseAsset fetches a single release asset.
|
||||||
|
//
|
||||||
|
// GitHub API docs : http://developer.github.com/v3/repos/releases/#get-a-single-release-asset
|
||||||
|
func (s *RepositoriesService) GetReleaseAsset(owner, repo string, id int) (*ReleaseAsset, *Response, 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, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
asset := new(ReleaseAsset)
|
||||||
|
resp, err := s.client.Do(req, asset)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, nil
|
||||||
|
}
|
||||||
|
return asset, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditReleaseAsset edits a repository release asset.
|
||||||
|
//
|
||||||
|
// GitHub API docs : http://developer.github.com/v3/repos/releases/#edit-a-release-asset
|
||||||
|
func (s *RepositoriesService) EditReleaseAsset(owner, repo string, id int, release *ReleaseAsset) (*ReleaseAsset, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("PATCH", u, release)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
asset := new(ReleaseAsset)
|
||||||
|
resp, err := s.client.Do(req, asset)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
return asset, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteReleaseAsset delete a single release asset from a repository.
|
||||||
|
//
|
||||||
|
// GitHub API docs : http://developer.github.com/v3/repos/releases/#delete-a-release-asset
|
||||||
|
func (s *RepositoriesService) DeleteReleaseAsset(owner, repo string, id int) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UploadReleaseAsset creates an asset by uploading a file into a release repository.
|
||||||
|
// To upload assets that cannot be represented by an os.File, call NewUploadRequest directly.
|
||||||
|
//
|
||||||
|
// GitHub API docs : http://developer.github.com/v3/repos/releases/#upload-a-release-asset
|
||||||
|
func (s *RepositoriesService) UploadReleaseAsset(owner, repo string, id int, opt *UploadOptions, file *os.File) (*ReleaseAsset, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%s/%s/releases/%d/assets", owner, repo, id)
|
||||||
|
u, err := addOptions(u, opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
stat, err := file.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if stat.IsDir() {
|
||||||
|
return nil, nil, errors.New("The asset to upload can't be a directory")
|
||||||
|
}
|
||||||
|
|
||||||
|
mediaType := mime.TypeByExtension(filepath.Ext(file.Name()))
|
||||||
|
req, err := s.client.NewUploadRequest(u, file, stat.Size(), mediaType)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
asset := new(ReleaseAsset)
|
||||||
|
resp, err := s.client.Do(req, asset)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
return asset, resp, err
|
||||||
|
}
|
||||||
237
Godeps/_workspace/src/github.com/google/go-github/github/repos_releases_test.go
generated
vendored
Normal file
237
Godeps/_workspace/src/github.com/google/go-github/github/repos_releases_test.go
generated
vendored
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListReleases(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/releases", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{"page": "2"})
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListOptions{Page: 2}
|
||||||
|
releases, _, err := client.Repositories.ListReleases("o", "r", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.ListReleases returned error: %v", err)
|
||||||
|
}
|
||||||
|
want := []RepositoryRelease{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(releases, want) {
|
||||||
|
t.Errorf("Repositories.ListReleases returned %+v, want %+v", releases, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_GetRelease(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/releases/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
release, resp, err := client.Repositories.GetRelease("o", "r", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.GetRelease returned error: %v\n%v", err, resp.Body)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &RepositoryRelease{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(release, want) {
|
||||||
|
t.Errorf("Repositories.GetRelease returned %+v, want %+v", release, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_CreateRelease(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &RepositoryRelease{Name: String("v1.0")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/releases", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(RepositoryRelease)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
release, _, err := client.Repositories.CreateRelease("o", "r", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.CreateRelease returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &RepositoryRelease{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(release, want) {
|
||||||
|
t.Errorf("Repositories.CreateRelease returned %+v, want %+v", release, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_EditRelease(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &RepositoryRelease{Name: String("n")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/releases/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(RepositoryRelease)
|
||||||
|
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}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
release, _, err := client.Repositories.EditRelease("o", "r", 1, input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.EditRelease returned error: %v", err)
|
||||||
|
}
|
||||||
|
want := &RepositoryRelease{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(release, want) {
|
||||||
|
t.Errorf("Repositories.EditRelease returned = %+v, want %+v", release, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_DeleteRelease(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/releases/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Repositories.DeleteRelease("o", "r", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.DeleteRelease returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListReleaseAssets(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/releases/1/assets", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{"page": "2"})
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListOptions{Page: 2}
|
||||||
|
assets, _, err := client.Repositories.ListReleaseAssets("o", "r", 1, opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.ListReleaseAssets returned error: %v", err)
|
||||||
|
}
|
||||||
|
want := []ReleaseAsset{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(assets, want) {
|
||||||
|
t.Errorf("Repositories.ListReleaseAssets returned %+v, want %+v", assets, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_GetReleaseAsset(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")
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
asset, _, err := client.Repositories.GetReleaseAsset("o", "r", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.GetReleaseAsset returned error: %v", err)
|
||||||
|
}
|
||||||
|
want := &ReleaseAsset{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(asset, want) {
|
||||||
|
t.Errorf("Repositories.GetReleaseAsset returned %+v, want %+v", asset, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_EditReleaseAsset(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &ReleaseAsset{Name: String("n")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/releases/assets/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(ReleaseAsset)
|
||||||
|
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}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
asset, _, err := client.Repositories.EditReleaseAsset("o", "r", 1, input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.EditReleaseAsset returned error: %v", err)
|
||||||
|
}
|
||||||
|
want := &ReleaseAsset{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(asset, want) {
|
||||||
|
t.Errorf("Repositories.EditReleaseAsset returned = %+v, want %+v", asset, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_DeleteReleaseAsset(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/releases/assets/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Repositories.DeleteReleaseAsset("o", "r", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.DeleteReleaseAsset returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_UploadReleaseAsset(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/releases/1/assets", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
testHeader(t, r, "Content-Type", "text/plain; charset=utf-8")
|
||||||
|
testHeader(t, r, "Content-Length", "12")
|
||||||
|
testFormValues(t, r, values{"name": "n"})
|
||||||
|
testBody(t, r, "Upload me !\n")
|
||||||
|
|
||||||
|
fmt.Fprintf(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
file, dir, err := openTestFile("upload.txt", "Upload me !\n")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create temp file: %v", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
|
opt := &UploadOptions{Name: "n"}
|
||||||
|
asset, _, err := client.Repositories.UploadReleaseAsset("o", "r", 1, opt, file)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.UploadReleaseAssert returned error: %v", err)
|
||||||
|
}
|
||||||
|
want := &ReleaseAsset{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(asset, want) {
|
||||||
|
t.Errorf("Repositories.UploadReleaseAssert returned %+v, want %+v", asset, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
214
Godeps/_workspace/src/github.com/google/go-github/github/repos_stats.go
generated
vendored
Normal file
214
Godeps/_workspace/src/github.com/google/go-github/github/repos_stats.go
generated
vendored
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
// Copyright 2014 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"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ContributorStats represents a contributor to a repository and their
|
||||||
|
// weekly contributions to a given repo.
|
||||||
|
type ContributorStats struct {
|
||||||
|
Author *Contributor `json:"author,omitempty"`
|
||||||
|
Total *int `json:"total,omitempty"`
|
||||||
|
Weeks []WeeklyStats `json:"weeks,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c ContributorStats) String() string {
|
||||||
|
return Stringify(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WeeklyStats represents the number of additions, deletions and commits
|
||||||
|
// a Contributor made in a given week.
|
||||||
|
type WeeklyStats struct {
|
||||||
|
Week *Timestamp `json:"w,omitempty"`
|
||||||
|
Additions *int `json:"a,omitempty"`
|
||||||
|
Deletions *int `json:"d,omitempty"`
|
||||||
|
Commits *int `json:"c,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WeeklyStats) String() string {
|
||||||
|
return Stringify(w)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListContributorsStats gets a repo's contributor list with additions,
|
||||||
|
// deletions and commit counts.
|
||||||
|
//
|
||||||
|
// If this is the first time these statistics are requested for the given
|
||||||
|
// repository, this method will return a non-nil error and a status code of
|
||||||
|
// 202. This is because this is the status that github returns to signify that
|
||||||
|
// it is now computing the requested statistics. A follow up request, after a
|
||||||
|
// delay of a second or so, should result in a successful request.
|
||||||
|
//
|
||||||
|
// GitHub API Docs: https://developer.github.com/v3/repos/statistics/#contributors
|
||||||
|
func (s *RepositoriesService) ListContributorsStats(owner, repo string) ([]ContributorStats, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/stats/contributors", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var contributorStats []ContributorStats
|
||||||
|
resp, err := s.client.Do(req, &contributorStats)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return contributorStats, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// WeeklyCommitActivity represents the weekly commit activity for a repository.
|
||||||
|
// The days array is a group of commits per day, starting on Sunday.
|
||||||
|
type WeeklyCommitActivity struct {
|
||||||
|
Days []int `json:"days,omitempty"`
|
||||||
|
Total *int `json:"total,omitempty"`
|
||||||
|
Week *Timestamp `json:"week,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WeeklyCommitActivity) String() string {
|
||||||
|
return Stringify(w)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListCommitActivity returns the last year of commit activity
|
||||||
|
// grouped by week. The days array is a group of commits per day,
|
||||||
|
// starting on Sunday.
|
||||||
|
//
|
||||||
|
// If this is the first time these statistics are requested for the given
|
||||||
|
// repository, this method will return a non-nil error and a status code of
|
||||||
|
// 202. This is because this is the status that github returns to signify that
|
||||||
|
// it is now computing the requested statistics. A follow up request, after a
|
||||||
|
// delay of a second or so, should result in a successful request.
|
||||||
|
//
|
||||||
|
// GitHub API Docs: https://developer.github.com/v3/repos/statistics/#commit-activity
|
||||||
|
func (s *RepositoriesService) ListCommitActivity(owner, repo string) ([]WeeklyCommitActivity, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/stats/commit_activity", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var weeklyCommitActivity []WeeklyCommitActivity
|
||||||
|
resp, err := s.client.Do(req, &weeklyCommitActivity)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return weeklyCommitActivity, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListCodeFrequency returns a weekly aggregate of the number of additions and
|
||||||
|
// deletions pushed to a repository. Returned WeeklyStats will contain
|
||||||
|
// additiona and deletions, but not total commits.
|
||||||
|
//
|
||||||
|
// GitHub API Docs: https://developer.github.com/v3/repos/statistics/#code-frequency
|
||||||
|
func (s *RepositoriesService) ListCodeFrequency(owner, repo string) ([]WeeklyStats, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/stats/code_frequency", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var weeks [][]int
|
||||||
|
resp, err := s.client.Do(req, &weeks)
|
||||||
|
|
||||||
|
// convert int slices into WeeklyStats
|
||||||
|
stats := make([]WeeklyStats, 0)
|
||||||
|
for _, week := range weeks {
|
||||||
|
if len(week) != 3 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
stat := WeeklyStats{
|
||||||
|
Week: &Timestamp{time.Unix(int64(week[0]), 0)},
|
||||||
|
Additions: Int(week[1]),
|
||||||
|
Deletions: Int(week[2]),
|
||||||
|
}
|
||||||
|
stats = append(stats, stat)
|
||||||
|
}
|
||||||
|
|
||||||
|
return stats, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepositoryParticipation is the number of commits by everyone
|
||||||
|
// who has contributed to the repository (including the owner)
|
||||||
|
// as well as the number of commits by the owner themself.
|
||||||
|
type RepositoryParticipation struct {
|
||||||
|
All []int `json:"all,omitempty"`
|
||||||
|
Owner []int `json:"owner,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r RepositoryParticipation) String() string {
|
||||||
|
return Stringify(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListParticipation returns the total commit counts for the 'owner'
|
||||||
|
// and total commit counts in 'all'. 'all' is everyone combined,
|
||||||
|
// including the 'owner' in the last 52 weeks. If you’d like to get
|
||||||
|
// the commit counts for non-owners, you can subtract 'all' from 'owner'.
|
||||||
|
//
|
||||||
|
// The array order is oldest week (index 0) to most recent week.
|
||||||
|
//
|
||||||
|
// If this is the first time these statistics are requested for the given
|
||||||
|
// repository, this method will return a non-nil error and a status code
|
||||||
|
// of 202. This is because this is the status that github returns to
|
||||||
|
// signify that it is now computing the requested statistics. A follow
|
||||||
|
// up request, after a delay of a second or so, should result in a
|
||||||
|
// successful request.
|
||||||
|
//
|
||||||
|
// GitHub API Docs: https://developer.github.com/v3/repos/statistics/#participation
|
||||||
|
func (s *RepositoriesService) ListParticipation(owner, repo string) (*RepositoryParticipation, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/stats/participation", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
participation := new(RepositoryParticipation)
|
||||||
|
resp, err := s.client.Do(req, participation)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return participation, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// PunchCard respresents the number of commits made during a given hour of a
|
||||||
|
// day of thew eek.
|
||||||
|
type PunchCard struct {
|
||||||
|
Day *int // Day of the week (0-6: =Sunday - Saturday).
|
||||||
|
Hour *int // Hour of day (0-23).
|
||||||
|
Commits *int // Number of commits.
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPunchCard returns the number of commits per hour in each day.
|
||||||
|
//
|
||||||
|
// GitHub API Docs: https://developer.github.com/v3/repos/statistics/#punch-card
|
||||||
|
func (s *RepositoriesService) ListPunchCard(owner, repo string) ([]PunchCard, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/stats/punch_card", owner, repo)
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var results [][]int
|
||||||
|
resp, err := s.client.Do(req, &results)
|
||||||
|
|
||||||
|
// convert int slices into Punchcards
|
||||||
|
cards := make([]PunchCard, 0)
|
||||||
|
for _, result := range results {
|
||||||
|
if len(result) != 3 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
card := PunchCard{
|
||||||
|
Day: Int(result[0]),
|
||||||
|
Hour: Int(result[1]),
|
||||||
|
Commits: Int(result[2]),
|
||||||
|
}
|
||||||
|
cards = append(cards, card)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cards, resp, err
|
||||||
|
}
|
||||||
210
Godeps/_workspace/src/github.com/google/go-github/github/repos_stats_test.go
generated
vendored
Normal file
210
Godeps/_workspace/src/github.com/google/go-github/github/repos_stats_test.go
generated
vendored
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
// Copyright 2014 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"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListContributorsStats(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/stats/contributors", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
|
||||||
|
fmt.Fprint(w, `
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"author": {
|
||||||
|
"id": 1
|
||||||
|
},
|
||||||
|
"total": 135,
|
||||||
|
"weeks": [
|
||||||
|
{
|
||||||
|
"w": 1367712000,
|
||||||
|
"a": 6898,
|
||||||
|
"d": 77,
|
||||||
|
"c": 10
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
stats, _, err := client.Repositories.ListContributorsStats("o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("RepositoriesService.ListContributorsStats returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []ContributorStats{
|
||||||
|
ContributorStats{
|
||||||
|
Author: &Contributor{
|
||||||
|
ID: Int(1),
|
||||||
|
},
|
||||||
|
Total: Int(135),
|
||||||
|
Weeks: []WeeklyStats{
|
||||||
|
{
|
||||||
|
Week: &Timestamp{time.Date(2013, 05, 05, 00, 00, 00, 0, time.UTC).Local()},
|
||||||
|
Additions: Int(6898),
|
||||||
|
Deletions: Int(77),
|
||||||
|
Commits: Int(10),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(stats, want) {
|
||||||
|
t.Errorf("RepositoriesService.ListContributorsStats returned %+v, want %+v", stats, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListCommitActivity(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/stats/commit_activity", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
|
||||||
|
fmt.Fprint(w, `
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"days": [0, 3, 26, 20, 39, 1, 0],
|
||||||
|
"total": 89,
|
||||||
|
"week": 1336280400
|
||||||
|
}
|
||||||
|
]
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
activity, _, err := client.Repositories.ListCommitActivity("o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("RepositoriesService.ListCommitActivity returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []WeeklyCommitActivity{
|
||||||
|
{
|
||||||
|
Days: []int{0, 3, 26, 20, 39, 1, 0},
|
||||||
|
Total: Int(89),
|
||||||
|
Week: &Timestamp{time.Date(2012, 05, 06, 05, 00, 00, 0, time.UTC).Local()},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(activity, want) {
|
||||||
|
t.Errorf("RepositoriesService.ListCommitActivity returned %+v, want %+v", activity, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListCodeFrequency(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/stats/code_frequency", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
|
||||||
|
fmt.Fprint(w, `[[1302998400, 1124, -435]]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
code, _, err := client.Repositories.ListCodeFrequency("o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("RepositoriesService.ListCodeFrequency returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []WeeklyStats{{
|
||||||
|
Week: &Timestamp{time.Date(2011, 04, 17, 00, 00, 00, 0, time.UTC).Local()},
|
||||||
|
Additions: Int(1124),
|
||||||
|
Deletions: Int(-435),
|
||||||
|
}}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(code, want) {
|
||||||
|
t.Errorf("RepositoriesService.ListCodeFrequency returned %+v, want %+v", code, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_Participation(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/stats/participation", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
|
||||||
|
fmt.Fprint(w, `
|
||||||
|
{
|
||||||
|
"all": [
|
||||||
|
11,21,15,2,8,1,8,23,17,21,11,10,33,
|
||||||
|
91,38,34,22,23,32,3,43,87,71,18,13,5,
|
||||||
|
13,16,66,27,12,45,110,117,13,8,18,9,19,
|
||||||
|
26,39,12,20,31,46,91,45,10,24,9,29,7
|
||||||
|
],
|
||||||
|
"owner": [
|
||||||
|
3,2,3,0,2,0,5,14,7,9,1,5,0,
|
||||||
|
48,19,2,0,1,10,2,23,40,35,8,8,2,
|
||||||
|
10,6,30,0,2,9,53,104,3,3,10,4,7,
|
||||||
|
11,21,4,4,22,26,63,11,2,14,1,10,3
|
||||||
|
]
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
participation, _, err := client.Repositories.ListParticipation("o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("RepositoriesService.ListParticipation returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &RepositoryParticipation{
|
||||||
|
All: []int{
|
||||||
|
11, 21, 15, 2, 8, 1, 8, 23, 17, 21, 11, 10, 33,
|
||||||
|
91, 38, 34, 22, 23, 32, 3, 43, 87, 71, 18, 13, 5,
|
||||||
|
13, 16, 66, 27, 12, 45, 110, 117, 13, 8, 18, 9, 19,
|
||||||
|
26, 39, 12, 20, 31, 46, 91, 45, 10, 24, 9, 29, 7,
|
||||||
|
},
|
||||||
|
Owner: []int{
|
||||||
|
3, 2, 3, 0, 2, 0, 5, 14, 7, 9, 1, 5, 0,
|
||||||
|
48, 19, 2, 0, 1, 10, 2, 23, 40, 35, 8, 8, 2,
|
||||||
|
10, 6, 30, 0, 2, 9, 53, 104, 3, 3, 10, 4, 7,
|
||||||
|
11, 21, 4, 4, 22, 26, 63, 11, 2, 14, 1, 10, 3,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(participation, want) {
|
||||||
|
t.Errorf("RepositoriesService.ListParticipation returned %+v, want %+v", participation, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListPunchCard(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/stats/punch_card", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
|
||||||
|
fmt.Fprint(w, `[
|
||||||
|
[0, 0, 5],
|
||||||
|
[0, 1, 43],
|
||||||
|
[0, 2, 21]
|
||||||
|
]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
card, _, err := client.Repositories.ListPunchCard("o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("RepositoriesService.ListPunchCard returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []PunchCard{
|
||||||
|
{Day: Int(0), Hour: Int(0), Commits: Int(5)},
|
||||||
|
{Day: Int(0), Hour: Int(1), Commits: Int(43)},
|
||||||
|
{Day: Int(0), Hour: Int(2), Commits: Int(21)},
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(card, want) {
|
||||||
|
t.Errorf("RepositoriesService.ListPunchCard returned %+v, want %+v", card, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
83
Godeps/_workspace/src/github.com/google/go-github/github/repos_statuses.go
generated
vendored
Normal file
83
Godeps/_workspace/src/github.com/google/go-github/github/repos_statuses.go
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
// 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"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RepoStatus represents the status of a repository at a particular reference.
|
||||||
|
type RepoStatus struct {
|
||||||
|
ID *int `json:"id,omitempty"`
|
||||||
|
|
||||||
|
// State is the current state of the repository. Possible values are:
|
||||||
|
// pending, success, error, or failure.
|
||||||
|
State *string `json:"state,omitempty"`
|
||||||
|
|
||||||
|
// TargetURL is the URL of the page representing this status. It will be
|
||||||
|
// linked from the GitHub UI to allow users to see the source of the status.
|
||||||
|
TargetURL *string `json:"target_url,omitempty"`
|
||||||
|
|
||||||
|
// Description is a short high level summary of the status.
|
||||||
|
Description *string `json:"description,omitempty"`
|
||||||
|
|
||||||
|
// A string label to differentiate this status from the statuses of other systems.
|
||||||
|
Context *string `json:"context,omitempty"`
|
||||||
|
|
||||||
|
Creator *User `json:"creator,omitempty"`
|
||||||
|
CreatedAt *time.Time `json:"created_at,omitempty"`
|
||||||
|
UpdatedAt *time.Time `json:"updated_at,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r RepoStatus) String() string {
|
||||||
|
return Stringify(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListStatuses lists the statuses of a repository at the specified
|
||||||
|
// reference. ref can be a SHA, a branch name, or a tag name.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/statuses/#list-statuses-for-a-specific-ref
|
||||||
|
func (s *RepositoriesService) ListStatuses(owner, repo, ref string, opt *ListOptions) ([]RepoStatus, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/statuses/%v", owner, repo, ref)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
statuses := new([]RepoStatus)
|
||||||
|
resp, err := s.client.Do(req, statuses)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *statuses, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateStatus creates a new status for a repository at the specified
|
||||||
|
// reference. Ref can be a SHA, a branch name, or a tag name.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/repos/statuses/#create-a-status
|
||||||
|
func (s *RepositoriesService) CreateStatus(owner, repo, ref string, status *RepoStatus) (*RepoStatus, *Response, error) {
|
||||||
|
u := fmt.Sprintf("repos/%v/%v/statuses/%v", owner, repo, ref)
|
||||||
|
req, err := s.client.NewRequest("POST", u, status)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
statuses := new(RepoStatus)
|
||||||
|
resp, err := s.client.Do(req, statuses)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return statuses, resp, err
|
||||||
|
}
|
||||||
74
Godeps/_workspace/src/github.com/google/go-github/github/repos_statuses_test.go
generated
vendored
Normal file
74
Godeps/_workspace/src/github.com/google/go-github/github/repos_statuses_test.go
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListStatuses(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/statuses/r", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{"page": "2"})
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListOptions{Page: 2}
|
||||||
|
statuses, _, err := client.Repositories.ListStatuses("o", "r", "r", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.ListStatuses returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []RepoStatus{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(statuses, want) {
|
||||||
|
t.Errorf("Repositories.ListStatuses returned %+v, want %+v", statuses, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListStatuses_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.ListStatuses("%", "r", "r", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_CreateStatus(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &RepoStatus{State: String("s"), TargetURL: String("t"), Description: String("d")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/statuses/r", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(RepoStatus)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
status, _, err := client.Repositories.CreateStatus("o", "r", "r", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.CreateStatus returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &RepoStatus{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(status, want) {
|
||||||
|
t.Errorf("Repositories.CreateStatus returned %+v, want %+v", status, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_CreateStatus_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.CreateStatus("%", "r", "r", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
406
Godeps/_workspace/src/github.com/google/go-github/github/repos_test.go
generated
vendored
Normal file
406
Godeps/_workspace/src/github.com/google/go-github/github/repos_test.go
generated
vendored
Normal file
@@ -0,0 +1,406 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRepositoriesService_List_authenticatedUser(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/user/repos", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `[{"id":1},{"id":2}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
repos, _, err := client.Repositories.List("", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.List returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Repository{{ID: Int(1)}, {ID: Int(2)}}
|
||||||
|
if !reflect.DeepEqual(repos, want) {
|
||||||
|
t.Errorf("Repositories.List returned %+v, want %+v", repos, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_List_specifiedUser(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/users/u/repos", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"type": "owner",
|
||||||
|
"sort": "created",
|
||||||
|
"direction": "asc",
|
||||||
|
"page": "2",
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &RepositoryListOptions{"owner", "created", "asc", ListOptions{Page: 2}}
|
||||||
|
repos, _, err := client.Repositories.List("u", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.List returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Repository{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(repos, want) {
|
||||||
|
t.Errorf("Repositories.List returned %+v, want %+v", repos, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_List_invalidUser(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.List("%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListByOrg(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/repos", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"type": "forks",
|
||||||
|
"page": "2",
|
||||||
|
})
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &RepositoryListByOrgOptions{"forks", ListOptions{Page: 2}}
|
||||||
|
repos, _, err := client.Repositories.ListByOrg("o", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.ListByOrg returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Repository{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(repos, want) {
|
||||||
|
t.Errorf("Repositories.ListByOrg returned %+v, want %+v", repos, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListByOrg_invalidOrg(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.ListByOrg("%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListAll(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repositories", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"since": "1",
|
||||||
|
"page": "2",
|
||||||
|
"per_page": "3",
|
||||||
|
})
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &RepositoryListAllOptions{1, ListOptions{2, 3}}
|
||||||
|
repos, _, err := client.Repositories.ListAll(opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.ListAll returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Repository{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(repos, want) {
|
||||||
|
t.Errorf("Repositories.ListAll returned %+v, want %+v", repos, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_Create_user(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &Repository{Name: String("n")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/user/repos", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(Repository)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
repo, _, err := client.Repositories.Create("", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.Create returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Repository{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(repo, want) {
|
||||||
|
t.Errorf("Repositories.Create returned %+v, want %+v", repo, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_Create_org(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := &Repository{Name: String("n")}
|
||||||
|
|
||||||
|
mux.HandleFunc("/orgs/o/repos", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(Repository)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"id":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
repo, _, err := client.Repositories.Create("o", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.Create returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Repository{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(repo, want) {
|
||||||
|
t.Errorf("Repositories.Create returned %+v, want %+v", repo, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_Create_invalidOrg(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.Create("%", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_Get(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"id":1,"name":"n","description":"d","owner":{"login":"l"}}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
repo, _, err := client.Repositories.Get("o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.Get returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Repository{ID: Int(1), Name: String("n"), Description: String("d"), Owner: &User{Login: String("l")}}
|
||||||
|
if !reflect.DeepEqual(repo, want) {
|
||||||
|
t.Errorf("Repositories.Get returned %+v, want %+v", repo, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_Edit(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
i := true
|
||||||
|
input := &Repository{HasIssues: &i}
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(Repository)
|
||||||
|
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}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
repo, _, err := client.Repositories.Edit("o", "r", input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.Edit returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Repository{ID: Int(1)}
|
||||||
|
if !reflect.DeepEqual(repo, want) {
|
||||||
|
t.Errorf("Repositories.Edit returned %+v, want %+v", repo, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_Delete(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Repositories.Delete("o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.Delete returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_Get_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.Get("%", "r")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_Edit_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.Edit("%", "r", nil)
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListContributors(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/contributors", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"anon": "true",
|
||||||
|
"page": "2",
|
||||||
|
})
|
||||||
|
fmt.Fprint(w, `[{"contributions":42}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opts := &ListContributorsOptions{Anon: "true", ListOptions: ListOptions{Page: 2}}
|
||||||
|
contributors, _, err := client.Repositories.ListContributors("o", "r", opts)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.ListContributors returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Contributor{{Contributions: Int(42)}}
|
||||||
|
if !reflect.DeepEqual(contributors, want) {
|
||||||
|
t.Errorf("Repositories.ListContributors returned %+v, want %+v", contributors, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListLanguages(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/languages", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"go":1}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
languages, _, err := client.Repositories.ListLanguages("o", "r")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.ListLanguages returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := map[string]int{"go": 1}
|
||||||
|
if !reflect.DeepEqual(languages, want) {
|
||||||
|
t.Errorf("Repositories.ListLanguages returned %+v, want %+v", languages, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListTeams(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/teams", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{"page": "2"})
|
||||||
|
fmt.Fprint(w, `[{"id":1}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListOptions{Page: 2}
|
||||||
|
teams, _, err := client.Repositories.ListTeams("o", "r", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.ListTeams returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Team{{ID: Int(1)}}
|
||||||
|
if !reflect.DeepEqual(teams, want) {
|
||||||
|
t.Errorf("Repositories.ListTeams returned %+v, want %+v", teams, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListTags(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/tags", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{"page": "2"})
|
||||||
|
fmt.Fprint(w, `[{"name":"n", "commit" : {"sha" : "s", "url" : "u"}, "zipball_url": "z", "tarball_url": "t"}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListOptions{Page: 2}
|
||||||
|
tags, _, err := client.Repositories.ListTags("o", "r", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.ListTags returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []RepositoryTag{
|
||||||
|
{
|
||||||
|
Name: String("n"),
|
||||||
|
Commit: &Commit{
|
||||||
|
SHA: String("s"),
|
||||||
|
URL: String("u"),
|
||||||
|
},
|
||||||
|
ZipballURL: String("z"),
|
||||||
|
TarballURL: String("t"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(tags, want) {
|
||||||
|
t.Errorf("Repositories.ListTags returned %+v, want %+v", tags, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListBranches(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/branches", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{"page": "2"})
|
||||||
|
fmt.Fprint(w, `[{"name":"master", "commit" : {"sha" : "a57781", "url" : "https://api.github.com/repos/o/r/commits/a57781"}}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListOptions{Page: 2}
|
||||||
|
branches, _, err := client.Repositories.ListBranches("o", "r", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.ListBranches returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []Branch{{Name: String("master"), Commit: &Commit{SHA: String("a57781"), URL: String("https://api.github.com/repos/o/r/commits/a57781")}}}
|
||||||
|
if !reflect.DeepEqual(branches, want) {
|
||||||
|
t.Errorf("Repositories.ListBranches returned %+v, want %+v", branches, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_GetBranch(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/repos/o/r/branches/b", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
fmt.Fprint(w, `{"name":"n", "commit":{"sha":"s"}}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
branch, _, err := client.Repositories.GetBranch("o", "r", "b")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Repositories.GetBranch returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &Branch{Name: String("n"), Commit: &Commit{SHA: String("s")}}
|
||||||
|
if !reflect.DeepEqual(branch, want) {
|
||||||
|
t.Errorf("Repositories.GetBranch returned %+v, want %+v", branch, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoriesService_ListLanguages_invalidOwner(t *testing.T) {
|
||||||
|
_, _, err := client.Repositories.ListLanguages("%", "%")
|
||||||
|
testURLParseError(t, err)
|
||||||
|
}
|
||||||
129
Godeps/_workspace/src/github.com/google/go-github/github/search.go
generated
vendored
Normal file
129
Godeps/_workspace/src/github.com/google/go-github/github/search.go
generated
vendored
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
// 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"
|
||||||
|
|
||||||
|
qs "github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SearchService provides access to the search related functions
|
||||||
|
// in the GitHub API.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/search/
|
||||||
|
type SearchService struct {
|
||||||
|
client *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// SearchOptions specifies optional parameters to the SearchService methods.
|
||||||
|
type SearchOptions struct {
|
||||||
|
// How to sort the search results. Possible values are:
|
||||||
|
// - for repositories: stars, fork, updated
|
||||||
|
// - for code: indexed
|
||||||
|
// - for issues: comments, created, updated
|
||||||
|
// - for users: followers, repositories, joined
|
||||||
|
//
|
||||||
|
// Default is to sort by best match.
|
||||||
|
Sort string `url:"sort,omitempty"`
|
||||||
|
|
||||||
|
// Sort order if sort parameter is provided. Possible values are: asc,
|
||||||
|
// desc. Default is desc.
|
||||||
|
Order string `url:"order,omitempty"`
|
||||||
|
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepositoriesSearchResult represents the result of a repositories search.
|
||||||
|
type RepositoriesSearchResult struct {
|
||||||
|
Total *int `json:"total_count,omitempty"`
|
||||||
|
Repositories []Repository `json:"items,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Repositories searches repositories via various criteria.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/search/#search-repositories
|
||||||
|
func (s *SearchService) Repositories(query string, opt *SearchOptions) (*RepositoriesSearchResult, *Response, error) {
|
||||||
|
result := new(RepositoriesSearchResult)
|
||||||
|
resp, err := s.search("repositories", query, opt, result)
|
||||||
|
return result, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// IssuesSearchResult represents the result of an issues search.
|
||||||
|
type IssuesSearchResult struct {
|
||||||
|
Total *int `json:"total_count,omitempty"`
|
||||||
|
Issues []Issue `json:"items,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Issues searches issues via various criteria.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/search/#search-issues
|
||||||
|
func (s *SearchService) Issues(query string, opt *SearchOptions) (*IssuesSearchResult, *Response, error) {
|
||||||
|
result := new(IssuesSearchResult)
|
||||||
|
resp, err := s.search("issues", query, opt, result)
|
||||||
|
return result, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UsersSearchResult represents the result of an issues search.
|
||||||
|
type UsersSearchResult struct {
|
||||||
|
Total *int `json:"total_count,omitempty"`
|
||||||
|
Users []User `json:"items,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Users searches users via various criteria.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/search/#search-users
|
||||||
|
func (s *SearchService) Users(query string, opt *SearchOptions) (*UsersSearchResult, *Response, error) {
|
||||||
|
result := new(UsersSearchResult)
|
||||||
|
resp, err := s.search("users", query, opt, result)
|
||||||
|
return result, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CodeSearchResult represents the result of an code search.
|
||||||
|
type CodeSearchResult struct {
|
||||||
|
Total *int `json:"total_count,omitempty"`
|
||||||
|
CodeResults []CodeResult `json:"items,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CodeResult represents a single search result.
|
||||||
|
type CodeResult struct {
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
Path *string `json:"path,omitempty"`
|
||||||
|
SHA *string `json:"sha,omitempty"`
|
||||||
|
HTMLURL *string `json:"html_url,omitempty"`
|
||||||
|
Repository *Repository `json:"repository,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CodeResult) String() string {
|
||||||
|
return Stringify(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code searches code via various criteria.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/search/#search-code
|
||||||
|
func (s *SearchService) Code(query string, opt *SearchOptions) (*CodeSearchResult, *Response, error) {
|
||||||
|
result := new(CodeSearchResult)
|
||||||
|
resp, err := s.search("code", query, opt, result)
|
||||||
|
return result, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function that executes search queries against different
|
||||||
|
// GitHub search types (repositories, code, issues, users)
|
||||||
|
func (s *SearchService) search(searchType string, query string, opt *SearchOptions, result interface{}) (*Response, error) {
|
||||||
|
params, err := qs.Values(opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
params.Add("q", query)
|
||||||
|
u := fmt.Sprintf("search/%s?%s", searchType, params.Encode())
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(req, result)
|
||||||
|
}
|
||||||
137
Godeps/_workspace/src/github.com/google/go-github/github/search_test.go
generated
vendored
Normal file
137
Godeps/_workspace/src/github.com/google/go-github/github/search_test.go
generated
vendored
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSearchService_Repositories(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/search/repositories", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"q": "blah",
|
||||||
|
"sort": "forks",
|
||||||
|
"order": "desc",
|
||||||
|
"page": "2",
|
||||||
|
"per_page": "2",
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"total_count": 4, "items": [{"id":1},{"id":2}]}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opts := &SearchOptions{Sort: "forks", Order: "desc", ListOptions: ListOptions{Page: 2, PerPage: 2}}
|
||||||
|
result, _, err := client.Search.Repositories("blah", opts)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Search.Repositories returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &RepositoriesSearchResult{
|
||||||
|
Total: Int(4),
|
||||||
|
Repositories: []Repository{{ID: Int(1)}, {ID: Int(2)}},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(result, want) {
|
||||||
|
t.Errorf("Search.Repositories returned %+v, want %+v", result, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSearchService_Issues(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/search/issues", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"q": "blah",
|
||||||
|
"sort": "forks",
|
||||||
|
"order": "desc",
|
||||||
|
"page": "2",
|
||||||
|
"per_page": "2",
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"total_count": 4, "items": [{"number":1},{"number":2}]}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opts := &SearchOptions{Sort: "forks", Order: "desc", ListOptions: ListOptions{Page: 2, PerPage: 2}}
|
||||||
|
result, _, err := client.Search.Issues("blah", opts)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Search.Issues returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &IssuesSearchResult{
|
||||||
|
Total: Int(4),
|
||||||
|
Issues: []Issue{{Number: Int(1)}, {Number: Int(2)}},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(result, want) {
|
||||||
|
t.Errorf("Search.Issues returned %+v, want %+v", result, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSearchService_Users(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/search/users", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"q": "blah",
|
||||||
|
"sort": "forks",
|
||||||
|
"order": "desc",
|
||||||
|
"page": "2",
|
||||||
|
"per_page": "2",
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"total_count": 4, "items": [{"id":1},{"id":2}]}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opts := &SearchOptions{Sort: "forks", Order: "desc", ListOptions: ListOptions{Page: 2, PerPage: 2}}
|
||||||
|
result, _, err := client.Search.Users("blah", opts)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Search.Issues returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &UsersSearchResult{
|
||||||
|
Total: Int(4),
|
||||||
|
Users: []User{{ID: Int(1)}, {ID: Int(2)}},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(result, want) {
|
||||||
|
t.Errorf("Search.Users returned %+v, want %+v", result, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSearchService_Code(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/search/code", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{
|
||||||
|
"q": "blah",
|
||||||
|
"sort": "forks",
|
||||||
|
"order": "desc",
|
||||||
|
"page": "2",
|
||||||
|
"per_page": "2",
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Fprint(w, `{"total_count": 4, "items": [{"name":"1"},{"name":"2"}]}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opts := &SearchOptions{Sort: "forks", Order: "desc", ListOptions: ListOptions{Page: 2, PerPage: 2}}
|
||||||
|
result, _, err := client.Search.Code("blah", opts)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Search.Code returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &CodeSearchResult{
|
||||||
|
Total: Int(4),
|
||||||
|
CodeResults: []CodeResult{{Name: String("1")}, {Name: String("2")}},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(result, want) {
|
||||||
|
t.Errorf("Search.Code returned %+v, want %+v", result, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
93
Godeps/_workspace/src/github.com/google/go-github/github/strings.go
generated
vendored
Normal file
93
Godeps/_workspace/src/github.com/google/go-github/github/strings.go
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
// 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 (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
var timestampType = reflect.TypeOf(Timestamp{})
|
||||||
|
|
||||||
|
// Stringify attempts to create a reasonable string representation of types in
|
||||||
|
// the GitHub library. It does things like resolve pointers to their values
|
||||||
|
// and omits struct fields with nil values.
|
||||||
|
func Stringify(message interface{}) string {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
v := reflect.ValueOf(message)
|
||||||
|
stringifyValue(&buf, v)
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// stringifyValue was heavily inspired by the goprotobuf library.
|
||||||
|
|
||||||
|
func stringifyValue(w io.Writer, val reflect.Value) {
|
||||||
|
if val.Kind() == reflect.Ptr && val.IsNil() {
|
||||||
|
w.Write([]byte("<nil>"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
v := reflect.Indirect(val)
|
||||||
|
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.String:
|
||||||
|
fmt.Fprintf(w, `"%s"`, v)
|
||||||
|
case reflect.Slice:
|
||||||
|
w.Write([]byte{'['})
|
||||||
|
for i := 0; i < v.Len(); i++ {
|
||||||
|
if i > 0 {
|
||||||
|
w.Write([]byte{' '})
|
||||||
|
}
|
||||||
|
|
||||||
|
stringifyValue(w, v.Index(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write([]byte{']'})
|
||||||
|
return
|
||||||
|
case reflect.Struct:
|
||||||
|
if v.Type().Name() != "" {
|
||||||
|
w.Write([]byte(v.Type().String()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// special handling of Timestamp values
|
||||||
|
if v.Type() == timestampType {
|
||||||
|
fmt.Fprintf(w, "{%s}", v.Interface())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write([]byte{'{'})
|
||||||
|
|
||||||
|
var sep bool
|
||||||
|
for i := 0; i < v.NumField(); i++ {
|
||||||
|
fv := v.Field(i)
|
||||||
|
if fv.Kind() == reflect.Ptr && fv.IsNil() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if fv.Kind() == reflect.Slice && fv.IsNil() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if sep {
|
||||||
|
w.Write([]byte(", "))
|
||||||
|
} else {
|
||||||
|
sep = true
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write([]byte(v.Type().Field(i).Name))
|
||||||
|
w.Write([]byte{':'})
|
||||||
|
stringifyValue(w, fv)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write([]byte{'}'})
|
||||||
|
default:
|
||||||
|
if v.CanInterface() {
|
||||||
|
fmt.Fprint(w, v.Interface())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
137
Godeps/_workspace/src/github.com/google/go-github/github/strings_test.go
generated
vendored
Normal file
137
Godeps/_workspace/src/github.com/google/go-github/github/strings_test.go
generated
vendored
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
// 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"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestStringify(t *testing.T) {
|
||||||
|
var nilPointer *string
|
||||||
|
|
||||||
|
var tests = []struct {
|
||||||
|
in interface{}
|
||||||
|
out string
|
||||||
|
}{
|
||||||
|
// basic types
|
||||||
|
{"foo", `"foo"`},
|
||||||
|
{123, `123`},
|
||||||
|
{1.5, `1.5`},
|
||||||
|
{false, `false`},
|
||||||
|
{
|
||||||
|
[]string{"a", "b"},
|
||||||
|
`["a" "b"]`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
A []string
|
||||||
|
}{nil},
|
||||||
|
// nil slice is skipped
|
||||||
|
`{}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
A string
|
||||||
|
}{"foo"},
|
||||||
|
// structs not of a named type get no prefix
|
||||||
|
`{A:"foo"}`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// pointers
|
||||||
|
{nilPointer, `<nil>`},
|
||||||
|
{String("foo"), `"foo"`},
|
||||||
|
{Int(123), `123`},
|
||||||
|
{Bool(false), `false`},
|
||||||
|
{
|
||||||
|
[]*string{String("a"), String("b")},
|
||||||
|
`["a" "b"]`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// actual GitHub structs
|
||||||
|
{
|
||||||
|
Timestamp{time.Date(2006, 01, 02, 15, 04, 05, 0, time.UTC)},
|
||||||
|
`github.Timestamp{2006-01-02 15:04:05 +0000 UTC}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
&Timestamp{time.Date(2006, 01, 02, 15, 04, 05, 0, time.UTC)},
|
||||||
|
`github.Timestamp{2006-01-02 15:04:05 +0000 UTC}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
User{ID: Int(123), Name: String("n")},
|
||||||
|
`github.User{ID:123, Name:"n"}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Repository{Owner: &User{ID: Int(123)}},
|
||||||
|
`github.Repository{Owner:github.User{ID:123}}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tt := range tests {
|
||||||
|
s := Stringify(tt.in)
|
||||||
|
if s != tt.out {
|
||||||
|
t.Errorf("%d. Stringify(%q) => %q, want %q", i, tt.in, s, tt.out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Directly test the String() methods on various GitHub types. We don't do an
|
||||||
|
// exaustive test of all the various field types, since TestStringify() above
|
||||||
|
// takes care of that. Rather, we just make sure that Stringify() is being
|
||||||
|
// used to build the strings, which we do by verifying that pointers are
|
||||||
|
// stringified as their underlying value.
|
||||||
|
func TestString(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
in interface{}
|
||||||
|
out string
|
||||||
|
}{
|
||||||
|
{CodeResult{Name: String("n")}, `github.CodeResult{Name:"n"}`},
|
||||||
|
{CommitAuthor{Name: String("n")}, `github.CommitAuthor{Name:"n"}`},
|
||||||
|
{CommitFile{SHA: String("s")}, `github.CommitFile{SHA:"s"}`},
|
||||||
|
{CommitStats{Total: Int(1)}, `github.CommitStats{Total:1}`},
|
||||||
|
{CommitsComparison{TotalCommits: Int(1)}, `github.CommitsComparison{TotalCommits:1}`},
|
||||||
|
{Commit{SHA: String("s")}, `github.Commit{SHA:"s"}`},
|
||||||
|
{Event{ID: String("1")}, `github.Event{ID:"1"}`},
|
||||||
|
{GistComment{ID: Int(1)}, `github.GistComment{ID:1}`},
|
||||||
|
{GistFile{Size: Int(1)}, `github.GistFile{Size:1}`},
|
||||||
|
{Gist{ID: String("1")}, `github.Gist{ID:"1", Files:map[]}`},
|
||||||
|
{GitObject{SHA: String("s")}, `github.GitObject{SHA:"s"}`},
|
||||||
|
{Gitignore{Name: String("n")}, `github.Gitignore{Name:"n"}`},
|
||||||
|
{Hook{ID: Int(1)}, `github.Hook{Config:map[], ID:1}`},
|
||||||
|
{IssueComment{ID: Int(1)}, `github.IssueComment{ID:1}`},
|
||||||
|
{Issue{Number: Int(1)}, `github.Issue{Number:1}`},
|
||||||
|
{Key{ID: Int(1)}, `github.Key{ID:1}`},
|
||||||
|
{Label{Name: String("l")}, "l"},
|
||||||
|
{Organization{ID: Int(1)}, `github.Organization{ID:1}`},
|
||||||
|
{PullRequestComment{ID: Int(1)}, `github.PullRequestComment{ID:1}`},
|
||||||
|
{PullRequest{Number: Int(1)}, `github.PullRequest{Number:1}`},
|
||||||
|
{PushEventCommit{SHA: String("s")}, `github.PushEventCommit{SHA:"s"}`},
|
||||||
|
{PushEvent{PushID: Int(1)}, `github.PushEvent{PushID:1}`},
|
||||||
|
{Reference{Ref: String("r")}, `github.Reference{Ref:"r"}`},
|
||||||
|
{ReleaseAsset{ID: Int(1)}, `github.ReleaseAsset{ID:1}`},
|
||||||
|
{RepoStatus{ID: Int(1)}, `github.RepoStatus{ID:1}`},
|
||||||
|
{RepositoryComment{ID: Int(1)}, `github.RepositoryComment{ID:1}`},
|
||||||
|
{RepositoryCommit{SHA: String("s")}, `github.RepositoryCommit{SHA:"s"}`},
|
||||||
|
{RepositoryContent{Name: String("n")}, `github.RepositoryContent{Name:"n"}`},
|
||||||
|
{RepositoryRelease{ID: Int(1)}, `github.RepositoryRelease{ID:1}`},
|
||||||
|
{Repository{ID: Int(1)}, `github.Repository{ID:1}`},
|
||||||
|
{Team{ID: Int(1)}, `github.Team{ID:1}`},
|
||||||
|
{TreeEntry{SHA: String("s")}, `github.TreeEntry{SHA:"s"}`},
|
||||||
|
{Tree{SHA: String("s")}, `github.Tree{SHA:"s"}`},
|
||||||
|
{User{ID: Int(1)}, `github.User{ID:1}`},
|
||||||
|
{WebHookAuthor{Name: String("n")}, `github.WebHookAuthor{Name:"n"}`},
|
||||||
|
{WebHookCommit{ID: String("1")}, `github.WebHookCommit{ID:"1"}`},
|
||||||
|
{WebHookPayload{Ref: String("r")}, `github.WebHookPayload{Ref:"r"}`},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tt := range tests {
|
||||||
|
s := tt.in.(fmt.Stringer).String()
|
||||||
|
if s != tt.out {
|
||||||
|
t.Errorf("%d. String() => %q, want %q", i, tt.in, tt.out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
41
Godeps/_workspace/src/github.com/google/go-github/github/timestamp.go
generated
vendored
Normal file
41
Godeps/_workspace/src/github.com/google/go-github/github/timestamp.go
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
// 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 (
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Timestamp represents a time that can be unmarshalled from a JSON string
|
||||||
|
// formatted as either an RFC3339 or Unix timestamp. This is necessary for some
|
||||||
|
// fields since the GitHub API is inconsistent in how it represents times. All
|
||||||
|
// exported methods of time.Time can be called on Timestamp.
|
||||||
|
type Timestamp struct {
|
||||||
|
time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t Timestamp) String() string {
|
||||||
|
return t.Time.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||||
|
// Time is expected in RFC3339 or Unix format.
|
||||||
|
func (t *Timestamp) UnmarshalJSON(data []byte) (err error) {
|
||||||
|
str := string(data)
|
||||||
|
i, err := strconv.ParseInt(str, 10, 64)
|
||||||
|
if err == nil {
|
||||||
|
(*t).Time = time.Unix(i, 0)
|
||||||
|
} else {
|
||||||
|
(*t).Time, err = time.Parse(`"`+time.RFC3339+`"`, str)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equal reports whether t and u are equal based on time.Equal
|
||||||
|
func (t Timestamp) Equal(u Timestamp) bool {
|
||||||
|
return t.Time.Equal(u.Time)
|
||||||
|
}
|
||||||
181
Godeps/_workspace/src/github.com/google/go-github/github/timestamp_test.go
generated
vendored
Normal file
181
Godeps/_workspace/src/github.com/google/go-github/github/timestamp_test.go
generated
vendored
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
emptyTimeStr = `"0001-01-01T00:00:00Z"`
|
||||||
|
referenceTimeStr = `"2006-01-02T15:04:05Z"`
|
||||||
|
referenceUnixTimeStr = `1136214245`
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
referenceTime = time.Date(2006, 01, 02, 15, 04, 05, 0, time.UTC)
|
||||||
|
unixOrigin = time.Unix(0, 0).In(time.UTC)
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTimestamp_Marshal(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
data Timestamp
|
||||||
|
want string
|
||||||
|
wantErr bool
|
||||||
|
equal bool
|
||||||
|
}{
|
||||||
|
{"Reference", Timestamp{referenceTime}, referenceTimeStr, false, true},
|
||||||
|
{"Empty", Timestamp{}, emptyTimeStr, false, true},
|
||||||
|
{"Mismatch", Timestamp{}, referenceTimeStr, false, false},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
out, err := json.Marshal(tc.data)
|
||||||
|
if gotErr := err != nil; gotErr != tc.wantErr {
|
||||||
|
t.Errorf("%s: gotErr=%v, wantErr=%v, err=%v", tc.desc, gotErr, tc.wantErr, err)
|
||||||
|
}
|
||||||
|
got := string(out)
|
||||||
|
equal := got == tc.want
|
||||||
|
if (got == tc.want) != tc.equal {
|
||||||
|
t.Errorf("%s: got=%s, want=%s, equal=%v, want=%v", tc.desc, got, tc.want, equal, tc.equal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTimestamp_Unmarshal(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
data string
|
||||||
|
want Timestamp
|
||||||
|
wantErr bool
|
||||||
|
equal bool
|
||||||
|
}{
|
||||||
|
{"Reference", referenceTimeStr, Timestamp{referenceTime}, false, true},
|
||||||
|
{"ReferenceUnix", `1136214245`, Timestamp{referenceTime}, false, true},
|
||||||
|
{"Empty", emptyTimeStr, Timestamp{}, false, true},
|
||||||
|
{"UnixStart", `0`, Timestamp{unixOrigin}, false, true},
|
||||||
|
{"Mismatch", referenceTimeStr, Timestamp{}, false, false},
|
||||||
|
{"MismatchUnix", `0`, Timestamp{}, false, false},
|
||||||
|
{"Invalid", `"asdf"`, Timestamp{referenceTime}, true, false},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
var got Timestamp
|
||||||
|
err := json.Unmarshal([]byte(tc.data), &got)
|
||||||
|
if gotErr := err != nil; gotErr != tc.wantErr {
|
||||||
|
t.Errorf("%s: gotErr=%v, wantErr=%v, err=%v", tc.desc, gotErr, tc.wantErr, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
equal := got.Equal(tc.want)
|
||||||
|
if equal != tc.equal {
|
||||||
|
t.Errorf("%s: got=%#v, want=%#v, equal=%v, want=%v", tc.desc, got, tc.want, equal, tc.equal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTimstamp_MarshalReflexivity(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
data Timestamp
|
||||||
|
}{
|
||||||
|
{"Reference", Timestamp{referenceTime}},
|
||||||
|
{"Empty", Timestamp{}},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
data, err := json.Marshal(tc.data)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%s: Marshal err=%v", tc.desc, err)
|
||||||
|
}
|
||||||
|
var got Timestamp
|
||||||
|
err = json.Unmarshal(data, &got)
|
||||||
|
if !got.Equal(tc.data) {
|
||||||
|
t.Errorf("%s: %+v != %+v", tc.desc, got, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type WrappedTimestamp struct {
|
||||||
|
A int
|
||||||
|
Time Timestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWrappedTimstamp_Marshal(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
data WrappedTimestamp
|
||||||
|
want string
|
||||||
|
wantErr bool
|
||||||
|
equal bool
|
||||||
|
}{
|
||||||
|
{"Reference", WrappedTimestamp{0, Timestamp{referenceTime}}, fmt.Sprintf(`{"A":0,"Time":%s}`, referenceTimeStr), false, true},
|
||||||
|
{"Empty", WrappedTimestamp{}, fmt.Sprintf(`{"A":0,"Time":%s}`, emptyTimeStr), false, true},
|
||||||
|
{"Mismatch", WrappedTimestamp{}, fmt.Sprintf(`{"A":0,"Time":%s}`, referenceTimeStr), false, false},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
out, err := json.Marshal(tc.data)
|
||||||
|
if gotErr := err != nil; gotErr != tc.wantErr {
|
||||||
|
t.Errorf("%s: gotErr=%v, wantErr=%v, err=%v", tc.desc, gotErr, tc.wantErr, err)
|
||||||
|
}
|
||||||
|
got := string(out)
|
||||||
|
equal := got == tc.want
|
||||||
|
if equal != tc.equal {
|
||||||
|
t.Errorf("%s: got=%s, want=%s, equal=%v, want=%v", tc.desc, got, tc.want, equal, tc.equal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWrappedTimstamp_Unmarshal(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
data string
|
||||||
|
want WrappedTimestamp
|
||||||
|
wantErr bool
|
||||||
|
equal bool
|
||||||
|
}{
|
||||||
|
{"Reference", referenceTimeStr, WrappedTimestamp{0, Timestamp{referenceTime}}, false, true},
|
||||||
|
{"ReferenceUnix", referenceUnixTimeStr, WrappedTimestamp{0, Timestamp{referenceTime}}, false, true},
|
||||||
|
{"Empty", emptyTimeStr, WrappedTimestamp{0, Timestamp{}}, false, true},
|
||||||
|
{"UnixStart", `0`, WrappedTimestamp{0, Timestamp{unixOrigin}}, false, true},
|
||||||
|
{"Mismatch", referenceTimeStr, WrappedTimestamp{0, Timestamp{}}, false, false},
|
||||||
|
{"MismatchUnix", `0`, WrappedTimestamp{0, Timestamp{}}, false, false},
|
||||||
|
{"Invalid", `"asdf"`, WrappedTimestamp{0, Timestamp{referenceTime}}, true, false},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
var got Timestamp
|
||||||
|
err := json.Unmarshal([]byte(tc.data), &got)
|
||||||
|
if gotErr := err != nil; gotErr != tc.wantErr {
|
||||||
|
t.Errorf("%s: gotErr=%v, wantErr=%v, err=%v", tc.desc, gotErr, tc.wantErr, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
equal := got.Time.Equal(tc.want.Time.Time)
|
||||||
|
if equal != tc.equal {
|
||||||
|
t.Errorf("%s: got=%#v, want=%#v, equal=%v, want=%v", tc.desc, got, tc.want, equal, tc.equal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWrappedTimstamp_MarshalReflexivity(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
data WrappedTimestamp
|
||||||
|
}{
|
||||||
|
{"Reference", WrappedTimestamp{0, Timestamp{referenceTime}}},
|
||||||
|
{"Empty", WrappedTimestamp{0, Timestamp{}}},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
bytes, err := json.Marshal(tc.data)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%s: Marshal err=%v", tc.desc, err)
|
||||||
|
}
|
||||||
|
var got WrappedTimestamp
|
||||||
|
err = json.Unmarshal(bytes, &got)
|
||||||
|
if !got.Time.Equal(tc.data.Time) {
|
||||||
|
t.Errorf("%s: %+v != %+v", tc.desc, got, tc.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
136
Godeps/_workspace/src/github.com/google/go-github/github/users.go
generated
vendored
Normal file
136
Godeps/_workspace/src/github.com/google/go-github/github/users.go
generated
vendored
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
// 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"
|
||||||
|
|
||||||
|
// UsersService handles communication with the user related
|
||||||
|
// methods of the GitHub API.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/users/
|
||||||
|
type UsersService struct {
|
||||||
|
client *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// User represents a GitHub user.
|
||||||
|
type User struct {
|
||||||
|
Login *string `json:"login,omitempty"`
|
||||||
|
ID *int `json:"id,omitempty"`
|
||||||
|
AvatarURL *string `json:"avatar_url,omitempty"`
|
||||||
|
HTMLURL *string `json:"html_url,omitempty"`
|
||||||
|
GravatarID *string `json:"gravatar_id,omitempty"`
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
Company *string `json:"company,omitempty"`
|
||||||
|
Blog *string `json:"blog,omitempty"`
|
||||||
|
Location *string `json:"location,omitempty"`
|
||||||
|
Email *string `json:"email,omitempty"`
|
||||||
|
Hireable *bool `json:"hireable,omitempty"`
|
||||||
|
Bio *string `json:"bio,omitempty"`
|
||||||
|
PublicRepos *int `json:"public_repos,omitempty"`
|
||||||
|
PublicGists *int `json:"public_gists,omitempty"`
|
||||||
|
Followers *int `json:"followers,omitempty"`
|
||||||
|
Following *int `json:"following,omitempty"`
|
||||||
|
CreatedAt *Timestamp `json:"created_at,omitempty"`
|
||||||
|
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
|
||||||
|
Type *string `json:"type,omitempty"`
|
||||||
|
SiteAdmin *bool `json:"site_admin,omitempty"`
|
||||||
|
TotalPrivateRepos *int `json:"total_private_repos,omitempty"`
|
||||||
|
OwnedPrivateRepos *int `json:"owned_private_repos,omitempty"`
|
||||||
|
PrivateGists *int `json:"private_gists,omitempty"`
|
||||||
|
DiskUsage *int `json:"disk_usage,omitempty"`
|
||||||
|
Collaborators *int `json:"collaborators,omitempty"`
|
||||||
|
Plan *Plan `json:"plan,omitempty"`
|
||||||
|
|
||||||
|
// API URLs
|
||||||
|
URL *string `json:"url,omitempty"`
|
||||||
|
EventsURL *string `json:"events_url,omitempty"`
|
||||||
|
FollowingURL *string `json:"following_url,omitempty"`
|
||||||
|
FollowersURL *string `json:"followers_url,omitempty"`
|
||||||
|
GistsURL *string `json:"gists_url,omitempty"`
|
||||||
|
OrganizationsURL *string `json:"organizations_url,omitempty"`
|
||||||
|
ReceivedEventsURL *string `json:"received_events_url,omitempty"`
|
||||||
|
ReposURL *string `json:"repos_url,omitempty"`
|
||||||
|
StarredURL *string `json:"starred_url,omitempty"`
|
||||||
|
SubscriptionsURL *string `json:"subscriptions_url,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u User) String() string {
|
||||||
|
return Stringify(u)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get fetches a user. Passing the empty string will fetch the authenticated
|
||||||
|
// user.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/users/#get-a-single-user
|
||||||
|
func (s *UsersService) Get(user string) (*User, *Response, error) {
|
||||||
|
var u string
|
||||||
|
if user != "" {
|
||||||
|
u = fmt.Sprintf("users/%v", user)
|
||||||
|
} else {
|
||||||
|
u = "user"
|
||||||
|
}
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
uResp := new(User)
|
||||||
|
resp, err := s.client.Do(req, uResp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return uResp, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Edit the authenticated user.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/users/#update-the-authenticated-user
|
||||||
|
func (s *UsersService) Edit(user *User) (*User, *Response, error) {
|
||||||
|
u := "user"
|
||||||
|
req, err := s.client.NewRequest("PATCH", u, user)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
uResp := new(User)
|
||||||
|
resp, err := s.client.Do(req, uResp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return uResp, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserListOptions specifies optional parameters to the UsersService.List
|
||||||
|
// method.
|
||||||
|
type UserListOptions struct {
|
||||||
|
// ID of the last user seen
|
||||||
|
Since int `url:"since,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListAll lists all GitHub users.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/users/#get-all-users
|
||||||
|
func (s *UsersService) ListAll(opt *UserListOptions) ([]User, *Response, error) {
|
||||||
|
u, err := addOptions("users", opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
users := new([]User)
|
||||||
|
resp, err := s.client.Do(req, users)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *users, resp, err
|
||||||
|
}
|
||||||
69
Godeps/_workspace/src/github.com/google/go-github/github/users_emails.go
generated
vendored
Normal file
69
Godeps/_workspace/src/github.com/google/go-github/github/users_emails.go
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
// 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
|
||||||
|
|
||||||
|
// UserEmail represents user's email address
|
||||||
|
type UserEmail struct {
|
||||||
|
Email *string `json:"email,omitempty"`
|
||||||
|
Primary *bool `json:"primary,omitempty"`
|
||||||
|
Verified *bool `json:"verified,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListEmails lists all email addresses for the authenticated user.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/users/emails/#list-email-addresses-for-a-user
|
||||||
|
func (s *UsersService) ListEmails(opt *ListOptions) ([]UserEmail, *Response, error) {
|
||||||
|
u := "user/emails"
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
emails := new([]UserEmail)
|
||||||
|
resp, err := s.client.Do(req, emails)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *emails, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddEmails adds email addresses of the authenticated user.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/users/emails/#add-email-addresses
|
||||||
|
func (s *UsersService) AddEmails(emails []string) ([]UserEmail, *Response, error) {
|
||||||
|
u := "user/emails"
|
||||||
|
req, err := s.client.NewRequest("POST", u, emails)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
e := new([]UserEmail)
|
||||||
|
resp, err := s.client.Do(req, e)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *e, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteEmails deletes email addresses from authenticated user.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/users/emails/#delete-email-addresses
|
||||||
|
func (s *UsersService) DeleteEmails(emails []string) (*Response, error) {
|
||||||
|
u := "user/emails"
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, emails)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
94
Godeps/_workspace/src/github.com/google/go-github/github/users_emails_test.go
generated
vendored
Normal file
94
Godeps/_workspace/src/github.com/google/go-github/github/users_emails_test.go
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
// 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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestUsersService_ListEmails(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/user/emails", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testFormValues(t, r, values{"page": "2"})
|
||||||
|
fmt.Fprint(w, `[{
|
||||||
|
"email": "user@example.com",
|
||||||
|
"verified": false,
|
||||||
|
"primary": true
|
||||||
|
}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
opt := &ListOptions{Page: 2}
|
||||||
|
emails, _, err := client.Users.ListEmails(opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Users.ListEmails returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []UserEmail{{Email: String("user@example.com"), Verified: Bool(false), Primary: Bool(true)}}
|
||||||
|
if !reflect.DeepEqual(emails, want) {
|
||||||
|
t.Errorf("Users.ListEmails returned %+v, want %+v", emails, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUsersService_AddEmails(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := []string{"new@example.com"}
|
||||||
|
|
||||||
|
mux.HandleFunc("/user/emails", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new([]string)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
if !reflect.DeepEqual(*v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", *v, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, `[{"email":"old@example.com"}, {"email":"new@example.com"}]`)
|
||||||
|
})
|
||||||
|
|
||||||
|
emails, _, err := client.Users.AddEmails(input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Users.AddEmails returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := []UserEmail{
|
||||||
|
{Email: String("old@example.com")},
|
||||||
|
{Email: String("new@example.com")},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(emails, want) {
|
||||||
|
t.Errorf("Users.AddEmails returned %+v, want %+v", emails, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUsersService_DeleteEmails(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
input := []string{"user@example.com"}
|
||||||
|
|
||||||
|
mux.HandleFunc("/user/emails", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new([]string)
|
||||||
|
json.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
if !reflect.DeepEqual(*v, input) {
|
||||||
|
t.Errorf("Request body = %+v, want %+v", *v, input)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Users.DeleteEmails(input)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Users.DeleteEmails returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
116
Godeps/_workspace/src/github.com/google/go-github/github/users_followers.go
generated
vendored
Normal file
116
Godeps/_workspace/src/github.com/google/go-github/github/users_followers.go
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
// 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"
|
||||||
|
|
||||||
|
// ListFollowers lists the followers for a user. Passing the empty string will
|
||||||
|
// fetch followers for the authenticated user.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/users/followers/#list-followers-of-a-user
|
||||||
|
func (s *UsersService) ListFollowers(user string, opt *ListOptions) ([]User, *Response, error) {
|
||||||
|
var u string
|
||||||
|
if user != "" {
|
||||||
|
u = fmt.Sprintf("users/%v/followers", user)
|
||||||
|
} else {
|
||||||
|
u = "user/followers"
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
users := new([]User)
|
||||||
|
resp, err := s.client.Do(req, users)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *users, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListFollowing lists the people that a user is following. Passing the empty
|
||||||
|
// string will list people the authenticated user is following.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/users/followers/#list-users-followed-by-another-user
|
||||||
|
func (s *UsersService) ListFollowing(user string, opt *ListOptions) ([]User, *Response, error) {
|
||||||
|
var u string
|
||||||
|
if user != "" {
|
||||||
|
u = fmt.Sprintf("users/%v/following", user)
|
||||||
|
} else {
|
||||||
|
u = "user/following"
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
users := new([]User)
|
||||||
|
resp, err := s.client.Do(req, users)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *users, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsFollowing checks if "user" is following "target". Passing the empty
|
||||||
|
// string for "user" will check if the authenticated user is following "target".
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/users/followers/#check-if-you-are-following-a-user
|
||||||
|
func (s *UsersService) IsFollowing(user, target string) (bool, *Response, error) {
|
||||||
|
var u string
|
||||||
|
if user != "" {
|
||||||
|
u = fmt.Sprintf("users/%v/following/%v", user, target)
|
||||||
|
} else {
|
||||||
|
u = fmt.Sprintf("user/following/%v", target)
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := s.client.Do(req, nil)
|
||||||
|
following, err := parseBoolResponse(err)
|
||||||
|
return following, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Follow will cause the authenticated user to follow the specified user.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/users/followers/#follow-a-user
|
||||||
|
func (s *UsersService) Follow(user string) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("user/following/%v", user)
|
||||||
|
req, err := s.client.NewRequest("PUT", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unfollow will cause the authenticated user to unfollow the specified user.
|
||||||
|
//
|
||||||
|
// GitHub API docs: http://developer.github.com/v3/users/followers/#unfollow-a-user
|
||||||
|
func (s *UsersService) Unfollow(user string) (*Response, error) {
|
||||||
|
u := fmt.Sprintf("user/following/%v", user)
|
||||||
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(req, nil)
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user