Newer
Older
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Tests\Integration\Tracker;
use Piwik\Cache;
use Piwik\CacheId;
Thomas Steur
a validé
use Piwik\DataAccess\ArchiveInvalidator;
use Piwik\Date;
use Piwik\Network\IPUtils;
mattab
a validé
use Piwik\Plugins\SitesManager\API;
Thomas Steur
a validé
use Piwik\Tests\Framework\Fixture;
use Piwik\Tests\Framework\Mock\FakeAccess;
use Piwik\Tracker\ActionPageview;
use Piwik\Tracker\Request;
use Piwik\Tracker\Visit;
Thomas Steur
a validé
use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
use Piwik\Tracker\Visitor;
Thomas Steur
a validé
/**
* @group Core
*/
class VisitTest extends IntegrationTestCase
{
public function setUp()
{
parent::setUp();
// setup the access layer
$pseudoMockAccess = new FakeAccess;
FakeAccess::$superUser = true;
Access::setSingletonInstance($pseudoMockAccess);
Thomas Steur
a validé
Manager::getInstance()->loadTrackerPlugins();
Manager::getInstance()->loadPlugin('SitesManager');
}
/**
* Dataprovider
*/
public function getExcludedIpTestData()
{
return array(
array('12.12.12.12', array(
'12.12.12.12' => true,
'12.12.12.11' => false,
'12.12.12.13' => false,
'0.0.0.0' => false,
'255.255.255.255' => false
)),
array('12.12.12.12/32', array(
'12.12.12.12' => true,
'12.12.12.11' => false,
'12.12.12.13' => false,
'0.0.0.0' => false,
'255.255.255.255' => false
)),
array('12.12.12.*', array(
'12.12.12.0' => true,
'12.12.12.255' => true,
'12.12.12.12' => true,
'12.12.11.255' => false,
'12.12.13.0' => false,
'0.0.0.0' => false,
'255.255.255.255' => false,
)),
array('12.12.12.0/24', array(
'12.12.12.0' => true,
'12.12.12.255' => true,
'12.12.12.12' => true,
'12.12.11.255' => false,
'12.12.13.0' => false,
'0.0.0.0' => false,
'255.255.255.255' => false,
)),
// add some ipv6 addresses!
);
}
public function testIsVisitorIpExcluded($excludedIp, $tests)
mattab
a validé
$idsite = API::getInstance()->addSite("name", "http://piwik.net/", $ecommerce = 0,
$siteSearch = 1, $searchKeywordParameters = null, $searchCategoryParameters = null, $excludedIp);
$request = new Request(array('idsite' => $idsite));
// test that IPs within the range, or the given IP, are excluded
foreach ($tests as $ip => $expected) {
$testIpIsExcluded = IPUtils::stringToBinaryIP($ip);
$excluded = new VisitExcluded_public($request, $testIpIsExcluded);
$this->assertSame($expected, $excluded->public_isVisitorIpExcluded($testIpIsExcluded));
benakamoorthi
a validé
/**
* Dataprovider for testIsVisitorUserAgentExcluded.
*/
public function getExcludedUserAgentTestData()
{
return array(
array('', array(
'whatever' => false,
'' => false,
'nlksdjfsldkjfsa' => false,
)),
array('mozilla', array(
'this has mozilla in it' => true,
'this doesn\'t' => false,
'partial presence: mozi' => false,
)),
array('cHrOmE,notinthere,&^%', array(
'chrome is here' => true,
'CHROME is here' => true,
'12&^%345' => true,
'sfasdf' => false,
)),
);
}
/**
* @dataProvider getExcludedUserAgentTestData
*/
public function testIsVisitorUserAgentExcluded($excludedUserAgent, $tests)
{
mattab
a validé
API::getInstance()->setSiteSpecificUserAgentExcludeEnabled(true);
mattab
a validé
$idsite = API::getInstance()->addSite("name", "http://piwik.net/", $ecommerce = 0,
$siteSearch = 1, $searchKeywordParameters = null, $searchCategoryParameters = null, $excludedIp = null,
$excludedQueryParameters = null, $timezone = null, $currency = null, $group = null, $startDate = null,
$excludedUserAgent);
$request = new Request(array('idsite' => $idsite));
// test that user agents that contain excluded user agent strings are excluded
foreach ($tests as $ua => $expected) {
$excluded = new VisitExcluded_public($request, $ip = false, $ua);
$this->assertSame($expected, $excluded->public_isUserAgentExcluded(), "Result if isUserAgentExcluded('$ua') was not " . ($expected ? 'true' : 'false') . ".");
}
}
/**
* @group referrerIsKnownSpam
*/
public function testIsVisitor_referrerIsKnownSpam()
{
$knownSpammers = array(
'http://semalt.com' => true,
'http://semalt.com/random/sub/page' => true,
'http://semalt.com/out/of/here?mate' => true,
'http://buttons-for-website.com/out/of/here?mate' => true,
'https://buttons-for-website.com' => true,
'https://make-money-online.7makemoneyonline.com' => true,
'http://valid.domain/' => false,
'http://valid.domain/page' => false,
);
API::getInstance()->setSiteSpecificUserAgentExcludeEnabled(true);
$idsite = API::getInstance()->addSite("name", "http://piwik.net/");
// test that user agents that contain excluded user agent strings are excluded
foreach ($knownSpammers as $spamUrl => $expectedIsReferrerSpam) {
$spamUrl = urlencode($spamUrl);
$request = new Request(array(
'idsite' => $idsite,
'urlref' => $spamUrl
));
$excluded = new VisitExcluded_public($request);
$this->assertSame($expectedIsReferrerSpam, $excluded->public_isReferrerSpamExcluded(), $spamUrl);
benakamoorthi
a validé
}
mattab
a validé
/**
* @group IpIsKnownBot
*/
public function testIsVisitor_ipIsKnownBot()
{
$isIpBot = array(
// Source: http://forum.piwik.org/read.php?3,108926
'66.249.85.36' => true,
'66.249.91.150' => true,
'64.233.172.1' => true,
'64.233.172.200' => true,
'66.249.88.216' => true,
'66.249.83.204' => true,
'64.233.172.6' => true,
// ddos bot
'1.202.218.8' => true,
// Not bots
'66.248.91.150' => false,
'66.250.91.150' => false,
// almost google range but not google
'66.249.2.1' => false,
'66.249.60.1' => false,
);
$idsite = API::getInstance()->addSite("name", "http://piwik.net/");
$request = new Request(array('idsite' => $idsite, 'bots' => 0));
foreach ($isIpBot as $ip => $isBot) {
$excluded = new VisitExcluded_public($request, IPUtils::stringToBinaryIP($ip));
$this->assertSame($isBot, $excluded->public_isNonHumanBot(), $ip);
}
}
mattab
a validé
/**
* @group UserAgentIsKnownBot
*/
public function testIsVisitor_userAgentIsKnownBot()
{
$isUserAgentBot = array(
'baiduspider' => true,
mattab
a validé
'bingbot' => true,
'BINGBOT' => true,
'x BingBot x' => true,
'BingPreview' => true,
'facebookexternalhit' => true,
mattab
a validé
'YottaaMonitor' => true,
'Mozilla/5.0 (compatible; CloudFlare-AlwaysOnline/1.0; +http://www.cloudflare.com/always-online) XXXX' => true,
'Pingdom.com_bot_version_1.4_(http://www.pingdom.com/)' => true,
'Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)' => true,
'Exabot/2.0' => true,
'sogou spider' => true,
'Mozilla/5.0(compatible;Sosospider/2.0;+http://help.soso.com/webspider.htm)' => true,
'AdsBot-Google (+http://www.google.com/adsbot.html)' => true,
'Google Page Speed Insights' => true,
// Web snippets
'Mozilla/5.0 (Windows NT 6.1; rv:6.0) Gecko/20110814 Firefox/6.0 Google (+https://developers.google.com/+/web/snippet/)' => true,
// Google Web Preview
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.51 (KHTML, like Gecko; Google Web Preview) Chrome/12.0.742 Safari/534.51' => true,
'Googlebot-Video/1.0' => true,
'Googlebot' => true,
mattab
a validé
'random' => false,
'hello world' => false,
'this is a user agent' => false,
'Mozilla' => false,
);
$idsite = API::getInstance()->addSite("name", "http://piwik.net/");
foreach ($isUserAgentBot as $userAgent => $isBot) {
$request = new Request(array(
'idsite' => $idsite,
'bots' => 0,
'ua' => $userAgent,
));
$excluded = new VisitExcluded_public($request);
$this->assertSame($isBot, $excluded->public_isNonHumanBot(), $userAgent);
}
}
public function test_isVisitNew_ReturnsFalse_IfLastActionTimestampIsWithinVisitTimeLength_AndNoDimensionForcesVisit_AndVisitorKnown()
{
$this->setDimensionsWithOnNewVisit(array(false, false, false));
/** @var Visit $visit */
list($visit, $visitor, $action) = $this->makeVisitorAndAction(
$lastActionTime = '2012-01-02 08:08:34', $thisActionTime = '2012-01-02 08:12:45', $isVisitorKnown = true);
$result = $visit->isVisitNew($visitor, $action);
$this->assertFalse($result);
}
public function test_isVisitNew_ReturnsTrue_IfLastActionTimestampWasYesterday()
{
$this->setDimensionsWithOnNewVisit(array(false, false, false));
// test same day
/** @var Visit $visit */
list($visit, $visitor, $action) = $this->makeVisitorAndAction(
$lastActionTime = '2012-01-01 23:59:58', $thisActionTime = '2012-01-01 23:59:59', $isVisitorKnown = true);
$result = $visit->isVisitNew($visitor, $action);
$this->assertFalse($result);
// test different day
list($visit, $visitor, $action) = $this->makeVisitorAndAction(
$lastActionTime = '2012-01-01 23:59:58', $thisActionTime = '2012-01-02 00:00:01', $isVisitorKnown = true);
$result = $visit->isVisitNew($visitor, $action);
$this->assertTrue($result);
}
Thomas Steur
a validé
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
public function test_markArchivedReportsAsInvalidIfArchiveAlreadyFinished_ShouldRemember_IfRequestWasDoneLongAgo()
{
$currentActionTime = '2012-01-02 08:12:45';
$idsite = API::getInstance()->addSite('name', 'http://piwik.net/');
$expectedRemembered = array('2012-01-02' => array($idsite));
$this->assertRememberedArchivedReportsThatShouldBeInvalidated($idsite, $currentActionTime, $expectedRemembered);
}
public function test_markArchivedReportsAsInvalidIfArchiveAlreadyFinished_ShouldNotRemember_IfRequestWasDoneJustAtStartOfTheDay()
{
$currentActionTime = Date::today()->getDatetime();
$idsite = API::getInstance()->addSite('name', 'http://piwik.net/');
$expectedRemembered = array();
$this->assertRememberedArchivedReportsThatShouldBeInvalidated($idsite, $currentActionTime, $expectedRemembered);
}
public function test_markArchivedReportsAsInvalidIfArchiveAlreadyFinished_ShouldRemember_IfRequestWasDoneAt11PMTheDayBefore()
{
$currentActionTime = Date::today()->subHour(1)->getDatetime();
$idsite = API::getInstance()->addSite('name', 'http://piwik.net/');
$expectedRemembered = array(
substr($currentActionTime, 0, 10) => array($idsite)
);
$this->assertRememberedArchivedReportsThatShouldBeInvalidated($idsite, $currentActionTime, $expectedRemembered);
}
public function test_markArchivedReportsAsInvalidIfArchiveAlreadyFinished_shouldConsiderWebsitesTimezone()
{
$timezone1 = 'UTC+4';
$timezone2 = 'UTC+6';
$currentActionTime1 = Date::today()->setTimezone($timezone1)->getDatetime();
$currentActionTime2 = Date::today()->setTimezone($timezone2)->getDatetime();
$idsite = API::getInstance()->addSite('name', 'http://piwik.net/', $ecommerce = null,
$siteSearch = null,
$searchKeywordParameters = null,
$searchCategoryParameters = null,
$excludedIps = null,
$excludedQueryParameters = null,
$timezone = 'UTC+5');
$expectedRemembered = array(
substr($currentActionTime1, 0, 10) => array($idsite)
);
// if website timezone was von considered both would be today (expected = array())
$this->assertRememberedArchivedReportsThatShouldBeInvalidated($idsite, $currentActionTime1, array());
$this->assertRememberedArchivedReportsThatShouldBeInvalidated($idsite, $currentActionTime2, $expectedRemembered);
}
private function assertRememberedArchivedReportsThatShouldBeInvalidated($idsite, $requestDate, $expectedRemeberedArchivedReports)
{
/** @var Visit $visit */
list($visit) = $this->prepareVisitWithRequest(array(
'idsite' => $idsite,
'rec' => 1,
'cip' => '156.146.156.146',
'token_auth' => Fixture::getTokenAuth()
), $requestDate);
$visit->handle();
$archive = new ArchiveInvalidator();
$remembered = $archive->getRememberedArchivedReportsThatShouldBeInvalidated();
$this->assertSame($expectedRemeberedArchivedReports, $remembered);
}
private function prepareVisitWithRequest($requestParams, $requestDate)
{
$request = new Request($requestParams);
$request->setCurrentTimestamp(Date::factory($requestDate)->getTimestamp());
$visit = new Visit();
$visit->setRequest($request);
$visit->handle();
return array($visit, $request);
}
public function test_isVisitNew_ReturnsTrue_IfLastActionTimestampIsNotWithinVisitTimeLength_AndNoDimensionForcesVisit_AndVisitorNotKnown()
{
$this->setDimensionsWithOnNewVisit(array(false, false, false));
/** @var Visit $visit */
list($visit, $visitor, $action) = $this->makeVisitorAndAction($lastActionTime = '2012-01-02 08:08:34', $thisActionTime = '2012-01-02 09:12:45');
$result = $visit->isVisitNew($visitor, $action);
$this->assertTrue($result);
}
public function test_isVisitNew_ReturnsTrue_IfLastActionTimestampIsWithinVisitTimeLength_AndDimensionForcesVisit()
{
$this->setDimensionsWithOnNewVisit(array(false, false, true));
/** @var Visit $visit */
list($visit, $visitor, $action) = $this->makeVisitorAndAction($lastActionTime = '2012-01-02 08:08:34', $thisActionTime = '2012-01-02 08:12:45');
$result = $visit->isVisitNew($visitor, $action);
$this->assertTrue($result);
}
Thomas Steur
a validé
public function test_isVisitNew_ReturnsTrue_IfDimensionForcesVisit_AndVisitorKnown()
{
$this->setDimensionsWithOnNewVisit(array(false, false, true));
/** @var Visit $visit */
list($visit, $visitor, $action) = $this->makeVisitorAndAction($lastActionTime = '2012-01-02 08:08:34', $thisActionTime = '2012-01-02 08:12:45');
$result = $visit->isVisitNew($visitor, $action);
$this->assertTrue($result);
}
private function makeVisitorAndAction($lastActionTimestamp, $currentActionTime, $isVisitorKnown = false)
{
$idsite = API::getInstance()->addSite("name", "http://piwik.net/");
Thomas Steur
a validé
list($visit, $request) = $this->prepareVisitWithRequest(array('idsite' => $idsite), $currentActionTime);
$visitor = new Visitor($request, 'configid', array('visit_last_action_time' => Date::factory($lastActionTimestamp)->getTimestamp()));
$visitor->setIsVisitorKnown($isVisitorKnown);
$action = new ActionPageview($request);
return array($visit, $visitor, $action);
}
private function setDimensionsWithOnNewVisit($dimensionOnNewVisitResults)
{
$dimensions = array();
foreach ($dimensionOnNewVisitResults as $onNewVisitResult) {
$dim = $this->getMock('Piwik\\Plugin\\Dimension', array('shouldForceNewVisit', 'getColumnName'));
$dim->expects($this->any())->method('shouldForceNewVisit')->will($this->returnValue($onNewVisitResult));
$dimensions[] = $dim;
}
$cache = Cache::getTransientCache();
$cache->save(CacheId::pluginAware('VisitDimensions'), $dimensions);
}
class VisitExcluded_public extends VisitExcluded
{
public function public_isVisitorIpExcluded($ip)
{
return $this->isVisitorIpExcluded($ip);
}
public function public_isUserAgentExcluded()
{
return $this->isUserAgentExcluded();
}
public function public_isReferrerSpamExcluded()
return $this->isReferrerSpamExcluded();
public function public_isNonHumanBot()
{
return $this->isNonHumanBot();
}