Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
WhitelistDeclarationTest.php
Go to the documentation of this file.
1 <?php
6 declare(strict_types=1);
7 
9 
20 
24 class WhitelistDeclarationTest extends \PHPUnit\Framework\TestCase
25 {
29  private $componentRegistrar;
30 
34  private $schemaConfig;
35 
36  public function setUp()
37  {
40  $resourceConnection = $objectManager->create(ResourceConnection::class);
41  $objectManager->removeSharedInstance(ResourceConnection::class);
42  $objectManager->addSharedInstance($resourceConnection, ResourceConnection::class);
43  $this->componentRegistrar = $objectManager->get(ComponentRegistrarInterface::class);
44  $this->schemaConfig = $objectManager->create(SchemaConfigInterface::class);
45  }
46 
54  {
55  $undeclaredElements = [];
56  $resultMessage = "New table elements that do not exist in the whitelist declaration:\n";
57  $whitelistTables = $this->getWhiteListTables();
58  $declarativeSchema = $this->schemaConfig->getDeclarationConfig();
59 
60  foreach ($declarativeSchema->getTables() as $schemaTable) {
61  $tableNameWithoutPrefix = $schemaTable->getNameWithoutPrefix();
62  foreach ($schemaTable->getConstraints() as $constraint) {
63  $constraintNameWithoutPrefix = $constraint->getNameWithoutPrefix();
64  if (isset($whitelistTables[$tableNameWithoutPrefix][Constraint::TYPE][$constraintNameWithoutPrefix])) {
65  continue;
66  }
67 
68  $undeclaredElements[$tableNameWithoutPrefix][Constraint::TYPE][] = $constraintNameWithoutPrefix;
69  }
70 
71  foreach ($schemaTable->getIndexes() as $index) {
72  $indexNameWithoutPrefix = $index->getNameWithoutPrefix();
73  if (isset($whitelistTables[$tableNameWithoutPrefix][Index::TYPE][$indexNameWithoutPrefix])) {
74  continue;
75  }
76 
77  $undeclaredElements[$tableNameWithoutPrefix][Index::TYPE][] = $indexNameWithoutPrefix;
78  }
79  }
80 
81  $undeclaredElements = $this->filterUndeclaredElements($undeclaredElements);
82 
83  if (!empty($undeclaredElements)) {
84  $resultMessage .= json_encode($undeclaredElements, JSON_PRETTY_PRINT);
85  }
86 
87  $this->assertEmpty($undeclaredElements, $resultMessage);
88  }
89 
96  private function filterUndeclaredElements(array $undeclaredElements): array
97  {
98  $files = Files::getFiles([__DIR__ . '/_files/ignore_whitelisting'], '*.json');
99  $ignoredElements = [];
100  foreach ($files as $filePath) {
101  $ignoredElements = array_merge_recursive(
102  $ignoredElements,
103  json_decode(file_get_contents($filePath), true)
104  );
105  }
106 
107  return $this->arrayRecursiveDiff($undeclaredElements, $ignoredElements);
108  }
109 
117  private function arrayRecursiveDiff(array $array1, array $array2): array
118  {
119  $diffResult = [];
120 
121  foreach ($array1 as $key => $value) {
122  if (array_key_exists($key, $array2)) {
123  if (is_array($value)) {
124  $recursiveDiffResult = $this->arrayRecursiveDiff($value, $array2[$key]);
125  if (count($recursiveDiffResult)) {
126  $diffResult[$key] = $recursiveDiffResult;
127  }
128  } else {
129  if (!in_array($value, $array2)) {
130  $diffResult[] = $value;
131  }
132  }
133  } else {
134  $diffResult[$key] = $value;
135  }
136  }
137 
138  return $diffResult;
139  }
140 
144  private function getWhiteListTables(): array
145  {
146  $whiteListTables = [];
147 
148  foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $path) {
149  $whiteListPath = $path . DIRECTORY_SEPARATOR . 'etc' .
150  DIRECTORY_SEPARATOR . 'db_schema_whitelist.json';
151 
152  if (file_exists($whiteListPath)) {
153  $whiteListTables = array_replace_recursive(
154  $whiteListTables,
155  json_decode(file_get_contents($whiteListPath), true)
156  );
157  }
158  }
159 
160  return $whiteListTables;
161  }
162 }
$objectManager
Definition: bootstrap.php:17
defined('TESTS_BP')||define('TESTS_BP' __DIR__
Definition: _bootstrap.php:60
$value
Definition: gender.phtml:16
static getFiles(array $dirPatterns, $fileNamePattern, $recursive=true)
Definition: Files.php:1306
$index
Definition: list.phtml:44
foreach($appDirs as $dir) $files