CRM-16243 - Redundant installation should not throw error
authorTim Otten <totten@civicrm.org>
Sat, 21 Oct 2017 00:17:43 +0000 (17:17 -0700)
committerTim Otten <totten@civicrm.org>
Sat, 21 Oct 2017 00:17:43 +0000 (17:17 -0700)
Suppose we have two modules, `foo.core` and `foo.addon` (where `foo.addon`
depends on `foo.core`).

Now you suppose you try to install `foo.addon` twice, e.g.

```
cv en foo.addon
cv en foo.addon
```

The first installation succeeds (and enables both modules as expected).
However, the second installation throws an error: "Dependency foo.core not
found, required by foo.addon"

This adds a test and resolves the error.

CRM/Extension/Manager.php
tests/phpunit/CRM/Extension/ManagerTest.php

index 013c9aa9a03bafd980a7d75718ef2cd240d3c510..975c88b8e719880fe6e1d51b48ae4f0610a2a181 100644 (file)
@@ -610,7 +610,7 @@ class CRM_Extension_Manager {
       $info = @$infos[$key];
 
       if ($this->getStatus($key) === self::STATUS_INSTALLED) {
-        $sorter->add($key, $info->requires);
+        $sorter->add($key, array());
       }
       elseif ($info && $info->requires) {
         $sorter->add($key, $info->requires);
index b8cf3f352aa28175e73238e570daca2391007c2a..30cdc7558f1e420865b2cdf11a794b4bb4695e14 100644 (file)
@@ -145,6 +145,40 @@ class CRM_Extension_ManagerTest extends CiviUnitTestCase {
     $this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang'));
   }
 
+  /**
+   * This is the same as testInstallAuto_Twice
+   *
+   * @throws \CRM_Extension_Exception
+   */
+  public function testInstallAuto_Twice() {
+    $testingTypeManager = $this->getMock('CRM_Extension_Manager_Interface');
+    $manager = $this->_createManager(array(
+      self::TESTING_TYPE => $testingTypeManager,
+    ));
+    $this->assertEquals('uninstalled', $manager->getStatus('test.foo.bar'));
+    $this->assertEquals('uninstalled', $manager->getStatus('test.foo.downstream'));
+    $this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang'));
+
+    $testingTypeManager->expects($this->exactly(2))->method('onPreInstall');
+    $testingTypeManager->expects($this->exactly(2))->method('onPostInstall');
+    $this->assertEquals(array('test.foo.bar', 'test.foo.downstream'),
+      $manager->findInstallRequirements(array('test.foo.downstream')));
+    $manager->install(
+      $manager->findInstallRequirements(array('test.foo.downstream')));
+    $this->assertEquals('installed', $manager->getStatus('test.foo.bar'));
+    $this->assertEquals('installed', $manager->getStatus('test.foo.downstream'));
+    $this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang'));
+
+    // And install a second time...
+    $testingTypeManager->expects($this->exactly(0))->method('onPreInstall');
+    $testingTypeManager->expects($this->exactly(0))->method('onPostInstall');
+    $manager->install(
+      $manager->findInstallRequirements(array('test.foo.downstream')));
+    $this->assertEquals('installed', $manager->getStatus('test.foo.bar'));
+    $this->assertEquals('installed', $manager->getStatus('test.foo.downstream'));
+    $this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang'));
+  }
+
   public function test_InstallAuto_DisableUpstream() {
     $testingTypeManager = $this->getMock('CRM_Extension_Manager_Interface');
     $manager = $this->_createManager(array(