Skip to content

Commit c310852

Browse files
committed
B2B-1671: Detect Missing Primary Key in Table Schema Test
1 parent cd857f9 commit c310852

File tree

2 files changed

+121
-0
lines changed

2 files changed

+121
-0
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\Test\Integrity\DBSchema;
10+
11+
use Magento\Framework\App\Utility\Files;
12+
use Magento\Framework\Exception\LocalizedException;
13+
use Magento\Framework\Setup\Declaration\Schema\Config\Converter;
14+
use PHPUnit\Framework\TestCase;
15+
16+
/**
17+
* Test for existance of primary key in database tables
18+
*/
19+
class PrimaryKeyTest extends TestCase
20+
{
21+
private $blockWhitelist;
22+
23+
/**
24+
* Check existance of database tables' primary key
25+
*
26+
* @throws LocalizedException
27+
*/
28+
public function testMissingPrimaryKey()
29+
{
30+
$exemptionList = $this->getExemptionlist();
31+
$tablesSchemaDeclaration = $this->getDbSchemaDeclaration()['table'];
32+
$exemptionList = array_intersect(array_keys($tablesSchemaDeclaration), $exemptionList);
33+
foreach ($exemptionList as $exemptionTableName) {
34+
unset($tablesSchemaDeclaration[$exemptionTableName]);
35+
}
36+
$errorMessage = '';
37+
$failedTableCtr = 0;
38+
foreach ($tablesSchemaDeclaration as $tableName => $tableSchemaDeclaration) {
39+
if (!isset($tableSchemaDeclaration['constraint']['PRIMARY'])) {
40+
$message = '';
41+
if (!empty($tableSchemaDeclaration['modules'])) {
42+
$message = "It is declared in the following modules: \n" . implode(
43+
"\t\n",
44+
$tableSchemaDeclaration['modules']
45+
);
46+
}
47+
$errorMessage .= 'Table ' . $tableName . ' does not have primary key. ' . $message . "\n";
48+
$failedTableCtr ++;
49+
}
50+
}
51+
if (!empty($errorMessage)) {
52+
$errorMessage .= "\n\nTotal " . $failedTableCtr . " tables failed";
53+
$this->fail($errorMessage);
54+
}
55+
}
56+
57+
/**
58+
* Get database schema declaration from file.
59+
*
60+
* @param string $filePath
61+
* @return array
62+
*/
63+
private function getDbSchemaDeclarationByFile(string $filePath): array
64+
{
65+
$dom = new \DOMDocument();
66+
$dom->loadXML(file_get_contents($filePath));
67+
return (new Converter())->convert($dom);
68+
}
69+
70+
/**
71+
* Get database schema declaration for whole application
72+
*
73+
* @return array
74+
* @throws LocalizedException
75+
*/
76+
private function getDbSchemaDeclaration(): array
77+
{
78+
$declaration = [];
79+
foreach (Files::init()->getDbSchemaFiles() as $filePath) {
80+
$filePath = reset($filePath);
81+
preg_match('#app/code/(\w+/\w+)#', $filePath, $result);
82+
$moduleName = str_replace('/', '\\', $result[1]);
83+
$moduleDeclaration = $this->getDbSchemaDeclarationByFile($filePath);
84+
85+
foreach ($moduleDeclaration['table'] as $tableName => $tableDeclaration) {
86+
if (!isset($tableDeclaration['modules'])) {
87+
$tableDeclaration['modules'] = [];
88+
}
89+
array_push($tableDeclaration['modules'], $moduleName);
90+
$moduleDeclaration = array_replace_recursive(
91+
$moduleDeclaration,
92+
['table' => [
93+
$tableName => $tableDeclaration,
94+
]
95+
]
96+
);
97+
}
98+
$declaration = array_merge_recursive($declaration, $moduleDeclaration);
99+
}
100+
return $declaration;
101+
}
102+
103+
/**
104+
* Return primary key exemption tables list
105+
*
106+
* @return string[]
107+
*/
108+
private function getExemptionlist(): array
109+
{
110+
$exemptionListFiles = str_replace(
111+
'\\',
112+
'/',
113+
realpath(__DIR__) . '/_files/primary_key_exemption_list*.txt'
114+
);
115+
$exemptionList = [];
116+
foreach (glob($exemptionListFiles) as $fileName) {
117+
$exemptionList[] = file($fileName, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
118+
}
119+
return array_merge([], ...$exemptionList);
120+
}
121+
}

dev/tests/static/testsuite/Magento/Test/Integrity/DBSchema/_files/primary_key_exemption_list.txt

Whitespace-only changes.

0 commit comments

Comments
 (0)