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

* Add feature flag and update test to use feature flag
* Add rollup behaviour to CustomDimension SQL query generation
* Fix bugs in SQL statement with rollup
* Resolve SQL query bugs
* Process rolled up values correctly
* Fix PHPCS
* Fix PHPCS
* Update Unit tests for ranking query
* Fix PHPCS
* Update broken tests
* Update expected test files
* Add missing expected files
* Revert "Update expected test files"
This reverts commit e5bdd0f414
.
* Update test to view correct expected files
* Added missing expected files
* fix feature flag detection
* Update ApiTest to remove testSuffix bug
* Update expected test files
* Update UI tests broken by new feature
* Wrap new logic around a check for feature flag
* Update expected test files to fix regression issue
* Add feature flag trigger into test
* Fix UI tests broken by test fixture update
* Revert separate functions for withRollup logic
* Update test suite to include ranking limit test withoutnew feature
* Fix formatting in test
* PHPCS fix
* Update Fixture to use correct dimension
* test fix of regression bug
* test fix to regression bug
* Wrap COALESCE around feature flag
* Remove test case from base ranking query test
* PHPCS fix
* Update expected test file
* Housekeeping
---------
Co-authored-by: Marc Neudert <marc@innocraft.com>
457 خطوط
16 KiB
PHP
457 خطوط
16 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\CustomDimensions\tests\System;
|
|
|
|
use Piwik\Cache;
|
|
use Piwik\Context;
|
|
use Piwik\Plugins\CustomDimensions\tests\Fixtures\TrackVisitsWithCustomDimensionsFixture;
|
|
use Piwik\ReportRenderer;
|
|
use Piwik\Tests\Framework\Fixture;
|
|
use Piwik\Tests\Framework\TestCase\SystemTestCase;
|
|
use Piwik\Config;
|
|
use Piwik\Plugins\CustomDimensions\FeatureFlags\CustomDimensionReportWithRollUp;
|
|
|
|
/**
|
|
* @group CustomDimensions
|
|
* @group ApiTest
|
|
* @group Plugins
|
|
*/
|
|
class ApiTest extends SystemTestCase
|
|
{
|
|
/**
|
|
* @var TrackVisitsWithCustomDimensionsFixture
|
|
*/
|
|
public static $fixture = null; // initialized below class definition
|
|
|
|
public static function setUpBeforeClass(): void
|
|
{
|
|
parent::setUpBeforeClass();
|
|
|
|
self::setAllowedModulesToFilterApiResponse('API.getReportMetadata', array('CustomDimensions'));
|
|
self::setAllowedCategoriesToFilterApiResponse('API.getSegmentsMetadata', array('Visitors', 'Behaviour'));
|
|
self::setAllowedModulesToFilterApiResponse('API.getWidgetMetadata', array('CustomDimensions'));
|
|
self::setAllowedCategoriesToFilterApiResponse('API.getReportPagesMetadata', array('Visitors', 'Behaviour'));
|
|
}
|
|
|
|
private static function triggerWithRollupFeatureFlag(bool $enableFlag)
|
|
{
|
|
$config = Config::getInstance();
|
|
$featureFlag = new CustomDimensionReportWithRollUp();
|
|
$featureFlagConfig = $featureFlag->getName() . '_feature';
|
|
|
|
if ($enableFlag) {
|
|
$config->FeatureFlags = [$featureFlagConfig => 'enabled'];
|
|
} else {
|
|
$config->FeatureFlags = [$featureFlagConfig => 'disabled'];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @dataProvider getApiForTesting
|
|
* @dataProvider getMetadataApiForTesting
|
|
*/
|
|
public function testApi($api, $params)
|
|
{
|
|
self::triggerWithRollupFeatureFlag($enableFlag = false);
|
|
self::deleteArchiveTables();
|
|
$this->runApiTests($api, $params);
|
|
}
|
|
|
|
/**
|
|
* @dataProvider getApiForTesting
|
|
*/
|
|
public function testApiWithRollup($api, $params)
|
|
{
|
|
if (!empty($params["testSuffix"])) {
|
|
$params["testSuffix"] .= "_with_rollup";
|
|
}
|
|
self::triggerWithRollupFeatureFlag($enableFlag = true);
|
|
self::deleteArchiveTables();
|
|
$this->runApiTests($api, $params);
|
|
}
|
|
|
|
/**
|
|
* @dataProvider getRankingLimitTestData
|
|
* @dataProvider getRankingLimitTestDataExpanded
|
|
*/
|
|
public function testRankingLimit(
|
|
int $rowsRankingQuery,
|
|
int $rowsTableTopLevel,
|
|
int $rowsTableSubTable,
|
|
string $testSuffix,
|
|
array $additionalRequestParameters = []
|
|
): void {
|
|
self::triggerWithRollupFeatureFlag($enableFlag = false);
|
|
self::deleteArchiveTables();
|
|
$generalConfig = &Config::getInstance()->General;
|
|
$generalConfig['archiving_ranking_query_row_limit'] = $rowsRankingQuery;
|
|
$generalConfig['datatable_archiving_maximum_rows_custom_dimensions'] = $rowsTableTopLevel;
|
|
$generalConfig['datatable_archiving_maximum_rows_subtable_custom_dimensions'] = $rowsTableSubTable;
|
|
|
|
// flush caches to ensure the RecordBuilder picks up the changed configuration
|
|
Cache::flushAll();
|
|
$this->runApiTests(['CustomDimensions.getCustomDimension'], [
|
|
'idSite' => 3,
|
|
'date' => self::$fixture->dateTime,
|
|
'periods' => ['day'],
|
|
'otherRequestParameters' => array_merge(['idDimension' => 1], $additionalRequestParameters),
|
|
'testSuffix' => 'ranking_limit_' . $testSuffix,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* @dataProvider getRankingLimitTestDataWithRollup
|
|
* @dataProvider getRankingLimitTestDataExpandedWithRollup
|
|
*/
|
|
public function testRankingLimitWithRollup(
|
|
int $rowsRankingQuery,
|
|
int $rowsTableTopLevel,
|
|
int $rowsTableSubTable,
|
|
string $testSuffix,
|
|
array $additionalRequestParameters = []
|
|
): void {
|
|
self::triggerWithRollupFeatureFlag($enableFlag = true);
|
|
self::deleteArchiveTables();
|
|
$generalConfig = &Config::getInstance()->General;
|
|
$generalConfig['archiving_ranking_query_row_limit'] = $rowsRankingQuery;
|
|
$generalConfig['datatable_archiving_maximum_rows_custom_dimensions'] = $rowsTableTopLevel;
|
|
$generalConfig['datatable_archiving_maximum_rows_subtable_custom_dimensions'] = $rowsTableSubTable;
|
|
|
|
// flush caches to ensure the RecordBuilder picks up the changed configuration
|
|
Cache::flushAll();
|
|
$this->runApiTests(['CustomDimensions.getCustomDimension'], [
|
|
'idSite' => 3,
|
|
'date' => self::$fixture->dateTime,
|
|
'periods' => ['day'],
|
|
'otherRequestParameters' => array_merge(['idDimension' => 1], $additionalRequestParameters),
|
|
'testSuffix' => 'ranking_limit_with_rollup_' . $testSuffix,
|
|
]);
|
|
}
|
|
|
|
public function getApiForTesting()
|
|
{
|
|
$api = array(
|
|
'CustomDimensions.getCustomDimension',
|
|
);
|
|
|
|
$tests = array(
|
|
array('idSite' => 1, 'idDimension' => 1),
|
|
array('idSite' => 1, 'idDimension' => 2),
|
|
array('idSite' => 1, 'idDimension' => 3),
|
|
array('idSite' => 1, 'idDimension' => 4),
|
|
array('idSite' => 1, 'idDimension' => 5),
|
|
array('idSite' => 1, 'idDimension' => 6),
|
|
array('idSite' => 2, 'idDimension' => 1),
|
|
array('idSite' => 1, 'idDimension' => 999), // dimension does not exist
|
|
);
|
|
|
|
$removeColumns = [
|
|
'sum_time_generation',
|
|
'sum_bandwidth',
|
|
'nb_hits_with_bandwidth',
|
|
'min_bandwidth',
|
|
'max_bandwidth',
|
|
'avg_bandwidth',
|
|
'nb_total_overall_bandwidth',
|
|
'nb_total_pageview_bandwidth',
|
|
'nb_total_download_bandwidth',
|
|
'nb_visits_converted'
|
|
];
|
|
|
|
$apiToTest = array();
|
|
|
|
foreach ($tests as $test) {
|
|
$idSite = $test['idSite'];
|
|
$idDimension = $test['idDimension'];
|
|
|
|
foreach (array('day', 'year') as $period) {
|
|
$apiToTest[] = array($api,
|
|
array(
|
|
'idSite' => $idSite,
|
|
'date' => self::$fixture->dateTime,
|
|
'periods' => array($period),
|
|
'otherRequestParameters' => array(
|
|
'idDimension' => $idDimension,
|
|
'expanded' => '0',
|
|
'flat' => '0',
|
|
),
|
|
'testSuffix' => "{$period}_site_{$idSite}_dimension_{$idDimension}",
|
|
'xmlFieldsToRemove' => $removeColumns
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
$apiToTest[] = array($api, array(
|
|
'idSite' => 1,
|
|
'date' => self::$fixture->dateTime,
|
|
'periods' => array('day'),
|
|
'otherRequestParameters' => array(
|
|
'idDimension' => 3,
|
|
'expanded' => '1',
|
|
'flat' => '0',
|
|
),
|
|
'testSuffix' => "day_site_1_dimension_3_expanded",
|
|
'xmlFieldsToRemove' => $removeColumns
|
|
));
|
|
|
|
$apiToTest[] = array($api, array(
|
|
'idSite' => 1,
|
|
'date' => self::$fixture->dateTime,
|
|
'periods' => array('day'),
|
|
'otherRequestParameters' => array(
|
|
'idDimension' => 3,
|
|
'expanded' => '0',
|
|
'flat' => '1',
|
|
),
|
|
'testSuffix' => "day_site_1_dimension_3_flat",
|
|
'xmlFieldsToRemove' => $removeColumns
|
|
));
|
|
|
|
$apiToTest[] = array($api,
|
|
array(
|
|
'idSite' => 1,
|
|
'date' => self::$fixture->dateTime,
|
|
'periods' => array('year'),
|
|
'segment' => 'dimension1=@value5',
|
|
'otherRequestParameters' => array(
|
|
'idDimension' => 1,
|
|
),
|
|
'testSuffix' => "year_site_1_dimension_1_withsegment",
|
|
'xmlFieldsToRemove' => $removeColumns
|
|
)
|
|
);
|
|
|
|
$apiToTest[] = array(array('API.getProcessedReport'),
|
|
array(
|
|
'idSite' => 1,
|
|
'date' => self::$fixture->dateTime,
|
|
'periods' => array('year'),
|
|
'otherRequestParameters' => array(
|
|
'apiModule' => 'CustomDimensions',
|
|
'apiAction' => 'getCustomDimension',
|
|
'idDimension' => '3'
|
|
),
|
|
'testSuffix' => '_actionDimension',
|
|
'xmlFieldsToRemove' => ['idsubdatatable']
|
|
)
|
|
);
|
|
|
|
$apiToTest[] = array(array('API.getProcessedReport'),
|
|
array(
|
|
'idSite' => 1,
|
|
'date' => self::$fixture->dateTime,
|
|
'periods' => array('year'),
|
|
'otherRequestParameters' => array(
|
|
'apiModule' => 'CustomDimensions',
|
|
'apiAction' => 'getCustomDimension',
|
|
'idDimension' => '1'
|
|
),
|
|
'testSuffix' => '_visitDimension',
|
|
'xmlFieldsToRemove' => ['nb_visits_converted']
|
|
)
|
|
);
|
|
|
|
$removeColumns = [
|
|
'generationTimeMilliseconds',
|
|
'totalEcommerceRevenue',
|
|
'totalEcommerceConversions',
|
|
'totalEcommerceItems',
|
|
'totalAbandonedCarts',
|
|
'totalAbandonedCartsRevenue',
|
|
'totalAbandonedCartsItems'
|
|
];
|
|
|
|
$apiToTest[] = array(
|
|
array('Live.getLastVisitsDetails'),
|
|
array(
|
|
'idSite' => 1,
|
|
'date' => self::$fixture->dateTime,
|
|
'periods' => array('year'),
|
|
'xmlFieldsToRemove' => $removeColumns
|
|
)
|
|
);
|
|
|
|
return $apiToTest;
|
|
}
|
|
|
|
public function getMetadataApiForTesting()
|
|
{
|
|
$apiToTest = array();
|
|
|
|
$apiToTest[] = array(
|
|
array('API.getReportMetadata'),
|
|
array(
|
|
'idSite' => 1,
|
|
'date' => self::$fixture->dateTime,
|
|
'periods' => array('day')
|
|
)
|
|
);
|
|
|
|
$apiToTest[] = array(array('API.getSegmentsMetadata'),
|
|
array(
|
|
'idSite' => 1,
|
|
'date' => self::$fixture->dateTime,
|
|
'periods' => array('year'),
|
|
'otherRequestParameters' => [
|
|
'hideColumns' => 'acceptedValues' // hide accepted values as they might change
|
|
]
|
|
)
|
|
);
|
|
|
|
$apiToTest[] = array(
|
|
array('API.getReportPagesMetadata'),
|
|
array(
|
|
'idSite' => 1,
|
|
'date' => self::$fixture->dateTime,
|
|
'periods' => array('day')
|
|
)
|
|
);
|
|
|
|
$apiToTest[] = array(array('CustomDimensions.getAvailableExtractionDimensions'),
|
|
array(
|
|
'idSite' => 1,
|
|
'date' => self::$fixture->dateTime,
|
|
'periods' => array('day')
|
|
)
|
|
);
|
|
|
|
foreach (array(1, 2, 99) as $idSite) {
|
|
$api = array('CustomDimensions.getConfiguredCustomDimensions',
|
|
'CustomDimensions.getAvailableScopes');
|
|
$apiToTest[] = array($api,
|
|
array(
|
|
'idSite' => $idSite,
|
|
'date' => self::$fixture->dateTime,
|
|
'periods' => array('day'),
|
|
'testSuffix' => '_' . $idSite
|
|
)
|
|
);
|
|
|
|
$apiToTest[] = array('CustomDimensions.getConfiguredCustomDimensionsHavingScope',
|
|
array(
|
|
'idSite' => $idSite,
|
|
'date' => self::$fixture->dateTime,
|
|
'periods' => array('day'),
|
|
'testSuffix' => '_' . $idSite,
|
|
'otherRequestParameters' => [
|
|
'scope' => 'visit',
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
$apiToTest[] = array(
|
|
array('API.getWidgetMetadata'),
|
|
array(
|
|
'idSite' => 1,
|
|
'date' => self::$fixture->dateTime,
|
|
'periods' => array('day')
|
|
)
|
|
);
|
|
|
|
return $apiToTest;
|
|
}
|
|
|
|
public function testScheduledReport()
|
|
{
|
|
if (!Fixture::canImagesBeIncludedInScheduledReports()) {
|
|
$this->markTestSkipped("Skipping test for scheduled reports, as system settings don't match.");
|
|
}
|
|
// Context change is needed, as otherwise the customdimension reports are not available
|
|
Context::changeIdSite(1, function () {
|
|
$this->runApiTests(['ScheduledReports.generateReport'], [
|
|
'idSite' => 1,
|
|
'date' => self::$fixture->dateTime,
|
|
'periods' => ['year'],
|
|
'format' => 'original',
|
|
'fileExtension' => 'pdf',
|
|
'otherRequestParameters' => [
|
|
'idReport' => 1,
|
|
'reportFormat' => ReportRenderer::PDF_FORMAT,
|
|
'outputType' => \Piwik\Plugins\ScheduledReports\API::OUTPUT_RETURN,
|
|
'serialize' => 0,
|
|
],
|
|
]);
|
|
});
|
|
}
|
|
|
|
public function getRankingLimitTestData(): iterable
|
|
{
|
|
yield [50000, 500, 500, 'unlimited'];
|
|
yield [50000, 500, 3, 'by_datatable_subtable'];
|
|
yield [50000, 3, 500, 'by_datatable_toplevel'];
|
|
yield [50000, 3, 3, 'by_datatable_subtable_and_toplevel'];
|
|
yield [50000, 1, 1, 'by_datatable_minimum'];
|
|
}
|
|
|
|
public function getRankingLimitTestDataWithRollup(): iterable
|
|
{
|
|
foreach ($this->getRankingLimitTestData() as $testData) {
|
|
yield $testData;
|
|
}
|
|
|
|
/*
|
|
* set zero for custom dimension rows to prevent
|
|
* "10 * datatable_archiving_maximum_rows_custom_dimensions"
|
|
* being used as the actual limit in the ranking query
|
|
*/
|
|
yield [3, 0, 0, 'by_archiving_query'];
|
|
}
|
|
|
|
public function getRankingLimitTestDataExpanded(): iterable
|
|
{
|
|
foreach ($this->getRankingLimitTestData() as $testData) {
|
|
[$rowsRankingQuery, $rowsTableTopLevel, $rowsTableSubTable, $testSuffix] = $testData;
|
|
|
|
yield [
|
|
$rowsRankingQuery,
|
|
$rowsTableTopLevel,
|
|
$rowsTableSubTable,
|
|
$testSuffix . '_expanded',
|
|
['expanded' => 1]
|
|
];
|
|
}
|
|
}
|
|
|
|
public function getRankingLimitTestDataExpandedWithRollup(): iterable
|
|
{
|
|
foreach ($this->getRankingLimitTestDataWithRollup() as $testData) {
|
|
[$rowsRankingQuery, $rowsTableTopLevel, $rowsTableSubTable, $testSuffix] = $testData;
|
|
|
|
yield [
|
|
$rowsRankingQuery,
|
|
$rowsTableTopLevel,
|
|
$rowsTableSubTable,
|
|
$testSuffix . '_expanded',
|
|
['expanded' => 1]
|
|
];
|
|
}
|
|
}
|
|
|
|
public static function getOutputPrefix()
|
|
{
|
|
return '';
|
|
}
|
|
|
|
public static function getPathToTestDirectory()
|
|
{
|
|
return dirname(__FILE__);
|
|
}
|
|
|
|
public static function tearDownAfterClass(): void
|
|
{
|
|
self::triggerWithRollupFeatureFlag($enableFlag = false);
|
|
parent::tearDownAfterClass();
|
|
}
|
|
}
|
|
|
|
ApiTest::$fixture = new TrackVisitsWithCustomDimensionsFixture();
|