recorder_test.go

 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}