From 63ba6f7ee07f26b48c215ffe6205317a94a4a5cd Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Thu, 14 May 2020 21:04:11 -0700 Subject: [PATCH 1/2] Moved the PSR-4 namespaced test directory to the correct folder I know this probably doesn't belong in this PR, but it has been thoroughly discussed and I don't think anyone will mind :) --- composer.json | 2 +- .../helper/{WCHelperTest.php => class-wc-helper-test.php} | 4 +--- tests/php/{ => src}/.gitkeep | 0 3 files changed, 2 insertions(+), 4 deletions(-) rename tests/php/includes/admin/helper/{WCHelperTest.php => class-wc-helper-test.php} (92%) rename tests/php/{ => src}/.gitkeep (100%) diff --git a/composer.json b/composer.json index 983bab82972..3380a30123f 100644 --- a/composer.json +++ b/composer.json @@ -45,7 +45,7 @@ }, "autoload-dev": { "psr-4": { - "Automattic\\WooCommerce\\Tests\\": "tests/php/" + "Automattic\\WooCommerce\\Tests\\": "tests/php/src" } }, "scripts": { diff --git a/tests/php/includes/admin/helper/WCHelperTest.php b/tests/php/includes/admin/helper/class-wc-helper-test.php similarity index 92% rename from tests/php/includes/admin/helper/WCHelperTest.php rename to tests/php/includes/admin/helper/class-wc-helper-test.php index 2580610b15f..e181f1e365e 100644 --- a/tests/php/includes/admin/helper/WCHelperTest.php +++ b/tests/php/includes/admin/helper/class-wc-helper-test.php @@ -5,12 +5,10 @@ * @package WooCommerce|Tests|WC_Helper. */ -namespace Automattic\WooCommerce; - /** * Class WC_Tests_WC_Helper. */ -class WCHelperTest extends \WC_Unit_Test_Case { +class WC_Helper_Test extends \WC_Unit_Test_Case { /** * Test that woo plugins are loaded correctly even if incorrect cache is intially set. diff --git a/tests/php/.gitkeep b/tests/php/src/.gitkeep similarity index 100% rename from tests/php/.gitkeep rename to tests/php/src/.gitkeep From 7bf9c31f6446fe5ae48736009eb05b17e5d4f4f3 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Thu, 14 May 2020 21:20:55 -0700 Subject: [PATCH 2/2] Adjusted the column name normalization to avoid squashing meta key case sensitivity Since we were converting the field to lowercase we ended up inserting meta in all lowercase, regardless of what it was in the CSV file. We should only be using the normalized field name when looking at the default columns, and should instead rely on a case-insensitive regex for the special columns. One thing to note is that we're still defaulting the $headers array to the normalized field, as we don't want to change what is being passed to the filter for unmapped columns. --- ...ass-wc-product-csv-importer-controller.php | 14 ++-- ...c-product-csv-importer-controller-test.php | 64 +++++++++++++++++++ 2 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 tests/php/includes/admin/importers/class-wc-product-csv-importer-controller-test.php diff --git a/includes/admin/importers/class-wc-product-csv-importer-controller.php b/includes/admin/importers/class-wc-product-csv-importer-controller.php index 22b70555917..5a87ec9ae50 100644 --- a/includes/admin/importers/class-wc-product-csv-importer-controller.php +++ b/includes/admin/importers/class-wc-product-csv-importer-controller.php @@ -319,6 +319,7 @@ class WC_Product_CSV_Importer_Controller { return new WP_Error( 'woocommerce_product_csv_importer_upload_file_empty', __( 'File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini.', 'woocommerce' ) ); } + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated if ( ! self::is_file_valid_csv( wc_clean( wp_unslash( $_FILES['import']['name'] ) ), false ) ) { return new WP_Error( 'woocommerce_product_csv_importer_upload_file_invalid', __( 'Invalid file type. The importer supports CSV and TXT file formats.', 'woocommerce' ) ); } @@ -327,7 +328,7 @@ class WC_Product_CSV_Importer_Controller { 'test_form' => false, 'mimes' => self::get_valid_csv_filetypes(), ); - $import = $_FILES['import']; // WPCS: sanitization ok, input var ok. + $import = $_FILES['import']; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash $upload = wp_handle_upload( $import, $overrides ); if ( isset( $upload['error'] ) ) { @@ -577,14 +578,15 @@ class WC_Product_CSV_Importer_Controller { $headers = array(); foreach ( $raw_headers as $key => $field ) { - $field = strtolower( $field ); + $normalized_field = strtolower( $field ); $index = $num_indexes ? $key : $field; - $headers[ $index ] = $field; + $headers[ $index ] = $normalized_field; - if ( isset( $default_columns[ $field ] ) ) { - $headers[ $index ] = $default_columns[ $field ]; + if ( isset( $default_columns[ $normalized_field ] ) ) { + $headers[ $index ] = $default_columns[ $normalized_field ]; } else { foreach ( $special_columns as $regex => $special_key ) { + // Don't use the normalized field in the regex since meta might be case-sensitive. if ( preg_match( $regex, $field, $matches ) ) { $headers[ $index ] = $special_key . $matches[1]; break; @@ -619,7 +621,7 @@ class WC_Product_CSV_Importer_Controller { * @return string */ protected function sanitize_special_column_name_regex( $value ) { - return '/' . str_replace( array( '%d', '%s' ), '(.*)', trim( quotemeta( $value ) ) ) . '/'; + return '/' . str_replace( array( '%d', '%s' ), '(.*)', trim( quotemeta( $value ) ) ) . '/i'; } /** diff --git a/tests/php/includes/admin/importers/class-wc-product-csv-importer-controller-test.php b/tests/php/includes/admin/importers/class-wc-product-csv-importer-controller-test.php new file mode 100644 index 00000000000..af046f38931 --- /dev/null +++ b/tests/php/includes/admin/importers/class-wc-product-csv-importer-controller-test.php @@ -0,0 +1,64 @@ +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'; + } + + /** + * Tests that the automatic mapping is case insensitive so that columns can be matched more easily. + */ + public function test_that_auto_mapping_is_case_insensitive() { + // Allow us to call the protected method. + $class = new ReflectionClass( WC_Product_CSV_Importer_Controller::class ); + $method = $class->getMethod( 'auto_map_columns' ); + $method->setAccessible( true ); + + $controller = new WC_Product_CSV_Importer_Controller(); + + // Test a few different casing formats first. + $columns = $method->invoke( $controller, array( 'Name', 'Type' ) ); + $this->assertEquals( + array( + 0 => 'name', + 1 => 'type', + ), + $columns + ); + $columns = $method->invoke( $controller, array( 'NAME', 'tYpE' ) ); + $this->assertEquals( + array( + 0 => 'name', + 1 => 'type', + ), + $columns + ); + + // Make sure that the case sensitivity doesn't squash the meta keys. + $columns = $method->invoke( $controller, array( 'Meta: _TESTING', 'Meta: _testing' ) ); + $this->assertEquals( + array( + 0 => 'meta:_TESTING', + 1 => 'meta:_testing', + ), + $columns + ); + } +}