Add tests using real WC

This commit is contained in:
Alex P 2022-06-15 21:37:10 +03:00
parent 02c84e43e0
commit 04aba8ceb1
14 changed files with 746 additions and 114 deletions

View file

@ -0,0 +1,235 @@
<?php
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\Tests\E2e\Order;
use Exception;
use WC_Coupon;
use WC_Order;
use WC_Order_Item_Product;
use WC_Order_Item_Shipping;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
use WooCommerce\PayPalCommerce\Tests\E2e\TestCase;
class PurchaseUnitTest extends TestCase
{
protected $postIds = [];
const CURRENCY = 'EUR';
public function tearDown(): void
{
foreach ($this->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;
}
}

View file

@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\Tests\E2e;
use PPCP_E2E;
use Psr\Container\ContainerInterface;
class TestCase extends \PHPUnit\Framework\TestCase
{
protected $container;
protected function getContainer(): ContainerInterface {
return PPCP_E2E::$container;
}
}

View file

@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
define('E2E_TESTS_ROOT_DIR', dirname(__DIR__));
define('ROOT_DIR', dirname(dirname(E2E_TESTS_ROOT_DIR)));
require_once ROOT_DIR . '/vendor/autoload.php';
if (file_exists(ROOT_DIR . '/.env.e2e')) {
$dotenv = Dotenv\Dotenv::createImmutable(ROOT_DIR, '.env.e2e');
$dotenv->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';

View file

@ -0,0 +1,19 @@
<?php
/**
* Plugin Name: WooCommerce PayPal Payments e2e
* Description: PPCP e2e
* Version: 1.0.0
* Author: Inpsyde
* License: GPL-2.0
*/
declare(strict_types=1);
class PPCP_E2E
{
public static $container;
}
add_filter('woocommerce_paypal_payments_built_container', function($app_container): void {
PPCP_E2E::$container = $app_container;
});

View file

@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
require __DIR__ . '/bootstrap.php';
$options = [
'woocommerce_calc_taxes' => '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;

View file

@ -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,
1 Country code State code Postcode / ZIP City Rate % Tax name Priority Compound Shipping Tax class
2 AQ CITY1 8.625 [PPCP TEST] Tax 1 1 0 1
3 AQ CITY2 10 [PPCP TEST] Tax 2.1 1 0 1
4 AQ CITY2 50 [PPCP TEST] Tax 2.2 2 0 1

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
bootstrap="PHPUnit/bootstrap.php"
backupGlobals="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
>
<testsuites>
<testsuite name="unit">
<directory suffix="Test.php">./PHPUnit</directory>
</testsuite>
</testsuites>
</phpunit>