Search code examples
unit-testinggotestinggithub-graphqlgraphql-go

How to use go-vcr with githubv4 ? - getting httpClient Transport


Looking at the set up for go-vcr

// Start our recorder
    r, err := recorder.New("fixtures/etcd")
    if err != nil {
        log.Fatal(err)
    }
    defer r.Stop() // Make sure recorder is stopped once done with it

    // Create an etcd configuration using our transport
    cfg := client.Config{
        Endpoints:               []string{"http://127.0.0.1:2379"},
        HeaderTimeoutPerRequest: time.Second,
        Transport:               r, // Inject as transport!
    }

Attempting to use this library using the githubv4 library seems at though it needs a way to handle Oauth

import "golang.org/x/oauth2"

func main() {
    src := oauth2.StaticTokenSource(
        &oauth2.Token{AccessToken: os.Getenv("GITHUB_TOKEN")},
    )
    httpClient := oauth2.NewClient(context.Background(), src)

    client := githubv4.NewClient(httpClient)
    // Use client...
}

I'm not sure how to get the recorder 'r' into the oauth2 client. If at all possible.

Has anyone been successful with this? I've tried passing in a httpClient with the 'r' recorder but it ends up as a 401 - looks like this default client can't do the Oauth dance.

I'd like to use the GraphQL API but can fall back to the REST API if is is easier but I just want to make sure this isn't really possible. Has anyone else been successful with this?


Solution

  • This issue resolved this question for me. https://github.com/dnaeon/go-vcr/issues/59

    Example below

    package example_test
    
    import (
        "context"
        "github.com/dnaeon/go-vcr/cassette"
        "github.com/dnaeon/go-vcr/recorder"
        "github.com/google/go-github/v33/github"
        "github.com/stretchr/testify/require"
        "golang.org/x/oauth2"
        "net/http"
        "path"
        "testing"
    )
    
    func TestGithub(t *testing.T) {
        //custom http.Transport, since github uses oauth2 authentication
        ts := oauth2.StaticTokenSource(
            &oauth2.Token{AccessToken: "YOUR_GITHUB_TOKEN"},
        )
    
        tr := &oauth2.Transport{
            Base:  http.DefaultTransport,
            Source: oauth2.ReuseTokenSource(nil, ts),
        }
    
        // Start our recorder
        vcrRecorder, err := recorder.NewAsMode(path.Join("testdata", "fixtures", t.Name()), recorder.ModeRecording, tr)
        require.NoError(t, err)
            defer vcrRecorder.Stop() // NEWLY ADDED CODE HERE
    
    
        // Filter out dynamic & sensitive data/headers
        // Your test code will continue to see the real access token and
        // it is redacted before the recorded interactions are saved
            // =====> commenting out this section has no impact on missing recording
        vcrRecorder.AddSaveFilter(func(i *cassette.Interaction) error {
            delete(i.Request.Headers, "Authorization")
            delete(i.Request.Headers, "User-Agent")
            i.Request.Headers["Authorization"] = []string{"Basic UExBQ0VIT0xERVI6UExBQ0VIT0xERVI="} //PLACEHOLDER:PLACEHOLDER
    
            return nil
        })
    
            // custom http.client
        httpClient := &http.Client{
            Transport: vcrRecorder,
        }
    
        ghClient := github.NewClient(httpClient)
    
        // =====> actual test, should create cassettes, but does not.
        _, _, err = ghClient.Users.Get(context.Background(), "")
    
        require.NoError(t, err)
    }