1+ <?php
2+
3+ declare (strict_types=1 );
4+
5+ namespace TypePHP \Tests \Contract ;
6+
7+ use ReflectionMethod ;
8+ use TypePHP \Contract \FileFilter ;
9+ use TypePHP \Internal \Config ;
10+ use TypePHP \Internal \StreamWrapper ;
11+
12+ describe ('Vendor Path Isolation & Whitelisting (Shopware Doctrine DBAL Reproduction) ' , function () {
13+ beforeEach (function () {
14+ Config::reset ();
15+ });
16+
17+ afterEach (function () {
18+ Config::reset ();
19+ });
20+
21+ test ('strictly excludes un-whitelisted vendor files even if they contain nested src folders (Doctrine DBAL in vendor) ' , function () {
22+ Config::set ([
23+ 'include ' => [
24+ 'src/** ' ,
25+ 'app/** ' ,
26+ 'tests/** ' ,
27+ ],
28+ 'exclude ' => [
29+ 'vendor/** ' ,
30+ 'storage/** ' ,
31+ 'var/** ' ,
32+ 'cache/** ' ,
33+ ],
34+ ]);
35+
36+ StreamWrapper::register ();
37+
38+ $ projectRoot = Config::getProjectRoot ();
39+
40+ $ vendorDoctrineFile = str_replace ('\\' , '/ ' , $ projectRoot . '/vendor/doctrine/dbal/src/Schema/AbstractNamedObject.php ' );
41+
42+ $ appFile = str_replace ('\\' , '/ ' , $ projectRoot . '/app/Services/UserService.php ' );
43+
44+ expect (FileFilter::isFileExcluded ($ vendorDoctrineFile ))->toBeTrue ()
45+ ->and (FileFilter::isFileExcluded ($ appFile ))->toBeFalse ()
46+ ;
47+
48+ $ refMethod = new ReflectionMethod (StreamWrapper::class, 'isApplicationFile ' );
49+ expect ($ refMethod ->invoke (null , $ vendorDoctrineFile , $ vendorDoctrineFile ))->toBeFalse ()
50+ ->and ($ refMethod ->invoke (null , $ appFile , $ appFile ))->toBeTrue ()
51+ ;
52+ });
53+
54+ test ('allows explicitly whitelisted vendor packages while strictly excluding all other vendor files ' , function () {
55+ Config::set ([
56+ 'include ' => [
57+ 'src/** ' ,
58+ 'vendor/my-org/whitelisted-package/** ' ,
59+ ],
60+ 'exclude ' => [
61+ 'vendor/** ' ,
62+ ],
63+ ]);
64+
65+ StreamWrapper::register ();
66+
67+ $ projectRoot = Config::getProjectRoot ();
68+
69+ $ whitelistedVendorFile = str_replace ('\\' , '/ ' , $ projectRoot . '/vendor/my-org/whitelisted-package/src/Service.php ' );
70+ $ unwhitelistedVendorFile = str_replace ('\\' , '/ ' , $ projectRoot . '/vendor/doctrine/dbal/src/Schema/AbstractNamedObject.php ' );
71+
72+ expect (FileFilter::isFileExcluded ($ whitelistedVendorFile ))->toBeFalse ();
73+ expect (FileFilter::isFileExcluded ($ unwhitelistedVendorFile ))->toBeTrue ();
74+
75+ $ refMethod = new ReflectionMethod (StreamWrapper::class, 'isApplicationFile ' );
76+ expect ($ refMethod ->invoke (null , $ whitelistedVendorFile , $ whitelistedVendorFile ))->toBeTrue ()
77+ ->and ($ refMethod ->invoke (null , $ unwhitelistedVendorFile , $ unwhitelistedVendorFile ))->toBeFalse ()
78+ ;
79+ });
80+
81+ test ('strictly isolates vendor files when specific nested application subpaths are included ' , function () {
82+ Config::set ([
83+ 'include ' => [
84+ 'src/** ' ,
85+ 'src/Core/Framework/** ' ,
86+ 'src/Core/Content/** ' ,
87+ ],
88+ 'exclude ' => [
89+ 'vendor/** ' ,
90+ ],
91+ ]);
92+
93+ $ projectRoot = Config::getProjectRoot ();
94+ $ vendorFile = str_replace ('\\' , '/ ' , $ projectRoot . '/vendor/doctrine/dbal/src/Core/Table.php ' );
95+
96+ expect (FileFilter::isFileExcluded ($ vendorFile ))->toBeTrue ();
97+ });
98+ });
0 commit comments