قرینه از
https://github.com/matomo-org/matomo.git
synced 2025-08-22 15:07:44 +00:00

* Add console plugin:install command * fix: install the remaining files of the plugin * fix: remove redundant code * fix: mention implicated plugin in error message * refactor: add function parameter type * refactor: move isMarketplaceEnabled check out of the loop * fix: fix plugin not being listed in the plugin manager * refactor: promote pluginManager to class property * Revert "refactor: promote pluginManager to class property" This reverts commit e38d349a955e40fb32c6bdd4bc4f45941b685b2a. * refactor: simplify method signature * fix: improve error message when plugin is not downloadable * chore: fix code indentation * refactor: use dependency injection for PluginInstaller * feat: make sure config file is writable * chore: update CHANGELOG file * feat: make plugin:install command able to also update the plugin * Apply suggestions from code review --------- Co-authored-by: Stefan Giehl <stefan@matomo.org>
321 خطوط
10 KiB
PHP
321 خطوط
10 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Matomo - free/libre analytics platform
|
|
*
|
|
* @link https://matomo.org
|
|
* @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
|
*/
|
|
|
|
namespace Piwik\Plugins\Marketplace\tests\System\Api;
|
|
|
|
use Piwik\Cache;
|
|
use Piwik\Http;
|
|
use Piwik\Plugin;
|
|
use Piwik\Plugins\Marketplace\Api\Client;
|
|
use Piwik\Plugins\Marketplace\Api\Service;
|
|
use Piwik\Plugins\Marketplace\Environment;
|
|
use Piwik\Plugins\Marketplace\Input\PurchaseType;
|
|
use Piwik\Tests\Framework\TestCase\SystemTestCase;
|
|
use Piwik\Version;
|
|
use Piwik\Plugins\Marketplace\tests\Framework\Mock\Service as TestService;
|
|
use Piwik\Log\NullLogger;
|
|
|
|
/**
|
|
* @group Plugins
|
|
* @group Marketplace
|
|
* @group ClientTest
|
|
* @group Client
|
|
*/
|
|
class ClientTest extends SystemTestCase
|
|
{
|
|
private $domain = 'http://plugins.piwik.org';
|
|
|
|
/**
|
|
* @var Client
|
|
*/
|
|
private $client;
|
|
|
|
/**
|
|
* @var Environment
|
|
*/
|
|
private $environment;
|
|
|
|
public function setUp(): void
|
|
{
|
|
$releaseChannels = new Plugin\ReleaseChannels(Plugin\Manager::getInstance());
|
|
$this->environment = new Environment($releaseChannels);
|
|
|
|
$this->client = $this->buildClient();
|
|
$this->getCache()->flushAll();
|
|
}
|
|
|
|
public function testGetPluginInfoExistingPluginOnTheMarketplace()
|
|
{
|
|
$plugin = $this->client->getPluginInfo('SecurityInfo');
|
|
|
|
$expectedPluginKeys = array(
|
|
'name',
|
|
'displayName',
|
|
'owner',
|
|
'description',
|
|
'homepage',
|
|
'createdDateTime',
|
|
'donate',
|
|
'support',
|
|
'isTheme',
|
|
'keywords',
|
|
'basePrice',
|
|
'authors',
|
|
'repositoryUrl',
|
|
'lastUpdated',
|
|
'latestVersion',
|
|
'numDownloads',
|
|
'screenshots',
|
|
'coverImage',
|
|
'previews',
|
|
'activity',
|
|
'featured',
|
|
'isFree',
|
|
'isPaid',
|
|
'isBundle',
|
|
'isCustomPlugin',
|
|
'shop',
|
|
'bundle',
|
|
'specialOffer',
|
|
'category',
|
|
'versions',
|
|
'isDownloadable',
|
|
'changelog',
|
|
'consumer');
|
|
|
|
$this->assertNotEmpty($plugin);
|
|
$this->assertEquals($expectedPluginKeys, array_keys($plugin));
|
|
$this->assertSame('SecurityInfo', $plugin['name']);
|
|
$this->assertSame('matomo-org', $plugin['owner']);
|
|
$this->assertTrue(is_array($plugin['keywords']));
|
|
$this->assertNotEmpty($plugin['authors']);
|
|
$this->assertGreaterThan(1000, $plugin['numDownloads']);
|
|
$this->assertTrue($plugin['isFree']);
|
|
$this->assertFalse($plugin['isPaid']);
|
|
$this->assertFalse($plugin['isCustomPlugin']);
|
|
$this->assertNotEmpty($plugin['versions']);
|
|
$this->assertNotEmpty($plugin['coverImage']);
|
|
$this->assertNotEmpty($plugin['category']);
|
|
|
|
$lastVersion = $plugin['versions'][count($plugin['versions']) - 1];
|
|
$this->assertEquals(
|
|
array('name', 'release', 'requires', 'wordPressCompatible', 'onPremiseCompatible', 'numDownloads', 'license', 'repositoryChangelogUrl', 'readmeHtml', 'download'),
|
|
array_keys($lastVersion)
|
|
);
|
|
$this->assertNotEmpty($lastVersion['download']);
|
|
}
|
|
|
|
public function testGetPluginInfoShouldThrowExceptionIfPluginDoesNotExistOnMarketplace()
|
|
{
|
|
$this->expectException(\Piwik\Plugins\Marketplace\Api\Exception::class);
|
|
$this->expectExceptionMessage('Requested plugin does not exist.');
|
|
|
|
$this->client->getPluginInfo('NotExistingPlugIn');
|
|
}
|
|
|
|
public function testGetConsumerShouldReturnNullAndNotThrowExceptionIfNotAuthorized()
|
|
{
|
|
$this->assertNull($this->client->getConsumer());
|
|
}
|
|
|
|
public function testIsValidConsumerShouldReturnFalseAndNotThrowExceptionIfNotAuthorized()
|
|
{
|
|
$this->assertFalse($this->client->isValidConsumer());
|
|
}
|
|
|
|
public function testSearchForPluginsRequestAll()
|
|
{
|
|
$plugins = $this->client->searchForPlugins($keywords = '', $query = '', $sort = '', $purchaseType = PurchaseType::TYPE_ALL);
|
|
|
|
$this->assertGreaterThan(15, count($plugins));
|
|
|
|
foreach ($plugins as $plugin) {
|
|
$this->assertNotEmpty($plugin['name']);
|
|
$this->assertFalse($plugin['isTheme']);
|
|
}
|
|
}
|
|
|
|
public function testSearchForPluginsOnlyFree()
|
|
{
|
|
$plugins = $this->client->searchForPlugins($keywords = '', $query = '', $sort = '', $purchaseType = PurchaseType::TYPE_FREE);
|
|
|
|
$this->assertGreaterThan(15, count($plugins));
|
|
|
|
foreach ($plugins as $plugin) {
|
|
$this->assertTrue($plugin['isFree']);
|
|
$this->assertFalse($plugin['isPaid']);
|
|
$this->assertFalse($plugin['isTheme']);
|
|
}
|
|
}
|
|
|
|
public function testSearchForPluginsOnlyPaid()
|
|
{
|
|
$plugins = $this->client->searchForPlugins($keywords = '', $query = '', $sort = '', $purchaseType = PurchaseType::TYPE_PAID);
|
|
|
|
$this->assertGreaterThanOrEqual(1, count($plugins));
|
|
$this->assertLessThan(30, count($plugins));
|
|
|
|
foreach ($plugins as $plugin) {
|
|
$this->assertFalse($plugin['isFree']);
|
|
$this->assertTrue($plugin['isPaid']);
|
|
$this->assertFalse($plugin['isTheme']);
|
|
}
|
|
}
|
|
|
|
public function testSearchForPluginsWithKeyword()
|
|
{
|
|
$plugins = $this->client->searchForPlugins($keywords = 'login', $query = '', $sort = '', $purchaseType = PurchaseType::TYPE_ALL);
|
|
|
|
$this->assertGreaterThanOrEqual(1, count($plugins));
|
|
$this->assertLessThan(30, count($plugins));
|
|
|
|
foreach ($plugins as $plugin) {
|
|
self::assertContains($keywords, $plugin['keywords']);
|
|
}
|
|
}
|
|
|
|
public function testSearchForThemesRequestAll()
|
|
{
|
|
$plugins = $this->client->searchForThemes($keywords = '', $query = '', $sort = '', $purchaseType = PurchaseType::TYPE_ALL);
|
|
|
|
$this->assertGreaterThanOrEqual(1, count($plugins));
|
|
$this->assertLessThan(50, count($plugins));
|
|
|
|
foreach ($plugins as $plugin) {
|
|
$this->assertNotEmpty($plugin['name']);
|
|
$this->assertTrue($plugin['isTheme']);
|
|
}
|
|
}
|
|
|
|
public function testGetDownloadUrl()
|
|
{
|
|
$url = $this->client->getDownloadUrl('SecurityInfo');
|
|
|
|
$start = $this->domain . '/api/2.0/plugins/SecurityInfo/download/';
|
|
$end = '?coreVersion=' . Version::VERSION;
|
|
|
|
$this->assertStringStartsWith($start, $url);
|
|
$this->assertStringEndsWith($end, $url);
|
|
|
|
$version = str_replace(array($start, $end), '', $url);
|
|
|
|
$this->assertNotEmpty($version);
|
|
$this->assertRegExp('/\d+\.\d+\.\d+/', $version);
|
|
}
|
|
|
|
public function testGetDownloadUrlMissingLicense()
|
|
{
|
|
$this->expectException(\Piwik\Plugins\Marketplace\Api\Exception::class);
|
|
$this->expectExceptionMessage('Plugin is not downloadable');
|
|
|
|
$this->client->getDownloadUrl('FormAnalytics');
|
|
}
|
|
|
|
public function testClientResponseShouldBeCached()
|
|
{
|
|
$params = array(
|
|
'keywords' => 'login',
|
|
'purchase_type' => '',
|
|
'query' => '',
|
|
'sort' => '',
|
|
'release_channel' => 'latest_stable',
|
|
'prefer_stable' => 1,
|
|
'piwik' => Version::VERSION,
|
|
'php' => $this->environment->getPhpVersion(),
|
|
'mysql' => $this->environment->getMySQLVersion(),
|
|
'num_users' => $this->environment->getNumUsers(),
|
|
'num_websites' => $this->environment->getNumWebsites()
|
|
);
|
|
$id = 'marketplace.api.2.0.plugins.' . md5(Http::buildQuery($params));
|
|
|
|
$cache = $this->getCache();
|
|
$this->assertFalse($cache->contains($id));
|
|
|
|
$this->client->searchForPlugins($keywords = 'login', $query = '', $sort = '', $purchaseType = PurchaseType::TYPE_ALL);
|
|
|
|
$this->assertTrue($cache->contains($id));
|
|
$cachedPlugins = $cache->fetch($id);
|
|
|
|
self::assertIsArray($cachedPlugins);
|
|
$this->assertNotEmpty($cachedPlugins);
|
|
$this->assertGreaterThan(30, $cachedPlugins);
|
|
}
|
|
|
|
public function testCachedClientResponseShouldBeReturned()
|
|
{
|
|
$params = array(
|
|
'keywords' => 'login',
|
|
'purchase_type' => '',
|
|
'query' => '',
|
|
'sort' => '',
|
|
'release_channel' => 'latest_stable',
|
|
'prefer_stable' => 1,
|
|
'piwik' => Version::VERSION,
|
|
'php' => $this->environment->getPhpVersion(),
|
|
'mysql' => $this->environment->getMySQLVersion(),
|
|
'num_users' => $this->environment->getNumUsers(),
|
|
'num_websites' => $this->environment->getNumWebsites());
|
|
$id = 'marketplace.api.2.0.plugins.' . md5(Http::buildQuery($params));
|
|
|
|
$cache = $this->getCache();
|
|
$cache->save($id, array('plugins' => array(array('name' => 'foobar'))));
|
|
|
|
$result = $this->client->searchForPlugins($keywords = 'login', $query = '', $sort = '', $purchaseType = PurchaseType::TYPE_ALL);
|
|
|
|
$this->assertSame(array(array('name' => 'foobar')), $result);
|
|
}
|
|
|
|
public function testGetInfoOfPluginsHavingUpdate()
|
|
{
|
|
$service = new TestService($this->domain);
|
|
$client = $this->buildClient($service);
|
|
|
|
$pluginTest = array();
|
|
if (!Plugin\Manager::getInstance()->isPluginLoaded('CustomAlerts')) {
|
|
$pluginTest[] = Plugin\Manager::getInstance()->loadPlugin('CustomAlerts');
|
|
} else {
|
|
$pluginTest[] = Plugin\Manager::getInstance()->getLoadedPlugin('CustomAlerts');
|
|
}
|
|
|
|
$client->getInfoOfPluginsHavingUpdate($pluginTest);
|
|
|
|
$this->assertSame('plugins/checkUpdates', $service->action);
|
|
$this->assertSame(array('plugins', 'release_channel', 'prefer_stable', 'piwik', 'php', 'mysql', 'num_users', 'num_websites'), array_keys($service->params));
|
|
|
|
$plugins = $service->params['plugins'];
|
|
self::assertIsString($plugins);
|
|
$this->assertJson($plugins);
|
|
$plugins = json_decode($plugins, true);
|
|
|
|
$names = array(
|
|
'CustomAlerts' => true,
|
|
);
|
|
foreach ($plugins['plugins'] as $plugin) {
|
|
$this->assertNotEmpty($plugin['version']);
|
|
unset($names[$plugin['name']]);
|
|
}
|
|
|
|
$this->assertEmpty($names);
|
|
}
|
|
|
|
private function buildClient($service = null)
|
|
{
|
|
if (!isset($service)) {
|
|
$service = new Service($this->domain);
|
|
}
|
|
|
|
return new Client($service, $this->getCache(), new NullLogger(), $this->environment);
|
|
}
|
|
|
|
private function getCache()
|
|
{
|
|
return Cache::getLazyCache();
|
|
}
|
|
}
|