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/farmfun/reserveren.farmfun.be/app/Komma/Shop/Tests/Unit/InvoiceServiceTest.php
<?php

namespace App\Komma\Shop\Tests\Unit;

use App\Komma\Addresses\Models\Address;
use App\Komma\Shop\Cart\ShoppingCartServiceInterface;
use App\Komma\Shop\Checkout\CheckoutService;
use App\Komma\Shop\Checkout\CheckoutServiceInterface;
use App\Komma\Shop\Invoicing\InvoiceService;
use App\Komma\Shop\Orders\Models\Order;
use App\Komma\Shop\Products\Product\Product;
use App\Komma\Shop\Tests\TestCase;
use App\Komma\Sites\SiteServiceInterface;
use App\Komma\Users\Models\SiteUser;
use Illuminate\Contracts\Filesystem\Filesystem;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpFoundation\BinaryFileResponse;

class InvoiceServiceTest extends TestCase
{
    /** @var InvoiceService */
    private $invoiceService;

    /** @var ShoppingCartServiceInterface */
    private $shoppingCart;

    /** @var CheckoutService */
    private $checkoutService;

    /** @var Filesystem The root directory from the Storage disk that the invoice service uses */
    private $invoiceDisk;

    /**
     * Runs before each test
     */
    public function setup(): void
    {
        parent::setup();

        /** @var SiteServiceInterface $invoiceService */
        $this->invoiceService = app(InvoiceService::class);
        $this->shoppingCart = app(ShoppingCartServiceInterface::class);
        $this->checkoutService = app(CheckoutServiceInterface::class);
        $this->invoiceDisk = Storage::disk('local');
    }

    /**
     * Test if an invoice will be created as pdf for an order
     *
     * @group InvoiceService
     * @test
     * @throws \Throwable
     */
    public function testInvoiceCreation()
    {
        $order = $this->createOrder();

        $invoicePDFPathFromOrder = $this->invoiceService->getPDFPathFromOrder($order);
        $this->assertFalse($this->invoiceDisk->exists($invoicePDFPathFromOrder));

        $binaryFileResponse = $this->invoiceService->getForOrderAsPDF($order); //Also generates a cached version on the filesystem
        $this->assertTrue($this->invoiceDisk->exists($invoicePDFPathFromOrder));
        $this->assertInstanceOf(BinaryFileResponse::class, $binaryFileResponse);
    }

    /**
     * Test if an invoice will be created as pdf for an order.
     * And test that it will be re-generated when it is updated.
     *
     * @group InvoiceService
     * @test
     * @throws \Throwable
     */
    public function testInvoiceCreationAndUpdateInvoice()
    {
        $order = $this->createOrder();

        //Generate the order for the first time.
        $invoicePDFPathFromOrder = $this->invoiceService->getPDFPathFromOrder($order);
        $this->assertFalse($this->invoiceDisk->exists($invoicePDFPathFromOrder));
        $binaryFileResponse = $this->invoiceService->getForOrderAsPDF($order); //Also generates a cached version on the filesystem
        $this->assertTrue($this->invoiceDisk->exists($invoicePDFPathFromOrder));
        $this->assertInstanceOf(BinaryFileResponse::class, $binaryFileResponse);
        $unixTimetampFirstGet = Storage::lastModified($invoicePDFPathFromOrder);
//        echo 'Old pdf invoice path: '.$invoicePDFPathFromOrder.PHP_EOL;

        //Get it a second time. It should not generate it again. This can be seen by comparing last modified timestamps. They should be the same.
        $binaryFileResponse = $this->invoiceService->getForOrderAsPDF($order); //Should not generate the cached version again. But just retrieved the cached one.
        $unixTimestampSecondGet = $this->invoiceDisk->lastModified($invoicePDFPathFromOrder);
        $this->assertEquals($unixTimetampFirstGet, $unixTimestampSecondGet);

        //Update the order (by touching it). When we get the pdf, it should be regenerated and have a different timestamp and path then before. And the old invoice should not exist anymore.
        $previousTimestamp = $unixTimestampSecondGet;
        $previousInvoicePDFPathFromOrder = $invoicePDFPathFromOrder;
        sleep(1); //We need to do this to make sure when we touch it, the invoice does have a new timestamp. IRL invoices are not re-generated after a second. Should take much longer ofcourse.
        $order->touch();
        $invoicePDFPathFromOrder = $this->invoiceService->getPDFPathFromOrder($order);
//        echo 'New pdf invoice path: '.$invoicePDFPathFromOrder.PHP_EOL;
        $this->assertNotEquals($invoicePDFPathFromOrder, $previousInvoicePDFPathFromOrder);
        $this->assertFalse($this->invoiceDisk->exists($invoicePDFPathFromOrder));
        $binaryFileResponse = $this->invoiceService->getForOrderAsPDF($order); //Generates the pdf and creates a new cached version on the filesystem.
        $this->assertTrue($this->invoiceDisk->exists($invoicePDFPathFromOrder));
        $this->assertInstanceOf(BinaryFileResponse::class, $binaryFileResponse);
        $this->assertFalse($this->invoiceDisk->exists($previousInvoicePDFPathFromOrder));
    }

    /**
     * @return Order
     * @throws \Throwable
     */
    public function createOrder(): Order
    {
        //Get a random customer user to test with
        /** @var SiteUser $customer */
        $customer = factory(SiteUser::class)->create();
        //Give it an address
        /** @var Address $address */
        $address = factory(Address::class)->create();
        $customer->addresses()->save($address);

        //Put some random products in the shopping cart
        /** @var Product $product */
        $product = Product::inRandomOrder()->first();

        $this->shoppingCart->addProductable($product, 2);

        return $this->checkoutService->createOrder($this->shoppingCart, $customer, $customer->addresses()->first(), $customer->addresses()->first());
    }
}