File: D:/HostingSpaces/SBogers10/shop.komma.nl/tests/Unit/OrderNumberTest.php
<?php
namespace Tests\Unit;
use App\Cart\ShoppingCart;
use App\Cart\ShoppingCartInterface;
use App\Orders\Models\Order;
use App\Orders\OrderNumberSequence;
use Tests\TestCase;
use Carbon\Carbon;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use RuntimeException;
class OrderNumberTest extends TestCase
{
use DatabaseTransactions; //Automatically rolls back database actions after tests
/**
* @var ShoppingCartInterface $shoppingCart
*/
private $shoppingCart;
/**
* Runs before each test
*/
public function setUp(): void
{
parent::setUp();
$this->shoppingCart = app(ShoppingCartInterface::class);
}
///////////////////////////////////////////////
// Tests without price modification
///////////////////////////////////////////////
/**
* Runs after each test
* @group ShoppingCart
*/
public function teardown(): void
{
parent::tearDown();
}
/**
* Test that the value is unique.
*
* @group OrderNumberTest
*/
public function testCheckingUniquenessInDatabase()
{
//Get the latest order number
$order = Order::latest()->first();
$latestOrderNumber = ($order) ? $order->order_number : 'O201700001';
//Create a basic sequence. Must match the OrderNumberSequence class since there may be order numbers.
$orderNumber = new OrderNumberSequence();
//Clone the sequence. After a next() call on ONE of them, they should not be equal.
$previousOrderNumber = clone $orderNumber;
$orderNumber->next();
$this->assertNotEquals((string) $orderNumber, (string) $previousOrderNumber);
//Create a unique order
/** @var Order $order */
$order = factory(Order::class)->make();
$order->order_number = $orderNumber;
$order->save();
//Reset the starting code to the previous one.
$orderNumber = clone $previousOrderNumber;
$this->assertEquals((string) $orderNumber, (string) $previousOrderNumber);
//Create an order with the same order_number as before. Should not be possible.
$order = factory(Order::class)->make();
$this->expectException(RuntimeException::class);
$order->order_number = $orderNumber->next(); //Increments the order number. And that is already is defined in the database. And therefore throws the RuntimeException
}
/**
* Test order number sequence
*
* @group OrderNumberTest
*/
public function testOrderNumberSequence()
{
//Make sure the orders table is empty. Only then we can test predictably
Order::all(['id'])->each(function(Order $order) { $order->delete(); });
$this->assertEquals(0, Order::count());
//Trick carbon into thinking it is one year back from now. E.g. time travel one year into the past.
$oneYearBack = Carbon::now()->subYear();
Carbon::setTestNow($oneYearBack);
//Create an order one year back
$latestOrderNumberOneYearBack = 'O'.Carbon::now()->year.'00000';
$orderNumberOneYearBack = (new OrderNumberSequence());
$this->assertEquals($latestOrderNumberOneYearBack, (string) $orderNumberOneYearBack);
$order = factory(Order::class)->make();
$order->order_number = $orderNumberOneYearBack;
$order->save();
//Check that it is as expected
$latestOrder = Order::latest('id')->first();
$this->assertNotNull($latestOrder);
$this->assertEquals($latestOrderNumberOneYearBack, $latestOrder->order_number);
//BACK TO THE FUTURE!!!!!!
// __---~~~~--__ __--~~~~---__
// `\---~~~~~~~~\\ //~~~~~~~~---/'
// \/~~~~~~~~~\|| ||/~~~~~~~~~\/
// `\\ //'
// `\\ //'
// || ||
// ______--~~~~~~~~~~~~~~~~~~--______
// ___ // _-~ ~-_ \\ ___
// `\__)\/~ ~\/(__/'
// _--`-___ ___-'--_
// /~ `\ ~~~~~~~~------------~~~~~~~~ /' ~\
// /| `\ /' |\
// | `\ ______`\_ DMC _/'______ /' |
// | `\_~-_____\ ~-________________-~ /_____-~_/' |
// `. ~-__________________________________-~ .'
// `. [_______/------|~~|------\_______] .'
// `\--___((____)(________\/________)(____))___--/'
// |>>>>>>|| ||<<<<<<|
// `\<<<<</' `\>>>>>/'
Carbon::setTestNow(); //<<<<Gets us back to the future. Acts as a flux capacitor
//Create an order with the date of now.
$latestOrderNumber = 'O'.Carbon::now()->year.'00000';
$orderNumber = (new OrderNumberSequence()); //In real live world situation a new request would create a new order number.
$this->assertEquals($latestOrderNumber, (string) $orderNumber);
$order = factory(Order::class)->make();
$order->order_number = $orderNumber;
$order->save();
//Check that it is as expected
$latestOrder = Order::latest('id')->first();
$this->assertNotNull($latestOrder);
$this->assertEquals($latestOrderNumber, $latestOrder->order_number);
//Check that the oldest order numbers year is 1 year back from the latest order numbers year.
$oldestOrder = Order::oldest('id')->first();
$newestOrder = Order::latest('id')->first();
$newestOrderYear = ((new OrderNumberSequence())->startingAt($newestOrder->order_number)->getPartByName('year')->getValue());
$oldestOrderYear = ((new OrderNumberSequence())->startingAt($oldestOrder->order_number)->getPartByName('year')->getValue());
$this->assertNotEquals($newestOrderYear, $oldestOrderYear);
$this->assertEquals($newestOrderYear - 1, $oldestOrderYear);
}
}