Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions github/github-accessors.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 50 additions & 0 deletions github/github-accessors_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

102 changes: 102 additions & 0 deletions github/repos_autolinks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright 2021 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 (
"context"
"fmt"
)

// AutolinkOptions specifies parameters for RepositoriesService.AddAutolink method.
type AutolinkOptions struct {
KeyPrefix *string `json:"key_prefix,omitempty"`
URLTemplate *string `json:"url_template,omitempty"`
}

// Autolink represents autolinks to external resources like JIRA issues and Zendesk tickets.
type Autolink struct {
ID *int64 `json:"id,omitempty"`
KeyPrefix *string `json:"key_prefix,omitempty"`
URLTemplate *string `json:"url_template,omitempty"`
}

// ListAutolinks returns a list of autolinks configured for the given repository.
// Information about autolinks are only available to repository administrators.
//
// GitHub API docs: https://docs.github.com/en/rest/reference/repos#list-all-autolinks-of-a-repository
Comment thread
gmlewis marked this conversation as resolved.
func (s *RepositoriesService) ListAutolinks(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Autolink, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/autolinks", owner, repo)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}

req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}

var autolinks []*Autolink
resp, err := s.client.Do(ctx, req, &autolinks)
if err != nil {
return nil, resp, err
}

return autolinks, resp, nil
}

// AddAutolink creates an autolink reference for a repository.
// Users with admin access to the repository can create an autolink.
//
// GitHub API docs: https://docs.github.com/en/rest/reference/repos#create-an-autolink-reference-for-a-repository
Comment thread
gmlewis marked this conversation as resolved.
func (s *RepositoriesService) AddAutolink(ctx context.Context, owner, repo string, opts *AutolinkOptions) (*Autolink, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/autolinks", owner, repo)
req, err := s.client.NewRequest("POST", u, opts)
if err != nil {
return nil, nil, err
}

al := new(Autolink)
Comment thread
gmlewis marked this conversation as resolved.
resp, err := s.client.Do(ctx, req, al)
if err != nil {
return nil, resp, err
}
return al, resp, nil
}

// GetAutolink returns a single autolink reference by ID that was configured for the given repository.
// Information about autolinks are only available to repository administrators.
//
// GitHub API docs: https://docs.github.com/en/rest/reference/repos#get-an-autolink-reference-of-a-repository
Comment thread
gmlewis marked this conversation as resolved.
func (s *RepositoriesService) GetAutolink(ctx context.Context, owner, repo string, id int64) (*Autolink, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/autolinks/%v", owner, repo, id)

req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}

var autolink *Autolink
resp, err := s.client.Do(ctx, req, &autolink)
if err != nil {
return nil, resp, err
}

return autolink, resp, nil
}

// DeleteAutolink deletes a single autolink reference by ID that was configured for the given repository.
// Information about autolinks are only available to repository administrators.
//
// GitHub API docs: https://docs.github.com/en/rest/reference/repos#delete-an-autolink-reference-from-a-repository
Comment thread
gmlewis marked this conversation as resolved.
func (s *RepositoriesService) DeleteAutolink(ctx context.Context, owner, repo string, id int64) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/autolinks/%v", owner, repo, id)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
154 changes: 154 additions & 0 deletions github/repos_autolinks_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
// Copyright 2021 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 (
"context"
"encoding/json"
"fmt"
"net/http"
"testing"

"github.com/google/go-cmp/cmp"
)

func TestRepositoriesService_ListAutolinks(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/repos/o/r/autolinks", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"page": "2"})
fmt.Fprintf(w, `[{"id":1, "key_prefix": "TICKET-", "url_template": "https://example.com/TICKET?query=<num>"}, {"id":2, "key_prefix": "STORY-", "url_template": "https://example.com/STORY?query=<num>"}]`)
})

opt := &ListOptions{
Page: 2,
}
ctx := context.Background()
autolinks, _, err := client.Repositories.ListAutolinks(ctx, "o", "r", opt)
if err != nil {
t.Errorf("Repositories.ListAutolinks returned error: %v", err)
}

want := []*Autolink{
{ID: Int64(1), KeyPrefix: String("TICKET-"), URLTemplate: String("https://example.com/TICKET?query=<num>")},
{ID: Int64(2), KeyPrefix: String("STORY-"), URLTemplate: String("https://example.com/STORY?query=<num>")},
}

if !cmp.Equal(autolinks, want) {
t.Errorf("Repositories.ListAutolinks returned %+v, want %+v", autolinks, want)
}

const methodName = "ListAutolinks"
testBadOptions(t, methodName, func() (err error) {
_, _, err = client.Repositories.ListAutolinks(ctx, "\n", "\n", opt)
return err
})

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
got, resp, err := client.Repositories.ListAutolinks(ctx, "o", "r", opt)
if got != nil {
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
}
return resp, err
})
}

func TestRepositoriesService_AddAutolink(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

opt := &AutolinkOptions{KeyPrefix: String("TICKET-"), URLTemplate: String("https://example.com/TICKET?query=<num>")}
mux.HandleFunc("/repos/o/r/autolinks", func(w http.ResponseWriter, r *http.Request) {
v := new(AutolinkOptions)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
if !cmp.Equal(v, opt) {
t.Errorf("Request body = %+v, want %+v", v, opt)
}
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"key_prefix": "TICKET-","url_template": "https://example.com/TICKET?query=<num>"}`))
})
ctx := context.Background()
autolink, _, err := client.Repositories.AddAutolink(ctx, "o", "r", opt)
if err != nil {
t.Errorf("Repositories.AddAutolink returned error: %v", err)
}
want := &Autolink{
KeyPrefix: String("TICKET-"),
URLTemplate: String("https://example.com/TICKET?query=<num>"),
}

if !cmp.Equal(autolink, want) {
t.Errorf("AddAutolink returned %+v, want %+v", autolink, want)
}

const methodName = "AddAutolink"
testBadOptions(t, methodName, func() (err error) {
_, _, err = client.Repositories.AddAutolink(ctx, "\n", "\n", opt)
return err
})

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
got, resp, err := client.Repositories.AddAutolink(ctx, "o", "r", opt)
if got != nil {
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
}
return resp, err
})
}

func TestRepositoriesService_GetAutolink(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/repos/o/r/autolinks/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprintf(w, `{"id":1, "key_prefix": "TICKET-", "url_template": "https://example.com/TICKET?query=<num>"}`)
})

ctx := context.Background()
autolink, _, err := client.Repositories.GetAutolink(ctx, "o", "r", 1)
if err != nil {
t.Errorf("Repositories.GetAutolink returned error: %v", err)
}

want := &Autolink{ID: Int64(1), KeyPrefix: String("TICKET-"), URLTemplate: String("https://example.com/TICKET?query=<num>")}
if !cmp.Equal(autolink, want) {
t.Errorf("Repositories.GetAutolink returned %+v, want %+v", autolink, want)
}

const methodName = "GetAutolink"
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
got, resp, err := client.Repositories.GetAutolink(ctx, "o", "r", 2)
if got != nil {
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
}
return resp, err
})
}

func TestRepositoriesService_DeleteAutolink(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/repos/o/r/autolinks/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
w.WriteHeader(http.StatusNoContent)
})

ctx := context.Background()
_, err := client.Repositories.DeleteAutolink(ctx, "o", "r", 1)
if err != nil {
t.Errorf("Repositories.DeleteAutolink returned error: %v", err)
}

const methodName = "DeleteAutolink"
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
return client.Repositories.DeleteAutolink(ctx, "o", "r", 2)
})
}