Skip to content

Commit

Permalink
github.Client: Add end-to-end tests
Browse files Browse the repository at this point in the history
Adds some simple end-to-end tests for the GitHub client
to avoid breaking this with other planned changes.

This introduces a new test dependency [dnaeon/go-vcr][1],
but it's a pretty small surface area,
and go-vcr itself only depends on yaml.v3.

  [1]: https://github.com/dnaeon/go-vcr

The way the test works is pretty straightforward:

- In record mode (enabled with `go test -update`)
  actual requests are made to GitHub and recorded into testdata files.
- In replay mode (the default),
  the HTTP client only replays the previously recorded interactions,
  and rejects any new requests.
  So tests will not make actual requests to GitHub after first run.

This test exposed a small bug in GitHub client initialization:
It ignored the supplied client if a token was not provided.
This change fixes that bug as well.
  • Loading branch information
abhinav committed Jun 14, 2024
1 parent 94b4cdb commit ecb9076
Show file tree
Hide file tree
Showing 8 changed files with 868 additions and 12 deletions.
6 changes: 2 additions & 4 deletions github/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,8 @@ func New(client *http.Client, token string) *Client {
if client == nil {
client = http.DefaultClient
}
if token == "" {
client = http.DefaultClient
} else {
client = &http.Client{Transport: TokenAuthenticatedTransport(client.Transport, token)}
if token != "" {
client.Transport = TokenAuthenticatedTransport(client.Transport, token)
}
return &Client{client: client}
}
Expand Down
119 changes: 119 additions & 0 deletions github/api_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package github_test

import (
"flag"
"io"
"path/filepath"
"testing"

"github.com/alecthomas/assert/v2"
"github.com/cashapp/hermit/github"
"gopkg.in/dnaeon/go-vcr.v3/recorder"
)

var updateRecordings = flag.Bool("update", false, "update test recordings")

func TestProjectForURL(t *testing.T) {
tests := []struct {
give string
want string
}{
{"https://github.com/cashapp/hermit", "cashapp/hermit"},
{"https://github.com/cashapp/hermit/", "cashapp/hermit"},
{"https://github.com/cashapp/hermit/releases", "cashapp/hermit"},
{"https://github.com/cashapp", ""},
{"https://exmaple.com/cashapp/hermit", ""},
}

for _, tt := range tests {
t.Run(tt.give, func(t *testing.T) {
client := github.New(nil, "")
got := client.ProjectForURL(tt.give)
assert.Equal(t, tt.want, got)
})
}
}

func newVCRClient(t *testing.T) *github.Client {
t.Helper()

casetteMode := recorder.ModeReplayOnly
if *updateRecordings {
casetteMode = recorder.ModeRecordOnly
} else {
t.Cleanup(func() {
if t.Failed() {
t.Logf("Run the following command to update the test recording:")
t.Logf(" go test -run '^%s$' -update", t.Name())
}
})
}

recorder, err := recorder.NewWithOptions(&recorder.Options{
CassetteName: filepath.Join("testdata", t.Name()),
Mode: casetteMode,
})
assert.NoError(t, err)
t.Cleanup(func() {
assert.NoError(t, recorder.Stop())
})

return github.New(recorder.GetDefaultClient(), "")
}

func TestRepo(t *testing.T) {
client := newVCRClient(t)
repo, err := client.Repo("cashapp/hermit")
assert.NoError(t, err)

assert.Equal(t, "https://cashapp.github.io/hermit", repo.Homepage)
}

func TestRelease(t *testing.T) {
client := newVCRClient(t)
release, err := client.Release("cashapp/hermit", "v0.39.2")
assert.NoError(t, err)

assert.Equal(t, "v0.39.2", release.TagName)
assert.Equal(t, 6, len(release.Assets))

// The cheapest asset to download is the install.sh script.
var installSh *github.Asset
for idx, asset := range release.Assets {
if asset.Name == "install.sh" {
installSh = &release.Assets[idx]
}
}
assert.NotZero(t, installSh, "install.sh not found in assets")

t.Run("ETag", func(t *testing.T) {
etag, err := client.ETag(*installSh)
assert.NoError(t, err)
assert.NotZero(t, etag)
})

t.Run("Download", func(t *testing.T) {
res, err := client.Download(*installSh)
assert.NoError(t, err)
defer res.Body.Close()

body, err := io.ReadAll(res.Body)
assert.NoError(t, err)

assert.Contains(t, string(body), "hermit")
})
}

func TestLatestRelease(t *testing.T) {
client := newVCRClient(t)
release, err := client.LatestRelease("cashapp/hermit")
assert.NoError(t, err)
assert.NotZero(t, release.TagName)
}

func TestReleases(t *testing.T) {
client := newVCRClient(t)
releases, err := client.Releases("cashapp/hermit-build", 5)
assert.NoError(t, err)
assert.Equal(t, 5, len(releases))
}
80 changes: 80 additions & 0 deletions github/testdata/TestLatestRelease.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
version: 2
interactions:
- id: 0
request:
proto: HTTP/1.1
proto_major: 1
proto_minor: 1
content_length: 0
transfer_encoding: []
trailer: {}
host: api.github.com
remote_addr: ""
request_uri: ""
body: ""
form: {}
headers: {}
url: https://api.github.com/repos/cashapp/hermit/releases/latest
method: GET
response:
proto: HTTP/2.0
proto_major: 2
proto_minor: 0
transfer_encoding: []
trailer: {}
content_length: -1
uncompressed: true
body: '{"url":"https://api.github.com/repos/cashapp/hermit/releases/158259817","assets_url":"https://api.github.com/repos/cashapp/hermit/releases/158259817/assets","upload_url":"https://uploads.github.com/repos/cashapp/hermit/releases/158259817/assets{?name,label}","html_url":"https://github.com/cashapp/hermit/releases/tag/v0.39.2","id":158259817,"author":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","site_admin":false},"node_id":"RE_kwDOFf-izM4Jbtpp","tag_name":"v0.39.2","target_commitish":"master","name":"v0.39.2","draft":false,"prerelease":false,"created_at":"2024-05-15T21:57:56Z","published_at":"2024-05-30T23:47:36Z","assets":[{"url":"https://api.github.com/repos/cashapp/hermit/releases/assets/171036319","id":171036319,"node_id":"RA_kwDOFf-izM4KMc6f","name":"hermit-darwin-amd64.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","site_admin":false},"content_type":"raw","state":"uploaded","size":8747866,"download_count":0,"created_at":"2024-05-30T23:47:41Z","updated_at":"2024-05-30T23:47:42Z","browser_download_url":"https://github.com/cashapp/hermit/releases/download/v0.39.2/hermit-darwin-amd64.gz"},{"url":"https://api.github.com/repos/cashapp/hermit/releases/assets/171036315","id":171036315,"node_id":"RA_kwDOFf-izM4KMc6b","name":"hermit-darwin-arm64.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","site_admin":false},"content_type":"raw","state":"uploaded","size":8420135,"download_count":1,"created_at":"2024-05-30T23:47:40Z","updated_at":"2024-05-30T23:47:40Z","browser_download_url":"https://github.com/cashapp/hermit/releases/download/v0.39.2/hermit-darwin-arm64.gz"},{"url":"https://api.github.com/repos/cashapp/hermit/releases/assets/171036311","id":171036311,"node_id":"RA_kwDOFf-izM4KMc6X","name":"hermit-linux-amd64.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","site_admin":false},"content_type":"raw","state":"uploaded","size":8940242,"download_count":2,"created_at":"2024-05-30T23:47:39Z","updated_at":"2024-05-30T23:47:39Z","browser_download_url":"https://github.com/cashapp/hermit/releases/download/v0.39.2/hermit-linux-amd64.gz"},{"url":"https://api.github.com/repos/cashapp/hermit/releases/assets/171036309","id":171036309,"node_id":"RA_kwDOFf-izM4KMc6V","name":"hermit-linux-arm64.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","site_admin":false},"content_type":"raw","state":"uploaded","size":8352833,"download_count":1,"created_at":"2024-05-30T23:47:38Z","updated_at":"2024-05-30T23:47:39Z","browser_download_url":"https://github.com/cashapp/hermit/releases/download/v0.39.2/hermit-linux-arm64.gz"},{"url":"https://api.github.com/repos/cashapp/hermit/releases/assets/171036305","id":171036305,"node_id":"RA_kwDOFf-izM4KMc6R","name":"install-180e997dd837f839a3072a5e2f558619b6d12555cd5452d3ab19d87720704e38.sh","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","site_admin":false},"content_type":"raw","state":"uploaded","size":4146,"download_count":1,"created_at":"2024-05-30T23:47:38Z","updated_at":"2024-05-30T23:47:38Z","browser_download_url":"https://github.com/cashapp/hermit/releases/download/v0.39.2/install-180e997dd837f839a3072a5e2f558619b6d12555cd5452d3ab19d87720704e38.sh"},{"url":"https://api.github.com/repos/cashapp/hermit/releases/assets/171036304","id":171036304,"node_id":"RA_kwDOFf-izM4KMc6Q","name":"install.sh","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","site_admin":false},"content_type":"raw","state":"uploaded","size":4146,"download_count":2,"created_at":"2024-05-30T23:47:37Z","updated_at":"2024-05-30T23:47:37Z","browser_download_url":"https://github.com/cashapp/hermit/releases/download/v0.39.2/install.sh"}],"tarball_url":"https://api.github.com/repos/cashapp/hermit/tarball/v0.39.2","zipball_url":"https://api.github.com/repos/cashapp/hermit/zipball/v0.39.2","body":""}'
headers:
Accept-Ranges:
- bytes
Access-Control-Allow-Origin:
- '*'
Access-Control-Expose-Headers:
- ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
Cache-Control:
- public, max-age=60, s-maxage=60
Content-Security-Policy:
- default-src 'none'
Content-Type:
- application/json; charset=utf-8
Date:
- Fri, 14 Jun 2024 16:56:40 GMT
Etag:
- W/"cf15d2a02b11c4fc424541a0ddf6079bf72e130c50face38cf09b809dc13d670"
Last-Modified:
- Thu, 30 May 2024 23:47:42 GMT
Referrer-Policy:
- origin-when-cross-origin, strict-origin-when-cross-origin
Server:
- GitHub.com
Strict-Transport-Security:
- max-age=31536000; includeSubdomains; preload
Vary:
- Accept, Accept-Encoding, Accept, X-Requested-With
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- deny
X-Github-Api-Version-Selected:
- "2022-11-28"
X-Github-Media-Type:
- github.v3; format=json
X-Github-Request-Id:
- FAC8:3BA2D9:DBDC13:DD90D3:666C7647
X-Ratelimit-Limit:
- "60"
X-Ratelimit-Remaining:
- "55"
X-Ratelimit-Reset:
- "1718387797"
X-Ratelimit-Resource:
- core
X-Ratelimit-Used:
- "5"
X-Xss-Protection:
- "0"
status: 200 OK
code: 200
duration: 193.488833ms
Loading

0 comments on commit ecb9076

Please sign in to comment.