9e473c29ff69a423b01c1608b2c30d35bec1aa33
[yaffs-website] / web / core / tests / Drupal / KernelTests / Core / Config / ConfigInstallTest.php
1 <?php
2
3 namespace Drupal\KernelTests\Core\Config;
4
5 use Drupal\Core\Config\InstallStorage;
6 use Drupal\Core\Config\PreExistingConfigException;
7 use Drupal\Core\Config\UnmetDependenciesException;
8 use Drupal\KernelTests\KernelTestBase;
9
10 /**
11  * Tests installation of configuration objects in installation functionality.
12  *
13  * @group config
14  * @see \Drupal\Core\Config\ConfigInstaller
15  */
16 class ConfigInstallTest extends KernelTestBase {
17
18   /**
19    * {@inheritdoc}
20    */
21   public static $modules = ['system'];
22
23   /**
24    * {@inheritdoc}
25    */
26   protected function setUp() {
27     parent::setUp();
28
29     // Ensure the global variable being asserted by this test does not exist;
30     // a previous test executed in this request/process might have set it.
31     unset($GLOBALS['hook_config_test']);
32   }
33
34   /**
35    * Tests module installation.
36    */
37   public function testModuleInstallation() {
38     $default_config = 'config_test.system';
39     $default_configuration_entity = 'config_test.dynamic.dotted.default';
40
41     // Verify that default module config does not exist before installation yet.
42     $config = $this->config($default_config);
43     $this->assertIdentical($config->isNew(), TRUE);
44     $config = $this->config($default_configuration_entity);
45     $this->assertIdentical($config->isNew(), TRUE);
46
47     // Ensure that schema provided by modules that are not installed is not
48     // available.
49     $this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'), 'Configuration schema for config_schema_test.someschema does not exist.');
50
51     // Install the test module.
52     $this->installModules(['config_test']);
53
54     // Verify that default module config exists.
55     \Drupal::configFactory()->reset($default_config);
56     \Drupal::configFactory()->reset($default_configuration_entity);
57     $config = $this->config($default_config);
58     $this->assertIdentical($config->isNew(), FALSE);
59     $config = $this->config($default_configuration_entity);
60     $this->assertIdentical($config->isNew(), FALSE);
61
62     // Verify that config_test API hooks were invoked for the dynamic default
63     // configuration entity.
64     $this->assertFalse(isset($GLOBALS['hook_config_test']['load']));
65     $this->assertTrue(isset($GLOBALS['hook_config_test']['presave']));
66     $this->assertTrue(isset($GLOBALS['hook_config_test']['insert']));
67     $this->assertFalse(isset($GLOBALS['hook_config_test']['update']));
68     $this->assertFalse(isset($GLOBALS['hook_config_test']['predelete']));
69     $this->assertFalse(isset($GLOBALS['hook_config_test']['delete']));
70
71     // Install the schema test module.
72     $this->enableModules(['config_schema_test']);
73     $this->installConfig(['config_schema_test']);
74
75     // After module installation the new schema should exist.
76     $this->assertTrue(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'), 'Configuration schema for config_schema_test.someschema exists.');
77
78     // Test that uninstalling configuration removes configuration schema.
79     $this->config('core.extension')->set('module', [])->save();
80     \Drupal::service('config.manager')->uninstall('module', 'config_test');
81     $this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'), 'Configuration schema for config_schema_test.someschema does not exist.');
82   }
83
84   /**
85    * Tests that collections are ignored if the event does not return anything.
86    */
87   public function testCollectionInstallationNoCollections() {
88     // Install the test module.
89     $this->enableModules(['config_collection_install_test']);
90     $this->installConfig(['config_collection_install_test']);
91     /** @var \Drupal\Core\Config\StorageInterface $active_storage */
92     $active_storage = \Drupal::service('config.storage');
93     $this->assertEqual([], $active_storage->getAllCollectionNames());
94   }
95
96   /**
97    * Tests config objects in collections are installed as expected.
98    */
99   public function testCollectionInstallationCollections() {
100     $collections = [
101       'another_collection',
102       'collection.test1',
103       'collection.test2',
104     ];
105     // Set the event listener to return three possible collections.
106     // @see \Drupal\config_collection_install_test\EventSubscriber
107     \Drupal::state()->set('config_collection_install_test.collection_names', $collections);
108     // Install the test module.
109     $this->enableModules(['config_collection_install_test']);
110     $this->installConfig(['config_collection_install_test']);
111     /** @var \Drupal\Core\Config\StorageInterface $active_storage */
112     $active_storage = \Drupal::service('config.storage');
113     $this->assertEqual($collections, $active_storage->getAllCollectionNames());
114     foreach ($collections as $collection) {
115       $collection_storage = $active_storage->createCollection($collection);
116       $data = $collection_storage->read('config_collection_install_test.test');
117       $this->assertEqual($collection, $data['collection']);
118     }
119
120     // Tests that clashing configuration in collections is detected.
121     try {
122       \Drupal::service('module_installer')->install(['config_collection_clash_install_test']);
123       $this->fail('Expected PreExistingConfigException not thrown.');
124     }
125     catch (PreExistingConfigException $e) {
126       $this->assertEqual($e->getExtension(), 'config_collection_clash_install_test');
127       $this->assertEqual($e->getConfigObjects(), [
128         'another_collection' => ['config_collection_install_test.test'],
129         'collection.test1' => ['config_collection_install_test.test'],
130         'collection.test2' => ['config_collection_install_test.test'],
131       ]);
132       $this->assertEqual($e->getMessage(), 'Configuration objects (another_collection/config_collection_install_test.test, collection/test1/config_collection_install_test.test, collection/test2/config_collection_install_test.test) provided by config_collection_clash_install_test already exist in active configuration');
133     }
134
135     // Test that the we can use the config installer to install all the
136     // available default configuration in a particular collection for enabled
137     // extensions.
138     \Drupal::service('config.installer')->installCollectionDefaultConfig('entity');
139     // The 'entity' collection will not exist because the 'config_test' module
140     // is not enabled.
141     $this->assertEqual($collections, $active_storage->getAllCollectionNames());
142     // Enable the 'config_test' module and try again.
143     $this->enableModules(['config_test']);
144     \Drupal::service('config.installer')->installCollectionDefaultConfig('entity');
145     $collections[] = 'entity';
146     $this->assertEqual($collections, $active_storage->getAllCollectionNames());
147     $collection_storage = $active_storage->createCollection('entity');
148     $data = $collection_storage->read('config_test.dynamic.dotted.default');
149     $this->assertSame(['label' => 'entity'], $data);
150
151     // Test that the config manager uninstalls configuration from collections
152     // as expected.
153     \Drupal::service('config.manager')->uninstall('module', 'config_collection_install_test');
154     $this->assertEqual(['entity'], $active_storage->getAllCollectionNames());
155     \Drupal::service('config.manager')->uninstall('module', 'config_test');
156     $this->assertEqual([], $active_storage->getAllCollectionNames());
157   }
158
159   /**
160    * Tests collections which do not support config entities install correctly.
161    *
162    * Config entity detection during config installation is done by matching
163    * config name prefixes. If a collection provides a configuration with a
164    * matching name but does not support config entities it should be created
165    * using simple configuration.
166    */
167   public function testCollectionInstallationCollectionConfigEntity() {
168     $collections = [
169       'entity',
170     ];
171     \Drupal::state()->set('config_collection_install_test.collection_names', $collections);
172     // Install the test module.
173     $this->installModules(['config_test', 'config_collection_install_test']);
174     /** @var \Drupal\Core\Config\StorageInterface $active_storage */
175     $active_storage = \Drupal::service('config.storage');
176     $this->assertEqual($collections, $active_storage->getAllCollectionNames());
177     $collection_storage = $active_storage->createCollection('entity');
178
179     // The config_test.dynamic.dotted.default configuration object saved in the
180     // active store should be a configuration entity complete with UUID. Because
181     // the entity collection does not support configuration entities the
182     // configuration object stored there with the same name should only contain
183     // a label.
184     $name = 'config_test.dynamic.dotted.default';
185     $data = $active_storage->read($name);
186     $this->assertTrue(isset($data['uuid']));
187     $data = $collection_storage->read($name);
188     $this->assertSame(['label' => 'entity'], $data);
189   }
190
191   /**
192    * Tests the configuration with unmet dependencies is not installed.
193    */
194   public function testDependencyChecking() {
195     $this->installModules(['config_test']);
196     try {
197       $this->installModules(['config_install_dependency_test']);
198       $this->fail('Expected UnmetDependenciesException not thrown.');
199     }
200     catch (UnmetDependenciesException $e) {
201       $this->assertEqual($e->getExtension(), 'config_install_dependency_test');
202       $this->assertEqual($e->getConfigObjects(), ['config_test.dynamic.other_module_test_with_dependency' => ['config_other_module_config_test', 'config_test.dynamic.dotted.english']]);
203       $this->assertEqual($e->getMessage(), 'Configuration objects provided by <em class="placeholder">config_install_dependency_test</em> have unmet dependencies: <em class="placeholder">config_test.dynamic.other_module_test_with_dependency (config_other_module_config_test, config_test.dynamic.dotted.english)</em>');
204     }
205     try {
206       $this->installModules(['config_install_double_dependency_test']);
207       $this->fail('Expected UnmetDependenciesException not thrown.');
208     }
209     catch (UnmetDependenciesException $e) {
210       $this->assertEquals('config_install_double_dependency_test', $e->getExtension());
211       $this->assertEquals(['config_test.dynamic.other_module_test_with_dependency' => ['config_other_module_config_test', 'config_test.dynamic.dotted.english']], $e->getConfigObjects());
212       $this->assertEquals('Configuration objects provided by <em class="placeholder">config_install_double_dependency_test</em> have unmet dependencies: <em class="placeholder">config_test.dynamic.other_module_test_with_dependency (config_other_module_config_test, config_test.dynamic.dotted.english)</em>', $e->getMessage());
213     }
214     $this->installModules(['config_test_language']);
215     try {
216       $this->installModules(['config_install_dependency_test']);
217       $this->fail('Expected UnmetDependenciesException not thrown.');
218     }
219     catch (UnmetDependenciesException $e) {
220       $this->assertEqual($e->getExtension(), 'config_install_dependency_test');
221       $this->assertEqual($e->getConfigObjects(), ['config_test.dynamic.other_module_test_with_dependency' => ['config_other_module_config_test']]);
222       $this->assertEqual($e->getMessage(), 'Configuration objects provided by <em class="placeholder">config_install_dependency_test</em> have unmet dependencies: <em class="placeholder">config_test.dynamic.other_module_test_with_dependency (config_other_module_config_test)</em>');
223     }
224     $this->installModules(['config_other_module_config_test']);
225     $this->installModules(['config_install_dependency_test']);
226     $entity = \Drupal::entityManager()->getStorage('config_test')->load('other_module_test_with_dependency');
227     $this->assertTrue($entity, 'The config_test.dynamic.other_module_test_with_dependency configuration has been created during install.');
228     // Ensure that dependencies can be added during module installation by
229     // hooks.
230     $this->assertSame('config_install_dependency_test', $entity->getDependencies()['module'][0]);
231   }
232
233   /**
234    * Tests imported configuration entities with and without language information.
235    */
236   public function testLanguage() {
237     $this->installModules(['config_test_language']);
238     // Test imported configuration with implicit language code.
239     $storage = new InstallStorage();
240     $data = $storage->read('config_test.dynamic.dotted.english');
241     $this->assertTrue(!isset($data['langcode']));
242     $this->assertEqual(
243       $this->config('config_test.dynamic.dotted.english')->get('langcode'),
244       'en'
245     );
246
247     // Test imported configuration with explicit language code.
248     $data = $storage->read('config_test.dynamic.dotted.french');
249     $this->assertEqual($data['langcode'], 'fr');
250     $this->assertEqual(
251       $this->config('config_test.dynamic.dotted.french')->get('langcode'),
252       'fr'
253     );
254   }
255
256   /**
257    * Installs a module.
258    *
259    * @param array $modules
260    *   The module names.
261    */
262   protected function installModules(array $modules) {
263     $this->container->get('module_installer')->install($modules);
264     $this->container = \Drupal::getContainer();
265   }
266
267 }