KernelTestBaseTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. <?php
  2. namespace Drupal\KernelTests;
  3. use Drupal\Component\FileCache\FileCacheFactory;
  4. use Drupal\Core\Database\Database;
  5. use org\bovigo\vfs\vfsStream;
  6. use org\bovigo\vfs\visitor\vfsStreamStructureVisitor;
  7. /**
  8. * @coversDefaultClass \Drupal\KernelTests\KernelTestBase
  9. *
  10. * @group PHPUnit
  11. * @group Test
  12. * @group KernelTests
  13. */
  14. class KernelTestBaseTest extends KernelTestBase {
  15. /**
  16. * @covers ::setUpBeforeClass
  17. */
  18. public function testSetUpBeforeClass() {
  19. // Note: PHPUnit automatically restores the original working directory.
  20. $this->assertSame(realpath(__DIR__ . '/../../../../'), getcwd());
  21. }
  22. /**
  23. * @covers ::bootEnvironment
  24. */
  25. public function testBootEnvironment() {
  26. $this->assertRegExp('/^test\d{8}$/', $this->databasePrefix);
  27. $this->assertStringStartsWith('vfs://root/sites/simpletest/', $this->siteDirectory);
  28. $this->assertEquals([
  29. 'root' => [
  30. 'sites' => [
  31. 'simpletest' => [
  32. substr($this->databasePrefix, 4) => [
  33. 'files' => [
  34. 'config' => [
  35. 'sync' => [],
  36. ],
  37. ],
  38. ],
  39. ],
  40. ],
  41. ],
  42. ], vfsStream::inspect(new vfsStreamStructureVisitor())->getStructure());
  43. }
  44. /**
  45. * @covers ::getDatabaseConnectionInfo
  46. */
  47. public function testGetDatabaseConnectionInfoWithOutManualSetDbUrl() {
  48. $options = $this->container->get('database')->getConnectionOptions();
  49. $this->assertSame($this->databasePrefix, $options['prefix']['default']);
  50. }
  51. /**
  52. * @covers ::setUp
  53. */
  54. public function testSetUp() {
  55. $this->assertTrue($this->container->has('request_stack'));
  56. $this->assertTrue($this->container->initialized('request_stack'));
  57. $request = $this->container->get('request_stack')->getCurrentRequest();
  58. $this->assertNotEmpty($request);
  59. $this->assertEquals('/', $request->getPathInfo());
  60. $this->assertSame($request, \Drupal::request());
  61. $this->assertEquals($this, $GLOBALS['conf']['container_service_providers']['test']);
  62. $GLOBALS['destroy-me'] = TRUE;
  63. $this->assertArrayHasKey('destroy-me', $GLOBALS);
  64. $database = $this->container->get('database');
  65. $database->schema()->createTable('foo', [
  66. 'fields' => [
  67. 'number' => [
  68. 'type' => 'int',
  69. 'unsigned' => TRUE,
  70. 'not null' => TRUE,
  71. ],
  72. ],
  73. ]);
  74. $this->assertTrue($database->schema()->tableExists('foo'));
  75. // Ensure that the database tasks have been run during set up. Neither MySQL
  76. // nor SQLite make changes that are testable.
  77. if ($database->driver() == 'pgsql') {
  78. $this->assertEquals('on', $database->query("SHOW standard_conforming_strings")->fetchField());
  79. $this->assertEquals('escape', $database->query("SHOW bytea_output")->fetchField());
  80. }
  81. $this->assertNotNull(FileCacheFactory::getPrefix());
  82. }
  83. /**
  84. * @covers ::setUp
  85. * @depends testSetUp
  86. */
  87. public function testSetUpDoesNotLeak() {
  88. $this->assertArrayNotHasKey('destroy-me', $GLOBALS);
  89. // Ensure that we have a different database prefix.
  90. $schema = $this->container->get('database')->schema();
  91. $this->assertFalse($schema->tableExists('foo'));
  92. }
  93. /**
  94. * @covers ::register
  95. */
  96. public function testRegister() {
  97. // Verify that this container is identical to the actual container.
  98. $this->assertInstanceOf('Symfony\Component\DependencyInjection\ContainerInterface', $this->container);
  99. $this->assertSame($this->container, \Drupal::getContainer());
  100. // The request service should never exist.
  101. $this->assertFalse($this->container->has('request'));
  102. // Verify that there is a request stack.
  103. $request = $this->container->get('request_stack')->getCurrentRequest();
  104. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Request', $request);
  105. $this->assertSame($request, \Drupal::request());
  106. // Trigger a container rebuild.
  107. $this->enableModules(['system']);
  108. // Verify that this container is identical to the actual container.
  109. $this->assertInstanceOf('Symfony\Component\DependencyInjection\ContainerInterface', $this->container);
  110. $this->assertSame($this->container, \Drupal::getContainer());
  111. // The request service should never exist.
  112. $this->assertFalse($this->container->has('request'));
  113. // Verify that there is a request stack (and that it persisted).
  114. $new_request = $this->container->get('request_stack')->getCurrentRequest();
  115. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Request', $new_request);
  116. $this->assertSame($new_request, \Drupal::request());
  117. $this->assertSame($request, $new_request);
  118. // Ensure getting the router.route_provider does not trigger a deprecation
  119. // message that errors.
  120. $this->container->get('router.route_provider');
  121. }
  122. /**
  123. * Tests whether the fixture allows us to install modules and configuration.
  124. *
  125. * @see ::testSubsequentContainerIsolation()
  126. */
  127. public function testContainerIsolation() {
  128. $this->enableModules(['system', 'user']);
  129. $this->assertNull($this->installConfig('user'));
  130. }
  131. /**
  132. * Tests whether the fixture can re-install modules and configuration.
  133. *
  134. * @depends testContainerIsolation
  135. */
  136. public function testSubsequentContainerIsolation() {
  137. $this->enableModules(['system', 'user']);
  138. $this->assertNull($this->installConfig('user'));
  139. }
  140. /**
  141. * @covers ::render
  142. */
  143. public function testRender() {
  144. $type = 'processed_text';
  145. $element_info = $this->container->get('element_info');
  146. $this->assertSame(['#defaults_loaded' => TRUE], $element_info->getInfo($type));
  147. $this->enableModules(['filter']);
  148. $this->assertNotSame($element_info, $this->container->get('element_info'));
  149. $this->assertNotEmpty($this->container->get('element_info')->getInfo($type));
  150. $build = [
  151. '#type' => 'html_tag',
  152. '#tag' => 'h3',
  153. '#value' => 'Inner',
  154. ];
  155. $expected = "<h3>Inner</h3>\n";
  156. $this->assertEquals('core', \Drupal::theme()->getActiveTheme()->getName());
  157. $output = \Drupal::service('renderer')->renderRoot($build);
  158. $this->assertEquals('core', \Drupal::theme()->getActiveTheme()->getName());
  159. $this->assertEquals($expected, $build['#markup']);
  160. $this->assertEquals($expected, $output);
  161. }
  162. /**
  163. * @covers ::render
  164. */
  165. public function testRenderWithTheme() {
  166. $this->enableModules(['system']);
  167. $build = [
  168. '#type' => 'textfield',
  169. '#name' => 'test',
  170. ];
  171. $expected = '/' . preg_quote('<input type="text" name="test"', '/') . '/';
  172. $this->assertArrayNotHasKey('theme', $GLOBALS);
  173. $output = \Drupal::service('renderer')->renderRoot($build);
  174. $this->assertEquals('core', \Drupal::theme()->getActiveTheme()->getName());
  175. $this->assertRegExp($expected, (string) $build['#children']);
  176. $this->assertRegExp($expected, (string) $output);
  177. }
  178. /**
  179. * @covers ::bootKernel
  180. */
  181. public function testFileDefaultScheme() {
  182. $this->assertEquals('public', file_default_scheme());
  183. $this->assertEquals('public', \Drupal::config('system.file')->get('default_scheme'));
  184. }
  185. /**
  186. * Tests the assumption that local time is in 'Australia/Sydney'.
  187. */
  188. public function testLocalTimeZone() {
  189. // The 'Australia/Sydney' time zone is set in core/tests/bootstrap.php
  190. $this->assertEquals('Australia/Sydney', date_default_timezone_get());
  191. }
  192. /**
  193. * Tests that a test method is skipped when it requires a module not present.
  194. *
  195. * In order to catch checkRequirements() regressions, we have to make a new
  196. * test object and run checkRequirements() here.
  197. *
  198. * @covers ::checkRequirements
  199. * @covers ::checkModuleRequirements
  200. */
  201. public function testMethodRequiresModule() {
  202. require __DIR__ . '/../../fixtures/KernelMissingDependentModuleMethodTest.php';
  203. $stub_test = new KernelMissingDependentModuleMethodTest();
  204. // We have to setName() to the method name we're concerned with.
  205. $stub_test->setName('testRequiresModule');
  206. // We cannot use $this->setExpectedException() because PHPUnit would skip
  207. // the test before comparing the exception type.
  208. try {
  209. $stub_test->publicCheckRequirements();
  210. $this->fail('Missing required module throws skipped test exception.');
  211. }
  212. catch (\PHPUnit_Framework_SkippedTestError $e) {
  213. $this->assertEqual('Required modules: module_does_not_exist', $e->getMessage());
  214. }
  215. }
  216. /**
  217. * Tests that a test case is skipped when it requires a module not present.
  218. *
  219. * In order to catch checkRequirements() regressions, we have to make a new
  220. * test object and run checkRequirements() here.
  221. *
  222. * @covers ::checkRequirements
  223. * @covers ::checkModuleRequirements
  224. */
  225. public function testRequiresModule() {
  226. require __DIR__ . '/../../fixtures/KernelMissingDependentModuleTest.php';
  227. $stub_test = new KernelMissingDependentModuleTest();
  228. // We have to setName() to the method name we're concerned with.
  229. $stub_test->setName('testRequiresModule');
  230. // We cannot use $this->setExpectedException() because PHPUnit would skip
  231. // the test before comparing the exception type.
  232. try {
  233. $stub_test->publicCheckRequirements();
  234. $this->fail('Missing required module throws skipped test exception.');
  235. }
  236. catch (\PHPUnit_Framework_SkippedTestError $e) {
  237. $this->assertEqual('Required modules: module_does_not_exist', $e->getMessage());
  238. }
  239. }
  240. /**
  241. * {@inheritdoc}
  242. */
  243. protected function tearDown() {
  244. parent::tearDown();
  245. // Check that all tables of the test instance have been deleted. At this
  246. // point the original database connection is restored so we need to prefix
  247. // the tables.
  248. $connection = Database::getConnection();
  249. if ($connection->databaseType() != 'sqlite') {
  250. $tables = $connection->schema()->findTables($this->databasePrefix . '%');
  251. $this->assertTrue(empty($tables), 'All test tables have been removed.');
  252. }
  253. else {
  254. $result = $connection->query("SELECT name FROM " . $this->databasePrefix . ".sqlite_master WHERE type = :type AND name LIKE :table_name AND name NOT LIKE :pattern", [
  255. ':type' => 'table',
  256. ':table_name' => '%',
  257. ':pattern' => 'sqlite_%',
  258. ])->fetchAllKeyed(0, 0);
  259. $this->assertTrue(empty($result), 'All test tables have been removed.');
  260. }
  261. }
  262. /**
  263. * Ensures KernelTestBase tests can access modules in profiles.
  264. */
  265. public function testProfileModules() {
  266. $this->assertFileExists('core/profiles/demo_umami/modules/demo_umami_content/demo_umami_content.info.yml');
  267. $this->assertSame(
  268. 'core/profiles/demo_umami/modules/demo_umami_content/demo_umami_content.info.yml',
  269. \Drupal::service('extension.list.module')->getPathname('demo_umami_content')
  270. );
  271. }
  272. }