7d37bc49099b1e9d46ee44319dd853eaa42b32d3
[yaffs-website] / web / core / modules / config / tests / src / Functional / ConfigImportAllTest.php
1 <?php
2
3 namespace Drupal\Tests\config\Functional;
4
5 use Drupal\Core\Config\StorageComparer;
6 use Drupal\Core\Entity\ContentEntityTypeInterface;
7 use Drupal\Tests\SchemaCheckTestTrait;
8 use Drupal\Tests\system\Functional\Module\ModuleTestBase;
9
10 /**
11  * Tests the largest configuration import possible with all available modules.
12  *
13  * @group config
14  */
15 class ConfigImportAllTest extends ModuleTestBase {
16
17   use SchemaCheckTestTrait;
18
19   /**
20    * A user with the 'synchronize configuration' permission.
21    *
22    * @var \Drupal\user\UserInterface
23    */
24   protected $webUser;
25
26   /**
27    * The profile to install as a basis for testing.
28    *
29    * Using the standard profile as this has a lot of additional configuration.
30    *
31    * @var string
32    */
33   protected $profile = 'standard';
34
35   protected function setUp() {
36     parent::setUp();
37
38     $this->webUser = $this->drupalCreateUser(['synchronize configuration']);
39     $this->drupalLogin($this->webUser);
40   }
41
42   /**
43    * Tests that a fixed set of modules can be installed and uninstalled.
44    */
45   public function testInstallUninstall() {
46
47     // Get a list of modules to enable.
48     $all_modules = system_rebuild_module_data();
49     $all_modules = array_filter($all_modules, function ($module) {
50       // Filter contrib, hidden, already enabled modules and modules in the
51       // Testing package.
52       if ($module->origin !== 'core' || !empty($module->info['hidden']) || $module->status == TRUE || $module->info['package'] == 'Testing') {
53         return FALSE;
54       }
55       return TRUE;
56     });
57
58     // Install every module possible.
59     \Drupal::service('module_installer')->install(array_keys($all_modules));
60
61     $this->assertModules(array_keys($all_modules), TRUE);
62     foreach ($all_modules as $module => $info) {
63       $this->assertModuleConfig($module);
64       $this->assertModuleTablesExist($module);
65     }
66
67     // Export active config to sync.
68     $this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.sync'));
69
70     system_list_reset();
71     $this->resetAll();
72
73     // Delete all entities provided by modules that prevent uninstallation. For
74     // example, if any content entity exists its provider cannot be uninstalled.
75     // So deleting all taxonomy terms allows the Taxonomy to be uninstalled.
76     // Additionally, every field is deleted so modules can be uninstalled. For
77     // example, if a comment field exists then Comment cannot be uninstalled.
78     $entity_type_manager = \Drupal::entityTypeManager();
79     foreach ($entity_type_manager->getDefinitions() as $entity_type) {
80       if (($entity_type instanceof ContentEntityTypeInterface || in_array($entity_type->id(), ['field_storage_config', 'filter_format'], TRUE))
81         && !in_array($entity_type->getProvider(), ['system', 'user'], TRUE)) {
82         $storage = $entity_type_manager->getStorage($entity_type->id());
83         $storage->delete($storage->loadMultiple());
84       }
85     }
86
87     // Purge the field data.
88     field_purge_batch(1000);
89
90     system_list_reset();
91     $all_modules = system_rebuild_module_data();
92
93     // Ensure that only core required modules and the install profile can not be uninstalled.
94     $validation_reasons = \Drupal::service('module_installer')->validateUninstall(array_keys($all_modules));
95     $this->assertEqual(['system', 'user', 'standard'], array_keys($validation_reasons));
96
97     $modules_to_uninstall = array_filter($all_modules, function ($module) use ($validation_reasons) {
98       // Filter required and not enabled modules.
99       if (!empty($module->info['required']) || $module->status == FALSE) {
100         return FALSE;
101       }
102       return TRUE;
103     });
104
105     // Can not uninstall config and use admin/config/development/configuration!
106     unset($modules_to_uninstall['config']);
107
108     $this->assertTrue(isset($modules_to_uninstall['comment']), 'The comment module will be disabled');
109     $this->assertTrue(isset($modules_to_uninstall['file']), 'The File module will be disabled');
110     $this->assertTrue(isset($modules_to_uninstall['editor']), 'The Editor module will be disabled');
111
112     // Uninstall all modules that can be uninstalled.
113     \Drupal::service('module_installer')->uninstall(array_keys($modules_to_uninstall));
114
115     $this->assertModules(array_keys($modules_to_uninstall), FALSE);
116     foreach ($modules_to_uninstall as $module => $info) {
117       $this->assertNoModuleConfig($module);
118       $this->assertModuleTablesDoNotExist($module);
119     }
120
121     // Import the configuration thereby re-installing all the modules.
122     $this->drupalPostForm('admin/config/development/configuration', [], t('Import all'));
123     // Modules have been installed that have services.
124     $this->rebuildContainer();
125
126     // Check that there are no errors.
127     $this->assertIdentical($this->configImporter()->getErrors(), []);
128
129     // Check that all modules that were uninstalled are now reinstalled.
130     $this->assertModules(array_keys($modules_to_uninstall), TRUE);
131     foreach ($modules_to_uninstall as $module => $info) {
132       $this->assertModuleConfig($module);
133       $this->assertModuleTablesExist($module);
134     }
135
136     // Ensure that we have no configuration changes to import.
137     $storage_comparer = new StorageComparer(
138       $this->container->get('config.storage.sync'),
139       $this->container->get('config.storage'),
140       $this->container->get('config.manager')
141     );
142     $this->assertIdentical($storage_comparer->createChangelist()->getChangelist(), $storage_comparer->getEmptyChangelist());
143
144     // Now we have all configuration imported, test all of them for schema
145     // conformance. Ensures all imported default configuration is valid when
146     // all modules are enabled.
147     $names = $this->container->get('config.storage')->listAll();
148     /** @var \Drupal\Core\Config\TypedConfigManagerInterface $typed_config */
149     $typed_config = $this->container->get('config.typed');
150     foreach ($names as $name) {
151       $config = $this->config($name);
152       $this->assertConfigSchema($typed_config, $name, $config->get());
153     }
154   }
155
156 }