From f329263ee2ca99cbd9efa5089c2576e758a51b40 Mon Sep 17 00:00:00 2001 From: Aleksandra Kukla Date: Thu, 2 Feb 2023 23:34:22 +0100 Subject: [PATCH 01/15] Implement doAccumulate function for NoopCalculator --- .../src/Calculator/NoopCalculator.php | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/app/module/Statistics/src/Calculator/NoopCalculator.php b/app/module/Statistics/src/Calculator/NoopCalculator.php index 6790ef3..0b37b5c 100644 --- a/app/module/Statistics/src/Calculator/NoopCalculator.php +++ b/app/module/Statistics/src/Calculator/NoopCalculator.php @@ -9,12 +9,34 @@ class NoopCalculator extends AbstractCalculator { + + protected const UNITS = 'posts per user'; + + /** + * @var array + */ + private $postTotals = []; + + /** + * @var array + */ + private $userList = []; + /** * @inheritDoc */ protected function doAccumulate(SocialPostTo $postTo): void { - // Noops! + $key = $postTo->getDate()->format('M, Y'); + + $this->postTotals[$key] = ($this->postTotals[$key] ?? 0) + 1; + + if (!isset($this->userList[$key])){ + $this->userList[$key] = []; + } + if (!in_array($postTo->getAuthorId(), $this->userList[$key])){ + $this->userList[$key][] = $postTo->getAuthorId(); + } } /** From 8ac4add21446613df2182ca1350595661d801ae5 Mon Sep 17 00:00:00 2001 From: Aleksandra Kukla Date: Thu, 2 Feb 2023 23:49:10 +0100 Subject: [PATCH 02/15] Implement doCalculate function in NoopController --- .../src/Calculator/NoopCalculator.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/app/module/Statistics/src/Calculator/NoopCalculator.php b/app/module/Statistics/src/Calculator/NoopCalculator.php index 0b37b5c..0e1f799 100644 --- a/app/module/Statistics/src/Calculator/NoopCalculator.php +++ b/app/module/Statistics/src/Calculator/NoopCalculator.php @@ -44,6 +44,23 @@ protected function doAccumulate(SocialPostTo $postTo): void */ protected function doCalculate(): StatisticsTo { - return new StatisticsTo(); + $averages = []; + foreach ($this->postTotals as $key => $postTotal) { + $authorCount = count($this->userList[$key]); + $averages[$key] = round($postTotal / $authorCount, 1); + } + + $stats = new StatisticsTo(); + foreach ($$averages as $splitPeriod => $average) { + $child = (new StatisticsTo()) + ->setName($this->parameters->getStatName()) + ->setSplitPeriod($splitPeriod) + ->setValue($average) + ->setUnits(self::UNITS); + + $stats->addChild($child); + } + + return $stats; } } From 21f1f7f7dd6b05711d24a6bd9d5d9e9975f484d3 Mon Sep 17 00:00:00 2001 From: Aleksandra Kukla Date: Fri, 3 Feb 2023 00:11:52 +0100 Subject: [PATCH 03/15] Refactoring --- app/module/Statistics/src/Calculator/NoopCalculator.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/module/Statistics/src/Calculator/NoopCalculator.php b/app/module/Statistics/src/Calculator/NoopCalculator.php index 0e1f799..75d2267 100644 --- a/app/module/Statistics/src/Calculator/NoopCalculator.php +++ b/app/module/Statistics/src/Calculator/NoopCalculator.php @@ -31,10 +31,8 @@ protected function doAccumulate(SocialPostTo $postTo): void $this->postTotals[$key] = ($this->postTotals[$key] ?? 0) + 1; - if (!isset($this->userList[$key])){ - $this->userList[$key] = []; - } - if (!in_array($postTo->getAuthorId(), $this->userList[$key])){ + $this->userList[$key] = $this->userList[$key] ?? []; + if (!in_array($postTo->getAuthorId(), $this->userList[$key])) { $this->userList[$key][] = $postTo->getAuthorId(); } } From 8bf54b838cf32564d447d8118877cf9872c93618 Mon Sep 17 00:00:00 2001 From: Aleksandra Kukla Date: Fri, 3 Feb 2023 00:12:28 +0100 Subject: [PATCH 04/15] Fix misspelling --- app/module/Statistics/src/Calculator/NoopCalculator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/module/Statistics/src/Calculator/NoopCalculator.php b/app/module/Statistics/src/Calculator/NoopCalculator.php index 75d2267..be0e881 100644 --- a/app/module/Statistics/src/Calculator/NoopCalculator.php +++ b/app/module/Statistics/src/Calculator/NoopCalculator.php @@ -49,7 +49,7 @@ protected function doCalculate(): StatisticsTo } $stats = new StatisticsTo(); - foreach ($$averages as $splitPeriod => $average) { + foreach ($averages as $splitPeriod => $average) { $child = (new StatisticsTo()) ->setName($this->parameters->getStatName()) ->setSplitPeriod($splitPeriod) From 22177d6115591a7e9d5cdd63bc6f03b7165c4674 Mon Sep 17 00:00:00 2001 From: Aleksandra Kukla Date: Sat, 4 Feb 2023 12:40:02 +0100 Subject: [PATCH 05/15] Add average posts per user per month test --- app/tests/unit/TestTest.php | 39 +++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/app/tests/unit/TestTest.php b/app/tests/unit/TestTest.php index 1ebb8a6..4b8134a 100644 --- a/app/tests/unit/TestTest.php +++ b/app/tests/unit/TestTest.php @@ -4,8 +4,13 @@ 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 ATestTest * @@ -18,6 +23,36 @@ class TestTest extends TestCase */ public function testNothing(): void { - $this->assertTrue(true); + $startDate = DateTime::createFromFormat('Y-m-d H:i:s', '2018-08-01 00:00:00'); + $endDate = DateTime::createFromFormat('Y-m-d H:i:s', '2018-08-31 23:59:59'); + $params = [ + (new ParamsTo()) + ->setStatName(StatsEnum::AVERAGE_POSTS_NUMBER_PER_USER_PER_MONTH) + ->setStartDate($startDate) + ->setEndDate($endDate) + ]; + + $posts = $this->fetchPosts(); + $statsService = StatisticsServiceFactory::create(); + $stats = $statsService->calculateStats($posts, $params); + + $noopStats = $stats->getChildren(); + $allMonthsStats = $noopStats[0]->getChildren(); + $monthStats = $allMonthsStats[0]; + $averagePostsPerUserPerMonth = $monthStats->getValue(); + + $this->assertEquals(1, $averagePostsPerUserPerMonth); + } + + private function fetchPosts() : Traversable { + $hydrator = new FictionalPostHydrator(); + + $postsJson = file_get_contents('./tests/data/social-posts-response.json'); + $responseData = json_decode($postsJson, true); + $posts = $responseData['data']['posts']; + + foreach ($posts as $postData) { + yield $hydrator->hydrate($postData); + } } } From c0359c16b13b8be2d95c950361afa58f07227ea8 Mon Sep 17 00:00:00 2001 From: Aleksandra Kukla Date: Sat, 4 Feb 2023 12:43:21 +0100 Subject: [PATCH 06/15] Refactor: Give proper name to NoopCalculator. Rename it to AveragePostsPerUserPerMonth --- .../{NoopCalculator.php => AveragePostsPerUserPerMonth.php} | 2 +- .../src/Calculator/Factory/StatisticsCalculatorFactory.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename app/module/Statistics/src/Calculator/{NoopCalculator.php => AveragePostsPerUserPerMonth.php} (96%) diff --git a/app/module/Statistics/src/Calculator/NoopCalculator.php b/app/module/Statistics/src/Calculator/AveragePostsPerUserPerMonth.php similarity index 96% rename from app/module/Statistics/src/Calculator/NoopCalculator.php rename to app/module/Statistics/src/Calculator/AveragePostsPerUserPerMonth.php index be0e881..e023e49 100644 --- a/app/module/Statistics/src/Calculator/NoopCalculator.php +++ b/app/module/Statistics/src/Calculator/AveragePostsPerUserPerMonth.php @@ -7,7 +7,7 @@ use SocialPost\Dto\SocialPostTo; use Statistics\Dto\StatisticsTo; -class NoopCalculator extends AbstractCalculator +class AveragePostsPerUserPerMonth extends AbstractCalculator { protected const UNITS = 'posts per user'; diff --git a/app/module/Statistics/src/Calculator/Factory/StatisticsCalculatorFactory.php b/app/module/Statistics/src/Calculator/Factory/StatisticsCalculatorFactory.php index 096c4ce..e58ed07 100644 --- a/app/module/Statistics/src/Calculator/Factory/StatisticsCalculatorFactory.php +++ b/app/module/Statistics/src/Calculator/Factory/StatisticsCalculatorFactory.php @@ -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; @@ -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, ]; /** From e548e01b0dde50a06ddf33b166529584eadc51bc Mon Sep 17 00:00:00 2001 From: Aleksandra Kukla Date: Sat, 4 Feb 2023 12:50:48 +0100 Subject: [PATCH 07/15] Refactor: Give proper name to TestTest. Rename it to AveragePostsPerUserPerMonthTest --- .../{TestTest.php => AveragePostsPerUserPerMonthTest.php} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename app/tests/unit/{TestTest.php => AveragePostsPerUserPerMonthTest.php} (91%) diff --git a/app/tests/unit/TestTest.php b/app/tests/unit/AveragePostsPerUserPerMonthTest.php similarity index 91% rename from app/tests/unit/TestTest.php rename to app/tests/unit/AveragePostsPerUserPerMonthTest.php index 4b8134a..b6e9faa 100644 --- a/app/tests/unit/TestTest.php +++ b/app/tests/unit/AveragePostsPerUserPerMonthTest.php @@ -12,16 +12,16 @@ use Statistics\Service\Factory\StatisticsServiceFactory; use SocialPost\Hydrator\FictionalPostHydrator; /** - * Class ATestTest + * Class ATestAveragePostsPerUserPerMonth * * @package Tests\unit */ -class TestTest extends TestCase +class AveragePostsPerUserPerMonthTest extends TestCase { /** * @test */ - public function testNothing(): void + public function testStatsForOneMonth(): void { $startDate = DateTime::createFromFormat('Y-m-d H:i:s', '2018-08-01 00:00:00'); $endDate = DateTime::createFromFormat('Y-m-d H:i:s', '2018-08-31 23:59:59'); From 7ac21c670e9fa9dfa0cb6678880a288363db7b81 Mon Sep 17 00:00:00 2001 From: Aleksandra Kukla Date: Sat, 4 Feb 2023 13:08:09 +0100 Subject: [PATCH 08/15] Refactor: extract setUpBeforeClass method, give proper names to variables --- .../unit/AveragePostsPerUserPerMonthTest.php | 48 +++++++++++++------ 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/app/tests/unit/AveragePostsPerUserPerMonthTest.php b/app/tests/unit/AveragePostsPerUserPerMonthTest.php index b6e9faa..9392724 100644 --- a/app/tests/unit/AveragePostsPerUserPerMonthTest.php +++ b/app/tests/unit/AveragePostsPerUserPerMonthTest.php @@ -11,6 +11,7 @@ use Statistics\Enum\StatsEnum; use Statistics\Service\Factory\StatisticsServiceFactory; use SocialPost\Hydrator\FictionalPostHydrator; + /** * Class ATestAveragePostsPerUserPerMonth * @@ -18,38 +19,57 @@ */ class AveragePostsPerUserPerMonthTest extends TestCase { - /** - * @test - */ - public function testStatsForOneMonth(): void + private $params; + + protected function setUpBeforeClass(): void { $startDate = DateTime::createFromFormat('Y-m-d H:i:s', '2018-08-01 00:00:00'); $endDate = DateTime::createFromFormat('Y-m-d H:i:s', '2018-08-31 23:59:59'); - $params = [ + $this->params = [ (new ParamsTo()) ->setStatName(StatsEnum::AVERAGE_POSTS_NUMBER_PER_USER_PER_MONTH) ->setStartDate($startDate) ->setEndDate($endDate) ]; + } - $posts = $this->fetchPosts(); + /** + * @test + */ + public function testStatsForOneMonth(): void + { + $postsJson = file_get_contents('./tests/data/social-posts-response.json'); + $responseData = json_decode($postsJson, true); + + $posts = $this->fetchPosts($responseData['data']['posts']); $statsService = StatisticsServiceFactory::create(); - $stats = $statsService->calculateStats($posts, $params); + $stats = $statsService->calculateStats($posts, $this->params); - $noopStats = $stats->getChildren(); - $allMonthsStats = $noopStats[0]->getChildren(); + $averageStats = $stats->getChildren(); + $allMonthsStats = $averageStats[0]->getChildren(); $monthStats = $allMonthsStats[0]; $averagePostsPerUserPerMonth = $monthStats->getValue(); $this->assertEquals(1, $averagePostsPerUserPerMonth); } - private function fetchPosts() : Traversable { - $hydrator = new FictionalPostHydrator(); + /** + * @test + */ + public function testForNoPosts(): void + { + $posts = $this->fetchPosts([]); + $statsService = StatisticsServiceFactory::create(); + $stats = $statsService->calculateStats($posts, $this->params); - $postsJson = file_get_contents('./tests/data/social-posts-response.json'); - $responseData = json_decode($postsJson, true); - $posts = $responseData['data']['posts']; + $averageStats = $stats->getChildren(); + $allMonthsStats = $averageStats[0]->getChildren(); + + $this->assertEmpty($allMonthsStats); + } + + private function fetchPosts($posts) : Traversable { + $hydrator = new FictionalPostHydrator(); foreach ($posts as $postData) { yield $hydrator->hydrate($postData); From e5bfd3c784092b8850ef517eaa473176a0aa41d2 Mon Sep 17 00:00:00 2001 From: Aleksandra Kukla Date: Sat, 4 Feb 2023 13:19:45 +0100 Subject: [PATCH 09/15] Refactor: rename social-post-response.json to match test name --- ...sponse.json => average-posts-per-user-per-month-data.json} | 0 app/tests/unit/AveragePostsPerUserPerMonthTest.php | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename app/tests/data/{social-posts-response.json => average-posts-per-user-per-month-data.json} (100%) diff --git a/app/tests/data/social-posts-response.json b/app/tests/data/average-posts-per-user-per-month-data.json similarity index 100% rename from app/tests/data/social-posts-response.json rename to app/tests/data/average-posts-per-user-per-month-data.json diff --git a/app/tests/unit/AveragePostsPerUserPerMonthTest.php b/app/tests/unit/AveragePostsPerUserPerMonthTest.php index 9392724..d0394b6 100644 --- a/app/tests/unit/AveragePostsPerUserPerMonthTest.php +++ b/app/tests/unit/AveragePostsPerUserPerMonthTest.php @@ -21,7 +21,7 @@ class AveragePostsPerUserPerMonthTest extends TestCase { private $params; - protected function setUpBeforeClass(): void + protected function setUp(): void { $startDate = DateTime::createFromFormat('Y-m-d H:i:s', '2018-08-01 00:00:00'); $endDate = DateTime::createFromFormat('Y-m-d H:i:s', '2018-08-31 23:59:59'); @@ -38,7 +38,7 @@ protected function setUpBeforeClass(): void */ public function testStatsForOneMonth(): void { - $postsJson = file_get_contents('./tests/data/social-posts-response.json'); + $postsJson = file_get_contents('./tests/data/average-posts-per-user-per-month-data.json'); $responseData = json_decode($postsJson, true); $posts = $this->fetchPosts($responseData['data']['posts']); From 6edf5aa6473e07b9f9812c366c1012f0fc5b67ad Mon Sep 17 00:00:00 2001 From: Aleksandra Kukla Date: Sat, 4 Feb 2023 13:55:57 +0100 Subject: [PATCH 10/15] Add test round stat number --- ...average-posts-per-user-per-month-data.json | 24 +++++++++++ .../unit/AveragePostsPerUserPerMonthTest.php | 42 +++++++++++++++---- 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/app/tests/data/average-posts-per-user-per-month-data.json b/app/tests/data/average-posts-per-user-per-month-data.json index 9d3e90f..9b58b39 100644 --- a/app/tests/data/average-posts-per-user-per-month-data.json +++ b/app/tests/data/average-posts-per-user-per-month-data.json @@ -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" } ] } diff --git a/app/tests/unit/AveragePostsPerUserPerMonthTest.php b/app/tests/unit/AveragePostsPerUserPerMonthTest.php index d0394b6..2297348 100644 --- a/app/tests/unit/AveragePostsPerUserPerMonthTest.php +++ b/app/tests/unit/AveragePostsPerUserPerMonthTest.php @@ -19,19 +19,24 @@ */ class AveragePostsPerUserPerMonthTest extends TestCase { - private $params; - protected function setUp(): void + private function getParams($start, $end): array { - $startDate = DateTime::createFromFormat('Y-m-d H:i:s', '2018-08-01 00:00:00'); - $endDate = DateTime::createFromFormat('Y-m-d H:i:s', '2018-08-31 23:59:59'); - $this->params = [ + $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); + } /** * @test @@ -41,9 +46,9 @@ public function testStatsForOneMonth(): void $postsJson = file_get_contents('./tests/data/average-posts-per-user-per-month-data.json'); $responseData = json_decode($postsJson, true); + $params = $this->getParams('2018-08-01 00:00:00', '2018-08-31 23:59:59'); $posts = $this->fetchPosts($responseData['data']['posts']); - $statsService = StatisticsServiceFactory::create(); - $stats = $statsService->calculateStats($posts, $this->params); + $stats = $this->getStats($params, $posts); $averageStats = $stats->getChildren(); $allMonthsStats = $averageStats[0]->getChildren(); @@ -53,14 +58,33 @@ public function testStatsForOneMonth(): void $this->assertEquals(1, $averagePostsPerUserPerMonth); } + /** + * @test + */ + public function testRoundingStatNumber(): void + { + $postsJson = file_get_contents('./tests/data/average-posts-per-user-per-month-data.json'); + $responseData = json_decode($postsJson, true); + + $params = $this->getParams('2018-09-01 00:00:00', '2018-09-30 23:59:59'); + $posts = $this->fetchPosts($responseData['data']['posts']); + $stats = $this->getStats($params, $posts); + + $averageStats = $stats->getChildren(); + $allMonthsStats = $averageStats[0]->getChildren(); + $monthStats = $allMonthsStats[0]; + $averagePostsPerUserPerMonth = $monthStats->getValue(); + $this->assertEquals(1.5, $averagePostsPerUserPerMonth); + } + /** * @test */ public function testForNoPosts(): void { + $params = $this->getParams('2018-08-01 00:00:00', '2018-08-31 23:59:59'); $posts = $this->fetchPosts([]); - $statsService = StatisticsServiceFactory::create(); - $stats = $statsService->calculateStats($posts, $this->params); + $stats = $this->getStats($params, $posts); $averageStats = $stats->getChildren(); $allMonthsStats = $averageStats[0]->getChildren(); From 291245ac50f47fb15093804623390c706ebef042 Mon Sep 17 00:00:00 2001 From: Aleksandra Kukla Date: Sun, 5 Feb 2023 23:04:04 +0100 Subject: [PATCH 11/15] AveragePostsPerUserPerMonth calculator returns one value instead of splited per month --- .../AveragePostsPerUserPerMonth.php | 30 +++++++------------ 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/app/module/Statistics/src/Calculator/AveragePostsPerUserPerMonth.php b/app/module/Statistics/src/Calculator/AveragePostsPerUserPerMonth.php index e023e49..9309cc5 100644 --- a/app/module/Statistics/src/Calculator/AveragePostsPerUserPerMonth.php +++ b/app/module/Statistics/src/Calculator/AveragePostsPerUserPerMonth.php @@ -9,8 +9,7 @@ class AveragePostsPerUserPerMonth extends AbstractCalculator { - - protected const UNITS = 'posts per user'; + protected const UNITS = 'posts'; /** * @var array @@ -31,9 +30,8 @@ protected function doAccumulate(SocialPostTo $postTo): void $this->postTotals[$key] = ($this->postTotals[$key] ?? 0) + 1; - $this->userList[$key] = $this->userList[$key] ?? []; - if (!in_array($postTo->getAuthorId(), $this->userList[$key])) { - $this->userList[$key][] = $postTo->getAuthorId(); + if (!in_array($postTo->getAuthorId(), $this->userList)) { + $this->userList[] = $postTo->getAuthorId(); } } @@ -42,23 +40,17 @@ protected function doAccumulate(SocialPostTo $postTo): void */ protected function doCalculate(): StatisticsTo { - $averages = []; - foreach ($this->postTotals as $key => $postTotal) { - $authorCount = count($this->userList[$key]); - $averages[$key] = round($postTotal / $authorCount, 1); + $averagePostsPerUserPerMonth = 0; + $totalPosts = array_sum($this->postTotals); + if ($totalPosts > 0) { + $numberOfMonths = count($this->postTotals); + $numberOfAuthors = count($this->userList); + $averagePostsPerUserPerMonth = round($totalPosts / $numberOfAuthors / $numberOfMonths, 1); } - $stats = new StatisticsTo(); - foreach ($averages as $splitPeriod => $average) { - $child = (new StatisticsTo()) + return (new StatisticsTo()) ->setName($this->parameters->getStatName()) - ->setSplitPeriod($splitPeriod) - ->setValue($average) + ->setValue($averagePostsPerUserPerMonth) ->setUnits(self::UNITS); - - $stats->addChild($child); - } - - return $stats; } } From e0b843e9f3ff38bcfdc08674effa67b78d65e916 Mon Sep 17 00:00:00 2001 From: Aleksandra Kukla Date: Sun, 5 Feb 2023 23:05:41 +0100 Subject: [PATCH 12/15] Update tests --- .../unit/AveragePostsPerUserPerMonthTest.php | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/app/tests/unit/AveragePostsPerUserPerMonthTest.php b/app/tests/unit/AveragePostsPerUserPerMonthTest.php index 2297348..0779254 100644 --- a/app/tests/unit/AveragePostsPerUserPerMonthTest.php +++ b/app/tests/unit/AveragePostsPerUserPerMonthTest.php @@ -50,10 +50,7 @@ public function testStatsForOneMonth(): void $posts = $this->fetchPosts($responseData['data']['posts']); $stats = $this->getStats($params, $posts); - $averageStats = $stats->getChildren(); - $allMonthsStats = $averageStats[0]->getChildren(); - $monthStats = $allMonthsStats[0]; - $averagePostsPerUserPerMonth = $monthStats->getValue(); + $averagePostsPerUserPerMonth = $stats->getChildren()[0]->getValue(); $this->assertEquals(1, $averagePostsPerUserPerMonth); } @@ -61,20 +58,18 @@ public function testStatsForOneMonth(): void /** * @test */ - public function testRoundingStatNumber(): void + public function testStatsForTwoMonths(): void { $postsJson = file_get_contents('./tests/data/average-posts-per-user-per-month-data.json'); $responseData = json_decode($postsJson, true); - $params = $this->getParams('2018-09-01 00:00:00', '2018-09-30 23:59:59'); + $params = $this->getParams('2018-08-01 00:00:00', '2018-09-30 23:59:59'); $posts = $this->fetchPosts($responseData['data']['posts']); $stats = $this->getStats($params, $posts); - $averageStats = $stats->getChildren(); - $allMonthsStats = $averageStats[0]->getChildren(); - $monthStats = $allMonthsStats[0]; - $averagePostsPerUserPerMonth = $monthStats->getValue(); - $this->assertEquals(1.5, $averagePostsPerUserPerMonth); + $averagePostsPerUserPerMonth = $stats->getChildren()[0]->getValue(); + + $this->assertEquals(0.7, $averagePostsPerUserPerMonth); } /** @@ -86,10 +81,9 @@ public function testForNoPosts(): void $posts = $this->fetchPosts([]); $stats = $this->getStats($params, $posts); - $averageStats = $stats->getChildren(); - $allMonthsStats = $averageStats[0]->getChildren(); + $averagePostsPerUserPerMonth = $stats->getChildren()[0]->getValue(); - $this->assertEmpty($allMonthsStats); + $this->assertEquals(0, $averagePostsPerUserPerMonth); } private function fetchPosts($posts) : Traversable { From 7c32a8defd35fa25b610f52e039bb7c9f07fdf72 Mon Sep 17 00:00:00 2001 From: Aleksandra Kukla Date: Sun, 5 Feb 2023 23:10:25 +0100 Subject: [PATCH 13/15] Refactor tests --- .../unit/AveragePostsPerUserPerMonthTest.php | 57 ++++++++++--------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/app/tests/unit/AveragePostsPerUserPerMonthTest.php b/app/tests/unit/AveragePostsPerUserPerMonthTest.php index 0779254..60a6a1d 100644 --- a/app/tests/unit/AveragePostsPerUserPerMonthTest.php +++ b/app/tests/unit/AveragePostsPerUserPerMonthTest.php @@ -20,24 +20,6 @@ class AveragePostsPerUserPerMonthTest extends TestCase { - 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); - } - /** * @test */ @@ -47,10 +29,9 @@ public function testStatsForOneMonth(): void $responseData = json_decode($postsJson, true); $params = $this->getParams('2018-08-01 00:00:00', '2018-08-31 23:59:59'); - $posts = $this->fetchPosts($responseData['data']['posts']); - $stats = $this->getStats($params, $posts); + + $averagePostsPerUserPerMonth = $this->getAveragePostsPerUserPerMonth($responseData['data']['posts'], $params); - $averagePostsPerUserPerMonth = $stats->getChildren()[0]->getValue(); $this->assertEquals(1, $averagePostsPerUserPerMonth); } @@ -64,10 +45,8 @@ public function testStatsForTwoMonths(): void $responseData = json_decode($postsJson, true); $params = $this->getParams('2018-08-01 00:00:00', '2018-09-30 23:59:59'); - $posts = $this->fetchPosts($responseData['data']['posts']); - $stats = $this->getStats($params, $posts); - $averagePostsPerUserPerMonth = $stats->getChildren()[0]->getValue(); + $averagePostsPerUserPerMonth = $this->getAveragePostsPerUserPerMonth($responseData['data']['posts'], $params); $this->assertEquals(0.7, $averagePostsPerUserPerMonth); } @@ -78,12 +57,36 @@ public function testStatsForTwoMonths(): void public function testForNoPosts(): void { $params = $this->getParams('2018-08-01 00:00:00', '2018-08-31 23:59:59'); - $posts = $this->fetchPosts([]); + + $averagePostsPerUserPerMonth = $this->getAveragePostsPerUserPerMonth([], $params); + + $this->assertEquals(0, $averagePostsPerUserPerMonth); + } + + private function getAveragePostsPerUserPerMonth($posts, $params) + { + $posts = $this->fetchPosts($posts); $stats = $this->getStats($params, $posts); - $averagePostsPerUserPerMonth = $stats->getChildren()[0]->getValue(); + return $stats->getChildren()[0]->getValue(); + } - $this->assertEquals(0, $averagePostsPerUserPerMonth); + 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 { From 5c40cfc2ba979934ec7f14fe8d3955b5e07af869 Mon Sep 17 00:00:00 2001 From: Aleksandra Kukla Date: Sun, 5 Feb 2023 23:14:59 +0100 Subject: [PATCH 14/15] Refactor tests --- .../unit/AveragePostsPerUserPerMonthTest.php | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/app/tests/unit/AveragePostsPerUserPerMonthTest.php b/app/tests/unit/AveragePostsPerUserPerMonthTest.php index 60a6a1d..071759a 100644 --- a/app/tests/unit/AveragePostsPerUserPerMonthTest.php +++ b/app/tests/unit/AveragePostsPerUserPerMonthTest.php @@ -19,19 +19,17 @@ */ class AveragePostsPerUserPerMonthTest extends TestCase { + protected const TEST_FILE = './tests/data/average-posts-per-user-per-month-data.json'; /** * @test */ public function testStatsForOneMonth(): void { - $postsJson = file_get_contents('./tests/data/average-posts-per-user-per-month-data.json'); - $responseData = json_decode($postsJson, true); - + $posts = $this->getTestPosts(); $params = $this->getParams('2018-08-01 00:00:00', '2018-08-31 23:59:59'); - $averagePostsPerUserPerMonth = $this->getAveragePostsPerUserPerMonth($responseData['data']['posts'], $params); - + $averagePostsPerUserPerMonth = $this->getAveragePostsPerUserPerMonth($posts, $params); $this->assertEquals(1, $averagePostsPerUserPerMonth); } @@ -41,12 +39,10 @@ public function testStatsForOneMonth(): void */ public function testStatsForTwoMonths(): void { - $postsJson = file_get_contents('./tests/data/average-posts-per-user-per-month-data.json'); - $responseData = json_decode($postsJson, true); - + $posts = $this->getTestPosts(); $params = $this->getParams('2018-08-01 00:00:00', '2018-09-30 23:59:59'); - $averagePostsPerUserPerMonth = $this->getAveragePostsPerUserPerMonth($responseData['data']['posts'], $params); + $averagePostsPerUserPerMonth = $this->getAveragePostsPerUserPerMonth($posts, $params); $this->assertEquals(0.7, $averagePostsPerUserPerMonth); } @@ -56,13 +52,22 @@ public function testStatsForTwoMonths(): void */ public function testForNoPosts(): void { + $posts = []; $params = $this->getParams('2018-08-01 00:00:00', '2018-08-31 23:59:59'); - $averagePostsPerUserPerMonth = $this->getAveragePostsPerUserPerMonth([], $params); + $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); @@ -75,6 +80,7 @@ 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) @@ -86,6 +92,7 @@ private function getParams($start, $end): array private function getStats($params, $posts) { $statsService = StatisticsServiceFactory::create(); + return $statsService->calculateStats($posts, $params); } From f4dbed7538b101acb07805ec72a769fa73b695d5 Mon Sep 17 00:00:00 2001 From: Aleksandra Kukla Date: Sun, 5 Feb 2023 23:48:11 +0100 Subject: [PATCH 15/15] Refactor AveragePostsPerUserPerMonth --- .../Statistics/src/Calculator/AveragePostsPerUserPerMonth.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/module/Statistics/src/Calculator/AveragePostsPerUserPerMonth.php b/app/module/Statistics/src/Calculator/AveragePostsPerUserPerMonth.php index 9309cc5..d90663c 100644 --- a/app/module/Statistics/src/Calculator/AveragePostsPerUserPerMonth.php +++ b/app/module/Statistics/src/Calculator/AveragePostsPerUserPerMonth.php @@ -41,8 +41,8 @@ protected function doAccumulate(SocialPostTo $postTo): void protected function doCalculate(): StatisticsTo { $averagePostsPerUserPerMonth = 0; - $totalPosts = array_sum($this->postTotals); - if ($totalPosts > 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);