Make WordPress Core


Ignore:
Timestamp:
10/20/2020 06:22:39 PM (6 years ago)
Author:
TimothyBlynJacobs
Message:

REST API: Add support for the oneOf and anyOf keywords.

This allows for REST API routes to define more complex validation requirements as JSON Schema instead of procedural validation.

The error code returned from rest_validate_value_from_schema for invalid parameter types has been changed from the generic rest_invalid_param to the more specific rest_invalid_type.

Props yakimun, johnbillion, TimothyBlynJacobs.
Fixes #51025.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/rest-api.php

    r49082 r49246  
    10861086        public function _dp_rest_filter_response_by_context() {
    10871087                return array(
    1088                         'default'                             => array(
     1088                        'default'                                      => array(
    10891089                                array(
    10901090                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
    … …  
    11071107                                array( 'first' => 'a' ),
    11081108                        ),
    1109                         'keeps missing context'               => array(
     1109                        'keeps missing context'                        => array(
    11101110                                array(
    11111111                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
    … …  
    11301130                                ),
    11311131                        ),
    1132                         'removes empty context'               => array(
     1132                        'removes empty context'                        => array(
    11331133                                array(
    11341134                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
    … …  
    11511151                                array( 'first' => 'a' ),
    11521152                        ),
    1153                         'nested properties'                   => array(
     1153                        'nested properties'                            => array(
    11541154                                array(
    11551155                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
    … …  
    11801180                                array( 'parent' => array( 'child' => 'hi' ) ),
    11811181                        ),
    1182                         'grand child properties'              => array(
     1182                        'grand child properties'                       => array(
    11831183                                array(
    11841184                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
    … …  
    12161216                                array( 'parent' => array( 'child' => array( 'grand' => 'hi' ) ) ),
    12171217                        ),
    1218                         'array'                               => array(
     1218                        'array'                                        => array(
    12191219                                array(
    12201220                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
    … …  
    12511251                                array( 'arr' => array( array( 'visible' => 'hi' ) ) ),
    12521252                        ),
    1253                         'additional properties'               => array(
     1253                        'additional properties'                        => array(
    12541254                                array(
    12551255                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
    … …  
    12851285                                array( 'additional' => array( 'a' => '1' ) ),
    12861286                        ),
    1287                         'pattern properties'                  => array(
     1287                        'pattern properties'                           => array(
    12881288                                array(
    12891289                                        '$schema'              => 'http://json-schema.org/draft-04/schema#',
    … …  
    13211321                                ),
    13221322                        ),
    1323                         'multiple types object'               => array(
     1323                        'multiple types object'                        => array(
    13241324                                array(
    13251325                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
    … …  
    13501350                                array( 'multi' => array( 'a' => '1' ) ),
    13511351                        ),
    1352                         'multiple types array'                => array(
     1352                        'multiple types array'                         => array(
    13531353                                array(
    13541354                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
    … …  
    13851385                                array( 'multi' => array( array( 'visible' => '1' ) ) ),
    13861386                        ),
    1387                         'does not traverse missing context'   => array(
     1387                        'does not traverse missing context'            => array(
    13881388                                array(
    13891389                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
    … …  
    14281428                                ),
    14291429                        ),
    1430                         'object with no matching properties'  => array(
     1430                        'object with no matching properties'           => array(
    14311431                                array(
    14321432                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
    … …  
    14491449                                array(),
    14501450                        ),
    1451                         'array whose type does not match'     => array(
     1451                        'array whose type does not match'              => array(
    14521452                                array(
    14531453                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
    … …  
    14691469                                array( 'arr' => array() ),
    14701470                        ),
    1471                         'array and object type passed object' => array(
     1471                        'array and object type passed object'          => array(
    14721472                                array(
    14731473                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
    … …  
    15071507                                ),
    15081508                        ),
    1509                         'array and object type passed array'  => array(
     1509                        'array and object type passed array'           => array(
    15101510                                array(
    15111511                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
    … …  
    15481548                                array(),
    15491549                        ),
     1550                        'anyOf applies the correct schema'             => array(
     1551                                array(
     1552                                        '$schema' => 'http://json-schema.org/draft-04/schema#',
     1553                                        'type'    => 'object',
     1554                                        'anyOf'   => array(
     1555                                                array(
     1556                                                        'properties' => array(
     1557                                                                'a' => array(
     1558                                                                        'type'    => 'string',
     1559                                                                        'context' => array( 'view' ),
     1560                                                                ),
     1561                                                                'b' => array(
     1562                                                                        'type'    => 'string',
     1563                                                                        'context' => array( 'edit' ),
     1564                                                                ),
     1565                                                        ),
     1566                                                ),
     1567                                                array(
     1568                                                        'properties' => array(
     1569                                                                'a' => array(
     1570                                                                        'type'    => 'integer',
     1571                                                                        'context' => array( 'edit' ),
     1572                                                                ),
     1573                                                                'b' => array(
     1574                                                                        'type'    => 'integer',
     1575                                                                        'context' => array( 'view' ),
     1576                                                                ),
     1577                                                        ),
     1578                                                ),
     1579                                        ),
     1580                                ),
     1581                                array(
     1582                                        'a' => 1,
     1583                                        'b' => 2,
     1584                                ),
     1585                                array(
     1586                                        'b' => 2,
     1587                                ),
     1588                        ),
     1589                        'anyOf is ignored if no valid schema is found' => array(
     1590                                array(
     1591                                        '$schema' => 'http://json-schema.org/draft-04/schema#',
     1592                                        'type'    => 'object',
     1593                                        'anyOf'   => array(
     1594                                                array(
     1595                                                        'properties' => array(
     1596                                                                'a' => array(
     1597                                                                        'type'    => 'string',
     1598                                                                        'context' => array( 'view' ),
     1599                                                                ),
     1600                                                                'b' => array(
     1601                                                                        'type'    => 'string',
     1602                                                                        'context' => array( 'edit' ),
     1603                                                                ),
     1604                                                        ),
     1605                                                ),
     1606                                                array(
     1607                                                        'properties' => array(
     1608                                                                'a' => array(
     1609                                                                        'type'    => 'integer',
     1610                                                                        'context' => array( 'edit' ),
     1611                                                                ),
     1612                                                                'b' => array(
     1613                                                                        'type'    => 'integer',
     1614                                                                        'context' => array( 'view' ),
     1615                                                                ),
     1616                                                        ),
     1617                                                ),
     1618                                        ),
     1619                                ),
     1620                                array(
     1621                                        'a' => true,
     1622                                        'b' => false,
     1623                                ),
     1624                                array(
     1625                                        'a' => true,
     1626                                        'b' => false,
     1627                                ),
     1628                        ),
     1629                        'oneOf applies the correct schema'             => array(
     1630                                array(
     1631                                        '$schema' => 'http://json-schema.org/draft-04/schema#',
     1632                                        'type'    => 'object',
     1633                                        'oneOf'   => array(
     1634                                                array(
     1635                                                        'properties' => array(
     1636                                                                'a' => array(
     1637                                                                        'type'    => 'string',
     1638                                                                        'context' => array( 'view' ),
     1639                                                                ),
     1640                                                                'b' => array(
     1641                                                                        'type'    => 'string',
     1642                                                                        'context' => array( 'edit' ),
     1643                                                                ),
     1644                                                        ),
     1645                                                ),
     1646                                                array(
     1647                                                        'properties' => array(
     1648                                                                'a' => array(
     1649                                                                        'type'    => 'integer',
     1650                                                                        'context' => array( 'edit' ),
     1651                                                                ),
     1652                                                                'b' => array(
     1653                                                                        'type'    => 'integer',
     1654                                                                        'context' => array( 'view' ),
     1655                                                                ),
     1656                                                        ),
     1657                                                ),
     1658                                        ),
     1659                                ),
     1660                                array(
     1661                                        'a' => 1,
     1662                                        'b' => 2,
     1663                                ),
     1664                                array(
     1665                                        'b' => 2,
     1666                                ),
     1667                        ),
     1668                        'oneOf ignored if no valid schema was found'   => array(
     1669                                array(
     1670                                        '$schema' => 'http://json-schema.org/draft-04/schema#',
     1671                                        'type'    => 'object',
     1672                                        'anyOf'   => array(
     1673                                                array(
     1674                                                        'properties' => array(
     1675                                                                'a' => array(
     1676                                                                        'type'    => 'string',
     1677                                                                        'context' => array( 'view' ),
     1678                                                                ),
     1679                                                                'b' => array(
     1680                                                                        'type'    => 'string',
     1681                                                                        'context' => array( 'edit' ),
     1682                                                                ),
     1683                                                        ),
     1684                                                ),
     1685                                                array(
     1686                                                        'properties' => array(
     1687                                                                'a' => array(
     1688                                                                        'type'    => 'integer',
     1689                                                                        'context' => array( 'edit' ),
     1690                                                                ),
     1691                                                                'b' => array(
     1692                                                                        'type'    => 'integer',
     1693                                                                        'context' => array( 'view' ),
     1694                                                                ),
     1695                                                        ),
     1696                                                ),
     1697                                        ),
     1698                                ),
     1699                                array(
     1700                                        'a' => true,
     1701                                        'b' => false,
     1702                                ),
     1703                                array(
     1704                                        'a' => true,
     1705                                        'b' => false,
     1706                                ),
     1707                        ),
     1708                        'oneOf combined with base'                     => array(
     1709                                array(
     1710                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
     1711                                        'type'       => 'object',
     1712                                        'properties' => array(
     1713                                                'c' => array(
     1714                                                        'type'    => 'integer',
     1715                                                        'context' => array( 'edit' ),
     1716                                                ),
     1717                                        ),
     1718                                        'oneOf'      => array(
     1719                                                array(
     1720                                                        'properties' => array(
     1721                                                                'a' => array(
     1722                                                                        'type'    => 'string',
     1723                                                                        'context' => array( 'view' ),
     1724                                                                ),
     1725                                                                'b' => array(
     1726                                                                        'type'    => 'string',
     1727                                                                        'context' => array( 'edit' ),
     1728                                                                ),
     1729                                                        ),
     1730                                                ),
     1731                                                array(
     1732                                                        'properties' => array(
     1733                                                                'a' => array(
     1734                                                                        'type'    => 'integer',
     1735                                                                        'context' => array( 'edit' ),
     1736                                                                ),
     1737                                                                'b' => array(
     1738                                                                        'type'    => 'integer',
     1739                                                                        'context' => array( 'view' ),
     1740                                                                ),
     1741                                                        ),
     1742                                                ),
     1743                                        ),
     1744                                ),
     1745                                array(
     1746                                        'a' => 1,
     1747                                        'b' => 2,
     1748                                        'c' => 3,
     1749                                ),
     1750                                array(
     1751                                        'b' => 2,
     1752                                ),
     1753                        ),
    15501754                );
    15511755        }
Note: See TracChangeset for help on using the changeset viewer.