Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ permissions:
contents: write # Allow commit

jobs:
test:
uses: ./.github/workflows/test.yml

deploy:
name: Deploy to ${{ github.event.inputs.environment }}
needs: test
runs-on: ubuntu-latest
environment: ${{ github.event.inputs.environment }}
steps:
Expand Down
31 changes: 31 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Test
on:
push:
branches:
- master
pull_request:
workflow_call:

permissions:
contents: read

jobs:
test:
name: PHPUnit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

# The locked dev dependencies (PHPUnit 9.3, Prophecy 1.11) don't install on PHP 8.
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: "7.4"
coverage: none
tools: composer:v2

- name: Install dependencies
run: composer install --no-interaction --no-progress

- name: Run tests
run: vendor/bin/phpunit -c tests/phpunit.xml --no-coverage
10 changes: 9 additions & 1 deletion spiff-connect/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,15 @@ All apparel, Shoes, Promotional Products, Homewares, sporting equipment, FMCG (a

* Check the "Enable Spiff" checkbox.

* Enter the ID of the corresponding integration product by clicking copy Integration ID to clipboard from the corresponding product on the integrations page.
* Enter the ID of the corresponding integration product by clicking copy Integration ID to clipboard from the corresponding product on the integrations page.

###**Customising the Spiff order number**

By default, orders are sent to Spiff with the WooCommerce order ID as their order number. To use a different value, such as a custom order number, add a filter to your theme's functions.php:

`add_filter('spiff_order_external_id', function ($external_id, $order) {
return $order->get_order_number();
}, 10, 2);`


If you have any problems contact spiff support [https://spiff3d.com/contact-us/](https://spiff3d.com/contact-us/) or visit [https://help.spiff.com.au](https://help.spiff.com.au)
4 changes: 3 additions & 1 deletion spiff-connect/spiff-connect.php
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,9 @@ function spiff_create_order($order_id) {
// Post the order.
if (!empty($items)) {
$application_key = get_option('spiff_application_key');
spiff_post_order($application_key, $items, $order->get_id(), $order->is_paid(), spiff_get_external_order_data($order));
// Allow the ID shown as the order number in Spiff to be customised, e.g. to use a custom order number.
$external_id = apply_filters('spiff_order_external_id', $order->get_id(), $order);
spiff_post_order($application_key, $items, $external_id, $order->is_paid(), spiff_get_external_order_data($order));
}
}

Expand Down
108 changes: 108 additions & 0 deletions tests/CreateOrderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?php

use PHPUnit\Framework\TestCase;

final class CreateOrderTest extends TestCase {
protected function setUp(): void {
spiff_test_reset();
$GLOBALS['spiff_test_options']['spiff_application_key'] = 'test-application-key';
}

private function addOrder($id, $order_number, $items, $paid = true) {
$GLOBALS['spiff_test_orders'][$id] = new Spiff_Test_Order($id, $order_number, $items, $paid);
}

private function spiffItem($transaction_id, $quantity = 1) {
return new Spiff_Test_Order_Item(array('spiff_transaction_id' => $transaction_id), $quantity);
}

private function sentVariables() {
$this->assertCount(1, $GLOBALS['spiff_test_requests']);
return json_decode($GLOBALS['spiff_test_requests'][0]['args']['body'], true)['variables'];
}

public function testUsesOrderIdAsExternalIdByDefault() {
$this->addOrder(123, 'VEG-1042', array($this->spiffItem('transaction-1')));

spiff_create_order(123);

$this->assertSame('123', $this->sentVariables()['externalId']);
}

public function testFilterCanReplaceExternalIdWithOrderNumber() {
$this->addOrder(123, 'VEG-1042', array($this->spiffItem('transaction-1')));
add_filter('spiff_order_external_id', function ($external_id, $order) {
return $order->get_order_number();
}, 10, 2);

spiff_create_order(123);

$this->assertSame('VEG-1042', $this->sentVariables()['externalId']);
}

public function testFilterReceivesOrderIdAndOrder() {
$this->addOrder(123, 'VEG-1042', array($this->spiffItem('transaction-1')));
$received = null;
add_filter('spiff_order_external_id', function ($external_id, $order) use (&$received) {
$received = array($external_id, $order);
return $external_id;
}, 10, 2);

spiff_create_order(123);

$this->assertSame(123, $received[0]);
$this->assertSame($GLOBALS['spiff_test_orders'][123], $received[1]);
}

public function testNumericFilterResultIsSentAsString() {
$this->addOrder(123, 'VEG-1042', array($this->spiffItem('transaction-1')));
add_filter('spiff_order_external_id', function () {
return 5000;
});

spiff_create_order(123);

$this->assertSame('5000', $this->sentVariables()['externalId']);
}

public function testOrderNumberIsAlwaysSentInExternalData() {
$this->addOrder(123, 'VEG-1042', array($this->spiffItem('transaction-1')));

spiff_create_order(123);

$this->assertSame('VEG-1042', $this->sentVariables()['externalData']['orderNumber']);
}

public function testOnlyItemsWithTransactionsAreSent() {
$this->addOrder(123, 'VEG-1042', array(
$this->spiffItem('transaction-1', 2),
new Spiff_Test_Order_Item(array(), 1),
$this->spiffItem('transaction-2', '3'),
));

spiff_create_order(123);

$this->assertSame(array(
array('amountToOrder' => 2, 'transactionId' => 'transaction-1'),
array('amountToOrder' => 3, 'transactionId' => 'transaction-2'),
), $this->sentVariables()['orderItems']);
}

public function testNoRequestIsSentWithoutSpiffItems() {
$this->addOrder(123, 'VEG-1042', array(new Spiff_Test_Order_Item(array(), 1)));

spiff_create_order(123);

$this->assertCount(0, $GLOBALS['spiff_test_requests']);
}

public function testSendsPaidFlagAndApplicationKey() {
$this->addOrder(123, 'VEG-1042', array($this->spiffItem('transaction-1')), false);

spiff_create_order(123);

$this->assertFalse($this->sentVariables()['paid']);
$headers = $GLOBALS['spiff_test_requests'][0]['args']['headers'];
$this->assertSame('test-application-key', $headers['X-Application-Key']);
}
}
2 changes: 0 additions & 2 deletions tests/RequestsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

use PHPUnit\Framework\TestCase;

require 'spiff-connect/includes/spiff-connect-requests.php';

final class RequestsTest extends TestCase {
public function testDummy() {
$this->assertEquals(true, true);
Expand Down
150 changes: 150 additions & 0 deletions tests/bootstrap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
<?php

/**
* Minimal WordPress and WooCommerce stand-ins so the plugin can be loaded and exercised outside of WordPress.
*/

$GLOBALS['spiff_test_options'] = array();
$GLOBALS['spiff_test_filters'] = array();
$GLOBALS['spiff_test_requests'] = array();
$GLOBALS['spiff_test_orders'] = array();

function spiff_test_reset() {
$GLOBALS['spiff_test_options'] = array();
$GLOBALS['spiff_test_requests'] = array();
$GLOBALS['spiff_test_orders'] = array();
unset($GLOBALS['spiff_test_filters']['spiff_order_external_id']);
}

// Hooks.

function add_filter($tag, $callback, $priority = 10, $accepted_args = 1) {
$GLOBALS['spiff_test_filters'][$tag][$priority][] = array($callback, $accepted_args);
return true;
}

function add_action($tag, $callback, $priority = 10, $accepted_args = 1) {
return add_filter($tag, $callback, $priority, $accepted_args);
}

function apply_filters($tag, $value, ...$args) {
if (empty($GLOBALS['spiff_test_filters'][$tag])) {
return $value;
}
$callbacks = $GLOBALS['spiff_test_filters'][$tag];
ksort($callbacks);
foreach ($callbacks as $priority_callbacks) {
foreach ($priority_callbacks as list($callback, $accepted_args)) {
$value = call_user_func_array($callback, array_slice(array_merge(array($value), $args), 0, $accepted_args));
}
}
return $value;
}

function register_activation_hook($file, $callback) {}
function add_shortcode($tag, $callback) {}

// Options.

function get_option($name, $default = false) {
return array_key_exists($name, $GLOBALS['spiff_test_options']) ? $GLOBALS['spiff_test_options'][$name] : $default;
}

function plugin_dir_path($file) {
return dirname($file) . '/';
}

// HTTP. Requests are recorded rather than sent.

function wp_remote_post($url, $args) {
$GLOBALS['spiff_test_requests'][] = array('url' => $url, 'args' => $args);
return array(
'response' => array('code' => 200),
'body' => json_encode(array('data' => array('orderCreate' => array('id' => 'spiff-order-id')))),
);
}

function wp_remote_retrieve_response_code($response) {
return $response['response']['code'];
}

function wp_remote_retrieve_body($response) {
return $response['body'];
}

// WooCommerce.

function wc_get_order($order_id) {
return $GLOBALS['spiff_test_orders'][$order_id] ?? false;
}

class Spiff_Test_Order_Item implements ArrayAccess {
private $meta;
private $quantity;

public function __construct($meta, $quantity) {
$this->meta = $meta;
$this->quantity = $quantity;
}

public function get_meta($key) {
return $this->meta[$key] ?? '';
}

public function get_quantity() {
return $this->quantity;
}

public function offsetExists($offset): bool {
return $offset === 'qty';
}

#[\ReturnTypeWillChange]
public function offsetGet($offset) {
return $offset === 'qty' ? $this->quantity : null;
}

public function offsetSet($offset, $value): void {}
public function offsetUnset($offset): void {}
}

class Spiff_Test_Order {
private $id;
private $order_number;
private $items;
private $paid;

public function __construct($id, $order_number, $items, $paid = true) {
$this->id = $id;
$this->order_number = $order_number;
$this->items = $items;
$this->paid = $paid;
}

public function get_id() {
return $this->id;
}

public function get_order_number() {
return $this->order_number;
}

public function get_items() {
return $this->items;
}

public function is_paid() {
return $this->paid;
}

public function get_coupon_codes() {
return array();
}

// Remaining getters (addresses, email, phone, note) aren't under test, so return empty values.
public function __call($name, $arguments) {
return '';
}
}

require_once __DIR__ . '/../spiff-connect/spiff-connect.php';
2 changes: 1 addition & 1 deletion tests/phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" colors="true" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<phpunit bootstrap="bootstrap.php" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" colors="true" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<coverage>
<include>
<directory suffix=".php">../../src</directory>
Expand Down
Loading