fix: Make sure len([BODY]) works if the body is a JSON array

Fixes #359
This commit is contained in:
TwiN 2022-11-03 20:46:35 -04:00
parent ed3683cb32
commit 1f84f2afa0
3 changed files with 32 additions and 3 deletions

View File

@ -234,6 +234,13 @@ func TestCondition_evaluate(t *testing.T) {
}, },
{ {
Name: "body-len-array", Name: "body-len-array",
Condition: Condition("len([BODY]) == 3"),
Result: &Result{body: []byte("[{\"id\": 1}, {\"id\": 2}, {\"id\": 3}]")},
ExpectedSuccess: true,
ExpectedOutput: "len([BODY]) == 3",
},
{
Name: "body-len-keyed-array",
Condition: Condition("len([BODY].data) == 3"), Condition: Condition("len([BODY].data) == 3"),
Result: &Result{body: []byte("{\"data\": [{\"id\": 1}, {\"id\": 2}, {\"id\": 3}]}")}, Result: &Result{body: []byte("{\"data\": [{\"id\": 1}, {\"id\": 2}, {\"id\": 3}]}")},
ExpectedSuccess: true, ExpectedSuccess: true,
@ -248,6 +255,13 @@ func TestCondition_evaluate(t *testing.T) {
}, },
{ {
Name: "body-len-string", Name: "body-len-string",
Condition: Condition("len([BODY]) == 8"),
Result: &Result{body: []byte("john.doe")},
ExpectedSuccess: true,
ExpectedOutput: "len([BODY]) == 8",
},
{
Name: "body-len-keyed-string",
Condition: Condition("len([BODY].name) == 8"), Condition: Condition("len([BODY].name) == 8"),
Result: &Result{body: []byte("{\"name\": \"john.doe\"}")}, Result: &Result{body: []byte("{\"name\": \"john.doe\"}")},
ExpectedSuccess: true, ExpectedSuccess: true,

View File

@ -9,10 +9,12 @@ import (
// Eval is a half-baked json path implementation that needs some love // Eval is a half-baked json path implementation that needs some love
func Eval(path string, b []byte) (string, int, error) { func Eval(path string, b []byte) (string, int, error) {
if len(path) == 0 && !(len(b) != 0 && b[0] == '[' && b[len(b)-1] == ']') {
// if there's no path AND the value is not a JSON array, then there's nothing to walk
return string(b), len(b), nil
}
var object interface{} var object interface{}
err := json.Unmarshal(b, &object) if err := json.Unmarshal(b, &object); err != nil {
if err != nil {
// Try to unmarshal it into an array instead
return "", 0, err return "", 0, err
} }
return walk(path, object) return walk(path, object)
@ -103,5 +105,10 @@ func extractValue(currentKey string, value interface{}) interface{} {
} }
return nil return nil
} }
if valueAsSlice, ok := value.([]interface{}); ok {
// If the type is a slice, return it
return valueAsSlice
}
// otherwise, it's a map
return value.(map[string]interface{})[currentKey] return value.(map[string]interface{})[currentKey]
} }

View File

@ -62,6 +62,14 @@ func TestEval(t *testing.T) {
ExpectedOutputLength: 1, ExpectedOutputLength: 1,
ExpectedError: false, ExpectedError: false,
}, },
{
Name: "array-of-values-with-no-path",
Path: "",
Data: `[1, 2]`,
ExpectedOutput: "[1 2]", // the output is an array
ExpectedOutputLength: 2,
ExpectedError: false,
},
{ {
Name: "array-of-values-and-invalid-index", Name: "array-of-values-and-invalid-index",
Path: "ids[wat]", Path: "ids[wat]",