diff --git a/includes/api/class-wc-rest-products-controller.php b/includes/api/class-wc-rest-products-controller.php index 9583e9a1fd2..f79a13ec437 100644 --- a/includes/api/class-wc-rest-products-controller.php +++ b/includes/api/class-wc-rest-products-controller.php @@ -161,14 +161,32 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { } /** - * Add new options for 'orderby' to the collection params. + * Prepare a single product for create or update. * - * @return array + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data */ - public function get_collection_params() { - $params = parent::get_collection_params(); - $params['orderby']['enum'] = array_merge( $params['orderby']['enum'], array( 'price', 'popularity', 'rating' ) ); - return $params; + protected function prepare_object_for_database( $request, $creating = false ) { + $product = parent::prepare_object_for_database( $request, $creating ); + + if ( ! empty( $request['date_created'] ) ) { + $date = rest_parse_date( $request['date_created'] ); + + if ( $date ) { + $product->set_date_created( $date ); + } + } + + if ( ! empty( $request['date_created_gmt'] ) ) { + $date = rest_parse_date( $request['date_created_gmt'], true ); + + if ( $date ) { + $product->set_date_created_gmt( $date ); + } + } + + return $product; } /** @@ -211,13 +229,11 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), - 'readonly' => true, ), 'date_created_gmt' => array( 'description' => __( 'The date the product was created, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), - 'readonly' => true, ), 'date_modified' => array( 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce' ), @@ -787,4 +803,15 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { ); return $this->add_additional_fields_schema( $schema ); } + + /** + * Add new options for 'orderby' to the collection params. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + $params['orderby']['enum'] = array_merge( $params['orderby']['enum'], array( 'price', 'popularity', 'rating' ) ); + return $params; + } } diff --git a/includes/api/v2/class-wc-rest-orders-v2-controller.php b/includes/api/v2/class-wc-rest-orders-v2-controller.php index a8e022d7111..626b9386a31 100644 --- a/includes/api/v2/class-wc-rest-orders-v2-controller.php +++ b/includes/api/v2/class-wc-rest-orders-v2-controller.php @@ -1397,6 +1397,11 @@ class WC_REST_Orders_V2_Controller extends WC_REST_Legacy_Orders_Controller { 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), + 'instance_id' => array( + 'description' => __( 'Shipping instance ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), 'total' => array( 'description' => __( 'Line total (after discounts).', 'woocommerce' ), 'type' => 'string', diff --git a/tests/unit-tests/api/products.php b/tests/unit-tests/api/products.php index 1c12ca2b596..4d1f87af9bd 100644 --- a/tests/unit-tests/api/products.php +++ b/tests/unit-tests/api/products.php @@ -6,7 +6,7 @@ * @since 3.5.0 */ -class Products_API extends WC_REST_Unit_Test_Case { +class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { /** * Setup our test server, endpoints, and user info. @@ -158,9 +158,10 @@ class Products_API extends WC_REST_Unit_Test_Case { wp_set_current_user( $this->user ); // test simple products - $product = WC_Helper_Product::create_simple_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) ); - $data = $response->get_data(); + $product = WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) ); + $data = $response->get_data(); + $date_created = date( 'Y-m-d\TH:i:s', current_time( 'timestamp' ) ); $this->assertEquals( 'DUMMY SKU', $data['sku'] ); $this->assertEquals( 10, $data['regular_price'] ); @@ -169,10 +170,11 @@ class Products_API extends WC_REST_Unit_Test_Case { $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() ); $request->set_body_params( array( - 'sku' => 'FIXED-SKU', - 'sale_price' => '8', - 'description' => 'Testing', - 'images' => array( + 'sku' => 'FIXED-SKU', + 'sale_price' => '8', + 'description' => 'Testing', + 'date_created' => $date_created, + 'images' => array( array( 'position' => 0, 'src' => 'http://cldup.com/Dr1Bczxq4q.png', @@ -189,6 +191,7 @@ class Products_API extends WC_REST_Unit_Test_Case { $this->assertEquals( '8', $data['sale_price'] ); $this->assertEquals( '10', $data['regular_price'] ); $this->assertEquals( 'FIXED-SKU', $data['sku'] ); + $this->assertEquals( $date_created, $data['date_created'] ); $this->assertContains( 'Dr1Bczxq4q', $data['images'][0]['src'] ); $this->assertContains( 'test upload image', $data['images'][0]['alt'] ); $product->delete( true ); diff --git a/tests/unit-tests/api/system-status.php b/tests/unit-tests/api/system-status.php index 881697b993e..52d47f99013 100644 --- a/tests/unit-tests/api/system-status.php +++ b/tests/unit-tests/api/system-status.php @@ -250,6 +250,37 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { ), $data ); + + $query_params = array( + '_fields' => 'id,name,nonexisting', + ); + $request = new WP_REST_Request( 'GET', '/wc/v3/system_status/tools' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $raw_tools ), count( $data ) ); + $this->assertContains( + array( + 'id' => 'reset_tracking', + 'name' => 'Reset usage tracking', + ), + $data + ); + foreach ( $data as $item ) { + // Fields that are not requested are not returned in response. + $this->assertArrayNotHasKey( 'action', $item ); + $this->assertArrayNotHasKey( 'description', $item ); + // Links are part of data in collections, so excluded if not explicitly requested. + $this->assertArrayNotHasKey( '_links', $item ); + // Non existing field is ignored. + $this->assertArrayNotHasKey( 'nonexisting', $item ); + } + + // Links are part of data, not links in collections. + $links = $response->get_links(); + $this->assertEquals( 0, count( $links ) ); } /** @@ -284,6 +315,28 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { $this->assertEquals( 'Term counts', $data['name'] ); $this->assertEquals( 'Recount terms', $data['action'] ); $this->assertEquals( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', $data['description'] ); + + // Test for _fields query parameter. + $query_params = array( + '_fields' => 'id,name,nonexisting', + ); + $request = new WP_REST_Request( 'GET', '/wc/v3/system_status/tools/recount_terms' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertEquals( 'recount_terms', $data['id'] ); + $this->assertEquals( 'Term counts', $data['name'] ); + $this->assertArrayNotHasKey( 'action', $data ); + $this->assertArrayNotHasKey( 'description', $data ); + // Links are part of links, not data in single items. + $this->assertArrayNotHasKey( '_links', $data ); + + // Links are part of links, not data in single item response. + $links = $response->get_links(); + $this->assertEquals( 1, count( $links ) ); } /** @@ -321,6 +374,32 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { $response = $this->server->dispatch( new WP_REST_Request( 'POST', '/wc/v3/system_status/tools/not_a_real_tool' ) ); $this->assertEquals( 404, $response->get_status() ); + + // Test _fields for execute system tool request. + $query_params = array( + '_fields' => 'id,success,nonexisting', + ); + $request = new WP_REST_Request( 'PUT', '/wc/v3/system_status/tools/recount_terms' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'recount_terms', $data['id'] ); + $this->assertTrue( $data['success'] ); + + // Fields that are not requested are not returned in response. + $this->assertArrayNotHasKey( 'action', $data ); + $this->assertArrayNotHasKey( 'name', $data ); + $this->assertArrayNotHasKey( 'description', $data ); + // Links are part of links, not data in single item response. + $this->assertArrayNotHasKey( '_links', $data ); + // Non existing field is ignored. + $this->assertArrayNotHasKey( 'nonexisting', $data ); + + // Links are part of links, not data in single item response. + $links = $response->get_links(); + $this->assertEquals( 1, count( $links ) ); } /** @@ -378,4 +457,36 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { $this->assertNotEmpty( get_post_meta( $order2->get_id(), '_shipping_address_index', true ) ); } + + /** + * Test system_status _filter query parameter. + */ + public function test_get_system_status_info_filtered() { + wp_set_current_user( $this->user ); + $query_params = array( + '_fields' => 'theme,settings,nonexisting', + ); + $request = new WP_REST_Request( 'GET', '/wc/v3/system_status' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $data ) ); + + // Selected fields returned in the response. + $this->assertArrayHasKey( 'theme', $data ); + $this->assertArrayHasKey( 'settings', $data ); + + // Fields not selected omitted from response. + $this->assertArrayNotHasKey( 'environment', $data ); + $this->assertArrayNotHasKey( 'database', $data ); + $this->assertArrayNotHasKey( 'active_plugins', $data ); + $this->assertArrayNotHasKey( 'security', $data ); + $this->assertArrayNotHasKey( 'pages', $data ); + + // Non existing field is ignored. + $this->assertArrayNotHasKey( 'nonexisting', $data ); + } + }