Add unit tests for the Filterer class (variable products)
This commit is contained in:
parent
9878aa37aa
commit
c78627e6ee
|
@ -4,6 +4,7 @@ namespace Automattic\WooCommerce\Tests\Internal\ProductAttributesLookup;
|
|||
|
||||
use Automattic\WooCommerce\Internal\AttributesHelper;
|
||||
use Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper;
|
||||
use Automattic\WooCommerce\Utilities\ArrayUtil;
|
||||
|
||||
/**
|
||||
* Tests related to filtering for WC_Query.
|
||||
|
@ -88,30 +89,49 @@ class FiltererTest extends \WC_Unit_Test_Case {
|
|||
/**
|
||||
* Core function to create a product.
|
||||
*
|
||||
* Format of $product_attributes is:
|
||||
*
|
||||
* [
|
||||
* 'non_variation_defining' => [
|
||||
* 'Name' => ['Value','Value'],...
|
||||
* ]
|
||||
* 'variation_defining' => [
|
||||
* 'Name' => ['Value','Value'],...
|
||||
* ]
|
||||
* ]
|
||||
*
|
||||
* @param string $class_name The name of the product class that will be instantiated to create the product.
|
||||
* @param array $attribute_terms_by_name An array of product attributes, keys are attribute names, values are arrays of attribute term names.
|
||||
* @param bool $attributes_define_variations True if the attributes are used to define variations.
|
||||
* @param array $product_attributes The product attributes.
|
||||
* @return mixed An instance of the class passed in $class_name representing the created product.
|
||||
*/
|
||||
private function create_product_core( $class_name, $attribute_terms_by_name, $attributes_define_variations ) {
|
||||
private function create_product_core( $class_name, $product_attributes ) {
|
||||
$attributes = array();
|
||||
$attribute_ids_by_name = wc_get_attribute_taxonomy_ids();
|
||||
|
||||
foreach ( $attribute_terms_by_name as $attribute_name => $attribute_terms ) {
|
||||
$sanitized_attribute_name = wc_sanitize_taxonomy_name( $attribute_name );
|
||||
$product_attributes = array(
|
||||
false => ArrayUtil::get_value_or_default( $product_attributes, 'non_variation_defining', array() ),
|
||||
true => ArrayUtil::get_value_or_default( $product_attributes, 'variation_defining', array() ),
|
||||
);
|
||||
foreach ( $product_attributes as $defines_variation => $attribute_terms_by_name ) {
|
||||
foreach ( $attribute_terms_by_name as $attribute_name => $attribute_terms ) {
|
||||
if ( ! is_array( $attribute_terms ) ) {
|
||||
$attribute_terms = array( $attribute_terms );
|
||||
}
|
||||
$sanitized_attribute_name = wc_sanitize_taxonomy_name( $attribute_name );
|
||||
|
||||
$term_ids = array();
|
||||
foreach ( $attribute_terms as $term ) {
|
||||
$term_ids[] = (int) term_exists( $term, 'pa_' . $sanitized_attribute_name )['term_id'];
|
||||
$term_ids = array();
|
||||
foreach ( $attribute_terms as $term ) {
|
||||
$term_ids[] = (int) term_exists( $term, 'pa_' . $sanitized_attribute_name )['term_id'];
|
||||
}
|
||||
|
||||
$attribute = new \WC_Product_Attribute();
|
||||
$attribute->set_id( $attribute_ids_by_name );
|
||||
$attribute->set_name( 'pa_' . $sanitized_attribute_name );
|
||||
$attribute->set_options( $term_ids );
|
||||
$attribute->set_visible( true );
|
||||
$attribute->set_variation( $defines_variation );
|
||||
$attributes[] = $attribute;
|
||||
}
|
||||
|
||||
$attribute = new \WC_Product_Attribute();
|
||||
$attribute->set_id( $attribute_ids_by_name );
|
||||
$attribute->set_name( 'pa_' . $sanitized_attribute_name );
|
||||
$attribute->set_options( $term_ids );
|
||||
$attribute->set_visible( true );
|
||||
$attribute->set_variation( $attributes_define_variations );
|
||||
$attributes[] = $attribute;
|
||||
}
|
||||
|
||||
$product = new $class_name();
|
||||
|
@ -141,7 +161,7 @@ class FiltererTest extends \WC_Unit_Test_Case {
|
|||
* @return array The product data, as generated by the REST API product creation entry point.
|
||||
*/
|
||||
private function create_simple_product( $attribute_terms_by_name, $in_stock ) {
|
||||
$product = $this->create_product_core( \WC_Product_Simple::class, $attribute_terms_by_name, false );
|
||||
$product = $this->create_product_core( \WC_Product_Simple::class, array( 'non_variation_defining' => $attribute_terms_by_name ) );
|
||||
|
||||
$product->set_stock_status( $in_stock ? 'instock' : 'outofstock' );
|
||||
|
||||
|
@ -164,6 +184,132 @@ class FiltererTest extends \WC_Unit_Test_Case {
|
|||
return $product;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a variable product.
|
||||
* Format for the supplied data:
|
||||
*
|
||||
* variation_attributes => [
|
||||
* Color => [Red, Blue, Green],
|
||||
* Size => [Big, Medium, Small]
|
||||
* ],
|
||||
* non_variation_attributes => [
|
||||
* Features => [Washable, Ironable]
|
||||
* ],
|
||||
* variations => [
|
||||
* [
|
||||
* defining_attributes => [
|
||||
* Color => Red,
|
||||
* Size => Small
|
||||
* ],
|
||||
* in_stock => true
|
||||
* ],
|
||||
* [
|
||||
* defining_attributes => [
|
||||
* Color => Red,
|
||||
* Size => null //Means "Any"
|
||||
* ],
|
||||
* in_stock => false
|
||||
* ],
|
||||
* ]
|
||||
*
|
||||
* Format for the returned data:
|
||||
*
|
||||
* [
|
||||
* id => 1,
|
||||
* variation_ids => [2,3]
|
||||
* ]
|
||||
*
|
||||
* @param array $data The data for creating the product.
|
||||
* @returns array The product and variation ids.
|
||||
*/
|
||||
private function create_variable_product( $data ) {
|
||||
|
||||
// * First create the main product.
|
||||
|
||||
$product = $this->create_product_core(
|
||||
\WC_Product_Variable::class,
|
||||
array(
|
||||
'non_variation_defining' => $data['non_variation_attributes'],
|
||||
'variation_defining' => $data['variation_attributes'],
|
||||
)
|
||||
);
|
||||
|
||||
$product->save();
|
||||
|
||||
$product_id = $product->get_id();
|
||||
|
||||
// * Now create the variations.
|
||||
|
||||
$variation_ids = array();
|
||||
|
||||
foreach ( $data['variations'] as $variation_data ) {
|
||||
$variation = new \WC_Product_Variation();
|
||||
$variation->set_props(
|
||||
array(
|
||||
'parent_id' => $product->get_id(),
|
||||
'regular_price' => 10,
|
||||
)
|
||||
);
|
||||
$attributes = array();
|
||||
foreach ( $variation_data['defining_attributes'] as $attribute_name => $attribute_value ) {
|
||||
$attribute_name = wc_attribute_taxonomy_name( $attribute_name );
|
||||
$attribute_value = wc_sanitize_taxonomy_name( $attribute_value );
|
||||
$attributes[ $attribute_name ] = $attribute_value;
|
||||
|
||||
}
|
||||
$variation->set_attributes( $attributes );
|
||||
$variation->set_stock_status( $variation_data['in_stock'] ? 'instock' : 'outofstock' );
|
||||
$variation->save();
|
||||
|
||||
$variation_ids[] = $variation->get_id();
|
||||
}
|
||||
|
||||
// This is needed because it's not done by the REST API.
|
||||
\WC_Product_Variable::sync_stock_status( $product_id );
|
||||
|
||||
// * And finally, insert the data in the lookup table.
|
||||
|
||||
$lookup_insert_clauses = array();
|
||||
$lookup_insert_values = array();
|
||||
|
||||
if ( ! empty( $data['non_variation_attributes'] ) ) {
|
||||
$main_product_in_stock = ! empty(
|
||||
array_filter(
|
||||
$data['variations'],
|
||||
function( $variation ) {
|
||||
return $variation['in_stock'];
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
foreach ( $data['non_variation_attributes'] as $name => $terms ) {
|
||||
$this->compose_lookup_table_insert( $product->get_id(), $product->get_id(), $name, $terms, $lookup_insert_clauses, $lookup_insert_values, $main_product_in_stock, false );
|
||||
}
|
||||
}
|
||||
|
||||
reset( $variation_ids );
|
||||
foreach ( $data['variations'] as $variation_data ) {
|
||||
$variation_id = current( $variation_ids );
|
||||
|
||||
foreach ( $variation_data['defining_attributes'] as $attribute_name => $attribute_value ) {
|
||||
if ( is_null( $attribute_value ) ) {
|
||||
$attribute_values = $data['variation_attributes'][ $attribute_name ];
|
||||
} else {
|
||||
$attribute_values = array( $attribute_value );
|
||||
}
|
||||
$this->compose_lookup_table_insert( $variation_id, $product->get_id(), $attribute_name, $attribute_values, $lookup_insert_clauses, $lookup_insert_values, $variation_data['in_stock'], true );
|
||||
}
|
||||
|
||||
next( $variation_ids );
|
||||
}
|
||||
|
||||
$this->run_lookup_table_insert( $lookup_insert_clauses, $lookup_insert_values );
|
||||
|
||||
return array(
|
||||
'id' => $product_id,
|
||||
'variation_ids' => $variation_ids,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compose the values part of a query to insert data in the lookup table.
|
||||
|
@ -179,7 +325,7 @@ class FiltererTest extends \WC_Unit_Test_Case {
|
|||
*/
|
||||
private function compose_lookup_table_insert( $product_id, $product_or_parent_id, $attribute_name, $terms, &$insert_query_parts, &$insert_query_values, $in_stock, $is_variation ) {
|
||||
$taxonomy_name = wc_attribute_taxonomy_name( $attribute_name );
|
||||
$term_objects = get_terms( $taxonomy_name );
|
||||
$term_objects = get_terms( $taxonomy_name, array( 'hide_empty' => false ) );
|
||||
$term_ids_by_names = wp_list_pluck( $term_objects, 'term_id', 'name' );
|
||||
|
||||
foreach ( $terms as $term ) {
|
||||
|
@ -255,7 +401,9 @@ class FiltererTest extends \WC_Unit_Test_Case {
|
|||
global $wp_the_query;
|
||||
|
||||
foreach ( $filters as $name => $values ) {
|
||||
$_GET[ 'filter_' . wc_sanitize_taxonomy_name( $name ) ] = join( ',', array_map( 'wc_sanitize_taxonomy_name', $values ) );
|
||||
if ( ! empty( $values ) ) {
|
||||
$_GET[ 'filter_' . wc_sanitize_taxonomy_name( $name ) ] = join( ',', array_map( 'wc_sanitize_taxonomy_name', $values ) );
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $query_types as $name => $value ) {
|
||||
|
@ -330,7 +478,7 @@ class FiltererTest extends \WC_Unit_Test_Case {
|
|||
*/
|
||||
public function test_filtering_simple_product_in_stock_using_lookup_table( $attributes, $filter_type, $expected_to_be_visible ) {
|
||||
$this->set_use_lookup_table( true );
|
||||
$this->test_filtering_simple_product_in_stock_core( $attributes, $filter_type, $expected_to_be_visible );
|
||||
$this->base_test_filtering_simple_product_in_stock( $attributes, $filter_type, $expected_to_be_visible );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -344,7 +492,7 @@ class FiltererTest extends \WC_Unit_Test_Case {
|
|||
*/
|
||||
public function test_filtering_simple_product_in_stock_not_using_lookup_table( $attributes, $filter_type, $expected_to_be_visible ) {
|
||||
$this->set_use_lookup_table( false );
|
||||
$this->test_filtering_simple_product_in_stock_core( $attributes, $filter_type, $expected_to_be_visible );
|
||||
$this->base_test_filtering_simple_product_in_stock( $attributes, $filter_type, $expected_to_be_visible );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -354,7 +502,7 @@ class FiltererTest extends \WC_Unit_Test_Case {
|
|||
* @param string $filter_type The filtering type, "or" or "and".
|
||||
* @param bool $expected_to_be_visible True if the product is expected to be returned by the query, false otherwise.
|
||||
*/
|
||||
private function test_filtering_simple_product_in_stock_core( $attributes, $filter_type, $expected_to_be_visible ) {
|
||||
private function base_test_filtering_simple_product_in_stock( $attributes, $filter_type, $expected_to_be_visible ) {
|
||||
$this->create_product_attribute( 'Color', array( 'Blue', 'Red', 'Green' ) );
|
||||
|
||||
$product = $this->create_simple_product(
|
||||
|
@ -409,7 +557,7 @@ class FiltererTest extends \WC_Unit_Test_Case {
|
|||
*/
|
||||
public function test_filtering_simple_product_out_of_stock_using_lookup_table( $hide_out_of_stock, $is_in_stock, $expected_to_be_visible ) {
|
||||
$this->set_use_lookup_table( true );
|
||||
$this->test_filtering_simple_product_out_of_stock_core( $hide_out_of_stock, $is_in_stock, $expected_to_be_visible );
|
||||
$this->base_test_filtering_simple_product_out_of_stock( $hide_out_of_stock, $is_in_stock, $expected_to_be_visible );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -428,7 +576,7 @@ class FiltererTest extends \WC_Unit_Test_Case {
|
|||
*/
|
||||
public function test_filtering_simple_product_out_of_stock_not_using_lookup_table( $hide_out_of_stock, $is_in_stock, $expected_to_be_visible ) {
|
||||
$this->set_use_lookup_table( false );
|
||||
$this->test_filtering_simple_product_out_of_stock_core( $hide_out_of_stock, $is_in_stock, $expected_to_be_visible );
|
||||
$this->base_test_filtering_simple_product_out_of_stock( $hide_out_of_stock, $is_in_stock, $expected_to_be_visible );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -438,7 +586,7 @@ class FiltererTest extends \WC_Unit_Test_Case {
|
|||
* @param bool $is_in_stock True if the product is in stock, false otherwise.
|
||||
* @param bool $expected_to_be_visible True if the product is expected to be returned by the query, false otherwise.
|
||||
*/
|
||||
private function test_filtering_simple_product_out_of_stock_core( $hide_out_of_stock, $is_in_stock, $expected_to_be_visible ) {
|
||||
private function base_test_filtering_simple_product_out_of_stock( $hide_out_of_stock, $is_in_stock, $expected_to_be_visible ) {
|
||||
$this->create_product_attribute( 'Features', array( 'Washable', 'Ironable', 'Elastic' ) );
|
||||
|
||||
$product = $this->create_simple_product(
|
||||
|
@ -490,7 +638,7 @@ class FiltererTest extends \WC_Unit_Test_Case {
|
|||
*/
|
||||
public function test_filtering_simple_product_by_multiple_attributes_using_lookup_table( $attributes_1, $attributes_2, $expected_to_be_visible ) {
|
||||
$this->set_use_lookup_table( true );
|
||||
$this->test_filtering_simple_product_by_multiple_attributes_core( $attributes_1, $attributes_2, $expected_to_be_visible );
|
||||
$this->base_test_filtering_simple_product_by_multiple_attributes( $attributes_1, $attributes_2, $expected_to_be_visible );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -506,7 +654,7 @@ class FiltererTest extends \WC_Unit_Test_Case {
|
|||
*/
|
||||
public function test_filtering_simple_product_by_multiple_attributes_not_using_using_lookup_table( $attributes_1, $attributes_2, $expected_to_be_visible ) {
|
||||
$this->set_use_lookup_table( false );
|
||||
$this->test_filtering_simple_product_by_multiple_attributes_core( $attributes_1, $attributes_2, $expected_to_be_visible );
|
||||
$this->base_test_filtering_simple_product_by_multiple_attributes( $attributes_1, $attributes_2, $expected_to_be_visible );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -516,7 +664,7 @@ class FiltererTest extends \WC_Unit_Test_Case {
|
|||
* @param array $attributes_2 The features attribute names that will be included in the query.
|
||||
* @param bool $expected_to_be_visible True if the product is expected to be returned by the query, false otherwise.
|
||||
*/
|
||||
private function test_filtering_simple_product_by_multiple_attributes_core( $attributes_1, $attributes_2, $expected_to_be_visible ) {
|
||||
private function base_test_filtering_simple_product_by_multiple_attributes( $attributes_1, $attributes_2, $expected_to_be_visible ) {
|
||||
$this->create_product_attribute( 'Color', array( 'Blue', 'Red' ) );
|
||||
$this->create_product_attribute( 'Features', array( 'Ironable', 'Washable' ) );
|
||||
|
||||
|
@ -548,4 +696,465 @@ class FiltererTest extends \WC_Unit_Test_Case {
|
|||
$this->assert_counters( 'Color', $expected_to_be_visible ? array( 'Blue' ) : array() );
|
||||
$this->assert_counters( 'Features', $expected_to_be_visible ? array( 'Ironable' ) : array() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for the test_filtering_variable_product_in_stock_for_non_variation_defining_attributes tests.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function data_provider_for_test_filtering_variable_product_in_stock_for_non_variation_defining_attributes() {
|
||||
return array(
|
||||
array( array(), 'and', true ),
|
||||
array( array(), 'or', true ),
|
||||
array( array( 'Washable' ), 'and', true ),
|
||||
array( array( 'Washable' ), 'or', true ),
|
||||
array( array( 'Washable', 'Ironable' ), 'and', true ),
|
||||
array( array( 'Washable', 'Ironable' ), 'or', true ),
|
||||
array( array( 'Elastic' ), 'and', false ),
|
||||
array( array( 'Elastic' ), 'or', false ),
|
||||
array( array( 'Washable', 'Elastic' ), 'and', false ),
|
||||
array( array( 'Washable', 'Elastic' ), 'or', true ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox The product query shows a variable product only if it's not filtered out by the specified attribute filters (for non-variation-defining attributes), using the lookup table.
|
||||
*
|
||||
* @dataProvider data_provider_for_test_filtering_variable_product_in_stock_for_non_variation_defining_attributes
|
||||
*
|
||||
* @param array $attributes The feature attribute names that will be included in the query.
|
||||
* @param string $filter_type The filtering type, "or" or "and".
|
||||
* @param bool $expected_to_be_visible True if the product is expected to be returned by the query, false otherwise.
|
||||
*/
|
||||
public function test_filtering_variable_product_in_stock_for_non_variation_defining_attributes_using_lookup_table( $attributes, $filter_type, $expected_to_be_visible ) {
|
||||
$this->set_use_lookup_table( true );
|
||||
$this->base_test_filtering_variable_product_in_stock_for_non_variation_defining_attributes( $attributes, $filter_type, $expected_to_be_visible );
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox The product query shows a variable product only if it's not filtered out by the specified attribute filters (for non-variation-defining attributes), not using the lookup table.
|
||||
*
|
||||
* @dataProvider data_provider_for_test_filtering_variable_product_in_stock_for_non_variation_defining_attributes
|
||||
*
|
||||
* @param array $attributes The feature attribute names that will be included in the query.
|
||||
* @param string $filter_type The filtering type, "or" or "and".
|
||||
* @param bool $expected_to_be_visible True if the product is expected to be returned by the query, false otherwise.
|
||||
*/
|
||||
public function test_filtering_variable_product_in_stock_for_non_variation_defining_attributes_not_using_lookup_table( $attributes, $filter_type, $expected_to_be_visible ) {
|
||||
$this->set_use_lookup_table( false );
|
||||
$this->base_test_filtering_variable_product_in_stock_for_non_variation_defining_attributes( $attributes, $filter_type, $expected_to_be_visible );
|
||||
}
|
||||
|
||||
/**
|
||||
* Main code for the test_filtering_variable_product_in_stock_for_non_variation_defining_attributes tests.
|
||||
*
|
||||
* @param array $attributes The feature attribute names that will be included in the query.
|
||||
* @param string $filter_type The filtering type, "or" or "and".
|
||||
* @param bool $expected_to_be_visible True if the product is expected to be returned by the query, false otherwise.
|
||||
*/
|
||||
private function base_test_filtering_variable_product_in_stock_for_non_variation_defining_attributes( $attributes, $filter_type, $expected_to_be_visible ) {
|
||||
$this->create_product_attribute( 'Color', array( 'Blue', 'Red' ) );
|
||||
$this->create_product_attribute( 'Features', array( 'Washable', 'Ironable', 'Elastic' ) );
|
||||
|
||||
$product = $this->create_variable_product(
|
||||
array(
|
||||
'variation_attributes' => array(
|
||||
'Color' => array( 'Blue', 'Red' ),
|
||||
),
|
||||
'non_variation_attributes' => array(
|
||||
'Features' => array( 'Washable', 'Ironable' ),
|
||||
),
|
||||
'variations' => array(
|
||||
array(
|
||||
'in_stock' => true,
|
||||
'defining_attributes' => array(
|
||||
'Color' => 'Blue',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'in_stock' => true,
|
||||
'defining_attributes' => array(
|
||||
'Color' => 'Red',
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
$filtered_product_ids = $this->do_product_request( array( 'Features' => $attributes ), array( 'Features' => $filter_type ) );
|
||||
|
||||
if ( $expected_to_be_visible ) {
|
||||
$this->assertEquals( array( $product['id'] ), $filtered_product_ids );
|
||||
} else {
|
||||
$this->assertEmpty( $filtered_product_ids );
|
||||
}
|
||||
|
||||
$expected_to_be_included_in_count = 'or' === $filter_type || $expected_to_be_visible;
|
||||
$this->assert_counters( 'Features', $expected_to_be_included_in_count ? array( 'Washable', 'Ironable' ) : array(), $filter_type );
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for the test_filtering_variable_product_out_of_stock tests.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function data_provider_for_test_filtering_variable_product_out_of_stock() {
|
||||
return array(
|
||||
array( false, true, true, true ),
|
||||
array( false, true, false, true ),
|
||||
array( false, false, true, true ),
|
||||
array( false, false, false, true ),
|
||||
array( true, true, true, true ),
|
||||
array( true, true, false, true ),
|
||||
array( true, false, true, true ),
|
||||
array( true, false, false, false ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox The product query shows a variable product only if at least one of the variations is in stock OR we don't have "hide out of stock items" set (using the lookup table).
|
||||
*
|
||||
* @dataProvider data_provider_for_test_filtering_variable_product_out_of_stock
|
||||
*
|
||||
* @param bool $hide_out_of_stock The value of the "hide out of stock products" option.
|
||||
* @param bool $variation_1_is_in_stock True if the first variation is in stock, false otherwise.
|
||||
* @param bool $variation_2_is_in_stock True if the second variation is in stock, false otherwise.
|
||||
* @param bool $expected_to_be_visible True if the product is expected to be returned by the query, false otherwise.
|
||||
*/
|
||||
public function test_filtering_variable_product_out_of_stock_using_lookup_table( $hide_out_of_stock, $variation_1_is_in_stock, $variation_2_is_in_stock, $expected_to_be_visible ) {
|
||||
$this->set_use_lookup_table( true );
|
||||
$this->base_test_filtering_variable_product_out_of_stock( $hide_out_of_stock, $variation_1_is_in_stock, $variation_2_is_in_stock, $expected_to_be_visible, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox The product query shows a variable product only if at least one of the variations is in stock OR we don't have "hide out of stock items" set (using the lookup table).
|
||||
*
|
||||
* @dataProvider data_provider_for_test_filtering_variable_product_out_of_stock
|
||||
*
|
||||
* @param bool $hide_out_of_stock The value of the "hide out of stock products" option.
|
||||
* @param bool $variation_1_is_in_stock True if the first variation is in stock, false otherwise.
|
||||
* @param bool $variation_2_is_in_stock True if the second variation is in stock, false otherwise.
|
||||
* @param bool $expected_to_be_visible True if the product is expected to be returned by the query, false otherwise.
|
||||
*/
|
||||
public function test_filtering_variable_product_out_of_stock_not_using_lookup_table( $hide_out_of_stock, $variation_1_is_in_stock, $variation_2_is_in_stock, $expected_to_be_visible ) {
|
||||
$this->set_use_lookup_table( false );
|
||||
$this->base_test_filtering_variable_product_out_of_stock( $hide_out_of_stock, $variation_1_is_in_stock, $variation_2_is_in_stock, $expected_to_be_visible, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Main code for the test_filtering_variable_product_out_of_stock tests.
|
||||
*
|
||||
* @param bool $hide_out_of_stock The value of the "hide out of stock products" option.
|
||||
* @param bool $variation_1_is_in_stock True if the first variation is in stock, false otherwise.
|
||||
* @param bool $variation_2_is_in_stock True if the second variation is in stock, false otherwise.
|
||||
* @param bool $expected_to_be_visible True if the product is expected to be returned by the query, false otherwise.
|
||||
* @param bool $using_lookup_table Are we using the lookup table?.
|
||||
*/
|
||||
private function base_test_filtering_variable_product_out_of_stock( $hide_out_of_stock, $variation_1_is_in_stock, $variation_2_is_in_stock, $expected_to_be_visible, $using_lookup_table ) {
|
||||
$this->create_product_attribute( 'Color', array( 'Blue', 'Red' ) );
|
||||
|
||||
$product = $this->create_variable_product(
|
||||
array(
|
||||
'variation_attributes' => array(
|
||||
'Color' => array( 'Blue', 'Red' ),
|
||||
),
|
||||
'non_variation_attributes' => array(),
|
||||
'variations' => array(
|
||||
array(
|
||||
'in_stock' => $variation_1_is_in_stock,
|
||||
'defining_attributes' => array(
|
||||
'Color' => 'Blue',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'in_stock' => $variation_2_is_in_stock,
|
||||
'defining_attributes' => array(
|
||||
'Color' => 'Red',
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
$this->set_hide_out_of_stock_items( $hide_out_of_stock );
|
||||
|
||||
$filtered_product_ids = $this->do_product_request( array() );
|
||||
|
||||
if ( $expected_to_be_visible ) {
|
||||
$this->assertEquals( array( $product['id'] ), $filtered_product_ids );
|
||||
} else {
|
||||
$this->assertEmpty( $filtered_product_ids );
|
||||
}
|
||||
|
||||
/**
|
||||
* When using the lookup table, attribute counters only take in account in stock variations.
|
||||
* When not using it, all variations are accounted if at least one of them has stock.
|
||||
*/
|
||||
|
||||
$expected_visible_attributes = array();
|
||||
if ( $using_lookup_table ) {
|
||||
if ( ! $hide_out_of_stock || $variation_1_is_in_stock ) {
|
||||
$expected_visible_attributes[] = 'Blue';
|
||||
}
|
||||
if ( ! $hide_out_of_stock || $variation_2_is_in_stock ) {
|
||||
$expected_visible_attributes[] = 'Red';
|
||||
}
|
||||
} elseif ( ! $hide_out_of_stock || $variation_1_is_in_stock || $variation_2_is_in_stock ) {
|
||||
$expected_visible_attributes = array( 'Blue', 'Red' );
|
||||
}
|
||||
|
||||
$this->assert_counters( 'Color', $expected_visible_attributes );
|
||||
}
|
||||
|
||||
/**
|
||||
* Base data provider for the test_filtering_variable_product_in_stock_for_variation_defining_attributes tests.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
private function data_provider_for_test_filtering_variable_product_in_stock_for_variation_defining_attributes_core() {
|
||||
return array(
|
||||
array( array(), 'and', true ),
|
||||
array( array(), 'or', true ),
|
||||
array( array( 'Blue' ), 'and', true ),
|
||||
array( array( 'Blue' ), 'or', true ),
|
||||
array( array( 'Blue', 'Red' ), 'and', true ),
|
||||
array( array( 'Blue', 'Red' ), 'or', true ),
|
||||
array( array( 'Green' ), 'and', false ),
|
||||
array( array( 'Green' ), 'or', false ),
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_filtering_variable_product_in_stock_for_variation_defining_attributes_using_lookup_table.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function data_provider_for_test_filtering_variable_product_in_stock_for_variation_defining_attributes_using_lookup_table() {
|
||||
$data = $this->data_provider_for_test_filtering_variable_product_in_stock_for_variation_defining_attributes_core();
|
||||
|
||||
/**
|
||||
* When filtering by an attribute having a variation AND another one not having it:
|
||||
* The product shows, since when dealing with variation attributes we're effectively doing OR.
|
||||
*/
|
||||
|
||||
$data[] = array( array( 'Blue', 'Green' ), 'and', true );
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox The product query shows a variable product only if it's not filtered out by the specified attribute filters (for variation-defining attributes), using the lookup table.
|
||||
*
|
||||
* Note that the difference with the simple product or the non-variation attributes case is that "and" is equivalent to "or".
|
||||
*
|
||||
* @dataProvider data_provider_for_test_filtering_variable_product_in_stock_for_variation_defining_attributes_using_lookup_table
|
||||
*
|
||||
* @param array $attributes The color attribute names that will be included in the query.
|
||||
* @param string $filter_type The filtering type, "or" or "and".
|
||||
* @param bool $expected_to_be_visible True if the product is expected to be returned by the query, false otherwise.
|
||||
*/
|
||||
public function test_filtering_variable_product_in_stock_for_variation_defining_attributes_using_lookup_table( $attributes, $filter_type, $expected_to_be_visible ) {
|
||||
$this->set_use_lookup_table( true );
|
||||
$this->base_test_filtering_variable_product_in_stock_for_variation_defining_attributes( $attributes, $filter_type, $expected_to_be_visible );
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_filtering_variable_product_in_stock_for_variation_defining_attributes_not_using_lookup_table.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function data_provider_for_test_filtering_variable_product_in_stock_for_variation_defining_attributes_not_using_lookup_table() {
|
||||
$data = $this->data_provider_for_test_filtering_variable_product_in_stock_for_variation_defining_attributes_core();
|
||||
|
||||
/**
|
||||
* When filtering by an attribute having a variation AND another one not having it:
|
||||
* The product doesn't show because variation attributes are treated as non-variation ones.
|
||||
*/
|
||||
|
||||
$data[] = array( array( 'Blue', 'Green' ), 'and', false );
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox The product query shows a variable product only if it's not filtered out by the specified attribute filters (for variation-defining attributes), not using the lookup table.
|
||||
*
|
||||
* Note that the difference with the simple product or the non-variation attributes case is that "and" is equivalent to "or".
|
||||
*
|
||||
* @dataProvider data_provider_for_test_filtering_variable_product_in_stock_for_variation_defining_attributes_not_using_lookup_table
|
||||
*
|
||||
* @param array $attributes The color attribute names that will be included in the query.
|
||||
* @param string $filter_type The filtering type, "or" or "and".
|
||||
* @param bool $expected_to_be_visible True if the product is expected to be returned by the query, false otherwise.
|
||||
*/
|
||||
public function test_filtering_variable_product_in_stock_for_variation_defining_attributes_not_using_lookup_table( $attributes, $filter_type, $expected_to_be_visible ) {
|
||||
$this->set_use_lookup_table( false );
|
||||
$this->base_test_filtering_variable_product_in_stock_for_variation_defining_attributes( $attributes, $filter_type, $expected_to_be_visible );
|
||||
}
|
||||
|
||||
/**
|
||||
* Main code for the test_filtering_variable_product_in_stock_for_variation_defining_attributes tests.
|
||||
*
|
||||
* @param array $attributes The color attribute names that will be included in the query.
|
||||
* @param string $filter_type The filtering type, "or" or "and".
|
||||
* @param bool $expected_to_be_visible True if the product is expected to be returned by the query, false otherwise.
|
||||
*/
|
||||
private function base_test_filtering_variable_product_in_stock_for_variation_defining_attributes( $attributes, $filter_type, $expected_to_be_visible ) {
|
||||
$this->create_product_attribute( 'Color', array( 'Blue', 'Red', 'Green' ) );
|
||||
|
||||
$product = $this->create_variable_product(
|
||||
array(
|
||||
'variation_attributes' => array(
|
||||
'Color' => array( 'Blue', 'Red' ),
|
||||
),
|
||||
'non_variation_attributes' => array(),
|
||||
'variations' => array(
|
||||
array(
|
||||
'in_stock' => true,
|
||||
'defining_attributes' => array(
|
||||
'Color' => 'Blue',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'in_stock' => true,
|
||||
'defining_attributes' => array(
|
||||
'Color' => 'Red',
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
$filtered_product_ids = $this->do_product_request( array( 'Color' => $attributes ), array( 'Color' => $filter_type ) );
|
||||
|
||||
if ( $expected_to_be_visible ) {
|
||||
$this->assertEquals( array( $product['id'] ), $filtered_product_ids );
|
||||
} else {
|
||||
$this->assertEmpty( $filtered_product_ids );
|
||||
}
|
||||
|
||||
$expected_counted_attributes = 'or' === $filter_type || $expected_to_be_visible ? array( 'Blue', 'Red' ) : array();
|
||||
$this->assert_counters( 'Color', $expected_counted_attributes, $filter_type );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Base data provider for the test_filtering_variable_product_in_stock_for_variation_defining_attributes_with_any_value tests.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
private function data_provider_for_test_filtering_variable_product_in_stock_for_variation_defining_attributes_with_any_value_core() {
|
||||
return array(
|
||||
array( array(), 'and', true ),
|
||||
array( array(), 'or', true ),
|
||||
array( array( 'Blue' ), 'and', true ),
|
||||
array( array( 'Blue' ), 'or', true ),
|
||||
array( array( 'Red' ), 'and', true ),
|
||||
array( array( 'Red' ), 'or', true ),
|
||||
array( array( 'Green' ), 'and', true ),
|
||||
array( array( 'Green' ), 'or', true ),
|
||||
array( array( 'White' ), 'and', false ),
|
||||
array( array( 'White' ), 'or', false ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_filtering_variable_product_in_stock_for_variation_defining_attributes_with_any_value_using_lookup_table.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function data_provider_for_test_filtering_variable_product_in_stock_for_variation_defining_attributes_with_any_value_using_lookup_table() {
|
||||
$data = $this->data_provider_for_test_filtering_variable_product_in_stock_for_variation_defining_attributes_with_any_value_core();
|
||||
|
||||
/**
|
||||
* When filtering by attributes having a variation AND others not having it:
|
||||
* The product shows, since when dealing with variation attributes we're effectively doing OR.
|
||||
*/
|
||||
$data[] = array( array( 'Blue', 'Red', 'Green', 'White' ), 'and', true );
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox The product query shows a variable product only if it's not filtered out by the specified attribute filters (for variation-defining attributes, with "Any" values), using the lookup table.
|
||||
*
|
||||
* @dataProvider data_provider_for_test_filtering_variable_product_in_stock_for_variation_defining_attributes_with_any_value_using_lookup_table
|
||||
*
|
||||
* @param array $attributes The color attribute names that will be included in the query.
|
||||
* @param string $filter_type The filtering type, "or" or "and".
|
||||
* @param bool $expected_to_be_visible True if the product is expected to be returned by the query, false otherwise.
|
||||
*/
|
||||
public function test_filtering_variable_product_in_stock_for_variation_defining_attributes_with_any_value_using_lookup_table( $attributes, $filter_type, $expected_to_be_visible ) {
|
||||
$this->set_use_lookup_table( true );
|
||||
$this->base_test_filtering_variable_product_in_stock_for_variation_defining_attributes_with_any_value( $attributes, $filter_type, $expected_to_be_visible );
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_filtering_variable_product_in_stock_for_variation_defining_attributes_with_any_value_not_using_lookup_table.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function data_provider_for_test_filtering_variable_product_in_stock_for_variation_defining_attributes_with_any_value_not_using_lookup_table() {
|
||||
$data = $this->data_provider_for_test_filtering_variable_product_in_stock_for_variation_defining_attributes_with_any_value_core();
|
||||
|
||||
/**
|
||||
* When filtering by attributes having a variation AND others not having it:
|
||||
* The product doesn't show because variation attributes are treated as non-variation ones.
|
||||
*/
|
||||
$data[] = array( array( 'Blue', 'Red', 'Green', 'White' ), 'and', false );
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox The product query shows a variable product only if it's not filtered out by the specified attribute filters (for variation-defining attributes, with "Any" values), not using the lookup table.
|
||||
*
|
||||
* @dataProvider data_provider_for_test_filtering_variable_product_in_stock_for_variation_defining_attributes_with_any_value_not_using_lookup_table
|
||||
*
|
||||
* @param array $attributes The color attribute names that will be included in the query.
|
||||
* @param string $filter_type The filtering type, "or" or "and".
|
||||
* @param bool $expected_to_be_visible True if the product is expected to be returned by the query, false otherwise.
|
||||
*/
|
||||
public function test_filtering_variable_product_in_stock_for_variation_defining_attributes_with_any_value_not_using_lookup_table( $attributes, $filter_type, $expected_to_be_visible ) {
|
||||
$this->set_use_lookup_table( false );
|
||||
$this->base_test_filtering_variable_product_in_stock_for_variation_defining_attributes_with_any_value( $attributes, $filter_type, $expected_to_be_visible );
|
||||
}
|
||||
|
||||
/**
|
||||
* Main code for the test_filtering_variable_product_in_stock_for_variation_defining_attributes_with_any_value tests.
|
||||
*
|
||||
* @param array $attributes The color attribute names that will be included in the query.
|
||||
* @param string $filter_type The filtering type, "or" or "and".
|
||||
* @param bool $expected_to_be_visible True if the product is expected to be returned by the query, false otherwise.
|
||||
*/
|
||||
private function base_test_filtering_variable_product_in_stock_for_variation_defining_attributes_with_any_value( $attributes, $filter_type, $expected_to_be_visible ) {
|
||||
$this->create_product_attribute( 'Color', array( 'Blue', 'Red', 'Green', 'White' ) );
|
||||
|
||||
$product = $this->create_variable_product(
|
||||
array(
|
||||
'variation_attributes' => array(
|
||||
'Color' => array( 'Blue', 'Red', 'Green' ),
|
||||
),
|
||||
'non_variation_attributes' => array(),
|
||||
'variations' => array(
|
||||
array(
|
||||
'in_stock' => true,
|
||||
'defining_attributes' => array(
|
||||
'Color' => null,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
$filtered_product_ids = $this->do_product_request( array( 'Color' => $attributes ), array( 'Color' => $filter_type ) );
|
||||
|
||||
if ( $expected_to_be_visible ) {
|
||||
$this->assertEquals( array( $product['id'] ), $filtered_product_ids );
|
||||
} else {
|
||||
$this->assertEmpty( $filtered_product_ids );
|
||||
}
|
||||
|
||||
$expected_to_be_included_in_count = 'or' === $filter_type || $expected_to_be_visible;
|
||||
$this->assert_counters( 'Color', $expected_to_be_included_in_count ? array( 'Blue', 'Red', 'Green' ) : array(), $filter_type );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue