From fa59486b7d19caa5ceb820424faf549205cef9ff Mon Sep 17 00:00:00 2001 From: Will Norris Date: Mon, 5 Aug 2013 16:20:58 -0700 Subject: [PATCH] add methods for issue labels --- github/issues_labels.go | 152 ++++++++++++++++++++- github/issues_labels_test.go | 252 +++++++++++++++++++++++++++++++++++ github/issues_test.go | 24 +--- 3 files changed, 403 insertions(+), 25 deletions(-) create mode 100644 github/issues_labels_test.go diff --git a/github/issues_labels.go b/github/issues_labels.go index 5fc7871..c22b115 100644 --- a/github/issues_labels.go +++ b/github/issues_labels.go @@ -5,11 +5,9 @@ package github -import +import "fmt" // Label represents a GitHib label on an Issue -"fmt" - type Label struct { URL string `json:"url,omitempty"` Name string `json:"name,omitempty"` @@ -19,3 +17,151 @@ type Label struct { func (label Label) String() string { return fmt.Sprint(label.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) ([]Label, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/labels", owner, repo) + 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) + 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) + 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) + 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) + 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) ([]Label, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number) + 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) + 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) + 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) + 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) ([]Label, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/milestones/%d/labels", owner, repo, number) + 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) + return *labels, resp, err +} diff --git a/github/issues_labels_test.go b/github/issues_labels_test.go new file mode 100644 index 0000000..f7376de --- /dev/null +++ b/github/issues_labels_test.go @@ -0,0 +1,252 @@ +// 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") + fmt.Fprint(w, `[{"name": "a"},{"name": "b"}]`) + }) + + labels, _, err := client.Issues.ListLabels("o", "r") + if err != nil { + t.Errorf("Issues.ListLabels returned error: %v", err) + } + + want := []Label{Label{Name: "a"}, Label{Name: "b"}} + if !reflect.DeepEqual(labels, want) { + t.Errorf("Issues.ListLabels returned %+v, want %+v", labels, want) + } +} + +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: "u", Name: "n", Color: "c"} + if !reflect.DeepEqual(label, want) { + t.Errorf("Issues.GetLabel returned %+v, want %+v", label, want) + } +} + +func TestIssuesService_CreateLabel(t *testing.T) { + setup() + defer teardown() + + input := &Label{Name: "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: "u"} + if !reflect.DeepEqual(label, want) { + t.Errorf("Issues.CreateLabel returned %+v, want %+v", label, want) + } +} + +func TestIssuesService_EditLabel(t *testing.T) { + setup() + defer teardown() + + input := &Label{Name: "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: "u"} + if !reflect.DeepEqual(label, want) { + t.Errorf("Issues.EditLabel returned %+v, want %+v", label, want) + } +} + +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_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") + fmt.Fprint(w, `[{"name": "a"},{"name": "b"}]`) + }) + + labels, _, err := client.Issues.ListLabelsByIssue("o", "r", 1) + if err != nil { + t.Errorf("Issues.ListLabelsByIssue returned error: %v", err) + } + + want := []Label{Label{Name: "a"}, Label{Name: "b"}} + if !reflect.DeepEqual(labels, want) { + t.Errorf("Issues.ListLabelsByIssue returned %+v, want %+v", labels, want) + } +} + +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{Label{URL: "u"}} + if !reflect.DeepEqual(labels, want) { + t.Errorf("Issues.AddLabelsToIssue returned %+v, want %+v", labels, want) + } +} + +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_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{Label{URL: "u"}} + if !reflect.DeepEqual(labels, want) { + t.Errorf("Issues.ReplaceLabelsForIssue returned %+v, want %+v", labels, want) + } +} + +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_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") + fmt.Fprint(w, `[{"name": "a"},{"name": "b"}]`) + }) + + labels, _, err := client.Issues.ListLabelsForMilestone("o", "r", 1) + if err != nil { + t.Errorf("Issues.ListLabelsForMilestone returned error: %v", err) + } + + want := []Label{Label{Name: "a"}, Label{Name: "b"}} + if !reflect.DeepEqual(labels, want) { + t.Errorf("Issues.ListLabelsForMilestone returned %+v, want %+v", labels, want) + } +} diff --git a/github/issues_test.go b/github/issues_test.go index e4490d6..dac7ad9 100644 --- a/github/issues_test.go +++ b/github/issues_test.go @@ -69,26 +69,6 @@ func TestIssuesService_List_owned(t *testing.T) { } } -func TestIssueService_List_label(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, "labels": [{"url": "https://api.github.com/repos/octocat/Hello-World/labels/bug", "name": "bug", "color": "f29513"}]}]`) - }) - - issues, _, err := client.Issues.List(false, nil) - if err != nil { - t.Errorf("Issues.List returned error: %v", err) - } - - want := []Issue{Issue{Number: 1, Labels: []Label{Label{URL: "https://api.github.com/repos/octocat/Hello-World/labels/bug", Name: "bug", Color: "f29513"}}}} - if !reflect.DeepEqual(issues, want) { - t.Errorf("Issues.List returned %+v, want %+v", issues, want) - } -} - func TestIssuesService_ListByOrg(t *testing.T) { setup() defer teardown() @@ -160,7 +140,7 @@ func TestIssuesService_Get(t *testing.T) { mux.HandleFunc("/repos/o/r/issues/1", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - fmt.Fprint(w, `{"number":1}`) + fmt.Fprint(w, `{"number":1, "labels": [{"url": "u", "name": "n", "color": "c"}]}`) }) issue, _, err := client.Issues.Get("o", "r", 1) @@ -168,7 +148,7 @@ func TestIssuesService_Get(t *testing.T) { t.Errorf("Issues.Get returned error: %v", err) } - want := &Issue{Number: 1} + want := &Issue{Number: 1, Labels: []Label{Label{URL: "u", Name: "n", Color: "c"}}} if !reflect.DeepEqual(issue, want) { t.Errorf("Issues.Get returned %+v, want %+v", issue, want) }