1
0
قرینه از https://github.com/matomo-org/matomo.git synced 2025-08-22 15:07:44 +00:00
Files
matomo/plugins/MultiSites/tests/Integration/DashboardTest.php
Stefan Giehl 1505379ed4 Refactor & improve MultiSites plugin (#23065)
* Disable autosanitize for MultiSites API

* Add proper type hints accross MultiSites plugin

* cs/ws

* Replace Common::getRequestVar with Request class methods

* some more type hints

* simplify table filter

* updates expected UI test file

* clean up more code & bring code to phpstan lvl 5

* Add tooltips to table header

* small code improvements
2025-02-26 13:04:23 +13:00

602 خطوط
21 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\MultiSites\tests\Integration;
use Piwik\DataTable;
use Piwik\Period;
use Piwik\Plugins\MultiSites\Dashboard;
use Piwik\Tests\Framework\Fixture;
use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
/**
* @group MultiSites
* @group DashboardTest
* @group Dashboard
* @group Plugins
*/
class DashboardTest extends IntegrationTestCase
{
/** @var Dashboard */
private $dashboard;
private $numSitesToCreate = 3;
public function setUp(): void
{
parent::setUp();
for ($i = 1; $i <= $this->numSitesToCreate; $i++) {
Fixture::createWebsite('2012-12-12 00:00:00', $ecommerce = 0, 'Site ' . $i);
}
Fixture::loadAllTranslations();
$this->dashboard = $this->getMockBuilder('Piwik\Plugins\MultiSites\Dashboard')
->setMethods(null)
->disableOriginalConstructor()
->getMock();
}
public function testConstructShouldFetchSitesWithNeededColumnsAndReturnEvenSitesHavingNoVisits()
{
$dayToFetch = '2012-12-13';
$lastDate = '2012-12-12';
$dashboard = new Dashboard('day', $dayToFetch, false);
$this->assertSame($this->numSitesToCreate, $dashboard->getNumSites());
$this->assertEquals($lastDate, $dashboard->getLastDate());
$expectedTotals = [
'nb_pageviews' => 0,
'nb_visits' => 0,
'nb_actions' => 0,
'revenue' => 0,
'hits' => 0,
'previous_nb_pageviews' => 0,
'previous_nb_visits' => 0,
'previous_hits' => 0,
'previous_nb_actions' => 0,
'previous_revenue' => 0,
];
$this->assertEquals($expectedTotals, $dashboard->getTotals());
$expectedSites = [
[
'label' => 'Site 1',
'nb_visits' => 0,
'nb_actions' => 0,
'nb_pageviews' => 0,
'revenue' => 0,
'visits_evolution' => '0%',
'actions_evolution' => '0%',
'pageviews_evolution' => '0%',
'revenue_evolution' => '0%',
'idsite' => 1,
'group' => '',
'main_url' => 'http://piwik.net',
'nb_conversions' => 0,
'nb_conversions_evolution' => '0%',
'ratio' => 1,
'previous_nb_visits' => 0,
'periodName' => 'day',
'previousRange' => 'Wed, Dec 12',
'previous_nb_actions' => 0,
'visits_evolution_trend' => 0,
'actions_evolution_trend' => 0,
'pageviews_evolution_trend' => 0,
'revenue_evolution_trend' => 0,
'nb_conversions_evolution_trend' => 0,
'currencySymbol' => '$',
'hits' => 0,
'hits_evolution' => '0%',
'hits_evolution_trend' => 0,
'previous_nb_pageviews' => 0,
'previous_hits' => 0,
'previous_revenue' => 0,
'previous_nb_conversions' => 0,
'previous_nb_actions' => 0,
],
[
'label' => 'Site 2',
'nb_visits' => 0,
'nb_actions' => 0,
'nb_pageviews' => 0,
'revenue' => 0,
'visits_evolution' => '0%',
'actions_evolution' => '0%',
'pageviews_evolution' => '0%',
'revenue_evolution' => '0%',
'idsite' => 2,
'group' => '',
'main_url' => 'http://piwik.net',
'nb_conversions' => 0,
'nb_conversions_evolution' => '0%',
'ratio' => 1,
'previous_nb_visits' => 0,
'periodName' => 'day',
'previousRange' => 'Wed, Dec 12',
'previous_nb_actions' => 0,
'visits_evolution_trend' => 0,
'actions_evolution_trend' => 0,
'pageviews_evolution_trend' => 0,
'revenue_evolution_trend' => 0,
'nb_conversions_evolution_trend' => 0,
'currencySymbol' => '$',
'hits' => 0,
'hits_evolution' => '0%',
'hits_evolution_trend' => 0,
'previous_nb_pageviews' => 0,
'previous_hits' => 0,
'previous_revenue' => 0,
'previous_nb_conversions' => 0,
'previous_nb_actions' => 0,
],
[
'label' => 'Site 3',
'nb_visits' => 0,
'nb_actions' => 0,
'nb_pageviews' => 0,
'revenue' => 0,
'visits_evolution' => '0%',
'actions_evolution' => '0%',
'pageviews_evolution' => '0%',
'revenue_evolution' => '0%',
'idsite' => 3,
'group' => '',
'main_url' => 'http://piwik.net',
'nb_conversions' => 0,
'nb_conversions_evolution' => '0%',
'ratio' => 1,
'previous_nb_visits' => 0,
'periodName' => 'day',
'previousRange' => 'Wed, Dec 12',
'previous_nb_actions' => 0,
'visits_evolution_trend' => 0,
'actions_evolution_trend' => 0,
'pageviews_evolution_trend' => 0,
'revenue_evolution_trend' => 0,
'nb_conversions_evolution_trend' => 0,
'currencySymbol' => '$',
'hits' => 0,
'hits_evolution' => '0%',
'hits_evolution_trend' => 0,
'previous_nb_pageviews' => 0,
'previous_hits' => 0,
'previous_revenue' => 0,
'previous_nb_conversions' => 0,
'previous_nb_actions' => 0,
],
];
$this->assertEquals($expectedSites, $dashboard->getSites([], $limit = 10));
}
public function testConstructShouldActuallyFindSitesWhenSeaching()
{
$dashboard = new Dashboard('day', '2012-12-13', false);
$this->assertSame($this->numSitesToCreate, $dashboard->getNumSites());
$expectedSites = [
[
'label' => 'Site 2',
'nb_visits' => 0,
'nb_actions' => 0,
'nb_pageviews' => 0,
'revenue' => 0,
'visits_evolution' => '0%',
'actions_evolution' => '0%',
'pageviews_evolution' => '0%',
'revenue_evolution' => '0%',
'idsite' => 2,
'group' => '',
'main_url' => 'http://piwik.net',
'nb_conversions' => 0,
'nb_conversions_evolution' => '0%',
'ratio' => 1,
'previous_nb_visits' => 0,
'periodName' => 'day',
'previousRange' => 'Wed, Dec 12',
'visits_evolution_trend' => 0,
'actions_evolution_trend' => 0,
'pageviews_evolution_trend' => 0,
'revenue_evolution_trend' => 0,
'nb_conversions_evolution_trend' => 0,
'currencySymbol' => '$',
'hits' => 0,
'hits_evolution' => '0%',
'hits_evolution_trend' => 0,
'previous_nb_pageviews' => 0,
'previous_hits' => 0,
'previous_revenue' => 0,
'previous_nb_conversions' => 0,
'previous_nb_actions' => 0,
],
];
$dashboard->search('site 2');
$this->assertEquals($expectedSites, $dashboard->getSites([], $limit = 10));
$this->assertSame(1, $dashboard->getNumSites());
}
public function testGetNumSitesShouldBeZeroIfNoSitesAreSet()
{
$this->assertSame(0, $this->dashboard->getNumSites());
}
public function testGetNumSitesShouldReturnTheNumberOfSetSites()
{
$this->setSitesTable(4);
$this->assertSame(4, $this->dashboard->getNumSites());
}
public function testGetNumSitesShouldCountGroupsIntoResult()
{
$sites = $this->setSitesTable(20);
$this->setGroupForSiteId($sites, $siteId = 1, 'group1');
$this->setGroupForSiteId($sites, $siteId = 2, 'group2');
$this->setGroupForSiteId($sites, $siteId = 3, 'group1');
$this->setGroupForSiteId($sites, $siteId = 4, 'group4');
$this->setGroupForSiteId($sites, $siteId = 15, 'group1');
$this->setGroupForSiteId($sites, $siteId = 16, 'group1');
$this->setGroupForSiteId($sites, $siteId = 18, 'group1');
$this->setGroupForSiteId($sites, $siteId = 6, 'group4');
$this->dashboard->setSitesTable($sites);
// 3 different groups
$this->assertSame(20 + 3, $this->dashboard->getNumSites());
}
public function testGetSitesShouldReturnAnArrayOfSites()
{
$this->setSitesTable(8);
$expectedSites = $this->buildSitesArray([1, 2, 3, 4, 5, 6, 7, 8]);
$this->assertEquals($expectedSites, $this->dashboard->getSites([], $limit = 20));
}
public function testGetSitesShouldApplyALimit()
{
$this->setSitesTable(8);
$expectedSites = $this->buildSitesArray([1, 2, 3, 4]);
$this->assertEquals($expectedSites, $this->dashboard->getSites([], $limit = 4));
}
public function testGetSitesShouldApplyLimitCorrectIfThereAreLessFirstLevelRowsThenLimit()
{
$sites = $this->setSitesTable(8);
$this->setGroupForSiteId($sites, $siteId = 1, 'group1');
$this->setGroupForSiteId($sites, $siteId = 2, 'group2');
$this->setGroupForSiteId($sites, $siteId = 3, 'group1');
$this->setGroupForSiteId($sites, $siteId = 4, 'group4');
$this->setGroupForSiteId($sites, $siteId = 5, 'group4');
$this->setGroupForSiteId($sites, $siteId = 6, 'group4');
$this->setGroupForSiteId($sites, $siteId = 7, 'group4');
$this->dashboard->setSitesTable($sites);
$expectedSites = [
[
'label' => 'group1',
'nb_visits' => 20,
'isGroup' => 1,
], [
'label' => 'Site1',
'nb_visits' => 10,
'group' => 'group1',
], [
'label' => 'Site3',
'nb_visits' => 10,
'group' => 'group1',
], [
'label' => 'group2',
'nb_visits' => 10,
'isGroup' => 1,
], [
'label' => 'Site2',
'nb_visits' => 10,
'group' => 'group2',
], [
'label' => 'Site8',
'nb_visits' => 10,
],
];
// there will be 4 first level entries (group1, group2, group4 and site8), offset is 5, limit is 6.
// See https://github.com/piwik/piwik/issues/7854 before there was no site returned since 5 > 4 first level entries
$this->assertEquals($expectedSites, $this->dashboard->getSites(['filter_offset' => 5], $limit = 6));
}
public function testGetSitesShouldReturnOneMoreGroupIfFirstSiteBelongsToAGroupButGroupWouldBeNormallyNotInResult()
{
$sites = $this->setSitesTable(8);
$this->setGroupForSiteId($sites, $siteId = 1, 'group1');
$this->setGroupForSiteId($sites, $siteId = 2, 'group2');
$this->setGroupForSiteId($sites, $siteId = 3, 'group1');
$this->setGroupForSiteId($sites, $siteId = 4, 'group4');
$this->setGroupForSiteId($sites, $siteId = 5, 'group4');
$this->setGroupForSiteId($sites, $siteId = 6, 'group4');
$this->setGroupForSiteId($sites, $siteId = 7, 'group4');
$this->dashboard->setSitesTable($sites);
$expectedSites = [
[
'label' => 'group4', // this group should be the added group, that's why there are 5 entries
'nb_visits' => 40,
'isGroup' => 1,
], [
'label' => 'Site6',
'nb_visits' => 10,
'group' => 'group4',
], [
'label' => 'Site7',
'nb_visits' => 10,
'group' => 'group4',
], [
'label' => 'group1',
'nb_visits' => 20,
'isGroup' => 1,
], [
'label' => 'Site1',
'nb_visits' => 10,
'group' => 'group1',
]
];
$this->assertEquals($expectedSites, $this->dashboard->getSites(['filter_offset' => 3], $limit = 4));
}
public function testGetSitesWithGroupShouldApplyALimitAndKeepSitesWithinGroup()
{
$sites = $this->setSitesTable(20);
$this->setGroupForSiteId($sites, $siteId = 1, 'group1');
$this->setGroupForSiteId($sites, $siteId = 2, 'group2');
$this->setGroupForSiteId($sites, $siteId = 3, 'group1');
$this->setGroupForSiteId($sites, $siteId = 4, 'group4');
$this->setGroupForSiteId($sites, $siteId = 15, 'group1');
$this->setGroupForSiteId($sites, $siteId = 16, 'group1');
$this->setGroupForSiteId($sites, $siteId = 18, 'group1');
$this->setGroupForSiteId($sites, $siteId = 6, 'group4');
$this->dashboard->setSitesTable($sites);
$expectedSites = [
[
'label' => 'group1', // do not count group into the limit
'nb_visits' => 50, // there are 5 matching sites having that group, we only return 3, still result is correct!
'isGroup' => 1,
], [
'label' => 'Site1',
'nb_visits' => 10,
'group' => 'group1',
], [
'label' => 'Site3',
'nb_visits' => 10,
'group' => 'group1',
], [
'label' => 'Site15',
'nb_visits' => 10,
'group' => 'group1',
],
];
$this->assertEquals($expectedSites, $this->dashboard->getSites([], $limit = 4));
}
public function testSearchShouldUpdateTheNumberOfAvailableSites()
{
$this->setSitesTable(100);
$this->dashboard->search('site1');
// site1 + site1* matches
$this->assertSame(12, $this->dashboard->getNumSites());
}
public function testSearchShouldOnlyKeepMatchingSites()
{
$this->setSitesTable(100);
$this->dashboard->search('site1');
$expectedSites = $this->buildSitesArray([1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 100]);
$this->assertEquals($expectedSites, $this->dashboard->getSites([], $limit = 20));
}
public function testSearchNoSiteMatches()
{
$this->setSitesTable(100);
$this->dashboard->search('anYString');
$this->assertSame(0, $this->dashboard->getNumSites());
$this->assertEquals([], $this->dashboard->getSites([], $limit = 20));
}
public function testSearchWithGroupShouldDoesSearchInGroupNameAndMatchesEvenSitesHavingThatGroupName()
{
$sites = $this->setSitesTable(20);
$this->setGroupForSiteId($sites, $siteId = 1, 'group1');
$this->setGroupForSiteId($sites, $siteId = 2, 'group2');
$this->setGroupForSiteId($sites, $siteId = 3, 'group1');
$this->setGroupForSiteId($sites, $siteId = 4, 'group4');
$this->setGroupForSiteId($sites, $siteId = 15, 'group1');
$this->setGroupForSiteId($sites, $siteId = 16, 'group1');
$this->setGroupForSiteId($sites, $siteId = 18, 'group1');
$this->setGroupForSiteId($sites, $siteId = 6, 'group4');
$this->dashboard->setSitesTable($sites);
$this->dashboard->search('group');
// groups within that site should be listed first.
$expectedSites = [
[
'label' => 'group1',
'nb_visits' => 50,
'isGroup' => 1,
],
[
'label' => 'Site1',
'nb_visits' => 10,
'group' => 'group1',
],
[
'label' => 'Site3',
'nb_visits' => 10,
'group' => 'group1',
],
[
'label' => 'Site15',
'nb_visits' => 10,
'group' => 'group1',
],
[
'label' => 'Site16',
'nb_visits' => 10,
'group' => 'group1',
],
[
'label' => 'Site18',
'nb_visits' => 10,
'group' => 'group1',
],
[
'label' => 'group4',
'nb_visits' => 20,
'isGroup' => 1,
],
[
'label' => 'Site4',
'nb_visits' => 10,
'group' => 'group4',
],
[
'label' => 'Site6',
'nb_visits' => 10,
'group' => 'group4',
],
[
'label' => 'group2',
'nb_visits' => 10,
'isGroup' => 1,
],
[
'label' => 'Site2',
'nb_visits' => 10,
'group' => 'group2',
],
];
// 3 groups + 8 sites having a group.
$this->assertSame(3 + 8, $this->dashboard->getNumSites());
$matchingSites = $this->dashboard->getSites([], $limit = 20);
$this->assertEquals($expectedSites, $matchingSites);
// test with limit should only return the first results
$matchingSites = $this->dashboard->getSites([], $limit = 8);
$this->assertEquals(array_slice($expectedSites, 0, 8), $matchingSites);
}
public function testSearchWithGroupIfASiteMatchesButNotTheGroupNameItShouldKeepTheGroupThough()
{
$sites = $this->setSitesTable(20);
$this->setGroupForSiteId($sites, $siteId = 1, 'group1');
$this->setGroupForSiteId($sites, $siteId = 2, 'group2');
$this->setGroupForSiteId($sites, $siteId = 3, 'group1');
$this->setGroupForSiteId($sites, $siteId = 20, 'group4');
$this->setGroupForSiteId($sites, $siteId = 15, 'group1');
$this->setGroupForSiteId($sites, $siteId = 16, 'group1');
$this->setGroupForSiteId($sites, $siteId = 18, 'group1');
$this->setGroupForSiteId($sites, $siteId = 6, 'group4');
$this->dashboard->setSitesTable($sites);
$this->dashboard->search('site2');
$expectedSites = [
[
'label' => 'group4',
'nb_visits' => 20, // another site belongs to that group which doesn't match that name yet still we need to sum the correct result.
'isGroup' => 1,
],
[
'label' => 'Site20',
'nb_visits' => 10,
'group' => 'group4',
],
[
'label' => 'group2',
'nb_visits' => 10,
'isGroup' => 1,
],
[
'label' => 'Site2',
'nb_visits' => 10,
'group' => 'group2',
],
];
// 2 matching sites + their group
$this->assertSame(2 + 2, $this->dashboard->getNumSites());
$matchingSites = $this->dashboard->getSites([], $limit = 20);
$this->assertEquals($expectedSites, $matchingSites);
}
public function testGetLastDateShouldReturnTheLastDateIfAnyIsSet()
{
$this->setSitesTable(1);
$this->assertSame('2012-12-12', $this->dashboard->getLastDate());
}
public function testGetLastDateShouldReturnAnEmptyStringIfNoLastDateIsSet()
{
$this->dashboard->setSitesTable(new DataTable());
$this->assertSame('', $this->dashboard->getLastDate());
}
private function setGroupForSiteId(DataTable $table, $siteId, $groupName)
{
$table->getRowFromLabel('Site' . $siteId)->setMetadata('group', $groupName);
}
private function setSitesTable($numSites)
{
$sites = new DataTable();
$sites->addRowsFromSimpleArray($this->buildSitesArray(range(1, $numSites)));
$sites->setMetadata('last_period_date', Period\Factory::build('day', '2012-12-12'));
$this->dashboard->setSitesTable($sites);
return $sites;
}
private function buildSitesArray($siteIds)
{
$sites = [];
foreach ($siteIds as $siteId) {
$sites[] = ['label' => 'Site' . $siteId, 'nb_visits' => 10];
}
return $sites;
}
}