From 2c0768b7ecd5efbb55c37eb66dafb16cb3d8970c Mon Sep 17 00:00:00 2001 From: Will Roden Date: Thu, 21 Sep 2023 07:48:48 -0500 Subject: [PATCH] move services to separate files --- github/codesofconduct.go | 81 ++++++++ github/codesofconduct_test.go | 121 ++++++++++++ github/emojis.go | 37 ++++ github/emojis_test.go | 45 +++++ github/markdown.go | 67 +++++++ github/markdown_test.go | 80 ++++++++ github/meta.go | 146 ++++++++++++++ github/meta_test.go | 155 +++++++++++++++ github/misc.go | 300 ---------------------------- github/misc_test.go | 356 ---------------------------------- 10 files changed, 732 insertions(+), 656 deletions(-) create mode 100644 github/codesofconduct.go create mode 100644 github/codesofconduct_test.go create mode 100644 github/emojis.go create mode 100644 github/emojis_test.go create mode 100644 github/markdown.go create mode 100644 github/markdown_test.go create mode 100644 github/meta.go create mode 100644 github/meta_test.go delete mode 100644 github/misc.go delete mode 100644 github/misc_test.go diff --git a/github/codesofconduct.go b/github/codesofconduct.go new file mode 100644 index 00000000000..17a0a876ca9 --- /dev/null +++ b/github/codesofconduct.go @@ -0,0 +1,81 @@ +// Copyright 2023 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" +) + +// CodesOfConductService provides access to code-of-conduct-related functions in the GitHub API. +type CodesOfConductService service + +// CodeOfConduct represents a code of conduct. +type CodeOfConduct struct { + Name *string `json:"name,omitempty"` + Key *string `json:"key,omitempty"` + URL *string `json:"url,omitempty"` + Body *string `json:"body,omitempty"` +} + +func (c *CodeOfConduct) String() string { + return Stringify(c) +} + +// ListCodesOfConduct returns all codes of conduct. +// +// GitHub API docs: https://docs.github.com/rest/codes-of-conduct/codes-of-conduct#get-all-codes-of-conduct +func (s *CodesOfConductService) ListCodesOfConduct(ctx context.Context) ([]*CodeOfConduct, *Response, error) { + req, err := s.client.NewRequest("GET", "codes_of_conduct", nil) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeCodesOfConductPreview) + + var cs []*CodeOfConduct + resp, err := s.client.Do(ctx, req, &cs) + if err != nil { + return nil, resp, err + } + + return cs, resp, nil +} + +// ListCodesOfConduct +// Deprecated: Use CodesOfConductService.ListCodesOfConduct instead +func (c *Client) ListCodesOfConduct(ctx context.Context) ([]*CodeOfConduct, *Response, error) { + return c.CodesOfConduct.ListCodesOfConduct(ctx) +} + +// GetCodeOfConduct returns an individual code of conduct. +// +// GitHub API docs: https://docs.github.com/rest/codes-of-conduct/codes-of-conduct#get-a-code-of-conduct +func (s *CodesOfConductService) GetCodeOfConduct(ctx context.Context, key string) (*CodeOfConduct, *Response, error) { + u := fmt.Sprintf("codes_of_conduct/%s", key) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeCodesOfConductPreview) + + coc := new(CodeOfConduct) + resp, err := s.client.Do(ctx, req, coc) + if err != nil { + return nil, resp, err + } + + return coc, resp, nil +} + +// GetCodeOfConduct +// Deprecated: Use CodesOfConductService.GetCodeOfConduct instead +func (c *Client) GetCodeOfConduct(ctx context.Context, key string) (*CodeOfConduct, *Response, error) { + return c.CodesOfConduct.GetCodeOfConduct(ctx, key) +} diff --git a/github/codesofconduct_test.go b/github/codesofconduct_test.go new file mode 100644 index 00000000000..01ccefc2643 --- /dev/null +++ b/github/codesofconduct_test.go @@ -0,0 +1,121 @@ +// Copyright 2023 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" + "net/http" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestCodesOfConductService_ListCodesOfConduct(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/codes_of_conduct", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeCodesOfConductPreview) + fmt.Fprint(w, `[{ + "key": "key", + "name": "name", + "url": "url"} + ]`) + }) + + ctx := context.Background() + cs, _, err := client.ListCodesOfConduct(ctx) + if err != nil { + t.Errorf("ListCodesOfConduct returned error: %v", err) + } + + want := []*CodeOfConduct{ + { + Key: String("key"), + Name: String("name"), + URL: String("url"), + }} + if !cmp.Equal(want, cs) { + t.Errorf("ListCodesOfConduct returned %+v, want %+v", cs, want) + } + + const methodName = "ListCodesOfConduct" + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.ListCodesOfConduct(ctx) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestCodesOfConductService_GetCodeOfConduct(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/codes_of_conduct/k", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeCodesOfConductPreview) + fmt.Fprint(w, `{ + "key": "key", + "name": "name", + "url": "url", + "body": "body"}`, + ) + }) + + ctx := context.Background() + coc, _, err := client.GetCodeOfConduct(ctx, "k") + if err != nil { + t.Errorf("ListCodesOfConduct returned error: %v", err) + } + + want := &CodeOfConduct{ + Key: String("key"), + Name: String("name"), + URL: String("url"), + Body: String("body"), + } + if !cmp.Equal(want, coc) { + t.Errorf("GetCodeOfConductByKey returned %+v, want %+v", coc, want) + } + + const methodName = "GetCodeOfConduct" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.GetCodeOfConduct(ctx, "\n") + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.GetCodeOfConduct(ctx, "k") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestCodeOfConduct_Marshal(t *testing.T) { + testJSONMarshal(t, &CodeOfConduct{}, "{}") + + a := &CodeOfConduct{ + Name: String("name"), + Key: String("key"), + URL: String("url"), + Body: String("body"), + } + + want := `{ + "name": "name", + "key": "key", + "url": "url", + "body": "body" + }` + + testJSONMarshal(t, a, want) +} diff --git a/github/emojis.go b/github/emojis.go new file mode 100644 index 00000000000..b51f46c9b5a --- /dev/null +++ b/github/emojis.go @@ -0,0 +1,37 @@ +// Copyright 2023 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" +) + +// EmojisService provides access to emoji-related functions in the GitHub API. +type EmojisService service + +// ListEmojis returns the emojis available to use on GitHub. +// +// GitHub API docs: https://docs.github.com/rest/emojis/emojis#get-emojis +func (s *EmojisService) ListEmojis(ctx context.Context) (map[string]string, *Response, error) { + req, err := s.client.NewRequest("GET", "emojis", nil) + if err != nil { + return nil, nil, err + } + + var emoji map[string]string + resp, err := s.client.Do(ctx, req, &emoji) + if err != nil { + return nil, resp, err + } + + return emoji, resp, nil +} + +// ListEmojis +// Deprecated: Use EmojisService.ListEmojis instead +func (c *Client) ListEmojis(ctx context.Context) (map[string]string, *Response, error) { + return c.Emojis.ListEmojis(ctx) +} diff --git a/github/emojis_test.go b/github/emojis_test.go new file mode 100644 index 00000000000..d0d811b5c53 --- /dev/null +++ b/github/emojis_test.go @@ -0,0 +1,45 @@ +// Copyright 2023 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" + "net/http" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestEmojisService_ListEmojis(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/emojis", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"+1": "+1.png"}`) + }) + + ctx := context.Background() + emoji, _, err := client.ListEmojis(ctx) + if err != nil { + t.Errorf("ListEmojis returned error: %v", err) + } + + want := map[string]string{"+1": "+1.png"} + if !cmp.Equal(want, emoji) { + t.Errorf("ListEmojis returned %+v, want %+v", emoji, want) + } + + const methodName = "ListEmojis" + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.ListEmojis(ctx) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} diff --git a/github/markdown.go b/github/markdown.go new file mode 100644 index 00000000000..871b1a77624 --- /dev/null +++ b/github/markdown.go @@ -0,0 +1,67 @@ +// Copyright 2023 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" + "context" +) + +// MarkdownService provides access to markdown-related functions in the GitHub API. +type MarkdownService service + +// 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://docs.github.com/rest/markdown/markdown#render-a-markdown-document +func (s *MarkdownService) Markdown(ctx context.Context, text string, opts *MarkdownOptions) (string, *Response, error) { + request := &markdownRequest{Text: String(text)} + if opts != nil { + if opts.Mode != "" { + request.Mode = String(opts.Mode) + } + if opts.Context != "" { + request.Context = String(opts.Context) + } + } + + req, err := s.client.NewRequest("POST", "markdown", request) + if err != nil { + return "", nil, err + } + + buf := new(bytes.Buffer) + resp, err := s.client.Do(ctx, req, buf) + if err != nil { + return "", resp, err + } + + return buf.String(), resp, nil +} diff --git a/github/markdown_test.go b/github/markdown_test.go new file mode 100644 index 00000000000..3bbf9fb7357 --- /dev/null +++ b/github/markdown_test.go @@ -0,0 +1,80 @@ +// Copyright 2023 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 TestMarkdownService_Markdown(t *testing.T) { + client, mux, _, teardown := 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) + assertNilError(t, json.NewDecoder(r.Body).Decode(v)) + + testMethod(t, r, "POST") + if !cmp.Equal(v, input) { + t.Errorf("Request body = %+v, want %+v", v, input) + } + fmt.Fprint(w, `

text

`) + }) + + ctx := context.Background() + md, _, err := client.Markdown.Markdown(ctx, "# text #", &MarkdownOptions{ + Mode: "gfm", + Context: "google/go-github", + }) + if err != nil { + t.Errorf("Markdown returned error: %v", err) + } + + if want := "

text

"; want != md { + t.Errorf("Markdown returned %+v, want %+v", md, want) + } + + const methodName = "Markdown" + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Markdown.Markdown(ctx, "# text #", &MarkdownOptions{ + Mode: "gfm", + Context: "google/go-github", + }) + if got != "" { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestMarkdownRequest_Marshal(t *testing.T) { + testJSONMarshal(t, &markdownRequest{}, "{}") + + a := &markdownRequest{ + Text: String("txt"), + Mode: String("mode"), + Context: String("ctx"), + } + + want := `{ + "text": "txt", + "mode": "mode", + "context": "ctx" + }` + + testJSONMarshal(t, a, want) +} diff --git a/github/meta.go b/github/meta.go new file mode 100644 index 00000000000..138febaedd1 --- /dev/null +++ b/github/meta.go @@ -0,0 +1,146 @@ +// 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" + "context" + "fmt" + "net/url" +) + +// MetaService provides access to functions in the GitHub API that GitHub categorizes as "meta". +type MetaService service + +// 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"` + + // An array of IP addresses in CIDR format specifying the addresses + // which serve GitHub Pages websites. + Pages []string `json:"pages,omitempty"` + + // An Array of IP addresses specifying the addresses that source imports + // will originate from on GitHub.com. + Importer []string `json:"importer,omitempty"` + + // An array of IP addresses in CIDR format specifying the IP addresses + // GitHub Actions will originate from. + Actions []string `json:"actions,omitempty"` + + // An array of IP addresses in CIDR format specifying the IP addresses + // Dependabot will originate from. + Dependabot []string `json:"dependabot,omitempty"` + + // A map of algorithms to SSH key fingerprints. + SSHKeyFingerprints map[string]string `json:"ssh_key_fingerprints,omitempty"` + + // An array of SSH keys. + SSHKeys []string `json:"ssh_keys,omitempty"` + + // An array of IP addresses in CIDR format specifying the addresses + // which serve GitHub websites. + Web []string `json:"web,omitempty"` + + // An array of IP addresses in CIDR format specifying the addresses + // which serve GitHub APIs. + API []string `json:"api,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://docs.github.com/rest/meta/meta#get-github-meta-information +func (s *MetaService) APIMeta(ctx context.Context) (*APIMeta, *Response, error) { + req, err := s.client.NewRequest("GET", "meta", nil) + if err != nil { + return nil, nil, err + } + + meta := new(APIMeta) + resp, err := s.client.Do(ctx, req, meta) + if err != nil { + return nil, resp, err + } + + return meta, resp, nil +} + +// APIMeta +// Deprecated: Use MetaService.APIMeta instead. +func (c *Client) APIMeta(ctx context.Context) (*APIMeta, *Response, error) { + return c.Meta.APIMeta(ctx) +} + +// Octocat returns an ASCII art octocat with the specified message in a speech +// bubble. If message is empty, a random zen phrase is used. +// +// GitHub API docs: https://docs.github.com/rest/meta/meta#get-octocat +func (s *MetaService) Octocat(ctx context.Context, message string) (string, *Response, error) { + u := "octocat" + if message != "" { + u = fmt.Sprintf("%s?s=%s", u, url.QueryEscape(message)) + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return "", nil, err + } + + buf := new(bytes.Buffer) + resp, err := s.client.Do(ctx, req, buf) + if err != nil { + return "", resp, err + } + + return buf.String(), resp, nil +} + +// Octocat +// Deprecated: Use MetaService.Octocat instead. +func (c *Client) Octocat(ctx context.Context, message string) (string, *Response, error) { + return c.Meta.Octocat(ctx, message) +} + +// Zen returns a random line from The Zen of GitHub. +// +// see also: http://warpspire.com/posts/taste/ +// +// GitHub API docs: https://docs.github.com/rest/meta/meta#get-the-zen-of-github +func (s *MetaService) Zen(ctx context.Context) (string, *Response, error) { + req, err := s.client.NewRequest("GET", "zen", nil) + if err != nil { + return "", nil, err + } + + buf := new(bytes.Buffer) + resp, err := s.client.Do(ctx, req, buf) + if err != nil { + return "", resp, err + } + + return buf.String(), resp, nil +} + +// Zen +// Deprecated: Use MetaService.Zen instead. +func (c *Client) Zen(ctx context.Context) (string, *Response, error) { + return c.Meta.Zen(ctx) +} diff --git a/github/meta_test.go b/github/meta_test.go new file mode 100644 index 00000000000..1df6d858f4c --- /dev/null +++ b/github/meta_test.go @@ -0,0 +1,155 @@ +// 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 ( + "context" + "fmt" + "net/http" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestAPIMeta_Marshal(t *testing.T) { + testJSONMarshal(t, &APIMeta{}, "{}") + + a := &APIMeta{ + Hooks: []string{"h"}, + Git: []string{"g"}, + VerifiablePasswordAuthentication: Bool(true), + Pages: []string{"p"}, + Importer: []string{"i"}, + Actions: []string{"a"}, + Dependabot: []string{"d"}, + SSHKeyFingerprints: map[string]string{"a": "f"}, + SSHKeys: []string{"k"}, + API: []string{"a"}, + Web: []string{"w"}, + } + want := `{ + "hooks":["h"], + "git":["g"], + "verifiable_password_authentication":true, + "pages":["p"], + "importer":["i"], + "actions":["a"], + "dependabot":["d"], + "ssh_key_fingerprints":{"a":"f"}, + "ssh_keys":["k"], + "api":["a"], + "web":["w"] + }` + + testJSONMarshal(t, a, want) +} + +func TestMetaService_APIMeta(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/meta", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"web":["w"],"api":["a"],"hooks":["h"], "git":["g"], "pages":["p"], "importer":["i"], "actions":["a"], "dependabot":["d"], "verifiable_password_authentication": true}`) + }) + + ctx := context.Background() + meta, _, err := client.APIMeta(ctx) + if err != nil { + t.Errorf("APIMeta returned error: %v", err) + } + + want := &APIMeta{ + Hooks: []string{"h"}, + Git: []string{"g"}, + Pages: []string{"p"}, + Importer: []string{"i"}, + Actions: []string{"a"}, + Dependabot: []string{"d"}, + API: []string{"a"}, + Web: []string{"w"}, + + VerifiablePasswordAuthentication: Bool(true), + } + if !cmp.Equal(want, meta) { + t.Errorf("APIMeta returned %+v, want %+v", meta, want) + } + + const methodName = "APIMeta" + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.APIMeta(ctx) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestMetaService_Octocat(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + input := "input" + output := "sample text" + + mux.HandleFunc("/octocat", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"s": input}) + w.Header().Set("Content-Type", "application/octocat-stream") + fmt.Fprint(w, output) + }) + + ctx := context.Background() + got, _, err := client.Octocat(ctx, input) + if err != nil { + t.Errorf("Octocat returned error: %v", err) + } + + if want := output; got != want { + t.Errorf("Octocat returned %+v, want %+v", got, want) + } + + const methodName = "Octocat" + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Octocat(ctx, input) + if got != "" { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestMetaService_Zen(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + output := "sample text" + + mux.HandleFunc("/zen", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + w.Header().Set("Content-Type", "text/plain;charset=utf-8") + fmt.Fprint(w, output) + }) + + ctx := context.Background() + got, _, err := client.Zen(ctx) + if err != nil { + t.Errorf("Zen returned error: %v", err) + } + + if want := output; got != want { + t.Errorf("Zen returned %+v, want %+v", got, want) + } + + const methodName = "Zen" + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Zen(ctx) + if got != "" { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} diff --git a/github/misc.go b/github/misc.go deleted file mode 100644 index 91b24780d44..00000000000 --- a/github/misc.go +++ /dev/null @@ -1,300 +0,0 @@ -// 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" - "context" - "fmt" - "net/url" -) - -// 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"` -} - -// MarkdownService provides access to markdown-related functions in the GitHub API. -type MarkdownService service - -// Markdown renders an arbitrary Markdown document. -// -// GitHub API docs: https://docs.github.com/rest/markdown/markdown#render-a-markdown-document -func (s *MarkdownService) Markdown(ctx context.Context, text string, opts *MarkdownOptions) (string, *Response, error) { - request := &markdownRequest{Text: String(text)} - if opts != nil { - if opts.Mode != "" { - request.Mode = String(opts.Mode) - } - if opts.Context != "" { - request.Context = String(opts.Context) - } - } - - req, err := s.client.NewRequest("POST", "markdown", request) - if err != nil { - return "", nil, err - } - - buf := new(bytes.Buffer) - resp, err := s.client.Do(ctx, req, buf) - if err != nil { - return "", resp, err - } - - return buf.String(), resp, nil -} - -// EmojisService provides access to emoji-related functions in the GitHub API. -type EmojisService service - -// ListEmojis returns the emojis available to use on GitHub. -// -// GitHub API docs: https://docs.github.com/rest/emojis/emojis#get-emojis -func (s *EmojisService) ListEmojis(ctx context.Context) (map[string]string, *Response, error) { - req, err := s.client.NewRequest("GET", "emojis", nil) - if err != nil { - return nil, nil, err - } - - var emoji map[string]string - resp, err := s.client.Do(ctx, req, &emoji) - if err != nil { - return nil, resp, err - } - - return emoji, resp, nil -} - -// ListEmojis returns the emojis available to use on GitHub. -// -// Deprecated: Use EmojisService.ListEmojis instead -func (c *Client) ListEmojis(ctx context.Context) (map[string]string, *Response, error) { - return c.Emojis.ListEmojis(ctx) -} - -// CodeOfConduct represents a code of conduct. -type CodeOfConduct struct { - Name *string `json:"name,omitempty"` - Key *string `json:"key,omitempty"` - URL *string `json:"url,omitempty"` - Body *string `json:"body,omitempty"` -} - -func (c *CodeOfConduct) String() string { - return Stringify(c) -} - -// CodesOfConductService provides access to code-of-conduct-related functions in the GitHub API. -type CodesOfConductService service - -// ListCodesOfConduct returns all codes of conduct. -// -// GitHub API docs: https://docs.github.com/rest/codes-of-conduct/codes-of-conduct#get-all-codes-of-conduct -func (s *CodesOfConductService) ListCodesOfConduct(ctx context.Context) ([]*CodeOfConduct, *Response, error) { - req, err := s.client.NewRequest("GET", "codes_of_conduct", nil) - if err != nil { - return nil, nil, err - } - - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeCodesOfConductPreview) - - var cs []*CodeOfConduct - resp, err := s.client.Do(ctx, req, &cs) - if err != nil { - return nil, resp, err - } - - return cs, resp, nil -} - -// ListCodesOfConduct -// Deprecated: Use CodesOfConductService.ListCodesOfConduct instead -func (c *Client) ListCodesOfConduct(ctx context.Context) ([]*CodeOfConduct, *Response, error) { - return c.CodesOfConduct.ListCodesOfConduct(ctx) -} - -// GetCodeOfConduct returns an individual code of conduct. -// -// GitHub API docs: https://docs.github.com/rest/codes-of-conduct/codes-of-conduct#get-a-code-of-conduct -func (s *CodesOfConductService) GetCodeOfConduct(ctx context.Context, key string) (*CodeOfConduct, *Response, error) { - u := fmt.Sprintf("codes_of_conduct/%s", key) - req, err := s.client.NewRequest("GET", u, nil) - if err != nil { - return nil, nil, err - } - - // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeCodesOfConductPreview) - - coc := new(CodeOfConduct) - resp, err := s.client.Do(ctx, req, coc) - if err != nil { - return nil, resp, err - } - - return coc, resp, nil -} - -// GetCodeOfConduct -// Deprecated: Use CodesOfConductService.GetCodeOfConduct instead -func (c *Client) GetCodeOfConduct(ctx context.Context, key string) (*CodeOfConduct, *Response, error) { - return c.CodesOfConduct.GetCodeOfConduct(ctx, key) -} - -// MetaService provides access to functions in the GitHub API that GitHub categorizes as "meta". -type MetaService service - -// 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"` - - // An array of IP addresses in CIDR format specifying the addresses - // which serve GitHub Pages websites. - Pages []string `json:"pages,omitempty"` - - // An Array of IP addresses specifying the addresses that source imports - // will originate from on GitHub.com. - Importer []string `json:"importer,omitempty"` - - // An array of IP addresses in CIDR format specifying the IP addresses - // GitHub Actions will originate from. - Actions []string `json:"actions,omitempty"` - - // An array of IP addresses in CIDR format specifying the IP addresses - // Dependabot will originate from. - Dependabot []string `json:"dependabot,omitempty"` - - // A map of algorithms to SSH key fingerprints. - SSHKeyFingerprints map[string]string `json:"ssh_key_fingerprints,omitempty"` - - // An array of SSH keys. - SSHKeys []string `json:"ssh_keys,omitempty"` - - // An array of IP addresses in CIDR format specifying the addresses - // which serve GitHub websites. - Web []string `json:"web,omitempty"` - - // An array of IP addresses in CIDR format specifying the addresses - // which serve GitHub APIs. - API []string `json:"api,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://docs.github.com/rest/meta/meta#get-github-meta-information -func (s *MetaService) APIMeta(ctx context.Context) (*APIMeta, *Response, error) { - req, err := s.client.NewRequest("GET", "meta", nil) - if err != nil { - return nil, nil, err - } - - meta := new(APIMeta) - resp, err := s.client.Do(ctx, req, meta) - if err != nil { - return nil, resp, err - } - - return meta, resp, nil -} - -// APIMeta -// Deprecated: Use MetaService.APIMeta instead. -func (c *Client) APIMeta(ctx context.Context) (*APIMeta, *Response, error) { - return c.Meta.APIMeta(ctx) -} - -// Octocat returns an ASCII art octocat with the specified message in a speech -// bubble. If message is empty, a random zen phrase is used. -// -// GitHub API docs: https://docs.github.com/rest/meta/meta#get-octocat -func (s *MetaService) Octocat(ctx context.Context, message string) (string, *Response, error) { - u := "octocat" - if message != "" { - u = fmt.Sprintf("%s?s=%s", u, url.QueryEscape(message)) - } - - req, err := s.client.NewRequest("GET", u, nil) - if err != nil { - return "", nil, err - } - - buf := new(bytes.Buffer) - resp, err := s.client.Do(ctx, req, buf) - if err != nil { - return "", resp, err - } - - return buf.String(), resp, nil -} - -// Octocat -// Deprecated: Use MetaService.Octocat instead. -func (c *Client) Octocat(ctx context.Context, message string) (string, *Response, error) { - return c.Meta.Octocat(ctx, message) -} - -// Zen returns a random line from The Zen of GitHub. -// -// see also: http://warpspire.com/posts/taste/ -// -// GitHub API docs: https://docs.github.com/rest/meta/meta#get-the-zen-of-github -func (s *MetaService) Zen(ctx context.Context) (string, *Response, error) { - req, err := s.client.NewRequest("GET", "zen", nil) - if err != nil { - return "", nil, err - } - - buf := new(bytes.Buffer) - resp, err := s.client.Do(ctx, req, buf) - if err != nil { - return "", resp, err - } - - return buf.String(), resp, nil -} - -// Zen -// Deprecated: Use MetaService.Zen instead. -func (c *Client) Zen(ctx context.Context) (string, *Response, error) { - return c.Meta.Zen(ctx) -} diff --git a/github/misc_test.go b/github/misc_test.go deleted file mode 100644 index 71fd69915cc..00000000000 --- a/github/misc_test.go +++ /dev/null @@ -1,356 +0,0 @@ -// 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 ( - "context" - "encoding/json" - "fmt" - "net/http" - "testing" - - "github.com/google/go-cmp/cmp" -) - -func TestMarkdownService_Markdown(t *testing.T) { - client, mux, _, teardown := 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) - assertNilError(t, json.NewDecoder(r.Body).Decode(v)) - - testMethod(t, r, "POST") - if !cmp.Equal(v, input) { - t.Errorf("Request body = %+v, want %+v", v, input) - } - fmt.Fprint(w, `

text

`) - }) - - ctx := context.Background() - md, _, err := client.Markdown.Markdown(ctx, "# text #", &MarkdownOptions{ - Mode: "gfm", - Context: "google/go-github", - }) - if err != nil { - t.Errorf("Markdown returned error: %v", err) - } - - if want := "

text

"; want != md { - t.Errorf("Markdown returned %+v, want %+v", md, want) - } - - const methodName = "Markdown" - testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Markdown.Markdown(ctx, "# text #", &MarkdownOptions{ - Mode: "gfm", - Context: "google/go-github", - }) - if got != "" { - t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) - } - return resp, err - }) -} - -func TestEmojisService_ListEmojis(t *testing.T) { - client, mux, _, teardown := setup() - defer teardown() - - mux.HandleFunc("/emojis", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, `{"+1": "+1.png"}`) - }) - - ctx := context.Background() - emoji, _, err := client.ListEmojis(ctx) - if err != nil { - t.Errorf("ListEmojis returned error: %v", err) - } - - want := map[string]string{"+1": "+1.png"} - if !cmp.Equal(want, emoji) { - t.Errorf("ListEmojis returned %+v, want %+v", emoji, want) - } - - const methodName = "ListEmojis" - testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.ListEmojis(ctx) - if got != nil { - t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) - } - return resp, err - }) -} - -func TestCodesOfConductService_ListCodesOfConduct(t *testing.T) { - client, mux, _, teardown := setup() - defer teardown() - - mux.HandleFunc("/codes_of_conduct", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeCodesOfConductPreview) - fmt.Fprint(w, `[{ - "key": "key", - "name": "name", - "url": "url"} - ]`) - }) - - ctx := context.Background() - cs, _, err := client.ListCodesOfConduct(ctx) - if err != nil { - t.Errorf("ListCodesOfConduct returned error: %v", err) - } - - want := []*CodeOfConduct{ - { - Key: String("key"), - Name: String("name"), - URL: String("url"), - }} - if !cmp.Equal(want, cs) { - t.Errorf("ListCodesOfConduct returned %+v, want %+v", cs, want) - } - - const methodName = "ListCodesOfConduct" - testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.ListCodesOfConduct(ctx) - if got != nil { - t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) - } - return resp, err - }) -} - -func TestCodesOfConductService_GetCodeOfConduct(t *testing.T) { - client, mux, _, teardown := setup() - defer teardown() - - mux.HandleFunc("/codes_of_conduct/k", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - testHeader(t, r, "Accept", mediaTypeCodesOfConductPreview) - fmt.Fprint(w, `{ - "key": "key", - "name": "name", - "url": "url", - "body": "body"}`, - ) - }) - - ctx := context.Background() - coc, _, err := client.GetCodeOfConduct(ctx, "k") - if err != nil { - t.Errorf("ListCodesOfConduct returned error: %v", err) - } - - want := &CodeOfConduct{ - Key: String("key"), - Name: String("name"), - URL: String("url"), - Body: String("body"), - } - if !cmp.Equal(want, coc) { - t.Errorf("GetCodeOfConductByKey returned %+v, want %+v", coc, want) - } - - const methodName = "GetCodeOfConduct" - testBadOptions(t, methodName, func() (err error) { - _, _, err = client.GetCodeOfConduct(ctx, "\n") - return err - }) - - testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.GetCodeOfConduct(ctx, "k") - if got != nil { - t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) - } - return resp, err - }) -} - -func TestAPIMeta_Marshal(t *testing.T) { - testJSONMarshal(t, &APIMeta{}, "{}") - - a := &APIMeta{ - Hooks: []string{"h"}, - Git: []string{"g"}, - VerifiablePasswordAuthentication: Bool(true), - Pages: []string{"p"}, - Importer: []string{"i"}, - Actions: []string{"a"}, - Dependabot: []string{"d"}, - SSHKeyFingerprints: map[string]string{"a": "f"}, - SSHKeys: []string{"k"}, - API: []string{"a"}, - Web: []string{"w"}, - } - want := `{ - "hooks":["h"], - "git":["g"], - "verifiable_password_authentication":true, - "pages":["p"], - "importer":["i"], - "actions":["a"], - "dependabot":["d"], - "ssh_key_fingerprints":{"a":"f"}, - "ssh_keys":["k"], - "api":["a"], - "web":["w"] - }` - - testJSONMarshal(t, a, want) -} - -func TestMetaService_APIMeta(t *testing.T) { - client, mux, _, teardown := setup() - defer teardown() - - mux.HandleFunc("/meta", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - fmt.Fprint(w, `{"web":["w"],"api":["a"],"hooks":["h"], "git":["g"], "pages":["p"], "importer":["i"], "actions":["a"], "dependabot":["d"], "verifiable_password_authentication": true}`) - }) - - ctx := context.Background() - meta, _, err := client.APIMeta(ctx) - if err != nil { - t.Errorf("APIMeta returned error: %v", err) - } - - want := &APIMeta{ - Hooks: []string{"h"}, - Git: []string{"g"}, - Pages: []string{"p"}, - Importer: []string{"i"}, - Actions: []string{"a"}, - Dependabot: []string{"d"}, - API: []string{"a"}, - Web: []string{"w"}, - - VerifiablePasswordAuthentication: Bool(true), - } - if !cmp.Equal(want, meta) { - t.Errorf("APIMeta returned %+v, want %+v", meta, want) - } - - const methodName = "APIMeta" - testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.APIMeta(ctx) - if got != nil { - t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) - } - return resp, err - }) -} - -func TestMetaService_Octocat(t *testing.T) { - client, mux, _, teardown := setup() - defer teardown() - - input := "input" - output := "sample text" - - mux.HandleFunc("/octocat", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - testFormValues(t, r, values{"s": input}) - w.Header().Set("Content-Type", "application/octocat-stream") - fmt.Fprint(w, output) - }) - - ctx := context.Background() - got, _, err := client.Octocat(ctx, input) - if err != nil { - t.Errorf("Octocat returned error: %v", err) - } - - if want := output; got != want { - t.Errorf("Octocat returned %+v, want %+v", got, want) - } - - const methodName = "Octocat" - testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Octocat(ctx, input) - if got != "" { - t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) - } - return resp, err - }) -} - -func TestMetaService_Zen(t *testing.T) { - client, mux, _, teardown := setup() - defer teardown() - - output := "sample text" - - mux.HandleFunc("/zen", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") - w.Header().Set("Content-Type", "text/plain;charset=utf-8") - fmt.Fprint(w, output) - }) - - ctx := context.Background() - got, _, err := client.Zen(ctx) - if err != nil { - t.Errorf("Zen returned error: %v", err) - } - - if want := output; got != want { - t.Errorf("Zen returned %+v, want %+v", got, want) - } - - const methodName = "Zen" - testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Zen(ctx) - if got != "" { - t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) - } - return resp, err - }) -} - -func TestMarkdownRequest_Marshal(t *testing.T) { - testJSONMarshal(t, &markdownRequest{}, "{}") - - a := &markdownRequest{ - Text: String("txt"), - Mode: String("mode"), - Context: String("ctx"), - } - - want := `{ - "text": "txt", - "mode": "mode", - "context": "ctx" - }` - - testJSONMarshal(t, a, want) -} - -func TestCodeOfConduct_Marshal(t *testing.T) { - testJSONMarshal(t, &CodeOfConduct{}, "{}") - - a := &CodeOfConduct{ - Name: String("name"), - Key: String("key"), - URL: String("url"), - Body: String("body"), - } - - want := `{ - "name": "name", - "key": "key", - "url": "url", - "body": "body" - }` - - testJSONMarshal(t, a, want) -}