Fix tests for batches

This commit is contained in:
Mike Jolley 2019-06-14 13:43:29 +01:00
parent d88ab33dda
commit 7f2ea5cc2f
15 changed files with 215 additions and 256 deletions

View File

@ -13,5 +13,8 @@
<testsuite name="WooCommerce REST API Test Suite">
<directory suffix=".php">./unit-tests/Tests</directory>
</testsuite>
<testsuite name="v4">
<directory suffix=".php">./unit-tests/Tests/Version4</directory>
</testsuite>
</testsuites>
</phpunit>

View File

@ -24,6 +24,7 @@ use \WP_REST_Controller;
* @version 2.6.0
*/
abstract class AbstractController extends WP_REST_Controller {
use BatchTrait;
/**
* Endpoint namespace.
@ -41,76 +42,97 @@ abstract class AbstractController extends WP_REST_Controller {
/**
* Register route for items requests.
*
* @param array $methods Supported methods. read, create.
*/
protected function register_items_route() {
protected function register_items_route( $methods = [ 'read', 'create' ] ) {
$routes = [];
$routes['schema'] = [ $this, 'get_public_item_schema' ];
if ( in_array( 'read', $methods, true ) ) {
$routes[] = array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array( $this, 'get_items' ),
'permission_callback' => array( $this, 'get_items_permissions_check' ),
'args' => $this->get_collection_params(),
);
}
if ( in_array( 'create', $methods, true ) ) {
$routes[] = array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array( $this, 'create_item' ),
'permission_callback' => array( $this, 'create_item_permissions_check' ),
'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ),
);
}
register_rest_route(
$this->namespace,
'/' . $this->rest_base,
array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array( $this, 'get_items' ),
'permission_callback' => array( $this, 'get_items_permissions_check' ),
'args' => $this->get_collection_params(),
),
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array( $this, 'create_item' ),
'permission_callback' => array( $this, 'create_item_permissions_check' ),
'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ),
),
'schema' => array( $this, 'get_public_item_schema' ),
),
$routes,
true
);
}
/**
* Register route for item create/get/delete/update requests.
*
* @param array $methods Supported methods. read, create.
*/
protected function register_item_route() {
protected function register_item_route( $methods = [ 'read', 'edit', 'delete' ] ) {
$routes = [];
$routes['schema'] = [ $this, 'get_public_item_schema' ];
$routes['args'] = [
'id' => [
'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
'type' => 'integer',
],
];
if ( in_array( 'read', $methods, true ) ) {
$routes[] = array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array( $this, 'get_item' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
'args' => array(
'context' => $this->get_context_param(
array(
'default' => 'view',
)
),
),
);
}
if ( in_array( 'edit', $methods, true ) ) {
$routes[] = array(
'methods' => \WP_REST_Server::EDITABLE,
'callback' => array( $this, 'update_item' ),
'permission_callback' => array( $this, 'update_item_permissions_check' ),
'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ),
);
}
if ( in_array( 'delete', $methods, true ) ) {
$routes[] = array(
'methods' => \WP_REST_Server::DELETABLE,
'callback' => array( $this, 'delete_item' ),
'permission_callback' => array( $this, 'delete_item_permissions_check' ),
'args' => array(
'force' => array(
'default' => false,
'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ),
'type' => 'boolean',
),
),
);
}
register_rest_route(
$this->namespace,
'/' . $this->rest_base . '/(?P<id>[\d]+)',
array(
'args' => array(
'id' => array(
'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
'type' => 'integer',
),
),
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array( $this, 'get_item' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
'args' => array(
'context' => $this->get_context_param(
array(
'default' => 'view',
)
),
),
),
array(
'methods' => \WP_REST_Server::EDITABLE,
'callback' => array( $this, 'update_item' ),
'permission_callback' => array( $this, 'update_item_permissions_check' ),
'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ),
),
array(
'methods' => \WP_REST_Server::DELETABLE,
'callback' => array( $this, 'delete_item' ),
'permission_callback' => array( $this, 'delete_item_permissions_check' ),
'args' => array(
'force' => array(
'default' => false,
'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ),
'type' => 'boolean',
),
),
),
'schema' => array( $this, 'get_public_item_schema' ),
),
$routes,
true
);
}

View File

@ -13,7 +13,6 @@ defined( 'ABSPATH' ) || exit;
* CRUD Object Controller.
*/
abstract class AbstractObjectsController extends AbstractController {
use BatchTrait;
/**
* If object is hierarchical.

View File

@ -117,20 +117,7 @@ abstract class AbstractTermsContoller extends AbstractController {
true
);
register_rest_route(
$this->namespace,
'/' . $this->rest_base . '/batch',
array(
array(
'methods' => \WP_REST_Server::EDITABLE,
'callback' => array( $this, 'batch_items' ),
'permission_callback' => array( $this, 'batch_items_permissions_check' ),
'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ),
),
'schema' => array( $this, 'get_public_batch_schema' ),
),
true
);
$this->register_batch_route();
}
/**

View File

@ -19,23 +19,37 @@ trait BatchTrait {
* @return array Of \WP_Error or \WP_REST_Response.
*/
public function batch_items( $request ) {
$items = array_filter( $request->get_params() );
$items = $request->get_params();
$limit = $this->check_batch_limit( $items );
if ( is_wp_error( $limit ) ) {
return $limit;
}
$response = [];
$batches = [ 'create', 'update', 'delete' ];
$response = [];
foreach ( $batches as $batch ) {
if ( ! isset( $items[ $batch ] ) ) {
continue;
}
$items[ $batch ] = wp_parse_id_list( $items[ $batch ] );
$response[ $batch ] = $this->{"batch_$batch"}( $items[ $batch ] );
$response[ $batch ] = $this->{"batch_$batch"}( $this->get_batch_of_items_from_request( $request, $batch ) );
}
return $response;
return array_filter( $response );
}
/**
* Get batch of items from requst.
*
* @param \WP_REST_Request $request Full details about the request.
* @param string $batch_type Batch type; one of create, update, delete.
* @return array
*/
protected function get_batch_of_items_from_request( $request, $batch_type ) {
$params = $request->get_params();
if ( ! isset( $params[ $batch_type ] ) ) {
return array();
}
return array_filter( $params[ $batch_type ] );
}
/**
@ -44,7 +58,9 @@ trait BatchTrait {
* @param \WP_REST_Request $request Full details about the request.
* @return boolean|\WP_Error
*/
abstract public function batch_items_permissions_check( $request );
public function batch_items_permissions_check( $request ) {
return update_items_permissions_check( $request );
}
/**
* Register route for batch requests.
@ -123,16 +139,15 @@ trait BatchTrait {
* @return bool|\WP_Error
*/
protected function check_batch_limit( $items ) {
$limit = apply_filters( 'woocommerce_rest_batch_items_limit', 100, $this->get_normalized_rest_base() );
$total = 0;
$limit = apply_filters( 'woocommerce_rest_batch_items_limit', 100, $this->get_normalized_rest_base() );
$total = 0;
$batches = [ 'create', 'update', 'delete' ];
$batches = [ 'create', 'update', 'delete' ];
foreach ( $batches as $batch ) {
if ( ! isset( $items[ $batch ] ) ) {
continue;
}
$items[ $batch ] = wp_parse_id_list( $items[ $batch ] );
$total = $total + count( $items[ $batch ] );
$total = $total + count( $items[ $batch ] );
}
if ( $total > $limit ) {
@ -162,40 +177,42 @@ trait BatchTrait {
/**
* Batch create items.
*
* @param array $items Array of item ids.
* @param array $items Array of items.
* @return array Response data.
*/
protected function batch_create( $items ) {
$response = [];
$batch_response = [];
foreach ( $items as $id ) {
$item = new \WP_REST_Request( 'POST' );
$item->set_default_params( $this->get_default_params() );
$item->set_body_params( $item );
$item_response = $this->create_item( $item );
$response[] = $this->format_response( $id, $item_response );
foreach ( $items as $item ) {
$request = new \WP_REST_Request( 'POST' );
$request->set_default_params( $this->get_default_params() );
$request->set_body_params( $item );
$response = $this->create_item( $request );
$batch_response[] = $this->format_response( 0, $response );
}
return $response;
return $batch_response;
}
/**
* Batch update items.
*
* @param array $items Array of item ids.
* @param array $items Array of items.
* @return array Response data.
*/
protected function batch_update( $items ) {
$response = [];
$batch_response = [];
foreach ( $items as $id ) {
$item = new \WP_REST_Request( 'PUT' );
$item->set_body_params( $item );
$item_response = $this->update_item( $item );
$response[] = $this->format_response( $id, $item_response );
foreach ( $items as $item ) {
$request = new \WP_REST_Request( 'PUT' );
$request->set_body_params( $item );
$response = $this->update_item( $request );
$batch_response[] = $this->format_response( $item['id'], $response );
}
return $response;
return $batch_response;
}
/**
@ -205,21 +222,22 @@ trait BatchTrait {
* @return array Response data.
*/
protected function batch_delete( $items ) {
$response = [];
$batch_response = [];
$items = wp_parse_id_list( $items );
foreach ( $items as $id ) {
$item = new \WP_REST_Request( 'DELETE' );
$item->set_query_params(
$request = new \WP_REST_Request( 'DELETE' );
$request->set_query_params(
[
'id' => $id,
'force' => true,
]
);
$item_response = $this->delete_item( $item );
$response[] = $this->format_response( $id, $item_response );
$response = $this->delete_item( $request );
$batch_response[] = $this->format_response( $id, $response );
}
return $response;
return $batch_response;
}
/**
@ -237,12 +255,12 @@ trait BatchTrait {
*/
global $wp_rest_server;
if ( is_wp_error( $response ) ) {
return $this->format_error_response( $response );
if ( ! is_wp_error( $response ) ) {
return $wp_rest_server->response_to_data( $response, '' );
} else {
return array(
'id' => $id,
'error' => $wp_rest_server->response_to_data( $response, '' ),
'error' => $this->format_error_response( $response ),
);
}
}

View File

@ -27,26 +27,7 @@ class CustomerDownloads extends AbstractController {
* Register the routes for customers.
*/
public function register_routes() {
register_rest_route(
$this->namespace,
'/' . $this->rest_base,
array(
'args' => array(
'customer_id' => array(
'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
'type' => 'integer',
),
),
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array( $this, 'get_items' ),
'permission_callback' => array( $this, 'get_items_permissions_check' ),
'args' => $this->get_collection_params(),
),
'schema' => array( $this, 'get_public_item_schema' ),
),
true
);
$this->register_items_route( [ 'read' ] );
}
/**

View File

@ -115,20 +115,7 @@ class Customers extends AbstractController {
true
);
register_rest_route(
$this->namespace,
'/' . $this->rest_base . '/batch',
array(
array(
'methods' => \WP_REST_Server::EDITABLE,
'callback' => array( $this, 'batch_items' ),
'permission_callback' => array( $this, 'batch_items_permissions_check' ),
'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ),
),
'schema' => array( $this, 'get_public_batch_schema' ),
),
true
);
$this->register_batch_route();
}
/**

View File

@ -105,20 +105,7 @@ class ProductAttributes extends AbstractController {
true
);
register_rest_route(
$this->namespace,
'/' . $this->rest_base . '/batch',
array(
array(
'methods' => \WP_REST_Server::EDITABLE,
'callback' => array( $this, 'batch_items' ),
'permission_callback' => array( $this, 'batch_items_permissions_check' ),
'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ),
),
'schema' => array( $this, 'get_public_batch_schema' ),
),
true
);
$this->register_batch_route();
}
/**

View File

@ -113,20 +113,7 @@ class ProductReviews extends AbstractController {
true
);
register_rest_route(
$this->namespace,
'/' . $this->rest_base . '/batch',
array(
array(
'methods' => \WP_REST_Server::EDITABLE,
'callback' => array( $this, 'batch_items' ),
'permission_callback' => array( $this, 'batch_items_permissions_check' ),
'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ),
),
'schema' => array( $this, 'get_public_batch_schema' ),
),
true
);
$this->register_batch_route();
}
/**

View File

@ -725,37 +725,35 @@ class ProductVariations extends Products {
}
/**
* Bulk create, update and delete items.
* Get batch of items from requst.
*
* @since 3.0.0
* @param \WP_REST_Request $request Full details about the request.
* @return array Of \WP_Error or \WP_REST_Response.
* @param string $batch_type Batch type; one of create, update, delete.
* @return array
*/
public function batch_items( $request ) {
$items = array_filter( $request->get_params() );
$params = $request->get_url_params();
$product_id = $params['product_id'];
$body_params = array();
protected function get_batch_of_items_from_request( $request, $batch_type ) {
$params = $request->get_params();
$url_params = $request->get_url_params();
$product_id = $url_params['product_id'];
foreach ( array( 'update', 'create', 'delete' ) as $batch_type ) {
if ( ! empty( $items[ $batch_type ] ) ) {
$injected_items = array();
foreach ( $items[ $batch_type ] as $item ) {
$injected_items[] = is_array( $item ) ? array_merge(
array(
'product_id' => $product_id,
),
$item
) : $item;
}
$body_params[ $batch_type ] = $injected_items;
if ( ! isset( $params[ $batch_type ] ) ) {
return array();
}
$items = array_filter( $params[ $batch_type ] );
if ( 'update' === $batch_type || 'create' === $batch_type ) {
foreach ( $items as $key => $item ) {
$items[ $key ] = array_merge(
array(
'product_id' => $product_id,
),
$item
);
}
}
$request = new \WP_REST_Request( $request->get_method() );
$request->set_body_params( $body_params );
return parent::batch_items( $request );
return array_filter( $items );
}
/**

View File

@ -42,19 +42,7 @@ class Settings extends AbstractController {
),
true
);
register_rest_route(
$this->namespace,
'/' . $this->rest_base . '/batch',
array(
array(
'methods' => \WP_REST_Server::EDITABLE,
'callback' => array( $this, 'batch_items' ),
'permission_callback' => array( $this, 'update_items_permissions_check' ),
),
'schema' => array( $this, 'get_public_batch_schema' ),
),
true
);
$this->register_batch_route();
}
/**

View File

@ -274,30 +274,32 @@ class SettingsOptions extends AbstractController {
}
/**
* Bulk create, update and delete items.
* Get batch of items from requst.
*
* @since 3.0.0
* @param \WP_REST_Request $request Full details about the request.
* @return array Of \WP_Error or \WP_REST_Response.
* @param string $batch_type Batch type; one of create, update, delete.
* @return array
*/
public function batch_items( $request ) {
// Get the request params.
$items = array_filter( $request->get_params() );
protected function get_batch_of_items_from_request( $request, $batch_type ) {
$params = $request->get_params();
/*
if ( ! isset( $params[ $batch_type ] ) ) {
return array();
}
/**
* Since our batch settings update is group-specific and matches based on the route,
* we inject the URL parameters (containing group) into the batch items
*/
if ( ! empty( $items['update'] ) ) {
$to_update = array();
foreach ( $items['update'] as $item ) {
$to_update[] = array_merge( $request->get_url_params(), $item );
$items = array_filter( $params[ $batch_type ] );
if ( 'update' === $batch_type ) {
foreach ( $items as $key => $item ) {
$items[ $key ] = array_merge( $request->get_url_params(), $item );
}
$request = new \WP_REST_Request( $request->get_method() );
$request->set_body_params( array( 'update' => $to_update ) );
}
return parent::batch_items( $request );
return array_filter( $items );
}
/**
@ -345,8 +347,7 @@ class SettingsOptions extends AbstractController {
/**
* Prepare a single setting object for response.
*
* @since 3.0.0
* @param object $item Setting object.
* @param object $item Setting object.
* @param \WP_REST_Request $request Request object.
* @return \WP_REST_Response $response Response data.
*/
@ -363,7 +364,6 @@ class SettingsOptions extends AbstractController {
/**
* Prepare links for the request.
*
* @since 3.0.0
* @param string $setting_id Setting ID.
* @param string $group_id Group ID.
* @return array Links for the given setting.

View File

@ -89,20 +89,7 @@ class Taxes extends AbstractController {
true
);
register_rest_route(
$this->namespace,
'/' . $this->rest_base . '/batch',
array(
array(
'methods' => \WP_REST_Server::EDITABLE,
'callback' => array( $this, 'batch_items' ),
'permission_callback' => array( $this, 'batch_items_permissions_check' ),
'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ),
),
'schema' => array( $this, 'get_public_batch_schema' ),
),
true
);
$this->register_batch_route();
}
/**

View File

@ -110,20 +110,7 @@ class Webhooks extends AbstractController {
true
);
register_rest_route(
$this->namespace,
'/' . $this->rest_base . '/batch',
array(
array(
'methods' => \WP_REST_Server::EDITABLE,
'callback' => array( $this, 'batch_items' ),
'permission_callback' => array( $this, 'batch_items_permissions_check' ),
'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ),
),
'schema' => array( $this, 'get_public_batch_schema' ),
),
true
);
$this->register_batch_route();
}
/**

View File

@ -12,7 +12,7 @@ defined( 'ABSPATH' ) || exit;
/**
* WC Tests API Data
*/
class Data {
class Data extends \WC_REST_Unit_Test_Case {
/**
* Endpoints.
@ -21,6 +21,34 @@ class Data {
*/
protected $endpoint = '/wc/v4/data';
/**
* User variable.
*
* @var WP_User
*/
protected static $user;
/**
* Setup once before running tests.
*
* @param object $factory Factory object.
*/
public static function wpSetUpBeforeClass( $factory ) {
self::$user = $factory->user->create(
array(
'role' => 'administrator',
)
);
}
/**
* Setup test class.
*/
public function setUp() {
parent::setUp();
wp_set_current_user( self::$user );
}
/**
* Test that the list of data endpoints includes download-ips.
*/