<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\Eav\Test\Unit\Model;
use Magento\Eav\Model\Cache\Type as Cache;
use Magento\Eav\Model\Config;
use Magento\Eav\Model\Entity\Attribute;
use Magento\Eav\Model\Entity\Type;
use Magento\Eav\Model\Entity\TypeFactory;
use Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection;
use Magento\Eav\Model\ResourceModel\Entity\Type\CollectionFactory;
use Magento\Framework\App\Cache\StateInterface;
use Magento\Framework\App\CacheInterface;
use Magento\Framework\DataObject;
use Magento\Framework\Serialize\SerializerInterface;
use Magento\Framework\Validator\UniversalFactory;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class ConfigTest extends TestCase
{
/**
* @var Config
*/
protected $config;
/**
* @var CacheInterface|MockObject
*/
protected $cacheMock;
/**
* @var TypeFactory|MockObject
*/
protected $typeFactoryMock;
/**
* @var CollectionFactory|MockObject
*/
protected $collectionFactoryMock;
/**
* @var StateInterface|MockObject
*/
protected $cacheStateMock;
/**
* @var UniversalFactory|MockObject
*/
protected $universalFactoryMock;
/**
* @var SerializerInterface|MockObject
*/
private $serializerMock;
/**
* @var Type|MockObject
*/
private $typeMock;
protected function setUp(): void
{
$this->cacheMock = $this->getMockForAbstractClass(CacheInterface::class);
$this->typeFactoryMock = $this->getMockBuilder(TypeFactory::class)
->setMethods(['create'])
->disableOriginalConstructor()
->getMock();
$this->collectionFactoryMock =
$this->getMockBuilder(CollectionFactory::class)
->setMethods(['create'])
->disableOriginalConstructor()
->getMock();
$this->cacheStateMock = $this->getMockForAbstractClass(StateInterface::class);
$this->universalFactoryMock = $this->getMockBuilder(UniversalFactory::class)
->setMethods(['create'])
->disableOriginalConstructor()
->getMock();
$this->serializerMock = $this->getMockForAbstractClass(SerializerInterface::class);
$this->typeMock = $this->createMock(Type::class);
$this->config = new Config(
$this->cacheMock,
$this->typeFactoryMock,
$this->collectionFactoryMock,
$this->cacheStateMock,
$this->universalFactoryMock,
$this->serializerMock
);
}
public function testGetAttributeCache()
{
$attributeData = [
'attribute_code' => 'attribute_code_1',
'attribute_id' => 1
];
$attributeCollectionMock = $this->getMockBuilder(
Collection::class
)->disableOriginalConstructor()
->setMethods(['getData', 'setEntityTypeFilter'])
->getMock();
$attributeCollectionMock->expects($this->any())
->method('setEntityTypeFilter')->willReturnSelf();
$attributeCollectionMock->expects($this->any())
->method('getData')
->willReturn([$attributeData]);
$entityAttributeMock = $this->getMockBuilder(Attribute::class)
->setMethods(['setData', 'loadByCode', 'toArray'])
->disableOriginalConstructor()
->getMock();
$entityAttributeMock->expects($this->atLeastOnce())->method('setData')
->willReturnSelf();
$entityAttributeMock->expects($this->atLeastOnce())->method('loadByCode')
->willReturnSelf();
$factoryCalls = [
[
Collection::class,
[],
$attributeCollectionMock
],
[
Attribute::class,
[],
$entityAttributeMock
],
];
$entityTypeData = [
'entity_type_id' => 'entity_type_id',
'entity_type_code' => 'entity_type_code'
];
$collectionStub = new DataObject([$entityTypeData]);
$this->collectionFactoryMock
->expects($this->any())
->method('create')
->willReturn($collectionStub);
$entityType = $this->getMockBuilder(Type::class)
->setMethods(['getEntity', 'setData', 'getData', 'getEntityTypeCode', 'getId'])
->disableOriginalConstructor()
->getMock();
$entityType->method('getEntityTypeCode')
->willReturn('entity_type_code');
$entityType->method('getId')
->willReturn(101);
$this->typeFactoryMock
->expects($this->any())
->method('create')
->willReturn($entityType);
$this->universalFactoryMock
->expects($this->atLeastOnce())
->method('create')
->willReturnMap($factoryCalls);
$this->assertInstanceOf(Attribute::class, $this->config->getAttribute($entityType, 'attribute_code_1'));
}
/**
* @return array
*/
public function getAttributeCacheDataProvider()
{
return [
'cache-disabled' => [
false,
0,
0,
false,
],
'cache-miss' => [
true,
1,
0,
false,
],
'cached' => [
true,
1,
1,
'attribute serialzied data',
],
];
}
/**
* @param boolean $cacheEnabled
* @param int $loadCalls
* @param int $cachedValue
* @param int $unserializeCalls
* @dataProvider getAttributeCacheDataProvider
* @return void
*/
public function testGetAttributes($cacheEnabled)
{
$attributeData = [
'attribute_code' => 'attribute_code_1',
'attribute_id' => 1
];
$attributeCollectionMock = $this->getMockBuilder(
Collection::class
)->disableOriginalConstructor()
->setMethods(['getData', 'setEntityTypeFilter'])
->getMock();
$attributeCollectionMock
->expects($this->any())
->method('setEntityTypeFilter')->willReturnSelf();
$attributeCollectionMock
->expects($this->any())
->method('getData')
->willReturn([$attributeData]);
$entityAttributeMock = $this->getMockBuilder(Attribute::class)
->setMethods(['setData', 'setOrigData', 'load', 'toArray'])
->disableOriginalConstructor()
->getMock();
$entityAttributeMock->method('setData')
->willReturnSelf();
$entityAttributeMock->method('setOrigData')
->willReturn($attributeData);
$entityAttributeMock->method('load')
->willReturnSelf();
$entityAttributeMock->method('toArray')
->willReturn($attributeData);
$factoryCalls = [
[
Collection::class,
[],
$attributeCollectionMock
],
[
Attribute::class,
[],
$entityAttributeMock
],
];
$this->cacheStateMock
->expects($this->atLeastOnce())
->method('isEnabled')
->with(Cache::TYPE_IDENTIFIER)
->willReturn($cacheEnabled);
$entityTypeData = [
'entity_type_id' => 'entity_type_id',
'entity_type_code' => 'entity_type_code'
];
$collectionStub = new DataObject([$entityTypeData]);
$this->collectionFactoryMock
->expects($this->any())
->method('create')
->willReturn($collectionStub);
$entityType = $this->getMockBuilder(Type::class)
->setMethods(['getEntity', 'setData', 'getData', 'getEntityTypeCode', 'getId'])
->disableOriginalConstructor()
->getMock();
$entityType->method('getEntityTypeCode')
->willReturn('entity_type_code');
$entityType->method('getId')
->willReturn(101);
$this->typeFactoryMock
->expects($this->any())
->method('create')
->willReturn($entityType);
$this->universalFactoryMock
->expects($this->atLeastOnce())
->method('create')
->willReturnMap($factoryCalls);
$this->assertEquals(['attribute_code_1' => $entityAttributeMock], $this->config->getAttributes($entityType));
}
public function testClear()
{
$this->cacheMock->expects($this->once())
->method('clean')
->with(
[
Cache::CACHE_TAG,
Attribute::CACHE_TAG,
]
);
$this->config->clear();
}
public function testGetEntityTypeInstanceOfTypePassed()
{
$this->assertEquals(
$this->typeMock,
$this->config->getEntityType($this->typeMock)
);
}
public function testGetEntityTypeCacheExists()
{
$entityTypeCode = 'catalog_product';
$data = [
$entityTypeCode => [
'entity_type_id' => 1
]
];
$serializedData = 'serialized data';
$this->cacheStateMock->expects($this->once())
->method('isEnabled')
->with(Cache::TYPE_IDENTIFIER)
->willReturn(true);
$this->cacheMock->expects($this->once())
->method('load')
->with(Config::ENTITIES_CACHE_ID)
->willReturn($serializedData);
$this->serializerMock->expects($this->once())
->method('unserialize')
->with($serializedData)
->willReturn($data);
$this->typeMock->expects($this->exactly(2))
->method('getId')
->willReturn($data[$entityTypeCode]['entity_type_id']);
$this->typeMock->expects($this->once())
->method('getEntityTypeCode')
->willReturn($entityTypeCode);
$this->typeFactoryMock->expects($this->once())
->method('create')
->with(['data' => $data[$entityTypeCode]])
->willReturn($this->typeMock);
$this->assertInstanceOf(
Type::class,
$this->config->getEntityType($entityTypeCode)
);
}
public function testGetEntityTypeCacheDoesNotExist()
{
$entityTypeCode = 'catalog_product';
$collectionData = [
[
'entity_type_id' => 1,
'entity_type_code' => $entityTypeCode
]
];
$data = [
$entityTypeCode => [
'entity_type_id' => 1,
'entity_type_code' => $entityTypeCode,
'attribute_model' => Attribute::class
]
];
$serializedData = 'serialized data';
$this->cacheStateMock->expects($this->once())
->method('isEnabled')
->with(Cache::TYPE_IDENTIFIER)
->willReturn(true);
$this->cacheMock->expects($this->once())
->method('load')
->with(Config::ENTITIES_CACHE_ID)
->willReturn(false);
$this->serializerMock->expects($this->never())
->method('unserialize');
$attributeCollectionMock = $this->createMock(Collection::class);
$this->collectionFactoryMock->expects($this->once())
->method('create')
->willReturn($attributeCollectionMock);
$attributeCollectionMock->expects($this->once())
->method('getData')
->willReturn($collectionData);
$this->serializerMock->expects($this->once())
->method('serialize')
->with($data)
->willReturn($serializedData);
$this->cacheMock->expects($this->once())
->method('save')
->with(
$serializedData,
Config::ENTITIES_CACHE_ID,
[
Cache::CACHE_TAG,
Attribute::CACHE_TAG
]
);
$this->typeMock->expects($this->exactly(2))
->method('getId')
->willReturn($data[$entityTypeCode]['entity_type_id']);
$this->typeMock->expects($this->once())
->method('getEntityTypeCode')
->willReturn($entityTypeCode);
$this->typeFactoryMock->expects($this->once())
->method('create')
->with(['data' => $data[$entityTypeCode]])
->willReturn($this->typeMock);
$this->assertInstanceOf(
Type::class,
$this->config->getEntityType($entityTypeCode)
);
}
}
|