diff --git a/composer.json b/composer.json
index b04a148f..440e42f8 100644
--- a/composer.json
+++ b/composer.json
@@ -25,6 +25,7 @@
"wpackagist-plugin/advanced-custom-fields": "5.8.12",
"wpackagist-plugin/easy-digital-downloads": "^2.9.23",
"wpackagist-plugin/user-switching": "^1.5.5",
+ "wpackagist-plugin/woocommerce": "^4.4",
"wpsh/local": "^0.2.3"
},
"config": {
diff --git a/composer.lock b/composer.lock
index 03b357a7..be2d2aa0 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,20 +4,20 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "c025a44ff83e162076363f15803df9da",
+ "content-hash": "845c0e3b708c2ae893cdd6c36db0e8a1",
"packages": [
{
"name": "composer/installers",
- "version": "v1.9.0",
+ "version": "v1.10.0",
"source": {
"type": "git",
"url": "https://github.com/composer/installers.git",
- "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca"
+ "reference": "1a0357fccad9d1cc1ea0c9a05b8847fbccccb78d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/installers/zipball/b93bcf0fa1fccb0b7d176b0967d969691cd74cca",
- "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca",
+ "url": "https://api.github.com/repos/composer/installers/zipball/1a0357fccad9d1cc1ea0c9a05b8847fbccccb78d",
+ "reference": "1a0357fccad9d1cc1ea0c9a05b8847fbccccb78d",
"shasum": ""
},
"require": {
@@ -28,17 +28,18 @@
"shama/baton": "*"
},
"require-dev": {
- "composer/composer": "1.6.* || 2.0.*@dev",
- "composer/semver": "1.0.* || 2.0.*@dev",
- "phpunit/phpunit": "^4.8.36",
- "sebastian/comparator": "^1.2.4",
+ "composer/composer": "1.6.* || ^2.0",
+ "composer/semver": "^1 || ^3",
+ "phpstan/phpstan": "^0.12.55",
+ "phpstan/phpstan-phpunit": "^0.12.16",
+ "symfony/phpunit-bridge": "^4.2 || ^5",
"symfony/process": "^2.3"
},
"type": "composer-plugin",
"extra": {
"class": "Composer\\Installers\\Plugin",
"branch-alias": {
- "dev-master": "1.0-dev"
+ "dev-main": "1.x-dev"
}
},
"autoload": {
@@ -76,6 +77,7 @@
"Porto",
"RadPHP",
"SMF",
+ "Starbug",
"Thelia",
"Whmcs",
"WolfCMS",
@@ -116,6 +118,7 @@
"phpbb",
"piwik",
"ppi",
+ "processwire",
"puppet",
"pxcms",
"reindex",
@@ -133,19 +136,23 @@
],
"support": {
"issues": "https://github.com/composer/installers/issues",
- "source": "https://github.com/composer/installers/tree/v1.9.0"
+ "source": "https://github.com/composer/installers/tree/v1.10.0"
},
"funding": [
{
"url": "https://packagist.com",
"type": "custom"
},
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
{
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
"type": "tidelift"
}
],
- "time": "2020-04-07T06:57:05+00:00"
+ "time": "2021-01-14T11:07:16+00:00"
}
],
"packages-dev": [
@@ -279,16 +286,16 @@
},
{
"name": "composer/composer",
- "version": "1.10.19",
+ "version": "1.10.20",
"source": {
"type": "git",
"url": "https://github.com/composer/composer.git",
- "reference": "196601d50c08c3fae389a417a7689367fcf37cef"
+ "reference": "e55d297525f0ecc805c813a0f63a40114fd670f6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/composer/zipball/196601d50c08c3fae389a417a7689367fcf37cef",
- "reference": "196601d50c08c3fae389a417a7689367fcf37cef",
+ "url": "https://api.github.com/repos/composer/composer/zipball/e55d297525f0ecc805c813a0f63a40114fd670f6",
+ "reference": "e55d297525f0ecc805c813a0f63a40114fd670f6",
"shasum": ""
},
"require": {
@@ -358,7 +365,7 @@
"support": {
"irc": "irc://irc.freenode.org/composer",
"issues": "https://github.com/composer/composer/issues",
- "source": "https://github.com/composer/composer/tree/1.10.19"
+ "source": "https://github.com/composer/composer/tree/1.10.20"
},
"funding": [
{
@@ -374,7 +381,7 @@
"type": "tidelift"
}
],
- "time": "2020-12-04T08:14:16+00:00"
+ "time": "2021-01-27T14:41:06+00:00"
},
{
"name": "composer/semver",
@@ -1079,20 +1086,20 @@
},
{
"name": "johnpbloch/wordpress",
- "version": "5.6.0",
+ "version": "5.6.1",
"source": {
"type": "git",
"url": "https://github.com/johnpbloch/wordpress.git",
- "reference": "3055975734646c8d0b8caf7b5af168ced6ec4309"
+ "reference": "d7a597988102967cdfc28851b6b897d018613823"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/johnpbloch/wordpress/zipball/3055975734646c8d0b8caf7b5af168ced6ec4309",
- "reference": "3055975734646c8d0b8caf7b5af168ced6ec4309",
+ "url": "https://api.github.com/repos/johnpbloch/wordpress/zipball/d7a597988102967cdfc28851b6b897d018613823",
+ "reference": "d7a597988102967cdfc28851b6b897d018613823",
"shasum": ""
},
"require": {
- "johnpbloch/wordpress-core": "5.6.0",
+ "johnpbloch/wordpress-core": "5.6.1",
"johnpbloch/wordpress-core-installer": "^1.0 || ^2.0",
"php": ">=5.6.20"
},
@@ -1121,20 +1128,20 @@
"source": "http://core.trac.wordpress.org/browser",
"wiki": "http://codex.wordpress.org/"
},
- "time": "2020-12-08T22:34:35+00:00"
+ "time": "2021-02-03T21:27:41+00:00"
},
{
"name": "johnpbloch/wordpress-core",
- "version": "5.6.0",
+ "version": "5.6.1",
"source": {
"type": "git",
"url": "https://github.com/johnpbloch/wordpress-core.git",
- "reference": "f074617dd69f466302836d1ae5de75c0bd7b6dfd"
+ "reference": "82592ec73d42cf784da38adb0028a24dbacab1b4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/johnpbloch/wordpress-core/zipball/f074617dd69f466302836d1ae5de75c0bd7b6dfd",
- "reference": "f074617dd69f466302836d1ae5de75c0bd7b6dfd",
+ "url": "https://api.github.com/repos/johnpbloch/wordpress-core/zipball/82592ec73d42cf784da38adb0028a24dbacab1b4",
+ "reference": "82592ec73d42cf784da38adb0028a24dbacab1b4",
"shasum": ""
},
"require": {
@@ -1142,7 +1149,7 @@
"php": ">=5.6.20"
},
"provide": {
- "wordpress/core-implementation": "5.6.0"
+ "wordpress/core-implementation": "5.6.1"
},
"type": "wordpress-core",
"notification-url": "https://packagist.org/downloads/",
@@ -1169,7 +1176,7 @@
"source": "https://core.trac.wordpress.org/browser",
"wiki": "https://codex.wordpress.org/"
},
- "time": "2020-12-08T22:34:23+00:00"
+ "time": "2021-02-03T21:27:35+00:00"
},
{
"name": "johnpbloch/wordpress-core-installer",
@@ -3145,16 +3152,16 @@
},
{
"name": "sirbrillig/phpcs-variable-analysis",
- "version": "v2.10.1",
+ "version": "v2.10.2",
"source": {
"type": "git",
"url": "https://github.com/sirbrillig/phpcs-variable-analysis.git",
- "reference": "c6716a98fe7bee25d31306e14fb62c3ffa16d70a"
+ "reference": "0775e0c683badad52c03b11c2cd86a9fdecb937a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sirbrillig/phpcs-variable-analysis/zipball/c6716a98fe7bee25d31306e14fb62c3ffa16d70a",
- "reference": "c6716a98fe7bee25d31306e14fb62c3ffa16d70a",
+ "url": "https://api.github.com/repos/sirbrillig/phpcs-variable-analysis/zipball/0775e0c683badad52c03b11c2cd86a9fdecb937a",
+ "reference": "0775e0c683badad52c03b11c2cd86a9fdecb937a",
"shasum": ""
},
"require": {
@@ -3194,7 +3201,7 @@
"source": "https://github.com/sirbrillig/phpcs-variable-analysis",
"wiki": "https://github.com/sirbrillig/phpcs-variable-analysis/wiki"
},
- "time": "2020-12-12T18:28:57+00:00"
+ "time": "2021-01-08T16:31:05+00:00"
},
{
"name": "squizlabs/php_codesniffer",
@@ -4288,12 +4295,12 @@
"version": "1.9.1",
"source": {
"type": "git",
- "url": "https://github.com/webmozart/assert.git",
+ "url": "https://github.com/webmozarts/assert.git",
"reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389",
+ "url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389",
"reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389",
"shasum": ""
},
@@ -4331,8 +4338,8 @@
"validate"
],
"support": {
- "issues": "https://github.com/webmozart/assert/issues",
- "source": "https://github.com/webmozart/assert/tree/master"
+ "issues": "https://github.com/webmozarts/assert/issues",
+ "source": "https://github.com/webmozarts/assert/tree/1.9.1"
},
"time": "2020-07-08T17:02:28+00:00"
},
@@ -6476,16 +6483,16 @@
},
{
"name": "wp-phpunit/wp-phpunit",
- "version": "5.6.0",
+ "version": "5.6.1",
"source": {
"type": "git",
"url": "https://github.com/wp-phpunit/wp-phpunit.git",
- "reference": "7130a214573cc8c12a0f8fe8a74b18b453bce1e9"
+ "reference": "f6b3fb65bccc0ff70b3bc7cc241935597dbd5562"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/wp-phpunit/wp-phpunit/zipball/7130a214573cc8c12a0f8fe8a74b18b453bce1e9",
- "reference": "7130a214573cc8c12a0f8fe8a74b18b453bce1e9",
+ "url": "https://api.github.com/repos/wp-phpunit/wp-phpunit/zipball/f6b3fb65bccc0ff70b3bc7cc241935597dbd5562",
+ "reference": "f6b3fb65bccc0ff70b3bc7cc241935597dbd5562",
"shasum": ""
},
"type": "library",
@@ -6520,7 +6527,7 @@
"issues": "https://github.com/wp-phpunit/issues",
"source": "https://github.com/wp-phpunit/wp-phpunit"
},
- "time": "2020-12-09T18:06:02+00:00"
+ "time": "2021-02-04T18:24:14+00:00"
},
{
"name": "wpackagist-plugin/advanced-custom-fields",
@@ -6576,6 +6583,24 @@
"type": "wordpress-plugin",
"homepage": "https://wordpress.org/plugins/user-switching/"
},
+ {
+ "name": "wpackagist-plugin/woocommerce",
+ "version": "4.9.2",
+ "source": {
+ "type": "svn",
+ "url": "https://plugins.svn.wordpress.org/woocommerce/",
+ "reference": "tags/4.9.2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://downloads.wordpress.org/plugin/woocommerce.4.9.2.zip"
+ },
+ "require": {
+ "composer/installers": "~1.0"
+ },
+ "type": "wordpress-plugin",
+ "homepage": "https://wordpress.org/plugins/woocommerce/"
+ },
{
"name": "wpsh/local",
"version": "0.2.3",
diff --git a/connectors/class-connector-woocommerce.php b/connectors/class-connector-woocommerce.php
index 1ab9aff0..7fe14c10 100644
--- a/connectors/class-connector-woocommerce.php
+++ b/connectors/class-connector-woocommerce.php
@@ -109,6 +109,16 @@ public function register() {
$this->get_woocommerce_settings_fields();
}
+ /**
+ * Unregister connection callbacks
+ */
+ public function unregister() {
+ parent::unregister();
+
+ remove_filter( 'wp_stream_posts_exclude_post_types', array( $this, 'exclude_order_post_types' ) );
+ remove_action( 'wp_stream_comments_exclude_comment_types', array( $this, 'exclude_order_comment_types' ) );
+ }
+
/**
* Check if plugin dependencies are satisfied and add an admin notice if not
*
@@ -327,6 +337,13 @@ public function exclude_order_comment_types( $comment_types ) {
return $comment_types;
}
+ /**
+ * Clears logged order
+ */
+ public function flush_logged_order() {
+ $this->order_update_logged = false;
+ }
+
/**
* Log Order major status changes ( creating / updating / trashing )
*
@@ -337,6 +354,7 @@ public function exclude_order_comment_types( $comment_types ) {
* @param \WP_Post $post Post object.
*/
public function callback_transition_post_status( $new, $old, $post ) {
+
// Only track orders.
if ( 'shop_order' !== $post->post_type ) {
return;
@@ -357,9 +375,10 @@ public function callback_transition_post_status( $new, $old, $post ) {
return;
}
- if ( in_array( $new, array( 'auto-draft', 'draft', 'inherit' ), true ) ) {
+ $start_statuses = array( 'auto-draft', 'inherit', 'new' );
+ if ( in_array( $new, $start_statuses, true ) ) {
return;
- } elseif ( 'auto-draft' === $old && 'publish' === $new ) {
+ } elseif ( in_array( $old, $start_statuses, true ) && ! in_array( $new, $start_statuses, true ) ) {
/* translators: %s: an order title (e.g. "Order #42") */
$message = esc_html_x(
'%s created',
@@ -375,7 +394,7 @@ public function callback_transition_post_status( $new, $old, $post ) {
'stream'
);
$action = 'trashed';
- } elseif ( 'trash' === $old && 'publish' === $new ) {
+ } elseif ( 'trash' === $old && ! in_array( $new, $start_statuses, true ) ) {
/* translators: %s: an order title (e.g. "Order #42") */
$message = esc_html_x(
'%s restored from the trash',
@@ -390,13 +409,10 @@ public function callback_transition_post_status( $new, $old, $post ) {
'Order title',
'stream'
);
+ $action = 'updated';
}
- if ( empty( $action ) ) {
- $action = 'updated';
- }
-
- $order = new \WC_Order( $post->ID );
+ $order = \wc_get_order( $post->ID );
$order_title = esc_html__( 'Order number', 'stream' ) . ' ' . esc_html( $order->get_order_number() );
$order_type_name = esc_html__( 'order', 'stream' );
@@ -437,7 +453,7 @@ public function callback_deleted_post( $post_id ) {
return;
}
- $order = new \WC_Order( $post->ID );
+ $order = \wc_get_order( $post->ID );
$order_title = esc_html__( 'Order number', 'stream' ) . ' ' . esc_html( $order->get_order_number() );
$order_type_name = esc_html__( 'order', 'stream' );
@@ -468,6 +484,7 @@ public function callback_deleted_post( $post_id ) {
* @param string $new New status.
*/
public function callback_woocommerce_order_status_changed( $order_id, $old, $new ) {
+
// Don't track customer actions.
if ( ! is_admin() ) {
return;
@@ -488,19 +505,21 @@ public function callback_woocommerce_order_status_changed( $order_id, $old, $new
$old_status_name = $old_status->name;
}
- /* translators: %1$s: an order title, %2$s: order status, %3$s: another order status (e.g. "Order #42", "processing", "complete") */
- $message = esc_html_x(
- '%1$s status changed from %2$s to %3$s',
- '1. Order title, 2. Old status, 3. New status',
- 'stream'
+ $order = \wc_get_order( $order_id );
+ $order_title = sprintf(
+ /* translators: %d: Order number */
+ __( 'Order number %d', 'stream' ),
+ $order->get_order_number()
);
-
- $order = new \WC_Order( $order_id );
- $order_title = esc_html__( 'Order number', 'stream' ) . ' ' . esc_html( $order->get_order_number() );
$order_type_name = esc_html__( 'order', 'stream' );
$this->log(
- $message,
+ /* translators: %1$s: an order title, %2$s: order status, %3$s: another order status (e.g. "Order #42", "processing", "complete") */
+ esc_html_x(
+ '%1$s status changed from %2$s to %3$s',
+ '1. Order title, 2. Old status, 3. New status',
+ 'stream'
+ ),
array(
'post_title' => $order_title,
'old_status_name' => $old_status_name,
@@ -641,27 +660,14 @@ public function callback_woocommerce_tax_rate_updated( $tax_rate_id, $tax_rate )
* @param int $tax_rate_id Tax Rate ID.
*/
public function callback_woocommerce_tax_rate_deleted( $tax_rate_id ) {
- global $wpdb;
-
- $tax_rate_name = $wpdb->get_var(
- $wpdb->prepare(
- "SELECT tax_rate_name FROM {$wpdb->prefix}woocommerce_tax_rates
- WHERE tax_rate_id = %s
- ",
- $tax_rate_id
- )
- );
-
$this->log(
/* translators: %4$s: a tax rate name (e.g. "GST") */
_x(
- '"%s" tax rate deleted',
+ 'Tax rate identified by ID:"%s" deleted',
'Tax rate name',
'stream'
),
- array(
- 'tax_rate_name' => $tax_rate_name,
- ),
+ compact( 'tax_rate_id' ),
$tax_rate_id,
'tax',
'deleted'
diff --git a/phpunit.xml b/phpunit.xml
index af2b1c44..8e53407e 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -10,7 +10,7 @@
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index 3c911062..dfdbf1bd 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -23,7 +23,7 @@
* @param array $active_plugins
* @return array
*/
-function xwp_filter_active_plugins_for_phpunit( $active_plugins ) {
+function wp_stream_filter_active_plugins_for_phpunit( $active_plugins ) {
$forced_active_plugins = array();
if ( defined( 'WP_TEST_ACTIVATED_PLUGINS' ) ) {
$forced_active_plugins = preg_split( '/\s*,\s*/', WP_TEST_ACTIVATED_PLUGINS );
@@ -36,8 +36,8 @@ function xwp_filter_active_plugins_for_phpunit( $active_plugins ) {
}
return $active_plugins;
}
-tests_add_filter( 'site_option_active_sitewide_plugins', 'xwp_filter_active_plugins_for_phpunit' );
-tests_add_filter( 'option_active_plugins', 'xwp_filter_active_plugins_for_phpunit' );
+tests_add_filter( 'site_option_active_sitewide_plugins', 'wp_stream_filter_active_plugins_for_phpunit' );
+tests_add_filter( 'option_active_plugins', 'wp_stream_filter_active_plugins_for_phpunit' );
tests_add_filter(
'muplugins_loaded',
@@ -79,6 +79,27 @@ function( $status = false, $args = array(), $url = '') {
);
}
+function wp_stream_install_wc() {
+ WC_Install::install();
+
+ // Initialize the WC API extensions.
+ \Automattic\WooCommerce\Admin\Install::create_tables();
+ \Automattic\WooCommerce\Admin\Install::create_events();
+
+ // Reload capabilities after install, see https://core.trac.wordpress.org/ticket/28374.
+ if ( version_compare( $GLOBALS['wp_version'], '4.7', '<' ) ) {
+ $GLOBALS['wp_roles']->reinit();
+ } else {
+ $GLOBALS['wp_roles'] = null; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
+ wp_roles();
+ }
+
+ echo esc_html( 'Installing WooCommerce...' . PHP_EOL );
+}
+
+// install WC.
+tests_add_filter( 'setup_theme', 'wp_stream_install_wc' );
+
// @see https://core.trac.wordpress.org/browser/trunk/tests/phpunit/includes/bootstrap.php
require $_tests_dir . '/includes/bootstrap.php';
diff --git a/tests/tests/connectors/test-class-connector-woocommerce.php b/tests/tests/connectors/test-class-connector-woocommerce.php
new file mode 100644
index 00000000..662b6928
--- /dev/null
+++ b/tests/tests/connectors/test-class-connector-woocommerce.php
@@ -0,0 +1,559 @@
+plugin->connectors->unload_connector( 'woocommerce' );
+ // Make partial of Connector_Woocommmerce class, with mocked "log" function.
+ $this->mock = $this->getMockBuilder( Connector_Woocommerce::class )
+ ->setMethods( array( 'log' ) )
+ ->getMock();
+
+ // Register connector.
+ $this->mock->is_dependency_satisfied();
+ $this->mock->register();
+ }
+
+ /**
+ * Create simple product.
+ *
+ * @param bool $save Save or return object.
+ * @param array $props Properties to be set in the new product, as an associative array.
+ *
+ * @return WC_Product_Simple
+ */
+ private function create_simple_product( $save = true, $props = array() ) {
+ $product = new \WC_Product_Simple();
+ $default_props =
+ array(
+ 'name' => 'Dummy Product',
+ 'regular_price' => 10,
+ 'price' => 10,
+ 'sku' => 'DUMMY SKU',
+ 'manage_stock' => false,
+ 'tax_status' => 'taxable',
+ 'downloadable' => false,
+ 'virtual' => false,
+ 'stock_status' => 'instock',
+ 'weight' => '1.1',
+ );
+
+ $product->set_props( array_merge( $default_props, $props ) );
+
+ if ( $save ) {
+ $product->save();
+ return \wc_get_product( $product->get_id() );
+ } else {
+ return $product;
+ }
+ }
+
+ /**
+ * Create a simple flat rate at the cost of 10.
+ *
+ * @param float $cost Optional. Cost of flat rate method.
+ */
+ private function create_simple_flat_rate( $cost = 10 ) {
+ $flat_rate_settings = array(
+ 'enabled' => 'yes',
+ 'title' => 'Flat rate',
+ 'availability' => 'all',
+ 'countries' => '',
+ 'tax_status' => 'taxable',
+ 'cost' => $cost,
+ );
+
+ update_option( 'woocommerce_flat_rate_settings', $flat_rate_settings );
+ update_option( 'woocommerce_flat_rate', array() );
+ \WC_Cache_Helper::get_transient_version( 'shipping', true );
+ \WC()->shipping()->load_shipping_methods();
+ }
+
+ /**
+ * Create a order.
+ *
+ * @param int $customer_id The ID of the customer the order is for.
+ * @param WC_Product $product The product to add to the order.
+ *
+ * @return WC_Order
+ */
+ private function create_order( $customer_id = 1, $product = null ) {
+
+ if ( ! is_a( $product, 'WC_Product' ) ) {
+ $product = $this->create_simple_product();
+ }
+
+ $this->create_simple_flat_rate();
+
+ $order_data = array(
+ 'status' => 'pending',
+ 'customer_id' => $customer_id,
+ 'customer_note' => '',
+ 'total' => '',
+ );
+
+ $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; // Required, else wc_create_order throws an exception.
+ $order = \wc_create_order( $order_data );
+
+ // Add order products.
+ $item = new \WC_Order_Item_Product();
+ $item->set_props(
+ array(
+ 'product' => $product,
+ 'quantity' => 4,
+ 'subtotal' => \wc_get_price_excluding_tax( $product, array( 'qty' => 4 ) ),
+ 'total' => \wc_get_price_excluding_tax( $product, array( 'qty' => 4 ) ),
+ )
+ );
+ $item->save();
+ $order->add_item( $item );
+
+ // Set billing address.
+ $order->set_billing_first_name( 'Jeroen' );
+ $order->set_billing_last_name( 'Sormani' );
+ $order->set_billing_company( 'WooCompany' );
+ $order->set_billing_address_1( 'WooAddress' );
+ $order->set_billing_address_2( '' );
+ $order->set_billing_city( 'WooCity' );
+ $order->set_billing_state( 'NY' );
+ $order->set_billing_postcode( '12345' );
+ $order->set_billing_country( 'US' );
+ $order->set_billing_email( 'admin@example.org' );
+ $order->set_billing_phone( '555-32123' );
+
+ // Add shipping costs.
+ $shipping_taxes = \WC_Tax::calc_shipping_tax( '10', \WC_Tax::get_shipping_tax_rates() );
+ $rate = new \WC_Shipping_Rate( 'flat_rate_shipping', 'Flat rate shipping', '10', $shipping_taxes, 'flat_rate' );
+ $item = new \WC_Order_Item_Shipping();
+ $item->set_props(
+ array(
+ 'method_title' => $rate->label,
+ 'method_id' => $rate->id,
+ 'total' => wc_format_decimal( $rate->cost ),
+ 'taxes' => $rate->taxes,
+ )
+ );
+ foreach ( $rate->get_meta_data() as $key => $value ) {
+ $item->add_meta_data( $key, $value, true );
+ }
+ $order->add_item( $item );
+
+ // Set payment gateway.
+ $payment_gateways = WC()->payment_gateways->payment_gateways();
+ $order->set_payment_method( $payment_gateways['bacs'] );
+
+ // Set totals.
+ $order->set_shipping_total( 10 );
+ $order->set_discount_total( 0 );
+ $order->set_discount_tax( 0 );
+ $order->set_cart_tax( 0 );
+ $order->set_shipping_tax( 0 );
+ $order->set_total( 50 ); // 4 x $10 simple helper product
+
+ return $order->save();
+ }
+
+ public function test_callback_transition_post_status() {
+ $this->mock->expects( $this->exactly( 4 ) )
+ ->method( 'log' )
+ ->withConsecutive(
+ array(
+ $this->equalTo(
+ esc_html_x(
+ '%s created',
+ 'Order title',
+ 'stream'
+ )
+ ),
+ $this->callback(
+ function( $meta ) {
+ $expected_meta = array(
+ 'singular_name' => 'order',
+ 'new_status' => 'wc-pending',
+ 'old_status' => 'new',
+ 'revision_id' => null,
+ );
+
+ return $expected_meta === array_intersect_key( $expected_meta, $meta );
+ }
+ ),
+ $this->greaterThan( 0 ),
+ $this->equalTo( 'shop_order' ),
+ $this->equalTo( 'created' ),
+ ),
+ array(
+ $this->equalTo(
+ esc_html_x(
+ '%s trashed',
+ 'Order title',
+ 'stream'
+ )
+ ),
+ $this->callback(
+ function( $meta ) {
+ $expected_meta = array(
+ 'singular_name' => 'order',
+ 'new_status' => 'trashed',
+ 'old_status' => 'wc-pending',
+ 'revision_id' => null,
+ );
+
+ return $expected_meta === array_intersect_key( $expected_meta, $meta );
+ }
+ ),
+ $this->greaterThan( 0 ),
+ $this->equalTo( 'shop_order' ),
+ $this->equalTo( 'trashed' ),
+ ),
+ array(
+ $this->equalTo(
+ esc_html_x(
+ '%s restored from the trash',
+ 'Order title',
+ 'stream'
+ )
+ ),
+ $this->callback(
+ function( $meta ) {
+ $expected_meta = array(
+ 'singular_name' => 'order',
+ 'new_status' => 'wc-pending',
+ 'old_status' => 'trashed',
+ 'revision_id' => null,
+ );
+
+ return $expected_meta === array_intersect_key( $expected_meta, $meta );
+ }
+ ),
+ $this->greaterThan( 0 ),
+ $this->equalTo( 'shop_order' ),
+ $this->equalTo( 'untrashed' ),
+ ),
+ array(
+ $this->equalTo(
+ esc_html_x(
+ '%s updated',
+ 'Order title',
+ 'stream'
+ )
+ ),
+ $this->callback(
+ function( $meta ) {
+ $expected_meta = array(
+ 'singular_name' => 'order',
+ 'new_status' => 'wc-failed',
+ 'old_status' => 'wc-pending',
+ 'revision_id' => null,
+ );
+
+ return $expected_meta === array_intersect_key( $expected_meta, $meta );
+ }
+ ),
+ $this->greaterThan( 0 ),
+ $this->equalTo( 'shop_order' ),
+ $this->equalTo( 'updated' ),
+ )
+ );
+
+ // Create/update/trash/restore order to trigger callback.
+ $order_id = $this->create_order();
+ $this->mock->flush_logged_order();
+
+ wp_trash_post( $order_id );
+ $this->mock->flush_logged_order();
+
+ wp_untrash_post( $order_id );
+ $this->mock->flush_logged_order();
+
+ wp_update_post(
+ array(
+ 'ID' => $order_id,
+ 'post_status' => 'wc-failed',
+ )
+ );
+
+ // Check callback test action.
+ $this->assertGreaterThan( 0, did_action( $this->action_prefix . 'callback_transition_post_status' ) );
+ }
+
+ public function test_callback_deleted_post() {
+ // Create order for later use.
+ $order_id = $this->create_order();
+ $order = \wc_get_order( $order_id );
+
+ // Expected log call.
+ $this->mock->expects( $this->once() )
+ ->method( 'log' )
+ ->with(
+ $this->equalTo(
+ _x(
+ '"%s" deleted from trash',
+ 'Order title',
+ 'stream'
+ )
+ ),
+ $this->equalTo(
+ array(
+ 'post_title' => 'Order number '. $order->get_order_number(),
+ 'singular_name' => 'order',
+ )
+ ),
+ $this->equalTo( $order_id ),
+ $this->equalTo( 'shop_order' ),
+ $this->equalTo( 'deleted' )
+ );
+
+ // Delete order to trigger callback.
+ wp_delete_post( $order_id );
+
+ // Check callback test action.
+ $this->assertGreaterThan( 0, did_action( $this->action_prefix . 'callback_deleted_post' ) );
+ }
+
+ public function test_callback_woocommerce_order_status_changed() {
+ // Create order for later use.
+ $order_id = $this->create_order();
+ $order = \wc_get_order( $order_id );
+
+ // Expected log call.
+ $this->mock->expects( $this->once() )
+ ->method( 'log' )
+ ->with(
+ $this->equalTo( '%1$s status changed from %2$s to %3$s' ),
+ $this->equalTo(
+ array(
+ 'post_title' => 'Order number '. $order->get_order_number(),
+ 'old_status_name' => 'Pending payment',
+ 'new_status_name' => 'Completed',
+ 'singular_name' => 'order',
+ 'new_status' => 'completed',
+ 'old_status' => 'pending',
+ 'revision_id' => null,
+ )
+ ),
+ $this->equalTo( $order_id ),
+ $this->equalTo( 'shop_order' ),
+ $this->equalTo( 'updated' )
+ );
+
+ // Update order status to trigger callback.
+ $order->update_status( 'completed' );
+ $order->save();
+
+ // Check callback test action.
+ $this->assertGreaterThan( 0, did_action( $this->action_prefix . 'callback_woocommerce_order_status_changed' ) );
+ }
+
+ public function test_callback_woocommerce_attribute_added() {
+ // Expected log calls
+ $this->mock->expects( $this->once() )
+ ->method( 'log' )
+ ->with(
+ $this->equalTo( '"%s" product attribute created' ),
+ $this->equalTo(
+ array(
+ 'attribute_label' => 'color',
+ 'attribute_name' => 'color',
+ 'attribute_type' => 'select',
+ 'attribute_orderby' => 'menu_order',
+ 'attribute_public' => 0,
+ )
+ ),
+ $this->greaterThan( 0 ),
+ $this->equalTo( 'attributes' ),
+ $this->equalTo( 'created' )
+ );
+
+ // Create attribute to product to trigger callback.
+ \wc_create_attribute(
+ array(
+ 'name' => 'color',
+ 'slug' => 'color',
+ 'text' => 'text',
+ )
+ );
+
+ // Check callback test action.
+ $this->assertGreaterThan( 0, did_action( $this->action_prefix . 'callback_woocommerce_attribute_added' ) );
+ }
+
+ public function test_callback_woocommerce_attribute_updated() {
+ // Create attribute for later use.
+ $attribute_id = \wc_create_attribute(
+ array(
+ 'name' => 'color',
+ 'slug' => 'color',
+ 'text' => 'text',
+ )
+ );
+
+ // Expected log calls
+ $this->mock->expects( $this->once() )
+ ->method( 'log' )
+ ->with(
+ $this->equalTo( '"%s" product attribute updated' ),
+ $this->equalTo(
+ array(
+ 'attribute_label' => 'color',
+ 'attribute_name' => 'colors',
+ 'attribute_type' => 'select',
+ 'attribute_orderby' => 'menu_order',
+ 'attribute_public' => 0,
+ )
+ ),
+ $this->equalTo( $attribute_id ),
+ $this->equalTo( 'attributes' ),
+ $this->equalTo( 'updated' )
+ );
+
+ // Update attribute to trigger callback.
+ \wc_update_attribute( $attribute_id, array( 'slug' => 'colors' ) );
+
+ // Check callback test action.
+ $this->assertGreaterThan( 0, did_action( $this->action_prefix . 'callback_woocommerce_attribute_updated' ) );
+ }
+
+ public function test_callback_woocommerce_attribute_deleted() {
+ // Create attribute for later use.
+ $attribute_id = \wc_create_attribute(
+ array(
+ 'name' => 'color',
+ 'slug' => 'color',
+ 'text' => 'text',
+ )
+ );
+
+ // Expected log calls
+ $this->mock->expects( $this->once() )
+ ->method( 'log' )
+ ->with(
+ $this->equalTo( '"%s" product attribute deleted' ),
+ $this->equalTo(
+ array(
+ 'attribute_name' => 'color'
+ )
+ ),
+ $this->equalTo( $attribute_id ),
+ $this->equalTo( 'attributes' ),
+ $this->equalTo( 'deleted' )
+ );
+
+ // Delete attribute to trigger callback.
+ \wc_delete_attribute( $attribute_id );
+
+ // Check callback test action.
+ $this->assertGreaterThan( 0, did_action( $this->action_prefix . 'callback_woocommerce_attribute_deleted' ) );
+ }
+
+ public function test_callback_woocommerce_tax_rate_added() {
+ // Create tax rate array for later use.
+ $tax_rate = array(
+ 'tax_rate' => '10',
+ 'tax_rate_name' => 'test tax rate',
+ );
+
+ // Expected log calls
+ $this->mock->expects( $this->once() )
+ ->method( 'log' )
+ ->with(
+ $this->equalTo( '"%4$s" tax rate created' ),
+ $this->equalTo( $tax_rate ),
+ $this->greaterThan( 0 ),
+ $this->equalTo( 'tax' ),
+ $this->equalTo( 'created' )
+ );
+
+ // Create tax rate to trigger callback.
+ \WC_Tax::_insert_tax_rate( $tax_rate );
+
+ // Check callback test action.
+ $this->assertGreaterThan( 0, did_action( $this->action_prefix . 'callback_woocommerce_tax_rate_added' ) );
+ }
+
+ public function test_callback_woocommerce_tax_rate_updated() {
+ // Create tax rate for later use.
+ $tax_rate = array(
+ 'tax_rate_country' => 'USA',
+ 'tax_rate_state' => 'Pennsylvania',
+ 'tax_rate' => '10',
+ 'tax_rate_name' => 'test tax rate',
+ 'tax_rate_priority' => 1,
+ 'tax_rate_compound' => 1,
+ 'tax_rate_shipping' => 1,
+ 'tax_rate_order' => 0,
+ 'tax_rate_class' => '',
+ );
+ $tax_rate_id = \WC_Tax::_insert_tax_rate( $tax_rate );
+
+ // Check tax rate data here for use in the upcoming `with()`.
+ $tax_rate['tax_rate_state'] = 'Virginia';
+
+ // Expected log calls
+ $this->mock->expects( $this->once() )
+ ->method( 'log' )
+ ->with(
+ $this->equalTo( '"%4$s" tax rate updated' ),
+ $this->equalTo( $tax_rate ),
+ $this->equalTo( $tax_rate_id ),
+ $this->equalTo( 'tax' ),
+ $this->equalTo( 'updated' )
+ );
+
+ // Update tax rate to trigger callback.
+ \WC_Tax::_update_tax_rate( $tax_rate_id, $tax_rate );
+
+
+ // Check callback test action.
+ $this->assertGreaterThan( 0, did_action( $this->action_prefix . 'callback_woocommerce_tax_rate_updated' ) );
+ }
+
+ public function test_callback_woocommerce_tax_rate_deleted() {
+ // Create tax rate for later use.
+ $tax_rate = array(
+ 'tax_rate_country' => 'USA',
+ 'tax_rate_state' => 'Pennsylvania',
+ 'tax_rate' => '10',
+ 'tax_rate_name' => 'test tax rate',
+ 'tax_rate_priority' => 1,
+ 'tax_rate_compound' => 1,
+ 'tax_rate_shipping' => 1,
+ 'tax_rate_order' => 0,
+ 'tax_rate_class' => '',
+ );
+ $tax_rate_id = \WC_Tax::_insert_tax_rate( $tax_rate );
+
+ // Expected log calls
+ $this->mock->expects( $this->once() )
+ ->method( 'log' )
+ ->with(
+ $this->equalTo( 'Tax rate identified by ID:"%s" deleted' ),
+ $this->equalTo( compact( 'tax_rate_id' ) ),
+ $this->equalTo( $tax_rate_id ),
+ $this->equalTo( 'tax' ),
+ $this->equalTo( 'deleted' )
+ );
+
+ // Delete tax rate to trigger callback.
+ \WC_Tax::_delete_tax_rate( $tax_rate_id );
+
+ // Check callback test action.
+ $this->assertGreaterThan( 0, did_action( $this->action_prefix . 'callback_woocommerce_tax_rate_deleted' ) );
+ }
+
+ public function test_callback_updated_option() {
+ $this->markTestSkipped( 'This test needs to be written.' );
+ }
+}