1package providertests
2
3import (
4 "bytes"
5 "io"
6 "net/http"
7 "path/filepath"
8 "strings"
9 "testing"
10
11 "gopkg.in/dnaeon/go-vcr.v4/pkg/cassette"
12 "gopkg.in/dnaeon/go-vcr.v4/pkg/recorder"
13)
14
15func newRecorder(t *testing.T) *recorder.Recorder {
16 cassetteName := filepath.Join("testdata", t.Name())
17
18 r, err := recorder.New(
19 cassetteName,
20 recorder.WithMode(recorder.ModeRecordOnce),
21 recorder.WithMatcher(customMatcher(t)),
22 recorder.WithSkipRequestLatency(true), // disable sleep to simulate response time, makes tests faster
23 recorder.WithHook(hookRemoveHeaders, recorder.AfterCaptureHook),
24 )
25 if err != nil {
26 t.Fatalf("recorder: failed to create recorder: %v", err)
27 }
28
29 t.Cleanup(func() {
30 if err := r.Stop(); err != nil {
31 t.Errorf("recorder: failed to stop recorder: %v", err)
32 }
33 })
34
35 return r
36}
37
38func customMatcher(t *testing.T) recorder.MatcherFunc {
39 return func(r *http.Request, i cassette.Request) bool {
40 if r.Body == nil || r.Body == http.NoBody {
41 return cassette.DefaultMatcher(r, i)
42 }
43
44 var reqBody []byte
45 var err error
46 reqBody, err = io.ReadAll(r.Body)
47 if err != nil {
48 t.Fatalf("recorder: failed to read request body")
49 }
50 r.Body.Close()
51 r.Body = io.NopCloser(bytes.NewBuffer(reqBody))
52
53 return r.Method == i.Method && r.URL.String() == i.URL && string(reqBody) == i.Body
54 }
55}
56
57var headersToKeep = map[string]struct{}{
58 "accept": {},
59 "content-type": {},
60 "user-agent": {},
61}
62
63func hookRemoveHeaders(i *cassette.Interaction) error {
64 for k := range i.Request.Headers {
65 if _, ok := headersToKeep[strings.ToLower(k)]; !ok {
66 delete(i.Request.Headers, k)
67 }
68 }
69 for k := range i.Response.Headers {
70 if _, ok := headersToKeep[strings.ToLower(k)]; !ok {
71 delete(i.Response.Headers, k)
72 }
73 }
74 return nil
75}