Pull merge.
[yaffs-website] / web / core / lib / Drupal / Core / Test / TestSetupTrait.php
1 <?php
2
3 namespace Drupal\Core\Test;
4
5 use Drupal\Core\Database\Database;
6
7 /**
8  * Provides a trait for shared test setup functionality.
9  */
10 trait TestSetupTrait {
11
12   /**
13    * An array of config object names that are excluded from schema checking.
14    *
15    * @var string[]
16    */
17   protected static $configSchemaCheckerExclusions = [
18     // Following are used to test lack of or partial schema. Where partial
19     // schema is provided, that is explicitly tested in specific tests.
20     'config_schema_test.noschema',
21     'config_schema_test.someschema',
22     'config_schema_test.schema_data_types',
23     'config_schema_test.no_schema_data_types',
24     // Used to test application of schema to filtering of configuration.
25     'config_test.dynamic.system',
26   ];
27
28   /**
29    * The dependency injection container used in the test.
30    *
31    * @var \Symfony\Component\DependencyInjection\ContainerInterface
32    */
33   protected $container;
34
35   /**
36    * The site directory of this test run.
37    *
38    * @var string
39    */
40   protected $siteDirectory = NULL;
41
42   /**
43    * The public file directory for the test environment.
44    *
45    * @see \Drupal\simpletest\TestBase::prepareEnvironment()
46    * @see \Drupal\Tests\BrowserTestBase::prepareEnvironment()
47    *
48    * @var string
49    */
50   protected $publicFilesDirectory;
51
52   /**
53    * The site directory of the original parent site.
54    *
55    * @var string
56    */
57   protected $originalSite;
58
59   /**
60    * The private file directory for the test environment.
61    *
62    * @see \Drupal\simpletest\TestBase::prepareEnvironment()
63    * @see \Drupal\Tests\BrowserTestBase::prepareEnvironment()
64    *
65    * @var string
66    */
67   protected $privateFilesDirectory;
68
69   /**
70    * The original installation profile.
71    *
72    * @var string
73    */
74   protected $originalProfile;
75
76   /**
77    * Set to TRUE to strict check all configuration saved.
78    *
79    * @see \Drupal\Core\Config\Testing\ConfigSchemaChecker
80    *
81    * @var bool
82    */
83   protected $strictConfigSchema = TRUE;
84
85   /**
86    * The DrupalKernel instance used in the test.
87    *
88    * @var \Drupal\Core\DrupalKernel
89    */
90   protected $kernel;
91
92   /**
93    * The temporary file directory for the test environment.
94    *
95    * This value has to match the temporary directory created in
96    * install_base_system() for test installs.
97    *
98    * @see \Drupal\simpletest\TestBase::prepareEnvironment()
99    * @see \Drupal\Tests\BrowserTestBase::prepareEnvironment()
100    * @see install_base_system()
101    *
102    * @var string
103    */
104   protected $tempFilesDirectory;
105
106   /**
107    * The test run ID.
108    *
109    * @var string
110    */
111   protected $testId;
112
113   /**
114    * Returns the database connection to the site running Simpletest.
115    *
116    * @return \Drupal\Core\Database\Connection
117    *   The database connection to use for inserting assertions.
118    */
119   public static function getDatabaseConnection() {
120     return TestDatabase::getConnection();
121   }
122
123   /**
124    * Generates a database prefix for running tests.
125    *
126    * The database prefix is used by prepareEnvironment() to setup a public files
127    * directory for the test to be run, which also contains the PHP error log,
128    * which is written to in case of a fatal error. Since that directory is based
129    * on the database prefix, all tests (even unit tests) need to have one, in
130    * order to access and read the error log.
131    *
132    * The generated database table prefix is used for the Drupal installation
133    * being performed for the test. It is also used as user agent HTTP header
134    * value by the cURL-based browser of WebTestBase, which is sent to the Drupal
135    * installation of the test. During early Drupal bootstrap, the user agent
136    * HTTP header is parsed, and if it matches, all database queries use the
137    * database table prefix that has been generated here.
138    *
139    * @see \Drupal\Tests\BrowserTestBase::prepareEnvironment()
140    * @see \Drupal\simpletest\WebTestBase::curlInitialize()
141    * @see \Drupal\simpletest\TestBase::prepareEnvironment()
142    * @see drupal_valid_test_ua()
143    */
144   protected function prepareDatabasePrefix() {
145     $test_db = new TestDatabase();
146     $this->siteDirectory = $test_db->getTestSitePath();
147     $this->databasePrefix = $test_db->getDatabasePrefix();
148   }
149
150   /**
151    * Changes the database connection to the prefixed one.
152    */
153   protected function changeDatabasePrefix() {
154     if (empty($this->databasePrefix)) {
155       $this->prepareDatabasePrefix();
156     }
157
158     // If the test is run with argument dburl then use it.
159     $db_url = getenv('SIMPLETEST_DB');
160     if (!empty($db_url)) {
161       // Ensure no existing database gets in the way. If a default database
162       // exists already it must be removed.
163       Database::removeConnection('default');
164       $database = Database::convertDbUrlToConnectionInfo($db_url, isset($this->root) ? $this->root : DRUPAL_ROOT);
165       Database::addConnectionInfo('default', 'default', $database);
166     }
167
168     // Clone the current connection and replace the current prefix.
169     $connection_info = Database::getConnectionInfo('default');
170     if (is_null($connection_info)) {
171       throw new \InvalidArgumentException('There is no database connection so no tests can be run. You must provide a SIMPLETEST_DB environment variable to run PHPUnit based functional tests outside of run-tests.sh.');
172     }
173     else {
174       Database::renameConnection('default', 'simpletest_original_default');
175       foreach ($connection_info as $target => $value) {
176         // Replace the full table prefix definition to ensure that no table
177         // prefixes of the test runner leak into the test.
178         $connection_info[$target]['prefix'] = [
179           'default' => $value['prefix']['default'] . $this->databasePrefix,
180         ];
181       }
182       Database::addConnectionInfo('default', 'default', $connection_info['default']);
183     }
184   }
185
186   /**
187    * Gets the config schema exclusions for this test.
188    *
189    * @return string[]
190    *   An array of config object names that are excluded from schema checking.
191    */
192   protected function getConfigSchemaExclusions() {
193     $class = get_class($this);
194     $exceptions = [];
195     while ($class) {
196       if (property_exists($class, 'configSchemaCheckerExclusions')) {
197         $exceptions = array_merge($exceptions, $class::$configSchemaCheckerExclusions);
198       }
199       $class = get_parent_class($class);
200     }
201     // Filter out any duplicates.
202     return array_unique($exceptions);
203   }
204
205 }