Changeset 49246
- Timestamp:
- 10/20/2020 06:22:39 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/rest-api.php
r49225 r49246 1666 1666 1667 1667 /** 1668 * Formats a combining operation error into a WP_Error object. 1669 * 1670 * @since 5.6.0 1671 * 1672 * @param string $param The parameter name. 1673 * @param array $error The error details. 1674 * @return WP_Error 1675 */ 1676 function rest_format_combining_operation_error( $param, $error ) { 1677 $position = $error['index']; 1678 $reason = $error['error_object']->get_error_message(); 1679 1680 if ( isset( $error['schema']['title'] ) ) { 1681 $title = $error['schema']['title']; 1682 1683 return new WP_Error( 1684 'rest_invalid_param', 1685 /* translators: 1: Parameter, 2: Schema title, 3: Reason. */ 1686 sprintf( __( '%1$s is not a valid %2$s. Reason: %3$s' ), $param, $title, $reason ), 1687 array( 'position' => $position ) 1688 ); 1689 } 1690 1691 return new WP_Error( 1692 'rest_invalid_param', 1693 /* translators: 1: Parameter, 2: Reason. */ 1694 sprintf( __( '%1$s does not match the expected format. Reason: %2$s' ), $param, $reason ), 1695 array( 'position' => $position ) 1696 ); 1697 } 1698 1699 /** 1700 * Gets the error of combining operation. 1701 * 1702 * @since 5.6.0 1703 * 1704 * @param array $value The value to validate. 1705 * @param string $param The parameter name, used in error messages. 1706 * @param array $errors The errors array, to search for possible error. 1707 * @return WP_Error The combining operation error. 1708 */ 1709 function rest_get_combining_operation_error( $value, $param, $errors ) { 1710 // If there is only one error, simply return it. 1711 if ( 1 === count( $errors ) ) { 1712 return rest_format_combining_operation_error( $param, $errors[0] ); 1713 } 1714 1715 // Filter out all errors related to type validation. 1716 $filtered_errors = array(); 1717 foreach ( $errors as $error ) { 1718 $error_code = $error['error_object']->get_error_code(); 1719 $error_data = $error['error_object']->get_error_data(); 1720 1721 if ( 'rest_invalid_type' !== $error_code || ( isset( $error_data['param'] ) && $param !== $error_data['param'] ) ) { 1722 $filtered_errors[] = $error; 1723 } 1724 } 1725 1726 // If there is only one error left, simply return it. 1727 if ( 1 === count( $filtered_errors ) ) { 1728 return rest_format_combining_operation_error( $param, $filtered_errors[0] ); 1729 } 1730 1731 // If there are only errors related to object validation, try choosing the most appropriate one. 1732 if ( count( $filtered_errors ) > 1 && 'object' === $filtered_errors[0]['schema']['type'] ) { 1733 $result = null; 1734 $number = 0; 1735 1736 foreach ( $filtered_errors as $error ) { 1737 if ( isset( $error['schema']['properties'] ) ) { 1738 $n = count( array_intersect_key( $error['schema']['properties'], $value ) ); 1739 if ( $n > $number ) { 1740 $result = $error; 1741 $number = $n; 1742 } 1743 } 1744 } 1745 1746 if ( null !== $result ) { 1747 return rest_format_combining_operation_error( $param, $result ); 1748 } 1749 } 1750 1751 // If each schema has a title, include those titles in the error message. 1752 $schema_titles = array(); 1753 foreach ( $errors as $error ) { 1754 if ( isset( $error['schema']['title'] ) ) { 1755 $schema_titles[] = $error['schema']['title']; 1756 } 1757 } 1758 1759 if ( count( $schema_titles ) === count( $errors ) ) { 1760 /* translators: 1: Parameter, 2: Schema titles. */ 1761 return new WP_Error( 'rest_invalid_param', wp_sprintf( __( '%1$s is not a valid %2$l.' ), $param, $schema_titles ) ); 1762 } 1763 1764 /* translators: 1: Parameter. */ 1765 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s does not match any of the expected formats.' ), $param ) ); 1766 } 1767 1768 /** 1769 * Finds the matching schema among the "anyOf" schemas. 1770 * 1771 * @since 5.6.0 1772 * 1773 * @param mixed $value The value to validate. 1774 * @param array $args The schema array to use. 1775 * @param string $param The parameter name, used in error messages. 1776 * @return array|WP_Error The matching schema or WP_Error instance if all schemas do not match. 1777 */ 1778 function rest_find_any_matching_schema( $value, $args, $param ) { 1779 $errors = array(); 1780 1781 foreach ( $args['anyOf'] as $index => $schema ) { 1782 if ( ! isset( $schema['type'] ) && isset( $args['type'] ) ) { 1783 $schema['type'] = $args['type']; 1784 } 1785 1786 $is_valid = rest_validate_value_from_schema( $value, $schema, $param ); 1787 if ( ! is_wp_error( $is_valid ) ) { 1788 return $schema; 1789 } 1790 1791 $errors[] = array( 1792 'error_object' => $is_valid, 1793 'schema' => $schema, 1794 'index' => $index, 1795 ); 1796 } 1797 1798 return rest_get_combining_operation_error( $value, $param, $errors ); 1799 } 1800 1801 /** 1802 * Finds the matching schema among the "oneOf" schemas. 1803 * 1804 * @since 5.6.0 1805 * 1806 * @param mixed $value The value to validate. 1807 * @param array $args The schema array to use. 1808 * @param string $param The parameter name, used in error messages. 1809 * @param bool $stop_after_first_match Optional. Whether the process should stop after the first successful match. 1810 * @return array|WP_Error The matching schema or WP_Error instance if the number of matching schemas is not equal to one. 1811 */ 1812 function rest_find_one_matching_schema( $value, $args, $param, $stop_after_first_match = false ) { 1813 $matching_schemas = array(); 1814 $errors = array(); 1815 1816 foreach ( $args['oneOf'] as $index => $schema ) { 1817 if ( ! isset( $schema['type'] ) && isset( $args['type'] ) ) { 1818 $schema['type'] = $args['type']; 1819 } 1820 1821 $is_valid = rest_validate_value_from_schema( $value, $schema, $param ); 1822 if ( ! is_wp_error( $is_valid ) ) { 1823 if ( $stop_after_first_match ) { 1824 return $schema; 1825 } 1826 1827 $matching_schemas[] = array( 1828 'schema_object' => $schema, 1829 'index' => $index, 1830 ); 1831 } else { 1832 $errors[] = array( 1833 'error_object' => $is_valid, 1834 'schema' => $schema, 1835 'index' => $index, 1836 ); 1837 } 1838 } 1839 1840 if ( ! $matching_schemas ) { 1841 return rest_get_combining_operation_error( $value, $param, $errors ); 1842 } 1843 1844 if ( count( $matching_schemas ) > 1 ) { 1845 $schema_positions = array(); 1846 $schema_titles = array(); 1847 1848 foreach ( $matching_schemas as $schema ) { 1849 $schema_positions[] = $schema['index']; 1850 1851 if ( isset( $schema['schema_object']['title'] ) ) { 1852 $schema_titles[] = $schema['schema_object']['title']; 1853 } 1854 } 1855 1856 // If each schema has a title, include those titles in the error message. 1857 if ( count( $schema_titles ) === count( $matching_schemas ) ) { 1858 return new WP_Error( 1859 'rest_invalid_param', 1860 /* translators: 1: Parameter, 2: Schema titles. */ 1861 wp_sprintf( __( '%1$s matches %2$l, but should match only one.' ), $param, $schema_titles ), 1862 array( 'positions' => $schema_positions ) 1863 ); 1864 } 1865 1866 return new WP_Error( 1867 'rest_invalid_param', 1868 /* translators: 1: Parameter. */ 1869 sprintf( __( '%1$s matches more than one of the expected formats.' ), $param ), 1870 array( 'positions' => $schema_positions ) 1871 ); 1872 } 1873 1874 return $matching_schemas[0]['schema_object']; 1875 } 1876 1877 /** 1668 1878 * Validate a value based on a schema. 1669 1879 * … … 1680 1890 * Support the "multipleOf" keyword for numbers and integers. 1681 1891 * Support the "patternProperties" keyword for objects. 1892 * Support the "anyOf" and "oneOf" keywords. 1682 1893 * 1683 1894 * @param mixed $value The value to validate. … … 1687 1898 */ 1688 1899 function rest_validate_value_from_schema( $value, $args, $param = '' ) { 1900 if ( isset( $args['anyOf'] ) ) { 1901 $matching_schema = rest_find_any_matching_schema( $value, $args, $param ); 1902 if ( is_wp_error( $matching_schema ) ) { 1903 return $matching_schema; 1904 } 1905 1906 if ( ! isset( $args['type'] ) && isset( $matching_schema['type'] ) ) { 1907 $args['type'] = $matching_schema['type']; 1908 } 1909 } 1910 1911 if ( isset( $args['oneOf'] ) ) { 1912 $matching_schema = rest_find_one_matching_schema( $value, $args, $param ); 1913 if ( is_wp_error( $matching_schema ) ) { 1914 return $matching_schema; 1915 } 1916 1917 if ( ! isset( $args['type'] ) && isset( $matching_schema['type'] ) ) { 1918 $args['type'] = $matching_schema['type']; 1919 } 1920 } 1921 1689 1922 $allowed_types = array( 'array', 'object', 'string', 'number', 'integer', 'boolean', 'null' ); 1690 1923 … … 1698 1931 1699 1932 if ( ! $best_type ) { 1700 /* translators: 1: Parameter, 2: List of types. */ 1701 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not of type %2$s.' ), $param, implode( ',', $args['type'] ) ) ); 1933 return new WP_Error( 1934 'rest_invalid_type', 1935 /* translators: 1: Parameter, 2: List of types. */ 1936 sprintf( __( '%1$s is not of type %2$s.' ), $param, implode( ',', $args['type'] ) ), 1937 array( 'param' => $param ) 1938 ); 1702 1939 } 1703 1940 … … 1716 1953 if ( 'array' === $args['type'] ) { 1717 1954 if ( ! rest_is_array( $value ) ) { 1718 /* translators: 1: Parameter, 2: Type name. */ 1719 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not of type %2$s.' ), $param, 'array' ) ); 1955 return new WP_Error( 1956 'rest_invalid_type', 1957 /* translators: 1: Parameter, 2: Type name. */ 1958 sprintf( __( '%1$s is not of type %2$s.' ), $param, 'array' ), 1959 array( 'param' => $param ) 1960 ); 1720 1961 } 1721 1962 … … 1749 1990 if ( 'object' === $args['type'] ) { 1750 1991 if ( ! rest_is_object( $value ) ) { 1751 /* translators: 1: Parameter, 2: Type name. */ 1752 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not of type %2$s.' ), $param, 'object' ) ); 1992 return new WP_Error( 1993 'rest_invalid_type', 1994 /* translators: 1: Parameter, 2: Type name. */ 1995 sprintf( __( '%1$s is not of type %2$s.' ), $param, 'object' ), 1996 array( 'param' => $param ) 1997 ); 1753 1998 } 1754 1999 … … 1817 2062 if ( 'null' === $args['type'] ) { 1818 2063 if ( null !== $value ) { 1819 /* translators: 1: Parameter, 2: Type name. */ 1820 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not of type %2$s.' ), $param, 'null' ) ); 2064 return new WP_Error( 2065 'rest_invalid_type', 2066 /* translators: 1: Parameter, 2: Type name. */ 2067 sprintf( __( '%1$s is not of type %2$s.' ), $param, 'null' ), 2068 array( 'param' => $param ) 2069 ); 1821 2070 } 1822 2071 … … 1833 2082 if ( in_array( $args['type'], array( 'integer', 'number' ), true ) ) { 1834 2083 if ( ! is_numeric( $value ) ) { 1835 /* translators: 1: Parameter, 2: Type name. */ 1836 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not of type %2$s.' ), $param, $args['type'] ) ); 2084 return new WP_Error( 2085 'rest_invalid_type', 2086 /* translators: 1: Parameter, 2: Type name. */ 2087 sprintf( __( '%1$s is not of type %2$s.' ), $param, $args['type'] ), 2088 array( 'param' => $param ) 2089 ); 1837 2090 } 1838 2091 … … 1844 2097 1845 2098 if ( 'integer' === $args['type'] && ! rest_is_integer( $value ) ) { 1846 /* translators: 1: Parameter, 2: Type name. */ 1847 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not of type %2$s.' ), $param, 'integer' ) ); 2099 return new WP_Error( 2100 'rest_invalid_type', 2101 /* translators: 1: Parameter, 2: Type name. */ 2102 sprintf( __( '%1$s is not of type %2$s.' ), $param, 'integer' ), 2103 array( 'param' => $param ) 2104 ); 1848 2105 } 1849 2106 1850 2107 if ( 'boolean' === $args['type'] && ! rest_is_boolean( $value ) ) { 1851 /* translators: 1: Parameter, 2: Type name. */ 1852 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not of type %2$s.' ), $param, 'boolean' ) ); 2108 return new WP_Error( 2109 'rest_invalid_type', 2110 /* translators: 1: Parameter, 2: Type name. */ 2111 sprintf( __( '%1$s is not of type %2$s.' ), $param, 'boolean' ), 2112 array( 'param' => $param ) 2113 ); 1853 2114 } 1854 2115 1855 2116 if ( 'string' === $args['type'] ) { 1856 2117 if ( ! is_string( $value ) ) { 1857 /* translators: 1: Parameter, 2: Type name. */ 1858 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not of type %2$s.' ), $param, 'string' ) ); 2118 return new WP_Error( 2119 'rest_invalid_type', 2120 /* translators: 1: Parameter, 2: Type name. */ 2121 sprintf( __( '%1$s is not of type %2$s.' ), $param, 'string' ), 2122 array( 'param' => $param ) 2123 ); 1859 2124 } 1860 2125 … … 1977 2242 * @since 4.7.0 1978 2243 * @since 5.5.0 Added the `$param` parameter. 2244 * @since 5.6.0 Support the "anyOf" and "oneOf" keywords. 1979 2245 * 1980 2246 * @param mixed $value The value to sanitize. … … 1984 2250 */ 1985 2251 function rest_sanitize_value_from_schema( $value, $args, $param = '' ) { 2252 if ( isset( $args['anyOf'] ) ) { 2253 $matching_schema = rest_find_any_matching_schema( $value, $args, $param ); 2254 if ( is_wp_error( $matching_schema ) ) { 2255 return $matching_schema; 2256 } 2257 2258 if ( ! isset( $args['type'] ) ) { 2259 $args['type'] = $matching_schema['type']; 2260 } 2261 2262 $value = rest_sanitize_value_from_schema( $value, $matching_schema, $param ); 2263 } 2264 2265 if ( isset( $args['oneOf'] ) ) { 2266 $matching_schema = rest_find_one_matching_schema( $value, $args, $param ); 2267 if ( is_wp_error( $matching_schema ) ) { 2268 return $matching_schema; 2269 } 2270 2271 if ( ! isset( $args['type'] ) ) { 2272 $args['type'] = $matching_schema['type']; 2273 } 2274 2275 $value = rest_sanitize_value_from_schema( $value, $matching_schema, $param ); 2276 } 2277 1986 2278 $allowed_types = array( 'array', 'object', 'string', 'number', 'integer', 'boolean', 'null' ); 1987 2279 … … 2199 2491 * @since 5.5.0 2200 2492 * @since 5.6.0 Support the "patternProperties" keyword for objects. 2493 * Support the "anyOf" and "oneOf" keywords. 2201 2494 * 2202 2495 * @param array|object $data The response data to modify. … … 2206 2499 */ 2207 2500 function rest_filter_response_by_context( $data, $schema, $context ) { 2501 if ( isset( $schema['anyOf'] ) ) { 2502 $matching_schema = rest_find_any_matching_schema( $data, $schema, '' ); 2503 if ( ! is_wp_error( $matching_schema ) ) { 2504 if ( ! isset( $schema['type'] ) ) { 2505 $schema['type'] = $matching_schema['type']; 2506 } 2507 2508 $data = rest_filter_response_by_context( $data, $matching_schema, $context ); 2509 } 2510 } 2511 2512 if ( isset( $schema['oneOf'] ) ) { 2513 $matching_schema = rest_find_one_matching_schema( $data, $schema, '', true ); 2514 if ( ! is_wp_error( $matching_schema ) ) { 2515 if ( ! isset( $schema['type'] ) ) { 2516 $schema['type'] = $matching_schema['type']; 2517 } 2518 2519 $data = rest_filter_response_by_context( $data, $matching_schema, $context ); 2520 } 2521 } 2522 2208 2523 if ( ! is_array( $data ) && ! is_object( $data ) ) { 2209 2524 return $data; … … 2472 2787 'maxItems', 2473 2788 'uniqueItems', 2789 'anyOf', 2790 'oneOf', 2474 2791 ); 2475 2792 -
trunk/tests/phpunit/tests/rest-api.php
r49082 r49246 1086 1086 public function _dp_rest_filter_response_by_context() { 1087 1087 return array( 1088 'default' => array(1088 'default' => array( 1089 1089 array( 1090 1090 '$schema' => 'http://json-schema.org/draft-04/schema#', … … 1107 1107 array( 'first' => 'a' ), 1108 1108 ), 1109 'keeps missing context' => array(1109 'keeps missing context' => array( 1110 1110 array( 1111 1111 '$schema' => 'http://json-schema.org/draft-04/schema#', … … 1130 1130 ), 1131 1131 ), 1132 'removes empty context' => array(1132 'removes empty context' => array( 1133 1133 array( 1134 1134 '$schema' => 'http://json-schema.org/draft-04/schema#', … … 1151 1151 array( 'first' => 'a' ), 1152 1152 ), 1153 'nested properties' => array(1153 'nested properties' => array( 1154 1154 array( 1155 1155 '$schema' => 'http://json-schema.org/draft-04/schema#', … … 1180 1180 array( 'parent' => array( 'child' => 'hi' ) ), 1181 1181 ), 1182 'grand child properties' => array(1182 'grand child properties' => array( 1183 1183 array( 1184 1184 '$schema' => 'http://json-schema.org/draft-04/schema#', … … 1216 1216 array( 'parent' => array( 'child' => array( 'grand' => 'hi' ) ) ), 1217 1217 ), 1218 'array' => array(1218 'array' => array( 1219 1219 array( 1220 1220 '$schema' => 'http://json-schema.org/draft-04/schema#', … … 1251 1251 array( 'arr' => array( array( 'visible' => 'hi' ) ) ), 1252 1252 ), 1253 'additional properties' => array(1253 'additional properties' => array( 1254 1254 array( 1255 1255 '$schema' => 'http://json-schema.org/draft-04/schema#', … … 1285 1285 array( 'additional' => array( 'a' => '1' ) ), 1286 1286 ), 1287 'pattern properties' => array(1287 'pattern properties' => array( 1288 1288 array( 1289 1289 '$schema' => 'http://json-schema.org/draft-04/schema#', … … 1321 1321 ), 1322 1322 ), 1323 'multiple types object' => array(1323 'multiple types object' => array( 1324 1324 array( 1325 1325 '$schema' => 'http://json-schema.org/draft-04/schema#', … … 1350 1350 array( 'multi' => array( 'a' => '1' ) ), 1351 1351 ), 1352 'multiple types array' => array(1352 'multiple types array' => array( 1353 1353 array( 1354 1354 '$schema' => 'http://json-schema.org/draft-04/schema#', … … 1385 1385 array( 'multi' => array( array( 'visible' => '1' ) ) ), 1386 1386 ), 1387 'does not traverse missing context' => array(1387 'does not traverse missing context' => array( 1388 1388 array( 1389 1389 '$schema' => 'http://json-schema.org/draft-04/schema#', … … 1428 1428 ), 1429 1429 ), 1430 'object with no matching properties' => array(1430 'object with no matching properties' => array( 1431 1431 array( 1432 1432 '$schema' => 'http://json-schema.org/draft-04/schema#', … … 1449 1449 array(), 1450 1450 ), 1451 'array whose type does not match' => array(1451 'array whose type does not match' => array( 1452 1452 array( 1453 1453 '$schema' => 'http://json-schema.org/draft-04/schema#', … … 1469 1469 array( 'arr' => array() ), 1470 1470 ), 1471 'array and object type passed object' => array(1471 'array and object type passed object' => array( 1472 1472 array( 1473 1473 '$schema' => 'http://json-schema.org/draft-04/schema#', … … 1507 1507 ), 1508 1508 ), 1509 'array and object type passed array' => array(1509 'array and object type passed array' => array( 1510 1510 array( 1511 1511 '$schema' => 'http://json-schema.org/draft-04/schema#', … … 1548 1548 array(), 1549 1549 ), 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 ), 1550 1754 ); 1551 1755 } -
trunk/tests/phpunit/tests/rest-api/rest-controller.php
r49082 r49246 67 67 68 68 $this->assertErrorResponse( 69 'rest_invalid_ param',69 'rest_invalid_type', 70 70 rest_validate_request_arg( 'abc', $this->request, 'someinteger' ) 71 71 ); … … 141 141 142 142 $this->assertErrorResponse( 143 'rest_invalid_ param',143 'rest_invalid_type', 144 144 rest_validate_request_arg( '123', $this->request, 'someboolean' ) 145 145 ); … … 153 153 154 154 $this->assertErrorResponse( 155 'rest_invalid_ param',155 'rest_invalid_type', 156 156 rest_validate_request_arg( array( 'foo' => 'bar' ), $this->request, 'somestring' ) 157 157 ); … … 298 298 'minProperties', 299 299 'maxProperties', 300 'anyOf', 301 'oneOf', 300 302 ); 301 303 foreach ( $object_properties as $property ) { -
trunk/tests/phpunit/tests/rest-api/rest-post-meta-fields.php
r48937 r49246 693 693 694 694 $response = rest_get_server()->dispatch( $request ); 695 $this->assertErrorResponse( 'rest_invalid_ param', $response, 400 );695 $this->assertErrorResponse( 'rest_invalid_type', $response, 400 ); 696 696 } 697 697 … … 718 718 719 719 $response = rest_get_server()->dispatch( $request ); 720 $this->assertErrorResponse( 'rest_invalid_ param', $response, 400 );720 $this->assertErrorResponse( 'rest_invalid_type', $response, 400 ); 721 721 } 722 722 -
trunk/tests/phpunit/tests/rest-api/rest-schema-sanitization.php
r49082 r49246 588 588 $this->assertWPError( rest_sanitize_value_from_schema( $data, $schema ) ); 589 589 } 590 591 /** 592 * @ticket 51025 593 */ 594 public function test_any_of() { 595 $schema = array( 596 'anyOf' => array( 597 array( 598 'type' => 'integer', 599 'multipleOf' => 2, 600 ), 601 array( 602 'type' => 'string', 603 'maxLength' => 1, 604 ), 605 ), 606 ); 607 608 $this->assertSame( 4, rest_sanitize_value_from_schema( '4', $schema ) ); 609 $this->assertSame( '5', rest_sanitize_value_from_schema( '5', $schema ) ); 610 $this->assertWPError( rest_sanitize_value_from_schema( true, $schema ) ); 611 $this->assertWPError( rest_sanitize_value_from_schema( '11', $schema ) ); 612 } 613 614 /** 615 * @ticket 51025 616 */ 617 public function test_one_of() { 618 $schema = array( 619 'oneOf' => array( 620 array( 621 'type' => 'integer', 622 'multipleOf' => 2, 623 ), 624 array( 625 'type' => 'string', 626 'maxLength' => 1, 627 ), 628 ), 629 ); 630 631 $this->assertSame( 10, rest_sanitize_value_from_schema( '10', $schema ) ); 632 $this->assertSame( '5', rest_sanitize_value_from_schema( '5', $schema ) ); 633 $this->assertWPError( rest_sanitize_value_from_schema( true, $schema ) ); 634 $this->assertWPError( rest_sanitize_value_from_schema( '11', $schema ) ); 635 $this->assertWPError( rest_sanitize_value_from_schema( '4', $schema ) ); 636 } 590 637 } -
trunk/tests/phpunit/tests/rest-api/rest-schema-validation.php
r49082 r49246 1254 1254 } 1255 1255 1256 /** 1257 * @ticket 51025 1258 * 1259 * @dataProvider data_any_of 1260 * 1261 * @param array $data 1262 * @param array $schema 1263 * @param bool $valid 1264 */ 1265 public function test_any_of( $data, $schema, $valid ) { 1266 $is_valid = rest_validate_value_from_schema( $data, $schema ); 1267 1268 if ( $valid ) { 1269 $this->assertTrue( $is_valid ); 1270 } else { 1271 $this->assertWPError( $is_valid ); 1272 } 1273 } 1274 1275 /** 1276 * @return array 1277 */ 1278 public function data_any_of() { 1279 $suites = json_decode( file_get_contents( __DIR__ . '/json_schema_test_suite/anyof.json' ), true ); 1280 $skip = array( 1281 'anyOf with boolean schemas, all true', 1282 'anyOf with boolean schemas, some true', 1283 'anyOf with boolean schemas, all false', 1284 'anyOf with one empty schema', 1285 'nested anyOf, to check validation semantics', 1286 ); 1287 1288 $tests = array(); 1289 1290 foreach ( $suites as $suite ) { 1291 if ( in_array( $suite['description'], $skip, true ) ) { 1292 continue; 1293 } 1294 1295 foreach ( $suite['tests'] as $test ) { 1296 $tests[ $suite['description'] . ': ' . $test['description'] ] = array( 1297 $test['data'], 1298 $suite['schema'], 1299 $test['valid'], 1300 ); 1301 } 1302 } 1303 1304 return $tests; 1305 } 1306 1307 /** 1308 * @ticket 51025 1309 * 1310 * @dataProvider data_one_of 1311 * 1312 * @param array $data 1313 * @param array $schema 1314 * @param bool $valid 1315 */ 1316 public function test_one_of( $data, $schema, $valid ) { 1317 $is_valid = rest_validate_value_from_schema( $data, $schema ); 1318 1319 if ( $valid ) { 1320 $this->assertTrue( $is_valid ); 1321 } else { 1322 $this->assertWPError( $is_valid ); 1323 } 1324 } 1325 1326 /** 1327 * @return array 1328 */ 1329 public function data_one_of() { 1330 $suites = json_decode( file_get_contents( __DIR__ . '/json_schema_test_suite/oneof.json' ), true ); 1331 $skip = array( 1332 'oneOf with boolean schemas, all true', 1333 'oneOf with boolean schemas, one true', 1334 'oneOf with boolean schemas, more than one true', 1335 'oneOf with boolean schemas, all false', 1336 'oneOf with empty schema', 1337 'nested oneOf, to check validation semantics', 1338 ); 1339 1340 $tests = array(); 1341 1342 foreach ( $suites as $suite ) { 1343 if ( in_array( $suite['description'], $skip, true ) ) { 1344 continue; 1345 } 1346 1347 foreach ( $suite['tests'] as $test ) { 1348 $tests[ $suite['description'] . ': ' . $test['description'] ] = array( 1349 $test['data'], 1350 $suite['schema'], 1351 $test['valid'], 1352 ); 1353 } 1354 } 1355 1356 return $tests; 1357 } 1358 1359 /** 1360 * @ticket 51025 1361 * 1362 * @dataProvider data_combining_operation_error_message 1363 * 1364 * @param $data 1365 * @param $schema 1366 * @param $expected 1367 */ 1368 public function test_combining_operation_error_message( $data, $schema, $expected ) { 1369 $is_valid = rest_validate_value_from_schema( $data, $schema, 'foo' ); 1370 1371 $this->assertWPError( $is_valid ); 1372 $this->assertSame( $expected, $is_valid->get_error_message() ); 1373 } 1374 1375 /** 1376 * @return array 1377 */ 1378 public function data_combining_operation_error_message() { 1379 return array( 1380 array( 1381 10, 1382 array( 1383 'anyOf' => array( 1384 array( 1385 'title' => 'circle', 1386 'type' => 'integer', 1387 'maximum' => 5, 1388 ), 1389 ), 1390 ), 1391 'foo is not a valid circle. Reason: foo must be less than or equal to 5', 1392 ), 1393 array( 1394 10, 1395 array( 1396 'anyOf' => array( 1397 array( 1398 'type' => 'integer', 1399 'maximum' => 5, 1400 ), 1401 ), 1402 ), 1403 'foo does not match the expected format. Reason: foo must be less than or equal to 5', 1404 ), 1405 array( 1406 array( 'a' => 1 ), 1407 array( 1408 'anyOf' => array( 1409 array( 'type' => 'boolean' ), 1410 array( 1411 'title' => 'circle', 1412 'type' => 'object', 1413 'properties' => array( 1414 'a' => array( 'type' => 'string' ), 1415 ), 1416 ), 1417 ), 1418 ), 1419 'foo is not a valid circle. Reason: foo[a] is not of type string.', 1420 ), 1421 array( 1422 array( 'a' => 1 ), 1423 array( 1424 'anyOf' => array( 1425 array( 'type' => 'boolean' ), 1426 array( 1427 'type' => 'object', 1428 'properties' => array( 1429 'a' => array( 'type' => 'string' ), 1430 ), 1431 ), 1432 ), 1433 ), 1434 'foo does not match the expected format. Reason: foo[a] is not of type string.', 1435 ), 1436 array( 1437 array( 1438 'a' => 1, 1439 'b' => 2, 1440 'c' => 3, 1441 ), 1442 array( 1443 'anyOf' => array( 1444 array( 'type' => 'boolean' ), 1445 array( 1446 'type' => 'object', 1447 'properties' => array( 1448 'a' => array( 'type' => 'string' ), 1449 ), 1450 ), 1451 array( 1452 'title' => 'square', 1453 'type' => 'object', 1454 'properties' => array( 1455 'b' => array( 'type' => 'string' ), 1456 'c' => array( 'type' => 'string' ), 1457 ), 1458 ), 1459 array( 1460 'type' => 'object', 1461 'properties' => array( 1462 'b' => array( 'type' => 'boolean' ), 1463 'x' => array( 'type' => 'boolean' ), 1464 ), 1465 ), 1466 ), 1467 ), 1468 'foo is not a valid square. Reason: foo[b] is not of type string.', 1469 ), 1470 array( 1471 array( 1472 'a' => 1, 1473 'b' => 2, 1474 'c' => 3, 1475 ), 1476 array( 1477 'anyOf' => array( 1478 array( 'type' => 'boolean' ), 1479 array( 1480 'type' => 'object', 1481 'properties' => array( 1482 'a' => array( 'type' => 'string' ), 1483 ), 1484 ), 1485 array( 1486 'type' => 'object', 1487 'properties' => array( 1488 'b' => array( 'type' => 'string' ), 1489 'c' => array( 'type' => 'string' ), 1490 ), 1491 ), 1492 array( 1493 'type' => 'object', 1494 'properties' => array( 1495 'b' => array( 'type' => 'boolean' ), 1496 'x' => array( 'type' => 'boolean' ), 1497 ), 1498 ), 1499 ), 1500 ), 1501 'foo does not match the expected format. Reason: foo[b] is not of type string.', 1502 ), 1503 array( 1504 'test', 1505 array( 1506 'anyOf' => array( 1507 array( 1508 'title' => 'circle', 1509 'type' => 'boolean', 1510 ), 1511 array( 1512 'title' => 'square', 1513 'type' => 'integer', 1514 ), 1515 array( 1516 'title' => 'triangle', 1517 'type' => 'null', 1518 ), 1519 ), 1520 ), 1521 'foo is not a valid circle, square, and triangle.', 1522 ), 1523 array( 1524 'test', 1525 array( 1526 'anyOf' => array( 1527 array( 'type' => 'boolean' ), 1528 array( 'type' => 'integer' ), 1529 array( 'type' => 'null' ), 1530 ), 1531 ), 1532 'foo does not match any of the expected formats.', 1533 ), 1534 array( 1535 'test', 1536 array( 1537 'oneOf' => array( 1538 array( 1539 'title' => 'circle', 1540 'type' => 'string', 1541 ), 1542 array( 'type' => 'integer' ), 1543 array( 1544 'title' => 'triangle', 1545 'type' => 'string', 1546 ), 1547 ), 1548 ), 1549 'foo matches circle and triangle, but should match only one.', 1550 ), 1551 array( 1552 'test', 1553 array( 1554 'oneOf' => array( 1555 array( 'type' => 'string' ), 1556 array( 'type' => 'integer' ), 1557 array( 'type' => 'string' ), 1558 ), 1559 ), 1560 'foo matches more than one of the expected formats.', 1561 ), 1562 ); 1563 } 1256 1564 } -
trunk/tests/phpunit/tests/rest-api/rest-term-meta-fields.php
r48937 r49246 640 640 641 641 $response = rest_get_server()->dispatch( $request ); 642 $this->assertErrorResponse( 'rest_invalid_ param', $response, 400 );642 $this->assertErrorResponse( 'rest_invalid_type', $response, 400 ); 643 643 } 644 644 … … 665 665 666 666 $response = rest_get_server()->dispatch( $request ); 667 $this->assertErrorResponse( 'rest_invalid_ param', $response, 400 );667 $this->assertErrorResponse( 'rest_invalid_type', $response, 400 ); 668 668 } 669 669 -
trunk/tests/phpunit/tests/rest-api/rest-test-controller.php
r49082 r49246 129 129 'minProperties' => 1, 130 130 'maxProperties' => 10, 131 'anyOf' => array( 132 array( 133 'properties' => array( 134 'object_id' => array( 135 'type' => 'integer', 136 'minimum' => 100, 137 ), 138 ), 139 ), 140 array( 141 'properties' => array( 142 'object_id' => array( 143 'type' => 'integer', 144 'maximum' => 100, 145 ), 146 ), 147 ), 148 ), 149 'oneOf' => array( 150 array( 151 'properties' => array( 152 'object_id' => array( 153 'type' => 'integer', 154 'minimum' => 100, 155 ), 156 ), 157 ), 158 array( 159 'properties' => array( 160 'object_id' => array( 161 'type' => 'integer', 162 'maximum' => 100, 163 ), 164 ), 165 ), 166 ), 131 167 'ignored_prop' => 'ignored_prop', 132 168 'context' => array( 'view' ),
Note: See TracChangeset
for help on using the changeset viewer.