Skip to content

Commit 14ba415

Browse files
committed
wip
1 parent 5876f5f commit 14ba415

File tree

4 files changed

+448
-168
lines changed

4 files changed

+448
-168
lines changed

internal/acctest/acctest.go

Lines changed: 0 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -102,65 +102,6 @@ func extractGeneratedNamePrefix(name string) string {
102102
return name
103103
}
104104

105-
// compareJSONFieldsStrings compare two strings from request JSON bodies
106-
// has special case when string are terraform generated names
107-
func compareJSONFieldsStrings(expected, actual string) bool {
108-
expectedHandled := expected
109-
actualHandled := actual
110-
111-
// Remove s3 url suffix to allow comparison
112-
if strings.HasSuffix(actual, ".s3-website.fr-par.scw.cloud") {
113-
actual = strings.TrimSuffix(actual, ".s3-website.fr-par.scw.cloud")
114-
expected = strings.TrimSuffix(expected, ".s3-website.fr-par.scw.cloud")
115-
}
116-
117-
// Try to parse test generated name
118-
if strings.Contains(actual, "-") {
119-
expectedHandled = extractTestGeneratedNamePrefix(expected)
120-
actualHandled = extractTestGeneratedNamePrefix(actual)
121-
}
122-
123-
// Try provider generated name
124-
if actualHandled == actual && strings.HasPrefix(actual, "tf-") {
125-
expectedHandled = extractGeneratedNamePrefix(expected)
126-
actualHandled = extractGeneratedNamePrefix(actual)
127-
}
128-
129-
return expectedHandled == actualHandled
130-
}
131-
132-
// compareJSONBodies compare two given maps that represent json bodies
133-
// returns true if both json are equivalent
134-
func compareJSONBodies(expected, actual map[string]interface{}) bool {
135-
// Check for each key in actual requests
136-
// Compare its value to cassette content if marshal-able to string
137-
for key := range actual {
138-
expectedValue, exists := expected[key]
139-
if !exists {
140-
// Actual request may contain a field that does not exist in cassette
141-
// New fields can appear in requests with new api features
142-
// We do not want to generate new cassettes for each new features
143-
continue
144-
}
145-
146-
if !compareJSONFields(expectedValue, actual[key]) {
147-
return false
148-
}
149-
}
150-
151-
for key := range expected {
152-
_, exists := actual[key]
153-
if !exists && expected[key] != nil {
154-
// Fails match if cassettes contains a field not in actual requests
155-
// Fields should not disappear from requests unless a sdk breaking change
156-
// We ignore if field is nil in cassette as it could be an old deprecated and unused field
157-
return false
158-
}
159-
}
160-
161-
return true
162-
}
163-
164105
// IsTestResource returns true if given resource identifier is from terraform test
165106
// identifier should be resource name but some resource don't have names
166107
// return true if identifier match regex "tf[-_]test"

internal/acctest/acctest_test.go

Lines changed: 199 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,128 @@ var fooMemberCreationBody = `{
4949
}
5050
`
5151

52+
var secretPatchBodyCassette = `{
53+
"environment_variables": {
54+
"foo": "bar"
55+
},
56+
"privacy": "unknown_privacy",
57+
"protocol": "unknown_protocol",
58+
"secret_environment_variables": [
59+
{
60+
"key": "foo_secret",
61+
"value": "bar_secret"
62+
},
63+
{
64+
"key": "test_secret",
65+
"value": "updated_secret"
66+
},
67+
{
68+
"key": "first_secret",
69+
"value": null
70+
}
71+
],
72+
"http_option": "unknown_http_option",
73+
"sandbox": "unknown_sandbox"
74+
}
75+
`
76+
77+
var secretPatchBodyRequest = `{
78+
"environment_variables": {
79+
"foo": "bar"
80+
},
81+
"privacy": "unknown_privacy",
82+
"protocol": "unknown_protocol",
83+
"secret_environment_variables": [
84+
{
85+
"key": "first_secret",
86+
"value": null
87+
},
88+
{
89+
"key": "foo_secret",
90+
"value": "bar_secret"
91+
},
92+
{
93+
"key": "test_secret",
94+
"value": "updated_secret"
95+
}
96+
],
97+
"http_option": "unknown_http_option",
98+
"sandbox": "unknown_sandbox"
99+
}
100+
`
101+
102+
var integertestBodyRequest = `{
103+
"akey": "avalue",
104+
"nested_integer": {
105+
"integers": [
106+
1,
107+
2,
108+
3
109+
]
110+
}
111+
}
112+
`
113+
114+
var integertestBodyCassette = `{
115+
"akey": "avalue",
116+
"nested_integer": {
117+
"integers": [
118+
4,
119+
5,
120+
6
121+
]
122+
}
123+
}
124+
`
125+
126+
var integerBodyRequestOutOfOrder = `{
127+
"akey": "avalue",
128+
"nested_integer": {
129+
"integers": [
130+
2,
131+
1,
132+
3
133+
]
134+
}
135+
}
136+
`
137+
138+
var nestedSliceOfSlicesRequest = `{
139+
"akey": "avalue",
140+
"nested_lists": [
141+
[
142+
"1",
143+
"2",
144+
"3"
145+
],
146+
[
147+
"4",
148+
"5",
149+
"6"
150+
]
151+
}
152+
}
153+
`
154+
155+
var nestedSliceOfSlicesCassette = `{
156+
"akey": "avalue",
157+
"nested_slice_of_slices": {
158+
"integers_array": [
159+
[
160+
"4",
161+
"5",
162+
"6"
163+
],
164+
[
165+
"1",
166+
"2",
167+
"3"
168+
]
169+
]
170+
},
171+
}
172+
`
173+
52174
// we don't use httptest.NewRequest because it does not set the GetBody func
53175
func newRequest(method, url string, body io.Reader) *http.Request {
54176
req, err := http.NewRequestWithContext(context.Background(), method, url, body)
@@ -64,43 +186,102 @@ var testBodyMatcherCases = []struct {
64186
cassetteBody *cassette.Request
65187
shouldMatch bool
66188
}{
189+
// create bar compare with foo
190+
// {
191+
// requestBody: newRequest(http.MethodPost, "https://api.scaleway.com/iam/v1alpha1/users", strings.NewReader(barMemberCreationBody)),
192+
// cassetteBody: &cassette.Request{
193+
// URL: "https://api.scaleway.com/iam/v1alpha1/users",
194+
// Method: http.MethodPost,
195+
// Body: fooMemberCreationBody,
196+
// ContentLength: int64(len(fooMemberCreationBody)),
197+
// },
198+
// shouldMatch: false,
199+
// },
200+
// // create bar compare with bar
201+
// {
202+
// requestBody: newRequest(http.MethodPost, "https://api.scaleway.com/iam/v1alpha1/users", strings.NewReader(barMemberCreationBody)),
203+
// cassetteBody: &cassette.Request{
204+
// URL: "https://api.scaleway.com/iam/v1alpha1/users",
205+
// Method: http.MethodPost,
206+
// Body: barMemberCreationBody,
207+
// ContentLength: int64(len(barMemberCreationBody)),
208+
// },
209+
// shouldMatch: true,
210+
// },
211+
// // simple http get
212+
// {
213+
// requestBody: newRequest(http.MethodGet, "https://api.scaleway.com/iam/v1alpha1/users/6867048b-fe12-4e96-835e-41c79a39604b", nil),
214+
// cassetteBody: &cassette.Request{
215+
// URL: "https://api.scaleway.com/iam/v1alpha1/users/6867048b-fe12-4e96-835e-41c79a39604b",
216+
// Method: http.MethodGet,
217+
// Body: "",
218+
// ContentLength: 0,
219+
// },
220+
// shouldMatch: true,
221+
// },
222+
// // patch secret with nested slices of map[string]interface{} in different order
223+
// // we cannot user deep equal because the order of the slices is different although the values are the same
224+
// // it is not possible to sort them because they are not comparable (map[string]interface{})
225+
// {
226+
// requestBody: newRequest(http.MethodPatch, "https://api.scaleway.com/secrets/v1/secrets/123", strings.NewReader(secretPatchBodyRequest)),
227+
// cassetteBody: &cassette.Request{
228+
// URL: "https://api.scaleway.com/secrets/v1/secrets/123",
229+
// Method: http.MethodPatch,
230+
// Body: secretPatchBodyCassette,
231+
// ContentLength: int64(len(secretPatchBodyCassette)),
232+
// },
233+
// shouldMatch: true,
234+
// },
235+
// // compare nested slices of different integers
236+
// {
237+
// requestBody: newRequest(http.MethodPost, "https://api.scaleway.com/iam/v1alpha1/users", strings.NewReader(integertestBodyRequest)),
238+
// cassetteBody: &cassette.Request{
239+
// URL: "https://api.scaleway.com/iam/v1alpha1/users",
240+
// Method: http.MethodPost,
241+
// Body: integertestBodyCassette,
242+
// ContentLength: int64(len(integertestBodyCassette)),
243+
// },
244+
// shouldMatch: false,
245+
// },
246+
// // compare nested slices of same integers in different order
247+
// {
248+
// requestBody: newRequest(http.MethodPost, "https://api.scaleway.com/iam/v1alpha1/users", strings.NewReader(integerBodyRequestOutOfOrder)),
249+
// cassetteBody: &cassette.Request{
250+
// URL: "https://api.scaleway.com/iam/v1alpha1/users",
251+
// Method: http.MethodPost,
252+
// Body: integertestBodyRequest,
253+
// ContentLength: int64(len(integertestBodyRequest)),
254+
// },
255+
// shouldMatch: true,
256+
// },
257+
// // compare nested slices of slices of strings
67258
{
68-
requestBody: newRequest(http.MethodPost, "https://api.scaleway.com/iam/v1alpha1/users", strings.NewReader(barMemberCreationBody)),
259+
requestBody: newRequest(http.MethodPost, "https://api.scaleway.com/iam/v1alpha1/users", strings.NewReader(nestedSliceOfSlicesRequest)),
69260
cassetteBody: &cassette.Request{
70261
URL: "https://api.scaleway.com/iam/v1alpha1/users",
71262
Method: http.MethodPost,
72-
Body: fooMemberCreationBody,
73-
ContentLength: int64(len(fooMemberCreationBody)),
263+
Body: nestedSliceOfSlicesCassette,
264+
ContentLength: int64(len(nestedSliceOfSlicesCassette)),
74265
},
75266
shouldMatch: false,
76267
},
77268
{
78-
requestBody: newRequest(http.MethodPost, "https://api.scaleway.com/iam/v1alpha1/users", strings.NewReader(barMemberCreationBody)),
269+
requestBody: newRequest(http.MethodPost, "https://api.scaleway.com/iam/v1alpha1/users", strings.NewReader(nestedSliceOfSlicesRequest)),
79270
cassetteBody: &cassette.Request{
80271
URL: "https://api.scaleway.com/iam/v1alpha1/users",
81272
Method: http.MethodPost,
82-
Body: barMemberCreationBody,
83-
ContentLength: int64(len(barMemberCreationBody)),
84-
},
85-
shouldMatch: true,
86-
},
87-
{
88-
requestBody: newRequest(http.MethodGet, "https://api.scaleway.com/iam/v1alpha1/users/6867048b-fe12-4e96-835e-41c79a39604b", nil),
89-
cassetteBody: &cassette.Request{
90-
URL: "https://api.scaleway.com/iam/v1alpha1/users/6867048b-fe12-4e96-835e-41c79a39604b",
91-
Method: http.MethodGet,
92-
Body: "",
93-
ContentLength: 0,
273+
Body: nestedSliceOfSlicesRequest,
274+
ContentLength: int64(len(nestedSliceOfSlicesRequest)),
94275
},
95276
shouldMatch: true,
96277
},
97278
}
98279

99280
func TestCassetteMatcher(t *testing.T) {
100-
for _, test := range testBodyMatcherCases {
281+
for i, test := range testBodyMatcherCases {
101282
shouldMatch := acctest.CassetteMatcher(test.requestBody, *test.cassetteBody)
102283
if shouldMatch != test.shouldMatch {
103-
t.Errorf("expected %v, got %v", test.shouldMatch, shouldMatch)
284+
t.Errorf("test %d: expected %v, got %v", i, test.shouldMatch, shouldMatch)
104285
}
105286
}
106287
}

0 commit comments

Comments
 (0)