basedir, $this->container) = $this->_createContainer();
$this->mapper = new CRM_Extension_Mapper($this->container);
}
function tearDown() {
parent::tearDown();
}
/**
* Install an extension with an invalid type name
*
* @expectedException CRM_Extension_Exception
*/
function testInstallInvalidType() {
$testingTypeManager = $this->getMock('CRM_Extension_Manager_Interface');
$testingTypeManager->expects($this->never())
->method('onPreInstall');
$manager = $this->_createManager(array(
self::OTHER_TESTING_TYPE => $testingTypeManager,
));
$manager->install(array('test.foo.bar'));
}
/**
* Install an extension with a valid type name
*
* Note: We initially install two extensions but then toggle only
* the second. This controls for bad SQL queries which hit either
* "the first row" or "all rows".
*/
function testInstall_Disable_Uninstall() {
$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.whiz.bang'));
$testingTypeManager
->expects($this->exactly(2))
->method('onPreInstall');
$testingTypeManager
->expects($this->exactly(2))
->method('onPostInstall');
$manager->install(array('test.whiz.bang', 'test.foo.bar'));
$this->assertEquals('installed', $manager->getStatus('test.foo.bar'));
$this->assertEquals('installed', $manager->getStatus('test.whiz.bang'));
$testingTypeManager
->expects($this->once())
->method('onPreDisable');
$testingTypeManager
->expects($this->once())
->method('onPostDisable');
$manager->disable(array('test.foo.bar'));
$this->assertEquals('disabled', $manager->getStatus('test.foo.bar'));
$this->assertEquals('installed', $manager->getStatus('test.whiz.bang')); // no side-effect
$testingTypeManager
->expects($this->once())
->method('onPreUninstall');
$testingTypeManager
->expects($this->once())
->method('onPostUninstall');
$manager->uninstall(array('test.foo.bar'));
$this->assertEquals('uninstalled', $manager->getStatus('test.foo.bar'));
$this->assertEquals('installed', $manager->getStatus('test.whiz.bang')); // no side-effect
}
/**
* Install an extension and then harshly remove the underlying source.
* Subseuently disable and uninstall.
*/
function testInstall_DirtyRemove_Disable_Uninstall() {
$testingTypeManager = $this->getMock('CRM_Extension_Manager_Interface');
$manager = $this->_createManager(array(
self::TESTING_TYPE => $testingTypeManager,
));
$this->assertEquals('uninstalled', $manager->getStatus('test.foo.bar'));
$manager->install(array('test.foo.bar'));
$this->assertEquals('installed', $manager->getStatus('test.foo.bar'));
$this->assertTrue(file_exists("{$this->basedir}/weird/foobar/info.xml"));
CRM_Utils_File::cleanDir("{$this->basedir}/weird/foobar", TRUE, FALSE);
$this->assertFalse(file_exists("{$this->basedir}/weird/foobar/info.xml"));
$manager->refresh();
$this->assertEquals('installed-missing', $manager->getStatus('test.foo.bar'));
$testingTypeManager
->expects($this->once())
->method('onPreDisable');
$testingTypeManager
->expects($this->once())
->method('onPostDisable');
$manager->disable(array('test.foo.bar'));
$this->assertEquals('disabled-missing', $manager->getStatus('test.foo.bar'));
$testingTypeManager
->expects($this->once())
->method('onPreUninstall');
$testingTypeManager
->expects($this->once())
->method('onPostUninstall');
$manager->uninstall(array('test.foo.bar'));
$this->assertEquals('unknown', $manager->getStatus('test.foo.bar'));
}
/**
* Install an extension with a valid type name
*/
function testInstall_Disable_Enable() {
$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.whiz.bang'));
$testingTypeManager
->expects($this->exactly(2))
->method('onPreInstall');
$testingTypeManager
->expects($this->exactly(2))
->method('onPostInstall');
$manager->install(array('test.whiz.bang', 'test.foo.bar'));
$this->assertEquals('installed', $manager->getStatus('test.foo.bar'));
$this->assertEquals('installed', $manager->getStatus('test.whiz.bang'));
$testingTypeManager
->expects($this->once())
->method('onPreDisable');
$testingTypeManager
->expects($this->once())
->method('onPostDisable');
$manager->disable(array('test.foo.bar'));
$this->assertEquals('disabled', $manager->getStatus('test.foo.bar'));
$this->assertEquals('installed', $manager->getStatus('test.whiz.bang'));
$testingTypeManager
->expects($this->once())
->method('onPreEnable');
$testingTypeManager
->expects($this->once())
->method('onPostEnable');
$manager->enable(array('test.foo.bar'));
$this->assertEquals('installed', $manager->getStatus('test.foo.bar'));
$this->assertEquals('installed', $manager->getStatus('test.whiz.bang'));
}
/**
* Performing 'install' on a 'disabled' extension performs an 'enable'
*/
function testInstall_Disable_Install() {
$testingTypeManager = $this->getMock('CRM_Extension_Manager_Interface');
$manager = $this->_createManager(array(
self::TESTING_TYPE => $testingTypeManager,
));
$this->assertEquals('uninstalled', $manager->getStatus('test.foo.bar'));
$testingTypeManager
->expects($this->once())
->method('onPreInstall');
$testingTypeManager
->expects($this->once())
->method('onPostInstall');
$manager->install(array('test.foo.bar'));
$this->assertEquals('installed', $manager->getStatus('test.foo.bar'));
$testingTypeManager
->expects($this->once())
->method('onPreDisable');
$testingTypeManager
->expects($this->once())
->method('onPostDisable');
$manager->disable(array('test.foo.bar'));
$this->assertEquals('disabled', $manager->getStatus('test.foo.bar'));
$testingTypeManager
->expects($this->once())
->method('onPreEnable');
$testingTypeManager
->expects($this->once())
->method('onPostEnable');
$manager->install(array('test.foo.bar')); // install() instead of enable()
$this->assertEquals('installed', $manager->getStatus('test.foo.bar'));
}
/**
* Install an extension with a valid type name
*/
function testEnableBare() {
$testingTypeManager = $this->getMock('CRM_Extension_Manager_Interface');
$manager = $this->_createManager(array(
self::TESTING_TYPE => $testingTypeManager,
));
$this->assertEquals('uninstalled', $manager->getStatus('test.foo.bar'));
$testingTypeManager
->expects($this->once())
->method('onPreInstall');
$testingTypeManager
->expects($this->once())
->method('onPostInstall');
$testingTypeManager
->expects($this->never())
->method('onPreEnable');
$testingTypeManager
->expects($this->never())
->method('onPostEnable');
$manager->enable(array('test.foo.bar')); // enable not install
$this->assertEquals('installed', $manager->getStatus('test.foo.bar'));
}
/**
* Get the status of an unknown extension
*/
function testStatusUnknownKey() {
$testingTypeManager = $this->getMock('CRM_Extension_Manager_Interface');
$testingTypeManager->expects($this->never())
->method('onPreInstall');
$manager = $this->_createManager(array(
self::TESTING_TYPE => $testingTypeManager,
));
$this->assertEquals('unknown', $manager->getStatus('test.foo.bar.whiz.bang'));
}
/**
* Replace code for an extension that doesn't exist in the container
*/
function testReplace_Unknown() {
$testingTypeManager = $this->getMock('CRM_Extension_Manager_Interface');
$manager = $this->_createManager(array(
self::TESTING_TYPE => $testingTypeManager,
));
$this->assertEquals('unknown', $manager->getStatus('test.newextension'));
$this->download = $this->_createDownload('test.newextension', 'newextension');
$testingTypeManager
->expects($this->never()) // no data to replace
->method('onPreReplace');
$testingTypeManager
->expects($this->never()) // no data to replace
->method('onPostReplace');
$manager->replace($this->download);
$this->assertEquals('uninstalled', $manager->getStatus('test.newextension'));
$this->assertTrue(file_exists("{$this->basedir}/test.newextension/info.xml"));
$this->assertTrue(file_exists("{$this->basedir}/test.newextension/newextension.php"));
$this->assertEquals(self::TESTING_TYPE, $this->mapper->keyToInfo('test.newextension')->type);
$this->assertEquals('newextension', $this->mapper->keyToInfo('test.newextension')->file);
}
/**
* Replace code for an extension that doesn't exist in the container
*/
function testReplace_Uninstalled() {
$testingTypeManager = $this->getMock('CRM_Extension_Manager_Interface');
$manager = $this->_createManager(array(
self::TESTING_TYPE => $testingTypeManager,
));
$this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang'));
$this->assertEquals('oddball', $this->mapper->keyToInfo('test.whiz.bang')->file);
$this->download = $this->_createDownload('test.whiz.bang', 'newextension');
$testingTypeManager
->expects($this->never()) // no data to replace
->method('onPreReplace');
$testingTypeManager
->expects($this->never()) // no data to replace
->method('onPostReplace');
$manager->replace($this->download);
$this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang'));
$this->assertTrue(file_exists("{$this->basedir}/weird/whizbang/info.xml"));
$this->assertTrue(file_exists("{$this->basedir}/weird/whizbang/newextension.php"));
$this->assertFalse(file_exists("{$this->basedir}/weird/whizbang/oddball.php"));
$this->assertEquals(self::TESTING_TYPE, $this->mapper->keyToInfo('test.whiz.bang')->type);
$this->assertEquals('newextension', $this->mapper->keyToInfo('test.whiz.bang')->file);
}
/**
* Install a module and then replace it with new code
*
* Note that some metadata changes between versions -- the original has
* file="oddball", and the upgrade has file="newextension".
*/
function testReplace_Installed() {
$testingTypeManager = $this->getMock('CRM_Extension_Manager_Interface');
$manager = $this->_createManager(array(
self::TESTING_TYPE => $testingTypeManager,
));
$this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang'));
$this->assertEquals('oddball', $this->mapper->keyToInfo('test.whiz.bang')->file);
$manager->install(array('test.whiz.bang'));
$this->assertEquals('installed', $manager->getStatus('test.whiz.bang'));
$this->assertEquals('oddball', $this->mapper->keyToInfo('test.whiz.bang')->file);
$this->assertDBQuery('oddball', 'SELECT file FROM civicrm_extension WHERE full_name ="test.whiz.bang"');
$this->download = $this->_createDownload('test.whiz.bang', 'newextension');
$testingTypeManager
->expects($this->once())
->method('onPreReplace');
$testingTypeManager
->expects($this->once())
->method('onPostReplace');
$manager->replace($this->download);
$this->assertEquals('installed', $manager->getStatus('test.whiz.bang'));
$this->assertTrue(file_exists("{$this->basedir}/weird/whizbang/info.xml"));
$this->assertTrue(file_exists("{$this->basedir}/weird/whizbang/newextension.php"));
$this->assertFalse(file_exists("{$this->basedir}/weird/whizbang/oddball.php"));
$this->assertEquals('newextension', $this->mapper->keyToInfo('test.whiz.bang')->file);
$this->assertDBQuery('newextension', 'SELECT file FROM civicrm_extension WHERE full_name ="test.whiz.bang"');
}
/**
* Install a module and then delete (leaving stale DB info); restore
* the module by downloading new code.
*
* Note that some metadata changes between versions -- the original has
* file="oddball", and the upgrade has file="newextension".
*/
function testReplace_InstalledMissing() {
$testingTypeManager = $this->getMock('CRM_Extension_Manager_Interface');
$manager = $this->_createManager(array(
self::TESTING_TYPE => $testingTypeManager,
));
// initial installation
$this->assertEquals('uninstalled', $manager->getStatus('test.whiz.bang'));
$manager->install(array('test.whiz.bang'));
$this->assertEquals('installed', $manager->getStatus('test.whiz.bang'));
// dirty remove
$this->assertTrue(file_exists("{$this->basedir}/weird/whizbang/info.xml"));
CRM_Utils_File::cleanDir("{$this->basedir}/weird/whizbang", TRUE, FALSE);
$this->assertFalse(file_exists("{$this->basedir}/weird/whizbang/info.xml"));
$manager->refresh();
$this->assertEquals('installed-missing', $manager->getStatus('test.whiz.bang'));
// download and reinstall
$this->download = $this->_createDownload('test.whiz.bang', 'newextension');
$testingTypeManager
->expects($this->once())
->method('onPreReplace');
$testingTypeManager
->expects($this->once())
->method('onPostReplace');
$manager->replace($this->download);
$this->assertEquals('installed', $manager->getStatus('test.whiz.bang'));
$this->assertTrue(file_exists("{$this->basedir}/test.whiz.bang/info.xml"));
$this->assertTrue(file_exists("{$this->basedir}/test.whiz.bang/newextension.php"));
$this->assertEquals('newextension', $this->mapper->keyToInfo('test.whiz.bang')->file);
$this->assertDBQuery('newextension', 'SELECT file FROM civicrm_extension WHERE full_name ="test.whiz.bang"');
}
function _createManager($typeManagers) {
//list ($basedir, $c) = $this->_createContainer();
$mapper = new CRM_Extension_Mapper($this->container);
return new CRM_Extension_Manager($this->container, $this->container, $this->mapper, $typeManagers);
}
function _createContainer(CRM_Utils_Cache_Interface $cache = NULL, $cacheKey = NULL) {
$basedir = $this->createTempDir('ext-');
mkdir("$basedir/weird");
mkdir("$basedir/weird/foobar");
file_put_contents("$basedir/weird/foobar/info.xml", "oddball");
// not needed for now // file_put_contents("$basedir/weird/bar/oddball.php", "oddball");
// not needed for now // file_put_contents("$basedir/weird/whizbang/oddball.php", "createTempDir('ext-dl-');
file_put_contents("$basedir/info.xml", "$file");
file_put_contents("$basedir/$file.php", "