PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/PHPUnit/Fixtures/UITestFixture.php

https://github.com/CodeYellowBV/piwik
PHP | 299 lines | 238 code | 43 blank | 18 comment | 22 complexity | a1e772ca11e0cd59c014b927dac7eb6a MD5 | raw file
Possible License(s): LGPL-3.0, JSON, MIT, GPL-3.0, LGPL-2.1, GPL-2.0, AGPL-1.0, BSD-2-Clause, BSD-3-Clause
  1. <?php
  2. /**
  3. * Piwik - free/libre analytics platform
  4. *
  5. * @link http://piwik.org
  6. * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
  7. */
  8. namespace Piwik\Tests\Fixtures;
  9. use Exception;
  10. use Piwik\Access;
  11. use Piwik\AssetManager;
  12. use Piwik\Common;
  13. use Piwik\Date;
  14. use Piwik\Db;
  15. use Piwik\DbHelper;
  16. use Piwik\FrontController;
  17. use Piwik\Option;
  18. use Piwik\Plugins\SegmentEditor\API as APISegmentEditor;
  19. use Piwik\Plugins\UsersManager\API as UsersManagerAPI;
  20. use Piwik\Plugins\VisitsSummary\API as VisitsSummaryAPI;
  21. use Piwik\WidgetsList;
  22. /**
  23. * Fixture for UI tests.
  24. */
  25. class UITestFixture extends OmniFixture
  26. {
  27. public function setUp()
  28. {
  29. parent::setUp();
  30. // make sure site has an early enough creation date (for period selector tests)
  31. Db::get()->update(Common::prefixTable("site"),
  32. array('ts_created' => '2011-01-01'),
  33. "idsite = 1"
  34. );
  35. $this->addOverlayVisits();
  36. $this->addNewSitesForSiteSelector();
  37. DbHelper::createAnonymousUser();
  38. UsersManagerAPI::getInstance()->setSuperUserAccess('superUserLogin', true);
  39. Option::set("Tests.forcedNowTimestamp", $this->now->getTimestamp());
  40. // launch archiving so tests don't run out of time
  41. $date = Date::factory($this->dateTime)->toString();
  42. VisitsSummaryAPI::getInstance()->get($this->idSite, 'year', $date);
  43. VisitsSummaryAPI::getInstance()->get($this->idSite, 'year', $date, urlencode($this->segment));
  44. }
  45. public function performSetUp($setupEnvironmentOnly = false)
  46. {
  47. parent::performSetUp($setupEnvironmentOnly);
  48. $this->createSegments();
  49. $this->setupDashboards();
  50. AssetManager::getInstance()->removeMergedAssets();
  51. $visitorIdDeterministic = bin2hex(Db::fetchOne(
  52. "SELECT idvisitor FROM " . Common::prefixTable('log_visit')
  53. . " WHERE idsite = 2 AND location_latitude IS NOT NULL LIMIT 1"));
  54. $this->testEnvironment->forcedIdVisitor = $visitorIdDeterministic;
  55. $this->testEnvironment->overlayUrl = $this->getLocalTestSiteUrl();
  56. $this->createOverlayTestSite();
  57. $forcedNowTimestamp = Option::get("Tests.forcedNowTimestamp");
  58. if ($forcedNowTimestamp == false) {
  59. throw Exception("Incorrect fixture setup, Tests.forcedNowTimestamp option does not exist! Run the setup again.");
  60. }
  61. $this->testEnvironment->forcedNowTimestamp = $forcedNowTimestamp;
  62. $this->testEnvironment->save();
  63. }
  64. private function addOverlayVisits()
  65. {
  66. $baseUrl = $this->getLocalTestSiteUrl();
  67. $visitProfiles = array(
  68. array('', 'page-1.html', 'page-2.html', 'page-3.html', ''),
  69. array('', 'page-3.html', 'page-4.html'),
  70. array('', 'page-4.html'),
  71. array('', 'page-1.html', 'page-3.html', 'page-4.html'),
  72. array('', 'page-4.html', 'page-1.html'),
  73. array('', 'page-1.html', ''),
  74. array('page-4.html', ''),
  75. array('', 'page-2.html', 'page-3.html'),
  76. array('', 'page-1.html', 'page-2.html'),
  77. array('', 'page-6.html', 'page-5.html', 'page-4.html', 'page-3.html', 'page-2.html', 'page-1.html', ''),
  78. array('', 'page-5.html', 'page-3.html', 'page-1.html'),
  79. array('', 'page-1.html', 'page-2.html', 'page-3.html'),
  80. array('', 'page-4.html', 'page-3.html'),
  81. array('', 'page-1.html', ''),
  82. array('page-6.html', 'page-3.html', ''),
  83. );
  84. $date = Date::factory('yesterday');
  85. $t = self::getTracker($idSite = 3, $dateTime = $date->getDatetime(), $defaultInit = true);
  86. $t->enableBulkTracking();
  87. foreach ($visitProfiles as $visitCount => $visit) {
  88. $t->setNewVisitorId();
  89. $t->setIp("123.234.23.$visitCount");
  90. foreach ($visit as $idx => $action) {
  91. $t->setForceVisitDateTime($date->addHour($visitCount)->addHour(0.01 * $idx)->getDatetime());
  92. $url = $baseUrl . $action;
  93. $t->setUrl($url);
  94. if ($idx != 0) {
  95. $referrerUrl = $baseUrl . $visit[$idx - 1];
  96. $t->setUrlReferrer($referrerUrl);
  97. }
  98. self::assertTrue($t->doTrackPageView("page title of $action"));
  99. }
  100. }
  101. self::checkBulkTrackingResponse($t->doBulkTrack());
  102. }
  103. private function createOverlayTestSite()
  104. {
  105. $realDir = PIWIK_INCLUDE_PATH . "/tests/resources/overlay-test-site-real";
  106. if (is_dir($realDir)) {
  107. return;
  108. }
  109. $files = array('index.html', 'page-1.html', 'page-2.html', 'page-3.html', 'page-4.html', 'page-5.html', 'page-6.html');
  110. // copy templates to overlay-test-site-real
  111. mkdir($realDir);
  112. foreach ($files as $file) {
  113. copy(PIWIK_INCLUDE_PATH . "/tests/resources/overlay-test-site/$file",
  114. PIWIK_INCLUDE_PATH . "/tests/resources/overlay-test-site-real/$file");
  115. }
  116. // replace URL in copied files
  117. $url = self::getRootUrl() . 'tests/PHPUnit/proxy/';
  118. $scheme = parse_url($url, PHP_URL_SCHEME);
  119. $url = substr($url, strlen($scheme) + 3);
  120. foreach ($files as $file) {
  121. $path = PIWIK_INCLUDE_PATH . "/tests/resources/overlay-test-site-real/$file";
  122. $contents = file_get_contents($path);
  123. $contents = str_replace("%trackerBaseUrl%", $url, $contents);
  124. file_put_contents($path, $contents);
  125. }
  126. }
  127. private function getLocalTestSiteUrl()
  128. {
  129. return self::getRootUrl() . "tests/resources/overlay-test-site-real/";
  130. }
  131. private function addNewSitesForSiteSelector()
  132. {
  133. for ($i = 0; $i != 8; ++$i) {
  134. self::createWebsite("2011-01-01 00:00:00", $ecommerce = 1, $siteName = "Site #$i", $siteUrl = "http://site$i.com");
  135. }
  136. }
  137. /** Creates two dashboards that split the widgets up into different groups. */
  138. public function setupDashboards()
  139. {
  140. $dashboardColumnCount = 3;
  141. $dashboardCount = 4;
  142. $layout = array();
  143. for ($j = 0; $j != $dashboardColumnCount; ++$j) {
  144. $layout[] = array();
  145. }
  146. $dashboards = array();
  147. for ($i = 0; $i != $dashboardCount; ++$i) {
  148. $dashboards[] = $layout;
  149. }
  150. $oldGet = $_GET;
  151. $_GET['idSite'] = 1;
  152. // collect widgets & sort them so widget order is not important
  153. $allWidgets = array();
  154. foreach (WidgetsList::get() as $category => $widgets) {
  155. $allWidgets = array_merge($allWidgets, $widgets);
  156. }
  157. usort($allWidgets, function ($lhs, $rhs) {
  158. return strcmp($lhs['uniqueId'], $rhs['uniqueId']);
  159. });
  160. $widgetsPerDashboard = ceil(count($allWidgets) / $dashboardCount);
  161. // group widgets so they will be spread out across 3 dashboards
  162. $groupedWidgets = array();
  163. $dashboard = 0;
  164. foreach ($allWidgets as $widget) {
  165. if ($widget['uniqueId'] == 'widgetSEOgetRank'
  166. || $widget['uniqueId'] == 'widgetReferrersgetKeywordsForPage'
  167. || $widget['uniqueId'] == 'widgetLivegetVisitorProfilePopup'
  168. || $widget['uniqueId'] == 'widgetActionsgetPageTitles'
  169. || strpos($widget['uniqueId'], 'widgetExample') === 0
  170. ) {
  171. continue;
  172. }
  173. $widgetEntry = array(
  174. 'uniqueId' => $widget['uniqueId'],
  175. 'parameters' => $widget['parameters']
  176. );
  177. // dashboard images must have height of less than 4000px to avoid odd discoloration of last line of image
  178. $widgetEntry['parameters']['filter_limit'] = 5;
  179. $groupedWidgets[$dashboard][] = $widgetEntry;
  180. if (count($groupedWidgets[$dashboard]) >= $widgetsPerDashboard) {
  181. $dashboard = $dashboard + 1;
  182. }
  183. // sanity check
  184. if ($dashboard >= $dashboardCount) {
  185. throw new Exception("Unexpected error: Incorrect dashboard widget placement logic. Something's wrong w/ the code.");
  186. }
  187. }
  188. // distribute widgets in each dashboard
  189. $column = 0;
  190. foreach ($groupedWidgets as $dashboardIndex => $dashboardWidgets) {
  191. foreach ($dashboardWidgets as $widget) {
  192. $column = ($column + 1) % $dashboardColumnCount;
  193. $dashboards[$dashboardIndex][$column][] = $widget;
  194. }
  195. }
  196. foreach ($dashboards as $id => $layout) {
  197. if ($id == 0) {
  198. $_GET['name'] = self::makeXssContent('dashboard name' . $id);
  199. } else {
  200. $_GET['name'] = 'dashboard name' . $id;
  201. }
  202. $_GET['layout'] = Common::json_encode($layout);
  203. $_GET['idDashboard'] = $id + 1;
  204. FrontController::getInstance()->fetchDispatch('Dashboard', 'saveLayout');
  205. }
  206. // create empty dashboard
  207. $dashboard = array(
  208. array(
  209. array(
  210. 'uniqueId' => "widgetVisitsSummarygetEvolutionGraphcolumnsArray",
  211. 'parameters' => array(
  212. 'module' => 'VisitsSummary',
  213. 'action' => 'getEvolutionGraph',
  214. 'columns' => 'nb_visits'
  215. )
  216. )
  217. ),
  218. array(),
  219. array()
  220. );
  221. $_GET['name'] = 'D4';
  222. $_GET['layout'] = Common::json_encode($dashboard);
  223. $_GET['idDashboard'] = 5;
  224. $_GET['idSite'] = 2;
  225. FrontController::getInstance()->fetchDispatch('Dashboard', 'saveLayout');
  226. $_GET = $oldGet;
  227. }
  228. public function createSegments()
  229. {
  230. Db::exec("TRUNCATE TABLE " . Common::prefixTable('segment'));
  231. $segmentName = self::makeXssContent('segment');
  232. $segmentDefinition = "browserCode==FF";
  233. APISegmentEditor::getInstance()->add(
  234. $segmentName, $segmentDefinition, $idSite = 1, $autoArchive = true, $enabledAllUsers = true);
  235. // create two more segments
  236. APISegmentEditor::getInstance()->add(
  237. "From Europe", "continentCode==eur", $idSite = 1, $autoArchive = false, $enabledAllUsers = true);
  238. APISegmentEditor::getInstance()->add(
  239. "Multiple actions", "actions>=2", $idSite = 1, $autoArchive = false, $enabledAllUsers = true);
  240. }
  241. public static function createAccessInstance()
  242. {
  243. Access::setSingletonInstance($access = new \Test_Access_OverrideLogin());
  244. \Piwik\Piwik::postEvent('Request.initAuthenticationObject');
  245. }
  246. }