1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Test\Legacy;
use Magento\Framework\Component\ComponentRegistrar;
/**
* Tests to find usage of restricted code
*/
class RestrictedCodeTest extends \PHPUnit\Framework\TestCase
{
/**@#+
* Lists of restricted entities from fixtures
*
* @var array
*/
private static $_classes = [];
/**#@-*/
/**
* List of fixtures that contain restricted classes and should not be tested
*
* @var array
*/
private static $_fixtureFiles = [];
/**
* @var ComponentRegistrar
*/
private $componentRegistrar;
protected function setUp()
{
$this->componentRegistrar = new ComponentRegistrar();
}
/**
* Read fixtures into memory as arrays
*
* @return void
*/
public static function setUpBeforeClass()
{
self::_loadData(self::$_classes, 'restricted_classes*.php');
}
/**
* Loads and merges data from fixtures
*
* @param array $data
* @param string $filePattern
* @return void
*/
protected static function _loadData(array &$data, $filePattern)
{
foreach (glob(__DIR__ . '/_files/' . $filePattern) as $file) {
$relativePath = str_replace(
'\\',
'/',
str_replace(BP . DIRECTORY_SEPARATOR, '', $file)
);
array_push(self::$_fixtureFiles, $relativePath);
$data = array_merge_recursive($data, self::_readList($file));
}
}
/**
* Isolate including a file into a method to reduce scope
*
* @param string $file
* @return array
*/
protected static function _readList($file)
{
return include $file;
}
/**
* Test that restricted entities are not used in PHP files
*
* @return void
*/
public function testPhpFiles()
{
$invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this);
$testFiles = \Magento\TestFramework\Utility\ChangedFiles::getPhpFiles(__DIR__ . '/../_files/changed_files*');
foreach (self::$_fixtureFiles as $fixtureFile) {
if (array_key_exists($fixtureFile, $testFiles)) {
unset($testFiles[$fixtureFile]);
}
}
$invoker(
function ($file) {
$this->_testRestrictedClasses($file);
},
$testFiles
);
}
/**
* Assert that restricted classes are not used in the file
*
* @param string $file
* @return void
*/
protected function _testRestrictedClasses($file)
{
$content = file_get_contents($file);
foreach (self::$_classes as $restrictedClass => $classRules) {
foreach ($classRules['exclude'] as $skippedPathInfo) {
if (strpos($file, $this->getExcludedFilePath($skippedPathInfo)) === 0) {
continue 2;
}
}
$this->assertFalse(
\Magento\TestFramework\Utility\CodeCheck::isClassUsed($restrictedClass, $content),
sprintf(
"Class '%s' is restricted in %s. Suggested replacement: %s",
$restrictedClass,
$file,
$classRules['replacement']
)
);
}
}
/**
* Get full path for excluded file
*
* @param array $pathInfo
* @return string
*/
private function getExcludedFilePath($pathInfo)
{
if ($pathInfo['type'] != 'setup') {
return $this->componentRegistrar->getPath($pathInfo['type'], $pathInfo['name']) . '/' . $pathInfo['path'];
}
return BP . '/setup/' . $pathInfo['path'];
}
}