tddwizard/magento2-fixtures

View on GitHub
src/Checkout/CartBuilder.php

Summary

Maintainability
A
0 mins
Test Coverage
<?php
declare(strict_types=1);

namespace TddWizard\Fixtures\Checkout;

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\Product;
use Magento\Checkout\Model\Cart;
use Magento\Framework\DataObject;
use Magento\Framework\Exception\LocalizedException;
use Magento\TestFramework\Helper\Bootstrap;

class CartBuilder
{
    /**
     * @var ProductRepositoryInterface
     */
    private $productRepository;

    /**
     * @var Cart
     */
    private $cart;

    /**
     * @var DataObject[][] Array in the form [sku => [buyRequest]] (multiple requests per sku are possible)
     */
    private $addToCartRequests;

    final public function __construct(ProductRepositoryInterface $productRepository, Cart $cart)
    {
        $this->productRepository = $productRepository;
        $this->cart = $cart;
        $this->addToCartRequests = [];
    }

    public static function forCurrentSession(): CartBuilder
    {
        $objectManager = Bootstrap::getObjectManager();
        return new static(
            $objectManager->create(ProductRepositoryInterface::class),
            $objectManager->create(Cart::class)
        );
    }

    public function withSimpleProduct(string $sku, float $qty = 1): CartBuilder
    {
        $result = clone $this;
        $result->addToCartRequests[$sku][] = new DataObject(['qty' => $qty]);
        return $result;
    }

    public function withReservedOrderId(string $orderId): CartBuilder
    {
        $result = clone $this;
        $result->cart->getQuote()->setReservedOrderId($orderId);
        return $result;
    }

    /**
     * Lower-level API to support arbitrary products
     *
     * @param string $sku
     * @param int $qty
     * @param mixed[] $request
     * @return CartBuilder
     */
    public function withProductRequest($sku, $qty = 1, $request = []): CartBuilder
    {
        $result = clone $this;
        $requestInfo = array_merge(['qty' => $qty], $request);
        $result->addToCartRequests[$sku][] = new DataObject($requestInfo);
        return $result;
    }

    /**
     * @return Cart
     * @throws LocalizedException
     */
    public function build(): Cart
    {
        foreach ($this->addToCartRequests as $sku => $requests) {
            /** @var Product $product */
            $product = $this->productRepository->get($sku);
            foreach ($requests as $requestInfo) {
                $this->cart->addProduct($product, $requestInfo);
            }
        }
        $this->cart->save();
        return $this->cart;
    }
}