2017-08-31 10:42:19 +00:00
|
|
|
<?php
|
|
|
|
/**
|
2017-11-22 22:03:26 +00:00
|
|
|
* Unit tests for the WC_Product_Variable class.
|
2017-08-31 10:42:19 +00:00
|
|
|
*
|
|
|
|
* @package WooCommerce\Tests\Product
|
|
|
|
*/
|
2017-11-22 22:03:26 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Class WC_Tests_Product_Variable.
|
|
|
|
*/
|
2017-08-31 10:42:19 +00:00
|
|
|
class WC_Tests_Product_Variable extends WC_Unit_Test_Case {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Test test_create_empty_variable().
|
|
|
|
*/
|
|
|
|
public function test_create_empty_variable() {
|
|
|
|
$product = new WC_Product_Variable();
|
|
|
|
$product_id = $product->save();
|
|
|
|
$prices = $product->get_variation_prices();
|
|
|
|
|
2017-11-22 22:03:26 +00:00
|
|
|
$this->assertArrayHasKey( 'regular_price', $prices );
|
|
|
|
$this->assertArrayHasKey( 'sale_price', $prices );
|
|
|
|
$this->assertArrayHasKey( 'price', $prices );
|
2017-08-31 10:42:19 +00:00
|
|
|
$this->assertTrue( $product_id > 0 );
|
|
|
|
}
|
2017-11-15 20:08:19 +00:00
|
|
|
|
2017-11-22 22:03:26 +00:00
|
|
|
/**
|
|
|
|
* Test the automatic stock status transitions done on variable product save.
|
|
|
|
*
|
|
|
|
* @since 3.3.0
|
|
|
|
*/
|
2017-11-15 20:08:19 +00:00
|
|
|
public function test_variable_product_auto_stock_status() {
|
|
|
|
$product = new WC_Product_Variable();
|
|
|
|
|
2017-11-22 22:03:26 +00:00
|
|
|
// Product should not have quantity and stock status should be based on children stock status if not managing stock.
|
|
|
|
$product->set_manage_stock( false );
|
|
|
|
$product->set_stock_quantity( 5 );
|
|
|
|
$product->set_stock_status( 'instock' );
|
|
|
|
$product->save();
|
|
|
|
$this->assertEquals( '', $product->get_stock_quantity() );
|
|
|
|
$this->assertEquals( 'outofstock', $product->get_stock_status() );
|
|
|
|
|
|
|
|
$product->set_manage_stock( true );
|
|
|
|
|
|
|
|
// Product should be out of stock if managing orders, no backorders allowed, and quantity too low.
|
|
|
|
$product->set_stock_quantity( 0 );
|
|
|
|
$product->set_stock_status( 'instock' );
|
|
|
|
$product->set_backorders( 'no' );
|
|
|
|
$product->save();
|
|
|
|
$this->assertEquals( 0, $product->get_stock_quantity() );
|
|
|
|
$this->assertEquals( 'outofstock', $product->get_stock_status() );
|
|
|
|
|
|
|
|
// Product should be on backorder if managing orders, backorders allowed, and quantity too low.
|
|
|
|
$product->set_stock_quantity( 0 );
|
|
|
|
$product->set_stock_status( 'instock' );
|
|
|
|
$product->set_backorders( 'yes' );
|
|
|
|
$product->save();
|
|
|
|
$this->assertEquals( 0, $product->get_stock_quantity() );
|
|
|
|
$this->assertEquals( 'onbackorder', $product->get_stock_status() );
|
|
|
|
|
|
|
|
// Product should go to in stock if backordered and inventory increases.
|
|
|
|
$product->set_stock_quantity( 5 );
|
|
|
|
$product->set_stock_status( 'onbackorder' );
|
|
|
|
$product->set_backorders( 'notify' );
|
|
|
|
$product->save();
|
|
|
|
$this->assertEquals( 5, $product->get_stock_quantity() );
|
|
|
|
$this->assertEquals( 'instock', $product->get_stock_status() );
|
|
|
|
|
|
|
|
// Product should go to in stock if out of stock and inventory increases.
|
|
|
|
$product->set_stock_quantity( 3 );
|
|
|
|
$product->set_stock_status( 'outofstock' );
|
|
|
|
$product->set_backorders( 'no' );
|
|
|
|
$product->save();
|
|
|
|
$this->assertEquals( 3, $product->get_stock_quantity() );
|
|
|
|
$this->assertEquals( 'instock', $product->get_stock_status() );
|
2017-11-15 20:08:19 +00:00
|
|
|
}
|
2017-11-17 16:46:49 +00:00
|
|
|
|
|
|
|
/**
|
2020-05-27 09:53:16 +00:00
|
|
|
* Create a variable product with two variations.
|
2017-11-17 16:46:49 +00:00
|
|
|
*
|
2020-05-27 09:53:16 +00:00
|
|
|
* @return array An array containing first the main product, and then the two variation products.
|
2017-11-17 16:46:49 +00:00
|
|
|
*/
|
2020-05-27 09:53:16 +00:00
|
|
|
private function get_variable_product_with_children() {
|
2017-11-17 16:46:49 +00:00
|
|
|
$product = new WC_Product_Variable();
|
|
|
|
$product->save();
|
|
|
|
|
|
|
|
$child1 = new WC_Product_Variation();
|
|
|
|
$child1->set_parent_id( $product->get_id() );
|
|
|
|
$child1->save();
|
|
|
|
|
|
|
|
$child2 = new WC_Product_Variation();
|
|
|
|
$child2->set_parent_id( $product->get_id() );
|
|
|
|
$child2->save();
|
|
|
|
|
|
|
|
$product->set_children( array( $child1->get_id(), $child2->get_id() ) );
|
|
|
|
|
2020-05-27 09:53:16 +00:00
|
|
|
return array( $product, $child1, $child2 );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Test that variable products have the correct status when syncing with their children.
|
|
|
|
*
|
|
|
|
* @since 3.3.0
|
|
|
|
*/
|
|
|
|
public function test_variable_product_stock_status_sync() {
|
|
|
|
list($product, $child1, $child2) = $this->get_variable_product_with_children();
|
|
|
|
|
2017-11-17 16:46:49 +00:00
|
|
|
// Product should be in stock if a child is in stock.
|
|
|
|
$child1->set_stock_status( 'instock' );
|
|
|
|
$child1->save();
|
|
|
|
$child2->set_stock_status( 'outofstock' );
|
|
|
|
$child2->save();
|
|
|
|
WC_Product_Variable::sync( $product );
|
|
|
|
$this->assertEquals( 'instock', $product->get_stock_status() );
|
|
|
|
|
2017-11-20 19:19:06 +00:00
|
|
|
$child2->set_stock_status( 'onbackorder' );
|
|
|
|
$child2->save();
|
|
|
|
WC_Product_Variable::sync( $product );
|
|
|
|
$this->assertEquals( 'instock', $product->get_stock_status() );
|
|
|
|
|
2017-11-17 16:46:49 +00:00
|
|
|
// Product should be out of stock if all children are out of stock.
|
|
|
|
$child1->set_stock_status( 'outofstock' );
|
|
|
|
$child1->save();
|
2017-11-20 19:19:06 +00:00
|
|
|
$child2->set_stock_status( 'outofstock' );
|
|
|
|
$child2->save();
|
2017-11-17 16:46:49 +00:00
|
|
|
WC_Product_Variable::sync( $product );
|
|
|
|
$this->assertEquals( 'outofstock', $product->get_stock_status() );
|
|
|
|
|
2017-11-20 19:19:06 +00:00
|
|
|
// Product should be on backorder if all children are on backorder.
|
2017-11-17 16:46:49 +00:00
|
|
|
$child1->set_stock_status( 'onbackorder' );
|
|
|
|
$child1->save();
|
2017-11-20 19:19:06 +00:00
|
|
|
$child2->set_stock_status( 'onbackorder' );
|
|
|
|
$child2->save();
|
2017-11-17 16:46:49 +00:00
|
|
|
WC_Product_Variable::sync( $product );
|
|
|
|
$this->assertEquals( 'onbackorder', $product->get_stock_status() );
|
2017-11-20 19:32:30 +00:00
|
|
|
|
|
|
|
// Product should be on backorder if at least one child is on backorder and the rest are out of stock.
|
|
|
|
$child1->set_stock_status( 'outofstock' );
|
|
|
|
$child1->save();
|
|
|
|
$child2->set_stock_status( 'onbackorder' );
|
|
|
|
$child2->save();
|
|
|
|
WC_Product_Variable::sync( $product );
|
|
|
|
$this->assertEquals( 'onbackorder', $product->get_stock_status() );
|
2017-11-17 16:46:49 +00:00
|
|
|
}
|
2020-05-27 09:53:16 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @testdox Test that stock status is set to the proper value when saving, if the product manages stock levels.
|
|
|
|
*
|
|
|
|
* @testWith [5, 4, true, "instock"]
|
|
|
|
* [5, 4, false, "instock"]
|
|
|
|
* [4, 4, true, "onbackorder"]
|
|
|
|
* [4, 4, false, "outofstock"]
|
|
|
|
* [3, 4, true, "onbackorder"]
|
|
|
|
* [3, 4, false, "outofstock"]
|
|
|
|
*
|
|
|
|
* @param int $stock_quantity Current stock quantity for the product.
|
|
|
|
* @param bool $notify_no_stock_amount Value for the woocommerce_notify_no_stock_amount option.
|
|
|
|
* @param bool $accepts_backorders Whether the product accepts backorders or not.
|
|
|
|
* @param string $expected_stock_status The expected stock status of the product after being saved.
|
|
|
|
*/
|
|
|
|
public function test_stock_status_on_save_when_managing_stock( $stock_quantity, $notify_no_stock_amount, $accepts_backorders, $expected_stock_status ) {
|
2020-04-23 13:07:09 +00:00
|
|
|
list( $product, $child1, $child2 ) = $this->get_variable_product_with_children();
|
2020-05-27 09:53:16 +00:00
|
|
|
|
|
|
|
update_option( 'woocommerce_notify_no_stock_amount', $notify_no_stock_amount );
|
|
|
|
|
|
|
|
$child1->set_stock_status( '' );
|
|
|
|
$child1->save();
|
|
|
|
$child2->set_stock_status( '' );
|
|
|
|
$child2->save();
|
|
|
|
|
|
|
|
$product->set_manage_stock( 'yes' );
|
|
|
|
$product->set_stock_status( '' );
|
|
|
|
$product->set_backorders( $accepts_backorders ? 'yes' : 'no' );
|
|
|
|
$product->set_stock_quantity( $stock_quantity );
|
|
|
|
$product->save();
|
|
|
|
|
|
|
|
$this->assertEquals( $expected_stock_status, $product->get_stock_status() );
|
|
|
|
}
|
2017-08-31 10:42:19 +00:00
|
|
|
}
|