0fc78caa953ae01a1fd8d1425aae6a827ac65372
[yaffs-website] / web / core / modules / system / tests / src / Functional / Module / DependencyTest.php
1 <?php
2
3 namespace Drupal\Tests\system\Functional\Module;
4
5 use Drupal\Component\Utility\Unicode;
6
7 /**
8  * Enable module without dependency enabled.
9  *
10  * @group Module
11  */
12 class DependencyTest extends ModuleTestBase {
13   /**
14    * Checks functionality of project namespaces for dependencies.
15    */
16   public function testProjectNamespaceForDependencies() {
17     $edit = [
18       'modules[filter][enable]' => TRUE,
19     ];
20     $this->drupalPostForm('admin/modules', $edit, t('Install'));
21     // Enable module with project namespace to ensure nothing breaks.
22     $edit = [
23       'modules[system_project_namespace_test][enable]' => TRUE,
24     ];
25     $this->drupalPostForm('admin/modules', $edit, t('Install'));
26     $this->assertModules(['system_project_namespace_test'], TRUE);
27   }
28
29   /**
30    * Attempts to enable the Content Translation module without Language enabled.
31    */
32   public function testEnableWithoutDependency() {
33     // Attempt to enable Content Translation without Language enabled.
34     $edit = [];
35     $edit['modules[content_translation][enable]'] = 'content_translation';
36     $this->drupalPostForm('admin/modules', $edit, t('Install'));
37     $this->assertText(t('Some required modules must be enabled'), 'Dependency required.');
38
39     $this->assertModules(['content_translation', 'language'], FALSE);
40
41     // Assert that the language tables weren't enabled.
42     $this->assertTableCount('language', FALSE);
43
44     $this->drupalPostForm(NULL, NULL, t('Continue'));
45     $this->assertText(t('2 modules have been enabled: Content Translation, Language.'), 'Modules status has been updated.');
46     $this->assertModules(['content_translation', 'language'], TRUE);
47
48     // Assert that the language YAML files were created.
49     $storage = $this->container->get('config.storage');
50     $this->assertTrue(count($storage->listAll('language.entity.')) > 0, 'Language config entity files exist.');
51   }
52
53   /**
54    * Attempts to enable a module with a missing dependency.
55    */
56   public function testMissingModules() {
57     // Test that the system_dependencies_test module is marked
58     // as missing a dependency.
59     $this->drupalGet('admin/modules');
60     $this->assertRaw(t('@module (<span class="admin-missing">missing</span>)', ['@module' => Unicode::ucfirst('_missing_dependency')]), 'A module with missing dependencies is marked as such.');
61     $checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[system_dependencies_test][enable]"]');
62     $this->assert(count($checkbox) == 1, 'Checkbox for the module is disabled.');
63   }
64
65   /**
66    * Tests enabling a module that depends on an incompatible version of a module.
67    */
68   public function testIncompatibleModuleVersionDependency() {
69     // Test that the system_incompatible_module_version_dependencies_test is
70     // marked as having an incompatible dependency.
71     $this->drupalGet('admin/modules');
72     $this->assertRaw(t('@module (<span class="admin-missing">incompatible with</span> version @version)', [
73       '@module' => 'System incompatible module version test (>2.0)',
74       '@version' => '1.0',
75     ]), 'A module that depends on an incompatible version of a module is marked as such.');
76     $checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[system_incompatible_module_version_dependencies_test][enable]"]');
77     $this->assert(count($checkbox) == 1, 'Checkbox for the module is disabled.');
78   }
79
80   /**
81    * Tests enabling a module that depends on a module with an incompatible core version.
82    */
83   public function testIncompatibleCoreVersionDependency() {
84     // Test that the system_incompatible_core_version_dependencies_test is
85     // marked as having an incompatible dependency.
86     $this->drupalGet('admin/modules');
87     $this->assertRaw(t('@module (<span class="admin-missing">incompatible with</span> this version of Drupal core)', [
88       '@module' => 'System incompatible core version test',
89     ]), 'A module that depends on a module with an incompatible core version is marked as such.');
90     $checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[system_incompatible_core_version_dependencies_test][enable]"]');
91     $this->assert(count($checkbox) == 1, 'Checkbox for the module is disabled.');
92   }
93
94   /**
95    * Tests failing PHP version requirements.
96    */
97   public function testIncompatiblePhpVersionDependency() {
98     $this->drupalGet('admin/modules');
99     $this->assertRaw('This module requires PHP version 6502.* and is incompatible with PHP version ' . phpversion() . '.', 'User is informed when the PHP dependency requirement of a module is not met.');
100     $checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[system_incompatible_php_version_test][enable]"]');
101     $this->assert(count($checkbox) == 1, 'Checkbox for the module is disabled.');
102   }
103
104   /**
105    * Tests enabling a module that depends on a module which fails hook_requirements().
106    */
107   public function testEnableRequirementsFailureDependency() {
108     \Drupal::service('module_installer')->install(['comment']);
109
110     $this->assertModules(['requirements1_test'], FALSE);
111     $this->assertModules(['requirements2_test'], FALSE);
112
113     // Attempt to install both modules at the same time.
114     $edit = [];
115     $edit['modules[requirements1_test][enable]'] = 'requirements1_test';
116     $edit['modules[requirements2_test][enable]'] = 'requirements2_test';
117     $this->drupalPostForm('admin/modules', $edit, t('Install'));
118
119     // Makes sure the modules were NOT installed.
120     $this->assertText(t('Requirements 1 Test failed requirements'), 'Modules status has been updated.');
121     $this->assertModules(['requirements1_test'], FALSE);
122     $this->assertModules(['requirements2_test'], FALSE);
123
124     // Makes sure that already enabled modules the failing modules depend on
125     // were not disabled.
126     $this->assertModules(['comment'], TRUE);
127   }
128
129   /**
130    * Tests that module dependencies are enabled in the correct order in the UI.
131    *
132    * Dependencies should be enabled before their dependents.
133    */
134   public function testModuleEnableOrder() {
135     \Drupal::service('module_installer')->install(['module_test'], FALSE);
136     $this->resetAll();
137     $this->assertModules(['module_test'], TRUE);
138     \Drupal::state()->set('module_test.dependency', 'dependency');
139     // module_test creates a dependency chain:
140     // - color depends on config
141     // - config depends on help
142     $expected_order = ['help', 'config', 'color'];
143
144     // Enable the modules through the UI, verifying that the dependency chain
145     // is correct.
146     $edit = [];
147     $edit['modules[color][enable]'] = 'color';
148     $this->drupalPostForm('admin/modules', $edit, t('Install'));
149     $this->assertModules(['color'], FALSE);
150     // Note that dependencies are sorted alphabetically in the confirmation
151     // message.
152     $this->assertText(t('You must enable the Configuration Manager, Help modules to install Color.'));
153
154     $edit['modules[config][enable]'] = 'config';
155     $edit['modules[help][enable]'] = 'help';
156     $this->drupalPostForm('admin/modules', $edit, t('Install'));
157     $this->assertModules(['color', 'config', 'help'], TRUE);
158
159     // Check the actual order which is saved by module_test_modules_enabled().
160     $module_order = \Drupal::state()->get('module_test.install_order') ?: [];
161     $this->assertIdentical($module_order, $expected_order);
162   }
163
164   /**
165    * Tests attempting to uninstall a module that has installed dependents.
166    */
167   public function testUninstallDependents() {
168     // Enable the forum module.
169     $edit = ['modules[forum][enable]' => 'forum'];
170     $this->drupalPostForm('admin/modules', $edit, t('Install'));
171     $this->drupalPostForm(NULL, [], t('Continue'));
172     $this->assertModules(['forum'], TRUE);
173
174     // Check that the comment module cannot be uninstalled.
175     $this->drupalGet('admin/modules/uninstall');
176     $checkbox = $this->xpath('//input[@type="checkbox" and @name="uninstall[comment]" and @disabled="disabled"]');
177     $this->assert(count($checkbox) == 1, 'Checkbox for uninstalling the comment module is disabled.');
178
179     // Delete any forum terms.
180     $vid = $this->config('forum.settings')->get('vocabulary');
181     // Ensure taxonomy has been loaded into the test-runner after forum was
182     // enabled.
183     \Drupal::moduleHandler()->load('taxonomy');
184     $terms = entity_load_multiple_by_properties('taxonomy_term', ['vid' => $vid]);
185     foreach ($terms as $term) {
186       $term->delete();
187     }
188     // Uninstall the forum module, and check that taxonomy now can also be
189     // uninstalled.
190     $edit = ['uninstall[forum]' => 'forum'];
191     $this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall'));
192     $this->drupalPostForm(NULL, NULL, t('Uninstall'));
193     $this->assertText(t('The selected modules have been uninstalled.'), 'Modules status has been updated.');
194
195     // Uninstall comment module.
196     $edit = ['uninstall[comment]' => 'comment'];
197     $this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall'));
198     $this->drupalPostForm(NULL, NULL, t('Uninstall'));
199     $this->assertText(t('The selected modules have been uninstalled.'), 'Modules status has been updated.');
200   }
201
202 }