diff --git a/github/activity_watching.go b/github/activity_watching.go index 25f2929..3af168a 100644 --- a/github/activity_watching.go +++ b/github/activity_watching.go @@ -2,13 +2,23 @@ package github import "fmt" +// RepositorySubscription identifies a repository subscription. +type RepositorySubscription 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"` + RepositoryURL *string `json:"repository_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) ([]User, *Response, error) { - url := fmt.Sprintf("repos/%s/%s/subscribers", owner, repo) + u := fmt.Sprintf("repos/%s/%s/subscribers", owner, repo) - req, err := s.client.NewRequest("GET", url, nil) + req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err } @@ -21,3 +31,88 @@ func (s *ActivityService) ListWatchers(owner, repo string) ([]User, *Response, e return *watchers, resp, err } + +// ListWatchedRepositories 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) ListWatchedRepositories(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 RepositorySubscription is returned. +// +// GitHub API Docs: https://developer.github.com/v3/activity/watching/#get-a-repository-subscription +func (s *ActivityService) GetRepositorySubscription(owner, repo string) (*RepositorySubscription, *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(RepositorySubscription) + 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 *RepositorySubscription) (*RepositorySubscription, *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(RepositorySubscription) + 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) +} diff --git a/github/activity_watching_test.go b/github/activity_watching_test.go index 72f1b51..46a2d96 100644 --- a/github/activity_watching_test.go +++ b/github/activity_watching_test.go @@ -1,6 +1,7 @@ package github import ( + "encoding/json" "fmt" "net/http" "reflect" @@ -26,3 +27,141 @@ func TestActivityService_ListWatchers(t *testing.T) { t.Errorf("Activity.ListWatchers returned %+v, want %+v", watchers, want) } } + +func TestActivityService_ListWatchedRepositories_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.ListWatchedRepositories("") + if err != nil { + t.Errorf("Activity.ListWatchedRepositories returned error: %v", err) + } + + want := []Repository{{ID: Int(1)}} + if !reflect.DeepEqual(watched, want) { + t.Errorf("Activity.ListWatchedRepositories returned %+v, want %+v", watched, want) + } +} + +func TestActivityService_ListWatchedRepositories_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.ListWatchedRepositories("u") + if err != nil { + t.Errorf("Activity.ListWatchedRepositories returned error: %v", err) + } + + want := []Repository{{ID: Int(1)}} + if !reflect.DeepEqual(watched, want) { + t.Errorf("Activity.ListWatchedRepositories 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 := &RepositorySubscription{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 *RepositorySubscription + 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 := &RepositorySubscription{Subscribed: Bool(true)} + + mux.HandleFunc("/repos/o/r/subscription", func(w http.ResponseWriter, r *http.Request) { + v := new(RepositorySubscription) + 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 := &RepositorySubscription{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") + }) + + _, err := client.Activity.DeleteRepositorySubscription("o", "r") + if err != nil { + t.Errorf("Activity.DeleteRepositorySubscription returned error: %v", err) + } +} diff --git a/tests/integration/activity_test.go b/tests/integration/activity_test.go new file mode 100644 index 0000000..a6e0f73 --- /dev/null +++ b/tests/integration/activity_test.go @@ -0,0 +1,58 @@ +// 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 tests + +import ( + "testing" + + "github.com/google/go-github/github" +) + +func TestActivity_Watching(t *testing.T) { + if !checkAuth("TestActivity_Watching") { + return + } + + // first, check if already watching google/go-github + sub, _, err := client.Activity.GetRepositorySubscription("google", "go-github") + if err != nil { + t.Fatalf("Activity.GetRepositorySubscription returned error: %v", err) + } + if sub != nil { + t.Fatalf("Already watching google/go-github. Please manually stop watching it first.") + } + + // watch google/go-github + sub = &github.RepositorySubscription{Subscribed: github.Bool(true)} + _, _, err = client.Activity.SetRepositorySubscription("google", "go-github", sub) + if err != nil { + t.Fatalf("Activity.SetRepositorySubscription returned error: %v", err) + } + + // check again and verify watching + sub, _, err = client.Activity.GetRepositorySubscription("google", "go-github") + if err != nil { + t.Fatalf("Activity.GetRepositorySubscription returned error: %v", err) + } + if sub == nil || !*sub.Subscribed { + t.Fatalf("Not watching google/go-github after setting subscription.") + } + + // delete subscription + _, err = client.Activity.DeleteRepositorySubscription("google", "go-github") + if err != nil { + t.Fatalf("Activity.DeleteRepositorySubscription returned error: %v", err) + } + + // check again and verify not watching + sub, _, err = client.Activity.GetRepositorySubscription("google", "go-github") + if err != nil { + t.Fatalf("Activity.GetRepositorySubscription returned error: %v", err) + } + if sub != nil { + t.Fatalf("Still watching google/go-github after deleting subscription.") + } +}