Browse Source

Add GistsService that handles GitHub's Gists API.

fixes #18
Akeda Bagus 13 years ago
committed by Will Norris
parent
commit
51442f25ff
3 changed files with 584 additions and 0 deletions
  1. +237
    -0
      github/gists.go
  2. +345
    -0
      github/gists_test.go
  3. +2
    -0
      github/github.go

+ 237
- 0
github/gists.go View File

@ -0,0 +1,237 @@
// 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"
"net/url"
"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"`
User *User `json:"user,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"`
}
// 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 GistFilename `json:"filename,omitempty"`
RawURL string `json:"raw_url,omitempty"`
Content string `json:"content,omitempty"`
}
// 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
}
// 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, error) {
var u string
if user != "" {
u = fmt.Sprintf("users/%v/gists", user)
} else {
u = "gists"
}
if opt != nil {
params := url.Values{}
if !opt.Since.IsZero() {
params.Add("since", opt.Since.Format(time.RFC3339))
}
u += "?" + params.Encode()
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, err
}
gists := new([]Gist)
_, err = s.client.Do(req, gists)
return *gists, err
}
// ListAll lists all public gists.
//
// GitHub API docs: http://developer.github.com/v3/gists/#list-gists
func (s *GistsService) ListAll(opt *GistListOptions) ([]Gist, error) {
u := "gists/public"
if opt != nil {
params := url.Values{}
if !opt.Since.IsZero() {
params.Add("since", opt.Since.Format(time.RFC3339))
}
u += "?" + params.Encode()
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, err
}
gists := new([]Gist)
_, err = s.client.Do(req, gists)
return *gists, 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, error) {
u := "gists/starred"
if opt != nil {
params := url.Values{}
if !opt.Since.IsZero() {
params.Add("since", opt.Since.Format(time.RFC3339))
}
u += "?" + params.Encode()
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, err
}
gists := new([]Gist)
_, err = s.client.Do(req, gists)
return *gists, 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, error) {
u := fmt.Sprintf("gists/%v", id)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, err
}
gist := new(Gist)
_, err = s.client.Do(req, gist)
return gist, 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, error) {
u := "gists"
req, err := s.client.NewRequest("POST", u, gist)
if err != nil {
return nil, err
}
g := new(Gist)
_, err = s.client.Do(req, g)
return g, 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, error) {
u := fmt.Sprintf("gists/%v", id)
req, err := s.client.NewRequest("PATCH", u, gist)
if err != nil {
return nil, err
}
g := new(Gist)
_, err = s.client.Do(req, g)
return g, err
}
// Delete a gist.
//
// GitHub API docs: http://developer.github.com/v3/gists/#delete-a-gist
func (s *GistsService) Delete(id string) error {
u := fmt.Sprintf("gists/%v", id)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return err
}
_, err = s.client.Do(req, nil)
return err
}
// 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) error {
u := fmt.Sprintf("gists/%v/star", id)
req, err := s.client.NewRequest("PUT", u, nil)
if err != nil {
return err
}
_, err = s.client.Do(req, nil)
return err
}
// 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) error {
u := fmt.Sprintf("gists/%v/star", id)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return err
}
_, err = s.client.Do(req, nil)
return err
}
// Starred 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) Starred(id string) (bool, error) {
u := fmt.Sprintf("gists/%v/star", id)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return false, err
}
_, err = s.client.Do(req, nil)
return parseBoolResponse(err)
}
// Fork a gist.
//
// GitHub API docs: http://developer.github.com/v3/gists/#fork-a-gist
func (s *GistsService) Fork(id string) (*Gist, error) {
u := fmt.Sprintf("gists/%v/forks", id)
req, err := s.client.NewRequest("POST", u, nil)
if err != nil {
return nil, err
}
g := new(Gist)
_, err = s.client.Do(req, g)
return g, err
}

+ 345
- 0
github/gists_test.go View File

@ -0,0 +1,345 @@
// 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(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{Gist{ID: "1"}}
if !reflect.DeepEqual(gists, want) {
t.Errorf("Gists.List returned %+v, want %+v", gists, want)
}
}
func TestGistsService_List_withEmptyUser(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{Gist{ID: "1"}}
if !reflect.DeepEqual(gists, want) {
t.Errorf("Gists.List returned %+v, want %+v", gists, want)
}
}
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{Gist{ID: "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{Gist{ID: "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: "1"}
if !reflect.DeepEqual(gist, want) {
t.Errorf("Gists.Get returned %+v, want %+v", gist, want)
}
}
func TestGistsService_Create(t *testing.T) {
setup()
defer teardown()
input := &Gist{
Description: "Gist description",
Public: false,
Files: map[GistFilename]GistFile{
"test.txt": GistFile{Content: "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: "1",
Description: "Gist description",
Public: false,
Files: map[GistFilename]GistFile{
"test.txt": GistFile{Filename: "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: "New description",
Files: map[GistFilename]GistFile{
"new.txt": GistFile{Content: "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: "1",
Description: "new description",
Public: false,
Files: map[GistFilename]GistFile{
"test.txt": GistFile{Filename: "test.txt"},
"new.txt": GistFile{Filename: "new.txt"},
},
}
if !reflect.DeepEqual(gist, want) {
t.Errorf("Gists.Edit returned %+v, want %+v", gist, want)
}
}
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_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_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_Starred_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.Starred("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_Starred_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.Starred("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_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: "2"}
if !reflect.DeepEqual(gist, want) {
t.Errorf("Gists.Fork returned %+v, want %+v", gist, want)
}
}

+ 2
- 0
github/github.go View File

@ -90,6 +90,7 @@ type Client struct {
PullRequests *PullRequestsService
Repositories *RepositoriesService
Users *UsersService
Gists *GistsService
}
// ListOptions specifies the optional parameters to various List methods that
@ -115,6 +116,7 @@ func NewClient(httpClient *http.Client) *Client {
c.PullRequests = &PullRequestsService{client: c}
c.Repositories = &RepositoriesService{client: c}
c.Users = &UsersService{client: c}
c.Gists = &GistsService{client: c}
return c
}


Loading…
Cancel
Save