chosen ) : ?>style="display:none;">
+
chosen ) : /* phpcs:ignore Squiz.ControlStructures.ControlSignature.NewlineAfterOpenBrace */ ?>style="display:none;">
payment_fields(); ?>
diff --git a/templates/emails/admin-cancelled-order.php b/templates/emails/admin-cancelled-order.php
index a447dc9ec05..7073349157b 100644
--- a/templates/emails/admin-cancelled-order.php
+++ b/templates/emails/admin-cancelled-order.php
@@ -25,7 +25,7 @@ if ( ! defined( 'ABSPATH' ) ) {
do_action( 'woocommerce_email_header', $email_heading, $email ); ?>
-
get_formatted_billing_full_name() ), esc_html( $order->get_order_number() ) ); ?>
+
get_formatted_billing_full_name() ), esc_html( $order->get_order_number() ) ); ?>
get_billing_first_name() ) ); ?>
-
get_order_number() ) ); ?>
+
get_order_number() ) ); ?>
get_formatted_billing_full_name() ), esc_html( $order->get_order_number() ) ) . "\n\n";
+echo sprintf( esc_html__( 'Alas. Just to let you know — %1$s has cancelled order #%2$s:', 'woocommerce' ), esc_html( $order->get_formatted_billing_full_name() ), esc_html( $order->get_order_number() ) ) . "\n\n";
echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";
diff --git a/templates/emails/plain/customer-invoice.php b/templates/emails/plain/customer-invoice.php
index 890f364d2fb..24c6376e257 100644
--- a/templates/emails/plain/customer-invoice.php
+++ b/templates/emails/plain/customer-invoice.php
@@ -26,17 +26,10 @@ echo sprintf( esc_html__( 'Hi %s,', 'woocommerce' ), esc_html( $order->get_billi
if ( $order->has_status( 'pending' ) ) {
echo sprintf(
- wp_kses(
- /* translators: %1$s Site title, %2$s Order pay link */
- __( 'An order has been created for you on %1$s. Your invoice is below, with a link to make payment when you’re ready: %1$s', 'woocommerce' ),
- array(
- 'a' => array(
- 'href' => array(),
- ),
- )
- ),
+ /* translators: %1$s Site title, %2$s Order pay link */
+ __( 'An order has been created for you on %1$s. Your invoice is below, with a link to make payment when you’re ready: %2$s', 'woocommerce' ),
esc_html( get_bloginfo( 'name', 'display' ) ),
- '
' . esc_html__( 'Pay for this order', 'woocommerce' ) . ''
+ esc_url( $order->get_checkout_payment_url() )
) . "\n\n";
} else {
diff --git a/templates/emails/plain/customer-processing-order.php b/templates/emails/plain/customer-processing-order.php
index d32d663ee3f..4ea616b1e19 100644
--- a/templates/emails/plain/customer-processing-order.php
+++ b/templates/emails/plain/customer-processing-order.php
@@ -24,7 +24,7 @@ echo '= ' . esc_html( $email_heading ) . " =\n\n";
/* translators: %s: Customer first name */
echo sprintf( esc_html__( 'Hi %s,', 'woocommerce' ), esc_html( $order->get_billing_first_name() ) ) . "\n\n";
/* translators: %s: Order number */
-echo sprintf( esc_html__( 'Just to let you know -- your payment has been confirmed, and order #%s is now being processed:', 'woocommerce' ), esc_html( $order->get_order_number() ) ) . "\n\n";
+echo sprintf( esc_html__( 'Just to let you know — your payment has been confirmed, and order #%s is now being processed:', 'woocommerce' ), esc_html( $order->get_order_number() ) ) . "\n\n";
echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";
diff --git a/tests/README.md b/tests/README.md
index e77403038e8..feddd0d7560 100644
--- a/tests/README.md
+++ b/tests/README.md
@@ -44,7 +44,7 @@ A text code coverage summary can be displayed using the `--coverage-text` option
* Use the test coverage HTML report (under `tmp/coverage/index.html`) to examine which lines your tests are covering and aim for 100% coverage
* For code that cannot be tested (e.g. they require a certain PHP version), you can exclude them from coverage using a comment: `// @codeCoverageIgnoreStart` and `// @codeCoverageIgnoreEnd`. For example, see [`wc_round_tax_total()`](https://github.com/woocommerce/woocommerce/blob/35f83867736713955fa2c4f463a024578bb88795/includes/wc-formatting-functions.php#L208-L219)
* In addition to covering each line of a method/function, make sure to test common input and edge cases.
-* Prefer `assertsEquals()` where possible as it tests both type & equality
+* Prefer `assertSame()` where possible as it tests both type & equality
* Remember that only methods prefixed with `test` will be run so use helper methods liberally to keep test methods small and reduce code duplication. If there is a common helper method used in multiple test files, consider adding it to the `WC_Unit_Test_Case` class so it can be shared by all test cases
* Filters persist between test cases so be sure to remove them in your test method or in the `tearDown()` method.
* Use data providers where possible. Be sure that their name is like `data_provider_function_to_test` (i.e. the data provider for `test_is_postcode` would be `data_provider_test_is_postcode`). Read more about data providers [here](https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.data-providers).
diff --git a/tests/unit-tests/attributes/functions.php b/tests/unit-tests/attributes/functions.php
index 698f6603cc0..577ece7229a 100644
--- a/tests/unit-tests/attributes/functions.php
+++ b/tests/unit-tests/attributes/functions.php
@@ -65,6 +65,95 @@ class WC_Tests_Attributes_Functions extends WC_Unit_Test_Case {
wc_delete_attribute( $id );
}
+ /**
+ * Test that updating a global attribute will not modify local attribute data.
+ *
+ * @since 3.4.6
+ */
+ public function test_wc_create_attribute_serialized_data() {
+ global $wpdb;
+
+ $global_attribute_data = WC_Helper_Product::create_attribute( 'test', array( 'Chicken', 'Nuggets' ) );
+
+ $local_attribute = new WC_Product_Attribute();
+ $local_attribute->set_id( 0 );
+ $local_attribute->set_name( 'Test Local Attribute' );
+ $local_attribute->set_options( array( 'Fish', 'Fingers', 's:7:"pa_test' ) );
+ $local_attribute->set_position( 0 );
+ $local_attribute->set_visible( true );
+ $local_attribute->set_variation( false );
+
+ $global_attribute = new WC_Product_Attribute();
+ $global_attribute->set_id( $global_attribute_data['attribute_id'] );
+ $global_attribute->set_name( $global_attribute_data['attribute_taxonomy'] );
+ $global_attribute->set_options( $global_attribute_data['term_ids'] );
+ $global_attribute->set_position( 1 );
+ $global_attribute->set_visible( true );
+ $global_attribute->set_variation( false );
+
+ $product = new WC_Product_Simple();
+ $product->set_attributes(
+ array(
+ 'test-local' => $local_attribute,
+ 'test-global' => $global_attribute,
+ )
+ );
+ $product->save();
+
+ // Check everything looks good before updating the attribute.
+ $meta_before_update = $wpdb->get_results( $wpdb->prepare( "SELECT meta_value FROM {$wpdb->postmeta} WHERE meta_key = '_product_attributes' AND post_id = %d", $product->get_id() ), ARRAY_A );
+ $product_meta_before_update = @unserialize( $meta_before_update[0]['meta_value'] ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged, WordPress.PHP.DiscouragedPHPFunctions.serialize_unserialize
+ $this->assertNotFalse( $product_meta_before_update, 'Meta should be an unserializable string' );
+
+ $expected_local_attribute_data = array(
+ 'name' => 'Test Local Attribute',
+ 'value' => 'Fish | Fingers | s:7:"pa_test',
+ 'position' => 0,
+ 'is_visible' => 1,
+ 'is_variation' => 0,
+ 'is_taxonomy' => 0,
+ );
+ $expected_global_attribute_data = array(
+ 'name' => 'pa_test',
+ 'value' => '',
+ 'position' => 1,
+ 'is_visible' => 1,
+ 'is_variation' => 0,
+ 'is_taxonomy' => 1,
+ );
+ $local_before = isset( $product_meta_before_update['Test Local Attribute'] ) ? $product_meta_before_update['Test Local Attribute'] : $product_meta_before_update['test-local-attribute'];
+ $this->assertEquals( $expected_local_attribute_data, $local_before );
+ $this->assertEquals( $expected_global_attribute_data, $product_meta_before_update['pa_test'] );
+
+ // Update the global attribute.
+ $updated_global_attribute_id = wc_create_attribute(
+ array(
+ 'id' => $global_attribute_data['attribute_id'],
+ 'name' => 'Test Update',
+ 'old_slug' => 'test',
+ 'slug' => 'testupdate',
+ )
+ );
+ $this->assertEquals( $updated_global_attribute_id, $global_attribute_data['attribute_id'] );
+
+ // Changes to the global attribute should update in the product without causing side-effects.
+ $meta_after_update = $wpdb->get_results( $wpdb->prepare( "SELECT meta_value FROM {$wpdb->postmeta} WHERE meta_key = '_product_attributes' AND post_id = %d", $product->get_id() ), ARRAY_A );
+ $product_meta_after_update = @unserialize( $meta_after_update[0]['meta_value'] ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged, WordPress.PHP.DiscouragedPHPFunctions.serialize_unserialize
+ $this->assertNotFalse( $product_meta_after_update, 'Meta should be an unserializable string' );
+
+ $expected_global_attribute_data = array(
+ 'name' => 'pa_testupdate',
+ 'value' => '',
+ 'position' => 1,
+ 'is_visible' => 1,
+ 'is_variation' => 0,
+ 'is_taxonomy' => 1,
+ );
+ $this->assertEquals( $local_before, isset( $product_meta_after_update['Test Local Attribute'] ) ? $product_meta_after_update['Test Local Attribute'] : $product_meta_after_update['test-local-attribute'] );
+ $this->assertEquals( $expected_global_attribute_data, $product_meta_after_update['pa_testupdate'] );
+ $this->assertArrayNotHasKey( 'pa_test', $product_meta_after_update );
+ }
+
/**
* Tests wc_update_attribute().
*
diff --git a/tests/unit-tests/importer/product.php b/tests/unit-tests/importer/product.php
index 42984e1086e..f039988646a 100644
--- a/tests/unit-tests/importer/product.php
+++ b/tests/unit-tests/importer/product.php
@@ -27,6 +27,16 @@ class WC_Tests_Product_CSV_Importer extends WC_Unit_Test_Case {
$bootstrap = WC_Unit_Tests_Bootstrap::instance();
require_once $bootstrap->plugin_dir . '/includes/import/class-wc-product-csv-importer.php';
require_once $bootstrap->plugin_dir . '/includes/admin/importers/class-wc-product-csv-importer-controller.php';
+
+ add_filter( 'woocommerce_product_csv_importer_check_import_file_path', '__return_false' );
+ }
+
+ /**
+ * Remove filters.
+ */
+ public function tearDown() {
+ parent::tearDown();
+ remove_filter( 'woocommerce_product_csv_importer_check_import_file_path', '__return_false' );
}
/**
diff --git a/tests/unit-tests/log/log-handler-db.php b/tests/unit-tests/log/log-handler-db.php
index 939d323dff8..ad776f778bf 100644
--- a/tests/unit-tests/log/log-handler-db.php
+++ b/tests/unit-tests/log/log-handler-db.php
@@ -8,12 +8,8 @@
class WC_Tests_Log_Handler_DB extends WC_Unit_Test_Case {
public function setUp() {
parent::setUp();
- WC_Log_Handler_DB::flush();
- }
- public function tearDown() {
- WC_Log_Handler_DB::flush();
- parent::tearDown();
+ $this->handler = new WC_Log_Handler_DB( array( 'threshold' => 'debug' ) );
}
/**
@@ -24,87 +20,92 @@ class WC_Tests_Log_Handler_DB extends WC_Unit_Test_Case {
public function test_handle() {
global $wpdb;
- $handler = new WC_Log_Handler_DB( array( 'threshold' => 'debug' ) );
- $time = time();
- $context = array( 1, 2, 'a', 'b', 'key' => 'value' );
+ $time = time();
+ $context = array(
+ 1,
+ 2,
+ 'a',
+ 'b',
+ 'key' => 'value',
+ );
- $handler->handle( $time, 'debug', 'msg_debug', array( 'source' => 'source_debug' ) );
- $handler->handle( $time, 'info', 'msg_info', array( 'source' => 'source_info' ) );
- $handler->handle( $time, 'notice', 'msg_notice', array( 'source' => 'source_notice' ) );
- $handler->handle( $time, 'warning', 'msg_warning', array( 'source' => 'source_warning' ) );
- $handler->handle( $time, 'error', 'msg_error', array( 'source' => 'source_error' ) );
- $handler->handle( $time, 'critical', 'msg_critical', array( 'source' => 'source_critical' ) );
- $handler->handle( $time, 'alert', 'msg_alert', array( 'source' => 'source_alert' ) );
- $handler->handle( $time, 'emergency', 'msg_emergency', array( 'source' => 'source_emergency' ) );
+ $this->handler->handle( $time, 'debug', 'msg_debug', array( 'source' => 'source_debug' ) );
+ $this->handler->handle( $time, 'info', 'msg_info', array( 'source' => 'source_info' ) );
+ $this->handler->handle( $time, 'notice', 'msg_notice', array( 'source' => 'source_notice' ) );
+ $this->handler->handle( $time, 'warning', 'msg_warning', array( 'source' => 'source_warning' ) );
+ $this->handler->handle( $time, 'error', 'msg_error', array( 'source' => 'source_error' ) );
+ $this->handler->handle( $time, 'critical', 'msg_critical', array( 'source' => 'source_critical' ) );
+ $this->handler->handle( $time, 'alert', 'msg_alert', array( 'source' => 'source_alert' ) );
+ $this->handler->handle( $time, 'emergency', 'msg_emergency', array( 'source' => 'source_emergency' ) );
- $handler->handle( $time, 'debug', 'context_test', $context );
+ $this->handler->handle( $time, 'debug', 'context_test', $context );
$log_entries = $wpdb->get_results( "SELECT timestamp, level, message, source, context FROM {$wpdb->prefix}woocommerce_log", ARRAY_A );
$expected_ts = date( 'Y-m-d H:i:s', $time );
- $expected = array(
+ $expected = array(
array(
'timestamp' => $expected_ts,
- 'level' => WC_Log_Levels::get_level_severity( 'debug' ),
- 'message' => 'msg_debug',
- 'source' => 'source_debug',
- 'context' => serialize( array( 'source' => 'source_debug' ) ),
+ 'level' => WC_Log_Levels::get_level_severity( 'debug' ),
+ 'message' => 'msg_debug',
+ 'source' => 'source_debug',
+ 'context' => serialize( array( 'source' => 'source_debug' ) ),
),
array(
'timestamp' => $expected_ts,
- 'level' => WC_Log_Levels::get_level_severity( 'info' ),
- 'message' => 'msg_info',
- 'source' => 'source_info',
- 'context' => serialize( array( 'source' => 'source_info' ) ),
+ 'level' => WC_Log_Levels::get_level_severity( 'info' ),
+ 'message' => 'msg_info',
+ 'source' => 'source_info',
+ 'context' => serialize( array( 'source' => 'source_info' ) ),
),
array(
'timestamp' => $expected_ts,
- 'level' => WC_Log_Levels::get_level_severity( 'notice' ),
- 'message' => 'msg_notice',
- 'source' => 'source_notice',
- 'context' => serialize( array( 'source' => 'source_notice' ) ),
+ 'level' => WC_Log_Levels::get_level_severity( 'notice' ),
+ 'message' => 'msg_notice',
+ 'source' => 'source_notice',
+ 'context' => serialize( array( 'source' => 'source_notice' ) ),
),
array(
'timestamp' => $expected_ts,
- 'level' => WC_Log_Levels::get_level_severity( 'warning' ),
- 'message' => 'msg_warning',
- 'source' => 'source_warning',
- 'context' => serialize( array( 'source' => 'source_warning' ) ),
+ 'level' => WC_Log_Levels::get_level_severity( 'warning' ),
+ 'message' => 'msg_warning',
+ 'source' => 'source_warning',
+ 'context' => serialize( array( 'source' => 'source_warning' ) ),
),
array(
'timestamp' => $expected_ts,
- 'level' => WC_Log_Levels::get_level_severity( 'error' ),
- 'message' => 'msg_error',
- 'source' => 'source_error',
- 'context' => serialize( array( 'source' => 'source_error' ) ),
+ 'level' => WC_Log_Levels::get_level_severity( 'error' ),
+ 'message' => 'msg_error',
+ 'source' => 'source_error',
+ 'context' => serialize( array( 'source' => 'source_error' ) ),
),
array(
'timestamp' => $expected_ts,
- 'level' => WC_Log_Levels::get_level_severity( 'critical' ),
- 'message' => 'msg_critical',
- 'source' => 'source_critical',
- 'context' => serialize( array( 'source' => 'source_critical' ) ),
+ 'level' => WC_Log_Levels::get_level_severity( 'critical' ),
+ 'message' => 'msg_critical',
+ 'source' => 'source_critical',
+ 'context' => serialize( array( 'source' => 'source_critical' ) ),
),
array(
'timestamp' => $expected_ts,
- 'level' => WC_Log_Levels::get_level_severity( 'alert' ),
- 'message' => 'msg_alert',
- 'source' => 'source_alert',
- 'context' => serialize( array( 'source' => 'source_alert' ) ),
+ 'level' => WC_Log_Levels::get_level_severity( 'alert' ),
+ 'message' => 'msg_alert',
+ 'source' => 'source_alert',
+ 'context' => serialize( array( 'source' => 'source_alert' ) ),
),
array(
'timestamp' => $expected_ts,
- 'level' => WC_Log_Levels::get_level_severity( 'emergency' ),
- 'message' => 'msg_emergency',
- 'source' => 'source_emergency',
- 'context' => serialize( array( 'source' => 'source_emergency' ) ),
+ 'level' => WC_Log_Levels::get_level_severity( 'emergency' ),
+ 'message' => 'msg_emergency',
+ 'source' => 'source_emergency',
+ 'context' => serialize( array( 'source' => 'source_emergency' ) ),
),
array(
'timestamp' => $expected_ts,
- 'level' => WC_Log_Levels::get_level_severity( 'debug' ),
- 'message' => 'context_test',
- 'source' => pathinfo( __FILE__, PATHINFO_FILENAME ),
- 'context' => serialize( $context ),
+ 'level' => WC_Log_Levels::get_level_severity( 'debug' ),
+ 'message' => 'context_test',
+ 'source' => pathinfo( __FILE__, PATHINFO_FILENAME ),
+ 'context' => serialize( $context ),
),
);
@@ -120,10 +121,9 @@ class WC_Tests_Log_Handler_DB extends WC_Unit_Test_Case {
public function test_flush() {
global $wpdb;
- $handler = new WC_Log_Handler_DB( array( 'threshold' => 'debug' ) );
$time = time();
- $handler->handle( $time, 'debug', '', array() );
+ $this->handler->handle( $time, 'debug', '', array() );
$log_entries = $wpdb->get_results( "SELECT timestamp, level, message, source FROM {$wpdb->prefix}woocommerce_log" );
$this->assertCount( 1, $log_entries );
@@ -134,4 +134,17 @@ class WC_Tests_Log_Handler_DB extends WC_Unit_Test_Case {
$this->assertCount( 0, $log_entries );
}
+ public function test_delete_logs_before_timestamp() {
+ global $wpdb;
+
+ $time = time();
+ $this->handler->handle( $time, 'debug', '', array() );
+ $this->handler->handle( $time - 10, 'debug', '', array() );
+
+ $this->handler->delete_logs_before_timestamp( $time );
+
+ $log_count = $wpdb->get_var( "SELECT count(*) FROM {$wpdb->prefix}woocommerce_log" );
+ $this->assertEquals( 1, $log_count );
+ }
+
}
diff --git a/tests/unit-tests/order/class-wc-tests-crud-orders.php b/tests/unit-tests/order/class-wc-tests-crud-orders.php
index 3a309b269c3..dc7da4ea03e 100644
--- a/tests/unit-tests/order/class-wc-tests-crud-orders.php
+++ b/tests/unit-tests/order/class-wc-tests-crud-orders.php
@@ -944,6 +944,28 @@ class WC_Tests_CRUD_Orders extends WC_Unit_Test_Case {
remove_filter( 'woocommerce_payment_complete_order_status', array( $this, 'throwAnException' ) );
}
+ /**
+ * Test: status_transition
+ */
+ public function test_status_transition_handles_transition_errors() {
+ $object = new WC_Order();
+ $object->save();
+
+ add_filter( 'woocommerce_order_status_on-hold', array( $this, 'throwAnException' ) );
+ $object->update_status( 'on-hold' );
+ remove_filter( 'woocommerce_order_status_on-hold', array( $this, 'throwAnException' ) );
+
+ $note = current(
+ wc_get_order_notes(
+ array(
+ 'order_id' => $object->get_id(),
+ )
+ )
+ );
+
+ $this->assertContains( __( 'Error during status transition.', 'woocommerce' ), $note->content );
+ }
+
/**
* Test: get_billing_first_name
*/
diff --git a/tests/unit-tests/product/class-wc-tests-product-download.php b/tests/unit-tests/product/class-wc-tests-product-download.php
new file mode 100644
index 00000000000..a5e183a305b
--- /dev/null
+++ b/tests/unit-tests/product/class-wc-tests-product-download.php
@@ -0,0 +1,142 @@
+set_id( 'testid' );
+ $download->set_name( 'Test Name' );
+ $download->set_file( 'http://example.com/file.jpg' );
+
+ $this->assertEquals( 'testid', $download->get_id() );
+ $this->assertEquals( 'Test Name', $download->get_name() );
+ $this->assertEquals( 'http://example.com/file.jpg', $download->get_file() );
+ }
+
+ /**
+ * Test the get_allowed_mime_types method.
+ *
+ * @since 3.4.6
+ */
+ public function test_get_allowed_mime_types() {
+ $download = new WC_Product_Download();
+ $this->assertEquals( get_allowed_mime_types(), $download->get_allowed_mime_types() );
+ }
+
+ /**
+ * Test the get_type_of_file_path method.
+ *
+ * @since 3.4.6
+ */
+ public function test_get_type_of_file_path() {
+ $download = new WC_Product_Download();
+
+ $this->assertEquals( 'absolute', $download->get_type_of_file_path( 'http://example.com/file.jpg' ) );
+ $this->assertEquals( 'absolute', $download->get_type_of_file_path( site_url( '/wp-content/uploads/test.jpg' ) ) );
+ $this->assertEquals( 'relative', $download->get_type_of_file_path( trailingslashit( WP_PLUGIN_DIR ) . 'woocommerce/assets/images/help.png' ) );
+ $this->assertEquals( 'shortcode', $download->get_type_of_file_path( '[s3 bucket ="" file=""]' ) );
+ }
+
+ /**
+ * Test the get_file_type method.
+ *
+ * @since 3.4.6
+ */
+ public function test_get_file_type() {
+ $download = new WC_Product_Download();
+
+ $download->set_file( 'http://example.com/file.jpg' );
+ $this->assertEquals( 'image/jpeg', $download->get_file_type() );
+
+ $download->set_file( 'http://example.com/file.php' );
+ $this->assertEquals( '', $download->get_file_type() );
+
+ $download->set_file( 'http://example.com/file.php?ext=jpg' );
+ $this->assertEquals( '', $download->get_file_type() );
+
+ $download->set_file( site_url( '/wp-content/plugins/woocommerce/assets/images/help.png' ) );
+ $this->assertEquals( 'image/png', $download->get_file_type() );
+
+ $download->set_file( site_url( '/wp-content/plugins/woocommerce/woocommerce.php' ) );
+ $this->assertEquals( '', $download->get_file_type() );
+
+ $download->set_file( trailingslashit( WP_PLUGIN_DIR ) . 'woocommerce/assets/images/help.png' );
+ $this->assertEquals( 'image/png', $download->get_file_type() );
+
+ $download->set_file( trailingslashit( WP_PLUGIN_DIR ) . 'woocommerce/woocommerce.php' );
+ $this->assertEquals( false, $download->get_file_type() );
+ }
+
+ /**
+ * Test the get_file_extension method.
+ *
+ * @since 3.4.6
+ */
+ public function test_get_file_extension() {
+ $download = new WC_Product_Download();
+
+ $download->set_file( 'http://example.com/file.jpg' );
+ $this->assertEquals( 'jpg', $download->get_file_extension() );
+
+ $download->set_file( 'http://example.com/file.php' );
+ $this->assertEquals( 'php', $download->get_file_extension() );
+
+ $download->set_file( 'http://example.com/file.php?ext=jpg' );
+ $this->assertEquals( 'php', $download->get_file_extension() );
+
+ $download->set_file( site_url( '/wp-content/plugins/woocommerce/assets/images/help.png' ) );
+ $this->assertEquals( 'png', $download->get_file_extension() );
+
+ $download->set_file( site_url( '/wp-content/plugins/woocommerce/woocommerce.php' ) );
+ $this->assertEquals( 'php', $download->get_file_extension() );
+
+ $download->set_file( trailingslashit( WP_PLUGIN_DIR ) . 'woocommerce/assets/images/help.png' );
+ $this->assertEquals( 'png', $download->get_file_extension() );
+
+ $download->set_file( trailingslashit( WP_PLUGIN_DIR ) . 'woocommerce/woocommerce.php' );
+ $this->assertEquals( 'php', $download->get_file_extension() );
+ }
+
+ /**
+ * Test the is_allowed_filetype method.
+ *
+ * @since 3.4.6
+ */
+ public function test_is_allowed_filetype() {
+ $download = new WC_Product_Download();
+
+ $download->set_file( 'http://example.com/file.jpg' );
+ $this->assertEquals( true, $download->is_allowed_filetype() );
+
+ $download->set_file( 'http://example.com/file.php' );
+ $this->assertEquals( true, $download->is_allowed_filetype() );
+
+ $download->set_file( site_url( '/wp-content/plugins/woocommerce/assets/images/help.png' ) );
+ $this->assertEquals( true, $download->is_allowed_filetype() );
+
+ $download->set_file( site_url( '/wp-content/plugins/woocommerce/woocommerce.php' ) );
+ $this->assertEquals( false, $download->is_allowed_filetype() );
+
+ $download->set_file( trailingslashit( WP_PLUGIN_DIR ) . 'woocommerce/assets/images/help.png' );
+ $this->assertEquals( true, $download->is_allowed_filetype() );
+
+ $download->set_file( trailingslashit( WP_PLUGIN_DIR ) . 'woocommerce/woocommerce.php' );
+ $this->assertEquals( false, $download->is_allowed_filetype() );
+ }
+}
diff --git a/tests/unit-tests/shortcodes/products.php b/tests/unit-tests/shortcodes/products.php
index 214f87469c4..f72453a2889 100644
--- a/tests/unit-tests/shortcodes/products.php
+++ b/tests/unit-tests/shortcodes/products.php
@@ -86,7 +86,7 @@ class WC_Test_Shortcode_Products extends WC_Unit_Test_Case {
// products shortcode with attributes.
$shortcode2 = new WC_Shortcode_Products( array(
- 'orderby' => 'id',
+ 'orderby' => 'ID',
'order' => 'DESC',
) );
$expected2 = array(
@@ -94,7 +94,7 @@ class WC_Test_Shortcode_Products extends WC_Unit_Test_Case {
'post_status' => 'publish',
'ignore_sticky_posts' => true,
'no_found_rows' => true,
- 'orderby' => 'id',
+ 'orderby' => 'ID',
'order' => 'DESC',
'posts_per_page' => '-1',
'meta_query' => $meta_query,
diff --git a/tests/unit-tests/util/class-wc-tests-core-functions.php b/tests/unit-tests/util/class-wc-tests-core-functions.php
index f8dcc0f6a51..2b4bf34fc0a 100644
--- a/tests/unit-tests/util/class-wc-tests-core-functions.php
+++ b/tests/unit-tests/util/class-wc-tests-core-functions.php
@@ -268,8 +268,8 @@ class WC_Tests_Core_Functions extends WC_Unit_Test_Case {
* @since 2.4
*/
public function test_wc_get_log_file_path() {
- $log_dir = trailingslashit( WC_LOG_DIR );
- $hash_name = sanitize_file_name( wp_hash( 'unit-tests' ) );
+ $log_dir = trailingslashit( WC_LOG_DIR );
+ $hash_name = sanitize_file_name( wp_hash( 'unit-tests' ) );
$date_suffix = date( 'Y-m-d', current_time( 'timestamp', true ) );
$this->assertEquals( $log_dir . 'unit-tests-' . $date_suffix . '-' . $hash_name . '.log', wc_get_log_file_path( 'unit-tests' ) );
@@ -293,6 +293,26 @@ class WC_Tests_Core_Functions extends WC_Unit_Test_Case {
$this->assertSame( $log_a, $log_b, '`wc_get_logger()` should return the same instance' );
}
+ /**
+ * Test wc_get_logger() to check if can return instance when given in filter.
+ */
+ public function test_wc_get_logger_for_instance() {
+ add_filter( 'woocommerce_logging_class', array( $this, 'return_valid_logger_instance' ) );
+
+ $logger = wc_get_logger();
+
+ $this->assertInstanceOf( 'WC_Logger_Interface', $logger, '`wc_get_logger()` should return valid Dummy_WC_Logger instance' );
+ }
+
+ /**
+ * Return valid logger instance that implements WC_Logger_Interface.
+ *
+ * @return WC_Logger_Interface
+ */
+ public function return_valid_logger_instance() {
+ return new Dummy_WC_Logger();
+ }
+
/**
* Return class which does not implement WC_Logger_Interface
*
@@ -326,7 +346,7 @@ class WC_Tests_Core_Functions extends WC_Unit_Test_Case {
$this->assertEquals(
array(
'country' => 'US',
- 'state' => 'CA',
+ 'state' => 'CA',
),
wc_format_country_state_string( 'US:CA' )
);
@@ -335,7 +355,7 @@ class WC_Tests_Core_Functions extends WC_Unit_Test_Case {
$this->assertEquals(
array(
'country' => 'US-CA',
- 'state' => '',
+ 'state' => '',
),
wc_format_country_state_string( 'US-CA' )
);
@@ -483,26 +503,32 @@ class WC_Tests_Core_Functions extends WC_Unit_Test_Case {
update_option( 'woocommerce_currency', $new_currency );
// New order should be created using shop currency.
- $order = wc_create_order( array(
- 'status' => 'pending',
- 'customer_id' => 1,
- 'created_via' => 'unit tests',
- 'cart_hash' => '',
- ) );
+ $order = wc_create_order(
+ array(
+ 'status' => 'pending',
+ 'customer_id' => 1,
+ 'created_via' => 'unit tests',
+ 'cart_hash' => '',
+ )
+ );
$this->assertEquals( $new_currency, $order->get_currency() );
update_option( 'woocommerce_currency', $old_currency );
// Currency should not change when order is updated.
- $order = wc_update_order( array(
- 'customer_id' => 2,
- 'order_id' => $order->get_id(),
- ) );
+ $order = wc_update_order(
+ array(
+ 'customer_id' => 2,
+ 'order_id' => $order->get_id(),
+ )
+ );
$this->assertEquals( $new_currency, $order->get_currency() );
- $order = wc_update_order( array(
- 'customer_id' => 2,
- ) );
+ $order = wc_update_order(
+ array(
+ 'customer_id' => 2,
+ )
+ );
$this->assertInstanceOf( 'WP_Error', $order );
}
@@ -577,25 +603,29 @@ class WC_Tests_Core_Functions extends WC_Unit_Test_Case {
* @return void
*/
public function test_wc_get_page_children() {
- $page_id = wp_insert_post( array(
- 'post_title' => 'Parent Page',
- 'post_type' => 'page',
- 'post_name' => 'parent-page',
- 'post_status' => 'publish',
- 'post_author' => 1,
- 'menu_order' => 0,
- ) );
+ $page_id = wp_insert_post(
+ array(
+ 'post_title' => 'Parent Page',
+ 'post_type' => 'page',
+ 'post_name' => 'parent-page',
+ 'post_status' => 'publish',
+ 'post_author' => 1,
+ 'menu_order' => 0,
+ )
+ );
- $child_page_id = wp_insert_post( array(
- 'post_parent' => $page_id,
- 'post_title' => 'Parent Page',
- 'post_type' => 'page',
- 'post_name' => 'parent-page',
- 'post_status' => 'publish',
- 'post_author' => 1,
- 'menu_order' => 0,
- ) );
- $children = wc_get_page_children( $page_id );
+ $child_page_id = wp_insert_post(
+ array(
+ 'post_parent' => $page_id,
+ 'post_title' => 'Parent Page',
+ 'post_type' => 'page',
+ 'post_name' => 'parent-page',
+ 'post_status' => 'publish',
+ 'post_author' => 1,
+ 'menu_order' => 0,
+ )
+ );
+ $children = wc_get_page_children( $page_id );
$this->assertEquals( $child_page_id, $children[0] );
wp_delete_post( $page_id, true );
@@ -721,7 +751,7 @@ class WC_Tests_Core_Functions extends WC_Unit_Test_Case {
foreach ( $test_cases as $test_case ) {
list( $value, $options, $result ) = $test_case;
- $actual_result = $result ? " selected='selected'" : '';
+ $actual_result = $result ? " selected='selected'" : '';
$this->assertEquals( wc_selected( $value, $options ), $actual_result );
}
}
@@ -815,7 +845,7 @@ class WC_Tests_Core_Functions extends WC_Unit_Test_Case {
* @return void
*/
public function test_wc_get_user_agent() {
- $example_user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36';
+ $example_user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36';
$_SERVER['HTTP_USER_AGENT'] = $example_user_agent;
$this->assertEquals( $example_user_agent, wc_get_user_agent() );
}
diff --git a/tests/unit-tests/util/class-wc-tests-user-functions.php b/tests/unit-tests/util/class-wc-tests-user-functions.php
new file mode 100644
index 00000000000..f4668146886
--- /dev/null
+++ b/tests/unit-tests/util/class-wc-tests-user-functions.php
@@ -0,0 +1,117 @@
+ 'test_admin',
+ 'user_pass' => $password,
+ 'user_email' => 'admin@example.com',
+ 'role' => 'administrator',
+ ) );
+
+ $editor_id = wp_insert_user( array(
+ 'user_login' => 'test_editor',
+ 'user_pass' => $password,
+ 'user_email' => 'editor@example.com',
+ 'role' => 'editor',
+ ) );
+
+ $manager_id = wp_insert_user( array(
+ 'user_login' => 'test_manager',
+ 'user_pass' => $password,
+ 'user_email' => 'manager@example.com',
+ 'role' => 'shop_manager',
+ ) );
+
+ // Admins should be able to edit anyone.
+ wp_set_current_user( $admin_id );
+ $admin_editable_roles = array_keys( get_editable_roles() );
+ $this->assertContains( 'administrator', $admin_editable_roles );
+ $this->assertContains( 'editor', $admin_editable_roles );
+ $this->assertContains( 'shop_manager', $admin_editable_roles );
+ $this->assertContains( 'customer', $admin_editable_roles );
+
+ // Editors should be able to edit non-admins.
+ wp_set_current_user( $editor_id );
+ $editor_editable_roles = array_keys( get_editable_roles() );
+ $this->assertNotContains( 'administrator', $editor_editable_roles );
+ $this->assertContains( 'editor', $editor_editable_roles );
+ $this->assertContains( 'shop_manager', $editor_editable_roles );
+ $this->assertContains( 'customer', $editor_editable_roles );
+
+ // Shop manager should only be able to edit customers.
+ wp_set_current_user( $manager_id );
+ $manager_editable_roles = array_keys( get_editable_roles() );
+ $this->assertEquals( array( 'customer' ), $manager_editable_roles );
+ }
+
+ /**
+ * Test the logic of wc_modify_map_meta_cap.
+ *
+ * @since 3.4.6
+ */
+ public function test_wc_modify_map_meta_cap() {
+ $password = wp_generate_password();
+
+ $admin_id = wp_insert_user( array(
+ 'user_login' => 'test_admin',
+ 'user_pass' => $password,
+ 'user_email' => 'admin@example.com',
+ 'role' => 'administrator',
+ ) );
+
+ $editor_id = wp_insert_user( array(
+ 'user_login' => 'test_editor',
+ 'user_pass' => $password,
+ 'user_email' => 'editor@example.com',
+ 'role' => 'editor',
+ ) );
+
+ $manager_id = wp_insert_user( array(
+ 'user_login' => 'test_manager',
+ 'user_pass' => $password,
+ 'user_email' => 'manager@example.com',
+ 'role' => 'shop_manager',
+ ) );
+
+ $customer_id = wp_insert_user( array(
+ 'user_login' => 'test_customer',
+ 'user_pass' => $password,
+ 'user_email' => 'customer@example.com',
+ 'role' => 'customer',
+ ) );
+
+ // Admins should be able to edit or promote anyone.
+ wp_set_current_user( $admin_id );
+ $caps = map_meta_cap( 'edit_user', $admin_id, $editor_id );
+ $this->assertEquals( array( 'edit_users' ), $caps );
+ $caps = map_meta_cap( 'promote_user', $admin_id, $manager_id );
+ $this->assertEquals( array( 'promote_users' ), $caps );
+
+ // Shop managers should only be able to edit themselves or customers.
+ wp_set_current_user( $manager_id );
+ $caps = map_meta_cap( 'edit_user', $manager_id, $admin_id );
+ $this->assertContains( 'do_not_allow', $caps );
+ $caps = map_meta_cap( 'edit_user', $manager_id, $editor_id );
+ $this->assertContains( 'do_not_allow', $caps );
+ $caps = map_meta_cap( 'edit_user', $manager_id, $customer_id );
+ $this->assertEquals( array( 'edit_users' ), $caps );
+ }
+}
diff --git a/tests/unit-tests/util/dummy-wc-logger.php b/tests/unit-tests/util/dummy-wc-logger.php
new file mode 100644
index 00000000000..b91f35a7caa
--- /dev/null
+++ b/tests/unit-tests/util/dummy-wc-logger.php
@@ -0,0 +1,103 @@
+