HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
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);
    }
}