From 04aba8ceb1d033f8b40baa9673473e7e4d51482d Mon Sep 17 00:00:00 2001 From: Alex P Date: Wed, 15 Jun 2022 21:37:10 +0300 Subject: [PATCH] Add tests using real WC --- .env.e2e.example | 1 + .gitattributes | 2 + .github/workflows/e2e.yml | 39 ++ .gitignore | 1 + composer.json | 6 +- composer.lock | 446 ++++++++++++++----- package.json | 4 +- tests/e2e/PHPUnit/Order/PurchaseUnitTest.php | 235 ++++++++++ tests/e2e/PHPUnit/TestCase.php | 16 + tests/e2e/PHPUnit/bootstrap.php | 23 + tests/e2e/PHPUnit/ppcp-e2e-plugin.php | 19 + tests/e2e/PHPUnit/setup.php | 49 ++ tests/e2e/data/tax_rates.csv | 4 + tests/e2e/phpunit.xml.dist | 15 + 14 files changed, 746 insertions(+), 114 deletions(-) create mode 100644 .env.e2e.example create mode 100644 .github/workflows/e2e.yml create mode 100644 tests/e2e/PHPUnit/Order/PurchaseUnitTest.php create mode 100644 tests/e2e/PHPUnit/TestCase.php create mode 100644 tests/e2e/PHPUnit/bootstrap.php create mode 100644 tests/e2e/PHPUnit/ppcp-e2e-plugin.php create mode 100644 tests/e2e/PHPUnit/setup.php create mode 100644 tests/e2e/data/tax_rates.csv create mode 100644 tests/e2e/phpunit.xml.dist diff --git a/.env.e2e.example b/.env.e2e.example new file mode 100644 index 000000000..02ffdb0bc --- /dev/null +++ b/.env.e2e.example @@ -0,0 +1 @@ +PPCP_E2E_WP_DIR=${ROOT_DIR}/.ddev/wordpress diff --git a/.gitattributes b/.gitattributes index 6774b417a..29fef5bbc 100644 --- a/.gitattributes +++ b/.gitattributes @@ -5,6 +5,8 @@ /.idea/ export-ignore .env export-ignore .env.example export-ignore +.env.e2e export-ignore +.env.e2e.example export-ignore .travis.yml export-ignore auth.json export-ignore composer.json export-ignore diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml new file mode 100644 index 000000000..b27d50bf9 --- /dev/null +++ b/.github/workflows/e2e.yml @@ -0,0 +1,39 @@ +name: e2e tests + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + php-versions: ['7.1', '7.4'] + + name: PHP ${{ matrix.php-versions }} + steps: + - uses: satackey/action-docker-layer-caching@v0.0.11 + continue-on-error: true + + - uses: jonaseberle/github-action-setup-ddev@v1 + with: + autostart: false + + - uses: actions/checkout@v1 + + - name: Configure DDEV + run: ddev config --php-version ${{ matrix.php-versions }} + + - name: Start DDEV + run: ddev start + + - name: Orchestrate DDEV + run: ddev orchestrate -f + + - name: Create config + run: cp -n .env.e2e.example .env.e2e + + - name: Setup tests + run: ddev php tests/e2e/PHPUnit/setup.php + + - name: Run PHPUnit + run: ddev exec phpunit -c tests/e2e/phpunit.xml.dist diff --git a/.gitignore b/.gitignore index ae438ab55..8fa78b2c6 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ modules/ppcp-wc-gateway/assets/js modules/ppcp-wc-gateway/assets/css *.zip .env +.env.e2e auth.json diff --git a/composer.json b/composer.json index ed3c2d4a3..4649de979 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,8 @@ "brain/monkey": "^2.4", "php-stubs/wordpress-stubs": "^5.0@stable", "php-stubs/woocommerce-stubs": "^5.0@stable", - "vimeo/psalm": "^4.0" + "vimeo/psalm": "^4.0", + "vlucas/phpdotenv": "^5" }, "autoload": { "psr-4": { @@ -32,7 +33,8 @@ }, "autoload-dev": { "psr-4": { - "WooCommerce\\PayPalCommerce\\": "tests/PHPUnit/" + "WooCommerce\\PayPalCommerce\\": "tests/PHPUnit/", + "WooCommerce\\PayPalCommerce\\Tests\\E2e\\": "tests/e2e/PHPUnit/" } }, "minimum-stability": "dev", diff --git a/composer.lock b/composer.lock index 1ff2571e2..d8fe60d77 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b3ddb500dfb804b3800901e2ac30108a", + "content-hash": "c556381af92720a1f7c3cd0795c2653a", "packages": [ { "name": "container-interop/service-provider", @@ -515,16 +515,16 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.24.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9" + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9", - "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", "shasum": "" }, "require": { @@ -533,7 +533,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -591,7 +591,7 @@ "type": "tidelift" } ], - "time": "2021-09-13T13:58:33+00:00" + "time": "2022-05-10T07:21:04+00:00" }, { "name": "wikimedia/composer-merge-plugin", @@ -1096,16 +1096,16 @@ }, { "name": "composer/semver", - "version": "3.2.9", + "version": "3.3.2", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "a951f614bd64dcd26137bc9b7b2637ddcfc57649" + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/a951f614bd64dcd26137bc9b7b2637ddcfc57649", - "reference": "a951f614bd64dcd26137bc9b7b2637ddcfc57649", + "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", "shasum": "" }, "require": { @@ -1168,20 +1168,20 @@ "type": "tidelift" } ], - "time": "2022-02-04T13:58:43+00:00" + "time": "2022-04-01T19:23:25+00:00" }, { "name": "composer/xdebug-handler", - "version": "2.0.4", + "version": "2.0.5", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "0c1a3925ec58a4ec98e992b9c7d171e9e184be0a" + "reference": "9e36aeed4616366d2b690bdce11f71e9178c579a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/0c1a3925ec58a4ec98e992b9c7d171e9e184be0a", - "reference": "0c1a3925ec58a4ec98e992b9c7d171e9e184be0a", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/9e36aeed4616366d2b690bdce11f71e9178c579a", + "reference": "9e36aeed4616366d2b690bdce11f71e9178c579a", "shasum": "" }, "require": { @@ -1229,7 +1229,7 @@ "type": "tidelift" } ], - "time": "2022-01-04T17:06:45+00:00" + "time": "2022-02-24T20:20:32+00:00" }, { "name": "dealerdirect/phpcodesniffer-composer-installer", @@ -1337,29 +1337,30 @@ }, { "name": "doctrine/instantiator", - "version": "1.4.0", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^8.0", + "doctrine/coding-standard": "^9", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.22" }, "type": "library", "autoload": { @@ -1384,7 +1385,21 @@ "constructor", "instantiate" ], - "time": "2020-11-10T18:47:58+00:00" + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-03-03T08:28:38+00:00" }, { "name": "felixfbecker/advanced-json-rpc", @@ -1429,16 +1444,16 @@ }, { "name": "felixfbecker/language-server-protocol", - "version": "1.5.1", + "version": "v1.5.2", "source": { "type": "git", "url": "https://github.com/felixfbecker/php-language-server-protocol.git", - "reference": "9d846d1f5cf101deee7a61c8ba7caa0a975cd730" + "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/9d846d1f5cf101deee7a61c8ba7caa0a975cd730", - "reference": "9d846d1f5cf101deee7a61c8ba7caa0a975cd730", + "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/6e82196ffd7c62f7794d778ca52b69feec9f2842", + "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842", "shasum": "" }, "require": { @@ -1477,7 +1492,65 @@ "php", "server" ], - "time": "2021-02-22T14:02:09+00:00" + "time": "2022-03-02T22:36:06+00:00" + }, + { + "name": "graham-campbell/result-type", + "version": "v1.0.4", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "0690bde05318336c7221785f2a932467f98b64ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/0690bde05318336c7221785f2a932467f98b64ca", + "reference": "0690bde05318336c7221785f2a932467f98b64ca", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "phpoption/phpoption": "^1.8" + }, + "require-dev": { + "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "GrahamCampbell\\ResultType\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "An Implementation Of The Result Type", + "keywords": [ + "Graham Campbell", + "GrahamCampbell", + "Result Type", + "Result-Type", + "result" + ], + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" + } + ], + "time": "2021-11-21T21:41:47+00:00" }, { "name": "hamcrest/hamcrest-php", @@ -1593,37 +1666,38 @@ }, { "name": "myclabs/deep-copy", - "version": "1.10.2", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, - "replace": { - "myclabs/deep-copy": "self.version" + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" }, "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.1" + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", "autoload": { - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, "files": [ "src/DeepCopy/deep_copy.php" - ] + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1637,7 +1711,13 @@ "object", "object graph" ], - "time": "2020-11-13T09:40:50+00:00" + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2022-03-03T13:19:32+00:00" }, { "name": "netresearch/jsonmapper", @@ -1687,16 +1767,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.13.2", + "version": "v4.14.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "210577fe3cf7badcc5814d99455df46564f3c077" + "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077", - "reference": "210577fe3cf7badcc5814d99455df46564f3c077", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1", + "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1", "shasum": "" }, "require": { @@ -1735,7 +1815,7 @@ "parser", "php" ], - "time": "2021-11-30T19:35:32+00:00" + "time": "2022-05-31T20:59:12+00:00" }, { "name": "openlss/lib-array2xml", @@ -1890,24 +1970,24 @@ }, { "name": "php-stubs/woocommerce-stubs", - "version": "v5.9.0", + "version": "v5.9.1", "source": { "type": "git", "url": "https://github.com/php-stubs/woocommerce-stubs.git", - "reference": "a7204cfbb5fa90720773122cb68530087de5bc78" + "reference": "486ccff117badfab94c404065d37a77d632d7db5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-stubs/woocommerce-stubs/zipball/a7204cfbb5fa90720773122cb68530087de5bc78", - "reference": "a7204cfbb5fa90720773122cb68530087de5bc78", + "url": "https://api.github.com/repos/php-stubs/woocommerce-stubs/zipball/486ccff117badfab94c404065d37a77d632d7db5", + "reference": "486ccff117badfab94c404065d37a77d632d7db5", "shasum": "" }, "require": { "php-stubs/wordpress-stubs": "^5.3.0" }, "require-dev": { - "giacocorsiglia/stubs-generator": "^0.5.0", - "php": "~7.1" + "php": "~7.1", + "php-stubs/generator": "^0.8.0" }, "suggest": { "symfony/polyfill-php73": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", @@ -1926,20 +2006,20 @@ "woocommerce", "wordpress" ], - "time": "2021-11-05T10:02:27+00:00" + "time": "2022-04-30T06:35:48+00:00" }, { "name": "php-stubs/wordpress-stubs", - "version": "v5.9.0", + "version": "v5.9.3", "source": { "type": "git", "url": "https://github.com/php-stubs/wordpress-stubs.git", - "reference": "0fa8dd9a1bd2a1b60e85afc6c798fca1f599cc1b" + "reference": "18d56875e5078a50b8ea4bc4b20b735ca61edeee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/0fa8dd9a1bd2a1b60e85afc6c798fca1f599cc1b", - "reference": "0fa8dd9a1bd2a1b60e85afc6c798fca1f599cc1b", + "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/18d56875e5078a50b8ea4bc4b20b735ca61edeee", + "reference": "18d56875e5078a50b8ea4bc4b20b735ca61edeee", "shasum": "" }, "replace": { @@ -1948,7 +2028,7 @@ "require-dev": { "nikic/php-parser": "< 4.12.0", "php": "~7.3 || ~8.0", - "php-stubs/generator": "^0.8.0", + "php-stubs/generator": "^0.8.1", "phpdocumentor/reflection-docblock": "^5.3", "phpstan/phpstan": "^1.2" }, @@ -1969,7 +2049,7 @@ "static analysis", "wordpress" ], - "time": "2022-01-26T00:27:45+00:00" + "time": "2022-04-06T15:33:59+00:00" }, { "name": "phpcompatibility/php-compatibility", @@ -2279,6 +2359,73 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "time": "2019-08-22T18:11:29+00:00" }, + { + "name": "phpoption/phpoption", + "version": "1.8.1", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15", + "reference": "eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "PhpOption\\": "src/PhpOption/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + }, + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], + "time": "2021-12-04T23:24:31+00:00" + }, { "name": "phpspec/prophecy", "version": "v1.10.3", @@ -3259,16 +3406,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.6.2", + "version": "3.7.0", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a" + "reference": "a2cd51b45bcaef9c1f2a4bda48f2dd2fa2b95563" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/5e4e71592f69da17871dba6e80dd51bce74a351a", - "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/a2cd51b45bcaef9c1f2a4bda48f2dd2fa2b95563", + "reference": "a2cd51b45bcaef9c1f2a4bda48f2dd2fa2b95563", "shasum": "" }, "require": { @@ -3306,20 +3453,20 @@ "phpcs", "standards" ], - "time": "2021-12-12T21:44:58+00:00" + "time": "2022-06-13T06:31:38+00:00" }, { "name": "symfony/console", - "version": "v4.4.37", + "version": "v4.4.42", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "0259f01dbf9d77badddbbf4c2abb681f24c9cac6" + "reference": "cce7a9f99e22937a71a16b23afa762558808d587" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/0259f01dbf9d77badddbbf4c2abb681f24c9cac6", - "reference": "0259f01dbf9d77badddbbf4c2abb681f24c9cac6", + "url": "https://api.github.com/repos/symfony/console/zipball/cce7a9f99e22937a71a16b23afa762558808d587", + "reference": "cce7a9f99e22937a71a16b23afa762558808d587", "shasum": "" }, "require": { @@ -3393,20 +3540,20 @@ "type": "tidelift" } ], - "time": "2022-01-26T16:15:26+00:00" + "time": "2022-05-14T12:35:33+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.24.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "30885182c981ab175d4d034db0f6f469898070ab" + "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", - "reference": "30885182c981ab175d4d034db0f6f469898070ab", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", "shasum": "" }, "require": { @@ -3421,7 +3568,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3429,12 +3576,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -3472,20 +3619,20 @@ "type": "tidelift" } ], - "time": "2021-10-20T20:35:02+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.24.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", "shasum": "" }, "require": { @@ -3500,7 +3647,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3552,20 +3699,20 @@ "type": "tidelift" } ], - "time": "2021-11-30T18:21:41+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.24.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5" + "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/e440d35fa0286f77fb45b79a03fedbeda9307e85", + "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85", "shasum": "" }, "require": { @@ -3574,7 +3721,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3628,20 +3775,20 @@ "type": "tidelift" } ], - "time": "2021-06-05T21:20:04+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/service-contracts", - "version": "v1.1.11", + "version": "v1.1.12", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "633df678bec3452e04a7b0337c9bcfe7354124b3" + "reference": "eedb374f02031714a48848758a27812f3eca317a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/633df678bec3452e04a7b0337c9bcfe7354124b3", - "reference": "633df678bec3452e04a7b0337c9bcfe7354124b3", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/eedb374f02031714a48848758a27812f3eca317a", + "reference": "eedb374f02031714a48848758a27812f3eca317a", "shasum": "" }, "require": { @@ -3704,7 +3851,7 @@ "type": "tidelift" } ], - "time": "2021-11-04T13:32:43+00:00" + "time": "2022-03-09T13:39:03+00:00" }, { "name": "theseer/tokenizer", @@ -3748,16 +3895,16 @@ }, { "name": "vimeo/psalm", - "version": "4.21.0", + "version": "4.23.0", "source": { "type": "git", "url": "https://github.com/vimeo/psalm.git", - "reference": "d8bec4c7aaee111a532daec32fb09de5687053d1" + "reference": "f1fe6ff483bf325c803df9f510d09a03fd796f88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vimeo/psalm/zipball/d8bec4c7aaee111a532daec32fb09de5687053d1", - "reference": "d8bec4c7aaee111a532daec32fb09de5687053d1", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/f1fe6ff483bf325c803df9f510d09a03fd796f88", + "reference": "f1fe6ff483bf325c803df9f510d09a03fd796f88", "shasum": "" }, "require": { @@ -3782,6 +3929,7 @@ "php": "^7.1|^8", "sebastian/diff": "^3.0 || ^4.0", "symfony/console": "^3.4.17 || ^4.1.6 || ^5.0 || ^6.0", + "symfony/polyfill-php80": "^1.25", "webmozart/path-util": "^2.3" }, "provide": { @@ -3846,7 +3994,83 @@ "inspection", "php" ], - "time": "2022-02-18T04:34:15+00:00" + "time": "2022-04-28T17:35:49+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "v5.4.1", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "264dce589e7ce37a7ba99cb901eed8249fbec92f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/264dce589e7ce37a7ba99cb901eed8249fbec92f", + "reference": "264dce589e7ce37a7ba99cb901eed8249fbec92f", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "graham-campbell/result-type": "^1.0.2", + "php": "^7.1.3 || ^8.0", + "phpoption/phpoption": "^1.8", + "symfony/polyfill-ctype": "^1.23", + "symfony/polyfill-mbstring": "^1.23.1", + "symfony/polyfill-php80": "^1.23.1" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "ext-filter": "*", + "phpunit/phpunit": "^7.5.20 || ^8.5.21 || ^9.5.10" + }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.4-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "time": "2021-12-12T23:22:04+00:00" }, { "name": "webmozart/assert", @@ -3946,16 +4170,16 @@ }, { "name": "woocommerce/woocommerce-sniffs", - "version": "0.1.2", + "version": "0.1.3", "source": { "type": "git", "url": "https://github.com/woocommerce/woocommerce-sniffs.git", - "reference": "5566270d280a300bc24bd0cb055a8b9325afdd6b" + "reference": "4576d54595614d689bc4436acff8baaece3c5bb0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/woocommerce/woocommerce-sniffs/zipball/5566270d280a300bc24bd0cb055a8b9325afdd6b", - "reference": "5566270d280a300bc24bd0cb055a8b9325afdd6b", + "url": "https://api.github.com/repos/woocommerce/woocommerce-sniffs/zipball/4576d54595614d689bc4436acff8baaece3c5bb0", + "reference": "4576d54595614d689bc4436acff8baaece3c5bb0", "shasum": "" }, "require": { @@ -3982,7 +4206,7 @@ "woocommerce", "wordpress" ], - "time": "2022-01-21T20:13:23+00:00" + "time": "2022-02-17T15:34:51+00:00" }, { "name": "wp-coding-standards/wpcs", diff --git a/package.json b/package.json index 53918de58..b02952909 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,9 @@ "ddev:install": "ddev composer install && yarn run ddev:build-js", "ddev:build-js": "ddev yarn build:dev", "ddev:composer-update": "ddev composer update && ddev composer update --lock", - "ddev:test": "ddev exec phpunit", + "ddev:unit-tests": "ddev exec phpunit", + "ddev:e2e-tests": "cp -n .env.e2e.example .env.e2e && ddev php tests/e2e/PHPUnit/setup.php && ddev exec phpunit -c tests/e2e/phpunit.xml.dist", + "ddev:test": "yarn run ddev:unit-tests && yarn run ddev:e2e-tests", "ddev:lint": "yarn ddev:phpcs && yarn ddev:psalm", "ddev:phpcs": "ddev exec phpcs --parallel=8 -s", "ddev:psalm": "ddev exec psalm --show-info=false --threads=8 --diff", diff --git a/tests/e2e/PHPUnit/Order/PurchaseUnitTest.php b/tests/e2e/PHPUnit/Order/PurchaseUnitTest.php new file mode 100644 index 000000000..97a3392bc --- /dev/null +++ b/tests/e2e/PHPUnit/Order/PurchaseUnitTest.php @@ -0,0 +1,235 @@ +postIds as $id) { + wp_delete_post($id); + } + + parent::tearDown(); + } + + /** + * @dataProvider successData + */ + public function testOrder(array $orderData, array $expectedAmount) + { + $wcOrder = $this->createWcOrder($orderData); + + $this->container = $this->getContainer(); + + $factory = $this->container->get( 'api.factory.purchase-unit' ); + assert($factory instanceof PurchaseUnitFactory); + + $pu = $factory->from_wc_order($wcOrder); + $puData = $pu->to_array(); + + self::assertTrue(isset($puData['amount']['breakdown'])); + + self::assertEquals($expectedAmount, $puData['amount']); + } + + protected function createWcOrder(array $data): WC_Order { + $wcOrder = new WC_Order(); + $wcOrder->set_currency( $data['currency'] ?? self::CURRENCY); + $wcOrder->set_prices_include_tax($data['prices_include_tax'] ?? true); + + foreach ($data['items'] as $itemData) { + $item = new WC_Order_Item_Product(); + $item->set_name($itemData['name'] ?? 'Test product'); + $item->set_quantity($itemData['quantity'] ?? 1); + $item->set_total((string) ($itemData['price'] * $itemData['quantity'] ?? 1)); + $wcOrder->add_item($item); + } + + $wcOrder->set_address(array_merge([ + 'first_name' => 'John', + 'last_name' => 'Doe', + 'company' => '', + 'email' => 'jd@example.com', + 'phone' => '1234567890', + 'address_1' => '123 st', + 'address_2' => '', + 'city' => 'city0', + 'state' => 'state0', + 'country' => 'AQ', + 'postcode' => '12345', + ], $data['billing'] ?? [])); + + if (isset($data['shipping'])) { + $shipping = new WC_Order_Item_Shipping(); + $shipping->set_total((string) $data['shipping']['total']); + $wcOrder->add_item($shipping); + } + + $wcOrder->calculate_totals(); + $wcOrder->save(); + + $this->postIds[] = $wcOrder->get_id(); + + foreach ($data['coupons'] ?? [] as $couponData) { + $coupon = new WC_Coupon(); + $coupon->set_amount($couponData['amount']); + $coupon->set_discount_type($couponData['type']); + $coupon->set_code(uniqid()); + $coupon->set_virtual(true); + $coupon->save(); + + $this->postIds[] = $coupon->get_id(); + + $ret = $wcOrder->apply_coupon($coupon); + if (is_wp_error($ret)) { + throw new Exception('Incorrect coupon. ' . $ret->get_error_message()); + } + } + + $wcOrder->calculate_totals(); + $wcOrder->save(); + + return $wcOrder; + } + + public function successData() { + yield [ + [ + 'items' => [ + ['price' => 11.99, 'quantity' => 1], + ], + 'shipping' => ['total' => 4.99], + 'billing' => ['city' => 'city1'], + ], + self::adaptAmountFormat([ + 'value' => 18.44, + 'breakdown' => [ + 'item_total' => 11.99, + 'tax_total' => 1.46, + 'shipping' => 4.99, + ], + ]), + ]; + yield [ + [ + 'items' => [ + ['price' => 11.99, 'quantity' => 3], + ], + 'shipping' => ['total' => 4.99], + 'billing' => ['city' => 'city1'], + ], + self::adaptAmountFormat([ + 'value' => 44.49, + 'breakdown' => [ + 'item_total' => 35.97, + 'tax_total' => 3.53, + 'shipping' => 4.99, + ], + ]), + ]; + yield [ + [ + 'items' => [ + ['price' => 18.0, 'quantity' => 1], + ], + 'shipping' => ['total' => 4.99], + 'billing' => ['city' => 'city1'], + ], + self::adaptAmountFormat([ + 'value' => 24.97, + 'breakdown' => [ + 'item_total' => 18.0, + 'tax_total' => 1.98, + 'shipping' => 4.99, + ], + ]), + ]; + yield [ + [ + 'items' => [ + ['price' => 18.0, 'quantity' => 3], + ], + 'shipping' => ['total' => 4.99], + 'billing' => ['city' => 'city1'], + ], + self::adaptAmountFormat([ + 'value' => 64.08, + 'breakdown' => [ + 'item_total' => 54.0, + 'tax_total' => 5.09, + 'shipping' => 4.99, + ], + ]), + ]; + yield [ + [ + 'items' => [ + ['price' => 11.25, 'quantity' => 3], + ], + 'billing' => ['city' => 'city2'], + ], + self::adaptAmountFormat([ + 'value' => 53.99, + 'breakdown' => [ + 'item_total' => 33.75, + 'tax_total' => 20.24, + 'shipping' => 0.0, + ], + ]), + ]; + yield [ + [ + 'items' => [ + ['price' => 11.99, 'quantity' => 3], + ], + 'shipping' => ['total' => 4.99], + 'billing' => ['city' => 'city1'], + 'coupons' => [ + ['amount' => 2.39, 'type' => 'fixed_cart'], + ['amount' => 7.33, 'type' => 'fixed_cart'], + ] + ], + self::adaptAmountFormat([ + 'value' => 34.77, + 'breakdown' => [ + 'item_total' => 35.97, + 'tax_total' => 2.76, + 'shipping' => 4.99, + 'discount' => 8.95, + ], + ]), + ]; + } + + private static function adaptAmountFormat(array $data, string $currency = null): array { + if (!$currency) { + $currency = self::CURRENCY; + } + + $data['currency_code'] = $currency; + if (isset($data['breakdown'])) { + foreach ($data['breakdown'] as $key => $value) { + $data['breakdown'][$key] = [ + 'currency_code' => $currency, + 'value' => $value, + ]; + } + } + + return $data; + } +} diff --git a/tests/e2e/PHPUnit/TestCase.php b/tests/e2e/PHPUnit/TestCase.php new file mode 100644 index 000000000..6c7694a77 --- /dev/null +++ b/tests/e2e/PHPUnit/TestCase.php @@ -0,0 +1,16 @@ +load(); +} + +if (!isset($_ENV['PPCP_E2E_WP_DIR'])) { + exit('Copy .env.e2e.example to .env.e2e or define the environment variables.' . PHP_EOL); +} +$wpRootDir = str_replace('${ROOT_DIR}', ROOT_DIR, $_ENV['PPCP_E2E_WP_DIR']); + +define('WP_ROOT_DIR', $wpRootDir); + +$_SERVER['HTTP_HOST'] = ''; // just to avoid a warning + +require_once WP_ROOT_DIR . '/wp-load.php'; diff --git a/tests/e2e/PHPUnit/ppcp-e2e-plugin.php b/tests/e2e/PHPUnit/ppcp-e2e-plugin.php new file mode 100644 index 000000000..1580fc75c --- /dev/null +++ b/tests/e2e/PHPUnit/ppcp-e2e-plugin.php @@ -0,0 +1,19 @@ + 'yes', + 'woocommerce_prices_include_tax' => 'yes', + 'woocommerce_tax_based_on' => 'billing', + 'woocommerce_shipping_tax_class' => 'inherit', + 'woocommerce_tax_round_at_subtotal' => 'no', +]; + +foreach ($options as $key => $value) { + echo "Setting $key to $value." . PHP_EOL; + update_option($key, $value); +} + +echo 'Adding ppcp-e2e-plugin.' . PHP_EOL; + +$pluginDir = WP_ROOT_DIR . '/wp-content/plugins/ppcp-e2e-plugin'; +if (!is_dir($pluginDir)) { + mkdir($pluginDir); +} +if (!copy(E2E_TESTS_ROOT_DIR . '/PHPUnit/ppcp-e2e-plugin.php', $pluginDir . '/ppcp-e2e-plugin.php')) { + echo 'Failed to copy ppcp-e2e-plugin.' . PHP_EOL; +} + +activate_plugin('ppcp-e2e-plugin/ppcp-e2e-plugin.php', '', true); + +echo 'Deleting test taxes.' . PHP_EOL; + +$taxRates = WC_Tax::get_rates_for_tax_class(''); +$testTaxRates = array_filter($taxRates, function ($taxRate): bool { + return str_contains($taxRate->tax_rate_name, '[PPCP TEST]'); +}); +foreach ($testTaxRates as $rate) { + WC_Tax::_delete_tax_rate($rate->tax_rate_id); +} + +echo 'Importing test taxes.' . PHP_EOL; + +require WP_ROOT_DIR . '/wp-admin/includes/class-wp-importer.php'; +require WP_ROOT_DIR . '/wp-content/plugins/woocommerce/includes/admin/importers/class-wc-tax-rate-importer.php'; + +$taxImporter = new WC_Tax_Rate_Importer(); +$taxImporter->import(E2E_TESTS_ROOT_DIR . '/data/tax_rates.csv'); + +echo PHP_EOL; diff --git a/tests/e2e/data/tax_rates.csv b/tests/e2e/data/tax_rates.csv new file mode 100644 index 000000000..304280f40 --- /dev/null +++ b/tests/e2e/data/tax_rates.csv @@ -0,0 +1,4 @@ +Country code,State code,Postcode / ZIP,City,Rate %,Tax name,Priority,Compound,Shipping,Tax class +AQ,,,CITY1,8.625,[PPCP TEST] Tax 1,1,0,1, +AQ,,,CITY2,10,[PPCP TEST] Tax 2.1,1,0,1, +AQ,,,CITY2,50,[PPCP TEST] Tax 2.2,2,0,1, diff --git a/tests/e2e/phpunit.xml.dist b/tests/e2e/phpunit.xml.dist new file mode 100644 index 000000000..433f7955a --- /dev/null +++ b/tests/e2e/phpunit.xml.dist @@ -0,0 +1,15 @@ + + + + + ./PHPUnit + + +