Skip to content

Commit ae3b0dd

Browse files
committed
bump coverage and lint.
1 parent 1e894f6 commit ae3b0dd

4 files changed

Lines changed: 88 additions & 15 deletions

File tree

errors/parameter_errors_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,38 @@ func TestInvalidDeepObjectPathConflict(t *testing.T) {
318318
require.Contains(t, err.HowToFix, "testParam[nested][child]")
319319
}
320320

321+
func TestInvalidDeepObjectPathConflict_NilPaths(t *testing.T) {
322+
param := createMockParameterWithDeepObjectStyle()
323+
324+
err := InvalidDeepObjectPathConflict(param, nil, nil)
325+
326+
require.NotNil(t, err)
327+
require.Contains(t, err.Reason, "property path ''")
328+
require.Contains(t, err.HowToFix, "testParam[]")
329+
}
330+
331+
func TestInvalidDeepObjectPathConflict_PropertyFallback(t *testing.T) {
332+
param := createMockParameterWithDeepObjectStyle()
333+
prefixParam := &helpers.QueryParam{
334+
Key: "testParam",
335+
Values: []string{"bad"},
336+
Property: "nested",
337+
}
338+
nestedParam := &helpers.QueryParam{
339+
Key: "testParam",
340+
Values: []string{"ok"},
341+
Property: "nested.child",
342+
}
343+
344+
err := InvalidDeepObjectPathConflict(param, prefixParam, nestedParam)
345+
346+
require.NotNil(t, err)
347+
require.Contains(t, err.Reason, "property path 'nested'")
348+
require.Contains(t, err.Reason, "'nested.child'")
349+
require.Contains(t, err.HowToFix, "testParam[nested]")
350+
require.Contains(t, err.HowToFix, "testParam[nested.child]")
351+
}
352+
321353
func createMockParameterForBooleanArray() *v3.Parameter {
322354
param := &lowv3.Parameter{
323355
Name: low.NodeReference[string]{Value: "testCookieParam"},

helpers/parameter_utilities.go

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -388,19 +388,7 @@ func setNestedDeepObjectValue(target map[string]interface{}, propertyPath []stri
388388
return true
389389
}
390390
current := target
391-
for i, propertyName := range propertyPath {
392-
if i == len(propertyPath)-1 {
393-
if existing, exists := current[propertyName]; exists {
394-
if _, existingIsMap := existing.(map[string]interface{}); existingIsMap {
395-
if _, valueIsMap := value.(map[string]interface{}); !valueIsMap {
396-
current[propertyName] = []interface{}{existing, value}
397-
return false
398-
}
399-
}
400-
}
401-
current[propertyName] = value
402-
return true
403-
}
391+
for _, propertyName := range propertyPath[:len(propertyPath)-1] {
404392
next, ok := current[propertyName].(map[string]interface{})
405393
if !ok {
406394
if existing, exists := current[propertyName]; exists {
@@ -412,6 +400,17 @@ func setNestedDeepObjectValue(target map[string]interface{}, propertyPath []stri
412400
}
413401
current = next
414402
}
403+
404+
propertyName := propertyPath[len(propertyPath)-1]
405+
if existing, exists := current[propertyName]; exists {
406+
if _, existingIsMap := existing.(map[string]interface{}); existingIsMap {
407+
if _, valueIsMap := value.(map[string]interface{}); !valueIsMap {
408+
current[propertyName] = []interface{}{existing, value}
409+
return false
410+
}
411+
}
412+
}
413+
current[propertyName] = value
415414
return true
416415
}
417416

helpers/parameter_utilities_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,20 @@ func TestDeepObjectPathConflict(t *testing.T) {
718718
{Key: "obj", Values: []string{"ok"}, Property: "nested", PropertyPath: []string{"nested", "other"}},
719719
},
720720
},
721+
{
722+
name: "different roots",
723+
values: []*QueryParam{
724+
{Key: "obj", Values: []string{"ok"}, Property: "nested", PropertyPath: []string{"nested"}},
725+
{Key: "obj", Values: []string{"ok"}, Property: "other", PropertyPath: []string{"other", "child"}},
726+
},
727+
},
728+
{
729+
name: "empty path is ignored",
730+
values: []*QueryParam{
731+
{Key: "obj", Values: []string{"ignored"}},
732+
{Key: "obj", Values: []string{"ok"}, Property: "nested", PropertyPath: []string{"nested", "child"}},
733+
},
734+
},
721735
}
722736

723737
for _, tc := range tests {
@@ -733,7 +747,24 @@ func TestDeepObjectPathConflict(t *testing.T) {
733747
}
734748
}
735749

750+
func TestQueryParamDeepObjectPath(t *testing.T) {
751+
require.Nil(t, queryParamDeepObjectPath(nil))
752+
require.Nil(t, queryParamDeepObjectPath(&QueryParam{}))
753+
require.Equal(t, []string{"root"}, queryParamDeepObjectPath(&QueryParam{Property: "root"}))
754+
require.Equal(t, []string{"root", "child"}, queryParamDeepObjectPath(&QueryParam{
755+
Property: "root",
756+
PropertyPath: []string{"root", "child"},
757+
}))
758+
}
759+
736760
func TestSetNestedDeepObjectValue_PreservesConflicts(t *testing.T) {
761+
t.Run("empty path", func(t *testing.T) {
762+
target := make(map[string]interface{})
763+
764+
require.True(t, setNestedDeepObjectValue(target, nil, "root"))
765+
require.Equal(t, "root", target[""])
766+
})
767+
737768
t.Run("scalar before nested", func(t *testing.T) {
738769
target := make(map[string]interface{})
739770

@@ -1171,6 +1202,17 @@ func TestConstructParamMapFromDeepObjectEncoding_WithSchema(t *testing.T) {
11711202
decoded := ConstructParamMapFromDeepObjectEncoding(values, sch)
11721203
require.Equal(t, "123", decoded["key1"].(map[string]interface{})["prop1"])
11731204
})
1205+
1206+
t.Run("preserves string values when root array items are strings", func(t *testing.T) {
1207+
sch := &base.Schema{
1208+
Type: []string{"array"},
1209+
Items: &base.DynamicValue[*base.SchemaProxy, bool]{
1210+
A: base.CreateSchemaProxy(&base.Schema{Type: []string{"string"}}),
1211+
},
1212+
}
1213+
1214+
require.Equal(t, "123", castWithSchema("123", sch, "unknown"))
1215+
})
11741216
}
11751217

11761218
func TestConstructParamMapFromPipeEncodingWithSchema(t *testing.T) {

helpers/path_finder.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func ExtractJSONPathFromValidationError(e *jsonschema.ValidationError) string {
2727
for _, seg := range e.InstanceLocation {
2828
switch {
2929
case isNumeric(seg):
30-
b.WriteString(fmt.Sprintf("[%s]", seg))
30+
fmt.Fprintf(&b, "[%s]", seg)
3131

3232
case isSimpleIdentifier(seg):
3333
b.WriteByte('.')
@@ -129,7 +129,7 @@ func ExtractJSONPathFromInstanceLocation(instanceLocation []string) string {
129129
for _, seg := range instanceLocation {
130130
switch {
131131
case isNumeric(seg):
132-
b.WriteString(fmt.Sprintf("[%s]", seg))
132+
fmt.Fprintf(&b, "[%s]", seg)
133133

134134
case isSimpleIdentifier(seg):
135135
b.WriteByte('.')

0 commit comments

Comments
 (0)