<?php
namespace Croogo\Core\Test\TestCase;
use Cake\Cache\Cache;
use Cake\Core\App;
use Cake\Core\Configure;
use Cake\Datasource\ConnectionManager;
use Croogo\Core\PluginManager;
use Croogo\Core\TestSuite\TestCase;
class PluginTest extends TestCase
{
/**
* @var \Croogo\Core\Plugin
*/
public $plugin;
/**
* @var \PDO Backup connection instance
*/
public $connection;
public function setUp()
{
parent::setUp();
$this->plugin = $this->getMockBuilder(PluginManager::class)
->setMethods([
'_writeSetting',
'needMigration',
])
->getMock();
$this->_mapping = [
1346748762 => [
'version' => 1346748762,
'name' => '1346748762_first',
'class' => 'First',
'type' => 'app',
'migrated' => '2012-09-04 10:52:42'
],
1346748933 => [
'version' => 1346748933,
'name' => '1346748933_addstatus',
'class' => 'AddStatus',
'type' => 'app',
'migrated' => '2012-09-04 10:55:33'
]
];
// Backup the PDO connection instance as the Migrations CakeAdapter replaces it with Phinx's.
$this->connection = ConnectionManager::get('test')
->getDriver()
->getConnection();
}
public function tearDown()
{
parent::tearDown();
unset($this->plugin);
// Restore the PDO connection instance
ConnectionManager::get('test')->getDriver()->getConnection($this->connection);
}
protected function _getMockMigrationVersion()
{
return $this->getMockBuilder('MigrationVersion')
->setMethods([
'getMapping',
'run'
])
->disableOriginalConstructor()
->getMock();
}
public function testGetDataPluginNotActive()
{
$actives = Configure::read('Hook.bootstraps');
Configure::write('Hook.bootstraps', '');
$suppliers = $this->plugin->getData('Suppliers');
$needed = [
'name' => 'Suppliers',
'description' => 'Suppliers plugin',
'active' => false,
'needMigration' => false
];
$this->assertEquals($needed, $suppliers);
Configure::write('Hook.bootstraps', $actives);
}
public function testGetDataPluginActive()
{
$actives = Configure::read('Hook.bootstraps');
Configure::write('Hook.bootstraps', 'suppliers');
$migrationVersion = $this->_getMockMigrationVersion();
$croogoPlugin = new PluginManager($migrationVersion);
$suppliers = $croogoPlugin->getData('Suppliers');
$needed = [
'name' => 'Suppliers',
'description' => 'Suppliers plugin',
'active' => true,
'needMigration' => false
];
$this->assertEquals($needed, $suppliers);
Configure::write('Hook.bootstraps', $actives);
}
public function testGetDataPluginNotExists()
{
$data = $this->plugin->getData('NotARealPlugin');
$this->assertEquals(false, $data);
}
public function testGetDataWithEmptyJson()
{
$expected = [
'needMigration' => false, 'active' => false, 'name' => 'EmptyJson',
];
$data = $this->plugin->getData('EmptyJson');
$this->assertEquals($expected, $data);
}
public function testGetDataWithMixedManifest()
{
$data = $this->plugin->getData('MixedManifest');
$expected = [
'active', 'dependencies', 'description', 'name', 'needMigration',
'type', 'vendor',
];
$keys = array_keys($data);
sort($keys);
$this->assertEquals($expected, $keys);
$this->assertContains('test plugin with mixed', $data['description']);
$this->assertEquals('croogo-plugin', $data['type']);
$this->assertEquals('MixedManifest', $data['name']);
}
public function testNeedMigrationPluginNotExists()
{
$migrationVersion = $this->_getMockMigrationVersion();
$migrationVersion->expects($this->any())
->method('getMapping')
->will($this->returnValue(false));
$croogoPlugin = new PluginManager($migrationVersion);
$this->assertEquals(false, $croogoPlugin->needMigration('Anything', true));
}
public function testNeedMigrationPluginNotActive()
{
$croogoPlugin = new PluginManager();
$this->assertEquals(false, $croogoPlugin->needMigration('Anything', false));
}
public function testNeedMigrationPluginNoMigration()
{
$this->markTestSkipped('This test needs to be ported to CakePHP 3.0');
$migrationVersion = $this->_getMockMigrationVersion();
$migrationVersion->expects($this->any())
->method('getMapping')
->will($this->returnValue($this->_mapping));
$migrationVersion->expects($this->any())
->method('getVersion')
->will($this->returnValue(1346748933));
$croogoPlugin = new PluginManager($migrationVersion);
$this->assertEquals(false, $croogoPlugin->needMigration('app', true));
}
public function testNeedMigrationPluginWithMigration()
{
$this->markTestSkipped('This test needs to be ported to CakePHP 3.0');
$migrationVersion = $this->_getMockMigrationVersion();
$migrationVersion->expects($this->any())
->method('getMapping')
->will($this->returnValue($this->_mapping));
$migrationVersion->expects($this->any())
->method('getVersion')
->will($this->returnValue(1346748762));
$croogoPlugin = new PluginManager($migrationVersion);
$this->assertEquals(true, $croogoPlugin->needMigration('app', true));
}
public function testMigratePluginNotNeedMigration()
{
$this->markTestSkipped('This test needs to be ported to CakePHP 3.0');
$actives = Configure::read('Hook.bootstraps');
Configure::write('Hook.bootstraps', 'Suppliers');
$migrationVersion = $this->_getMockMigrationVersion();
$migrationVersion->expects($this->any())
->method('getMapping')
->will($this->returnValue($this->_mapping));
$croogoPlugin = new PluginManager($migrationVersion);
$this->assertEquals(false, $croogoPlugin->migrate('Suppliers'));
Configure::read('Hook.bootstraps', $actives);
}
public function testMigratePluginWithMigration()
{
PluginManager::load('Suppliers');
$actives = Configure::read('Hook.bootstraps');
Configure::write('Hook.bootstraps', 'Suppliers');
$migrationVersion = $this->_getMockMigrationVersion();
$migrationVersion->expects($this->any())
->method('getMapping')
->will($this->returnValue($this->_mapping));
$migrationVersion->expects($this->any())
->method('run')
->with($this->logicalAnd($this->arrayHasKey('version'), $this->arrayHasKey('type')))
->will($this->returnValue(true));
$croogoPlugin = new Plugin($migrationVersion);
$this->assertEquals(true, $croogoPlugin->migrate('Suppliers'));
Configure::read('Hook.bootstraps', $actives);
}
public function testMigratePluginWithMigrationError()
{
$this->markTestSkipped('This test needs to be ported to CakePHP 3.0');
$actives = Configure::read('Hook.bootstraps');
Configure::write('Hook.bootstraps', 'Suppliers');
$migrationVersion = $this->_getMockMigrationVersion();
$migrationVersion->expects($this->any())
->method('getMapping')
->will($this->returnValue($this->_mapping));
$migrationVersion->expects($this->any())
->method('run')
->will($this->returnValue('An error message'));
$croogoPlugin = new PluginManager($migrationVersion);
$expectedErrors = ['An error message'];
$this->assertEquals(false, $croogoPlugin->migrate('Suppliers'));
$this->assertEquals($expectedErrors, $croogoPlugin->migrationErrors);
Configure::read('Hook.bootstraps', $actives);
}
public function testUnmigrate()
{
$this->markTestSkipped('This test needs to be ported to CakePHP 3.0');
$actives = Configure::read('Hook.bootstraps');
Configure::write('Hook.bootstraps', 'Suppliers');
$migrationVersion = $this->_getMockMigrationVersion();
$migrationVersion->expects($this->once())
->method('getMapping')
->will($this->returnValue($this->_mapping));
$migrationVersion->expects($this->once())
->method('run')
->with($this->arrayHasKey('version', 'type', 'direction'))
->will($this->returnValue(true));
$croogoPlugin = new PluginManager($migrationVersion);
$this->assertEquals(true, $croogoPlugin->unmigrate('Suppliers'));
Configure::read('Hook.bootstraps', $actives);
}
public function testUnmigrateNoMapping()
{
$this->markTestSkipped('This test needs to be ported to CakePHP 3.0');
$actives = Configure::read('Hook.bootstraps');
Configure::write('Hook.bootstraps', 'Suppliers');
$migrationVersion = $this->_getMockMigrationVersion();
$migrationVersion->expects($this->once())
->method('getMapping')
->will($this->returnValue([]));
$migrationVersion->expects($this->never())
->method('run')
->will($this->returnValue(false));
$croogoPlugin = new PluginManager($migrationVersion);
$this->assertEquals(false, $croogoPlugin->unmigrate('Suppliers'));
Configure::read('Hook.bootstraps', $actives);
}
/**
* testReorderBootstraps
*/
public function testReorderBootstraps()
{
$bootstraps = explode(',', 'Croogo/Settings,Croogo/Taxonomy,Sites,Croogo/Example');
$expected = 'Croogo/Example is already at the last position';
$result = $this->plugin->move('down', 'Croogo/Example', $bootstraps);
$this->assertEquals($expected, $result);
// core and bundled plugins must not be reordered
$result = $this->plugin->move('up', 'Sites', $bootstraps);
$this->assertEquals('Sites is already at the first position', $result);
$bootstraps = explode(',', 'Croogo/Example,Croogo/Settings,Croogo/Taxonomy,Sites');
$result = $this->plugin->move('up', 'Croogo/Example', $bootstraps);
$this->assertEquals('Croogo/Example is already at the first position', $result);
}
/**
* testReorderBootstrapsWithDependency
*/
public function testReorderBootstrapsWithDependency()
{
$bootstraps = explode(',', 'Widgets,Editors');
$expected = 'Plugin Editors depends on Widgets';
$result = $this->plugin->move('up', 'Editors', $bootstraps);
$this->assertEquals($expected, $result);
$expected = 'Plugin Editors depends on Widgets';
$result = $this->plugin->move('down', 'Widgets', $bootstraps);
$this->assertEquals($expected, $result);
}
/**
* testDeleteEmptyPlugin
* @expectedException InvalidArgumentException
*/
public function testDeleteEmptyPlugin()
{
$this->plugin->delete(null);
}
/**
* testUsedBy
*/
public function testUsedBy()
{
Cache::delete('pluginDeps', 'cached_settings');
PluginManager::load('Widgets');
PluginManager::load('Editors');
PluginManager::load('Articles');
PluginManager::cacheDependencies();
$usedBy = $this->plugin->usedBy('Widgets');
$this->assertTrue(in_array('Articles', $usedBy));
$this->assertTrue(in_array('Editors', $usedBy));
PluginManager::unload('Articles');
PluginManager::unload('Editors');
PluginManager::unload('Widgets');
}
/**
* @dataProvider pathDataProvider
*/
public function testPath($plugin, $path, $expectedException = null)
{
$this->setExpectedException($expectedException);
$this->assertEquals($path, Plugin::path($plugin));
}
/**
* @dataProvider pathDataProvider
*/
public function testAvailable($plugin, $path)
{
if ($path) {
$this->assertTrue(PluginManager::available($plugin));
return;
}
$this->assertFalse(PluginManager::available($plugin));
}
public function testEventsSinglePlugin()
{
PluginManager::load('Shops', [
'events' => true
]);
$this->assertTrue(PluginManager::events('Shops'));
$this->assertEquals([
'Shops.ShopsNodesEventHandler',
'Shops.ShopsEventHandler' => [
'options' => [
'priority' => 1
]
]
], Configure::read('EventHandlers'));
}
public function testEventsAllPlugins()
{
PluginManager::load('Shops', [
'events' => true
]);
$this->assertTrue(PluginManager::events());
$this->assertContains('Shops.ShopsNodesEventHandler', Configure::read('EventHandlers'));
}
public function pathDataProvider()
{
return [
// Internal Croogo plugins based on Croogo/Core path
['Croogo/Core', CROOGO_INCLUDE_PATH . 'Core' . DS],
['Croogo/Nodes', CROOGO_INCLUDE_PATH . 'Nodes' . DS],
// Plugin paths from the 'plugins' Configure key
['BootstrapUI', VENDOR . 'friendsofcake' . DS . 'bootstrap-ui' . DS],
// Plugin path from the plugins directory
['Shops', App::path('Plugin')[0] . 'Shops'],
// A non existing plugin
['NonExisting', false, 'Cake\\Core\\Exception\\MissingPluginException']
];
}
}