Skip to content

Commit ae0303b

Browse files
demeyerthommvantellingen
authored andcommitted
Added fix for customFieldEncodeValue mishandling non-string values
1 parent db90922 commit ae0303b

File tree

3 files changed

+95
-22
lines changed

3 files changed

+95
-22
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
kind: Fixed
2+
body: Fixed custom field encoding with non-string field values
3+
time: 2023-08-16T14:39:23.454743853+02:00

commercetools/custom_fields.go

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,8 @@ type SetCustomFieldAction interface {
6868
platform.CartDiscountSetCustomFieldAction
6969
}
7070

71-
func CustomFieldCreateFieldContainer(data map[string]any) *platform.FieldContainer {
72-
if raw, ok := data["fields"].(map[string]any); ok {
73-
fields := platform.FieldContainer(raw)
74-
return &fields
75-
}
76-
return nil
77-
}
78-
7971
func customFieldEncodeType(t *platform.Type, name string, value any) (any, error) {
80-
// Sub-optimal to do this everytime, however performance is not that
81-
// important here and impact is neglible
72+
// Suboptimal to do this everytime, however performance is not that important here and impact is negligible
8273
fieldTypes := map[string]platform.FieldType{}
8374
for _, field := range t.FieldDefinitions {
8475
fieldTypes[field.Name] = field.Type
@@ -124,7 +115,18 @@ func customFieldEncodeValue(t platform.FieldType, name string, value any) (any,
124115

125116
result := make([]any, len(values))
126117
for i := range values {
127-
itemValue, err := customFieldEncodeValue(v.ElementType, name, values[i])
118+
var element = values[i]
119+
_, ok := element.(string)
120+
121+
//We need to re-marshal the data here, so we can recursively pass it back to the encoding function
122+
if !ok {
123+
marshalledValue, err := json.Marshal(values[i])
124+
if err != nil {
125+
return nil, err
126+
}
127+
element = string(marshalledValue)
128+
}
129+
itemValue, err := customFieldEncodeValue(v.ElementType, name, element)
128130
if err != nil {
129131
return nil, err
130132
}
@@ -263,22 +265,22 @@ func CustomFieldUpdateActions[T SetCustomTypeAction, F SetCustomFieldAction](ctx
263265
return nil, err
264266
}
265267

266-
old, new := d.GetChange("custom")
267-
old_data := firstElementFromSlice(old.([]any))
268-
new_data := firstElementFromSlice(new.([]any))
269-
old_type_id := old_data["type_id"]
270-
new_type_id := new_data["type_id"]
268+
oldState, newState := d.GetChange("custom")
269+
oldData := firstElementFromSlice(oldState.([]any))
270+
newData := firstElementFromSlice(newState.([]any))
271+
oldTypeId := oldData["type_id"]
272+
newTypeId := newData["type_id"]
271273

272274
// Remove custom field from resource
273-
if new_type_id == nil {
275+
if newTypeId == nil {
274276
action := T{
275277
Type: nil,
276278
}
277279
return []any{action}, nil
278280
}
279281

280-
if old_type_id == nil || (old_type_id.(string) != new_type_id.(string)) {
281-
value, err := CreateCustomFieldDraftRaw(new_data, t)
282+
if oldTypeId == nil || (oldTypeId.(string) != newTypeId.(string)) {
283+
value, err := CreateCustomFieldDraftRaw(newData, t)
282284
if err != nil {
283285
return nil, err
284286
}
@@ -290,10 +292,10 @@ func CustomFieldUpdateActions[T SetCustomTypeAction, F SetCustomFieldAction](ctx
290292
}
291293

292294
changes := diffSlices(
293-
old_data["fields"].(map[string]any),
294-
new_data["fields"].(map[string]any))
295+
oldData["fields"].(map[string]any),
296+
newData["fields"].(map[string]any))
295297

296-
result := []any{}
298+
var result []any
297299
for key := range changes {
298300
val, err := customFieldEncodeType(t, key, changes[key])
299301
if err != nil {

commercetools/custom_fields_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package commercetools
2+
3+
import (
4+
"github.com/labd/commercetools-go-sdk/platform"
5+
"github.com/stretchr/testify/assert"
6+
"testing"
7+
)
8+
9+
var customFieldEncodeValueTests = []struct {
10+
typ any
11+
value any
12+
expectedVal any
13+
hasError bool
14+
}{
15+
//CustomFieldLocalizedStringType
16+
{typ: platform.CustomFieldLocalizedStringType{}, value: `{"foo":"bar"}`, expectedVal: platform.LocalizedString{"foo": "bar"}},
17+
{typ: platform.CustomFieldLocalizedStringType{}, value: `foobar`, hasError: true},
18+
19+
//CustomFieldBooleanType
20+
{typ: platform.CustomFieldBooleanType{}, value: "true", expectedVal: true},
21+
{typ: platform.CustomFieldBooleanType{}, value: "false", expectedVal: false},
22+
{typ: platform.CustomFieldBooleanType{}, value: "foobar", hasError: true},
23+
24+
//CustomFieldNumberType
25+
{typ: platform.CustomFieldNumberType{}, value: "1", expectedVal: int64(1)},
26+
{typ: platform.CustomFieldNumberType{}, value: "foobar", hasError: true},
27+
28+
//CustomFieldSetType
29+
{
30+
typ: platform.CustomFieldSetType{ElementType: platform.CustomFieldStringType{}},
31+
value: `["hello", "world"]`,
32+
expectedVal: []interface{}{"hello", "world"},
33+
},
34+
{
35+
typ: platform.CustomFieldSetType{ElementType: platform.CustomFieldNumberType{}},
36+
value: `[1, 2]`,
37+
expectedVal: []interface{}{int64(1), int64(2)},
38+
},
39+
{
40+
typ: platform.CustomFieldSetType{ElementType: platform.CustomFieldReferenceType{}},
41+
value: `[{"id":"98edd6e4-1702-45d5-8bc0-bbb792a4a839","typeId":"zone"},{"id":"8a8efb57-71d3-4a8d-aa77-4d4e6df9ef2a","typeId":"zone"}]`,
42+
expectedVal: []interface{}{
43+
map[string]interface{}{"id": "98edd6e4-1702-45d5-8bc0-bbb792a4a839", "typeId": "zone"},
44+
map[string]interface{}{"id": "8a8efb57-71d3-4a8d-aa77-4d4e6df9ef2a", "typeId": "zone"},
45+
},
46+
},
47+
48+
//CustomFieldReferenceType
49+
{
50+
typ: platform.CustomFieldReferenceType{},
51+
value: `{"id":"98edd6e4-1702-45d5-8bc0-bbb792a4a839","typeId":"zone"}`,
52+
expectedVal: map[string]interface{}{"id": "98edd6e4-1702-45d5-8bc0-bbb792a4a839", "typeId": "zone"},
53+
},
54+
}
55+
56+
func TestCustomFieldEncodeValue(t *testing.T) {
57+
for _, tt := range customFieldEncodeValueTests {
58+
t.Run("TestCustomFieldEncodeValue", func(t *testing.T) {
59+
encodedValue, err := customFieldEncodeValue(tt.typ, "some_field", tt.value)
60+
if tt.hasError {
61+
assert.Error(t, err)
62+
} else {
63+
assert.Nil(t, err)
64+
}
65+
assert.Equal(t, tt.expectedVal, encodedValue)
66+
})
67+
}
68+
}

0 commit comments

Comments
 (0)