REST API: Add support for the uniqueItems keyword.
Props sorenbronsted. Fixes #48821. git-svn-id: https://develop.svn.wordpress.org/trunk@48357 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
abfd9441b7
commit
41912bcece
@ -1438,6 +1438,63 @@ function rest_handle_multi_type_schema( $value, $args, $param = '' ) {
|
|||||||
return $best_type;
|
return $best_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if an array is made up of unique items.
|
||||||
|
*
|
||||||
|
* @since 5.5.0
|
||||||
|
*
|
||||||
|
* @param array $array The array to check.
|
||||||
|
* @return bool True if the array contains unique items, false otherwise.
|
||||||
|
*/
|
||||||
|
function rest_validate_array_contains_unique_items( $array ) {
|
||||||
|
$seen = array();
|
||||||
|
|
||||||
|
foreach ( $array as $item ) {
|
||||||
|
$stabilized = rest_stabilize_value( $item );
|
||||||
|
$key = serialize( $stabilized );
|
||||||
|
|
||||||
|
if ( ! isset( $seen[ $key ] ) ) {
|
||||||
|
$seen[ $key ] = true;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stabilizes a value following JSON Schema semantics.
|
||||||
|
*
|
||||||
|
* For lists, order is preserved. For objects, properties are reordered alphabetically.
|
||||||
|
*
|
||||||
|
* @since 5.5.0
|
||||||
|
*
|
||||||
|
* @param mixed $value The value to stabilize. Must already be sanitized. Objects should have been converted to arrays.
|
||||||
|
* @return mixed The stabilized value.
|
||||||
|
*/
|
||||||
|
function rest_stabilize_value( $value ) {
|
||||||
|
if ( is_scalar( $value ) || is_null( $value ) ) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( is_object( $value ) ) {
|
||||||
|
_doing_it_wrong( __FUNCTION__, __( 'Cannot stabilize objects. Convert the object to an array first.' ), '5.5.0' );
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
ksort( $value );
|
||||||
|
|
||||||
|
foreach ( $value as $k => $v ) {
|
||||||
|
$value[ $k ] = rest_stabilize_value( $v );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate a value based on a schema.
|
* Validate a value based on a schema.
|
||||||
*
|
*
|
||||||
@ -1448,8 +1505,8 @@ function rest_handle_multi_type_schema( $value, $args, $param = '' ) {
|
|||||||
* @since 5.4.0 Convert an empty string to an empty object.
|
* @since 5.4.0 Convert an empty string to an empty object.
|
||||||
* @since 5.5.0 Add the "uuid" and "hex-color" formats.
|
* @since 5.5.0 Add the "uuid" and "hex-color" formats.
|
||||||
* Support the "minLength", "maxLength" and "pattern" keywords for strings.
|
* Support the "minLength", "maxLength" and "pattern" keywords for strings.
|
||||||
|
* Support the "minItems", "maxItems" and "uniqueItems" keywords for arrays.
|
||||||
* Validate required properties.
|
* Validate required properties.
|
||||||
* Support the "minItems" and "maxItems" keywords for arrays.
|
|
||||||
*
|
*
|
||||||
* @param mixed $value The value to validate.
|
* @param mixed $value The value to validate.
|
||||||
* @param array $args Schema array to use for validation.
|
* @param array $args Schema array to use for validation.
|
||||||
@ -1492,10 +1549,12 @@ function rest_validate_value_from_schema( $value, $args, $param = '' ) {
|
|||||||
|
|
||||||
$value = rest_sanitize_array( $value );
|
$value = rest_sanitize_array( $value );
|
||||||
|
|
||||||
foreach ( $value as $index => $v ) {
|
if ( isset( $args['items'] ) ) {
|
||||||
$is_valid = rest_validate_value_from_schema( $v, $args['items'], $param . '[' . $index . ']' );
|
foreach ( $value as $index => $v ) {
|
||||||
if ( is_wp_error( $is_valid ) ) {
|
$is_valid = rest_validate_value_from_schema( $v, $args['items'], $param . '[' . $index . ']' );
|
||||||
return $is_valid;
|
if ( is_wp_error( $is_valid ) ) {
|
||||||
|
return $is_valid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1508,6 +1567,11 @@ function rest_validate_value_from_schema( $value, $args, $param = '' ) {
|
|||||||
/* translators: 1: Parameter, 2: Number. */
|
/* translators: 1: Parameter, 2: Number. */
|
||||||
return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must contain at most %2$s items.' ), $param, number_format_i18n( $args['maxItems'] ) ) );
|
return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s must contain at most %2$s items.' ), $param, number_format_i18n( $args['maxItems'] ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ! empty( $args['uniqueItems'] ) && ! rest_validate_array_contains_unique_items( $value ) ) {
|
||||||
|
/* translators: 1: Parameter */
|
||||||
|
return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s has duplicate items.' ), $param ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( 'object' === $args['type'] ) {
|
if ( 'object' === $args['type'] ) {
|
||||||
@ -1718,7 +1782,7 @@ function rest_validate_value_from_schema( $value, $args, $param = '' ) {
|
|||||||
* @param mixed $value The value to sanitize.
|
* @param mixed $value The value to sanitize.
|
||||||
* @param array $args Schema array to use for sanitization.
|
* @param array $args Schema array to use for sanitization.
|
||||||
* @param string $param The parameter name, used in error messages.
|
* @param string $param The parameter name, used in error messages.
|
||||||
* @return mixed The sanitized value.
|
* @return mixed|WP_Error The sanitized value or a WP_Error instance if the value cannot be safely sanitized.
|
||||||
*/
|
*/
|
||||||
function rest_sanitize_value_from_schema( $value, $args, $param = '' ) {
|
function rest_sanitize_value_from_schema( $value, $args, $param = '' ) {
|
||||||
$allowed_types = array( 'array', 'object', 'string', 'number', 'integer', 'boolean', 'null' );
|
$allowed_types = array( 'array', 'object', 'string', 'number', 'integer', 'boolean', 'null' );
|
||||||
@ -1750,12 +1814,15 @@ function rest_sanitize_value_from_schema( $value, $args, $param = '' ) {
|
|||||||
if ( 'array' === $args['type'] ) {
|
if ( 'array' === $args['type'] ) {
|
||||||
$value = rest_sanitize_array( $value );
|
$value = rest_sanitize_array( $value );
|
||||||
|
|
||||||
if ( empty( $args['items'] ) ) {
|
if ( ! empty( $args['items'] ) ) {
|
||||||
return $value;
|
foreach ( $value as $index => $v ) {
|
||||||
|
$value[ $index ] = rest_sanitize_value_from_schema( $v, $args['items'], $param . '[' . $index . ']' );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ( $value as $index => $v ) {
|
if ( ! empty( $args['uniqueItems'] ) && ! rest_validate_array_contains_unique_items( $value ) ) {
|
||||||
$value[ $index ] = rest_sanitize_value_from_schema( $v, $args['items'], $param . '[' . $index . ']' );
|
/* translators: 1: Parameter */
|
||||||
|
return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s has duplicate items.' ), $param ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return $value;
|
return $value;
|
||||||
|
@ -0,0 +1,374 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"description": "uniqueItems validation",
|
||||||
|
"schema": {"uniqueItems": true},
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"description": "unique array of integers is valid",
|
||||||
|
"data": [1, 2],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "non-unique array of integers is invalid",
|
||||||
|
"data": [1, 1],
|
||||||
|
"valid": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "numbers are unique if mathematically unequal",
|
||||||
|
"data": [1.0, 1.00, 1],
|
||||||
|
"valid": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "false is not equal to zero",
|
||||||
|
"data": [0, false],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "true is not equal to one",
|
||||||
|
"data": [1, true],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "unique array of objects is valid",
|
||||||
|
"data": [{"foo": "bar"}, {"foo": "baz"}],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "non-unique array of objects is invalid",
|
||||||
|
"data": [{"foo": "bar"}, {"foo": "bar"}],
|
||||||
|
"valid": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "unique array of nested objects is valid",
|
||||||
|
"data": [
|
||||||
|
{"foo": {"bar" : {"baz" : true}}},
|
||||||
|
{"foo": {"bar" : {"baz" : false}}}
|
||||||
|
],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "non-unique array of nested objects is invalid",
|
||||||
|
"data": [
|
||||||
|
{"foo": {"bar" : {"baz" : true}}},
|
||||||
|
{"foo": {"bar" : {"baz" : true}}}
|
||||||
|
],
|
||||||
|
"valid": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "unique array of arrays is valid",
|
||||||
|
"data": [["foo"], ["bar"]],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "non-unique array of arrays is invalid",
|
||||||
|
"data": [["foo"], ["foo"]],
|
||||||
|
"valid": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "1 and true are unique",
|
||||||
|
"data": [1, true],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "0 and false are unique",
|
||||||
|
"data": [0, false],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "[1] and [true] are unique",
|
||||||
|
"data": [[1], [true]],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "[0] and [false] are unique",
|
||||||
|
"data": [[0], [false]],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "nested [1] and [true] are unique",
|
||||||
|
"data": [[[1], "foo"], [[true], "foo"]],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "nested [0] and [false] are unique",
|
||||||
|
"data": [[[0], "foo"], [[false], "foo"]],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "unique heterogeneous types are valid",
|
||||||
|
"data": [{}, [1], true, null, 1, "{}"],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "non-unique heterogeneous types are invalid",
|
||||||
|
"data": [{}, [1], true, null, {}, 1],
|
||||||
|
"valid": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "different objects are unique",
|
||||||
|
"data": [{"a": 1, "b": 2}, {"a": 2, "b": 1}],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "objects are non-unique despite key order",
|
||||||
|
"data": [{"a": 1, "b": 2}, {"b": 2, "a": 1}],
|
||||||
|
"valid": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "uniqueItems with an array of items",
|
||||||
|
"schema": {
|
||||||
|
"items": [{"type": "boolean"}, {"type": "boolean"}],
|
||||||
|
"uniqueItems": true
|
||||||
|
},
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"description": "[false, true] from items array is valid",
|
||||||
|
"data": [false, true],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "[true, false] from items array is valid",
|
||||||
|
"data": [true, false],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "[false, false] from items array is not valid",
|
||||||
|
"data": [false, false],
|
||||||
|
"valid": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "[true, true] from items array is not valid",
|
||||||
|
"data": [true, true],
|
||||||
|
"valid": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "unique array extended from [false, true] is valid",
|
||||||
|
"data": [false, true, "foo", "bar"],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "unique array extended from [true, false] is valid",
|
||||||
|
"data": [true, false, "foo", "bar"],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "non-unique array extended from [false, true] is not valid",
|
||||||
|
"data": [false, true, "foo", "foo"],
|
||||||
|
"valid": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "non-unique array extended from [true, false] is not valid",
|
||||||
|
"data": [true, false, "foo", "foo"],
|
||||||
|
"valid": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "uniqueItems with an array of items and additionalItems=false",
|
||||||
|
"schema": {
|
||||||
|
"items": [{"type": "boolean"}, {"type": "boolean"}],
|
||||||
|
"uniqueItems": true,
|
||||||
|
"additionalItems": false
|
||||||
|
},
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"description": "[false, true] from items array is valid",
|
||||||
|
"data": [false, true],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "[true, false] from items array is valid",
|
||||||
|
"data": [true, false],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "[false, false] from items array is not valid",
|
||||||
|
"data": [false, false],
|
||||||
|
"valid": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "[true, true] from items array is not valid",
|
||||||
|
"data": [true, true],
|
||||||
|
"valid": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "extra items are invalid even if unique",
|
||||||
|
"data": [false, true, null],
|
||||||
|
"valid": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "uniqueItems=false validation",
|
||||||
|
"schema": { "uniqueItems": false },
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"description": "unique array of integers is valid",
|
||||||
|
"data": [1, 2],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "non-unique array of integers is valid",
|
||||||
|
"data": [1, 1],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "numbers are unique if mathematically unequal",
|
||||||
|
"data": [1.0, 1.00, 1],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "false is not equal to zero",
|
||||||
|
"data": [0, false],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "true is not equal to one",
|
||||||
|
"data": [1, true],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "unique array of objects is valid",
|
||||||
|
"data": [{"foo": "bar"}, {"foo": "baz"}],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "non-unique array of objects is valid",
|
||||||
|
"data": [{"foo": "bar"}, {"foo": "bar"}],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "unique array of nested objects is valid",
|
||||||
|
"data": [
|
||||||
|
{"foo": {"bar" : {"baz" : true}}},
|
||||||
|
{"foo": {"bar" : {"baz" : false}}}
|
||||||
|
],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "non-unique array of nested objects is valid",
|
||||||
|
"data": [
|
||||||
|
{"foo": {"bar" : {"baz" : true}}},
|
||||||
|
{"foo": {"bar" : {"baz" : true}}}
|
||||||
|
],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "unique array of arrays is valid",
|
||||||
|
"data": [["foo"], ["bar"]],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "non-unique array of arrays is valid",
|
||||||
|
"data": [["foo"], ["foo"]],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "1 and true are unique",
|
||||||
|
"data": [1, true],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "0 and false are unique",
|
||||||
|
"data": [0, false],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "unique heterogeneous types are valid",
|
||||||
|
"data": [{}, [1], true, null, 1],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "non-unique heterogeneous types are valid",
|
||||||
|
"data": [{}, [1], true, null, {}, 1],
|
||||||
|
"valid": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "uniqueItems=false with an array of items",
|
||||||
|
"schema": {
|
||||||
|
"items": [{"type": "boolean"}, {"type": "boolean"}],
|
||||||
|
"uniqueItems": false
|
||||||
|
},
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"description": "[false, true] from items array is valid",
|
||||||
|
"data": [false, true],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "[true, false] from items array is valid",
|
||||||
|
"data": [true, false],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "[false, false] from items array is valid",
|
||||||
|
"data": [false, false],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "[true, true] from items array is valid",
|
||||||
|
"data": [true, true],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "unique array extended from [false, true] is valid",
|
||||||
|
"data": [false, true, "foo", "bar"],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "unique array extended from [true, false] is valid",
|
||||||
|
"data": [true, false, "foo", "bar"],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "non-unique array extended from [false, true] is valid",
|
||||||
|
"data": [false, true, "foo", "foo"],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "non-unique array extended from [true, false] is valid",
|
||||||
|
"data": [true, false, "foo", "foo"],
|
||||||
|
"valid": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "uniqueItems=false with an array of items and additionalItems=false",
|
||||||
|
"schema": {
|
||||||
|
"items": [{"type": "boolean"}, {"type": "boolean"}],
|
||||||
|
"uniqueItems": false,
|
||||||
|
"additionalItems": false
|
||||||
|
},
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"description": "[false, true] from items array is valid",
|
||||||
|
"data": [false, true],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "[true, false] from items array is valid",
|
||||||
|
"data": [true, false],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "[false, false] from items array is valid",
|
||||||
|
"data": [false, false],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "[true, true] from items array is valid",
|
||||||
|
"data": [true, true],
|
||||||
|
"valid": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "extra items are invalid even if unique",
|
||||||
|
"data": [false, true, null],
|
||||||
|
"valid": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
@ -464,4 +464,26 @@ class WP_Test_REST_Schema_Sanitization extends WP_UnitTestCase {
|
|||||||
|
|
||||||
$this->assertNull( rest_sanitize_value_from_schema( array( 'Hello!' ), $schema ) );
|
$this->assertNull( rest_sanitize_value_from_schema( array( 'Hello!' ), $schema ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ticket 48821
|
||||||
|
*/
|
||||||
|
public function test_unique_items_after_sanitization() {
|
||||||
|
$schema = array(
|
||||||
|
'type' => 'array',
|
||||||
|
'uniqueItems' => true,
|
||||||
|
'items' => array(
|
||||||
|
'type' => 'string',
|
||||||
|
'format' => 'uri',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array(
|
||||||
|
'https://example.org/hello%20world',
|
||||||
|
'https://example.org/hello world',
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertTrue( rest_validate_value_from_schema( $data, $schema ) );
|
||||||
|
$this->assertWPError( rest_sanitize_value_from_schema( $data, $schema ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -507,7 +507,7 @@ class WP_Test_REST_Schema_Validation extends WP_UnitTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ticket 48818
|
* @ticket 48818
|
||||||
*
|
*
|
||||||
* @dataProvider data_required_property
|
* @dataProvider data_required_property
|
||||||
*/
|
*/
|
||||||
@ -535,7 +535,7 @@ class WP_Test_REST_Schema_Validation extends WP_UnitTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ticket 48818
|
* @ticket 48818
|
||||||
*
|
*
|
||||||
* @dataProvider data_required_property
|
* @dataProvider data_required_property
|
||||||
*/
|
*/
|
||||||
@ -577,7 +577,7 @@ class WP_Test_REST_Schema_Validation extends WP_UnitTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ticket 48818
|
* @ticket 48818
|
||||||
*
|
*
|
||||||
* @dataProvider data_required_nested_property
|
* @dataProvider data_required_nested_property
|
||||||
*/
|
*/
|
||||||
@ -610,7 +610,7 @@ class WP_Test_REST_Schema_Validation extends WP_UnitTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ticket 48818
|
* @ticket 48818
|
||||||
*
|
*
|
||||||
* @dataProvider data_required_nested_property
|
* @dataProvider data_required_nested_property
|
||||||
*/
|
*/
|
||||||
@ -669,7 +669,7 @@ class WP_Test_REST_Schema_Validation extends WP_UnitTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ticket 48818
|
* @ticket 48818
|
||||||
*
|
*
|
||||||
* @dataProvider data_required_deeply_nested_property
|
* @dataProvider data_required_deeply_nested_property
|
||||||
*/
|
*/
|
||||||
@ -709,7 +709,7 @@ class WP_Test_REST_Schema_Validation extends WP_UnitTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ticket 48818
|
* @ticket 48818
|
||||||
*
|
*
|
||||||
* @dataProvider data_required_deeply_nested_property
|
* @dataProvider data_required_deeply_nested_property
|
||||||
*/
|
*/
|
||||||
@ -749,7 +749,7 @@ class WP_Test_REST_Schema_Validation extends WP_UnitTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ticket 48818
|
* @ticket 48818
|
||||||
*
|
*
|
||||||
* @dataProvider data_required_deeply_nested_property
|
* @dataProvider data_required_deeply_nested_property
|
||||||
*/
|
*/
|
||||||
@ -905,4 +905,139 @@ class WP_Test_REST_Schema_Validation extends WP_UnitTestCase {
|
|||||||
$this->assertWPError( rest_validate_value_from_schema( array( 1, 2, 3 ), $schema ) );
|
$this->assertWPError( rest_validate_value_from_schema( array( 1, 2, 3 ), $schema ) );
|
||||||
$this->assertWPError( rest_validate_value_from_schema( 'foobar', $schema ) );
|
$this->assertWPError( rest_validate_value_from_schema( 'foobar', $schema ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ticket 48821
|
||||||
|
*
|
||||||
|
* @dataProvider data_unique_items
|
||||||
|
*/
|
||||||
|
public function test_unique_items( $test, $suite ) {
|
||||||
|
$test_description = $suite['description'] . ': ' . $test['description'];
|
||||||
|
$message = $test_description . ': ' . var_export( $test['data'], true );
|
||||||
|
|
||||||
|
$valid = rest_validate_value_from_schema( $test['data'], $suite['schema'] );
|
||||||
|
|
||||||
|
if ( $test['valid'] ) {
|
||||||
|
$this->assertTrue( $valid, $message );
|
||||||
|
} else {
|
||||||
|
$this->assertWPError( $valid, $message );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function data_unique_items() {
|
||||||
|
$all_types = array( 'object', 'array', 'null', 'number', 'integer', 'boolean', 'string' );
|
||||||
|
|
||||||
|
// the following test suites is not supported at the moment
|
||||||
|
$skip = array(
|
||||||
|
'uniqueItems with an array of items',
|
||||||
|
'uniqueItems with an array of items and additionalItems=false',
|
||||||
|
'uniqueItems=false with an array of items',
|
||||||
|
'uniqueItems=false with an array of items and additionalItems=false',
|
||||||
|
);
|
||||||
|
$suites = json_decode( file_get_contents( __DIR__ . '/json_schema_test_suite/uniqueitems.json' ), true );
|
||||||
|
|
||||||
|
$tests = array();
|
||||||
|
|
||||||
|
foreach ( $suites as $suite ) {
|
||||||
|
if ( in_array( $suite['description'], $skip, true ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// type is required for our implementation
|
||||||
|
if ( ! isset( $suite['schema']['type'] ) ) {
|
||||||
|
$suite['schema']['type'] = 'array';
|
||||||
|
}
|
||||||
|
// items is required for our implementation
|
||||||
|
if ( ! isset( $suite['schema']['items'] ) ) {
|
||||||
|
$suite['schema']['items'] = array(
|
||||||
|
'type' => $all_types,
|
||||||
|
'items' => array(
|
||||||
|
'type' => $all_types,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
foreach ( $suite['tests'] as $test ) {
|
||||||
|
$tests[] = array( $test, $suite );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $tests;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ticket 48821
|
||||||
|
*/
|
||||||
|
public function test_unique_items_deep_objects() {
|
||||||
|
$schema = array(
|
||||||
|
'type' => 'array',
|
||||||
|
'uniqueItems' => true,
|
||||||
|
'items' => array(
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'release' => array(
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'name' => array(
|
||||||
|
'type' => 'string',
|
||||||
|
),
|
||||||
|
'version' => array(
|
||||||
|
'type' => 'string',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array(
|
||||||
|
array(
|
||||||
|
'release' => array(
|
||||||
|
'name' => 'Kirk',
|
||||||
|
'version' => '5.3',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'release' => array(
|
||||||
|
'version' => '5.3',
|
||||||
|
'name' => 'Kirk',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertWPError( rest_validate_value_from_schema( $data, $schema ) );
|
||||||
|
|
||||||
|
$data[0]['release']['version'] = '5.3.0';
|
||||||
|
$this->assertTrue( rest_validate_value_from_schema( $data, $schema ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ticket 48821
|
||||||
|
*/
|
||||||
|
public function test_unique_items_deep_arrays() {
|
||||||
|
$schema = array(
|
||||||
|
'type' => 'array',
|
||||||
|
'uniqueItems' => true,
|
||||||
|
'items' => array(
|
||||||
|
'type' => 'array',
|
||||||
|
'items' => array(
|
||||||
|
'type' => 'string',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array(
|
||||||
|
array(
|
||||||
|
'Kirk',
|
||||||
|
'Jaco',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'Kirk',
|
||||||
|
'Jaco',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertWPError( rest_validate_value_from_schema( $data, $schema ) );
|
||||||
|
|
||||||
|
$data[1] = array_reverse( $data[1] );
|
||||||
|
$this->assertTrue( rest_validate_value_from_schema( $data, $schema ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user