mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2026-08-12 12:50:28 +00:00
REST API: Support type coercion when validating the enum JSON Schema keyword.
Previously, the `enum` keyword was validated by perform a strict equality check. For `string` types this is generally ok, but it prevented using alternative types like `number` when rich type support isn't available. Now the same level of type coercion/sanitization is applied when validating `enum` as all other validation checks. This means that a value of `"1"` will be accepted for an `enum` of `[ 0, 1 ]`. Additionally, `object` types now properly ignore key order when checking for equality. Props yakimun. Fixes #51911. git-svn-id: https://develop.svn.wordpress.org/trunk@50010 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
@@ -248,6 +248,512 @@ class WP_Test_REST_Schema_Validation extends WP_UnitTestCase {
|
||||
$this->assertTrue( rest_validate_value_from_schema( '', $schema ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 51911
|
||||
*
|
||||
* @dataProvider data_different_types_of_value_and_enum_elements
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param array $args
|
||||
* @param bool $expected
|
||||
*/
|
||||
public function test_different_types_of_value_and_enum_elements( $value, $args, $expected ) {
|
||||
$result = rest_validate_value_from_schema( $value, $args );
|
||||
if ( $expected ) {
|
||||
$this->assertTrue( $result );
|
||||
} else {
|
||||
$this->assertWPError( $result );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function data_different_types_of_value_and_enum_elements() {
|
||||
return array(
|
||||
// enum with integers
|
||||
array(
|
||||
0,
|
||||
array(
|
||||
'type' => 'integer',
|
||||
'enum' => array( 0, 1 ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
0.0,
|
||||
array(
|
||||
'type' => 'integer',
|
||||
'enum' => array( 0, 1 ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
'0',
|
||||
array(
|
||||
'type' => 'integer',
|
||||
'enum' => array( 0, 1 ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
1,
|
||||
array(
|
||||
'type' => 'integer',
|
||||
'enum' => array( 0, 1 ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
1.0,
|
||||
array(
|
||||
'type' => 'integer',
|
||||
'enum' => array( 0, 1 ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
'1',
|
||||
array(
|
||||
'type' => 'integer',
|
||||
'enum' => array( 0, 1 ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
2,
|
||||
array(
|
||||
'type' => 'integer',
|
||||
'enum' => array( 0, 1 ),
|
||||
),
|
||||
false,
|
||||
),
|
||||
array(
|
||||
2.0,
|
||||
array(
|
||||
'type' => 'integer',
|
||||
'enum' => array( 0, 1 ),
|
||||
),
|
||||
false,
|
||||
),
|
||||
array(
|
||||
'2',
|
||||
array(
|
||||
'type' => 'integer',
|
||||
'enum' => array( 0, 1 ),
|
||||
),
|
||||
false,
|
||||
),
|
||||
|
||||
// enum with floats
|
||||
array(
|
||||
0,
|
||||
array(
|
||||
'type' => 'number',
|
||||
'enum' => array( 0.0, 1.0 ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
0.0,
|
||||
array(
|
||||
'type' => 'number',
|
||||
'enum' => array( 0.0, 1.0 ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
'0',
|
||||
array(
|
||||
'type' => 'number',
|
||||
'enum' => array( 0.0, 1.0 ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
1,
|
||||
array(
|
||||
'type' => 'number',
|
||||
'enum' => array( 0.0, 1.0 ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
1.0,
|
||||
array(
|
||||
'type' => 'number',
|
||||
'enum' => array( 0.0, 1.0 ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
'1',
|
||||
array(
|
||||
'type' => 'number',
|
||||
'enum' => array( 0.0, 1.0 ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
2,
|
||||
array(
|
||||
'type' => 'number',
|
||||
'enum' => array( 0.0, 1.0 ),
|
||||
),
|
||||
false,
|
||||
),
|
||||
array(
|
||||
2.0,
|
||||
array(
|
||||
'type' => 'number',
|
||||
'enum' => array( 0.0, 1.0 ),
|
||||
),
|
||||
false,
|
||||
),
|
||||
array(
|
||||
'2',
|
||||
array(
|
||||
'type' => 'number',
|
||||
'enum' => array( 0.0, 1.0 ),
|
||||
),
|
||||
false,
|
||||
),
|
||||
|
||||
// enum with booleans
|
||||
array(
|
||||
true,
|
||||
array(
|
||||
'type' => 'boolean',
|
||||
'enum' => array( true ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
1,
|
||||
array(
|
||||
'type' => 'boolean',
|
||||
'enum' => array( true ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
'true',
|
||||
array(
|
||||
'type' => 'boolean',
|
||||
'enum' => array( true ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
false,
|
||||
array(
|
||||
'type' => 'boolean',
|
||||
'enum' => array( true ),
|
||||
),
|
||||
false,
|
||||
),
|
||||
array(
|
||||
0,
|
||||
array(
|
||||
'type' => 'boolean',
|
||||
'enum' => array( true ),
|
||||
),
|
||||
false,
|
||||
),
|
||||
array(
|
||||
'false',
|
||||
array(
|
||||
'type' => 'boolean',
|
||||
'enum' => array( true ),
|
||||
),
|
||||
false,
|
||||
),
|
||||
array(
|
||||
false,
|
||||
array(
|
||||
'type' => 'boolean',
|
||||
'enum' => array( false ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
0,
|
||||
array(
|
||||
'type' => 'boolean',
|
||||
'enum' => array( false ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
'false',
|
||||
array(
|
||||
'type' => 'boolean',
|
||||
'enum' => array( false ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
true,
|
||||
array(
|
||||
'type' => 'boolean',
|
||||
'enum' => array( false ),
|
||||
),
|
||||
false,
|
||||
),
|
||||
array(
|
||||
1,
|
||||
array(
|
||||
'type' => 'boolean',
|
||||
'enum' => array( false ),
|
||||
),
|
||||
false,
|
||||
),
|
||||
array(
|
||||
'true',
|
||||
array(
|
||||
'type' => 'boolean',
|
||||
'enum' => array( false ),
|
||||
),
|
||||
false,
|
||||
),
|
||||
|
||||
// enum with arrays
|
||||
array(
|
||||
array( 0, 1 ),
|
||||
array(
|
||||
'type' => 'array',
|
||||
'items' => array( 'type' => 'integer' ),
|
||||
'enum' => array( array( 0, 1 ), array( 1, 2 ) ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
array( '0', 1 ),
|
||||
array(
|
||||
'type' => 'array',
|
||||
'items' => array( 'type' => 'integer' ),
|
||||
'enum' => array( array( 0, 1 ), array( 1, 2 ) ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
array( 0, '1' ),
|
||||
array(
|
||||
'type' => 'array',
|
||||
'items' => array( 'type' => 'integer' ),
|
||||
'enum' => array( array( 0, 1 ), array( 1, 2 ) ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
array( '0', '1' ),
|
||||
array(
|
||||
'type' => 'array',
|
||||
'items' => array( 'type' => 'integer' ),
|
||||
'enum' => array( array( 0, 1 ), array( 1, 2 ) ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
array( 1, 2 ),
|
||||
array(
|
||||
'type' => 'array',
|
||||
'items' => array( 'type' => 'integer' ),
|
||||
'enum' => array( array( 0, 1 ), array( 1, 2 ) ),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
array( 2, 3 ),
|
||||
array(
|
||||
'type' => 'array',
|
||||
'items' => array( 'type' => 'integer' ),
|
||||
'enum' => array( array( 0, 1 ), array( 1, 2 ) ),
|
||||
),
|
||||
false,
|
||||
),
|
||||
array(
|
||||
array( 1, 0 ),
|
||||
array(
|
||||
'type' => 'array',
|
||||
'items' => array( 'type' => 'integer' ),
|
||||
'enum' => array( array( 0, 1 ), array( 1, 2 ) ),
|
||||
),
|
||||
false,
|
||||
),
|
||||
|
||||
// enum with objects
|
||||
array(
|
||||
array(
|
||||
'a' => 1,
|
||||
'b' => 2,
|
||||
),
|
||||
array(
|
||||
'type' => 'object',
|
||||
'additionalProperties' => array( 'type' => 'integer' ),
|
||||
'enum' => array(
|
||||
array(
|
||||
'a' => 1,
|
||||
'b' => 2,
|
||||
),
|
||||
array(
|
||||
'b' => 2,
|
||||
'c' => 3,
|
||||
),
|
||||
),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'a' => '1',
|
||||
'b' => 2,
|
||||
),
|
||||
array(
|
||||
'type' => 'object',
|
||||
'additionalProperties' => array( 'type' => 'integer' ),
|
||||
'enum' => array(
|
||||
array(
|
||||
'a' => 1,
|
||||
'b' => 2,
|
||||
),
|
||||
array(
|
||||
'b' => 2,
|
||||
'c' => 3,
|
||||
),
|
||||
),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'a' => 1,
|
||||
'b' => '2',
|
||||
),
|
||||
array(
|
||||
'type' => 'object',
|
||||
'additionalProperties' => array( 'type' => 'integer' ),
|
||||
'enum' => array(
|
||||
array(
|
||||
'a' => 1,
|
||||
'b' => 2,
|
||||
),
|
||||
array(
|
||||
'b' => 2,
|
||||
'c' => 3,
|
||||
),
|
||||
),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'a' => '1',
|
||||
'b' => '2',
|
||||
),
|
||||
array(
|
||||
'type' => 'object',
|
||||
'additionalProperties' => array( 'type' => 'integer' ),
|
||||
'enum' => array(
|
||||
array(
|
||||
'a' => 1,
|
||||
'b' => 2,
|
||||
),
|
||||
array(
|
||||
'b' => 2,
|
||||
'c' => 3,
|
||||
),
|
||||
),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'b' => 2,
|
||||
'a' => 1,
|
||||
),
|
||||
array(
|
||||
'type' => 'object',
|
||||
'additionalProperties' => array( 'type' => 'integer' ),
|
||||
'enum' => array(
|
||||
array(
|
||||
'a' => 1,
|
||||
'b' => 2,
|
||||
),
|
||||
array(
|
||||
'b' => 2,
|
||||
'c' => 3,
|
||||
),
|
||||
),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'b' => 2,
|
||||
'c' => 3,
|
||||
),
|
||||
array(
|
||||
'type' => 'object',
|
||||
'additionalProperties' => array( 'type' => 'integer' ),
|
||||
'enum' => array(
|
||||
array(
|
||||
'a' => 1,
|
||||
'b' => 2,
|
||||
),
|
||||
array(
|
||||
'b' => 2,
|
||||
'c' => 3,
|
||||
),
|
||||
),
|
||||
),
|
||||
true,
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'a' => 1,
|
||||
'b' => 3,
|
||||
),
|
||||
array(
|
||||
'type' => 'object',
|
||||
'additionalProperties' => array( 'type' => 'integer' ),
|
||||
'enum' => array(
|
||||
array(
|
||||
'a' => 1,
|
||||
'b' => 2,
|
||||
),
|
||||
array(
|
||||
'b' => 2,
|
||||
'c' => 3,
|
||||
),
|
||||
),
|
||||
),
|
||||
false,
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'c' => 3,
|
||||
'd' => 4,
|
||||
),
|
||||
array(
|
||||
'type' => 'object',
|
||||
'additionalProperties' => array( 'type' => 'integer' ),
|
||||
'enum' => array(
|
||||
array(
|
||||
'a' => 1,
|
||||
'b' => 2,
|
||||
),
|
||||
array(
|
||||
'b' => 2,
|
||||
'c' => 3,
|
||||
),
|
||||
),
|
||||
),
|
||||
false,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public function test_type_array_is_associative() {
|
||||
$schema = array(
|
||||
'type' => 'array',
|
||||
|
||||
Reference in New Issue
Block a user