Skip to content

Commit 1715747

Browse files
committed
Add DiscardOnSave field to Interaction type
The DiscardOnSave field may be set to true by hooks, in order to discard an interaction before saving it on disk. See issue #80 for some background info.
1 parent db4802a commit 1715747

File tree

2 files changed

+109
-3
lines changed

2 files changed

+109
-3
lines changed

Diff for: cassette/cassette.go

+30-3
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,23 @@ type Response struct {
123123
// Interaction type contains a pair of request/response for a
124124
// single HTTP interaction between a client and a server
125125
type Interaction struct {
126-
ID int `yaml:"id"`
127-
Request Request `yaml:"request"`
126+
// ID is the id of the interaction
127+
ID int `yaml:"id"`
128+
129+
// Request is the recorded request
130+
Request Request `yaml:"request"`
131+
132+
// Response is the recorded response
128133
Response Response `yaml:"response"`
129-
replayed bool `yaml:"-"`
134+
135+
// DiscardOnSave if set to true will discard the interaction
136+
// as a whole and it will not be part of the final
137+
// interactions when saving the cassette on disk.
138+
DiscardOnSave bool `yaml:"-"`
139+
140+
// replayed is true when this interaction has been played
141+
// already.
142+
replayed bool `yaml:"-"`
130143
}
131144

132145
// GetHTTPRequest converts the recorded interaction request to
@@ -301,6 +314,20 @@ func (c *Cassette) Save() error {
301314
}
302315
}
303316

317+
// Filter out interactions which should be discarded. While
318+
// discarding interactions we should also fix the interaction
319+
// IDs, so that we don't introduce gaps in the final results.
320+
nextId := 0
321+
interactions := make([]*Interaction, 0)
322+
for _, i := range c.Interactions {
323+
if !i.DiscardOnSave {
324+
i.ID = nextId
325+
interactions = append(interactions, i)
326+
nextId += 1
327+
}
328+
}
329+
c.Interactions = interactions
330+
304331
// Marshal to YAML and save interactions
305332
data, err := yaml.Marshal(c)
306333
if err != nil {

Diff for: recorder/recorder_test.go

+79
Original file line numberDiff line numberDiff line change
@@ -1225,3 +1225,82 @@ func TestInvalidRecorderMode(t *testing.T) {
12251225
t.Fatal("expected recorder to fail with invalid mode")
12261226
}
12271227
}
1228+
1229+
func TestDiscardInteractionsOnSave(t *testing.T) {
1230+
tests := []testCase{
1231+
{
1232+
method: http.MethodPost,
1233+
body: "foo",
1234+
wantBody: "POST go-vcr\nfoo",
1235+
wantStatus: http.StatusOK,
1236+
wantContentLength: 15,
1237+
path: "/api/v1/foo",
1238+
},
1239+
{
1240+
method: http.MethodPost,
1241+
body: "bar",
1242+
wantBody: "POST go-vcr\nbar",
1243+
wantStatus: http.StatusOK,
1244+
wantContentLength: 15,
1245+
path: "/api/v1/bar",
1246+
},
1247+
}
1248+
1249+
server := newEchoHttpServer()
1250+
serverUrl := server.URL
1251+
1252+
cassPath, err := newCassettePath("test_discard_interactions_on_save")
1253+
if err != nil {
1254+
t.Fatal(err)
1255+
}
1256+
1257+
// Create recorder
1258+
rec, err := recorder.New(cassPath)
1259+
if err != nil {
1260+
t.Fatal(err)
1261+
}
1262+
1263+
if rec.Mode() != recorder.ModeRecordOnce {
1264+
t.Fatal("recorder is not in the correct mode")
1265+
}
1266+
1267+
if rec.IsRecording() != true {
1268+
t.Fatal("recorder is not recording")
1269+
}
1270+
1271+
// The following hook function will be used to determine
1272+
// whether an interaction is to be discarded when saving the
1273+
// cassette on disk.
1274+
hook := func(i *cassette.Interaction) error {
1275+
if i.Request.Method == http.MethodPost && i.Request.Body == "foo" {
1276+
i.DiscardOnSave = true
1277+
}
1278+
1279+
return nil
1280+
}
1281+
rec.AddHook(hook, recorder.AfterCaptureHook)
1282+
1283+
ctx := context.Background()
1284+
client := rec.GetDefaultClient()
1285+
for _, test := range tests {
1286+
if err := test.run(client, ctx, serverUrl); err != nil {
1287+
t.Fatal(err)
1288+
}
1289+
}
1290+
1291+
// Stop recorder and verify cassette
1292+
rec.Stop()
1293+
1294+
cass, err := cassette.Load(cassPath)
1295+
if err != nil {
1296+
t.Fatal(err)
1297+
}
1298+
1299+
// We should have one interaction less than our test cases
1300+
// when reading the cassette from disk.
1301+
wantInteractions := len(tests) - 1
1302+
gotInteractions := len(cass.Interactions)
1303+
if wantInteractions != gotInteractions {
1304+
t.Fatalf("expected %d interactions, got %d", wantInteractions, gotInteractions)
1305+
}
1306+
}

0 commit comments

Comments
 (0)