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

* [Coding Style] Enable rule PSR12.Files.FileHeader * Apply CS * Replace Piwik with Matomo in file headers * Unify file headers (position, no. of lines, https links) * Rebuild dist files * Apply CS * Fix system test that relies on line numbers in a file that had the file header updated --------- Co-authored-by: Stefan Giehl <stefan@matomo.org>
310 خطوط
10 KiB
PHP
310 خطوط
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\API\tests\System;
|
|
|
|
use Piwik\API\Request;
|
|
use Piwik\Application\Environment;
|
|
use Piwik\ArchiveProcessor\Rules;
|
|
use Piwik\Cache as PiwikCache;
|
|
use Piwik\Columns\Dimension;
|
|
use Piwik\Common;
|
|
use Piwik\Date;
|
|
use Piwik\Option;
|
|
use Piwik\Plugins\API\API;
|
|
use Piwik\Plugins\CustomVariables\Columns\CustomVariableName;
|
|
use Piwik\Plugins\CustomVariables\Columns\CustomVariableValue;
|
|
use Piwik\Tests\Fixtures\ManyVisitsWithGeoIPAndEcommerce;
|
|
use Piwik\Tests\Framework\TestCase\SystemTestCase;
|
|
use Piwik\Tracker\Cache;
|
|
|
|
// Class to cache results of getSuggestedValuesForSegment to prevent it beeing called multiple time for each segment
|
|
class CachedAPI extends API
|
|
{
|
|
public static $cache = [];
|
|
|
|
public function getSuggestedValuesForSegment($segmentName, $idSite)
|
|
{
|
|
if (empty(self::$cache[$segmentName . $idSite])) {
|
|
self::$cache[$segmentName . $idSite] = parent::getSuggestedValuesForSegment($segmentName, $idSite);
|
|
}
|
|
return self::$cache[$segmentName . $idSite];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* testing a the auto suggest API for all known segments
|
|
*
|
|
* @group AutoSuggestAPITest
|
|
* @group Plugins
|
|
*/
|
|
class AutoSuggestAPITest extends SystemTestCase
|
|
{
|
|
public static $fixture = null; // initialized below class definition
|
|
|
|
private static $originalAutoSuggestLookBack = null;
|
|
|
|
protected static $processed = 0;
|
|
protected static $skipped = array();
|
|
private static $hasArchivedData = false;
|
|
|
|
public static function setUpBeforeClass(): void
|
|
{
|
|
$date = mktime(0, 0, 0, 1, 1, 2018);
|
|
|
|
$lookBack = ceil((time() - $date) / 86400);
|
|
|
|
self::$originalAutoSuggestLookBack = API::$_autoSuggestLookBack;
|
|
|
|
API::$_autoSuggestLookBack = $lookBack;
|
|
self::$fixture->dateTime = Date::factory($date)->getDatetime();
|
|
|
|
parent::setUpBeforeClass();
|
|
|
|
API::setSingletonInstance(CachedAPI::getInstance());
|
|
}
|
|
|
|
public static function tearDownAfterClass(): void
|
|
{
|
|
API::$_autoSuggestLookBack = self::$originalAutoSuggestLookBack;
|
|
|
|
parent::tearDownAfterClass();
|
|
|
|
CachedAPI::$cache = [];
|
|
API::unsetInstance();
|
|
}
|
|
|
|
/**
|
|
* @dataProvider getApiForTesting
|
|
*/
|
|
public function testApi($api, $params)
|
|
{
|
|
Cache::clearCacheGeneral();
|
|
|
|
$this->runApiTests($api, $params);
|
|
}
|
|
|
|
public function getApiForTesting()
|
|
{
|
|
$idSite = self::$fixture->idSite;
|
|
$segments = self::getSegmentsMetadata();
|
|
|
|
$apiForTesting = array();
|
|
foreach ($segments as $segment) {
|
|
$apiForTesting[] = $this->getApiForTestingForSegment($idSite, $segment);
|
|
}
|
|
|
|
if (self::isMysqli()) {
|
|
// Skip the test on Mysqli as it fails due to rounding Float errors on latitude/longitude
|
|
// then the test started failing after bc19503 and I cannot understand why
|
|
echo "Skipped test \n";
|
|
} else {
|
|
$apiForTesting[] = array('Live.getLastVisitsDetails',
|
|
array('idSite' => $idSite,
|
|
'date' => '1998-07-12,today',
|
|
'period' => 'range',
|
|
'otherRequestParameters' => array('filter_limit' => 1000)));
|
|
}
|
|
return $apiForTesting;
|
|
}
|
|
|
|
/**
|
|
* @dataProvider getApiForTestingBrowserArchivingDisabled
|
|
*/
|
|
public function testApiBrowserArchivingDisabled($api, $params)
|
|
{
|
|
if (!self::$hasArchivedData) {
|
|
self::$hasArchivedData = true;
|
|
// need to make sure data is archived before disabling the archiving
|
|
Request::processRequest('API.get', array(
|
|
'date' => '2018-01-10', 'period' => 'year', 'idSite' => $params['idSite'],
|
|
'trigger' => 'archivephp'
|
|
));
|
|
}
|
|
|
|
Cache::clearCacheGeneral();
|
|
// disable browser archiving so the APIs are used
|
|
Option::set(Rules::OPTION_BROWSER_TRIGGER_ARCHIVING, 0);
|
|
|
|
$this->runApiTests($api, $params);
|
|
|
|
Option::set(Rules::OPTION_BROWSER_TRIGGER_ARCHIVING, 1);
|
|
}
|
|
|
|
public function getApiForTestingBrowserArchivingDisabled()
|
|
{
|
|
$idSite = self::$fixture->idSite;
|
|
$segments = self::getSegmentsMetadata($onlyWithSuggestedValuesApi = true);
|
|
|
|
$apiForTesting = array();
|
|
foreach ($segments as $segment) {
|
|
$apiForTesting[] = $this->getApiForTestingForSegment($idSite, $segment);
|
|
}
|
|
|
|
return $apiForTesting;
|
|
}
|
|
|
|
/**
|
|
* @param $idSite
|
|
* @param $segment
|
|
* @return array
|
|
*/
|
|
protected function getApiForTestingForSegment($idSite, $segment)
|
|
{
|
|
return array('API.getSuggestedValuesForSegment',
|
|
array('idSite' => $idSite,
|
|
'testSuffix' => '_' . $segment,
|
|
'otherRequestParameters' => array('segmentName' => $segment)));
|
|
}
|
|
|
|
/**
|
|
* @depends testApi
|
|
* @dataProvider getAnotherApiForTesting
|
|
*/
|
|
public function testAnotherApi($api, $params)
|
|
{
|
|
// Get the top segment value
|
|
$request = new Request(
|
|
'method=API.getSuggestedValuesForSegment'
|
|
. '&segmentName=' . $params['segmentToComplete']
|
|
. '&idSite=' . $params['idSite']
|
|
. '&format=json'
|
|
);
|
|
$response = json_decode($request->process(), true);
|
|
$this->assertApiResponseHasNoError($response);
|
|
$topSegmentValue = @$response[0];
|
|
|
|
if ($topSegmentValue !== false && !is_null($topSegmentValue)) {
|
|
if (is_numeric($topSegmentValue) || is_float($topSegmentValue) || preg_match('/^\d*?,\d*$/', $topSegmentValue)) {
|
|
$topSegmentValue = Common::forceDotAsSeparatorForDecimalPoint($topSegmentValue);
|
|
}
|
|
|
|
// use some specific test values for segments where auto suggest returns list of values that might not occur
|
|
switch ($params['segmentToComplete']) {
|
|
case 'countryName':
|
|
$topSegmentValue = 'France';
|
|
break;
|
|
case 'browserName':
|
|
$topSegmentValue = 'Chrome';
|
|
break;
|
|
case 'operatingSystemName':
|
|
$topSegmentValue = 'Android';
|
|
break;
|
|
case 'visitEndServerDate':
|
|
$topSegmentValue = '2018-01-03';
|
|
break;
|
|
case 'visitEndServerDayOfMonth':
|
|
$topSegmentValue = '03';
|
|
break;
|
|
case 'visitEndServerYear':
|
|
$topSegmentValue = '2018';
|
|
break;
|
|
case 'visitLocalMinute':
|
|
$topSegmentValue = '34';
|
|
break;
|
|
}
|
|
|
|
// Now build the segment request
|
|
$segmentValue = rawurlencode(html_entity_decode($topSegmentValue, ENT_COMPAT | ENT_HTML401, 'UTF-8'));
|
|
$params['segment'] = $params['segmentToComplete'] . '==' . $segmentValue;
|
|
unset($params['segmentToComplete']);
|
|
$this->runApiTests($api, $params);
|
|
self::$processed++;
|
|
} else {
|
|
self::$skipped[] = $params['segmentToComplete'];
|
|
}
|
|
}
|
|
|
|
public function getAnotherApiForTesting()
|
|
{
|
|
$segments = self::getSegmentsMetadata();
|
|
|
|
$apiForTesting = array();
|
|
foreach ($segments as $segment) {
|
|
$apiForTesting[] = array('VisitsSummary.get',
|
|
array('idSite' => self::$fixture->idSite,
|
|
'date' => date("Y-m-d", strtotime(self::$fixture->dateTime)) . ',today',
|
|
'period' => 'range',
|
|
'testSuffix' => '_' . $segment,
|
|
'segmentToComplete' => $segment));
|
|
}
|
|
return $apiForTesting;
|
|
}
|
|
|
|
/**
|
|
* @depends testAnotherApi
|
|
*/
|
|
public function testCheckOtherTestsWereComplete()
|
|
{
|
|
// Check that only a few haven't been tested specifically (these are all custom variables slots since we only test slot 1, 2, 5 (see the fixture) and example dimension slots and bandwidth)
|
|
$maximumSegmentsToSkip = 24;
|
|
$this->assertLessThan($maximumSegmentsToSkip, count(self::$skipped), 'SKIPPED ' . count(self::$skipped) . ' segments --> some segments had no "auto-suggested values"
|
|
but we should try and test the autosuggest for all new segments. Segments skipped were: ' . implode(', ', self::$skipped));
|
|
|
|
// and check that most others have been tested
|
|
$minimumSegmentsToTest = 46;
|
|
$message = 'PROCESSED ' . self::$processed . ' segments --> it seems some segments "auto-suggested values" haven\'t been tested as we were expecting. ';
|
|
$this->assertGreaterThan($minimumSegmentsToTest, self::$processed, $message);
|
|
}
|
|
|
|
public static function getSegmentsMetadata($onlyWithSuggestedValuesApi = false)
|
|
{
|
|
Cache::clearCacheGeneral();
|
|
PiwikCache::getTransientCache()->flushAll();
|
|
|
|
$segments = array();
|
|
|
|
$environment = new Environment(null);
|
|
|
|
$exception = null;
|
|
try {
|
|
$environment->init();
|
|
$environment->getContainer()->get('Piwik\Plugin\Manager')->loadActivatedPlugins();
|
|
|
|
foreach (Dimension::getAllDimensions() as $dimension) {
|
|
if (
|
|
$dimension instanceof CustomVariableName
|
|
|| $dimension instanceof CustomVariableValue
|
|
) {
|
|
continue; // ignore custom variables dimensions as they are tested in the plugin
|
|
}
|
|
|
|
foreach ($dimension->getSegments() as $segment) {
|
|
if ($segment->isInternal()) {
|
|
continue;
|
|
}
|
|
if ($onlyWithSuggestedValuesApi && !$segment->getSuggestedValuesApi()) {
|
|
continue;
|
|
}
|
|
$segments[] = $segment->getSegment();
|
|
}
|
|
}
|
|
} catch (\Exception $ex) {
|
|
$exception = $ex;
|
|
|
|
echo $ex->getMessage() . "\n" . $ex->getTraceAsString() . "\n";
|
|
}
|
|
|
|
$environment->destroy();
|
|
|
|
if (!empty($exception)) {
|
|
throw $exception;
|
|
}
|
|
|
|
return $segments;
|
|
}
|
|
|
|
public static function getPathToTestDirectory()
|
|
{
|
|
return dirname(__FILE__);
|
|
}
|
|
}
|
|
|
|
\Piwik\Plugins\API\tests\System\AutoSuggestAPITest::$fixture = new ManyVisitsWithGeoIPAndEcommerce();
|