Skip to content

Commit 80fc704

Browse files
committed
Add TDD tests for vendor path isolation and whitelisting in FileFilter
1 parent bb9f4c1 commit 80fc704

1 file changed

Lines changed: 98 additions & 0 deletions

File tree

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
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

Comments
 (0)