PageRenderTime 27ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/core/modules/system/src/Tests/Module/UninstallTest.php

http://github.com/drupal/drupal
PHP | 153 lines | 90 code | 22 blank | 41 comment | 0 complexity | 67a1c00b82d95b1068dfaa6b8850ffb0 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. namespace Drupal\system\Tests\Module;
  3. use Drupal\Core\Cache\Cache;
  4. use Drupal\Component\Utility\SafeMarkup;
  5. use Drupal\Core\Entity\EntityMalformedException;
  6. use Drupal\node\Entity\Node;
  7. use Drupal\node\Entity\NodeType;
  8. use Drupal\simpletest\WebTestBase;
  9. /**
  10. * Tests the uninstallation of modules.
  11. *
  12. * @group Module
  13. */
  14. class UninstallTest extends WebTestBase {
  15. /**
  16. * Modules to enable.
  17. *
  18. * @var array
  19. */
  20. public static $modules = array('module_test', 'user', 'views', 'node');
  21. /**
  22. * Tests the hook_modules_uninstalled() of the user module.
  23. */
  24. function testUserPermsUninstalled() {
  25. // Uninstalls the module_test module, so hook_modules_uninstalled()
  26. // is executed.
  27. $this->container->get('module_installer')->uninstall(array('module_test'));
  28. // Are the perms defined by module_test removed?
  29. $this->assertFalse(user_roles(FALSE, 'module_test perm'), 'Permissions were all removed.');
  30. }
  31. /**
  32. * Tests the Uninstall page and Uninstall confirmation page.
  33. */
  34. function testUninstallPage() {
  35. $account = $this->drupalCreateUser(array('administer modules'));
  36. $this->drupalLogin($account);
  37. // Create a node type.
  38. $node_type = NodeType::create(['type' => 'uninstall_blocker', 'name' => 'Uninstall blocker']);
  39. // Create a dependency that can be fixed.
  40. $node_type->setThirdPartySetting('module_test', 'key', 'value');
  41. $node_type->save();
  42. // Add a node to prevent node from being uninstalled.
  43. $node = Node::create([
  44. 'type' => 'uninstall_blocker',
  45. 'title' => $this->randomString(),
  46. ]);
  47. $node->save();
  48. $this->drupalGet('admin/modules/uninstall');
  49. $this->assertTitle(t('Uninstall') . ' | Drupal');
  50. // Be sure labels are rendered properly.
  51. // @see regression https://www.drupal.org/node/2512106
  52. $this->assertRaw('<label for="edit-uninstall-node" class="module-name table-filter-text-source">Node</label>');
  53. $this->assertText(\Drupal::translation()->translate('The following reason prevents Node from being uninstalled:'));
  54. $this->assertText(\Drupal::translation()->translate('There is content for the entity type: Content'));
  55. // Delete the node to allow node to be uninstalled.
  56. $node->delete();
  57. // Uninstall module_test.
  58. $edit = array();
  59. $edit['uninstall[module_test]'] = TRUE;
  60. $this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall'));
  61. $this->assertNoText(\Drupal::translation()->translate('Configuration deletions'), 'No configuration deletions listed on the module install confirmation page.');
  62. $this->assertText(\Drupal::translation()->translate('Configuration updates'), 'Configuration updates listed on the module install confirmation page.');
  63. $this->assertText($node_type->label());
  64. $this->drupalPostForm(NULL, NULL, t('Uninstall'));
  65. $this->assertText(t('The selected modules have been uninstalled.'), 'Modules status has been updated.');
  66. // Uninstall node testing that the configuration that will be deleted is
  67. // listed.
  68. $node_dependencies = \Drupal::service('config.manager')->findConfigEntityDependentsAsEntities('module', array('node'));
  69. $edit = array();
  70. $edit['uninstall[node]'] = TRUE;
  71. $this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall'));
  72. $this->assertText(\Drupal::translation()->translate('Configuration deletions'), 'Configuration deletions listed on the module install confirmation page.');
  73. $this->assertNoText(\Drupal::translation()->translate('Configuration updates'), 'No configuration updates listed on the module install confirmation page.');
  74. $entity_types = array();
  75. foreach ($node_dependencies as $entity) {
  76. $label = $entity->label() ?: $entity->id();
  77. $this->assertText($label);
  78. $entity_types[] = $entity->getEntityTypeId();
  79. }
  80. $entity_types = array_unique($entity_types);
  81. foreach ($entity_types as $entity_type_id) {
  82. $entity_type = \Drupal::entityManager()->getDefinition($entity_type_id);
  83. // Add h3's since the entity type label is often repeated in the entity
  84. // labels.
  85. $this->assertRaw('<h3>' . $entity_type->getLabel() . '</h3>');
  86. }
  87. // Set a unique cache entry to be able to test whether all caches are
  88. // cleared during the uninstall.
  89. \Drupal::cache()->set('uninstall_test', 'test_uninstall_page', Cache::PERMANENT);
  90. $cached = \Drupal::cache()->get('uninstall_test');
  91. $this->assertEqual($cached->data, 'test_uninstall_page', SafeMarkup::format('Cache entry found: @bin', array('@bin' => $cached->data)));
  92. $this->drupalPostForm(NULL, NULL, t('Uninstall'));
  93. $this->assertText(t('The selected modules have been uninstalled.'), 'Modules status has been updated.');
  94. $this->assertNoRaw('&lt;label', 'The page does not have double escaped HTML tags.');
  95. // Make sure our unique cache entry is gone.
  96. $cached = \Drupal::cache()->get('uninstall_test');
  97. $this->assertFalse($cached, 'Cache entry not found');
  98. // Make sure we get an error message when we try to confirm uninstallation
  99. // of an empty list of modules.
  100. $this->drupalGet('admin/modules/uninstall/confirm');
  101. $this->assertText(t('The selected modules could not be uninstalled, either due to a website problem or due to the uninstall confirmation form timing out. Please try again.'), 'Module uninstall confirmation form displays error message');
  102. // Make sure confirmation page is accessible only during uninstall process.
  103. $this->drupalGet('admin/modules/uninstall/confirm');
  104. $this->assertUrl('admin/modules/uninstall');
  105. $this->assertTitle(t('Uninstall') . ' | Drupal');
  106. }
  107. /**
  108. * Tests that a module which fails to install can still be uninstalled.
  109. */
  110. public function testFailedInstallStatus() {
  111. $account = $this->drupalCreateUser(array('administer modules'));
  112. $this->drupalLogin($account);
  113. $message = 'Exception thrown when installing module_installer_config_test with an invalid configuration file.';
  114. try {
  115. $this->container->get('module_installer')->install(array('module_installer_config_test'));
  116. $this->fail($message);
  117. }
  118. catch (EntityMalformedException $e) {
  119. $this->pass($message);
  120. }
  121. // Even though the module failed to install properly, its configuration
  122. // status is "enabled" and should still be available to uninstall.
  123. $this->drupalGet('admin/modules/uninstall');
  124. $this->assertText('Module installer config test');
  125. $edit['uninstall[module_installer_config_test]'] = TRUE;
  126. $this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall'));
  127. $this->drupalPostForm(NULL, NULL, t('Uninstall'));
  128. $this->assertText(t('The selected modules have been uninstalled.'));
  129. $this->assertNoText('Module installer config test');
  130. }
  131. }