Projet

Général

Profil

Paste
Télécharger (14,6 ko) Statistiques
| Branche: | Révision:

root / drupal7 / modules / simpletest / tests / module.test @ 76597ebf

1
<?php
2

    
3
/**
4
 * @file
5
 * Tests for the module API.
6
 */
7

    
8
/**
9
 * Unit tests for the module API.
10
 */
11
class ModuleUnitTest extends DrupalWebTestCase {
12
  public static function getInfo() {
13
    return array(
14
      'name' => 'Module API',
15
      'description' => 'Test low-level module functions.',
16
      'group' => 'Module',
17
    );
18
  }
19

    
20
  /**
21
   * The basic functionality of module_list().
22
   */
23
  function testModuleList() {
24
    // Build a list of modules, sorted alphabetically.
25
    $profile_info = install_profile_info('standard', 'en');
26
    $module_list = $profile_info['dependencies'];
27

    
28
    // Installation profile is a module that is expected to be loaded.
29
    $module_list[] = 'standard';
30

    
31
    sort($module_list);
32
    // Compare this list to the one returned by module_list(). We expect them
33
    // to match, since all default profile modules have a weight equal to 0
34
    // (except for block.module, which has a lower weight but comes first in
35
    // the alphabet anyway).
36
    $this->assertModuleList($module_list, t('Standard profile'));
37

    
38
    // Try to install a new module.
39
    module_enable(array('contact'));
40
    $module_list[] = 'contact';
41
    sort($module_list);
42
    $this->assertModuleList($module_list, t('After adding a module'));
43

    
44
    // Try to mess with the module weights.
45
    db_update('system')
46
      ->fields(array('weight' => 20))
47
      ->condition('name', 'contact')
48
      ->condition('type', 'module')
49
      ->execute();
50
    // Reset the module list.
51
    module_list(TRUE);
52
    // Move contact to the end of the array.
53
    unset($module_list[array_search('contact', $module_list)]);
54
    $module_list[] = 'contact';
55
    $this->assertModuleList($module_list, t('After changing weights'));
56

    
57
    // Test the fixed list feature.
58
    $fixed_list = array(
59
      'system' => array('filename' => drupal_get_path('module', 'system')),
60
      'menu' => array('filename' => drupal_get_path('module', 'menu')),
61
    );
62
    module_list(FALSE, FALSE, FALSE, $fixed_list);
63
    $new_module_list = array_combine(array_keys($fixed_list), array_keys($fixed_list));
64
    $this->assertModuleList($new_module_list, t('When using a fixed list'));
65

    
66
    // Reset the module list.
67
    module_list(TRUE);
68
    $this->assertModuleList($module_list, t('After reset'));
69
  }
70

    
71
  /**
72
   * Assert that module_list() return the expected values.
73
   *
74
   * @param $expected_values
75
   *   The expected values, sorted by weight and module name.
76
   */
77
  protected function assertModuleList(Array $expected_values, $condition) {
78
    $expected_values = array_combine($expected_values, $expected_values);
79
    $this->assertEqual($expected_values, module_list(), format_string('@condition: module_list() returns correct results', array('@condition' => $condition)));
80
    ksort($expected_values);
81
    $this->assertIdentical($expected_values, module_list(FALSE, FALSE, TRUE), format_string('@condition: module_list() returns correctly sorted results', array('@condition' => $condition)));
82
  }
83

    
84
  /**
85
   * Test module_implements() caching.
86
   */
87
  function testModuleImplements() {
88
    // Clear the cache.
89
    cache_clear_all('module_implements', 'cache_bootstrap');
90
    $this->assertFalse(cache_get('module_implements', 'cache_bootstrap'), 'The module implements cache is empty.');
91
    $this->drupalGet('');
92
    $this->assertTrue(cache_get('module_implements', 'cache_bootstrap'), 'The module implements cache is populated after requesting a page.');
93

    
94
    // Test again with an authenticated user.
95
    $this->user = $this->drupalCreateUser();
96
    $this->drupalLogin($this->user);
97
    cache_clear_all('module_implements', 'cache_bootstrap');
98
    $this->drupalGet('');
99
    $this->assertTrue(cache_get('module_implements', 'cache_bootstrap'), 'The module implements cache is populated after requesting a page.');
100

    
101
    // Make sure group include files are detected properly even when the file is
102
    // already loaded when the cache is rebuilt.
103
    // For that activate the module_test which provides the file to load.
104
    module_enable(array('module_test'));
105

    
106
    module_load_include('inc', 'module_test', 'module_test.file');
107
    $modules = module_implements('test_hook');
108
    $static = drupal_static('module_implements');
109
    $this->assertTrue(in_array('module_test', $modules), 'Hook found.');
110
    $this->assertEqual($static['test_hook']['module_test'], 'file', 'Include file detected.');
111
  }
112

    
113
  /**
114
   * Test that module_invoke() can load a hook defined in hook_hook_info().
115
   */
116
  function testModuleInvoke() {
117
    module_enable(array('module_test'), FALSE);
118
    $this->resetAll();
119
    $this->drupalGet('module-test/hook-dynamic-loading-invoke');
120
    $this->assertText('success!', 'module_invoke() dynamically loads a hook defined in hook_hook_info().');
121
  }
122

    
123
  /**
124
   * Test that module_invoke_all() can load a hook defined in hook_hook_info().
125
   */
126
  function testModuleInvokeAll() {
127
    module_enable(array('module_test'), FALSE);
128
    $this->resetAll();
129
    $this->drupalGet('module-test/hook-dynamic-loading-invoke-all');
130
    $this->assertText('success!', 'module_invoke_all() dynamically loads a hook defined in hook_hook_info().');
131
  }
132

    
133
  /**
134
   * Test dependency resolution.
135
   */
136
  function testDependencyResolution() {
137
    // Enable the test module, and make sure that other modules we are testing
138
    // are not already enabled. (If they were, the tests below would not work
139
    // correctly.)
140
    module_enable(array('module_test'), FALSE);
141
    $this->assertTrue(module_exists('module_test'), 'Test module is enabled.');
142
    $this->assertFalse(module_exists('forum'), 'Forum module is disabled.');
143
    $this->assertFalse(module_exists('poll'), 'Poll module is disabled.');
144
    $this->assertFalse(module_exists('php'), 'PHP module is disabled.');
145

    
146
    // First, create a fake missing dependency. Forum depends on poll, which
147
    // depends on a made-up module, foo. Nothing should be installed.
148
    variable_set('dependency_test', 'missing dependency');
149
    drupal_static_reset('system_rebuild_module_data');
150
    $result = module_enable(array('forum'));
151
    $this->assertFalse($result, 'module_enable() returns FALSE if dependencies are missing.');
152
    $this->assertFalse(module_exists('forum'), 'module_enable() aborts if dependencies are missing.');
153

    
154
    // Now, fix the missing dependency. Forum module depends on poll, but poll
155
    // depends on the PHP module. module_enable() should work.
156
    variable_set('dependency_test', 'dependency');
157
    drupal_static_reset('system_rebuild_module_data');
158
    $result = module_enable(array('forum'));
159
    $this->assertTrue($result, 'module_enable() returns the correct value.');
160
    // Verify that the fake dependency chain was installed.
161
    $this->assertTrue(module_exists('poll') && module_exists('php'), 'Dependency chain was installed by module_enable().');
162
    // Verify that the original module was installed.
163
    $this->assertTrue(module_exists('forum'), 'Module installation with unlisted dependencies succeeded.');
164
    // Finally, verify that the modules were enabled in the correct order.
165
    $this->assertEqual(variable_get('test_module_enable_order', array()), array('php', 'poll', 'forum'), 'Modules were enabled in the correct order by module_enable().');
166

    
167
    // Now, disable the PHP module. Both forum and poll should be disabled as
168
    // well, in the correct order.
169
    module_disable(array('php'));
170
    $this->assertTrue(!module_exists('forum') && !module_exists('poll'), 'Depedency chain was disabled by module_disable().');
171
    $this->assertFalse(module_exists('php'), 'Disabling a module with unlisted dependents succeeded.');
172
    $this->assertEqual(variable_get('test_module_disable_order', array()), array('forum', 'poll', 'php'), 'Modules were disabled in the correct order by module_disable().');
173

    
174
    // Disable a module that is listed as a dependency by the installation
175
    // profile. Make sure that the profile itself is not on the list of
176
    // dependent modules to be disabled.
177
    $profile = drupal_get_profile();
178
    $info = install_profile_info($profile);
179
    $this->assertTrue(in_array('comment', $info['dependencies']), 'Comment module is listed as a dependency of the installation profile.');
180
    $this->assertTrue(module_exists('comment'), 'Comment module is enabled.');
181
    module_disable(array('comment'));
182
    $this->assertFalse(module_exists('comment'), 'Comment module was disabled.');
183
    $disabled_modules = variable_get('test_module_disable_order', array());
184
    $this->assertTrue(in_array('comment', $disabled_modules), 'Comment module is in the list of disabled modules.');
185
    $this->assertFalse(in_array($profile, $disabled_modules), 'The installation profile is not in the list of disabled modules.');
186

    
187
    // Try to uninstall the PHP module by itself. This should be rejected,
188
    // since the modules which it depends on need to be uninstalled first, and
189
    // that is too destructive to perform automatically.
190
    $result = drupal_uninstall_modules(array('php'));
191
    $this->assertFalse($result, 'Calling drupal_uninstall_modules() on a module whose dependents are not uninstalled fails.');
192
    foreach (array('forum', 'poll', 'php') as $module) {
193
      $this->assertNotEqual(drupal_get_installed_schema_version($module), SCHEMA_UNINSTALLED, format_string('The @module module was not uninstalled.', array('@module' => $module)));
194
    }
195

    
196
    // Now uninstall all three modules explicitly, but in the incorrect order,
197
    // and make sure that drupal_uninstal_modules() uninstalled them in the
198
    // correct sequence.
199
    $result = drupal_uninstall_modules(array('poll', 'php', 'forum'));
200
    $this->assertTrue($result, 'drupal_uninstall_modules() returns the correct value.');
201
    foreach (array('forum', 'poll', 'php') as $module) {
202
      $this->assertEqual(drupal_get_installed_schema_version($module), SCHEMA_UNINSTALLED, format_string('The @module module was uninstalled.', array('@module' => $module)));
203
    }
204
    $this->assertEqual(variable_get('test_module_uninstall_order', array()), array('forum', 'poll', 'php'), 'Modules were uninstalled in the correct order by drupal_uninstall_modules().');
205

    
206
    // Uninstall the profile module from above, and make sure that the profile
207
    // itself is not on the list of dependent modules to be uninstalled.
208
    $result = drupal_uninstall_modules(array('comment'));
209
    $this->assertTrue($result, 'drupal_uninstall_modules() returns the correct value.');
210
    $this->assertEqual(drupal_get_installed_schema_version('comment'), SCHEMA_UNINSTALLED, 'Comment module was uninstalled.');
211
    $uninstalled_modules = variable_get('test_module_uninstall_order', array());
212
    $this->assertTrue(in_array('comment', $uninstalled_modules), 'Comment module is in the list of uninstalled modules.');
213
    $this->assertFalse(in_array($profile, $uninstalled_modules), 'The installation profile is not in the list of uninstalled modules.');
214

    
215
    // Enable forum module again, which should enable both the poll module and
216
    // php module. But, this time do it with poll module declaring a dependency
217
    // on a specific version of php module in its info file. Make sure that
218
    // module_enable() still works.
219
    variable_set('dependency_test', 'version dependency');
220
    drupal_static_reset('system_rebuild_module_data');
221
    $result = module_enable(array('forum'));
222
    $this->assertTrue($result, 'module_enable() returns the correct value.');
223
    // Verify that the fake dependency chain was installed.
224
    $this->assertTrue(module_exists('poll') && module_exists('php'), 'Dependency chain was installed by module_enable().');
225
    // Verify that the original module was installed.
226
    $this->assertTrue(module_exists('forum'), 'Module installation with version dependencies succeeded.');
227
    // Finally, verify that the modules were enabled in the correct order.
228
    $enable_order = variable_get('test_module_enable_order', array());
229
    $php_position = array_search('php', $enable_order);
230
    $poll_position = array_search('poll', $enable_order);
231
    $forum_position = array_search('forum', $enable_order);
232
    $php_before_poll = $php_position !== FALSE && $poll_position !== FALSE && $php_position < $poll_position;
233
    $poll_before_forum = $poll_position !== FALSE && $forum_position !== FALSE && $poll_position < $forum_position;
234
    $this->assertTrue($php_before_poll && $poll_before_forum, 'Modules were enabled in the correct order by module_enable().');
235
  }
236
}
237

    
238
/**
239
 * Unit tests for module installation.
240
 */
241
class ModuleInstallTestCase extends DrupalWebTestCase {
242
  public static function getInfo() {
243
    return array(
244
      'name' => 'Module installation',
245
      'description' => 'Tests the installation of modules.',
246
      'group' => 'Module',
247
    );
248
  }
249

    
250
  function setUp() {
251
    parent::setUp('module_test');
252
  }
253

    
254
  /**
255
   * Test that calls to drupal_write_record() work during module installation.
256
   *
257
   * This is a useful function to test because modules often use it to insert
258
   * initial data in their database tables when they are being installed or
259
   * enabled. Furthermore, drupal_write_record() relies on the module schema
260
   * information being available, so this also checks that the data from one of
261
   * the module's hook implementations, in particular hook_schema(), is
262
   * properly available during this time. Therefore, this test helps ensure
263
   * that modules are fully functional while Drupal is installing and enabling
264
   * them.
265
   */
266
  function testDrupalWriteRecord() {
267
    // Check for data that was inserted using drupal_write_record() while the
268
    // 'module_test' module was being installed and enabled.
269
    $data = db_query("SELECT data FROM {module_test}")->fetchCol();
270
    $this->assertTrue(in_array('Data inserted in hook_install()', $data), 'Data inserted using drupal_write_record() in hook_install() is correctly saved.');
271
    $this->assertTrue(in_array('Data inserted in hook_enable()', $data), 'Data inserted using drupal_write_record() in hook_enable() is correctly saved.');
272
  }
273
}
274

    
275
/**
276
 * Unit tests for module uninstallation and related hooks.
277
 */
278
class ModuleUninstallTestCase extends DrupalWebTestCase {
279
  public static function getInfo() {
280
    return array(
281
      'name' => 'Module uninstallation',
282
      'description' => 'Tests the uninstallation of modules.',
283
      'group' => 'Module',
284
    );
285
  }
286

    
287
  function setUp() {
288
    parent::setUp('module_test', 'user');
289
  }
290

    
291
  /**
292
   * Tests the hook_modules_uninstalled() of the user module.
293
   */
294
  function testUserPermsUninstalled() {
295
    // Uninstalls the module_test module, so hook_modules_uninstalled()
296
    // is executed.
297
    module_disable(array('module_test'));
298
    drupal_uninstall_modules(array('module_test'));
299

    
300
    // Are the perms defined by module_test removed from {role_permission}.
301
    $count = db_query("SELECT COUNT(rid) FROM {role_permission} WHERE permission = :perm", array(':perm' => 'module_test perm'))->fetchField();
302
    $this->assertEqual(0, $count, 'Permissions were all removed.');
303
  }
304
}