1
0

AnalyticsBotsChartTest.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. <?php
  2. use PHPUnit\Framework\Attributes\DataProvider;
  3. /**
  4. * The Bots and agents chart against bot rows, which are stored per UTC day. A period in a
  5. * timezone east or west of UTC touches one more UTC day than it has local days, and the
  6. * chart must have exactly the UTC days the table reads, today's included.
  7. * Rows are dated 2001, far from real traffic, and deleted afterwards.
  8. */
  9. class AnalyticsBotsChartTest extends BxDolIntegrationTestCase
  10. {
  11. // 2001-09-09 05:30 UTC: 15:30 in Sydney (UTC+10), 22:30 on 2001-09-08 in Los Angeles (UTC-7)
  12. const NOW_SEPTEMBER = 1000013400;
  13. // 2001-10-30 05:30 UTC: 16:30 in Sydney (UTC+11 since 2001-10-28), 21:30 on 2001-10-29
  14. // in Los Angeles (UTC-8 since 2001-10-28); the week before crosses both changes
  15. const NOW_OCTOBER = 1004419800;
  16. // hits on the UTC day of "now", told apart from the 1 hit of every other day
  17. const TODAY_HITS = 7;
  18. protected $_oModule;
  19. protected function setUp(): void
  20. {
  21. parent::setUp();
  22. if (!BxDolModuleQuery::getInstance()->isEnabledByName('bx_analytics'))
  23. $this->markTestSkipped('bx_analytics is not installed');
  24. $this->_oModule = BxDolModule::getInstance('bx_analytics');
  25. $this->_oModule->getFilter([]); // loads the filter class
  26. $this->_cleanup();
  27. }
  28. protected function tearDown(): void
  29. {
  30. if ($this->_oModule)
  31. $this->_cleanup();
  32. parent::tearDown();
  33. }
  34. public static function periods()
  35. {
  36. return [
  37. 'UTC, a week' => ['UTC', self::NOW_SEPTEMBER, '7d', '2001-09-03', '2001-09-09', 7],
  38. 'Sydney +10, a week' => ['Australia/Sydney', self::NOW_SEPTEMBER, '7d', '2001-09-02', '2001-09-09', 8],
  39. 'Sydney +10, today' => ['Australia/Sydney', self::NOW_SEPTEMBER, 'today', '2001-09-08', '2001-09-09', 2],
  40. 'Sydney +10 to +11, a week' => ['Australia/Sydney', self::NOW_OCTOBER, '7d', '2001-10-23', '2001-10-30', 8],
  41. 'Los Angeles -7, a week' => ['America/Los_Angeles', self::NOW_SEPTEMBER, '7d', '2001-09-02', '2001-09-09', 8],
  42. 'Los Angeles -7, today' => ['America/Los_Angeles', self::NOW_SEPTEMBER, 'today', '2001-09-08', '2001-09-09', 2],
  43. 'Los Angeles -7 to -8, a week' => ['America/Los_Angeles', self::NOW_OCTOBER, '7d', '2001-10-23', '2001-10-30', 8],
  44. ];
  45. }
  46. #[DataProvider('periods')]
  47. public function testChartHasTheUtcDaysOfThePeriod($sTz, $iNow, $sRange, $sFirst, $sLast, $iDays)
  48. {
  49. $this->_addHits($iNow);
  50. $oFilter = new BxAnalyticsFilter($this->_oModule, ['range' => $sRange, 'tz' => $sTz], $iNow);
  51. $aReport = $this->_oModule->getReports()->getBots($oFilter, []);
  52. $aChart = $aReport['chart'];
  53. $aLabels = array_map(function ($i) { return gmdate('Y-m-d H:i:s', $i); }, $aChart['labels']);
  54. $this->assertSame('UTC', $aChart['tz'], 'labels are UTC days, as the rows are');
  55. $this->assertCount($iDays, $aLabels);
  56. $this->assertSame($sFirst . ' 00:00:00', $aLabels[0]);
  57. $this->assertSame($sLast . ' 00:00:00', end($aLabels));
  58. $this->assertSame(array_values(array_unique($aLabels)), $aLabels, 'one bar per day');
  59. $this->assertCount(1, $aChart['datasets']);
  60. $aValues = $aChart['datasets'][0]['values'];
  61. $this->assertCount($iDays, $aValues);
  62. $this->assertSame(self::TODAY_HITS, end($aValues), "today's hits are the last bar");
  63. // the chart and the table read the same days
  64. $iTotal = (int)$this->_oModule->_oDb->getBotTotals($oFilter->get())['hits'];
  65. $this->assertSame($iTotal, array_sum($aValues));
  66. $this->assertSame($iTotal, array_sum(array_column(array_column($aReport['bots']['rows'], 'values'), 'hits')));
  67. $this->assertSame($iDays - 1 + self::TODAY_HITS, $iTotal, 'a hit on every other day of the chart, none outside it');
  68. }
  69. /**
  70. * A hit on each UTC day from 10 days before "now" to 2 days after, and more on the day of "now".
  71. */
  72. protected function _addHits($iNow)
  73. {
  74. $oDb = $this->_oModule->_oDb;
  75. $sToday = gmdate('Y-m-d', $iNow);
  76. for ($i = -10; $i <= 2; $i++) {
  77. $sDay = gmdate('Y-m-d', $iNow + $i * 86400);
  78. for ($j = $sDay == $sToday ? self::TODAY_HITS : 1; $j > 0; $j--)
  79. $this->assertTrue($oDb->addBotHit($sDay, 'Googlebot', 'search', 'core-web', '/', $iNow + $i * 86400));
  80. }
  81. }
  82. protected function _cleanup()
  83. {
  84. $oDb = BxDolDb::getInstance();
  85. $oDb->query("DELETE FROM `bx_analytics_bots` WHERE `day` < '2002-01-01'");
  86. $oDb->query("DELETE FROM `bx_analytics_bot_pages` WHERE `day` < '2002-01-01'");
  87. }
  88. }