Skip to content

Commit 10c653f

Browse files
committed
Preparations for 1.0.0
- Modify customer group provider to use proxy in DI instead of class declaration - Add test cases for product wrapper - Fix wrong factory used for product collection
1 parent 28e5bff commit 10c653f

10 files changed

+212
-14
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
vendor/
22
composer.lock
33
.idea
4+
.phpunit.result.cache

composer.json

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
},
1313
"require-dev": {
1414
"phpstan/phpstan": "^0.12.86",
15-
"squizlabs/php_codesniffer": "^3.6.0"
15+
"squizlabs/php_codesniffer": "^3.6.0",
16+
"phpunit/phpunit": "~8.5.15"
1617
},
1718
"license": [
1819
"MIT"
@@ -31,9 +32,15 @@
3132
"EcomDev\\ProductDataPreLoader\\": "src"
3233
}
3334
},
35+
"autoload-dev": {
36+
"psr-4": {
37+
"EcomDev\\ProductDataPreLoader\\": "tests"
38+
}
39+
},
3440
"scripts": {
3541
"phpcs": "phpcs",
3642
"phpcbf": "phpcbf",
37-
"phpstan": "phpstan analyze src"
43+
"phpstan": "phpstan analyze src",
44+
"test": "phpunit tests"
3845
}
3946
}

src/DataService/CustomerGroupProvider.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class CustomerGroupProvider
1919
/**
2020
* Customer session instance
2121
*
22-
* @var Session\Proxy
22+
* @var Session
2323
*/
2424
private $customerSession;
2525

@@ -33,10 +33,10 @@ class CustomerGroupProvider
3333
/**
3434
* CustomerGroupProvider constructor.
3535
*
36-
* @param Session\Proxy $customerSession
36+
* @param Session $customerSession
3737
* @param SessionStartChecker $sessionChecker
3838
*/
39-
public function __construct(Session\Proxy $customerSession, SessionStartChecker $sessionChecker)
39+
public function __construct(Session $customerSession, SessionStartChecker $sessionChecker)
4040
{
4141
$this->customerSession = $customerSession;
4242
$this->sessionChecker = $sessionChecker;

src/DataService/MagentoProductWrapper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function __construct(Product $product)
3535
*/
3636
public function getSku(): string
3737
{
38-
return $this->product->getSku();
38+
return $this->product->getData('sku');
3939
}
4040

4141

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace EcomDev\ProductDataPreLoader\DataService;
4+
5+
use Magento\Catalog\Model\Product;
6+
use Magento\Framework\ObjectManagerInterface;
7+
8+
/**
9+
* Factory for a product wrapper
10+
*/
11+
class MagentoProductWrapperFactory
12+
{
13+
/**
14+
* Object manager instance to create wrappers around product
15+
*
16+
* @var ObjectManagerInterface
17+
*/
18+
private $objectManager;
19+
20+
/**
21+
* MagentoProductWrapperFactory constructor.
22+
*
23+
* @param ObjectManagerInterface $objectManager
24+
*/
25+
public function __construct(ObjectManagerInterface $objectManager)
26+
{
27+
$this->objectManager = $objectManager;
28+
}
29+
30+
/**
31+
* Crates a product wrapper instance
32+
*
33+
* @param Product $product
34+
*/
35+
public function create(Product $product): ProductWrapper
36+
{
37+
return $this->objectManager->create(MagentoProductWrapper::class, ['product' => $product]);
38+
}
39+
}

src/Observer/ListCollectionAfterLoad.php

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99

1010
use EcomDev\ProductDataPreLoader\DataService\DataLoader;
1111
use EcomDev\ProductDataPreLoader\DataService\LoadService;
12-
use EcomDev\ProductDataPreLoader\DataService\ProductAdapterFactory;
12+
use EcomDev\ProductDataPreLoader\DataService\MagentoProductWrapperFactory;
1313
use EcomDev\ProductDataPreLoader\DataService\ScopeFilter;
1414
use EcomDev\ProductDataPreLoader\DataService\ScopeFilterFactory;
15-
use Magento\Catalog\Api\Data\ProductInterface;
1615
use Magento\Catalog\Model\ResourceModel\Product\Collection;
16+
17+
use Magento\Catalog\Model\Product;
1718
use Magento\Framework\Event\Observer;
1819
use Magento\Framework\Event\ObserverInterface;
1920

@@ -53,7 +54,7 @@ class ListCollectionAfterLoad implements ObserverInterface
5354
/**
5455
* Factory for creating product adapters
5556
*
56-
* @var ProductAdapterFactory
57+
* @var MagentoProductWrapperFactory
5758
*/
5859
private $adapterFactory;
5960

@@ -62,12 +63,12 @@ class ListCollectionAfterLoad implements ObserverInterface
6263
*
6364
* @param LoadService $loadService
6465
* @param ScopeFilterFactory $filterFactory
65-
* @param ProductAdapterFactory $adapterFactory
66+
* @param MagentoProductWrapperFactory $adapterFactory
6667
*/
6768
public function __construct(
6869
LoadService $loadService,
6970
ScopeFilterFactory $filterFactory,
70-
ProductAdapterFactory $adapterFactory
71+
MagentoProductWrapperFactory $adapterFactory
7172
) {
7273
$this->loadService = $loadService;
7374
$this->filterFactory = $filterFactory;
@@ -95,9 +96,9 @@ public function execute(Observer $observer)
9596
$collection = $observer->getData('collection');
9697

9798
$productInfo = [];
98-
/* @var ProductInterface $product */
99+
/* @var Product $product */
99100
foreach ($collection->getItems() as $product) {
100-
$productInfo[(int)$product->getId()] = $this->adapterFactory->create(['product' => $product]);
101+
$productInfo[(int)$product->getId()] = $this->adapterFactory->create($product);
101102
}
102103

103104
$type = DataLoader::TYPE_OTHER;

src/Observer/ProductAfterLoad.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public function execute(Observer $observer)
8383
$scope = $this->filterFactory->createFromStore($product->getStoreId());
8484
$type = DataLoader::TYPE_CART;
8585

86-
$adapter = $this->productAdapterFactory->create(['product' => $product]);
86+
$adapter = $this->productAdapterFactory->create($product);
8787

8888
$productInfo = [
8989
$product->getId() => $adapter

src/etc/di.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,10 @@
77
<argument name="loaders" xsi:type="array" />
88
</arguments>
99
</type>
10+
11+
<type name="EcomDev\ProductDataPreLoader\DataService\CustomerGroupProvider">
12+
<arguments>
13+
<argument name="customerSession" xsi:type="object">Magento\Customer\Model\Session\Proxy</argument>
14+
</arguments>
15+
</type>
1016
</config>

tests/FakeObjectManager.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
namespace EcomDev\ProductDataPreLoader;
4+
5+
use Magento\Framework\ObjectManagerInterface;
6+
7+
/**
8+
* Simplistic implementation of Object Manager for testing
9+
*/
10+
class FakeObjectManager implements ObjectManagerInterface
11+
{
12+
/**
13+
* Configuration of classes used for interfaces
14+
*
15+
* @var array
16+
*/
17+
private $configuration = [];
18+
19+
/* @inheritDoc */
20+
public function create($type, array $arguments = [])
21+
{
22+
$reflectionClass = new \ReflectionClass($type);
23+
$constructorArguments = [];
24+
25+
foreach ($reflectionClass->getConstructor()->getParameters() as $parameter) {
26+
if (isset($arguments[$parameter->getName()])) {
27+
$constructorArguments[] = $arguments[$parameter->getName()];
28+
} elseif (!$parameter->isOptional() && $parameter->getType() instanceof \ReflectionNamedType) {
29+
$constructorArguments[] = $this->get($parameter->getType()->getName());
30+
} elseif (!$parameter->isOptional()) {
31+
throw new \RuntimeException(
32+
sprintf(
33+
'Cannot resolve constructor argument %s property for instantiating %s',
34+
$parameter->getName(),
35+
$type
36+
)
37+
);
38+
}
39+
}
40+
41+
return $reflectionClass->newInstanceArgs($constructorArguments);
42+
}
43+
44+
/* @inheritDoc */
45+
public function get($type)
46+
{
47+
$type = $this->configuration['preferences'][$type] ?? $type;
48+
return (new \ReflectionClass($type))->newInstanceWithoutConstructor();
49+
}
50+
51+
/* @inheritDoc */
52+
public function configure(array $configuration)
53+
{
54+
$this->configuration = $configuration;
55+
}
56+
}

tests/MagentoProductWrapperTest.php

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
3+
namespace EcomDev\ProductDataPreLoader;
4+
5+
use EcomDev\ProductDataPreLoader\DataService\MagentoProductWrapperFactory;
6+
use Magento\Catalog\Model\Product;
7+
use PHPUnit\Framework\TestCase;
8+
9+
/**
10+
* Tests for product wrapper
11+
*
12+
*/
13+
class MagentoProductWrapperTest extends TestCase
14+
{
15+
/* @var MagentoProductWrapperFactory */
16+
private $factory;
17+
18+
protected function setUp(): void
19+
{
20+
$this->factory = new MagentoProductWrapperFactory(new FakeObjectManager());
21+
}
22+
23+
/** @test */
24+
public function verifiesThatSimpleProductIsNotAConfigurable()
25+
{
26+
$item = $this->factory->create($this->createProduct(['type_id' => 'simple']));
27+
28+
$this->assertFalse($item->isType('configurable'));
29+
}
30+
31+
/** @test */
32+
public function verifiesThatProductMatchesAtLeastOneProductTypeInArgumentList()
33+
{
34+
$item = $this->factory->create($this->createProduct(['type_id' => 'valid_type']));
35+
36+
$this->assertTrue($item->isType('simple', 'virtual', 'valid_type', 'another_type'));
37+
}
38+
39+
/** @test */
40+
public function returnsSkuFromWrappedProduct()
41+
{
42+
$item = $this->factory->create($this->createProduct(['sku' => 'SKU10']));
43+
44+
$this->assertEquals('SKU10', $item->getSku());
45+
}
46+
47+
/** @test */
48+
public function returnsIdFromWrappedProduct()
49+
{
50+
$item = $this->factory->create($this->createProduct(['entity_id' => '123']));
51+
52+
$this->assertEquals(123, $item->getId());
53+
}
54+
55+
/** @test */
56+
public function updatesFieldsInProductDataStorage()
57+
{
58+
$product = $this->createProduct(['some_data' => 1]);
59+
$item = $this->factory->create($product);
60+
61+
$item->updateField('another_field', 'value1');
62+
$item->updateField('final_field', 'value2');
63+
64+
$this->assertEquals(
65+
[
66+
'some_data' => 1,
67+
'another_field' => 'value1',
68+
'final_field' => 'value2'
69+
],
70+
$product->getData()
71+
);
72+
}
73+
74+
/**
75+
* Crates a new product for testing
76+
*
77+
* @param array $data
78+
*
79+
* @return Product
80+
*/
81+
private function createProduct(array $data = []): Product
82+
{
83+
$product = (new FakeObjectManager())->get(Product::class);
84+
$product->setData($data);
85+
86+
return $product;
87+
}
88+
}

0 commit comments

Comments
 (0)