1
0
قرینه از https://github.com/matomo-org/matomo.git synced 2025-08-22 15:07:44 +00:00
Files
matomo/plugins/Marketplace/tests/System/Api/ClientTest.php
João Almeida Santos a4d8cebebc Add console plugin:install command (#22640)
* 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>
2024-10-25 09:58:45 +02:00

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();
}
}