Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

declare(strict_types = 1);

namespace Statistics\Calculator;

use SocialPost\Dto\SocialPostTo;
use Statistics\Dto\StatisticsTo;

class AveragePostsPerUserPerMonth extends AbstractCalculator
{
protected const UNITS = 'posts';

/**
* @var array
*/
private $postTotals = [];

/**
* @var array
*/
private $userList = [];

/**
* @inheritDoc
*/
protected function doAccumulate(SocialPostTo $postTo): void
{
$key = $postTo->getDate()->format('M, Y');

$this->postTotals[$key] = ($this->postTotals[$key] ?? 0) + 1;

if (!in_array($postTo->getAuthorId(), $this->userList)) {
$this->userList[] = $postTo->getAuthorId();
}
}

/**
* @inheritDoc
*/
protected function doCalculate(): StatisticsTo
{
$averagePostsPerUserPerMonth = 0;
if (!empty($this->postTotals) && !empty($this->userList)) {
$totalPosts = array_sum($this->postTotals);
$numberOfMonths = count($this->postTotals);
$numberOfAuthors = count($this->userList);
$averagePostsPerUserPerMonth = round($totalPosts / $numberOfAuthors / $numberOfMonths, 1);
}

return (new StatisticsTo())
->setName($this->parameters->getStatName())
->setValue($averagePostsPerUserPerMonth)
->setUnits(self::UNITS);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use Statistics\Calculator\CalculatorComposite;
use Statistics\Calculator\CalculatorInterface;
use Statistics\Calculator\MaxPostLength;
use Statistics\Calculator\NoopCalculator;
use Statistics\Calculator\AveragePostsPerUserPerMonth;
use Statistics\Calculator\TotalPostsPerWeek;
use Statistics\Dto\ParamsTo;
use Statistics\Enum\StatsEnum;
Expand All @@ -24,7 +24,7 @@ class StatisticsCalculatorFactory
StatsEnum::AVERAGE_POST_LENGTH => AveragePostLength::class,
StatsEnum::MAX_POST_LENGTH => MaxPostLength::class,
StatsEnum::TOTAL_POSTS_PER_WEEK => TotalPostsPerWeek::class,
StatsEnum::AVERAGE_POSTS_NUMBER_PER_USER_PER_MONTH => NoopCalculator::class,
StatsEnum::AVERAGE_POSTS_NUMBER_PER_USER_PER_MONTH => AveragePostsPerUserPerMonth::class,
];

/**
Expand Down
27 changes: 0 additions & 27 deletions app/module/Statistics/src/Calculator/NoopCalculator.php

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,30 @@
"message": "computer grandmother level body bed dismissal make viable dirty berry heavy bay lion quest house forget dead galaxy dramatic greeting design exact revoke era pit train thinker grandmother printer still leader act speech invisible achievement benefit shake golf address cause visual spend pavement elephant viable galaxy alcohol allocation birthday recruit freeze heal disaster chief leaflet hostile judgment mine delicate approval confine fuel crop depression syndrome use hostile Europe raid lighter passage press",
"type": "status",
"created_time": "2018-08-10T17:08:53+00:00"
},
{
"id": "post5b6ed7aeeb613_37c3a760",
"from_name": "Lael Vassel",
"from_id": "user_10",
"message": "mother drop falsify describe college area blue jean dressing fuss hell barrier export escape linen museum flat referee instal jurisdiction execute instrument part fuss waist helmet friend rhythm cord extend plagiarize thinker sister dominant basket dignity value dorm fill marsh angel publisher spend album reconcile charter convince bed quest housing failure landowner",
"type": "status",
"created_time": "2018-09-11T02:42:39+00:00"
},
{
"id": "post5b6ed7aeeb6cf_e16f82fb",
"from_name": "Lael Vassel",
"from_id": "user_14",
"message": "proud pool hilarious center bury facade button therapist opposite instal facade velvet full rough cover adoption grimace element fail herb dominant buy fling tie courtship empire chaos highway twist noble flourish clinic representative market magnetic album scheme harsh describe swim racism bother intermediate ankle rough ton discrimination instrument pit ban horror curl house script skin eject presidency nest correspondence viable offense money abbey size",
"type": "status",
"created_time": "2018-09-10T22:36:36+00:00"
},
{
"id": "post5b6ed7aeeb79b_131737df",
"from_name": "Woodrow Lindholm",
"from_id": "user_14",
"message": "computer grandmother level body bed dismissal make viable dirty berry heavy bay lion quest house forget dead galaxy dramatic greeting design exact revoke era pit train thinker grandmother printer still leader act speech invisible achievement benefit shake golf address cause visual spend pavement elephant viable galaxy alcohol allocation birthday recruit freeze heal disaster chief leaflet hostile judgment mine delicate approval confine fuel crop depression syndrome use hostile Europe raid lighter passage press",
"type": "status",
"created_time": "2018-09-10T17:08:53+00:00"
}
]
}
Expand Down
106 changes: 106 additions & 0 deletions app/tests/unit/AveragePostsPerUserPerMonthTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php

declare(strict_types = 1);

namespace Tests\unit;

use Traversable;
use DateTime;
use PHPUnit\Framework\TestCase;
use Statistics\Dto\ParamsTo;
use Statistics\Enum\StatsEnum;
use Statistics\Service\Factory\StatisticsServiceFactory;
use SocialPost\Hydrator\FictionalPostHydrator;

/**
* Class ATestAveragePostsPerUserPerMonth
*
* @package Tests\unit
*/
class AveragePostsPerUserPerMonthTest extends TestCase
{
protected const TEST_FILE = './tests/data/average-posts-per-user-per-month-data.json';

/**
* @test
*/
public function testStatsForOneMonth(): void
{
$posts = $this->getTestPosts();
$params = $this->getParams('2018-08-01 00:00:00', '2018-08-31 23:59:59');

$averagePostsPerUserPerMonth = $this->getAveragePostsPerUserPerMonth($posts, $params);

$this->assertEquals(1, $averagePostsPerUserPerMonth);
}

/**
* @test
*/
public function testStatsForTwoMonths(): void
{
$posts = $this->getTestPosts();
$params = $this->getParams('2018-08-01 00:00:00', '2018-09-30 23:59:59');

$averagePostsPerUserPerMonth = $this->getAveragePostsPerUserPerMonth($posts, $params);

$this->assertEquals(0.7, $averagePostsPerUserPerMonth);
}

/**
* @test
*/
public function testForNoPosts(): void
{
$posts = [];
$params = $this->getParams('2018-08-01 00:00:00', '2018-08-31 23:59:59');

$averagePostsPerUserPerMonth = $this->getAveragePostsPerUserPerMonth($posts, $params);

$this->assertEquals(0, $averagePostsPerUserPerMonth);
}

private function getTestPosts()
{
$postsJson = file_get_contents(self::TEST_FILE);
$responseData = json_decode($postsJson, true);

return $responseData['data']['posts'];
}

private function getAveragePostsPerUserPerMonth($posts, $params)
{
$posts = $this->fetchPosts($posts);
$stats = $this->getStats($params, $posts);

return $stats->getChildren()[0]->getValue();
}

private function getParams($start, $end): array
{
$startDate = DateTime::createFromFormat('Y-m-d H:i:s', $start);
$endDate = DateTime::createFromFormat('Y-m-d H:i:s', $end);

return [
(new ParamsTo())
->setStatName(StatsEnum::AVERAGE_POSTS_NUMBER_PER_USER_PER_MONTH)
->setStartDate($startDate)
->setEndDate($endDate)
];
}

private function getStats($params, $posts)
{
$statsService = StatisticsServiceFactory::create();

return $statsService->calculateStats($posts, $params);
}

private function fetchPosts($posts) : Traversable {
$hydrator = new FictionalPostHydrator();

foreach ($posts as $postData) {
yield $hydrator->hydrate($postData);
}
}
}
23 changes: 0 additions & 23 deletions app/tests/unit/TestTest.php

This file was deleted.