Version 1
[yaffs-website] / web / core / modules / simpletest / src / InstallerTestBase.php
1 <?php
2
3 namespace Drupal\simpletest;
4
5 use Drupal\Core\DrupalKernel;
6 use Drupal\Core\Language\Language;
7 use Drupal\Core\Session\UserSession;
8 use Drupal\Core\Site\Settings;
9 use Symfony\Component\DependencyInjection\ContainerBuilder;
10 use Symfony\Component\DependencyInjection\Reference;
11 use Symfony\Component\HttpFoundation\Request;
12 use Symfony\Component\HttpFoundation\RequestStack;
13
14 /**
15  * Base class for testing the interactive installer.
16  */
17 abstract class InstallerTestBase extends WebTestBase {
18
19   /**
20    * Custom settings.php values to write for a test run.
21    *
22    * @var array
23    *   An array of settings to write out, in the format expected by
24    *   drupal_rewrite_settings().
25    */
26   protected $settings = [];
27
28   /**
29    * The language code in which to install Drupal.
30    *
31    * @var string
32    */
33   protected $langcode = 'en';
34
35   /**
36    * The installation profile to install.
37    *
38    * @var string
39    */
40   protected $profile = 'testing';
41
42   /**
43    * Additional parameters to use for installer screens.
44    *
45    * @see WebTestBase::installParameters()
46    *
47    * @var array
48    */
49   protected $parameters = [];
50
51   /**
52    * A string translation map used for translated installer screens.
53    *
54    * Keys are English strings, values are translated strings.
55    *
56    * @var array
57    */
58   protected $translations = [
59     'Save and continue' => 'Save and continue',
60   ];
61
62   /**
63    * Whether the installer has completed.
64    *
65    * @var bool
66    */
67   protected $isInstalled = FALSE;
68
69   /**
70    * {@inheritdoc}
71    */
72   protected function setUp() {
73     $this->isInstalled = FALSE;
74
75     // Define information about the user 1 account.
76     $this->rootUser = new UserSession([
77       'uid' => 1,
78       'name' => 'admin',
79       'mail' => 'admin@example.com',
80       'pass_raw' => $this->randomMachineName(),
81     ]);
82
83     // If any $settings are defined for this test, copy and prepare an actual
84     // settings.php, so as to resemble a regular installation.
85     if (!empty($this->settings)) {
86       // Not using File API; a potential error must trigger a PHP warning.
87       copy(DRUPAL_ROOT . '/sites/default/default.settings.php', DRUPAL_ROOT . '/' . $this->siteDirectory . '/settings.php');
88       $this->writeSettings($this->settings);
89     }
90
91     // Note that WebTestBase::installParameters() returns form input values
92     // suitable for a programmed \Drupal::formBuilder()->submitForm().
93     // @see WebTestBase::translatePostValues()
94     $this->parameters = $this->installParameters();
95
96     // Set up a minimal container (required by WebTestBase). Set cookie and
97     // server information so that XDebug works.
98     // @see install_begin_request()
99     $request = Request::create($GLOBALS['base_url'] . '/core/install.php', 'GET', [], $_COOKIE, [], $_SERVER);
100     $this->container = new ContainerBuilder();
101     $request_stack = new RequestStack();
102     $request_stack->push($request);
103     $this->container
104       ->set('request_stack', $request_stack);
105     $this->container
106       ->setParameter('language.default_values', Language::$defaultValues);
107     $this->container
108       ->register('language.default', 'Drupal\Core\Language\LanguageDefault')
109       ->addArgument('%language.default_values%');
110     $this->container
111       ->register('string_translation', 'Drupal\Core\StringTranslation\TranslationManager')
112       ->addArgument(new Reference('language.default'));
113     $this->container
114       ->set('app.root', DRUPAL_ROOT);
115     \Drupal::setContainer($this->container);
116
117     $this->visitInstaller();
118
119     // Select language.
120     $this->setUpLanguage();
121
122     // Select profile.
123     $this->setUpProfile();
124
125     // Configure settings.
126     $this->setUpSettings();
127
128     // @todo Allow test classes based on this class to act on further installer
129     //   screens.
130
131     // Configure site.
132     $this->setUpSite();
133
134     if ($this->isInstalled) {
135       // Import new settings.php written by the installer.
136       $request = Request::createFromGlobals();
137       $class_loader = require $this->container->get('app.root') . '/autoload.php';
138       Settings::initialize($this->container->get('app.root'), DrupalKernel::findSitePath($request), $class_loader);
139       foreach ($GLOBALS['config_directories'] as $type => $path) {
140         $this->configDirectories[$type] = $path;
141       }
142
143       // After writing settings.php, the installer removes write permissions
144       // from the site directory. To allow drupal_generate_test_ua() to write
145       // a file containing the private key for drupal_valid_test_ua(), the site
146       // directory has to be writable.
147       // WebTestBase::tearDown() will delete the entire test site directory.
148       // Not using File API; a potential error must trigger a PHP warning.
149       chmod($this->container->get('app.root') . '/' . $this->siteDirectory, 0777);
150       $this->kernel = DrupalKernel::createFromRequest($request, $class_loader, 'prod', FALSE);
151       $this->kernel->prepareLegacyRequest($request);
152       $this->container = $this->kernel->getContainer();
153
154       // Manually configure the test mail collector implementation to prevent
155       // tests from sending out emails and collect them in state instead.
156       $this->container->get('config.factory')
157         ->getEditable('system.mail')
158         ->set('interface.default', 'test_mail_collector')
159         ->save();
160     }
161   }
162
163   /**
164    * Visits the interactive installer.
165    */
166   protected function visitInstaller() {
167     $this->drupalGet($GLOBALS['base_url'] . '/core/install.php');
168   }
169
170   /**
171    * Installer step: Select language.
172    */
173   protected function setUpLanguage() {
174     $edit = [
175       'langcode' => $this->langcode,
176     ];
177     $this->drupalPostForm(NULL, $edit, $this->translations['Save and continue']);
178   }
179
180   /**
181    * Installer step: Select installation profile.
182    */
183   protected function setUpProfile() {
184     $edit = [
185       'profile' => $this->profile,
186     ];
187     $this->drupalPostForm(NULL, $edit, $this->translations['Save and continue']);
188   }
189
190   /**
191    * Installer step: Configure settings.
192    */
193   protected function setUpSettings() {
194     $edit = $this->translatePostValues($this->parameters['forms']['install_settings_form']);
195     $this->drupalPostForm(NULL, $edit, $this->translations['Save and continue']);
196   }
197
198   /**
199    * Final installer step: Configure site.
200    */
201   protected function setUpSite() {
202     $edit = $this->translatePostValues($this->parameters['forms']['install_configure_form']);
203     $this->drupalPostForm(NULL, $edit, $this->translations['Save and continue']);
204     // If we've got to this point the site is installed using the regular
205     // installation workflow.
206     $this->isInstalled = TRUE;
207   }
208
209   /**
210    * {@inheritdoc}
211    *
212    * WebTestBase::refreshVariables() tries to operate on persistent storage,
213    * which is only available after the installer completed.
214    */
215   protected function refreshVariables() {
216     if ($this->isInstalled) {
217       parent::refreshVariables();
218     }
219   }
220
221 }