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

* [Coding Style] Enable rule PSR1.Methods.CamelCapsMethodName.NotCamelCaps * [Coding Style] Use camel case for method names in API plugin tests (#22145) * [Coding Style] Use camel case for method names in Core* plugin tests (#22147) * [Coding Style] Use camel case for method names in core Unit tests (#22149) * [Coding Style] Use camel case for method names in Actions and BulkTracking plugin tests (#22146) * [Coding Style] Use camel case for method names in CustomDimensions and CustomJSTracker plugin tests (#22148) * [Coding Style] Use camel case for method names in core Integration tests (#22151) * [Coding Style] Use camel case for method names in more core plugin tests (#22153) * [Coding Style] Use camel case for method names in more core plugin tests (#22157) * [Coding Style] Use camel case for method names in more core plugin tests * Update plugins/Monolog/tests/Unit/Processor/ExceptionToTextProcessorTest.php Co-authored-by: Michal Kleiner <michal@innocraft.com> --------- Co-authored-by: Michal Kleiner <michal@innocraft.com> * [Coding Style] Use camel case for method names in more core plugin tests (#22159) * [Coding Style] Use camel case for method names in remaining tests (#22160) * [Coding Style] Use camel case for method names in remaining tests * rename expected test files --------- Co-authored-by: Michal Kleiner <michal@innocraft.com>
423 خطوط
15 KiB
PHP
423 خطوط
15 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\UserCountry\tests\Integration;
|
|
|
|
use Piwik\Common;
|
|
use Piwik\Db;
|
|
use Matomo\Network\IPUtils;
|
|
use Piwik\Plugins\UserCountry\VisitorGeolocator;
|
|
use Piwik\Plugins\UserCountry\LocationProvider;
|
|
use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
|
|
use Piwik\Tests\Framework\TestDataHelper\LogHelper;
|
|
use Piwik\Tracker\Cache;
|
|
use Piwik\Tracker\Visit;
|
|
use Piwik\Tests\Framework\Mock\LocationProvider as MockLocationProvider;
|
|
|
|
require_once PIWIK_INCLUDE_PATH . '/tests/PHPUnit/Framework/Mock/LocationProvider.php';
|
|
|
|
/**
|
|
* @group UserCountry
|
|
*/
|
|
class VisitorGeolocatorTest extends IntegrationTestCase
|
|
{
|
|
public const TEST_IP = '1.2.3.4';
|
|
|
|
/**
|
|
* @var LogHelper
|
|
*/
|
|
private $logInserter;
|
|
|
|
public function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->logInserter = new LogHelper();
|
|
|
|
// ensure all providers are loaded and add mock provider
|
|
LocationProvider::$providers = null;
|
|
$providers = LocationProvider::getAllProviders();
|
|
LocationProvider::$providers[] = new MockLocationProvider();
|
|
}
|
|
|
|
public function testGetLocationShouldReturnLocationForProviderIfLocationIsSetForCurrentProvider()
|
|
{
|
|
$location = array(
|
|
'city' => 'Wroclaw',
|
|
'country_code' => 'pl'
|
|
);
|
|
|
|
$provider = $this->getProviderMock();
|
|
$provider->expects($this->once())
|
|
->method('getLocation')
|
|
->will($this->returnValue($location));
|
|
|
|
$geolocator = new VisitorGeolocator($provider);
|
|
|
|
$this->assertEquals(
|
|
$location,
|
|
$geolocator->getLocation(array('ip' => '127.0.0.1'))
|
|
);
|
|
}
|
|
|
|
public function testGetLocationShouldReturnLocationForProviderIfLocationCountryCodeIsNotSetShouldSetAsxx()
|
|
{
|
|
$location = array(
|
|
'city' => 'Wroclaw'
|
|
);
|
|
|
|
$provider = $this->getProviderMock();
|
|
$provider->expects($this->once())
|
|
->method('getLocation')
|
|
->will($this->returnValue($location));
|
|
|
|
$geolocator = new VisitorGeolocator($provider);
|
|
|
|
$this->assertEquals(
|
|
array_merge(
|
|
$location,
|
|
array(
|
|
'country_code' => Visit::UNKNOWN_CODE
|
|
)
|
|
),
|
|
$geolocator->getLocation(array('ip' => '127.0.0.2'))
|
|
);
|
|
}
|
|
|
|
public function testGetLocationShouldReturnLocationForProviderAndReadFromCacheIfIPIsNotChanged()
|
|
{
|
|
$locations = array(
|
|
'pl' => array(
|
|
'city' => 'Wroclaw',
|
|
'country_code' => 'pl'
|
|
),
|
|
|
|
'nz' => array(
|
|
'city' => 'Wellington',
|
|
'country_code' => 'nz'
|
|
),
|
|
);
|
|
|
|
$poland = $this->getProviderMock();
|
|
$poland->expects($this->once())
|
|
->method('getLocation')
|
|
->will($this->returnValue($locations['pl']));
|
|
|
|
$geolocator = new VisitorGeolocator($poland);
|
|
$geolocator->getLocation(array('ip' => '10.0.0.1'));
|
|
|
|
$nz = $this->getProviderMock();
|
|
$nz->expects($this->once())
|
|
->method('getLocation')
|
|
->will($this->returnValue($locations['nz']));
|
|
|
|
$geolocator = new VisitorGeolocator($nz);
|
|
$geolocator->getLocation(array('ip' => '10.0.0.2'));
|
|
|
|
$this->assertEquals(
|
|
$locations,
|
|
array(
|
|
'pl' => $geolocator->getLocation(array('ip' => '10.0.0.1')),
|
|
'nz' => $geolocator->getLocation(array('ip' => '10.0.0.2'))
|
|
)
|
|
);
|
|
}
|
|
|
|
public function testGetShouldReturnDefaultProviderIfCurrentProviderReturnFalse()
|
|
{
|
|
Cache::setCacheGeneral(array('currentLocationProviderId' => 'nonexistant'));
|
|
$geolocator = new VisitorGeolocator();
|
|
|
|
$this->assertEquals(LocationProvider\DefaultProvider::ID, $geolocator->getProvider()->getId());
|
|
}
|
|
|
|
public function testGetShouldReturnCurrentProviderIfCurrentProviderIsSet()
|
|
{
|
|
Cache::setCacheGeneral(array('currentLocationProviderId' => MockLocationProvider::ID));
|
|
$geolocator = new VisitorGeolocator();
|
|
|
|
$this->assertEquals(MockLocationProvider::ID, $geolocator->getProvider()->getId());
|
|
}
|
|
|
|
public function getDataForAttributeExistingVisitTests()
|
|
{
|
|
$basicTestLocation = array(
|
|
LocationProvider::COUNTRY_CODE_KEY => 'US',
|
|
LocationProvider::REGION_CODE_KEY => 'rg',
|
|
LocationProvider::CITY_NAME_KEY => 'the city',
|
|
LocationProvider::LATITUDE_KEY => '29.959698',
|
|
LocationProvider::LONGITUDE_KEY => '-90.064880'
|
|
);
|
|
|
|
// note: floating point values should be used for expected properties so floating point comparison is done
|
|
// by PHPUnit
|
|
$basicExpectedVisitProperties = array(
|
|
'location_country' => 'us',
|
|
'location_region' => 'rg',
|
|
'location_city' => 'the city',
|
|
'location_latitude' => 29.959698,
|
|
'location_longitude' => -90.064880
|
|
);
|
|
|
|
return array(
|
|
array( // test normal re-attribution
|
|
$basicTestLocation,
|
|
|
|
$basicExpectedVisitProperties
|
|
),
|
|
|
|
array( // test w/ garbage in location provider result
|
|
array(
|
|
LocationProvider::COUNTRY_CODE_KEY => 'US',
|
|
'garbage' => 'field',
|
|
LocationProvider::REGION_CODE_KEY => 'rg',
|
|
LocationProvider::CITY_NAME_KEY => 'the city',
|
|
LocationProvider::LATITUDE_KEY => '29.959698',
|
|
LocationProvider::LONGITUDE_KEY => '-90.064880',
|
|
'another' => 'garbage field'
|
|
),
|
|
|
|
array(
|
|
'location_country' => 'us',
|
|
'location_region' => 'rg',
|
|
'location_city' => 'the city',
|
|
'location_latitude' => 29.959698,
|
|
'location_longitude' => -90.064880
|
|
)
|
|
),
|
|
|
|
array( // test when visit has some correct properties already
|
|
$basicTestLocation,
|
|
|
|
$basicExpectedVisitProperties,
|
|
|
|
array(
|
|
'location_country' => 'US',
|
|
'location_region' => 'rg',
|
|
'location_city' => 'the city'
|
|
),
|
|
|
|
array(
|
|
'location_country' => 'us',
|
|
'location_latitude' => 29.959698,
|
|
'location_longitude' => -90.064880
|
|
)
|
|
),
|
|
|
|
array( // test when visit has all correct properties already
|
|
$basicTestLocation,
|
|
|
|
$basicExpectedVisitProperties,
|
|
|
|
$basicExpectedVisitProperties,
|
|
|
|
array()
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @dataProvider getDataForAttributeExistingVisitTests
|
|
*/
|
|
public function testAttributeExistingVisitCorrectlySetsLocationPropertiesAndReturnsCorrectResult(
|
|
$mockLocation,
|
|
$expectedVisitProperties,
|
|
$visitProperties = array(),
|
|
$expectedUpdateValues = null
|
|
) {
|
|
$mockLocationProvider = $this->getProviderMockThatGeolocates($mockLocation);
|
|
|
|
$visit = $this->insertVisit($visitProperties);
|
|
$this->insertTwoConversions($visit);
|
|
|
|
$geolocator = new VisitorGeolocator($mockLocationProvider);
|
|
$valuesUpdated = $geolocator->attributeExistingVisit($visit, $useCache = false);
|
|
|
|
$this->assertEqualsWithDelta($expectedVisitProperties, $this->logInserter->getVisit($visit['idvisit']), $delta = 0.001);
|
|
|
|
$expectedUpdateValues = $expectedUpdateValues === null ? $expectedVisitProperties : $expectedUpdateValues;
|
|
$this->assertEqualsWithDelta($expectedUpdateValues, $valuesUpdated, $delta = 0.001);
|
|
|
|
$conversions = $this->getConversions($visit);
|
|
$this->assertEqualsWithDelta(array($expectedVisitProperties, $expectedVisitProperties), $conversions, $delta = 0.001);
|
|
}
|
|
|
|
public function testAttributeExistingVisitReturnsNullAndSkipsAttributionIfIdVisitMissingFromInput()
|
|
{
|
|
$mockLocationProvider = $this->getProviderMock();
|
|
$geolocator = new VisitorGeolocator($mockLocationProvider);
|
|
|
|
$result = $geolocator->attributeExistingVisit(array());
|
|
|
|
$this->assertNull($result);
|
|
}
|
|
|
|
public function testAttributeExistingVisitReturnsNullAndSkipsAttributionIfIdVisitPresentAndLocationIpMissingFromInput()
|
|
{
|
|
$mockLocationProvider = $this->getProviderMock();
|
|
$geolocator = new VisitorGeolocator($mockLocationProvider);
|
|
|
|
$result = $geolocator->attributeExistingVisit(array('idvisit' => 1));
|
|
|
|
$this->assertNull($result);
|
|
}
|
|
|
|
public function testReattributeVisitLogsReattributesVisitsInDateRangeAndFromSiteAndCallsCallbackWithEveryProcessedRow()
|
|
{
|
|
foreach (array(1, 2) as $idSite) {
|
|
foreach (array('2012-01-01', '2012-01-02', '2012-01-03', '2012-01-04') as $date) {
|
|
$this->insertVisit(array(
|
|
'visit_last_action_time' => $date,
|
|
'idsite' => $idSite
|
|
));
|
|
}
|
|
}
|
|
|
|
$mockLocationProvider = $this->getProviderMockThatGeolocates(array(
|
|
'location_country' => 'US',
|
|
'location_region' => 'rg',
|
|
'location_city' => 'the city'
|
|
));
|
|
$geolocator = new VisitorGeolocator($mockLocationProvider);
|
|
|
|
$reattributedVisits = array();
|
|
$geolocator->reattributeVisitLogs('2012-01-02', '2012-01-04', 2, $segmentLimit = 1000, function ($row) use (&$reattributedVisits) {
|
|
$reattributedVisits[] = $row['idvisit'];
|
|
});
|
|
|
|
sort($reattributedVisits);
|
|
|
|
$expectedVisitsVisited = array(6, 7);
|
|
$this->assertEquals($expectedVisitsVisited, $reattributedVisits);
|
|
|
|
// check that no visits were re-attributed for site 1
|
|
$actualVisits = Db::fetchAll("SELECT visit_last_action_time, idsite, location_country, location_region, location_city FROM "
|
|
. Common::prefixTable('log_visit') . " ORDER BY idsite ASC, visit_last_action_time ASC");
|
|
$expectedVisits = array(
|
|
array(
|
|
'visit_last_action_time' => '2012-01-01 00:00:00',
|
|
'idsite' => '1',
|
|
'location_country' => 'xx',
|
|
'location_region' => null,
|
|
'location_city' => null
|
|
),
|
|
array(
|
|
'visit_last_action_time' => '2012-01-02 00:00:00',
|
|
'idsite' => '1',
|
|
'location_country' => 'xx',
|
|
'location_region' => null,
|
|
'location_city' => null
|
|
),
|
|
array(
|
|
'visit_last_action_time' => '2012-01-03 00:00:00',
|
|
'idsite' => '1',
|
|
'location_country' => 'xx',
|
|
'location_region' => null,
|
|
'location_city' => null
|
|
),
|
|
array(
|
|
'visit_last_action_time' => '2012-01-04 00:00:00',
|
|
'idsite' => '1',
|
|
'location_country' => 'xx',
|
|
'location_region' => null,
|
|
'location_city' => null
|
|
),
|
|
array(
|
|
'visit_last_action_time' => '2012-01-01 00:00:00',
|
|
'idsite' => '2',
|
|
'location_country' => 'xx',
|
|
'location_region' => null,
|
|
'location_city' => null
|
|
),
|
|
array(
|
|
'visit_last_action_time' => '2012-01-02 00:00:00',
|
|
'idsite' => '2',
|
|
'location_country' => 'us',
|
|
'location_region' => 'rg',
|
|
'location_city' => 'the city'
|
|
),
|
|
array(
|
|
'visit_last_action_time' => '2012-01-03 00:00:00',
|
|
'idsite' => '2',
|
|
'location_country' => 'us',
|
|
'location_region' => 'rg',
|
|
'location_city' => 'the city'
|
|
),
|
|
array(
|
|
'visit_last_action_time' => '2012-01-04 00:00:00',
|
|
'idsite' => '2',
|
|
'location_country' => 'xx',
|
|
'location_region' => null,
|
|
'location_city' => null
|
|
),
|
|
);
|
|
|
|
$this->assertEquals($expectedVisits, $actualVisits);
|
|
}
|
|
|
|
/**
|
|
* @return \PHPUnit\Framework\MockObject\MockObject|LocationProvider
|
|
*/
|
|
protected function getProviderMock()
|
|
{
|
|
return $this->getMockBuilder('\Piwik\Plugins\UserCountry\LocationProvider')
|
|
->setMethods(array('getId', 'getInfo', 'getLocation', 'isAvailable', 'isWorking', 'getSupportedLocationInfo'))
|
|
->disableOriginalConstructor()
|
|
->getMock();
|
|
}
|
|
|
|
private function getProviderMockThatGeolocates($locationResult)
|
|
{
|
|
$mock = $this->getProviderMock();
|
|
$mock->expects($this->any())->method('getLocation')->will($this->returnCallback(function ($info) use ($locationResult) {
|
|
if ($info['ip'] == VisitorGeolocatorTest::TEST_IP) {
|
|
return $locationResult;
|
|
} else {
|
|
return null;
|
|
}
|
|
}));
|
|
return $mock;
|
|
}
|
|
|
|
private function insertVisit($visit = array())
|
|
{
|
|
$defaultProperties = array(
|
|
'location_ip' => IPUtils::stringToBinaryIP(self::TEST_IP)
|
|
);
|
|
|
|
return $this->logInserter->insertVisit(array_merge($defaultProperties, $visit));
|
|
}
|
|
|
|
private function insertTwoConversions($visit)
|
|
{
|
|
$conversionProperties = array(
|
|
'idsite' => $visit['idsite'],
|
|
'idvisitor' => $visit['idvisitor'],
|
|
'location_longitude' => $visit['location_longitude'],
|
|
'location_latitude' => $visit['location_latitude'],
|
|
'location_region' => $visit['location_region'],
|
|
'location_country' => $visit['location_country'],
|
|
'location_city' => $visit['location_city'],
|
|
'visitor_count_visits' => $visit['visitor_count_visits'],
|
|
'visitor_returning' => $visit['visitor_returning'],
|
|
);
|
|
|
|
$this->logInserter->insertConversion($visit['idvisit'], $conversionProperties);
|
|
|
|
$conversionProperties['buster'] = 2;
|
|
$this->logInserter->insertConversion($visit['idvisit'], $conversionProperties);
|
|
}
|
|
|
|
private function getConversions($visit)
|
|
{
|
|
return Db::fetchAll("SELECT location_country, location_region, location_city, location_latitude, location_longitude
|
|
FROM " . Common::prefixTable('log_conversion') . " WHERE idvisit = ?", array($visit['idvisit']));
|
|
}
|
|
}
|