Skip to content
This repository was archived by the owner on Apr 29, 2019. It is now read-only.

Commit df6b6ef

Browse files
committed
Merge branch 'MAGETWO-82883' into MPI-PR-2.2.2
2 parents 0483421 + 7dd8acd commit df6b6ef

File tree

5 files changed

+224
-53
lines changed

5 files changed

+224
-53
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Sales\Model\ResourceModel\Provider;
7+
8+
use Magento\Framework\App\ResourceConnection;
9+
use Magento\Framework\DB\Adapter\AdapterInterface;
10+
11+
/**
12+
* Retrieves ID's of not synced by `updated_at` column entities.
13+
* The result should contain list of entities ID's from the main table which have `updated_at` column greater
14+
* than in the grid table.
15+
*/
16+
class UpdatedAtListProvider implements NotSyncedDataProviderInterface
17+
{
18+
/**
19+
* @var ResourceConnection
20+
*/
21+
private $resourceConnection;
22+
23+
/**
24+
* @var AdapterInterface
25+
*/
26+
private $connection;
27+
28+
/**
29+
* @param ResourceConnection $resourceConnection
30+
*/
31+
public function __construct(ResourceConnection $resourceConnection)
32+
{
33+
$this->connection = $resourceConnection->getConnection('sales');
34+
$this->resourceConnection = $resourceConnection;
35+
}
36+
37+
/**
38+
* @inheritdoc
39+
*/
40+
public function getIds($mainTableName, $gridTableName)
41+
{
42+
$mainTableName = $this->resourceConnection->getTableName($mainTableName);
43+
$gridTableName = $this->resourceConnection->getTableName($gridTableName);
44+
$select = $this->connection->select()
45+
->from($mainTableName, [$mainTableName . '.entity_id'])
46+
->joinInner(
47+
[$gridTableName => $gridTableName],
48+
sprintf(
49+
'%s.entity_id = %s.entity_id AND %s.updated_at > %s.updated_at',
50+
$mainTableName,
51+
$gridTableName,
52+
$mainTableName,
53+
$gridTableName
54+
),
55+
[]
56+
);
57+
58+
return $this->connection->fetchAll($select, [], \Zend_Db::FETCH_COLUMN);
59+
}
60+
}

app/code/Magento/Sales/Model/ResourceModel/Provider/UpdatedIdListProvider.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,12 @@ public function __construct(
3838
*/
3939
public function getIds($mainTableName, $gridTableName)
4040
{
41+
$mainTableName = $this->resourceConnection->getTableName($mainTableName);
42+
$gridTableName = $this->resourceConnection->getTableName($gridTableName);
4143
$select = $this->getConnection()->select()
42-
->from($this->getConnection()->getTableName($mainTableName), [$mainTableName . '.entity_id'])
44+
->from($mainTableName, [$mainTableName . '.entity_id'])
4345
->joinLeft(
44-
[$gridTableName => $this->getConnection()->getTableName($gridTableName)],
46+
[$gridTableName => $gridTableName],
4547
sprintf(
4648
'%s.%s = %s.%s',
4749
$mainTableName,

app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Provider/NotSyncedDataProviderTest.php

Lines changed: 16 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,11 @@
55
*/
66
namespace Magento\Sales\Test\Unit\Model\ResourceModel\Provider;
77

8-
use Magento\Framework\ObjectManager\TMap;
98
use Magento\Framework\ObjectManager\TMapFactory;
109
use Magento\Sales\Model\ResourceModel\Provider\NotSyncedDataProvider;
1110
use Magento\Sales\Model\ResourceModel\Provider\NotSyncedDataProviderInterface;
1211
use PHPUnit_Framework_MockObject_MockObject as MockObject;
1312

14-
/**
15-
* Class NotSyncedDataProviderTest
16-
*/
1713
class NotSyncedDataProviderTest extends \PHPUnit\Framework\TestCase
1814
{
1915
public function testGetIdsEmpty()
@@ -23,77 +19,46 @@ public function testGetIdsEmpty()
2319
->disableOriginalConstructor()
2420
->setMethods(['create'])
2521
->getMock();
26-
$tMap = $this->getMockBuilder(TMap::class)
27-
->disableOriginalConstructor()
28-
->getMock();
2922

30-
$tMapFactory->expects(static::once())
31-
->method('create')
32-
->with(
33-
[
34-
'array' => [],
35-
'type' => NotSyncedDataProviderInterface::class
36-
]
37-
)
38-
->willReturn($tMap);
39-
$tMap->expects(static::once())
40-
->method('getIterator')
41-
->willReturn(new \ArrayIterator([]));
23+
$tMapFactory->method('create')
24+
->willReturn([]);
4225

43-
$provider = new NotSyncedDataProvider($tMapFactory, []);
44-
static::assertEquals([], $provider->getIds('main_table', 'grid_table'));
26+
$provider = new NotSyncedDataProvider($tMapFactory);
27+
self::assertEquals([], $provider->getIds('main_table', 'grid_table'));
4528
}
4629

47-
/**
48-
* @covers \Magento\Sales\Model\ResourceModel\Provider\NotSyncedDataProvider::getIds
49-
*/
5030
public function testGetIds()
5131
{
5232
/** @var TMapFactory|MockObject $tMapFactory */
5333
$tMapFactory = $this->getMockBuilder(TMapFactory::class)
5434
->disableOriginalConstructor()
5535
->setMethods(['create'])
5636
->getMock();
57-
$tMap = $this->getMockBuilder(TMap::class)
58-
->disableOriginalConstructor()
59-
->getMock();
6037

6138
$provider1 = $this->getMockBuilder(NotSyncedDataProviderInterface::class)
6239
->getMockForAbstractClass();
63-
$provider1->expects(static::once())
64-
->method('getIds')
40+
$provider1->method('getIds')
6541
->willReturn([1, 2]);
6642

6743
$provider2 = $this->getMockBuilder(NotSyncedDataProviderInterface::class)
6844
->getMockForAbstractClass();
69-
$provider2->expects(static::once())
70-
->method('getIds')
45+
$provider2->method('getIds')
7146
->willReturn([2, 3, 4]);
7247

73-
$tMapFactory->expects(static::once())
74-
->method('create')
75-
->with(
48+
$tMapFactory->method('create')
49+
->with(self::equalTo(
7650
[
77-
'array' => [
78-
'provider1' => NotSyncedDataProviderInterface::class,
79-
'provider2' => NotSyncedDataProviderInterface::class
80-
],
51+
'array' => [$provider1, $provider2],
8152
'type' => NotSyncedDataProviderInterface::class
8253
]
83-
)
84-
->willReturn($tMap);
85-
$tMap->expects(static::once())
86-
->method('getIterator')
87-
->willReturn(new \ArrayIterator([$provider1, $provider2]));
54+
))
55+
->willReturn([$provider1, $provider2]);
8856

89-
$provider = new NotSyncedDataProvider(
90-
$tMapFactory,
91-
[
92-
'provider1' => NotSyncedDataProviderInterface::class,
93-
'provider2' => NotSyncedDataProviderInterface::class,
94-
]
95-
);
57+
$provider = new NotSyncedDataProvider($tMapFactory, [$provider1, $provider2]);
9658

97-
static::assertEquals([1, 2, 3, 4], array_values($provider->getIds('main_table', 'grid_table')));
59+
self::assertEquals(
60+
[1, 2, 3, 4],
61+
array_values($provider->getIds('main_table', 'grid_table'))
62+
);
9863
}
9964
}

app/code/Magento/Sales/etc/di.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,15 @@
470470
<argument name="entityRelationComposite" xsi:type="object">CreditmemoRelationsComposite</argument>
471471
</arguments>
472472
</type>
473+
474+
<virtualType name="Magento\Sales\Model\ResourceModel\Provider\NotSyncedOrderDataProvider" type="Magento\Sales\Model\ResourceModel\Provider\NotSyncedDataProvider">
475+
<arguments>
476+
<argument name="providers" xsi:type="array">
477+
<item name="default" xsi:type="string">Magento\Sales\Model\ResourceModel\Provider\UpdatedIdListProvider</item>
478+
<item name="updated_at" xsi:type="string">Magento\Sales\Model\ResourceModel\Provider\UpdatedAtListProvider</item>
479+
</argument>
480+
</arguments>
481+
</virtualType>
473482
<virtualType name="Magento\Sales\Model\ResourceModel\Order\Grid" type="Magento\Sales\Model\ResourceModel\Grid">
474483
<arguments>
475484
<argument name="mainTableName" xsi:type="string">sales_order</argument>
@@ -520,6 +529,7 @@
520529
<item name="payment_method" xsi:type="string">sales_order_payment.method</item>
521530
<item name="total_refunded" xsi:type="string">sales_order.total_refunded</item>
522531
</argument>
532+
<argument name="notSyncedDataProvider" xsi:type="object">Magento\Sales\Model\ResourceModel\Provider\NotSyncedOrderDataProvider</argument>
523533
</arguments>
524534
</virtualType>
525535
<virtualType name="ShipmentGridAggregator" type="Magento\Sales\Model\ResourceModel\Grid">
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Sales\Model;
7+
8+
use Magento\Framework\Api\SearchCriteria;
9+
use Magento\Framework\Api\SearchCriteriaBuilder;
10+
use Magento\Framework\App\ResourceConnection;
11+
use Magento\Framework\DB\Adapter\AdapterInterface;
12+
use Magento\Sales\Api\Data\OrderInterface;
13+
use Magento\Sales\Api\OrderRepositoryInterface;
14+
use Magento\Sales\Model\ResourceModel\Grid as AbstractGrid;
15+
use Magento\Sales\Model\ResourceModel\Order\Grid;
16+
use Magento\TestFramework\Helper\Bootstrap;
17+
use Magento\TestFramework\ObjectManager;
18+
19+
class GridAsyncInsertTest extends \PHPUnit\Framework\TestCase
20+
{
21+
/**
22+
* @var ObjectManager
23+
*/
24+
private $objectManager;
25+
26+
/**
27+
* @var GridAsyncInsert
28+
*/
29+
private $gridAsyncInsert;
30+
31+
/**
32+
* @var AdapterInterface
33+
*/
34+
private $connection;
35+
36+
/**
37+
* @var OrderRepositoryInterface
38+
*/
39+
private $orderRepository;
40+
41+
/**
42+
* @var AbstractGrid
43+
*/
44+
private $grid;
45+
46+
protected function setUp()
47+
{
48+
$this->objectManager = Bootstrap::getObjectManager();
49+
50+
/** @var ResourceConnection $resourceConnection */
51+
$resourceConnection = $this->objectManager->get(ResourceConnection::class);
52+
$this->connection = $resourceConnection->getConnection('sales');
53+
$this->orderRepository = $this->objectManager->get(OrderRepositoryInterface::class);
54+
$this->grid = $this->objectManager->get(Grid::class);
55+
56+
$this->gridAsyncInsert = $this->objectManager->create(
57+
GridAsyncInsert::class,
58+
[
59+
'entityGrid' => $this->grid
60+
]
61+
);
62+
}
63+
64+
/**
65+
* Checks a case when order's grid should be updated asynchronously.
66+
*
67+
* @magentoConfigFixture default/dev/grid/async_indexing 1
68+
* @magentoDataFixture Magento/Sales/_files/order.php
69+
*/
70+
public function testExecuteAsyncUpdateOrderGrid()
71+
{
72+
$order = $this->getOrder('100000001');
73+
$this->performUpdateAssertions($order);
74+
75+
// to un-sync main table and grid table need to wait at least one second
76+
sleep(1);
77+
$order->setStatus('complete');
78+
$this->orderRepository->save($order);
79+
80+
$gridRow = $this->getGridRow($order->getEntityId());
81+
self::assertNotEquals($order->getStatus(), $gridRow['status']);
82+
83+
$this->gridAsyncInsert->asyncInsert();
84+
$this->performUpdateAssertions($order);
85+
}
86+
87+
/**
88+
* Loads order entity by provided order increment ID.
89+
*
90+
* @param string $incrementId
91+
* @return OrderInterface
92+
*/
93+
private function getOrder(string $incrementId) : OrderInterface
94+
{
95+
/** @var SearchCriteria $searchCriteria */
96+
$searchCriteria = $this->objectManager->get(SearchCriteriaBuilder::class)
97+
->addFilter('increment_id', $incrementId)
98+
->create();
99+
100+
$items = $this->orderRepository->getList($searchCriteria)
101+
->getItems();
102+
103+
return array_pop($items);
104+
}
105+
106+
/**
107+
* Gets row from `sales_order_grid` table by order's ID.
108+
*
109+
* @param int $entityId
110+
* @return array
111+
*/
112+
private function getGridRow(int $entityId) : array
113+
{
114+
$tableName = $this->grid->getGridTable();
115+
$select = $this->connection->select()
116+
->from($tableName)
117+
->where($tableName . '.entity_id = ?', $entityId);
118+
119+
return $this->connection->fetchRow($select);
120+
}
121+
122+
/**
123+
* Perform assertions for updating grid test.
124+
*
125+
* @param OrderInterface $order
126+
*/
127+
private function performUpdateAssertions(OrderInterface $order)
128+
{
129+
$gridRow = $this->getGridRow($order->getEntityId());
130+
131+
self::assertEquals($order->getStatus(), $gridRow['status']);
132+
self::assertEquals($order->getUpdatedAt(), $gridRow['updated_at']);
133+
}
134+
}

0 commit comments

Comments
 (0)