Skip to content
This repository has been archived by the owner on Nov 13, 2024. It is now read-only.

Commit

Permalink
Merge pull request #4 from a8cteam51/test/events
Browse files Browse the repository at this point in the history
Add event tests
  • Loading branch information
n3f authored Oct 23, 2024
2 parents 01628e1 + bfda5c6 commit a7f8a51
Show file tree
Hide file tree
Showing 15 changed files with 775 additions and 33 deletions.
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
stable
4 changes: 2 additions & 2 deletions .wp-env.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"plugins": [
"https://downloads.wordpress.org/plugin/woocommerce.9.3.3.zip",
"./bin/test-payment-gateway",
"."
".",
"./bin/test-payment-gateway"
],
"lifecycleScripts": {
"afterStart": "./bin/bootstrap-woocommerce.sh"
Expand Down
19 changes: 15 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,19 @@ As you develop your plugin, update the README.md file with detailed information

## Local Development

Use [`wp-env`](https://github.com/WordPress/gutenberg/tree/HEAD/packages/env#readme) to run a local development environment.
1. `npm install`
2. `composer install`
3. `npx wp-env start` -- This starts a local WordPress environment available at <http://localhost:8888>
4. `npm test`

```bash
wp-env start
```
### Using XDEBUG

Start environment with XDEBUG enabled: `npx wp-env start --xdebug`. Configure your IDE to listen for XDEBUG connections on port 9003. When you browse in the browser, XDEBUG should connect to your IDE.

To get tests working with XDEBUG, it requires a little more work. Configure your IDE server name to be something like `XDEBUG_OMATTIC` and then launch the tests by running `npx wp-env run tests-cli --env-cwd=wp-content/plugins/sift-decisions bash`. At the new prompt you need to run: `PHP_IDE_CONFIG=serverName=XDEBUG_OMATTIC vendor/bin/phpunit`.

### Troubleshooting:

#### `Error response from daemon: error while creating mount source path`

Restart docker.
78 changes: 52 additions & 26 deletions src/inc/woocommerce-actions.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace WPCOMSpecialProjects\SiftDecisions\WooCommerce_Actions;

use WC_Order_Item_Product;

/**
* Class Events
*/
Expand All @@ -20,7 +22,7 @@ public static function hooks() {
add_action( 'wp_login', array( static::class, 'login_success' ), 100, 2 );
add_action( 'wp_login_failed', array( static::class, 'login_failure' ), 100, 2 );
add_action( 'user_register', array( static::class, 'create_account' ), 100 );
add_action( 'profile_update', array( static::class, 'update_account' ), 100 );
add_action( 'profile_update', array( static::class, 'update_account' ), 100, 3 );
add_action( 'wp_set_password', array( static::class, 'update_password' ), 100, 2 );
add_action( 'woocommerce_add_to_cart', array( static::class, 'add_to_cart' ), 100 );
add_action( 'woocommerce_remove_cart_item', array( static::class, 'remove_from_cart' ), 100, 2 );
Expand Down Expand Up @@ -114,22 +116,24 @@ public static function login_failure( string $username, \WP_Error $error ) {
$failure_reason = '$account_disabled';
break;
default:
$failure_reason = '$' . $error->get_error_code();
// Only other accepted failure reason is $account_suspended... We shouldn't set the failure reason.
$failure_reason = null;
}

self::add(
'$login',
array(
'$user_id' => $attempted_user->ID ? $attempted_user->ID : null,
'$login_status' => '$failure',
'$session_id' => WC()->session->get_customer_unique_id(),
'$browser' => self::get_client_browser(), // alternately, `$app` for details of the app if not a browser.
'$username' => $username,
'$failure_reason' => $failure_reason,
'$ip' => self::get_client_ip(),
'$time' => intval( 1000 * microtime( true ) ),
)
$properties = array(
'$user_id' => $attempted_user->ID ? $attempted_user->ID : null,
'$login_status' => '$failure',
'$session_id' => WC()->session->get_customer_unique_id(),
'$browser' => self::get_client_browser(), // alternately, `$app` for details of the app if not a browser.
'$username' => $username,
'$ip' => self::get_client_ip(),
'$time' => intval( 1000 * microtime( true ) ),
);

if ( ! empty( $failure_reason ) ) {
$properties['$failure_reason'] = $failure_reason;
}

self::add( '$login', $properties );
}

/**
Expand Down Expand Up @@ -171,13 +175,20 @@ public static function create_account( string $user_id ) {
*
* @link https://developers.sift.com/docs/curl/events-api/reserved-events/update-account
*
* @param string $user_id User's ID.
* @param string $user_id User's ID.
* @param \WP_User $old_user_data The old user data.
* @param array $new_user_data The new user data.
*
* @return void
*/
public static function update_account( string $user_id ) {
public static function update_account( string $user_id, ?\WP_User $old_user_data = null, ?array $new_user_data = null ) {
$user = get_user_by( 'id', $user_id );

// check if the password changed
if ( ! empty( $new_user_data['user_pass'] ) && $old_user_data->user_pass !== $new_user_data['user_pass'] ) {
self::update_password( '', $user_id );
}

self::add(
'$update_account',
array(
Expand Down Expand Up @@ -264,14 +275,19 @@ public static function link_session_to_user( string $session_id, string $user_id
*/
public static function add_to_cart( string $cart_item_key ) {
$cart_item = \WC()->cart->get_cart_item( $cart_item_key );
$product = $cart_item['data'];
$user = wp_get_current_user();
/** @var \WC_Abstract_Legacy_Product $product */
$product = $cart_item['data'] ?? null;
$user = wp_get_current_user();

if ( ! $product ) {
return;
}

self::add(
'$add_item_to_cart',
array(
'$user_id' => $user->ID ? $user->ID : null,
'$user_email' => $user->user_email ? $user->user_email : null,
'$user_id' => $user->ID ?? null,
'$user_email' => $user->user_email ?? null,
'$session_id' => \WC()->session->get_customer_unique_id(),
'$item' => array(
'$item_id' => $cart_item_key,
Expand All @@ -280,8 +296,8 @@ public static function add_to_cart( string $cart_item_key ) {
'$price' => $product->get_price() * 1000000, // $39.99
'$currency_code' => get_woocommerce_currency(),
'$quantity' => $cart_item['quantity'],
'$category' => $product->get_categories(),
'$tags' => wp_list_pluck( get_the_terms( $product->ID, 'product_tag' ), 'name' ),
'$category' => wc_get_product_category_list( $product->get_id() ),
'$tags' => wp_list_pluck( get_the_terms( $product->get_id(), 'product_tag' ), 'name' ),
),
'$browser' => self::get_client_browser(),
'$site_domain' => wp_parse_url( site_url(), PHP_URL_HOST ),
Expand Down Expand Up @@ -320,8 +336,8 @@ public static function remove_from_cart( string $cart_item_key, \WC_Cart $cart )
'$price' => $product->get_price() * 1000000, // $39.99
'$currency_code' => get_woocommerce_currency(),
'$quantity' => $cart_item['quantity'],
'$category' => $product->get_categories(),
'$tags' => wp_list_pluck( get_the_terms( $product->ID, 'product_tag' ), 'name' ),
'$category' => wc_get_product_category_list( $product->get_id() ),
'$tags' => wp_list_pluck( get_the_terms( $product->get_id(), 'product_tag' ), 'name' ),
),
'$browser' => self::get_client_browser(),
'$site_domain' => wp_parse_url( site_url(), PHP_URL_HOST ),
Expand Down Expand Up @@ -350,8 +366,18 @@ public static function create_order( string $order_id, array $posted_data, \WC_O
$physical_or_electronic = '$electronic';
$items = array();
foreach ( $order->get_items( 'line_item' ) as $item ) {
if ( ! $item instanceof WC_Order_Item_Product ) {
// log an error...
wc_get_logger()->error( sprintf( 'Item not Item Product (order: %d).', $order->get_id() ) );
continue;
}
// Most of this we're basing off return value from `WC_Order_Item_Product::get_product()` as it will return the correct variation.
$product = $item->get_product();
if ( empty( $product ) ) {
// log an error...
wc_get_logger()->error( sprintf( 'Product not found for order %d.', $order->get_id() ) );
continue;
}

$items[] = array(
'$item_id' => $product->get_id(),
Expand All @@ -360,7 +386,7 @@ public static function create_order( string $order_id, array $posted_data, \WC_O
'$price' => $product->get_price() * 1000000, // $39.99
'$currency_code' => $order->get_currency(), // For the order specifically, not the whole store.
'$quantity' => $item->get_quantity(),
'$category' => $product->get_categories(),
'$category' => wc_get_product_category_list( $product->get_id() ),
'$tags' => wp_list_pluck( get_the_terms( $product->get_id(), 'product_tag' ), 'name' ),
);

Expand Down
1 change: 1 addition & 0 deletions src/sift-decisions.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ public static function get_api_client() {
array(
'api_key' => $api_key,
'account_id' => $account_id,
'version' => '205', // Hardcode this so new sift versions don't break us.
)
);
}
Expand Down
45 changes: 45 additions & 0 deletions tests/AddsItemToCartEventTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php
/**
* Class AddsItemToCartEventTest
*
* @package Sift_Decisions
*/

require_once 'EventTest.php';

// phpcs:disable Universal.Arrays.DisallowShortArraySyntax.Found, WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound

use WPCOMSpecialProjects\SiftDecisions\WooCommerce_Actions\Events;

/**
* Test case.
*/
class AddsItemToCartEventTest extends EventTest {
/**
* Test that the $add_item_to_cart event is triggered.
*
* @return void
*/
public function test_adds_item_to_cart() {
\WC()->cart->add_to_cart( static::$product_id );
$this->assertAddsItemToCartEventTriggered();
}

/**
* Assert $add_item_to_cart event is triggered.
*
* @param integer $product_id Product ID.
*
* @return void
*/
public static function assertAddsItemToCartEventTriggered( $product_id = null ) {
$product = wc_get_product( $product_id ?? static::$product_id );
$events = static::filter_events(
[
'event' => '$add_item_to_cart',
'properties.$item.$sku' => $product->get_sku(),
]
);
static::assertGreaterThanOrEqual( 1, count( $events ), 'No $add_item_to_cart event found.' );
}
}
40 changes: 40 additions & 0 deletions tests/CreateAccountEventTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php
/**
* Class CreateAccountEventTest
*
* @package Sift_Decisions
*/

require_once 'EventTest.php';

// phpcs:disable Universal.Arrays.DisallowShortArraySyntax.Found, WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound

use WPCOMSpecialProjects\SiftDecisions\WooCommerce_Actions\Events;

/**
* Test case.
*/
class CreateAccountEventTest extends EventTest {
/**
* Test that the $create_account event is triggered.
*
* @return void
*/
public function test_create_account() {
$user = wp_create_user( 'testuser', 'password' );

$this->assertCreateAccountEventTriggered();

wp_delete_user( $user );
}

/**
* Assert $create_account event is triggered.
*
* @return void
*/
public static function assertCreateAccountEventTriggered() {
$events = static::filter_events( [ 'event' => '$create_account' ] );
static::assertGreaterThanOrEqual( 1, count( $events ) );
}
}
47 changes: 47 additions & 0 deletions tests/CreateOrderEventTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php
/**
* Class CreateOrderEventTest
*
* @package Sift_Decisions
*/

require_once 'EventTest.php';

// phpcs:disable Universal.Arrays.DisallowShortArraySyntax.Found, WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound

use WPCOMSpecialProjects\SiftDecisions\WooCommerce_Actions\Events;

/**
* Test case.
*/
class CreateOrderEventTest extends EventTest {
/**
* Test that the $create_order event is triggered.
*
* @return void
*/
public function test_create_account() {
// Arrange
$_REQUEST['woocommerce-process-checkout-nonce'] = wp_create_nonce( 'woocommerce-process_checkout' );
add_filter( 'woocommerce_checkout_fields', fn() => [], 10, 0 );
add_filter( 'woocommerce_cart_needs_payment', '__return_false' );

// Act
WC()->cart->add_to_cart( static::$product_id );
$co = WC_Checkout::instance();
$co->process_checkout();

// Assert
static::assertCreateOrderEventTriggered();
}

/**
* Assert $create_order event is triggered.
*
* @return void
*/
public static function assertCreateOrderEventTriggered() {
$events = static::filter_events( [ 'event' => '$create_order' ] );
static::assertGreaterThanOrEqual( 1, count( $events ), 'No $create_order event found' );
}
}
Loading

0 comments on commit a7f8a51

Please sign in to comment.