Skip to content

Commit 5a73c96

Browse files
committed
Add test to ensure rollup ranking query result structure
1 parent 9a3e16b commit 5a73c96

2 files changed

Lines changed: 243 additions & 16 deletions

File tree

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
<?php
2+
3+
/**
4+
* Matomo - free/libre analytics platform
5+
*
6+
* @link https://matomo.org
7+
* @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
8+
*/
9+
10+
declare(strict_types=1);
11+
12+
namespace Piwik\Tests\System;
13+
14+
use Piwik\ArchiveProcessor\Parameters;
15+
use Piwik\DataAccess\LogAggregator;
16+
use Piwik\Period;
17+
use Piwik\RankingQuery;
18+
use Piwik\Segment;
19+
use Piwik\Site;
20+
use Piwik\Tests\Fixtures\ManyVisitsWithGeoIP;
21+
use Piwik\Tests\Framework\TestCase\SystemTestCase;
22+
23+
/**
24+
* @group Core
25+
* @group RankingQuery
26+
*/
27+
class RankingQueryTest extends SystemTestCase
28+
{
29+
/**
30+
* @var ManyVisitsWithGeoIP
31+
*/
32+
public static $fixture = null; // initialized below class definition
33+
34+
/**
35+
* @var LogAggregator
36+
*/
37+
private $logAggregator;
38+
39+
public function setUp(): void
40+
{
41+
parent::setUp();
42+
43+
$site = new Site(self::$fixture->idSite);
44+
$period = Period\Factory::build('month', self::$fixture->dateTime);
45+
$segment = new Segment('', [$site->getId()]);
46+
$params = new Parameters($site, $period, $segment);
47+
48+
$this->logAggregator = new LogAggregator($params);
49+
}
50+
51+
/**
52+
* Make sure the results are consistently structured across database vendors.
53+
*
54+
* We always expect the same order, with second-level results ordered by the given base query:
55+
*
56+
* 1. top-level rollup (both labels NULL)
57+
* 2. first-level rollups (secondary label NULL)
58+
* 3. first-level "Others"
59+
* 4. second-level results
60+
* 5. second-level "Others"
61+
*
62+
* @dataProvider getRollupResultStructureTestData
63+
*/
64+
public function testRollupResultStructure(string $sortOrder, array $expectedResultSet): void
65+
{
66+
$select = '
67+
log_visit.config_browser_engine AS config_browser_engine,
68+
log_visit.custom_var_v1 AS custom_var_v1,
69+
COUNT(log_visit.idvisit) AS nb_visits
70+
';
71+
72+
$where = '
73+
log_visit.visit_last_action_time >= ?
74+
AND log_visit.visit_last_action_time <= ?
75+
AND log_visit.idsite IN (?)
76+
AND custom_var_v1 IS NOT NULL
77+
';
78+
79+
$from = 'log_visit';
80+
$groupBy = 'config_browser_engine, custom_var_v1';
81+
$orderBy = "nb_visits $sortOrder, config_browser_engine, custom_var_v1";
82+
83+
$query = $this->logAggregator->generateQuery(
84+
$select,
85+
$from,
86+
$where,
87+
$groupBy,
88+
$orderBy,
89+
$limit = 0,
90+
$offset = 0,
91+
true
92+
);
93+
94+
$rankingQuery = new RankingQuery(3);
95+
$rankingQuery->addLabelColumn(['config_browser_engine', 'custom_var_v1']);
96+
$rankingQuery->addColumn(['nb_visits'], 'sum');
97+
98+
$query['sql'] = $rankingQuery->generateRankingQuery($query['sql'], true);
99+
$resultSet = $this->logAggregator->getDb()->query($query['sql'], $query['bind'])->fetchAll();
100+
101+
self::assertEquals($expectedResultSet, $resultSet);
102+
}
103+
104+
public function getRollupResultStructureTestData(): iterable
105+
{
106+
yield 'nb_visits DESC' => [
107+
'DESC',
108+
[
109+
[
110+
'config_browser_engine' => null,
111+
'custom_var_v1' => null,
112+
'nb_visits' => 30,
113+
],
114+
[
115+
'config_browser_engine' => 'Gecko',
116+
'custom_var_v1' => null,
117+
'nb_visits' => 20,
118+
],
119+
[
120+
'config_browser_engine' => 'Blink',
121+
'custom_var_v1' => null,
122+
'nb_visits' => 4,
123+
],
124+
[
125+
'config_browser_engine' => 'WebKit',
126+
'custom_var_v1' => null,
127+
'nb_visits' => 4,
128+
],
129+
[
130+
'config_browser_engine' => RankingQuery::LABEL_SUMMARY_ROW,
131+
'custom_var_v1' => null,
132+
'nb_visits' => 2,
133+
],
134+
[
135+
'config_browser_engine' => 'Gecko',
136+
'custom_var_v1' => 'Cvar1 value is 1',
137+
'nb_visits' => 4,
138+
],
139+
[
140+
'config_browser_engine' => 'Blink',
141+
'custom_var_v1' => 'Cvar1 value is 0',
142+
'nb_visits' => 3,
143+
],
144+
[
145+
'config_browser_engine' => 'Gecko',
146+
'custom_var_v1' => 'Cvar1 value is 0',
147+
'nb_visits' => 2,
148+
],
149+
[
150+
'config_browser_engine' => 'Blink',
151+
'custom_var_v1' => RankingQuery::LABEL_SUMMARY_ROW,
152+
'nb_visits' => 1,
153+
],
154+
[
155+
'config_browser_engine' => 'Gecko',
156+
'custom_var_v1' => RankingQuery::LABEL_SUMMARY_ROW,
157+
'nb_visits' => 14,
158+
],
159+
[
160+
'config_browser_engine' => 'Trident',
161+
'custom_var_v1' => RankingQuery::LABEL_SUMMARY_ROW,
162+
'nb_visits' => 2,
163+
],
164+
[
165+
'config_browser_engine' => 'WebKit',
166+
'custom_var_v1' => RankingQuery::LABEL_SUMMARY_ROW,
167+
'nb_visits' => 4,
168+
],
169+
],
170+
];
171+
172+
yield 'nb_visits ASC' => [
173+
'ASC',
174+
[
175+
[
176+
'config_browser_engine' => null,
177+
'custom_var_v1' => null,
178+
'nb_visits' => 30,
179+
],
180+
[
181+
'config_browser_engine' => 'Trident',
182+
'custom_var_v1' => null,
183+
'nb_visits' => 2,
184+
],
185+
[
186+
'config_browser_engine' => 'Blink',
187+
'custom_var_v1' => null,
188+
'nb_visits' => 4,
189+
],
190+
[
191+
'config_browser_engine' => 'WebKit',
192+
'custom_var_v1' => null,
193+
'nb_visits' => 4,
194+
],
195+
[
196+
'config_browser_engine' => RankingQuery::LABEL_SUMMARY_ROW,
197+
'custom_var_v1' => null,
198+
'nb_visits' => 20,
199+
],
200+
[
201+
'config_browser_engine' => 'Blink',
202+
'custom_var_v1' => 'Cvar1 value is 3',
203+
'nb_visits' => 1,
204+
],
205+
[
206+
'config_browser_engine' => 'Trident',
207+
'custom_var_v1' => 'Cvar1 value is 1',
208+
'nb_visits' => 1,
209+
],
210+
[
211+
'config_browser_engine' => 'Trident',
212+
'custom_var_v1' => 'Cvar1 value is 2',
213+
'nb_visits' => 1,
214+
],
215+
[
216+
'config_browser_engine' => 'Blink',
217+
'custom_var_v1' => RankingQuery::LABEL_SUMMARY_ROW,
218+
'nb_visits' => 3,
219+
],
220+
[
221+
'config_browser_engine' => 'Gecko',
222+
'custom_var_v1' => RankingQuery::LABEL_SUMMARY_ROW,
223+
'nb_visits' => 20,
224+
],
225+
[
226+
'config_browser_engine' => 'WebKit',
227+
'custom_var_v1' => RankingQuery::LABEL_SUMMARY_ROW,
228+
'nb_visits' => 4,
229+
],
230+
],
231+
];
232+
}
233+
}
234+
235+
RankingQueryTest::$fixture = new ManyVisitsWithGeoIP();

tests/PHPUnit/Unit/RankingQueryTest.php

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@
1212
use Piwik\Db\Schema;
1313
use Piwik\RankingQuery;
1414

15+
/**
16+
* @group Core
17+
* @group RankingQuery
18+
*/
1519
class RankingQueryTest extends \PHPUnit\Framework\TestCase
1620
{
17-
/**
18-
* @group Core
19-
*/
20-
public function testBasic()
21+
public function testBasic(): void
2122
{
2223
$query = new RankingQuery();
2324
$query->setOthersLabel('Others');
@@ -82,10 +83,7 @@ public function testBasic()
8283
$this->checkQuery($query, $innerQuery, $expected);
8384
}
8485

85-
/**
86-
* @group Core
87-
*/
88-
public function testBasicWithRollup()
86+
public function testBasicWithRollup(): void
8987
{
9088
$query = new RankingQuery();
9189
$query->setOthersLabel('Others');
@@ -302,10 +300,7 @@ public function testBasicWithRollup()
302300
$this->checkQuery($query, $innerQuery, $expected, true);
303301
}
304302

305-
/**
306-
* @group Core
307-
*/
308-
public function testExcludeRows()
303+
public function testExcludeRows(): void
309304
{
310305

311306
$query = new RankingQuery(20);
@@ -373,10 +368,7 @@ public function testExcludeRows()
373368
$this->checkQuery($query, $innerQuery, $expected);
374369
}
375370

376-
/**
377-
* @group Core
378-
*/
379-
public function testPartitionResult()
371+
public function testPartitionResult(): void
380372
{
381373
$query = new RankingQuery(1000);
382374
$query->setOthersLabel('Others');

0 commit comments

Comments
 (0)