tddwizard / magento2-fixtures

Fixture library for Magento 2 integration tests by @schmengler (@integer-net)
http://tddwizard.com/
MIT License
141 stars 28 forks source link

Trying to update a bundle item -> Failing to save quote (Magento 2.2.1) #7

Open amenk opened 6 years ago

amenk commented 6 years ago

I am trying to write a test for a method which works when testing manually. Essentially I am updating the quantity of a bundle product.

I have the following test - with code from my own class ItemInfo inlined here for this issue:

protected function setUp()
{
    $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();

    $this->itemInfoFactory = $objectManager->create(\Proofgigant\Product\Model\ItemInfoFactory::class);
    $this->guestCartRepository = $objectManager->create(\Magento\Quote\Model\GuestCart\GuestCartRepository::class);

    // get them from debugging into \Proofgigant\Product\Model\ItemInfo::__construct, check buyRequest in itemOptions
    $this->options =
        array (
            'options' =>
                array (
                    19 => '53',
                    17 => 'test',
                ),
            'bundle_option' =>
                array (
                    9 => '44',
                ),
            'bundle_option_qty_pages' =>
                array (
                    9 => '1',
                ),
            'bundle_option_qty_copies' =>
                array (
                    9 => '1',
                ),
            'bundle_option_qty' =>
                array (
                    9 => '1',
                ),
        );

    $this->cartBuilder = CartBuilder::forCurrentSession();
}

public function testCanIncreaseNumberOfPages()
{
    $cart =  $this->cartBuilder->withProductRequest("proof", 1, $this->options)
        ->build();
    $cart->save();

    $quote = $cart->getCheckoutSession()->getQuote();
    $quoteItem = $quote->getItemsCollection()->getFirstItem();

    $this->assertEquals(6.0, $quote->getGrandTotal());

    /**
     * @var $itemInfo ItemInfo
     */
    $itemInfo = $this->itemInfoFactory->create(['quoteItem' => $quoteItem]);
    $this->assertEquals(1, $itemInfo->getNumberOfPages());

//       $itemInfo->updateNumberOfPages(2, $cart);
    $orderOptions = $quoteItem->getProduct()->getTypeInstance()->getOrderOptions($quoteItem->getProduct());

    $pages = 2;
    $qty = $pages * 1;
    $requestInfo = $orderOptions['info_buyRequest'];
    $requestInfo['bundle_option_qty_pages'][9] = $pages;
    $requestInfo['bundle_option_qty'][9] = $qty;

    $buyRequest = new \Magento\Framework\DataObject($requestInfo);

    $item = $cart->updateItem($quoteItem->getId(), $buyRequest);

    if (is_string($item)) {
        throw new \Magento\Framework\Exception\LocalizedException(__($item));
    }
    if ($item->getHasError()) {
        throw new \Magento\Framework\Exception\LocalizedException(__($item->getMessage()));
    }

    $cart->save();   ### Line 139 
// end updateNumberOfPages

    $quote = $cart->getQuote();
    $quoteItem = $quote->getItemsCollection()->getFirstItem();
    $itemInfo = $this->itemInfoFactory->create(['quoteItem' => $quoteItem]);
    $this->assertEquals(12.0, $quote->getGrandTotal());
    $this->assertEquals(2, $itemInfo->getNumberOfPages());
}

This fails as follows:

Could not save quote
 vendor/magento/module-quote/Model/Quote/Item/CartItemPersister.php:112
 vendor/magento/module-quote/Model/QuoteRepository/SaveHandler.php:82
 generated/code/Magento/Quote/Model/QuoteRepository/SaveHandler/Interceptor.php:24
 vendor/magento/module-quote/Model/QuoteRepository.php:181
 generated/code/Magento/Quote/Model/QuoteRepository/Interceptor.php:76
 vendor/magento/module-checkout/Model/Cart.php:574
 generated/code/Magento/Checkout/Model/Cart/Interceptor.php:180
 app/code/Example/Upload/Test/Integration/QuantityUpdateTest.php:139

When debugging into CartItemPersister, the problem seems to be, that my QuoteItem does not have a ID in the database.

Can this be solved on the side of the fixture module? Is it because I am using a guest cart?

schmengler commented 6 years ago

@amenk I am not sure to be honest. Assuming that the quote items have been saved correctly, It might help to reload the quote after the first $cart->save() so that the item collection contains all ids.