Skip to content

Commit 840af3e

Browse files
ENGCOM-6059: Fix for #23577. Check if db tables for config data exists before fetch #24959
2 parents 65c9107 + 3a1540c commit 840af3e

File tree

6 files changed

+440
-16
lines changed

6 files changed

+440
-16
lines changed

app/code/Magento/Store/App/Config/Source/RuntimeConfigSource.php

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public function __construct(
4444

4545
/**
4646
* Return whole scopes config data from db.
47+
*
4748
* Ignore $path argument due to config source must return all config data
4849
*
4950
* @param string $path
@@ -64,6 +65,8 @@ public function get($path = '')
6465
}
6566

6667
/**
68+
* Retrieve default connection
69+
*
6770
* @return AdapterInterface
6871
*/
6972
private function getConnection()
@@ -83,12 +86,17 @@ private function getConnection()
8386
*/
8487
private function getEntities($table, $keyField)
8588
{
86-
$entities = $this->getConnection()->fetchAll(
87-
$this->getConnection()->select()->from($this->resourceConnection->getTableName($table))
88-
);
8989
$data = [];
90-
foreach ($entities as $entity) {
91-
$data[$entity[$keyField]] = $entity;
90+
$tableName = $this->resourceConnection->getTableName($table);
91+
// Check if db table exists before fetch data
92+
if ($this->resourceConnection->getConnection()->isTableExists($tableName)) {
93+
$entities = $this->getConnection()->fetchAll(
94+
$this->getConnection()->select()->from($tableName)
95+
);
96+
97+
foreach ($entities as $entity) {
98+
$data[$entity[$keyField]] = $entity;
99+
}
92100
}
93101

94102
return $data;

app/code/Magento/Store/Model/ResourceModel/Store.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,11 +166,16 @@ protected function _changeGroup(\Magento\Framework\Model\AbstractModel $model)
166166
*/
167167
public function readAllStores()
168168
{
169-
$select = $this->getConnection()
170-
->select()
171-
->from($this->getTable('store'));
169+
$stores = [];
170+
if ($this->getConnection()->isTableExists($this->getMainTable())) {
171+
$select = $this->getConnection()
172+
->select()
173+
->from($this->getTable($this->getMainTable()));
172174

173-
return $this->getConnection()->fetchAll($select);
175+
$stores = $this->getConnection()->fetchAll($select);
176+
}
177+
178+
return $stores;
174179
}
175180

176181
/**

app/code/Magento/Store/Model/ResourceModel/Website.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,15 @@ protected function _initUniqueFields()
4747
public function readAllWebsites()
4848
{
4949
$websites = [];
50-
$select = $this->getConnection()
51-
->select()
52-
->from($this->getTable('store_website'));
50+
$tableName = $this->getMainTable();
51+
if ($this->getConnection()->isTableExists($tableName)) {
52+
$select = $this->getConnection()
53+
->select()
54+
->from($tableName);
5355

54-
foreach ($this->getConnection()->fetchAll($select) as $websiteData) {
55-
$websites[$websiteData['code']] = $websiteData;
56+
foreach ($this->getConnection()->fetchAll($select) as $websiteData) {
57+
$websites[$websiteData['code']] = $websiteData;
58+
}
5659
}
5760

5861
return $websites;
@@ -115,6 +118,7 @@ protected function _afterDelete(\Magento\Framework\Model\AbstractModel $model)
115118

116119
/**
117120
* Retrieve default stores select object
121+
*
118122
* Select fields website_id, store_id
119123
*
120124
* @param bool $includeDefault include/exclude default admin website

app/code/Magento/Store/Test/Unit/App/Config/Source/RuntimeConfigSourceTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ public function setUp()
5353

5454
public function testGet()
5555
{
56-
$this->deploymentConfig->expects($this->once())
56+
$this->deploymentConfig->expects($this->any())
5757
->method('get')
5858
->with('db')
5959
->willReturn(true);
60-
$this->resourceConnection->expects($this->once())->method('getConnection')->willReturn($this->connection);
60+
$this->resourceConnection->expects($this->any())->method('getConnection')->willReturn($this->connection);
6161

6262
$selectMock = $this->getMockBuilder(Select::class)->disableOriginalConstructor()->getMock();
6363
$selectMock->expects($this->any())->method('from')->willReturnSelf();
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Store\Test\Unit\Model\ResourceModel;
8+
9+
use Magento\Framework\App\ResourceConnection;
10+
use Magento\Framework\DB\Select;
11+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
12+
use Magento\Store\Model\ResourceModel\Store;
13+
use Magento\Framework\DB\Adapter\AdapterInterface;
14+
15+
class StoreTest extends \PHPUnit\Framework\TestCase
16+
{
17+
/** @var Store */
18+
protected $model;
19+
20+
/**
21+
* @var ResourceConnection|\PHPUnit_Framework_MockObject_MockObject
22+
*/
23+
protected $resourceMock;
24+
25+
/** @var Select | \PHPUnit_Framework_MockObject_MockObject */
26+
protected $select;
27+
28+
/**
29+
* @var AdapterInterface|\PHPUnit_Framework_MockObject_MockObject
30+
*/
31+
protected $connectionMock;
32+
33+
public function setUp()
34+
{
35+
$objectManagerHelper = new ObjectManager($this);
36+
$this->select = $this->createMock(Select::class);
37+
$this->resourceMock = $this->createPartialMock(
38+
ResourceConnection::class,
39+
[
40+
'getConnection',
41+
'getTableName'
42+
]
43+
);
44+
$this->connectionMock = $this->createPartialMock(
45+
\Magento\Framework\DB\Adapter\Pdo\Mysql::class,
46+
[
47+
'isTableExists',
48+
'select',
49+
'fetchAll',
50+
'fetchOne',
51+
'from',
52+
'getCheckSql',
53+
'where',
54+
'quoteIdentifier',
55+
'quote'
56+
]
57+
);
58+
59+
$contextMock = $this->createMock(\Magento\Framework\Model\ResourceModel\Db\Context::class);
60+
$contextMock->expects($this->once())->method('getResources')->willReturn($this->resourceMock);
61+
$configCacheTypeMock = $this->createMock('\Magento\Framework\App\Cache\Type\Config');
62+
$this->model = $objectManagerHelper->getObject(
63+
Store::class,
64+
[
65+
'context' => $contextMock,
66+
'configCacheType' => $configCacheTypeMock
67+
]
68+
);
69+
}
70+
71+
public function testCountAll($countAdmin = false)
72+
{
73+
$mainTable = 'store';
74+
$tableIdentifier = 'code';
75+
$tableIdentifierValue = 'admin';
76+
$count = 1;
77+
78+
$this->resourceMock->expects($this->once())
79+
->method('getConnection')
80+
->willReturn($this->connectionMock);
81+
82+
$this->connectionMock->expects($this->once())
83+
->method('select')
84+
->willReturn($this->select);
85+
86+
$this->resourceMock->expects($this->once())
87+
->method('getTableName')
88+
->willReturn($mainTable);
89+
90+
$this->select->expects($this->once())
91+
->method('from')
92+
->with($mainTable, 'COUNT(*)')
93+
->willReturnSelf();
94+
95+
$this->connectionMock->expects($this->any())
96+
->method('quoteIdentifier')
97+
->with($tableIdentifier)
98+
->willReturn($tableIdentifier);
99+
100+
$this->connectionMock->expects($this->once())
101+
->method('quote')
102+
->with($tableIdentifierValue)
103+
->willReturn($tableIdentifierValue);
104+
105+
$this->select->expects($this->any())
106+
->method('where')
107+
->with(sprintf('%s <> %s', $tableIdentifier, $tableIdentifierValue))
108+
->willReturnSelf();
109+
110+
$this->connectionMock->expects($this->once())
111+
->method('fetchOne')
112+
->with($this->select)
113+
->willReturn($count);
114+
115+
$this->assertEquals($count, $this->model->countAll($countAdmin));
116+
}
117+
118+
public function testReadAllStores()
119+
{
120+
$mainTable = 'store';
121+
$data = [
122+
["store_id" => "0", "code" => "admin", "website_id" => 0, "name" => "Admin"],
123+
["store_id" => "1", "code" => "default", "website_id" => 1, "name" => "Default Store View"]
124+
];
125+
126+
$this->resourceMock->expects($this->atLeastOnce())
127+
->method('getConnection')
128+
->willReturn($this->connectionMock);
129+
130+
$this->resourceMock->expects($this->atLeastOnce())
131+
->method('getTableName')
132+
->willReturn($mainTable);
133+
134+
$this->connectionMock->expects($this->once())
135+
->method('isTableExists')
136+
->with($mainTable)
137+
->willReturn(true);
138+
139+
$this->connectionMock->expects($this->once())
140+
->method('select')
141+
->willReturn($this->select);
142+
143+
$this->select->expects($this->once())
144+
->method('from')
145+
->with($mainTable)
146+
->willReturnSelf();
147+
148+
$this->connectionMock->expects($this->once())
149+
->method('fetchAll')
150+
->with($this->select)
151+
->willReturn($data);
152+
153+
$this->assertEquals($data, $this->model->readAllStores());
154+
}
155+
156+
public function testReadAllStoresNoDbTable()
157+
{
158+
$mainTable = 'no_store_table';
159+
$data = [];
160+
161+
$this->resourceMock->expects($this->once())
162+
->method('getConnection')
163+
->willReturn($this->connectionMock);
164+
165+
$this->resourceMock->expects($this->once())
166+
->method('getTableName')
167+
->willReturn($mainTable);
168+
169+
$this->connectionMock->expects($this->once())
170+
->method('isTableExists')
171+
->with($mainTable)
172+
->willReturn(false);
173+
174+
$this->connectionMock->expects($this->never())
175+
->method('select')
176+
->willReturn($this->select);
177+
178+
$this->select->expects($this->never())
179+
->method('from')
180+
->with($mainTable)
181+
->willReturnSelf();
182+
183+
$this->connectionMock->expects($this->never())
184+
->method('fetchAll')
185+
->with($this->select)
186+
->willReturn($data);
187+
188+
$this->assertEquals($data, $this->model->readAllStores());
189+
}
190+
}

0 commit comments

Comments
 (0)