Merge pull request #27492 from woocommerce/fix/api/229

Add User-friendly Attribute Names and Values to Order Line Items Metadata
This commit is contained in:
Vedanshu Jain 2020-10-14 22:02:19 +05:30 committed by GitHub
commit ae610d3f5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 213 additions and 8 deletions

View File

@ -197,9 +197,46 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller {
unset( $data['order_id'] );
unset( $data['type'] );
// Expand meta_data to include user-friendly values.
$formatted_meta_data = $item->get_formatted_meta_data( null, true );
$data['meta_data'] = array_map(
array( $this, 'merge_meta_item_with_formatted_meta_display_attributes' ),
$data['meta_data'],
array_fill( 0, count( $data['meta_data'] ), $formatted_meta_data )
);
return $data;
}
/**
* Merge the `$formatted_meta_data` `display_key` and `display_value` attribute values into the corresponding
* {@link WC_Meta_Data}. Returns the merged array.
*
* @param WC_Meta_Data $meta_item An object from {@link WC_Order_Item::get_meta_data()}.
* @param array $formatted_meta_data An object result from {@link WC_Order_Item::get_formatted_meta_data}.
* The keys are the IDs of {@link WC_Meta_Data}.
*
* @return array
*/
private function merge_meta_item_with_formatted_meta_display_attributes( $meta_item, $formatted_meta_data ) {
$result = array(
'id' => $meta_item->id,
'key' => $meta_item->key,
'value' => $meta_item->value,
'display_key' => $meta_item->key, // Default to original key, in case a formatted key is not available.
'display_value' => $meta_item->value, // Default to original value, in case a formatted value is not available.
);
if ( array_key_exists( $meta_item->id, $formatted_meta_data ) ) {
$formatted_meta_item = $formatted_meta_data[ $meta_item->id ];
$result['display_key'] = wc_clean( $formatted_meta_item->display_key );
$result['display_value'] = wc_clean( $formatted_meta_item->display_value );
}
return $result;
}
/**
* Get formatted item data.
*
@ -590,8 +627,8 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller {
* Gets the product ID from the SKU or posted ID.
*
* @throws WC_REST_Exception When SKU or ID is not valid.
* @param array $posted Request data.
* @param string $action 'create' to add line item or 'update' to update it.
* @param array $posted Request data.
* @param string $action 'create' to add line item or 'update' to update it.
* @return int
*/
protected function get_product_id( $posted, $action = 'create' ) {
@ -1269,22 +1306,32 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller {
'items' => array(
'type' => 'object',
'properties' => array(
'id' => array(
'id' => array(
'description' => __( 'Meta ID.', 'woocommerce' ),
'type' => 'integer',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'key' => array(
'key' => array(
'description' => __( 'Meta key.', 'woocommerce' ),
'type' => 'string',
'context' => array( 'view', 'edit' ),
),
'value' => array(
'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
'display_key' => array(
'description' => __( 'Meta key for UI display.', 'woocommerce' ),
'type' => 'string',
'context' => array( 'view', 'edit' ),
),
'display_value' => array(
'description' => __( 'Meta value for UI display.', 'woocommerce' ),
'type' => 'string',
'context' => array( 'view', 'edit' ),
),
),
),
),

View File

@ -68,6 +68,57 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case {
$this->assertEquals( 401, $response->get_status() );
}
/**
* Tests line items have the expected meta_data properties when getting a single order.
*/
public function test_get_item_with_line_items_meta_data() {
wp_set_current_user( $this->user );
$site_level_attribute_id = wc_create_attribute( array( 'name' => 'Site Level Color' ) );
$site_level_attribute_slug = wc_attribute_taxonomy_name_by_id( $site_level_attribute_id );
// Register the attribute so that wp_insert_term will be successful
register_taxonomy( $site_level_attribute_slug, array( 'product' ), array() );
$site_level_term_insertion_result = wp_insert_term( 'Site Level Value - Blue', $site_level_attribute_slug );
$site_level_term = get_term( $site_level_term_insertion_result['term_id'] );
$product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product();
$variation = wc_get_product( $product->get_children()[0] );
$line_item = new WC_Order_Item_Product();
$line_item->set_product( $variation );
$line_item->set_props( array(
'variation' => array( "attribute_{$site_level_attribute_slug}" => $site_level_term->slug )
) );
$order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order();
$order->add_item( $line_item );
$order->save();
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/orders/' . $order->get_id() ) );
$data = $response->get_data();
$this->assertEquals( 200, $response->get_status() );
$this->assertEquals( $order->get_id(), $data['id'] );
$last_line_item = array_slice( $data['line_items'], -1 )[0];
$size_meta_data = $last_line_item['meta_data'][0];
$this->assertEquals( $line_item->get_meta_data()[0]->id, $size_meta_data['id'] );
$this->assertEquals( 'pa_size', $size_meta_data['key'] );
$this->assertEquals( 'size', $size_meta_data['display_key'] );
$this->assertEquals( 'small', $size_meta_data['value'] );
$this->assertEquals( 'small', $size_meta_data['display_value'] );
$color_meta_data = $last_line_item['meta_data'][1];
$this->assertEquals( $line_item->get_meta_data()[1]->id, $color_meta_data['id'] );
$this->assertEquals( $site_level_attribute_slug, $color_meta_data['key'] );
$this->assertEquals( 'Site Level Color', $color_meta_data['display_key'] );
$this->assertEquals( $site_level_term->slug, $color_meta_data['value'] );
$this->assertEquals( 'Site Level Value - Blue', $color_meta_data['display_value'] );
}
/**
* Tests getting a single order.
* @since 3.0.0
@ -718,4 +769,25 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case {
$this->assertEquals( 42, count( $properties ) );
$this->assertArrayHasKey( 'id', $properties );
}
/**
* Test the order line items schema.
*/
public function test_order_line_items_schema() {
wp_set_current_user( $this->user );
$order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order();
$request = new WP_REST_Request( 'OPTIONS', '/wc/v2/orders/' . $order->get_id() );
$response = $this->server->dispatch( $request );
$data = $response->get_data();
$line_item_properties = $data['schema']['properties']['line_items']['items']['properties'];
$this->assertEquals( 14, count( $line_item_properties ) );
$this->assertArrayHasKey( 'id', $line_item_properties );
$this->assertArrayHasKey( 'meta_data', $line_item_properties );
$meta_data_item_properties = $line_item_properties['meta_data']['items']['properties'];
$this->assertEquals( 5, count( $meta_data_item_properties ) );
$this->assertEquals( [ 'id', 'key', 'value', 'display_key', 'display_value' ], array_keys( $meta_data_item_properties ) );
}
}

View File

@ -146,6 +146,59 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case {
$this->assertEquals( 401, $response->get_status() );
}
/**
* Tests line items have the expected meta_data properties when getting a single order.
*/
public function test_get_item_with_line_items_meta_data() {
wp_set_current_user( $this->user );
$attribute_name = 'Site Level Type';
$site_level_attribute_id = wc_create_attribute( array( 'name' => $attribute_name ) );
$site_level_attribute_slug = wc_attribute_taxonomy_name_by_id( $site_level_attribute_id );
// Register the attribute so that wp_insert_term will be successful.
register_taxonomy( $site_level_attribute_slug, array( 'product' ), array() );
$term_name = 'Site Level Value - Wood';
$site_level_term_insertion_result = wp_insert_term( $term_name, $site_level_attribute_slug );
$site_level_term = get_term( $site_level_term_insertion_result['term_id'] );
$product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product();
$variation = wc_get_product( $product->get_children()[0] );
$line_item = new WC_Order_Item_Product();
$line_item->set_product( $variation );
$line_item->set_props(
array( 'variation' => array( "attribute_{$site_level_attribute_slug}" => $site_level_term->slug ) )
);
$order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order();
$order->add_item( $line_item );
$order->save();
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/orders/' . $order->get_id() ) );
$data = $response->get_data();
$this->assertEquals( 200, $response->get_status() );
$this->assertEquals( $order->get_id(), $data['id'] );
$last_line_item = array_slice( $data['line_items'], -1 )[0];
$size_meta_data = $last_line_item['meta_data'][0];
$this->assertEquals( $line_item->get_meta_data()[0]->id, $size_meta_data['id'] );
$this->assertEquals( 'pa_size', $size_meta_data['key'] );
$this->assertEquals( 'size', $size_meta_data['display_key'] );
$this->assertEquals( 'small', $size_meta_data['value'] );
$this->assertEquals( 'small', $size_meta_data['display_value'] );
$color_meta_data = $last_line_item['meta_data'][1];
$this->assertEquals( $line_item->get_meta_data()[1]->id, $color_meta_data['id'] );
$this->assertEquals( $site_level_attribute_slug, $color_meta_data['key'] );
$this->assertEquals( $attribute_name, $color_meta_data['display_key'] );
$this->assertEquals( $site_level_term->slug, $color_meta_data['value'] );
$this->assertEquals( $term_name, $color_meta_data['display_value'] );
}
/**
* Tests getting an order with an invalid ID.
* @since 3.5.0
@ -265,8 +318,9 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case {
$this->assertEquals( $order->get_shipping_country(), $data['shipping']['country'] );
$this->assertEquals( 1, count( $data['line_items'] ) );
$this->assertEquals( 1, count( $data['shipping_lines'] ) );
$shipping = current( $order->get_items( 'shipping' ) );
$expected = array(
$expected_shipping_line = array(
'id' => $shipping->get_id(),
'method_title' => $shipping->get_method_title(),
'method_id' => $shipping->get_method_id(),
@ -274,9 +328,20 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case {
'total' => wc_format_decimal( $shipping->get_total(), '' ),
'total_tax' => wc_format_decimal( $shipping->get_total_tax(), '' ),
'taxes' => array(),
'meta_data' => $shipping->get_meta_data(),
);
$this->assertEquals( $expected, $data['shipping_lines'][0] );
foreach ( $expected_shipping_line as $key => $value ) {
$this->assertEquals( $value, $data['shipping_lines'][0][ $key ] );
}
$actual_shipping_line_meta_data = $data['shipping_lines'][0]['meta_data'];
$this->assertCount( 3, $actual_shipping_line_meta_data );
foreach ( $shipping->get_meta_data() as $index => $expected_meta_item ) {
$this->assertEquals( $expected_meta_item->id, $actual_shipping_line_meta_data[ $index ]['id'] );
$this->assertEquals( $expected_meta_item->key, $actual_shipping_line_meta_data[ $index ]['key'] );
$this->assertEquals( $expected_meta_item->value, $actual_shipping_line_meta_data[ $index ]['value'] );
$this->assertEquals( $expected_meta_item->key, $actual_shipping_line_meta_data[ $index ]['display_key'] );
$this->assertEquals( $expected_meta_item->value, $actual_shipping_line_meta_data[ $index ]['display_value'] );
}
}
/**
@ -800,4 +865,25 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case {
$this->assertEquals( 42, count( $properties ) );
$this->assertArrayHasKey( 'id', $properties );
}
/**
* Test the order line items schema.
*/
public function test_order_line_items_schema() {
wp_set_current_user( $this->user );
$order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order();
$request = new WP_REST_Request( 'OPTIONS', '/wc/v3/orders/' . $order->get_id() );
$response = $this->server->dispatch( $request );
$data = $response->get_data();
$line_item_properties = $data['schema']['properties']['line_items']['items']['properties'];
$this->assertEquals( 14, count( $line_item_properties ) );
$this->assertArrayHasKey( 'id', $line_item_properties );
$this->assertArrayHasKey( 'meta_data', $line_item_properties );
$meta_data_item_properties = $line_item_properties['meta_data']['items']['properties'];
$this->assertEquals( 5, count( $meta_data_item_properties ) );
$this->assertEquals( array( 'id', 'key', 'value', 'display_key', 'display_value' ), array_keys( $meta_data_item_properties ) );
}
}