Version 1
[yaffs-website] / web / core / tests / Drupal / Tests / Core / DrupalKernel / DrupalKernelTest.php
1 <?php
2
3 namespace Drupal\Tests\Core\DrupalKernel {
4
5   use Drupal\Core\DrupalKernel;
6   use Drupal\Tests\UnitTestCase;
7   use org\bovigo\vfs\vfsStream;
8   use Symfony\Component\ClassLoader\ApcClassLoader;
9   use Symfony\Component\HttpFoundation\Request;
10
11   /**
12    * @coversDefaultClass \Drupal\Core\DrupalKernel
13    * @group DrupalKernel
14    */
15   class DrupalKernelTest extends UnitTestCase {
16
17     /**
18      * Tests hostname validation with settings.
19      *
20      * @covers ::setupTrustedHosts
21      * @dataProvider providerTestTrustedHosts
22      */
23     public function testTrustedHosts($host, $server_name, $message, $expected = FALSE) {
24       $request = new Request();
25
26       $trusted_host_patterns = [
27         '^example\.com$',
28         '^.+\.example\.com$',
29         '^example\.org',
30         '^.+\.example\.org',
31       ];
32
33       if (!empty($host)) {
34         $request->headers->set('HOST', $host);
35       }
36
37       $request->server->set('SERVER_NAME', $server_name);
38
39       $method = new \ReflectionMethod('Drupal\Core\DrupalKernel', 'setupTrustedHosts');
40       $method->setAccessible(TRUE);
41       $valid_host = $method->invoke(NULL, $request, $trusted_host_patterns);
42
43       $this->assertSame($expected, $valid_host, $message);
44
45       // Reset the trusted hosts because it is statically stored on the request.
46       $method->invoke(NULL, $request, []);
47       // Reset the request factory because it is statically stored on the request.
48       Request::setFactory(NULL);
49     }
50
51     /**
52      * Tests the reregistration of autoloaders if APCu available.
53      *
54      * This test runs in a separate process since it registers class loaders and
55      * results in statics being set.
56      *
57      * @runInSeparateProcess
58      * @preserveGlobalState disabled
59      * @requires function apcu_fetch
60      * @covers ::initializeSettings
61      */
62     public function testInitializeSettings() {
63       $request = new Request();
64       $classloader = new fakeAutoloader();
65
66       // Create a kernel suitable for testing.
67       $kernel = $this->getMockBuilder(DrupalKernel::class)
68         ->disableOriginalConstructor()
69         ->setMethods(['do_not_mock_any_methods'])
70         ->getMock();
71       $classloader_property = new \ReflectionProperty($kernel, 'classLoader');
72       $classloader_property->setAccessible(TRUE);
73       $classloader_property->setValue($kernel, $classloader);
74       $method = new \ReflectionMethod($kernel, 'initializeSettings');
75       $method->setAccessible(TRUE);
76
77       // Prepend another autoloader to simulate Drush's autoloader.
78       $fake_drush_autoloader = function () {
79         return NULL;
80       };
81       spl_autoload_register($fake_drush_autoloader, TRUE, TRUE);
82
83       // Before calling DrupalKernel::initializeSettings() the first autoloader
84       // is the fake Drush autoloader.
85       $this->assertSame($fake_drush_autoloader, spl_autoload_functions()[0]);
86
87       // Call DrupalKernel::initializeSettings() to simulate part of a Drupal
88       // bootstrap. During the include of autoload.php Composer would prepend
89       // Drupal's autoloader and then this method should not result in Drush's
90       // autoloader becoming the first autoloader even if it swaps out
91       // Composer's autoloader for an optimised one.
92       $method->invoke($kernel, $request);
93
94       $autoloaders = spl_autoload_functions();
95       // The first autoloader should be the APCu based autoloader.
96       $this->assertInstanceOf(ApcClassLoader::class, $autoloaders[0][0]);
97       // The second autoloader should be the original autoloader the kernel was
98       // constructed with.
99       $this->assertSame($classloader, $autoloaders[1][0]);
100       // The third autoloader should be Drush's autoloader.
101       $this->assertSame($fake_drush_autoloader, $autoloaders[2]);
102
103       // Reset the request factory because it is statically stored on the
104       // request.
105       Request::setFactory(NULL);
106     }
107
108     /**
109      * Provides test data for testTrustedHosts().
110      */
111     public function providerTestTrustedHosts() {
112       $data = [];
113
114       // Tests canonical URL.
115       $data[] = [
116         'www.example.com',
117         'www.example.com',
118         'canonical URL is trusted',
119         TRUE
120       ];
121
122       // Tests missing hostname for HTTP/1.0 compatibility where the Host
123       // header is optional.
124       $data[] = [NULL, 'www.example.com', 'empty Host is valid', TRUE];
125
126       // Tests the additional patterns from the settings.
127       $data[] = [
128         'example.com',
129         'www.example.com',
130         'host from settings is trusted',
131         TRUE
132       ];
133       $data[] = [
134         'subdomain.example.com',
135         'www.example.com',
136         'host from settings is trusted',
137         TRUE
138       ];
139       $data[] = [
140         'www.example.org',
141         'www.example.com',
142         'host from settings is trusted',
143         TRUE
144       ];
145       $data[] = [
146         'example.org',
147         'www.example.com',
148         'host from settings is trusted',
149         TRUE
150       ];
151
152       // Tests mismatch.
153       $data[] = [
154         'www.blackhat.com',
155         'www.example.com',
156         'unspecified host is untrusted',
157         FALSE
158       ];
159
160       return $data;
161     }
162
163     /**
164      * Tests site path finding.
165      *
166      * This test is run in a separate process since it defines DRUPAL_ROOT. This
167      * stops any possible pollution of other tests.
168      *
169      * @covers ::findSitePath
170      * @runInSeparateProcess
171      */
172     public function testFindSitePath() {
173       $vfs_root = vfsStream::setup('drupal_root');
174       $sites_php = <<<'EOD'
175 <?php
176 $sites['8888.www.example.org'] = 'example';
177 EOD;
178
179       // Create the expected directory structure.
180       vfsStream::create(['sites' => [
181         'sites.php' => $sites_php,
182         'example' => [
183           'settings.php' => 'test'
184         ]
185       ]]);
186
187       $request = new Request();
188       $request->server->set('SERVER_NAME', 'www.example.org');
189       $request->server->set('SERVER_PORT', '8888');
190       $request->server->set('SCRIPT_NAME', '/index.php');
191       $this->assertEquals('sites/example', DrupalKernel::findSitePath($request, TRUE, $vfs_root->url('drupal_root')));
192       $this->assertEquals('sites/example', DrupalKernel::findSitePath($request, FALSE, $vfs_root->url('drupal_root')));
193     }
194
195   }
196
197   /**
198    * A fake autoloader for testing
199    */
200   class fakeAutoloader {
201
202     /**
203      * Registers this instance as an autoloader.
204      *
205      * @param bool $prepend
206      *   Whether to prepend the autoloader or not
207      */
208     public function register($prepend = FALSE) {
209       spl_autoload_register([$this, 'loadClass'], TRUE, $prepend);
210     }
211
212     /**
213      * Unregisters this instance as an autoloader.
214      */
215     public function unregister() {
216       spl_autoload_unregister([$this, 'loadClass']);
217     }
218
219     /**
220      * Loads the given class or interface.
221      *
222      * @return null
223      *   This class never loads.
224      */
225     public function loadClass() {
226       return NULL;
227     }
228
229     /**
230      * Finds a file by class name while caching lookups to APC.
231      *
232      * @return null
233      *   This class never finds.
234      */
235     public function findFile() {
236       return NULL;
237     }
238
239   }
240 }
241
242
243 namespace {
244   if (!function_exists('drupal_valid_test_ua')) {
245     function drupal_valid_test_ua($new_prefix = NULL) {
246       return FALSE;
247     }
248   }
249 }