123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- /**
- * As far none class is present as separate bundle product,
- * this test is clone of \Magento\Catalog\Model\Product with product type "bundle"
- */
- namespace Magento\Bundle\Model;
- use Magento\Bundle\Model\Product\Price;
- use Magento\Bundle\Model\Product\Type as BundleType;
- use Magento\Catalog\Api\ProductRepositoryInterface;
- use Magento\Catalog\Model\Product;
- use Magento\Catalog\Model\Product\Attribute\Source\Status;
- use Magento\Catalog\Model\Product\Type;
- use Magento\Catalog\Model\Product\Visibility;
- use Magento\CatalogInventory\Model\Stock;
- use Magento\Framework\ObjectManagerInterface;
- use Magento\Store\Api\StoreRepositoryInterface;
- use Magento\Store\Model\StoreManagerInterface;
- use Magento\TestFramework\Entity;
- use Magento\TestFramework\Helper\Bootstrap;
- /**
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
- class ProductTest extends \PHPUnit\Framework\TestCase
- {
- /**
- * @var Product
- */
- private $model;
- /**
- * @var ObjectManagerInterface
- */
- private $objectManager;
- /**
- * @return void
- */
- protected function setUp()
- {
- $this->objectManager = Bootstrap::getObjectManager();
- $this->model = $this->objectManager->create(Product::class);
- $this->model->setTypeId(Type::TYPE_BUNDLE);
- }
- /**
- * Tests Retrieve ans set type instance of the product
- *
- * @see \Magento\Catalog\Model\Product::getTypeInstance
- * @see \Magento\Catalog\Model\Product::setTypeInstance
- * @return void
- */
- public function testGetSetTypeInstance()
- {
- // model getter
- $typeInstance = $this->model->getTypeInstance();
- $this->assertInstanceOf(BundleType::class, $typeInstance);
- $this->assertSame($typeInstance, $this->model->getTypeInstance());
- // singleton getter
- $otherProduct = $this->objectManager->create(Product::class);
- $otherProduct->setTypeId(Type::TYPE_BUNDLE);
- $this->assertSame($typeInstance, $otherProduct->getTypeInstance());
- // model setter
- $customTypeInstance = $this->objectManager->create(BundleType::class);
- $this->model->setTypeInstance($customTypeInstance);
- $this->assertSame($customTypeInstance, $this->model->getTypeInstance());
- }
- /**
- * @magentoDbIsolation enabled
- * @magentoAppIsolation enabled
- * @magentoAppArea adminhtml
- */
- public function testCRUD()
- {
- $this->model->setTypeId(Type::TYPE_BUNDLE)
- ->setAttributeSetId(4)
- ->setName('Bundle Product')
- ->setSku(uniqid())
- ->setPrice(10)
- ->setMetaTitle('meta title')
- ->setMetaKeyword('meta keyword')
- ->setMetaDescription('meta description')
- ->setVisibility(Visibility::VISIBILITY_BOTH)
- ->setStatus(Status::STATUS_ENABLED);
- $crud = new Entity($this->model, ['sku' => uniqid()]);
- $crud->testCrud();
- }
- /**
- * Tests Get product price model
- *
- * @see \Magento\Catalog\Model\Product::getPriceModel
- * @return void
- */
- public function testGetPriceModel()
- {
- $this->model->setTypeId(Type::TYPE_BUNDLE);
- $type = $this->model->getPriceModel();
- $this->assertInstanceOf(Price::class, $type);
- $this->assertSame($type, $this->model->getPriceModel());
- }
- /**
- * Tests Check is product composite
- *
- * @see \Magento\Catalog\Model\Product::isComposite
- * @return void
- */
- public function testIsComposite()
- {
- $this->assertTrue($this->model->isComposite());
- }
- /**
- * Checks a case when bundle product is should be available per multiple stores.
- *
- * @magentoDataFixture Magento/Bundle/_files/product_with_multiple_options.php
- * @magentoDataFixture Magento/Store/_files/second_website_with_two_stores.php
- * @magentoDbIsolation disabled
- */
- public function testMultipleStores()
- {
- /** @var ProductRepositoryInterface $productRepository */
- $productRepository = $this->objectManager->get(ProductRepositoryInterface::class);
- $bundle = $productRepository->get('bundle-product');
- /** @var StoreRepositoryInterface $storeRepository */
- $storeRepository = $this->objectManager->get(StoreRepositoryInterface::class);
- $store = $storeRepository->get('fixture_second_store');
- self::assertNotEquals($store->getId(), $bundle->getStoreId());
- /** @var StoreManagerInterface $storeManager */
- $storeManager = $this->objectManager->get(StoreManagerInterface::class);
- $storeManager->setCurrentStore($store->getId());
- $bundle->setStoreId($store->getId())
- ->setCopyFromView(true);
- $updatedBundle = $productRepository->save($bundle);
- self::assertEquals($store->getId(), $updatedBundle->getStoreId());
- }
- /**
- * @param float $selectionQty
- * @param float $qty
- * @param int $isInStock
- * @param bool $manageStock
- * @param int $backorders
- * @param bool $isSalable
- * @magentoAppIsolation enabled
- * @magentoDataFixture Magento/Bundle/_files/product.php
- * @dataProvider stockConfigDataProvider
- * @covers \Magento\Catalog\Model\Product::isSalable
- */
- public function testIsSalable(
- float $selectionQty,
- float $qty,
- int $isInStock,
- bool $manageStock,
- int $backorders,
- bool $isSalable
- ) {
- $productRepository = $this->objectManager->get(ProductRepositoryInterface::class);
- $child = $productRepository->get('simple');
- $childStockItem = $child->getExtensionAttributes()->getStockItem();
- $childStockItem->setQty($qty);
- $childStockItem->setIsInStock($isInStock);
- $childStockItem->setUseConfigManageStock(false);
- $childStockItem->setManageStock($manageStock);
- $childStockItem->setUseConfigBackorders(false);
- $childStockItem->setBackorders($backorders);
- $productRepository->save($child);
- /** @var \Magento\Catalog\Model\Product $bundle */
- $bundle = $productRepository->get('bundle-product');
- foreach ($bundle->getExtensionAttributes()->getBundleProductOptions() as $productOption) {
- foreach ($productOption->getProductLinks() as $productLink) {
- $productLink->setCanChangeQuantity(0);
- $productLink->setQty($selectionQty);
- }
- }
- $productRepository->save($bundle);
- $this->assertEquals($isSalable, $bundle->isSalable());
- }
- /**
- * @return array
- */
- public function stockConfigDataProvider(): array
- {
- $qtyVars = [0, 10];
- $isInStockVars = [
- Stock::STOCK_OUT_OF_STOCK,
- Stock::STOCK_IN_STOCK,
- ];
- $manageStockVars = [false, true];
- $backordersVars = [
- Stock::BACKORDERS_NO,
- Stock::BACKORDERS_YES_NONOTIFY,
- Stock::BACKORDERS_YES_NOTIFY,
- ];
- $selectionQtyVars = [5, 10, 15];
- $variations = [];
- foreach ($qtyVars as $qty) {
- foreach ($isInStockVars as $isInStock) {
- foreach ($manageStockVars as $manageStock) {
- foreach ($backordersVars as $backorders) {
- foreach ($selectionQtyVars as $selectionQty) {
- $variationName = "selectionQty: {$selectionQty}"
- . " qty: {$qty}"
- . " isInStock: {$isInStock}"
- . " manageStock: {$manageStock}"
- . " backorders: {$backorders}";
- $isSalable = $this->checkIsSalable(
- $selectionQty,
- $qty,
- $isInStock,
- $manageStock,
- $backorders
- );
- $variations[$variationName] = [
- $selectionQty,
- $qty,
- $isInStock,
- $manageStock,
- $backorders,
- $isSalable
- ];
- }
- }
- }
- }
- }
- return $variations;
- }
- /**
- * @param float $selectionQty
- * @param float $qty
- * @param int $isInStock
- * @param bool $manageStock
- * @param int $backorders
- * @return bool
- * @see \Magento\Bundle\Model\ResourceModel\Selection\Collection::addQuantityFilter
- */
- private function checkIsSalable(
- float $selectionQty,
- float $qty,
- int $isInStock,
- bool $manageStock,
- int $backorders
- ): bool {
- return !$manageStock || ($isInStock && ($backorders || $selectionQty <= $qty));
- }
- }
|