EnableDisableTest.php 9.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
<?php

/**
 * @file
 * Definition of Drupal\system\Tests\Module\EnableDisableTest.
 */

namespace Drupal\system\Tests\Module;

/**
 * Test module enabling/disabling functionality.
 */
class EnableDisableTest extends ModuleTestBase {
  public static function getInfo() {
    return array(
      'name' => 'Enable/disable modules',
      'description' => 'Enable/disable core module and confirm table creation/deletion.',
      'group' => 'Module',
    );
  }

  /**
   * Test that all core modules can be enabled, disabled and uninstalled.
   */
  function testEnableDisable() {
    // Try to enable, disable and uninstall all core modules, unless they are
    // hidden or required.
    $modules = system_rebuild_module_data();
    foreach ($modules as $name => $module) {
      if ($module->info['package'] != 'Core' || !empty($module->info['hidden']) || !empty($module->info['required'])) {
        unset($modules[$name]);
      }
    }

    // Throughout this test, some modules may be automatically enabled (due to
    // dependencies). We'll keep track of them in an array, so we can handle
    // them separately.
    $automatically_enabled = array();

    // Remove already enabled modules (via installation profile).
    // @todo Remove this after removing all dependencies from Testing profile.
    foreach (module_list() as $dependency) {
      // Exclude required modules. Only installation profile "suggestions" can
      // be disabled and uninstalled.
      if (isset($modules[$dependency])) {
        $automatically_enabled[$dependency] = TRUE;
      }
    }

50
    $this->assertTrue(count($modules), format_string('Found @count modules that can be enabled: %modules', array(
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
      '@count' => count($modules),
      '%modules' => implode(', ', array_keys($modules)),
    )));

    // Enable the dblog module first, since we will be asserting the presence
    // of log messages throughout the test.
   if (isset($modules['dblog'])) {
     $modules = array('dblog' => $modules['dblog']) + $modules;
   }

   // Set a variable so that the hook implementations in system_test.module
   // will display messages via drupal_set_message().
   variable_set('test_verbose_module_hooks', TRUE);

    // Go through each module in the list and try to enable it (unless it was
    // already enabled automatically due to a dependency).
    foreach ($modules as $name => $module) {
      if (empty($automatically_enabled[$name])) {
        // Start a list of modules that we expect to be enabled this time.
        $modules_to_enable = array($name);

        // Find out if the module has any dependencies that aren't enabled yet;
        // if so, add them to the list of modules we expect to be automatically
        // enabled.
        foreach (array_keys($module->requires) as $dependency) {
          if (isset($modules[$dependency]) && empty($automatically_enabled[$dependency])) {
            $modules_to_enable[] = $dependency;
            $automatically_enabled[$dependency] = TRUE;
          }
        }

        // Check that each module is not yet enabled and does not have any
        // database tables yet.
        foreach ($modules_to_enable as $module_to_enable) {
          $this->assertModules(array($module_to_enable), FALSE);
          $this->assertModuleTablesDoNotExist($module_to_enable);
        }

        // Install and enable the module.
        $edit = array();
        $edit['modules[Core][' . $name . '][enable]'] = $name;
        $this->drupalPost('admin/modules', $edit, t('Save configuration'));
        // Handle the case where modules were installed along with this one and
        // where we therefore hit a confirmation screen.
        if (count($modules_to_enable) > 1) {
          $this->drupalPost(NULL, array(), t('Continue'));
        }
98
        $this->assertText(t('The configuration options have been saved.'), 'Modules status has been updated.');
99 100 101 102 103 104 105 106 107 108

        // Check that hook_modules_installed() and hook_modules_enabled() were
        // invoked with the expected list of modules, that each module's
        // database tables now exist, and that appropriate messages appear in
        // the logs.
        foreach ($modules_to_enable as $module_to_enable) {
          $this->assertText(t('hook_modules_installed fired for @module', array('@module' => $module_to_enable)));
          $this->assertText(t('hook_modules_enabled fired for @module', array('@module' => $module_to_enable)));
          $this->assertModules(array($module_to_enable), TRUE);
          $this->assertModuleTablesExist($module_to_enable);
109
          $this->assertModuleConfig($module_to_enable);
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
          $this->assertLogMessage('system', "%module module installed.", array('%module' => $module_to_enable), WATCHDOG_INFO);
          $this->assertLogMessage('system', "%module module enabled.", array('%module' => $module_to_enable), WATCHDOG_INFO);
        }

        // Disable and uninstall the original module, and check appropriate
        // hooks, tables, and log messages. (Later, we'll go back and do the
        // same thing for modules that were enabled automatically.) Skip this
        // for the dblog module, because that is needed for the test; we'll go
        // back and do that one at the end also.
        if ($name != 'dblog') {
          $this->assertSuccessfulDisableAndUninstall($name);
        }
      }
    }

    // Go through all modules that were automatically enabled, and try to
    // disable and uninstall them one by one.
    while (!empty($automatically_enabled)) {
      $initial_count = count($automatically_enabled);
      foreach (array_keys($automatically_enabled) as $name) {
        // If the module can't be disabled due to dependencies, skip it and try
        // again the next time. Otherwise, try to disable it.
        $this->drupalGet('admin/modules');
        $disabled_checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[Core][' . $name . '][enable]"]');
        if (empty($disabled_checkbox) && $name != 'dblog') {
          unset($automatically_enabled[$name]);
          $this->assertSuccessfulDisableAndUninstall($name);
        }
      }
      $final_count = count($automatically_enabled);
      // If all checkboxes were disabled, something is really wrong with the
      // test. Throw a failure and avoid an infinite loop.
      if ($initial_count == $final_count) {
        $this->fail(t('Remaining modules could not be disabled.'));
        break;
      }
    }

    // Disable and uninstall the dblog module last, since we needed it for
    // assertions in all the above tests.
    if (isset($modules['dblog'])) {
      $this->assertSuccessfulDisableAndUninstall('dblog');
    }

    // Now that all modules have been tested, go back and try to enable them
    // all again at once. This tests two things:
    // - That each module can be successfully enabled again after being
    //   uninstalled.
    // - That enabling more than one module at the same time does not lead to
    //   any errors.
    $edit = array();
    foreach (array_keys($modules) as $name) {
      $edit['modules[Core][' . $name . '][enable]'] = $name;
    }
    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
165
    $this->assertText(t('The configuration options have been saved.'), 'Modules status has been updated.');
166 167 168 169 170 171 172 173 174 175 176 177 178
  }

  /**
   * Disables and uninstalls a module and asserts that it was done correctly.
   *
   * @param $module
   *   The name of the module to disable and uninstall.
   */
  function assertSuccessfulDisableAndUninstall($module) {
    // Disable the module.
    $edit = array();
    $edit['modules[Core][' . $module . '][enable]'] = FALSE;
    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
179
    $this->assertText(t('The configuration options have been saved.'), 'Modules status has been updated.');
180 181 182 183 184 185 186 187 188 189
    $this->assertModules(array($module), FALSE);

    // Check that the appropriate hook was fired and the appropriate log
    // message appears.
    $this->assertText(t('hook_modules_disabled fired for @module', array('@module' => $module)));
    $this->assertLogMessage('system', "%module module disabled.", array('%module' => $module), WATCHDOG_INFO);

    //  Check that the module's database tables still exist.
    $this->assertModuleTablesExist($module);
    //  Check that the module's config files still exist.
190
    $this->assertModuleConfig($module);
191 192 193 194 195 196

    // Uninstall the module.
    $edit = array();
    $edit['uninstall[' . $module . ']'] = $module;
    $this->drupalPost('admin/modules/uninstall', $edit, t('Uninstall'));
    $this->drupalPost(NULL, NULL, t('Uninstall'));
197
    $this->assertText(t('The selected modules have been uninstalled.'), 'Modules status has been updated.');
198 199 200 201 202 203 204 205 206 207 208 209 210 211
    $this->assertModules(array($module), FALSE);

    // Check that the appropriate hook was fired and the appropriate log
    // message appears. (But don't check for the log message if the dblog
    // module was just uninstalled, since the {watchdog} table won't be there
    // anymore.)
    $this->assertText(t('hook_modules_uninstalled fired for @module', array('@module' => $module)));
    if ($module != 'dblog') {
      $this->assertLogMessage('system', "%module module uninstalled.", array('%module' => $module), WATCHDOG_INFO);
    }

    // Check that the module's database tables no longer exist.
    $this->assertModuleTablesDoNotExist($module);
    // Check that the module's config files no longer exist.
212
    $this->assertNoModuleConfig($module);
213 214
  }
}