Fix type handling and default value for remote API transformers (#44418)
* Add default value check and parameter, change transformer behaviour around defaults and types, update and add tests * Changelog
This commit is contained in:
parent
e5e641180b
commit
8ba2942099
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: update
|
||||
|
||||
Fix type handling and default value for remote API transformers
|
|
@ -20,13 +20,14 @@ class OptionRuleProcessor implements RuleProcessorInterface {
|
|||
* @return bool The result of the operation.
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
$is_contains = $rule->operation && strpos( $rule->operation, 'contains' ) !== false;
|
||||
$default_value = $is_contains ? array() : false;
|
||||
$default = isset( $rule->default ) ? $rule->default : $default_value;
|
||||
$option_value = $this->get_option_value( $rule, $default, $is_contains );
|
||||
$is_contains = $rule->operation && strpos( $rule->operation, 'contains' ) !== false;
|
||||
$default_value = $is_contains ? array() : false;
|
||||
$is_default_set = property_exists( $rule, 'default' );
|
||||
$default = $is_default_set ? $rule->default : $default_value;
|
||||
$option_value = $this->get_option_value( $rule, $default, $is_contains );
|
||||
|
||||
if ( isset( $rule->transformers ) && is_array( $rule->transformers ) ) {
|
||||
$option_value = TransformerService::apply( $option_value, $rule->transformers, $default );
|
||||
$option_value = TransformerService::apply( $option_value, $rule->transformers, $is_default_set, $default );
|
||||
}
|
||||
|
||||
return ComparisonOperation::compare(
|
||||
|
|
|
@ -36,12 +36,13 @@ class TransformerService {
|
|||
*
|
||||
* @param mixed $target_value a value to transform.
|
||||
* @param array $transformer_configs transform configuration.
|
||||
* @param bool $is_default_set flag on is default value set.
|
||||
* @param string $default default value.
|
||||
*
|
||||
* @throws InvalidArgumentException Throws when one of the requried arguments is missing.
|
||||
* @return mixed|null
|
||||
*/
|
||||
public static function apply( $target_value, array $transformer_configs, $default ) {
|
||||
public static function apply( $target_value, array $transformer_configs, $is_default_set, $default ) {
|
||||
foreach ( $transformer_configs as $transformer_config ) {
|
||||
if ( ! isset( $transformer_config->use ) ) {
|
||||
throw new InvalidArgumentException( 'Missing required config value: use' );
|
||||
|
@ -56,13 +57,25 @@ class TransformerService {
|
|||
throw new InvalidArgumentException( "Unable to find a transformer by name: {$transformer_config->use}" );
|
||||
}
|
||||
|
||||
$transformed_value = $transformer->transform( $target_value, $transformer_config->arguments, $default );
|
||||
// if the transformer returns null, then return the previously transformed value.
|
||||
if ( null === $transformed_value ) {
|
||||
return $target_value;
|
||||
$target_value = $transformer->transform( $target_value, $transformer_config->arguments, $is_default_set ? $default : null );
|
||||
|
||||
// Break early when there's no more value to traverse.
|
||||
if ( null === $target_value ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $is_default_set ) {
|
||||
// Nulls always return the default value.
|
||||
if ( null === $target_value ) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$target_value = $transformed_value;
|
||||
// When type of the default value is different from the target value, return the default value
|
||||
// to ensure type safety.
|
||||
if ( gettype( $default ) !== gettype( $target_value ) ) {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
return $target_value;
|
||||
|
|
|
@ -34,7 +34,7 @@ class WC_Admin_Tests_RemoteInboxNotifications_TransformerService extends WC_Unit
|
|||
public function test_it_throw_exception_when_transformer_config_is_missing_use() {
|
||||
$this->expectException( InvalidArgumentException::class );
|
||||
$this->expectExceptionMessage( 'Missing required config value: use' );
|
||||
TransformerService::apply( array( 'value' ), array( new stdClass() ), null );
|
||||
TransformerService::apply( array( 'value' ), array( new stdClass() ), false, null );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,22 +43,65 @@ class WC_Admin_Tests_RemoteInboxNotifications_TransformerService extends WC_Unit
|
|||
public function test_it_throws_exception_when_transformer_is_not_found() {
|
||||
$this->expectExceptionMessage( 'Unable to find a transformer by name: i_do_not_exist' );
|
||||
$transformer = $this->transformer_config( 'i_do_not_exist' );
|
||||
TransformerService::apply( array( 'value' ), array( $transformer ), null );
|
||||
TransformerService::apply( array( 'value' ), array( $transformer ), false, null );
|
||||
}
|
||||
|
||||
/**
|
||||
* Given two transformers
|
||||
* When the second transformer returns null
|
||||
* Then the value transformed by the first transformer should be returned.
|
||||
* Then the default value should be returned.
|
||||
*/
|
||||
public function test_it_returns_previously_transformed_value_when_transformer_returns_null() {
|
||||
public function test_it_returns_default_when_transformer_returns_null() {
|
||||
$dot_notation = $this->transformer_config( 'dot_notation', array( 'path' => 'industries' ) );
|
||||
$array_search = $this->transformer_config( 'array_search', array( 'value' => 'i_do_not_exist' ) );
|
||||
$items = array(
|
||||
'industries' => array( 'item1', 'item2' ),
|
||||
);
|
||||
$result = TransformerService::apply( $items, array( $dot_notation, $array_search ), null );
|
||||
$this->assertEquals( $result, $items['industries'] );
|
||||
$result = TransformerService::apply( $items, array( $dot_notation, $array_search ), true, 'default' );
|
||||
$this->assertEquals( $result, 'default' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Given two transformers
|
||||
* When the second transformer returns null but no default is set
|
||||
* Then the final result should returned.
|
||||
*/
|
||||
public function test_it_returns_null_when_transformer_returns_null() {
|
||||
$dot_notation = $this->transformer_config( 'dot_notation', array( 'path' => 'industries' ) );
|
||||
$array_search = $this->transformer_config( 'array_search', array( 'value' => 'i_do_not_exist' ) );
|
||||
$items = array(
|
||||
'industries' => array( 'item1', 'item2' ),
|
||||
);
|
||||
$result = TransformerService::apply( $items, array( $dot_notation, $array_search ), false, null );
|
||||
$this->assertEquals( $result, null );
|
||||
}
|
||||
|
||||
/**
|
||||
* Given two transformers
|
||||
* When the transformed value type is different from the default value type and default is set
|
||||
* Then the default value should be returned.
|
||||
*/
|
||||
public function test_it_returns_default_when_transformer_returns_different_type() {
|
||||
$dot_notation = $this->transformer_config( 'dot_notation', array( 'path' => 'industries' ) );
|
||||
$items = array(
|
||||
'industries' => array(),
|
||||
);
|
||||
$result = TransformerService::apply( $items, array( $dot_notation ), true, 'clothing' );
|
||||
$this->assertEquals( $result, 'clothing' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Given two transformers
|
||||
* When the transformed value type is the same with the default value type and default is set
|
||||
* Then the transformed value should be returned.
|
||||
*/
|
||||
public function test_it_returns_default_when_transformer_returns_same_type() {
|
||||
$dot_notation = $this->transformer_config( 'dot_notation', array( 'path' => 'industries' ) );
|
||||
$items = array(
|
||||
'industries' => 'food_and_beverage',
|
||||
);
|
||||
$result = TransformerService::apply( $items, array( $dot_notation ), true, 'clothing' );
|
||||
$this->assertEquals( $result, 'food_and_beverage' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -94,7 +137,7 @@ class WC_Admin_Tests_RemoteInboxNotifications_TransformerService extends WC_Unit
|
|||
$array_flatten = $this->transformer_config( 'array_flatten' );
|
||||
$array_search = $this->transformer_config( 'array_search', array( 'value' => 'mothra-member' ) );
|
||||
|
||||
$result = TransformerService::apply( $items, array( $dot_notation, $array_column, $array_flatten, $array_search ), null );
|
||||
$result = TransformerService::apply( $items, array( $dot_notation, $array_column, $array_flatten, $array_search ), false, null );
|
||||
|
||||
// Then.
|
||||
$this->assertEquals( 'mothra-member', $result );
|
||||
|
|
Loading…
Reference in New Issue