3 namespace Drupal\config\Tests;
5 use Drupal\Core\Config\StorageComparer;
6 use Drupal\filter\Entity\FilterFormat;
7 use Drupal\system\Tests\Module\ModuleTestBase;
8 use Drupal\shortcut\Entity\Shortcut;
9 use Drupal\taxonomy\Entity\Term;
12 * Tests the largest configuration import possible with all available modules.
16 class ConfigImportAllTest extends ModuleTestBase {
18 use SchemaCheckTestTrait;
21 * A user with the 'synchronize configuration' permission.
23 * @var \Drupal\user\UserInterface
28 * The profile to install as a basis for testing.
30 * Using the standard profile as this has a lot of additional configuration.
34 protected $profile = 'standard';
36 protected function setUp() {
39 $this->webUser = $this->drupalCreateUser(['synchronize configuration']);
40 $this->drupalLogin($this->webUser);
44 * Tests that a fixed set of modules can be installed and uninstalled.
46 public function testInstallUninstall() {
48 // Get a list of modules to enable.
49 $all_modules = system_rebuild_module_data();
50 $all_modules = array_filter($all_modules, function ($module) {
51 // Filter contrib, hidden, already enabled modules and modules in the
53 if ($module->origin !== 'core' || !empty($module->info['hidden']) || $module->status == TRUE || $module->info['package'] == 'Testing') {
59 // Install every module possible.
60 \Drupal::service('module_installer')->install(array_keys($all_modules));
62 $this->assertModules(array_keys($all_modules), TRUE);
63 foreach ($all_modules as $module => $info) {
64 $this->assertModuleConfig($module);
65 $this->assertModuleTablesExist($module);
68 // Export active config to sync.
69 $this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.sync'));
74 // Delete every field on the site so all modules can be uninstalled. For
75 // example, if a comment field exists then module becomes required and can
76 // not be uninstalled.
78 $field_storages = \Drupal::entityManager()->getStorage('field_storage_config')->loadMultiple();
79 \Drupal::entityManager()->getStorage('field_storage_config')->delete($field_storages);
81 field_purge_batch(1000);
84 $terms = Term::loadMultiple();
85 entity_delete_multiple('taxonomy_term', array_keys($terms));
87 // Delete all filter formats.
88 $filters = FilterFormat::loadMultiple();
89 entity_delete_multiple('filter_format', array_keys($filters));
91 // Delete any shortcuts so the shortcut module can be uninstalled.
92 $shortcuts = Shortcut::loadMultiple();
93 entity_delete_multiple('shortcut', array_keys($shortcuts));
96 $all_modules = system_rebuild_module_data();
98 // Ensure that only core required modules and the install profile can not be uninstalled.
99 $validation_reasons = \Drupal::service('module_installer')->validateUninstall(array_keys($all_modules));
100 $this->assertEqual(['standard', 'system', 'user'], array_keys($validation_reasons));
102 $modules_to_uninstall = array_filter($all_modules, function ($module) use ($validation_reasons) {
103 // Filter required and not enabled modules.
104 if (!empty($module->info['required']) || $module->status == FALSE) {
110 // Can not uninstall config and use admin/config/development/configuration!
111 unset($modules_to_uninstall['config']);
113 $this->assertTrue(isset($modules_to_uninstall['comment']), 'The comment module will be disabled');
114 $this->assertTrue(isset($modules_to_uninstall['file']), 'The File module will be disabled');
115 $this->assertTrue(isset($modules_to_uninstall['editor']), 'The Editor module will be disabled');
117 // Uninstall all modules that can be uninstalled.
118 \Drupal::service('module_installer')->uninstall(array_keys($modules_to_uninstall));
120 $this->assertModules(array_keys($modules_to_uninstall), FALSE);
121 foreach ($modules_to_uninstall as $module => $info) {
122 $this->assertNoModuleConfig($module);
123 $this->assertModuleTablesDoNotExist($module);
126 // Import the configuration thereby re-installing all the modules.
127 $this->drupalPostForm('admin/config/development/configuration', [], t('Import all'));
128 // Modules have been installed that have services.
129 $this->rebuildContainer();
131 // Check that there are no errors.
132 $this->assertIdentical($this->configImporter()->getErrors(), []);
134 // Check that all modules that were uninstalled are now reinstalled.
135 $this->assertModules(array_keys($modules_to_uninstall), TRUE);
136 foreach ($modules_to_uninstall as $module => $info) {
137 $this->assertModuleConfig($module);
138 $this->assertModuleTablesExist($module);
141 // Ensure that we have no configuration changes to import.
142 $storage_comparer = new StorageComparer(
143 $this->container->get('config.storage.sync'),
144 $this->container->get('config.storage'),
145 $this->container->get('config.manager')
147 $this->assertIdentical($storage_comparer->createChangelist()->getChangelist(), $storage_comparer->getEmptyChangelist());
149 // Now we have all configuration imported, test all of them for schema
150 // conformance. Ensures all imported default configuration is valid when
151 // all modules are enabled.
152 $names = $this->container->get('config.storage')->listAll();
153 /** @var \Drupal\Core\Config\TypedConfigManagerInterface $typed_config */
154 $typed_config = $this->container->get('config.typed');
155 foreach ($names as $name) {
156 $config = $this->config($name);
157 $this->assertConfigSchema($typed_config, $name, $config->get());