From b7b8ed19820e75559236009502a73ea08fa57c6f Mon Sep 17 00:00:00 2001 From: sgiehl <stefangiehl@gmail.com> Date: Tue, 26 Jun 2012 15:06:33 +0000 Subject: [PATCH] refs #3227 more tests converted to PHPUnit git-svn-id: http://dev.piwik.org/svn/trunk@6504 59fd770c-687e-43c8-a1e3-f5a4ff64c105 --- tests/PHPUnit/Core/ArchiveProcessingTest.php | 459 ++++++++++++++++++ .../Core/Tracker/Action.config.ini.php | 5 + tests/PHPUnit/Core/Tracker/ActionTest.php | 319 ++++++++++++ 3 files changed, 783 insertions(+) create mode 100644 tests/PHPUnit/Core/ArchiveProcessingTest.php create mode 100644 tests/PHPUnit/Core/Tracker/Action.config.ini.php create mode 100644 tests/PHPUnit/Core/Tracker/ActionTest.php diff --git a/tests/PHPUnit/Core/ArchiveProcessingTest.php b/tests/PHPUnit/Core/ArchiveProcessingTest.php new file mode 100644 index 0000000000..92f305553c --- /dev/null +++ b/tests/PHPUnit/Core/ArchiveProcessingTest.php @@ -0,0 +1,459 @@ +<?php +/** + * Piwik - Open source web analytics + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * @version $Id$ + */ +class ArchiveProcessingTest extends DatabaseTestCase +{ + public function setUp() + { + parent::setUp(); + + // setup the access layer + $pseudoMockAccess = new FakeAccess; + FakeAccess::$superUser = true; + Zend_Registry::set('access', $pseudoMockAccess); + } + + /** + * Creates a new website + * + * @param string $timezone + * @return Piwik_Site + */ + private function _createWebsite($timezone = 'UTC') + { + $idSite = Piwik_SitesManager_API::getInstance()->addSite( + "site1", + array("http://piwik.net"), + $ecommerce=0, + $excludedIps = "", + $excludedQueryParameters = "", + $timezone); + + Piwik_Site::clearCache(); + return new Piwik_Site($idSite); + } + + /** + * Creates a new ArchiveProcessing object + * + * @param string $periodLabel + * @param string $dateLabel + * @param string $siteTimezone + * @return Piwik_ArchiveProcessing + */ + private function _createArchiveProcessing($periodLabel, $dateLabel, $siteTimezone) + { + $site = $this->_createWebsite($siteTimezone); + $date = Piwik_Date::factory($dateLabel); + $period = Piwik_Period::factory($periodLabel, $date); + + $archiveProcessing = Piwik_ArchiveProcessing::factory($periodLabel); + $archiveProcessing->setSite($site); + $archiveProcessing->setPeriod($period); + $archiveProcessing->setSegment(new Piwik_Segment('', $site->getId())); + $archiveProcessing->init(); + return $archiveProcessing; + } + + /** + * test of validity of an archive, for a month not finished + * @group Core + * @group ArchiveProcessing + */ + public function testInitCurrentMonth() + { + $siteTimezone = 'UTC+10'; + $now = time(); + + $dateLabel = date('Y-m-d', $now); + $archiveProcessing = $this->_createArchiveProcessing('month', $dateLabel, $siteTimezone); + $archiveProcessing->time = $now; + + // min finished timestamp considered when looking at archive timestamp + $timeout = Piwik_ArchiveProcessing::getTodayArchiveTimeToLive(); + $this->assertTrue($timeout >= 10); + $dateMinArchived = $now - $timeout; + + $minTimestamp = $archiveProcessing->getMinTimeArchivedProcessed(); + $this->assertEquals($minTimestamp, $dateMinArchived, Piwik_Date::factory($minTimestamp)->getDatetime() . " != " . Piwik_Date::factory($dateMinArchived)->getDatetime()); + $this->assertTrue($archiveProcessing->isArchiveTemporary()); + } + + /** + * test of validity of an archive, for a month in the past + * @group Core + * @group ArchiveProcessing + */ + public function testInitDayInPast() + { + $archiveProcessing = $this->_createArchiveProcessing('day', '2010-01-01', 'UTC'); + + // min finished timestamp considered when looking at archive timestamp + $dateMinArchived = Piwik_Date::factory('2010-01-02')->getTimestamp(); + $this->assertEquals($archiveProcessing->getMinTimeArchivedProcessed() + 1, $dateMinArchived); + + $this->assertEquals('2010-01-01 00:00:00', $archiveProcessing->getStartDatetimeUTC()); + $this->assertEquals('2010-01-01 23:59:59', $archiveProcessing->getEndDatetimeUTC()); + $this->assertFalse($archiveProcessing->isArchiveTemporary()); + } + + /** + * test of validity of an archive, for a non UTC date in the past + * @group Core + * @group ArchiveProcessing + */ + public function testInitDayInPastNonUTCWebsite() + { + $timezone = 'UTC+5.5'; + $archiveProcessing = $this->_createArchiveProcessing('day', '2010-01-01', $timezone); + // min finished timestamp considered when looking at archive timestamp + $dateMinArchived = Piwik_Date::factory('2010-01-01 18:30:00'); + $this->assertEquals($archiveProcessing->getMinTimeArchivedProcessed() + 1, $dateMinArchived->getTimestamp()); + + $this->assertEquals('2009-12-31 18:30:00', $archiveProcessing->getStartDatetimeUTC()); + $this->assertEquals('2010-01-01 18:29:59', $archiveProcessing->getEndDatetimeUTC()); + $this->assertFalse($archiveProcessing->isArchiveTemporary()); + } + + /** + * test of validity of an archive, for a non UTC month in the past + * @group Core + * @group ArchiveProcessing + */ + public function testInitMonthInPastNonUTCWebsite() + { + $timezone = 'UTC-5.5'; + $archiveProcessing = $this->_createArchiveProcessing('month', '2010-01-02', $timezone); + // min finished timestamp considered when looking at archive timestamp + $dateMinArchived = Piwik_Date::factory('2010-02-01 05:30:00'); + $this->assertEquals($archiveProcessing->getMinTimeArchivedProcessed() + 1, $dateMinArchived->getTimestamp()); + + $this->assertEquals('2010-01-01 05:30:00', $archiveProcessing->getStartDatetimeUTC()); + $this->assertEquals('2010-02-01 05:29:59', $archiveProcessing->getEndDatetimeUTC()); + $this->assertFalse($archiveProcessing->isArchiveTemporary()); + } + + /** + * test of validity of an archive, for today's archive + * @group Core + * @group ArchiveProcessing + */ + public function testInitToday() + { + $now = time(); + $siteTimezone = 'UTC-1'; + $timestamp = Piwik_Date::factory('now', $siteTimezone)->getTimestamp(); + $dateLabel = date('Y-m-d', $timestamp); + + Piwik_ArchiveProcessing::setBrowserTriggerArchiving(true); + + $archiveProcessing = $this->_createArchiveProcessing('day', $dateLabel, $siteTimezone); + $archiveProcessing->time = $now; + + // we look at anything processed within the time to live range + $dateMinArchived = $now - Piwik_ArchiveProcessing::getTodayArchiveTimeToLive(); + $this->assertEquals($dateMinArchived, $archiveProcessing->getMinTimeArchivedProcessed()); + $this->assertTrue($archiveProcessing->isArchiveTemporary()); + + // when browsers don't trigger archives, we force ArchiveProcessing + // to fetch any of the most recent archive + Piwik_ArchiveProcessing::setBrowserTriggerArchiving(false); + // see isArchivingDisabled() + // Running in CLI doesn't impact the time to live today's archive we are loading + // From CLI, we will not return data that is 'stale' + if(!Piwik_Common::isPhpCliMode()) + { + $dateMinArchived = 0; + } + $this->assertEquals($archiveProcessing->getMinTimeArchivedProcessed(), $dateMinArchived); + + $this->assertEquals(date('Y-m-d', $timestamp).' 01:00:00', $archiveProcessing->getStartDatetimeUTC()); + $this->assertEquals(date('Y-m-d', $timestamp+86400).' 00:59:59', $archiveProcessing->getEndDatetimeUTC()); + $this->assertTrue($archiveProcessing->isArchiveTemporary()); + } + + /** + * test of validity of an archive, for today's archive with european timezone + * @group Core + * @group ArchiveProcessing + */ + public function testInitTodayEurope() + { + if(!Piwik::isTimezoneSupportEnabled()) + { + $this->markTestSkipped('timezones needs to be supported'); + } + + $now = time(); + $siteTimezone = 'Europe/Paris'; + $timestamp = Piwik_Date::factory('now', $siteTimezone)->getTimestamp(); + $dateLabel = date('Y-m-d', $timestamp); + + Piwik_ArchiveProcessing::setBrowserTriggerArchiving(true); + + $archiveProcessing = $this->_createArchiveProcessing('day', $dateLabel, $siteTimezone); + $archiveProcessing->time = $now; + + // we look at anything processed within the time to live range + $dateMinArchived = $now - Piwik_ArchiveProcessing::getTodayArchiveTimeToLive(); + $this->assertEquals($archiveProcessing->getMinTimeArchivedProcessed(), $dateMinArchived); + $this->assertTrue($archiveProcessing->isArchiveTemporary()); + + // when browsers don't trigger archives, we force ArchiveProcessing + // to fetch any of the most recent archive + Piwik_ArchiveProcessing::setBrowserTriggerArchiving(false); + // see isArchivingDisabled() + // Running in CLI doesn't impact the time to live today's archive we are loading + // From CLI, we will not return data that is 'stale' + if(!Piwik_Common::isPhpCliMode()) + { + $dateMinArchived = 0; + } + $this->assertEquals($archiveProcessing->getMinTimeArchivedProcessed(), $dateMinArchived); + + // this test varies with DST + $this->assertTrue($archiveProcessing->getStartDatetimeUTC() == date('Y-m-d', $timestamp-86400).' 22:00:00' || + $archiveProcessing->getStartDatetimeUTC() == date('Y-m-d', $timestamp-86400).' 23:00:00'); + $this->assertTrue($archiveProcessing->getEndDatetimeUTC() == date('Y-m-d', $timestamp).' 21:59:59' || + $archiveProcessing->getEndDatetimeUTC() == date('Y-m-d', $timestamp).' 22:59:59'); + + $this->assertTrue($archiveProcessing->isArchiveTemporary()); + } + + /** + * test of validity of an archive, for today's archive with toronto's timezone + * @group Core + * @group ArchiveProcessing + */ + public function testInitTodayToronto() + { + if(!Piwik::isTimezoneSupportEnabled()) + { + $this->markTestSkipped('timezones needs to be supported'); + } + + $now = time(); + $siteTimezone = 'America/Toronto'; + $timestamp = Piwik_Date::factory('now', $siteTimezone)->getTimestamp(); + $dateLabel = date('Y-m-d', $timestamp); + + Piwik_ArchiveProcessing::setBrowserTriggerArchiving(true); + + $archiveProcessing = $this->_createArchiveProcessing('day', $dateLabel, $siteTimezone); + $archiveProcessing->time = $now; + + // we look at anything processed within the time to live range + $dateMinArchived = $now - Piwik_ArchiveProcessing::getTodayArchiveTimeToLive(); + $this->assertEquals($archiveProcessing->getMinTimeArchivedProcessed(), $dateMinArchived); + $this->assertTrue($archiveProcessing->isArchiveTemporary()); + + // when browsers don't trigger archives, we force ArchiveProcessing + // to fetch any of the most recent archive + Piwik_ArchiveProcessing::setBrowserTriggerArchiving(false); + // see isArchivingDisabled() + // Running in CLI doesn't impact the time to live today's archive we are loading + // From CLI, we will not return data that is 'stale' + if(!Piwik_Common::isPhpCliMode()) + { + $dateMinArchived = 0; + } + $this->assertEquals($archiveProcessing->getMinTimeArchivedProcessed(), $dateMinArchived); + + // this test varies with DST + $this->assertTrue($archiveProcessing->getStartDatetimeUTC() == date('Y-m-d', $timestamp).' 04:00:00' || + $archiveProcessing->getStartDatetimeUTC() == date('Y-m-d', $timestamp).' 05:00:00'); + $this->assertTrue($archiveProcessing->getEndDatetimeUTC() == date('Y-m-d', $timestamp+86400).' 03:59:59' || + $archiveProcessing->getEndDatetimeUTC() == date('Y-m-d', $timestamp+86400).' 04:59:59'); + + $this->assertTrue($archiveProcessing->isArchiveTemporary()); + } + + /** + * Testing batch insert + * @group Core + * @group ArchiveProcessing + */ + public function testTableInsertBatch() + { + $table = Piwik_Common::prefixTable('site_url'); + $data = $this->_getDataInsert(); + $didWeUseBulk = Piwik::tableInsertBatch($table, array('idsite', 'url'), $data); + if(version_compare(PHP_VERSION, '5.2.9') < 0 || + version_compare(PHP_VERSION, '5.3.7') >= 0 || + Piwik_Config::getInstance()->database['adapter'] != 'PDO_MYSQL') + { + $this->assertTrue($didWeUseBulk, "The test didn't LOAD DATA INFILE but fallbacked to plain INSERT, but we must unit test this function!"); + } + $this->_checkTableIsExpected($table, $data); + + // INSERT again the bulk. Because we use keyword LOCAL the data will be REPLACED automatically (see mysql doc) + Piwik::tableInsertBatch($table, array('idsite', 'url'), $data); + $this->_checkTableIsExpected($table, $data); + } + + /** + * Testing plain inserts + * @group Core + * @group ArchiveProcessing + */ + public function testTableInsertBatchIterate() + { + $table = Piwik_Common::prefixTable('site_url'); + $data = $this->_getDataInsert(); + Piwik::tableInsertBatchIterate($table, array('idsite', 'url'), $data); + $this->_checkTableIsExpected($table, $data); + + // If we insert AGAIN, expect to throw an error because the primary key already exists + try { + Piwik::tableInsertBatchIterate($table, array('idsite', 'url'), $data, $ignoreWhenDuplicate = false); + } catch (Exception $e) { + // However if we insert with keyword REPLACE, then the new data should be saved + Piwik::tableInsertBatchIterate($table, array('idsite', 'url'), $data, $ignoreWhenDuplicate = true ); + $this->_checkTableIsExpected($table, $data); + return; + } + $this->fail('Exception expected'); + } + + /** + * Testing batch insert (BLOB) + * @group Core + * @group ArchiveProcessing + */ + public function testTableInsertBatchBlob() + { + $siteTimezone = 'America/Toronto'; + $dateLabel = '2011-03-31'; + $archiveProcessing = $this->_createArchiveProcessing('day', $dateLabel, $siteTimezone); + + $table = $archiveProcessing->getTableArchiveBlobName(); + + $data = $this->_getBlobDataInsert(); + $didWeUseBulk = Piwik::tableInsertBatch($table, array('idarchive', 'name', 'idsite', 'date1', 'date2', 'period', 'ts_archived', 'value'), $data); + if(version_compare(PHP_VERSION, '5.2.9') < 0 || + version_compare(PHP_VERSION, '5.3.7') >= 0 || + Piwik_Config::getInstance()->database['adapter'] != 'PDO_MYSQL') + { + $this->assertTrue($didWeUseBulk, "The test didn't LOAD DATA INFILE but fallbacked to plain INSERT, but we must unit test this function!"); + } + $this->_checkTableIsExpectedBlob($table, $data); + + // INSERT again the bulk. Because we use keyword LOCAL the data will be REPLACED automatically (see mysql doc) + Piwik::tableInsertBatch($table, array('idarchive', 'name', 'idsite', 'date1', 'date2', 'period', 'ts_archived', 'value'), $data); + $this->_checkTableIsExpectedBlob($table, $data); + } + + /** + * Testing plain inserts (BLOB) + * @group Core + * @group ArchiveProcessing + */ + public function testTableInsertBatchIterateBlob() + { + $siteTimezone = 'America/Toronto'; + $dateLabel = '2011-03-31'; + $archiveProcessing = $this->_createArchiveProcessing('day', $dateLabel, $siteTimezone); + + $table = $archiveProcessing->getTableArchiveBlobName(); + + $data = $this->_getBlobDataInsert(); + Piwik::tableInsertBatchIterate($table, array('idarchive', 'name', 'idsite', 'date1', 'date2', 'period', 'ts_archived', 'value'), $data); + $this->_checkTableIsExpectedBlob($table, $data); + + // If we insert AGAIN, expect to throw an error because the primary key already exist + try { + Piwik::tableInsertBatchIterate($table, array('idarchive', 'name', 'idsite', 'date1', 'date2', 'period', 'ts_archived', 'value'), $data, $ignoreWhenDuplicate = false); + } catch (Exception $e) { + // However if we insert with keyword REPLACE, then the new data should be saved + Piwik::tableInsertBatchIterate($table, array('idarchive', 'name', 'idsite', 'date1', 'date2', 'period', 'ts_archived', 'value'), $data, $ignoreWhenDuplicate = true ); + $this->_checkTableIsExpectedBlob($table, $data); + return; + } + $this->fail('Exception expected'); + } + + + protected function _checkTableIsExpected($table, $data) + { + $fetched = Piwik_FetchAll('SELECT * FROM '.$table); + foreach($data as $id => $row) { + $this->assertEquals($fetched[$id]['idsite'], $data[$id][0], "record $id is not {$data[$id][0]}"); + $this->assertEquals($fetched[$id]['url'], $data[$id][1], "Record $id bug, not {$data[$id][1]} BUT {$fetched[$id]['url']}"); + } + } + + protected function _checkTableIsExpectedBlob($table, $data) + { + $fetched = Piwik_FetchAll('SELECT * FROM '.$table); + foreach($data as $id => $row) { + $this->assertEquals($fetched[$id]['idarchive'], $data[$id][0], "record $id idarchive is not '{$data[$id][0]}'"); + $this->assertEquals($fetched[$id]['name'], $data[$id][1], "record $id name is not '{$data[$id][1]}'"); + $this->assertEquals($fetched[$id]['idsite'], $data[$id][2], "record $id idsite is not '{$data[$id][2]}'"); + $this->assertEquals($fetched[$id]['date1'], $data[$id][3], "record $id date1 is not '{$data[$id][3]}'"); + $this->assertEquals($fetched[$id]['date2'], $data[$id][4], "record $id date2 is not '{$data[$id][4]}'"); + $this->assertEquals($fetched[$id]['period'], $data[$id][5], "record $id period is not '{$data[$id][5]}'"); + $this->assertEquals($fetched[$id]['ts_archived'], $data[$id][6], "record $id ts_archived is not '{$data[$id][6]}'"); + $this->assertEquals($fetched[$id]['value'], $data[$id][7], "record $id value is unexpected"); + } + } + + /* + * Schema for site_url table: + * site_url ( + * idsite INTEGER(10) UNSIGNED NOT NULL, + * url VARCHAR(255) NOT NULL, + * PRIMARY KEY(idsite, url) + * ) + */ + protected function _getDataInsert() + { + return array( + array(1, 'test'), + array(2, 'te" \n st2'), + array(3, " \n \r \t test"), + + // these aren't expected to work on a column of datatype VARCHAR +// array(4, gzcompress( " \n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942")), +// array(5, gzcompress('test4')), + + array(6, 'test5'), + array(7, 'ç®€ä½“ä¸æ–‡'), + array(8, '"'), + array(9, "'"), + array(10, '\\'), + array(11, '\\"'), + array(12, '\\\''), + array(13, "\t"), + array(14, "test \x00 null"), + array(15, "\x00\x01\x02\0x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"), + ); + } + + /** + * see archive_blob table + */ + protected function _getBlobDataInsert() + { + $ts = '2011-03-31 17:48:00'; + $str = ''; + for($i = 0; $i < 256; $i++) + { + $str .= chr($i); + } + $array[] = array(1, 'bytes 0-255', 1, '2011-03-31', '2011-03-31', Piwik::$idPeriods['day'], $ts, $str); + + $array[] = array(2, 'compressed string', 1, '2011-03-31', '2011-03-31', Piwik::$idPeriods['day'], $ts, gzcompress( " \n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942\n \r \t teste eigaj oegheao geaoh guoea98742983 2 342942")); + + $str = file_get_contents(PIWIK_PATH_TEST_TO_ROOT . '/tests/core/Piwik/lipsum.txt'); + $array[] = array(3, 'lorem ipsum', 1, '2011-03-31', '2011-03-31', Piwik::$idPeriods['day'], $ts, $str); + + $array[] = array(4, 'lorem ipsum compressed', 1, '2011-03-31', '2011-03-31', Piwik::$idPeriods['day'], $ts, gzcompress($str)); + + return $array; + } +} diff --git a/tests/PHPUnit/Core/Tracker/Action.config.ini.php b/tests/PHPUnit/Core/Tracker/Action.config.ini.php new file mode 100644 index 0000000000..706eb1e313 --- /dev/null +++ b/tests/PHPUnit/Core/Tracker/Action.config.ini.php @@ -0,0 +1,5 @@ +[Tracker] +action_url_category_delimiter = "/" +default_action_url = "/" +campaign_var_name = "campaign_param_name,piwik_campaign,utm_campaign,test_campaign_name" +campaign_keyword_var_name = "piwik_kwd,utm_term,test_piwik_kwd" diff --git a/tests/PHPUnit/Core/Tracker/ActionTest.php b/tests/PHPUnit/Core/Tracker/ActionTest.php new file mode 100644 index 0000000000..3fa59cb01e --- /dev/null +++ b/tests/PHPUnit/Core/Tracker/ActionTest.php @@ -0,0 +1,319 @@ +<?php +/** + * Piwik - Open source web analytics + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * @version $Id$ + */ +class Tracker_ActionTest extends DatabaseTestCase +{ + public function setUp() + { + parent::setUp(); + $userFile = dirname(__FILE__) . '/Action.config.ini.php'; + $config = Piwik_Config::getInstance(); + $config->clear(); + $config->setTestEnvironment($userFile, false); + } + + protected function setUpRootAccess() + { + $pseudoMockAccess = new FakeAccess; + FakeAccess::$superUser = true; + Zend_Registry::set('access', $pseudoMockAccess); + } + + public function getTestUrls() + { + $campaignNameParam = 'test_campaign_name'; + $campaignKwdParam = 'test_piwik_kwd'; + + $urls = array( + // a wrongly formatted url (parse_url returns false) + array('http:////wrongurl', + array('http:////wrongurl', + 'http:////wrongurl')), + + // a URL with all components + array('http://username:password@hostname:80/path?phpSESSID=value#anchor', + array('http://username:password@hostname:80/path#anchor', + 'http://username:password@hostname:80/path#anchor')), + + // a standard url with excluded campaign parameters + array('http://a.com/index?p1=v1&'.$campaignNameParam.'=Adwords-CPC&'.$campaignKwdParam.'=My killer keyword', + array('http://a.com/index?p1=v1', + 'http://a.com/index?p1=v1')), + + // a standard url with excluded campaign parameters, GA style + array('http://a.com/index?p1=v1&utm_campaign=Adwords-CPC&utm_term=My killer keyword', + array('http://a.com/index?p1=v1', + 'http://a.com/index?p1=v1')), + + // testing with capital parameter + array('http://a.com/index?p1=v1&P2=v2&p3=v3', + array('http://a.com/index?p1=v1&P2=v2&p3=v3', + 'http://a.com/index?p1=v1&p3=v3')), + + // testing with array [] + array('http://a.com/index?p1=v1&p2[]=v2a&p2[]=v2b&p2[]=v2c&p3=v3&p4=v4', + array('http://a.com/index?p1=v1&p2[]=v2a&p2[]=v2b&p2[]=v2c&p3=v3&p4=v4', + 'http://a.com/index?p1=v1&p3=v3')), + + // testing with missing value + array('http://a.com/index?p1=v1&p2=&p3=v3&p4', + array('http://a.com/index?p1=v1&p2=&p3=v3&p4', + 'http://a.com/index?p1=v1&p3=v3')), + array('http://a.com/index?p1&p2=v2&p3=v3&p4', + array('http://a.com/index?p1&p2=v2&p3=v3&p4', + 'http://a.com/index?p1&p3=v3')), + + // testing with extra && + array('http://a.com/index?p1=v1&&p2=v2&p3=v3&p4=v4&&', + array('http://a.com/index?p1=v1&p2=v2&p3=v3&p4=v4', + 'http://a.com/index?p1=v1&p3=v3')), + ); + + return $urls; + } + + /** + * No excluded query parameters specified, apart from the standard "session" parameters, always excluded + * + * @group Core + * @group Tracker + * @group Tracker_Action + * @dataProvider getTestUrls + */ + public function testExcludeQueryParametersNone($url, $filteredUrl) + { + $this->setUpRootAccess(); + $idSite = Piwik_SitesManager_API::getInstance()->addSite("site1",array('http://example.org'),$ecommerce=0, $excludedIps = '', $excludedQueryParameters=''); + $this->assertEquals($filteredUrl[0], Piwik_Tracker_Action::excludeQueryParametersFromUrl($url, $idSite)); + } + + /** + * Testing with some website specific parameters excluded + * @group Core + * @group Tracker + * @group Tracker_Action + * @dataProvider getTestUrls + */ + public function testExcludeQueryParametersSiteExcluded($url, $filteredUrl) + { + $excludedQueryParameters = 'p4, p2'; + $this->setUpRootAccess(); + $idSite = Piwik_SitesManager_API::getInstance()->addSite("site1",array('http://example.org'),$ecommerce=0, $excludedIps = '', $excludedQueryParameters); + $this->assertEquals($filteredUrl[1], Piwik_Tracker_Action::excludeQueryParametersFromUrl($url, $idSite)); + } + + /** + * Testing with some website specific and some global excluded query parameters + * @group Core + * @group Tracker + * @group Tracker_Action + * @dataProvider getTestUrls + */ + public function testExcludeQueryParametersSiteAndGlobalExcluded($url, $filteredUrl) + { + // testing also that query parameters are case insensitive + $excludedQueryParameters = 'P2'; + $excludedGlobalParameters = 'blabla, P4'; + $this->setUpRootAccess(); + $idSite = Piwik_SitesManager_API::getInstance()->addSite("site1",array('http://example.org'),$ecommerce=0, $excludedIps = '', $excludedQueryParameters); + Piwik_SitesManager_API::getInstance()->setGlobalExcludedQueryParameters($excludedGlobalParameters); + $this->assertEquals($filteredUrl[1], Piwik_Tracker_Action::excludeQueryParametersFromUrl($url, $idSite)); + } + + + public function getExtractUrlData() { + return array( + // outlinks + array( + 'request' => array('link' => 'http://example.org'), + 'expected' => array('name' => null, + 'url' => 'http://example.org', + 'type' => Piwik_Tracker_Action::TYPE_OUTLINK), + ), + // outlinks with custom name + array( + 'request' => array('link' => 'http://example.org', 'action_name' => 'Example.org'), + 'expected' => array('name' => 'Example.org', + 'url' => 'http://example.org', + 'type' => Piwik_Tracker_Action::TYPE_OUTLINK), + ), + // keep the case in urls, but trim + array( + 'request' => array('link' => ' http://example.org/Category/Test/ '), + 'expected' => array('name' => null, + 'url' => 'http://example.org/Category/Test/', + 'type' => Piwik_Tracker_Action::TYPE_OUTLINK), + ), + + // trim the custom name + array( + 'request' => array('link' => ' http://example.org/Category/Test/ ', 'action_name' => ' Example dot org '), + 'expected' => array('name' => 'Example dot org', + 'url' => 'http://example.org/Category/Test/', + 'type' => Piwik_Tracker_Action::TYPE_OUTLINK), + ), + + // downloads + array( + 'request' => array('download' => 'http://example.org/*$test.zip'), + 'expected' => array('name' => null, + 'url' => 'http://example.org/*$test.zip', + 'type' => Piwik_Tracker_Action::TYPE_DOWNLOAD), + ), + + // downloads with custom name + array( + 'request' => array('download' => 'http://example.org/*$test.zip', 'action_name' => 'Download test.zip'), + 'expected' => array('name' => 'Download test.zip', + 'url' => 'http://example.org/*$test.zip', + 'type' => Piwik_Tracker_Action::TYPE_DOWNLOAD), + ), + + // keep the case and multiple / in urls + array( + 'request' => array('download' => 'http://example.org/CATEGORY/test///test.pdf'), + 'expected' => array('name' => null, + 'url' => 'http://example.org/CATEGORY/test///test.pdf', + 'type' => Piwik_Tracker_Action::TYPE_DOWNLOAD), + ), + + // page view + array( + 'request' => array('url' => 'http://example.org/'), + 'expected' => array('name' => null, + 'url' => 'http://example.org/', + 'type' => Piwik_Tracker_Action::TYPE_ACTION_URL), + ), + array( + 'request' => array('url' => 'http://example.org/', 'action_name' => 'Example.org Website'), + 'expected' => array('name' => 'Example.org Website', + 'url' => 'http://example.org/', + 'type' => Piwik_Tracker_Action::TYPE_ACTION_URL), + ), + array( + 'request' => array('url' => 'http://example.org/CATEGORY/'), + 'expected' => array('name' => null, + 'url' => 'http://example.org/CATEGORY/', + 'type' => Piwik_Tracker_Action::TYPE_ACTION_URL), + ), + array( + 'request' => array('url' => 'http://example.org/CATEGORY/TEST', 'action_name' => 'Example.org / Category / test /'), + 'expected' => array('name' => 'Example.org/Category/test', + 'url' => 'http://example.org/CATEGORY/TEST', + 'type' => Piwik_Tracker_Action::TYPE_ACTION_URL), + ), + array( + 'request' => array('url' => 'http://example.org/?2,123'), + 'expected' => array('name' => null, + 'url' => 'http://example.org/?2,123', + 'type' => Piwik_Tracker_Action::TYPE_ACTION_URL), + ), + + // empty request + array( + 'request' => array(), + 'expected' => array('name' => null, 'url' => '', + 'type' => Piwik_Tracker_Action::TYPE_ACTION_URL), + ), + array( + 'request' => array('name' => null, 'url' => "\n"), + 'expected' => array('name' => null, 'url' => '', + 'type' => Piwik_Tracker_Action::TYPE_ACTION_URL), + ), + array( + 'request' => array('url' => 'http://example.org/category/', + 'action_name' => 'custom name with/one delimiter/two delimiters/'), + 'expected' => array('name' => 'custom name with/one delimiter/two delimiters', + 'url' => 'http://example.org/category/', + 'type' => Piwik_Tracker_Action::TYPE_ACTION_URL), + ), + array( + 'request' => array('url' => 'http://example.org/category/', + 'action_name' => 'http://custom action name look like url/'), + 'expected' => array('name' => 'http:/custom action name look like url', + 'url' => 'http://example.org/category/', + 'type' => Piwik_Tracker_Action::TYPE_ACTION_URL), + ), + // testing: delete tab, trimmed, not strtolowered + array( + 'request' => array('url' => "http://example.org/category/test///test wOw "), + 'expected' => array('name' => null, + 'url' => 'http://example.org/category/test///test wOw', + 'type' => Piwik_Tracker_Action::TYPE_ACTION_URL), + ), + // testing: inclusion of zero values in action name + array( + 'request' => array('url' => "http://example.org/category/1/0/t/test"), + 'expected' => array('name' => null, + 'url' => 'http://example.org/category/1/0/t/test', + 'type' => Piwik_Tracker_Action::TYPE_ACTION_URL), + ), + // testing: action name ("Test …") - expect decoding of some html entities + array( + 'request' => array('url' => 'http://example.org/ACTION/URL', + 'action_name' => "Test …"), + 'expected' => array('name' => 'Test …', + 'url' => 'http://example.org/ACTION/URL', + 'type' => Piwik_Tracker_Action::TYPE_ACTION_URL), + ), + // testing: action name ("Special & chars") - expect no conversion of html special chars + array( + 'request' => array('url' => 'http://example.org/ACTION/URL', + 'action_name' => "Special & chars"), + 'expected' => array('name' => 'Special & chars', + 'url' => 'http://example.org/ACTION/URL', + 'type' => Piwik_Tracker_Action::TYPE_ACTION_URL), + ), + // testing: action name ("Tést") - handle wide character + array( + 'request' => array('url' => 'http://example.org/ACTION/URL', + 'action_name' => "Tést"), + 'expected' => array('name' => 'Tést', + 'url' => 'http://example.org/ACTION/URL', + 'type' => Piwik_Tracker_Action::TYPE_ACTION_URL), + ), + // testing: action name ("Tést") - handle UTF-8 byte sequence + array( + 'request' => array('url' => 'http://example.org/ACTION/URL', + 'action_name' => "T\xc3\xa9st"), + 'expected' => array('name' => 'Tést', + 'url' => 'http://example.org/ACTION/URL', + 'type' => Piwik_Tracker_Action::TYPE_ACTION_URL), + ), + // testing: action name ("Tést") - invalid UTF-8 (e.g., ISO-8859-1) is not handled + array( + 'request' => array('url' => 'http://example.org/ACTION/URL', + 'action_name' => "T\xe9st"), + 'expected' => array('name' => version_compare(PHP_VERSION, '5.2.5') === -1 ? 'T\xe9st' : 'Tést', + 'url' => 'http://example.org/ACTION/URL', + 'type' => Piwik_Tracker_Action::TYPE_ACTION_URL), + ), + ); + } + + /** + * @dataProvider getExtractUrlData + * @group Core + * @group Tracker + * @group Tracker_Action + */ + function testExtractUrlAndActionNameFromRequest($request, $expected) + { + $action = new Test_Piwik_TrackerAction_extractUrlAndActionNameFromRequest(); + $action->setRequest($request); + $this->assertEquals($action->public_extractUrlAndActionNameFromRequest(), $expected); + } +} + +class Test_Piwik_TrackerAction_extractUrlAndActionNameFromRequest extends Piwik_Tracker_Action +{ + public function public_extractUrlAndActionNameFromRequest() + { + return $this->extractUrlAndActionNameFromRequest(); + } +} \ No newline at end of file -- GitLab