diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php b/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php index 9c2aeeec4abf5d2817df474c4a7c1cfbb818df6f..2b5bbc406d4690602acff51e79904a82aaad9151 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php @@ -5,6 +5,9 @@ */ namespace Magento\Eav\Model\Entity\Attribute\Source; +use Magento\Framework\App\ObjectManager; +use Magento\Store\Model\StoreManagerInterface; + class Table extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource { /** @@ -24,6 +27,11 @@ class Table extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource */ protected $_attrOptionFactory; + /** + * @var StoreManagerInterface + */ + private $storeManager; + /** * @param \Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\CollectionFactory $attrOptionCollectionFactory * @param \Magento\Eav\Model\ResourceModel\Entity\Attribute\OptionFactory $attrOptionFactory @@ -47,24 +55,30 @@ class Table extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource public function getAllOptions($withEmpty = true, $defaultValues = false) { $storeId = $this->getAttribute()->getStoreId(); + if ($storeId === null) { + $storeId = $this->getStoreManager()->getStore()->getId(); + } if (!is_array($this->_options)) { $this->_options = []; } if (!is_array($this->_optionsDefault)) { $this->_optionsDefault = []; } - if (!isset($this->_options[$storeId])) { + $attributeId = $this->getAttribute()->getId(); + if (!isset($this->_options[$storeId][$attributeId])) { $collection = $this->_attrOptionCollectionFactory->create()->setPositionOrder( 'asc' )->setAttributeFilter( - $this->getAttribute()->getId() + $attributeId )->setStoreFilter( - $this->getAttribute()->getStoreId() + $storeId )->load(); - $this->_options[$storeId] = $collection->toOptionArray(); - $this->_optionsDefault[$storeId] = $collection->toOptionArray('default_value'); + $this->_options[$storeId][$attributeId] = $collection->toOptionArray(); + $this->_optionsDefault[$storeId][$attributeId] = $collection->toOptionArray('default_value'); } - $options = $defaultValues ? $this->_optionsDefault[$storeId] : $this->_options[$storeId]; + $options = $defaultValues + ? $this->_optionsDefault[$storeId][$attributeId] + : $this->_options[$storeId][$attributeId]; if ($withEmpty) { $options = $this->addEmptyOption($options); } @@ -72,6 +86,20 @@ class Table extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource return $options; } + /** + * Get StoreManager dependency + * + * @return StoreManagerInterface + * @deprecated + */ + private function getStoreManager() + { + if ($this->storeManager === null) { + $this->storeManager = ObjectManager::getInstance()->get(StoreManagerInterface::class); + } + return $this->storeManager; + } + /** * Retrieve Option values array by ids * diff --git a/app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/Source/TableTest.php b/app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/Source/TableTest.php index fcae389b8e2e3d6d7e312055a305b4b615734c59..9b893bf9017681b584a611939f1332ee50fbc869 100644 --- a/app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/Source/TableTest.php +++ b/app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/Source/TableTest.php @@ -6,6 +6,11 @@ namespace Magento\Eav\Test\Unit\Model\Entity\Attribute\Source; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Eav\Model\Entity\Attribute\Source\AbstractSource; +use Magento\Eav\Model\Entity\Attribute\AbstractAttribute; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Store\Api\Data\StoreInterface; +use Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\Collection as AttributeOptionCollection; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -28,6 +33,31 @@ class TableTest extends \PHPUnit_Framework_TestCase */ private $attrOptionFactory; + /** + * @var AbstractSource | \PHPUnit_Framework_MockObject_MockObject + */ + private $sourceMock; + + /** + * @var AbstractAttribute | \PHPUnit_Framework_MockObject_MockObject + */ + private $abstractAttributeMock; + + /** + * @var StoreManagerInterface | \PHPUnit_Framework_MockObject_MockObject + */ + private $storeManagerMock; + + /** + * @var StoreInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $storeMock; + + /** + * @var AttributeOptionCollection|\PHPUnit_Framework_MockObject_MockObject + */ + private $attributeOptionCollectionMock; + protected function setUp() { $objectManager = new ObjectManager($this); @@ -48,6 +78,11 @@ class TableTest extends \PHPUnit_Framework_TestCase false ); + $this->attributeOptionCollectionMock = $this->getMockBuilder(AttributeOptionCollection::class) + ->setMethods(['toOptionArray']) + ->disableOriginalConstructor() + ->getMock(); + $this->attrOptionFactory = $this->getMockBuilder( \Magento\Eav\Model\ResourceModel\Entity\Attribute\OptionFactory::class ) @@ -55,6 +90,20 @@ class TableTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->getMockForAbstractClass(); + $this->sourceMock = $this->getMockBuilder(AbstractSource::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->abstractAttributeMock = $this->getMockBuilder(AbstractAttribute::class) + ->setMethods( + [ + 'getFrontend', 'getAttributeCode', '__wakeup', 'getStoreId', + 'getId', 'getIsRequired', 'getEntity', 'getBackend' + ] + ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->model = $objectManager->getObject( \Magento\Eav\Model\Entity\Attribute\Source\Table::class, [ @@ -62,6 +111,16 @@ class TableTest extends \PHPUnit_Framework_TestCase 'attrOptionFactory' => $this->attrOptionFactory ] ); + $this->model->setAttribute($this->abstractAttributeMock); + + $this->storeManagerMock = $this->getMockForAbstractClass(StoreManagerInterface::class); + $this->storeMock = $this->getMockForAbstractClass(StoreInterface::class); + + $objectManager->setBackwardCompatibleProperty( + $this->model, + 'storeManager', + $this->storeManagerMock + ); } public function testGetFlatColumns() @@ -74,25 +133,8 @@ class TableTest extends \PHPUnit_Framework_TestCase false ); - $abstractAttributeMock = $this->getMock( - \Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class, - ['getFrontend', 'getAttributeCode', '__wakeup'], - [], - '', - false - ); - - $abstractAttributeMock->expects( - $this->any() - )->method( - 'getFrontend' - )->will( - $this->returnValue($abstractFrontendMock) - ); - - $abstractAttributeMock->expects($this->any())->method('getAttributeCode')->will($this->returnValue('code')); - - $this->model->setAttribute($abstractAttributeMock); + $this->abstractAttributeMock->expects($this->any())->method('getFrontend')->willReturn(($abstractFrontendMock)); + $this->abstractAttributeMock->expects($this->any())->method('getAttributeCode')->willReturn('code'); $flatColumns = $this->model->getFlatColumns(); @@ -121,25 +163,16 @@ class TableTest extends \PHPUnit_Framework_TestCase $storeId = 5; $options = [['label' => 'The label', 'value' => 'A value']]; - $attribute = $this->getMock( - \Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class, - ['getId', 'getStoreId', 'getIsRequired', '__wakeup'], - [], - '', - false - ); - $attribute->expects($this->once()) + $this->abstractAttributeMock->expects($this->once()) ->method('getId') ->willReturn($attributeId); - $attribute->expects($this->once()) + $this->abstractAttributeMock->expects($this->once()) ->method('getStoreId') ->willReturn($storeId); - $attribute->expects($this->any()) + $this->abstractAttributeMock->expects($this->any()) ->method('getIsRequired') ->willReturn(false); - $this->model->setAttribute($attribute); - $this->collectionFactory->expects($this->once()) ->method('create') ->willReturnSelf(); @@ -191,22 +224,14 @@ class TableTest extends \PHPUnit_Framework_TestCase { $attributeId = 1; $storeId = 5; - $attribute = $this->getMock( - \Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class, - ['getId', 'getStoreId', '__wakeup'], - [], - '', - false - ); - $attribute->expects($this->once()) + + $this->abstractAttributeMock->expects($this->once()) ->method('getId') ->willReturn($attributeId); - $attribute->expects($this->once()) + $this->abstractAttributeMock->expects($this->once()) ->method('getStoreId') ->willReturn($storeId); - $this->model->setAttribute($attribute); - $this->collectionFactory->expects($this->once()) ->method('create') ->willReturnSelf(); @@ -257,16 +282,13 @@ class TableTest extends \PHPUnit_Framework_TestCase ->setMethods([ 'getSelect', 'getStoreId']) ->disableOriginalConstructor() ->getMockForAbstractClass(); - $attribute = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class) - ->setMethods(['getAttributeCode', 'getEntity', 'getBackend', 'getId']) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); - $attribute->expects($this->any())->method('getAttributeCode')->willReturn($attributeCode); + + $this->abstractAttributeMock->expects($this->any())->method('getAttributeCode')->willReturn($attributeCode); $entity = $this->getMockBuilder(\Magento\Eav\Model\Entity\AbstractEntity::class) ->setMethods(['getLinkField']) ->disableOriginalConstructor() ->getMockForAbstractClass(); - $attribute->expects($this->once())->method('getEntity')->willReturn($entity); + $this->abstractAttributeMock->expects($this->once())->method('getEntity')->willReturn($entity); $entity->expects($this->once())->method('getLinkField')->willReturn('entity_id'); $select = $this->getMockBuilder(\Magento\Framework\DB\Select::class) ->setMethods(['joinLeft', 'getConnection', 'order']) @@ -278,9 +300,9 @@ class TableTest extends \PHPUnit_Framework_TestCase ->setMethods(['getTable']) ->disableOriginalConstructor() ->getMockForAbstractClass(); - $attribute->expects($this->any())->method('getBackend')->willReturn($backend); + $this->abstractAttributeMock->expects($this->any())->method('getBackend')->willReturn($backend); $backend->expects($this->any())->method('getTable')->willReturn('table_name'); - $attribute->expects($this->any())->method('getId')->willReturn(1); + $this->abstractAttributeMock->expects($this->any())->method('getId')->willReturn(1); $collection->expects($this->once())->method('getStoreId')->willReturn(1); $connection = $this->getMockBuilder(\Magento\Framework\DB\Adapter\AdapterInterface::class) ->disableOriginalConstructor() @@ -294,11 +316,99 @@ class TableTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->getMock(); $this->attrOptionFactory->expects($this->once())->method('create')->willReturn($attrOption); - $attrOption->expects($this->once())->method('addOptionValueToCollection')->with($collection, $attribute, $expr) + $attrOption->expects($this->once())->method('addOptionValueToCollection') + ->with($collection, $this->abstractAttributeMock, $expr) ->willReturnSelf(); $select->expects($this->once())->method('order')->with("{$attributeCode} {$dir}"); - $this->model->setAttribute($attribute); $this->assertEquals($this->model, $this->model->addValueSortToCollection($collection, $dir)); } + + /** + * @param bool $withEmpty + * @param bool $defaultValues + * @param array $options + * @param array $optionsDefault + * @param array $expectedResult + * @dataProvider getAllOptionsDataProvider + */ + public function testGetAllOptions( + $withEmpty, + $defaultValues, + array $options, + array $optionsDefault, + array $expectedResult + ) { + $storeId = '1'; + $attributeId = '42'; + + $this->abstractAttributeMock->expects($this->once())->method('getStoreId')->willReturn(null); + + $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($this->storeMock); + $this->storeMock->expects($this->once())->method('getId')->willReturn($storeId); + + $this->abstractAttributeMock->expects($this->once())->method('getId')->willReturn($attributeId); + + $this->collectionFactory->expects($this->once()) + ->method('create') + ->willReturnSelf(); + $this->collectionFactory->expects($this->once()) + ->method('setPositionOrder') + ->willReturnSelf(); + $this->collectionFactory->expects($this->once()) + ->method('setAttributeFilter') + ->with($attributeId) + ->willReturnSelf(); + $this->collectionFactory->expects($this->once()) + ->method('setStoreFilter') + ->with($storeId) + ->willReturnSelf(); + $this->collectionFactory->expects($this->once()) + ->method('load') + ->willReturn($this->attributeOptionCollectionMock); + $this->attributeOptionCollectionMock->expects($this->any()) + ->method('toOptionArray') + ->willReturnMap( + [ + ['value', $options], + ['default_value', $optionsDefault] + ] + ); + + $this->assertEquals($expectedResult, $this->model->getAllOptions($withEmpty, $defaultValues)); + } + + /** + * @return array + */ + public function getAllOptionsDataProvider() + { + return [ + [ + false, + false, + [['value' => '16', 'label' => 'black'], ['value' => '17', 'label' => 'white']], + [['value' => '16', 'label' => 'blck'], ['value' => '17', 'label' => 'wht']], + [['value' => '16', 'label' => 'black'], ['value' => '17', 'label' => 'white']] + ], + [ + false, + true, + [['value' => '16', 'label' => 'black'], ['value' => '17', 'label' => 'white']], + [['value' => '16', 'label' => 'blck'], ['value' => '17', 'label' => 'wht']], + [['value' => '16', 'label' => 'blck'], ['value' => '17', 'label' => 'wht']] + ], + [ + true, + false, + [['value' => '16', 'label' => 'black'], ['value' => '17', 'label' => 'white']], + [['value' => '16', 'label' => 'blck'], ['value' => '17', 'label' => 'wht']], + [ + ['label' => ' ', 'value' => ''], + ['value' => '16', 'label' => 'black'], + ['value' => '17', 'label' => 'white'] + ] + ] + ]; + } }