From a6f0c779decd9cbfc53f083af691a46d33d4b8b3 Mon Sep 17 00:00:00 2001 From: Liam Parker Date: Wed, 30 Sep 2026 12:14:06 +1000 Subject: [PATCH] Add filter support to order value --- .github/workflows/deploy.yml | 4 + .github/workflows/test.yml | 31 +++++++ spiff-connect/README.txt | 10 ++- spiff-connect/spiff-connect.php | 4 +- tests/CreateOrderTest.php | 108 +++++++++++++++++++++++ tests/RequestsTest.php | 2 - tests/bootstrap.php | 150 ++++++++++++++++++++++++++++++++ tests/phpunit.xml | 2 +- 8 files changed, 306 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/test.yml create mode 100644 tests/CreateOrderTest.php create mode 100644 tests/bootstrap.php diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 4da5ef0..aaa1afa 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -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: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..c28b3e0 --- /dev/null +++ b/.github/workflows/test.yml @@ -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 diff --git a/spiff-connect/README.txt b/spiff-connect/README.txt index 4f02d78..4f320b1 100644 --- a/spiff-connect/README.txt +++ b/spiff-connect/README.txt @@ -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) diff --git a/spiff-connect/spiff-connect.php b/spiff-connect/spiff-connect.php index dbe9143..8b718a6 100644 --- a/spiff-connect/spiff-connect.php +++ b/spiff-connect/spiff-connect.php @@ -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)); } } diff --git a/tests/CreateOrderTest.php b/tests/CreateOrderTest.php new file mode 100644 index 0000000..e143da2 --- /dev/null +++ b/tests/CreateOrderTest.php @@ -0,0 +1,108 @@ + $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']); + } +} diff --git a/tests/RequestsTest.php b/tests/RequestsTest.php index 483db81..a4c8a24 100644 --- a/tests/RequestsTest.php +++ b/tests/RequestsTest.php @@ -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); diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..325938c --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,150 @@ + $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'; diff --git a/tests/phpunit.xml b/tests/phpunit.xml index ff2e2a2..ec5b1e0 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -1,5 +1,5 @@ - + ../../src