Implement has() function to determine if an element at a JSONPath exists
This commit is contained in:
		| @ -159,6 +159,8 @@ Here are some examples of conditions you can use: | ||||
| | `[BODY].age == [BODY].id`    | JSONPath value of `$.age` is equal JSONPath `$.id`      | `{"age":1,"id":1}`         |  | | ||||
| | `len([BODY].data) < 5`       | Array at JSONPath `$.data` has less than 5 elements     | `{"data":[{"id":1}]}`      |  | | ||||
| | `len([BODY].name) == 8`      | String at JSONPath `$.name` has a length of 8           | `{"name":"john.doe"}`      | `{"name":"bob"}` | | ||||
| | `has([BODY].errors) == false` | JSONPath `$.errors` does not exist                     | `{"name":"john.doe"}`      | `{"errors":[]}` | | ||||
| | `has([BODY].users) == true`  | JSONPath `$.users` exists                               | `{"users":[]}`             | `{}` | | ||||
| | `[BODY].name == pat(john*)`  | String at JSONPath `$.name` matches pattern `john*`     | `{"name":"john.doe"}`      | `{"name":"bob"}` | | ||||
| | `[BODY].id == any(1, 2)`     | Value at JSONPath `$.id` is equal to `1` or `2`         | 1, 2                       | 3, 4, 5 | | ||||
| | `[CERTIFICATE_EXPIRATION] > 48h` | Certificate expiration is more than 48h away        | 49h, 50h, 123h             | 1h, 24h, ... | | ||||
| @ -182,6 +184,7 @@ Here are some examples of conditions you can use: | ||||
| | Function   | Description                                                                                                      | Example                    | | ||||
| |:-----------|:---------------------------------------------------------------------------------------------------------------- |:-------------------------- | | ||||
| | `len`      | Returns the length of the object/slice. Works only with the `[BODY]` placeholder.                                | `len([BODY].username) > 8` | ||||
| | `has`      | Returns `true` or `false` based on whether a given path is valid. Works only with the `[BODY]` placeholder.      | `has([BODY].errors) == false` | ||||
| | `pat`      | Specifies that the string passed as parameter should be evaluated as a pattern. Works only with `==` and `!=`.   | `[IP] == pat(192.168.*)` | ||||
| | `any`      | Specifies that any one of the values passed as parameters is a valid value. Works only with `==` and `!=`.       | `[BODY].ip == any(127.0.0.1, ::1)` | ||||
|  | ||||
|  | ||||
| @ -51,14 +51,19 @@ const ( | ||||
| 	// Usage: len([BODY].articles) == 10, len([BODY].name) > 5 | ||||
| 	LengthFunctionPrefix = "len(" | ||||
|  | ||||
| 	// HasFunctionPrefix is the prefix for the has function | ||||
| 	// | ||||
| 	// Usage: has([BODY].errors) == true | ||||
| 	HasFunctionPrefix = "has(" | ||||
|  | ||||
| 	// PatternFunctionPrefix is the prefix for the pattern function | ||||
| 	// | ||||
| 	// Usage: pat(192.168.*.*) | ||||
| 	// Usage: [IP] == pat(192.168.*.*) | ||||
| 	PatternFunctionPrefix = "pat(" | ||||
|  | ||||
| 	// AnyFunctionPrefix is the prefix for the any function | ||||
| 	// | ||||
| 	// Usage: any(1.1.1.1, 1.0.0.1) | ||||
| 	// Usage: [IP] == any(1.1.1.1, 1.0.0.1) | ||||
| 	AnyFunctionPrefix = "any(" | ||||
|  | ||||
| 	// FunctionSuffix is the suffix for all functions | ||||
| @ -209,26 +214,39 @@ func sanitizeAndResolve(elements []string, result *Result) ([]string, []string) | ||||
| 		default: | ||||
| 			// if contains the BodyPlaceholder, then evaluate json path | ||||
| 			if strings.Contains(element, BodyPlaceholder) { | ||||
| 				wantLength := false | ||||
| 				checkingForLength := false | ||||
| 				checkingForExistence := false | ||||
| 				if strings.HasPrefix(element, LengthFunctionPrefix) && strings.HasSuffix(element, FunctionSuffix) { | ||||
| 					wantLength = true | ||||
| 					checkingForLength = true | ||||
| 					element = strings.TrimSuffix(strings.TrimPrefix(element, LengthFunctionPrefix), FunctionSuffix) | ||||
| 				} | ||||
| 				if strings.HasPrefix(element, HasFunctionPrefix) && strings.HasSuffix(element, FunctionSuffix) { | ||||
| 					checkingForExistence = true | ||||
| 					element = strings.TrimSuffix(strings.TrimPrefix(element, HasFunctionPrefix), FunctionSuffix) | ||||
| 				} | ||||
| 				resolvedElement, resolvedElementLength, err := jsonpath.Eval(strings.TrimPrefix(element, BodyPlaceholder+"."), result.body) | ||||
| 				if err != nil { | ||||
| 					if err.Error() != "unexpected end of JSON input" { | ||||
| 						result.Errors = append(result.Errors, err.Error()) | ||||
| 					} | ||||
| 					if wantLength { | ||||
| 						element = LengthFunctionPrefix + element + FunctionSuffix + " " + InvalidConditionElementSuffix | ||||
| 				if checkingForExistence { | ||||
| 					if err != nil { | ||||
| 						element = "false" | ||||
| 					} else { | ||||
| 						element = element + " " + InvalidConditionElementSuffix | ||||
| 						element = "true" | ||||
| 					} | ||||
| 				} else { | ||||
| 					if wantLength { | ||||
| 						element = strconv.Itoa(resolvedElementLength) | ||||
| 					if err != nil { | ||||
| 						if err.Error() != "unexpected end of JSON input" { | ||||
| 							result.Errors = append(result.Errors, err.Error()) | ||||
| 						} | ||||
| 						if checkingForLength { | ||||
| 							element = LengthFunctionPrefix + element + FunctionSuffix + " " + InvalidConditionElementSuffix | ||||
| 						} else { | ||||
| 							element = element + " " + InvalidConditionElementSuffix | ||||
| 						} | ||||
| 					} else { | ||||
| 						element = resolvedElement | ||||
| 						if checkingForLength { | ||||
| 							element = strconv.Itoa(resolvedElementLength) | ||||
| 						} else { | ||||
| 							element = resolvedElement | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user