diff --git a/includes/AlmaSettings.php b/includes/AlmaSettings.php index cba71050..6486eb4f 100644 --- a/includes/AlmaSettings.php +++ b/includes/AlmaSettings.php @@ -88,9 +88,9 @@ class AlmaSettings { public $display_cart_eligibility; /** - * Bool if In Page is activated. + * In Page is activated ("yes" or "no"). * - * @var bool + * @var string */ public $display_in_page; diff --git a/includes/Services/CollectCmsDataService.php b/includes/Services/CollectCmsDataService.php index a75ef87b..0b70819b 100644 --- a/includes/Services/CollectCmsDataService.php +++ b/includes/Services/CollectCmsDataService.php @@ -25,6 +25,7 @@ use Alma\Woocommerce\Helpers\ToolsHelper; use Alma\Woocommerce\WcProxy\FunctionsProxy; use Alma\Woocommerce\WcProxy\OptionProxy; +use Alma\Woocommerce\WcProxy\PaymentGatewaysProxy; use Alma\Woocommerce\WcProxy\ThemeProxy; /** @@ -180,13 +181,14 @@ private function get_cms_features() { 'widget_cart_activated' => 'yes' === $this->alma_settings->display_cart_eligibility, 'widget_product_activated' => 'yes' === $this->alma_settings->display_product_eligibility, 'used_fee_plans' => $this->format_fee_plans(), - 'in_page_activated' => $this->alma_settings->display_in_page, + 'in_page_activated' => 'yes' === $this->alma_settings->display_in_page, 'log_activated' => 'yes' === $this->alma_settings->debug, 'excluded_categories' => $this->alma_settings->excluded_products_list, 'is_multisite' => is_multisite(), 'specific_features' => array( ( in_array( 'alma-woocommerce-gateway/alma-gateway-for-woocommerce.php', $auto_update_plugins, true ) ) ? 'auto_update' : null, ), + 'payment_method_position' => $this->get_alma_gateway_position(), ) ); } @@ -255,4 +257,33 @@ private function format_fee_plans() { return $plans; } + /** + * Get Alma gateway position. + * Remove alma_* gateways from the list of gateways. + * Sort gateways to re-index all. + * + * @return int + */ + private function get_alma_gateway_position() { + $gateways = PaymentGatewaysProxy::get_instance()->get_payment_gateways(); + $gateway_position = 0; + + $gateways = array_filter( + $gateways, + function( $gateway) { + return ! preg_match( '/alma_.+/', $gateway->id ); + } + ); + + $gateways = array_values( $gateways ); + + foreach ( $gateways as $position => $gateway ) { + if ( 'alma' === $gateway->id ) { + $gateway_position = $position + 1; + } + } + + return $gateway_position; + } + } diff --git a/includes/WcProxy/PaymentGatewaysProxy.php b/includes/WcProxy/PaymentGatewaysProxy.php new file mode 100644 index 00000000..d6a12eb0 --- /dev/null +++ b/includes/WcProxy/PaymentGatewaysProxy.php @@ -0,0 +1,64 @@ +wc_payment_gateway = $wc_payment_gateway ? $wc_payment_gateway : WC_Payment_Gateways::instance(); + } + + /** + * Get the singleton instance of PaymentGatewaysProxy. + * + * @param WC_Payment_Gateways|null $wc_payment_gateway + * @return PaymentGatewaysProxy + */ + public static function get_instance( $wc_payment_gateway = null) { + if (null === self::$instance) { + self::$instance = new self( $wc_payment_gateway ); + } + + return self::$instance; + } + + /** + * Get payment gateways. + * + * @return array + */ + public function get_payment_gateways() { + return $this->wc_payment_gateway->payment_gateways(); + } + + /** + * Used for unit tests. + * + * @return void + */ + public static function reset_instance() { + self::$instance = null; + } + +} diff --git a/tests/Services/CollectCmsDataServiceTest.php b/tests/Services/CollectCmsDataServiceTest.php index d36844ac..bf462b19 100644 --- a/tests/Services/CollectCmsDataServiceTest.php +++ b/tests/Services/CollectCmsDataServiceTest.php @@ -17,12 +17,12 @@ use Alma\Woocommerce\Services\CollectCmsDataService; use Alma\Woocommerce\WcProxy\FunctionsProxy; use Alma\Woocommerce\WcProxy\OptionProxy; +use Alma\Woocommerce\WcProxy\PaymentGatewaysProxy; use Alma\Woocommerce\WcProxy\ThemeProxy; use WP_UnitTestCase; use function PHPUnit\Framework\assertNull; -class CollectCmsDataServiceTest extends WP_UnitTestCase -{ +class CollectCmsDataServiceTest extends WP_UnitTestCase { protected $collect_cms_data_service; protected $alma_logger_mock; protected $alma_settings_mock; @@ -34,31 +34,32 @@ class CollectCmsDataServiceTest extends WP_UnitTestCase protected $fee_plan_mock; protected $tools_helper_mock; - public function set_up() - { - $this->alma_logger_mock = $this->createMock(AlmaLogger::class); - $this->alma_settings_mock = $this->createMock(AlmaSettings::class); - $this->alma_settings_mock->method('is_enabled')->willReturn(true); - $this->alma_settings_mock->display_cart_eligibility = 'yes'; + public function set_up() { + $this->alma_logger_mock = $this->createMock( AlmaLogger::class ); + $this->alma_settings_mock = $this->createMock( AlmaSettings::class ); + $this->alma_settings_mock->method( 'is_enabled' )->willReturn( true ); + $this->alma_settings_mock->display_cart_eligibility = 'yes'; $this->alma_settings_mock->display_product_eligibility = 'no'; - $this->alma_settings_mock->display_in_page = false; - $this->alma_settings_mock->debug = "yes"; - $this->alma_settings_mock->method('is_plan_enabled')->willReturn(true); - $this->alma_settings_mock->method('get_min_amount')->willReturn(0); - $this->alma_settings_mock->method('get_max_amount')->willReturn(1000); - $this->fee_plan_mock = $this->createMock(FeePlan::class); - $this->fee_plan_mock->method('getPlanKey')->willReturn('general_1_0_0'); - $this->alma_settings_mock->allowed_fee_plans = [$this->fee_plan_mock]; - $this->alma_settings_mock->fee_plan_helper = $this->createMock(FeePlanHelper::class); + $this->alma_settings_mock->display_in_page = 'no'; + $this->alma_settings_mock->debug = 'yes'; + $this->alma_settings_mock->method( 'is_plan_enabled' )->willReturn( true ); + $this->alma_settings_mock->method( 'get_min_amount' )->willReturn( 0 ); + $this->alma_settings_mock->method( 'get_max_amount' )->willReturn( 1000 ); + $this->fee_plan_mock = $this->createMock( FeePlan::class ); + $this->fee_plan_mock->method( 'getPlanKey' )->willReturn( 'general_1_0_0' ); + $this->alma_settings_mock->allowed_fee_plans = [ $this->fee_plan_mock ]; + $this->alma_settings_mock->fee_plan_helper = $this->createMock( FeePlanHelper::class ); $this->alma_settings_mock->excluded_products_list = []; - $this->security_helper_mock = $this->createMock(SecurityHelper::class); - $this->payload_formatter_mock = $this->createMock(PayloadFormatter::class); - $this->option_proxy_mock = $this->createMock(OptionProxy::class); - $this->theme_proxy_mock = $this->createMock(ThemeProxy::class); - $this->theme_proxy_mock->method('get_name')->willReturn('Storefront'); - $this->theme_proxy_mock->method('get_version')->willReturn('v.4.5'); - $this->functions_proxy_mock = $this->createMock(FunctionsProxy::class); - $this->tools_helper_mock = $this->createMock(ToolsHelper::class); + $this->security_helper_mock = $this->createMock( SecurityHelper::class ); + $this->payload_formatter_mock = $this->createMock( PayloadFormatter::class ); + $this->option_proxy_mock = $this->createMock( OptionProxy::class ); + $this->theme_proxy_mock = $this->createMock( ThemeProxy::class ); + $this->theme_proxy_mock->method( 'get_name' )->willReturn( 'Storefront' ); + $this->theme_proxy_mock->method( 'get_version' )->willReturn( 'v.4.5' ); + $this->functions_proxy_mock = $this->createMock( FunctionsProxy::class ); + $this->tools_helper_mock = $this->createMock( ToolsHelper::class ); + + $this->set_payment_gateways(); $this->collect_cms_data_service = new CollectCmsDataService( $this->alma_settings_mock, @@ -72,131 +73,177 @@ public function set_up() ); } - public function test_send_url() - { - $this->alma_settings_mock->alma_client = $this->createMock(Client::class); - $this->alma_settings_mock->alma_client->configuration = $this->createMock(Configuration::class); + public function tear_down() { + PaymentGatewaysProxy::reset_instance(); + } + + public function test_send_url() { + $this->alma_settings_mock->alma_client = $this->createMock( Client::class ); + $this->alma_settings_mock->alma_client->configuration = $this->createMock( Configuration::class ); - $this->tools_helper_mock->expects($this->once()) - ->method('url_for_webhook') - ->with(CollectCmsDataService::COLLECT_URL) - ->willReturn('http://example.com/woocommerce_api_alma_collect_data_url'); + $this->tools_helper_mock->expects( $this->once() ) + ->method( 'url_for_webhook' ) + ->with( CollectCmsDataService::COLLECT_URL ) + ->willReturn( 'http://example.com/woocommerce_api_alma_collect_data_url' ); - $this->alma_settings_mock->alma_client->configuration->expects($this->once()) - ->method('sendIntegrationsConfigurationsUrl') - ->with('http://example.com/woocommerce_api_alma_collect_data_url'); + $this->alma_settings_mock->alma_client->configuration->expects( $this->once() ) + ->method( 'sendIntegrationsConfigurationsUrl' ) + ->with( 'http://example.com/woocommerce_api_alma_collect_data_url' ); - assertNull($this->collect_cms_data_service->send_url()); + assertNull( $this->collect_cms_data_service->send_url() ); } - public function test_handle_collect_cms_data_without_signature_header() - { - $this->alma_logger_mock->expects($this->once()) - ->method('error') - ->with("Header key X-Alma-Signature doesn't exist"); + public function test_handle_collect_cms_data_without_signature_header() { + $this->alma_logger_mock->expects( $this->once() ) + ->method( 'error' ) + ->with( "Header key X-Alma-Signature doesn't exist" ); - $this->functions_proxy_mock->expects($this->once()) - ->method('send_http_response') - ->with(array('error' => 'Header key X-Alma-Signature doesn\'t exist'), 403); - $this->security_helper_mock->expects($this->never())->method('validate_collect_data_signature'); + $this->functions_proxy_mock->expects( $this->once() ) + ->method( 'send_http_response' ) + ->with( array( 'error' => 'Header key X-Alma-Signature doesn\'t exist' ), 403 ); + $this->security_helper_mock->expects( $this->never() )->method( 'validate_collect_data_signature' ); - $this->assertNull($this->collect_cms_data_service->handle_collect_cms_data()); + $this->assertNull( $this->collect_cms_data_service->handle_collect_cms_data() ); } - public function test_handle_collect_cms_data_with_invalid_signature() - { + public function test_handle_collect_cms_data_with_invalid_signature() { $_SERVER['HTTP_X_ALMA_SIGNATURE'] = 'invalid_signature'; - $this->security_helper_mock->expects($this->once()) - ->method('validate_collect_data_signature') - ->willThrowException(new AlmaInvalidSignatureException("Invalid signature")); + $this->security_helper_mock->expects( $this->once() ) + ->method( 'validate_collect_data_signature' ) + ->willThrowException( new AlmaInvalidSignatureException( "Invalid signature" ) ); - $this->alma_logger_mock->expects($this->once()) - ->method('error') - ->with("Invalid signature"); + $this->alma_logger_mock->expects( $this->once() ) + ->method( 'error' ) + ->with( "Invalid signature" ); - $this->functions_proxy_mock->expects($this->once()) - ->method('send_http_response') - ->with(array('error' => 'Invalid signature'), 403); + $this->functions_proxy_mock->expects( $this->once() ) + ->method( 'send_http_response' ) + ->with( array( 'error' => 'Invalid signature' ), 403 ); - $this->payload_formatter_mock->expects($this->never())->method('formatConfigurationPayload'); + $this->payload_formatter_mock->expects( $this->never() )->method( 'formatConfigurationPayload' ); - $this->assertNull($this->collect_cms_data_service->handle_collect_cms_data()); + $this->assertNull( $this->collect_cms_data_service->handle_collect_cms_data() ); } /** * @dataProvider get_auto_update_plugins_settings */ - public function test_handle_collect_cms_data_with_valid_signature($specific_features, $auto_update_plugins) - { + public function test_handle_collect_cms_data_with_valid_signature( $specific_features, $auto_update_plugins ) { $_SERVER['HTTP_X_ALMA_SIGNATURE'] = 'valid_signature'; - $this->security_helper_mock->expects($this->once()) - ->method('validate_collect_data_signature'); + $this->security_helper_mock->expects( $this->once() ) + ->method( 'validate_collect_data_signature' ); $valueMap = [ - ['active_plugins', false, []], - ['woocommerce_version', false, 'v.4.2'], - ['auto_update_plugins', [], $auto_update_plugins] + [ 'active_plugins', false, [] ], + [ 'woocommerce_version', false, 'v.4.2' ], + [ 'auto_update_plugins', [], $auto_update_plugins ] ]; - $this->option_proxy_mock->method('get_option')->willReturnMap($valueMap); + $this->option_proxy_mock->method( 'get_option' )->willReturnMap( $valueMap ); - $cms_info = new CmsInfo([ - 'cms_name' => 'WooCommerce', - 'cms_version' => 'v.4.2', + $cms_info = new CmsInfo( [ + 'cms_name' => 'WooCommerce', + 'cms_version' => 'v.4.2', 'third_parties_plugins' => [], - 'theme_name' => 'Storefront', - 'theme_version' => 'v.4.5', - 'language_name' => 'PHP', - 'language_version' => phpversion(), - 'alma_plugin_version' => ALMA_VERSION, - 'alma_sdk_version' => Client::VERSION, - 'alma_sdk_name' => 'alma/alma-php-client', - ]); - - $cms_features = new CmsFeatures([ - 'alma_enabled' => true, - 'widget_cart_activated' => true, + 'theme_name' => 'Storefront', + 'theme_version' => 'v.4.5', + 'language_name' => 'PHP', + 'language_version' => phpversion(), + 'alma_plugin_version' => ALMA_VERSION, + 'alma_sdk_version' => Client::VERSION, + 'alma_sdk_name' => 'alma/alma-php-client', + ] ); + + $cms_features = new CmsFeatures( [ + 'alma_enabled' => true, + 'widget_cart_activated' => true, 'widget_product_activated' => false, - 'used_fee_plans' => ['general_1_0_0' => ['enabled' => true, 'min_amount' => 0, 'max_amount' => 1000]], - 'in_page_activated' => false, - 'log_activated' => true, - 'excluded_categories' => [], - 'is_multisite' => is_multisite(), - 'specific_features' => $specific_features, - ]); + 'used_fee_plans' => [ + 'general_1_0_0' => [ + 'enabled' => true, + 'min_amount' => 0, + 'max_amount' => 1000 + ] + ], + 'payment_method_position' => 3, + 'in_page_activated' => false, + 'log_activated' => true, + 'excluded_categories' => [], + 'is_multisite' => is_multisite(), + 'specific_features' => $specific_features, + ] ); $payload_formatter_return = [ - 'cms_info' => $cms_info->getProperties(), + 'cms_info' => $cms_info->getProperties(), 'cms_features' => $cms_features->getProperties() ]; - $this->payload_formatter_mock->expects($this->once()) - ->method('formatConfigurationPayload') - ->with($cms_info, $cms_features) - ->willReturn($payload_formatter_return); + $this->payload_formatter_mock->expects( $this->once() ) + ->method( 'formatConfigurationPayload' ) + ->with( $cms_info, $cms_features ) + ->willReturn( $payload_formatter_return ); + + $this->functions_proxy_mock->expects( $this->once() ) + ->method( 'send_http_response' ) + ->with( $payload_formatter_return, 200 ); - $this->functions_proxy_mock->expects($this->once()) - ->method('send_http_response') - ->with($payload_formatter_return, 200); - $this->assertNull($this->collect_cms_data_service->handle_collect_cms_data()); + $this->assertNull( $this->collect_cms_data_service->handle_collect_cms_data() ); } public function get_auto_update_plugins_settings() { return [ - 'Auto update plugins key does not exist' => [ - 'specific_features' => [null], + 'Auto update plugins key does not exist' => [ + 'specific_features' => [ null ], 'auto_update_plugins' => [] ], 'Auto update plugins key exists and nor contain Alma plugin' => [ - 'specific_features' => [null], - 'auto_update_plugins' => ['woocommerce/woocommerce.php'] + 'specific_features' => [ null ], + 'auto_update_plugins' => [ 'woocommerce/woocommerce.php' ] ], - 'Auto update plugins key exists and contain Alma plugin' => [ - 'specific_features' => ['auto_update'], - 'auto_update_plugins' => ['woocommerce/woocommerce.php', 'alma-woocommerce-gateway/alma-gateway-for-woocommerce.php'] + 'Auto update plugins key exists and contain Alma plugin' => [ + 'specific_features' => [ 'auto_update' ], + 'auto_update_plugins' => [ + 'woocommerce/woocommerce.php', + 'alma-woocommerce-gateway/alma-gateway-for-woocommerce.php' + ] ] ]; } + + /** + * @return void + */ + private function set_payment_gateways() { + $cheque_mock = $this->createMock( \WC_Payment_Gateway::class ); + $cheque_mock->id = 'cheque'; + + $bacs_mock = $this->createMock( \WC_Payment_Gateway::class ); + $bacs_mock->id = 'bacs'; + + $alma_in_page_mock = $this->createMock( \WC_Payment_Gateway::class ); + $alma_in_page_mock->id = 'alma_in_page'; + + $alma_mock = $this->createMock( \WC_Payment_Gateway::class ); + $alma_mock->id = 'alma'; + + $paypal_mock = $this->createMock( \WC_Payment_Gateway::class ); + $paypal_mock->id = 'paypal'; + + $payment_gateways = [ + 'cheque' => $cheque_mock, + 'bacs' => $bacs_mock, + 'alma_in_page' => $alma_in_page_mock, + 'alma' => $alma_mock, + 'paypal' => $paypal_mock + ]; + + $wc_payment_gateway =$this->createMock( \WC_Payment_Gateways::class ); + + $wc_payment_gateway->method( 'payment_gateways' ) + ->willReturn( $payment_gateways ); + + PaymentGatewaysProxy::get_instance( $wc_payment_gateway ); + } } \ No newline at end of file