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/rentman2019.komma.pro/app/Komma/Shop/Tests/Unit/OrderTest.php
<?php

namespace App\Komma\Shop\Tests\Unit;

use App\Komma\Shop\Orders\Models\Order;
use App\Komma\Shop\Orders\Product\OrderedProduct;
use App\Komma\Shop\Orders\ProductComposite\OrderedProductComposite;
use App\Komma\Shop\Orders\ProductGroup\OrderedProductGroup;
use App\Komma\Shop\Products\Product\Product;
use App\Komma\Shop\Products\Product\ProductService;
use App\Komma\Shop\Products\ProductComposite\ProductComposite;
use App\Komma\Shop\Products\ProductComposite\ProductCompositeService;
use App\Komma\Shop\Products\ProductGroup\ProductGroup;
use App\Komma\Shop\Products\ProductGroup\ProductGroupService;
use App\Komma\Shop\Products\ProductGroupBehaviour\ProductGroupBehaviour;
use App\Komma\Shop\Tests\TestCase;
use App\Komma\Users\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Collection;

class OrderTest extends TestCase
{
    use DatabaseTransactions; //Automatically rolls back database actions after tests

    /**
     * This method is being run before each test
     */
    protected function setUp()
    {
        parent::setUp();
    }

    /**
     * Helper function
     */
    private function createEmptyOrderLinkedToRandomCustomer()
    {
        $user = User::inRandomOrder()->first();
        $order = new Order();
        $order->customer()->associate($user);
        $order->save();

        return $order;
    }

    /**
     * @group orderedProducts
     */
    public function testOrderedProductCreation()
    {
        $productService = new ProductService();

        $product = factory(Product::class)->create();
        $this->assertInstanceOf(Product::class, $product);
        /** @var Product $product */
        $this->assertDatabaseHas('products', [
            'price' => $product->price,
            'stock_keeping_unit' => $product->stock_keeping_unit,
        ]);

        $order = $this->createEmptyOrderLinkedToRandomCustomer();

        /** @var OrderedProduct $orderedProduct */
        $orderedProduct = $productService->createOrderedProductFromProduct($product, $order);
        $this->assertInstanceOf(OrderedProduct::class, $orderedProduct);

        $this->assertEquals($product->price, $orderedProduct->price);
        $this->assertEquals($product->stock_keeping_unit, $orderedProduct->stock_keeping_unit);
    }

    /**
     * @group orderedProducts
     */
    public function testOrderedGroupCreation()
    {
        $productService = new ProductGroupService();

        $group = factory(ProductGroup::class)->make();
        $behaviour = factory(ProductGroupBehaviour::class)->create();

        $this->assertInstanceOf(ProductGroup::class, $group);
        $this->assertInstanceOf(ProductGroupBehaviour::class, $behaviour);
        /** @var ProductGroup $group */
        /** @var ProductGroupBehaviour $behaviour */
        $group->productGroupBehaviour()->associate($behaviour);
        $group->save();

        $this->assertDatabaseHas('product_groups', [
            'id' => $group->id,
            'active' => $group->active,
        ]);

        $order = $this->createEmptyOrderLinkedToRandomCustomer();

        /** @var OrderedProductGroup $orderedProductGroup */
        $orderedProductGroup = $productService->createOrderedProductGroupFromProductGroup($group, $order);

        $this->assertInstanceOf(OrderedProductGroup::class, $orderedProductGroup);

        $this->assertEquals($group->active, $orderedProductGroup->active);
    }

    /**
     * @group orderedProducts
     */
    public function testOrderedCompositeCreation()
    {
        $productCompositeService = new ProductCompositeService();

        $productComposite = factory(ProductComposite::class)->make();
        $productGroup = factory(ProductGroup::class)->make();
        $behaviour = factory(ProductGroupBehaviour::class)->create();

        $this->assertInstanceOf(ProductGroup::class, $productGroup);
        $this->assertInstanceOf(ProductGroupBehaviour::class, $behaviour);
        $this->assertInstanceOf(ProductComposite::class, $productComposite);
        /** @var ProductGroup $productGroup */
        /** @var ProductGroupBehaviour $behaviour */
        /** @var ProductComposite $productComposite */
        $productGroup->productGroupBehaviour()->associate($behaviour);
        $productGroup->save();

        $productComposite->save();
        $productComposite->groups()->attach($productGroup);
        $productComposite->save();

        $this->assertDatabaseHas('product_composites', [
            'active' => $productComposite->active,
        ]);

        $order = $this->createEmptyOrderLinkedToRandomCustomer();

        /** @var OrderedProduct $orderedComposite */
        $orderedComposite = $productCompositeService->createOrderedProductCompositeProductComposite($productComposite, $order);

        $this->assertInstanceOf(OrderedProductComposite::class, $orderedComposite);

        $this->assertEquals($productComposite->name, $orderedComposite->name);
        $this->assertEquals($productComposite->active, $orderedComposite->active);
    }

    /**
     * @group orderedProducts
     */
    public function testOrderedProductHistory()
    {
        $productService = new ProductService();

        $product = factory(Product::class)->create();

        $order = $this->createEmptyOrderLinkedToRandomCustomer();

        /** @var OrderedProduct $orderedProduct */
        $orderedProduct = $productService->createOrderedProductFromProduct($product, $order);
        $this->assertInstanceOf(OrderedProduct::class, $orderedProduct);

        $originalPrice = $product->price;
        $newPrice = $originalPrice + 10000;

        $product->price = $newPrice;
        $product->save();

        $this->assertNotEquals($product->price, $orderedProduct->price);
        $this->assertEquals($product->price, $newPrice);
        $this->assertEquals($orderedProduct->price, $originalPrice);
    }

    /**
     * @group orderedProducts
     */
    public function testOrderedGroupHistory()
    {
        $productGroupService = new ProductGroupService();

        $productsCount = 3;

        /** @var Collection $products */
        $products = factory(Product::class, $productsCount)->create();
        $products = $products->keyBy('id'); //Now we can use ->get(12) on the products collection to get the product with id 12
        $group = factory(ProductGroup::class)->make(); /** @var ProductGroup $group */
        $behaviour = factory(ProductGroupBehaviour::class)->create();

        $group->productGroupBehaviour()->associate($behaviour);
        $group->save();
        $group->products()->saveMany($products);

        $order = $this->createEmptyOrderLinkedToRandomCustomer();

        /** @var OrderedProductGroup $orderedProductGroup */
        $orderedProductGroup = $productGroupService->createOrderedProductGroupFromProductGroup($group, $order);

//        echo PHP_EOL.'Testing ordered product group history:';
//        echo PHP_EOL.'Original product prices:';
//        $products->each(function(Product $product) {
//            echo PHP_EOL.$product->id.' => '.$product->price;
//        });
//
//        echo PHP_EOL.'Ordered product prices';
//        $orderedProductGroup->orderedProducts()->get()->each(function(OrderedProduct $orderedProduct) {
//            echo PHP_EOL.$orderedProduct->id.' => '.$orderedProduct->price.' (Original product price: '.$orderedProduct->product()->first()->price.')';
//        });

        //Edit the products prices. The ordered products still have the same price after the loop
        $add = 1000;
        $products->each(function (Product $product) use ($add) {
            $product->price += $add;
            $product->save();
        });

//        echo PHP_EOL.'Modified product prices';
//        $products->each(function(Product $product) {
//            echo PHP_EOL.$product->id.' => '.$product->price;
//        });

        $orderedProductGroupOriginalProducts = $orderedProductGroup->products()->get();
        $this->assertEquals($productsCount, $orderedProductGroupOriginalProducts->count());

        $orderedProductGroupOriginalProducts->each(function (Product $product) use ($products) {
            $originalProduct = $products->get($product->id);
            $this->assertNotNull($originalProduct); //Checks that ordered products original products id's are in the products collection we started with
        });

        $orderedProductGroup->orderedProducts()->get()->each(function (OrderedProduct $orderedProduct) use ($products, $add) {
            $originalProduct = $orderedProduct->product()->first();
            $this->assertNotNull($originalProduct);

            $this->assertNotEquals($orderedProduct->price, $originalProduct->price);
            $this->assertEquals($orderedProduct->price, $originalProduct->price - $add);
        });
    }

    /**
     * @group orderedProducts
     */
    public function testOrderedCompositeHistory()
    {
        $productCompositeService = new ProductCompositeService();

        $productsCount = 3;

        /** @var Collection $products */
        $products = factory(Product::class, $productsCount)->create();
        $products = $products->keyBy('id'); //Now we can use ->get(12) on the products collection to get the product with id 12
        $group = factory(ProductGroup::class)->make(); /** @var ProductGroup $group */
        $behaviour = factory(ProductGroupBehaviour::class)->create();

        $group->productGroupBehaviour()->associate($behaviour);
        $group->save();
        $group->products()->saveMany($products);

        /** @var ProductComposite $composite */
        $composite = factory(ProductComposite::class)->create();
        $composite->groups()->save($group);

        $order = $this->createEmptyOrderLinkedToRandomCustomer();

        /** @var OrderedProductComposite $orderedComposite */
        $orderedComposite = $productCompositeService->createOrderedProductCompositeProductComposite($composite, $order);

        //Edit the products prices. The ordered products still have the same price after the loop
        $add = 1000;
        $products->each(function (Product $product) use ($add) {
            $product->price += $add;
            $product->save();
        });

        /** @var ProductGroup|null $orderedProductCompositeOriginalGroup */
        $orderedProductCompositeOriginalGroup = $orderedComposite->groups()->first();
        $orderedProductCompositeOriginalProducts = $orderedProductCompositeOriginalGroup->products()->get();
        $this->assertEquals($productsCount, $orderedProductCompositeOriginalProducts->count());

        $orderedProductCompositeOriginalProducts->each(function (Product $product) use ($products) {
            $originalProduct = $products->get($product->id);
            $this->assertNotNull($originalProduct); //Checks that ordered products original products id's are in the products collection we started with
        });

        /** @var OrderedProductGroup|null $orderedGroup */
        $orderedGroup = $orderedComposite->orderedGroups()->first();
        $this->assertNotNull($orderedGroup);

        $orderedGroup->orderedProducts()->get()->each(function (OrderedProduct $orderedProduct) use ($products, $add) {
            $originalProduct = $orderedProduct->product()->first();
            $this->assertNotNull($originalProduct);

            $this->assertNotEquals($orderedProduct->price, $originalProduct->price);
            $this->assertEquals($orderedProduct->price, $originalProduct->price + $add);
        });
    }
}