Skip to content
This repository was archived by the owner on Oct 21, 2020. It is now read-only.

Commit 4802e1c

Browse files
author
Alex Agile
committed
Add BurndownWidget doamin layer
1 parent c7a177e commit 4802e1c

File tree

6 files changed

+321
-1
lines changed

6 files changed

+321
-1
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Werkspot\JiraDashboard\BurndownWidget\Domain;
5+
6+
use Symfony\Component\HttpFoundation\Response;
7+
use Werkspot\JiraDashboard\SharedKernel\Domain\Exception\EntityNotFoundException;
8+
use Werkspot\JiraDashboard\SharedKernel\Domain\Model\Sprint\Sprint;
9+
use Werkspot\JiraDashboard\SharedKernel\Domain\Model\Sprint\SprintRepositoryInterface;
10+
use Werkspot\JiraDashboard\SharedKernel\Domain\Model\Widget\WidgetInterface;
11+
12+
final class BurndownWidget implements WidgetInterface
13+
{
14+
/** @var SprintRepositoryInterface */
15+
private $sprintRepository;
16+
17+
/** @var RemainingPointsRepositoryInterface */
18+
private $remainingPointsRepository;
19+
20+
public function __construct(SprintRepositoryInterface $sprintRepository, RemainingPointsRepositoryInterface $remainingPointsRepository)
21+
{
22+
$this->sprintRepository = $sprintRepository;
23+
$this->remainingPointsRepository = $remainingPointsRepository;
24+
}
25+
26+
/**
27+
* @throws EntityNotFoundException
28+
* @return RemainingPoints[]
29+
*/
30+
public function getRemainingPointsBySprint(Sprint $sprint): array
31+
{
32+
return $this->remainingPointsRepository->findBySprint($sprint);
33+
}
34+
35+
public function saveRemainingPoints(RemainingPoints $remainingPoints): void
36+
{
37+
$this->remainingPointsRepository->upsert($remainingPoints);
38+
}
39+
40+
public function render(): Response
41+
{
42+
return new Response('RemainingPoints Widget');
43+
}
44+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Werkspot\JiraDashboard\BurndownWidget\Domain;
5+
6+
use DateTimeImmutable;
7+
use Werkspot\JiraDashboard\SharedKernel\Domain\Model\Sprint\Sprint;
8+
use Werkspot\JiraDashboard\SharedKernel\Domain\ValueObject\Id;
9+
use Werkspot\JiraDashboard\SharedKernel\Domain\ValueObject\PositiveNumber;
10+
11+
class RemainingPoints
12+
{
13+
/** @var Id */
14+
private $id;
15+
16+
/** @var Sprint */
17+
private $sprint;
18+
19+
/** @var DateTimeImmutable */
20+
private $date;
21+
22+
/** @var PositiveNumber */
23+
private $value;
24+
25+
public function __construct(Sprint $sprint, DateTimeImmutable $date, PositiveNumber $value)
26+
{
27+
$this->id = Id::create();
28+
$this->sprint = $sprint;
29+
$this->date = $date;
30+
$this->value = $value;
31+
}
32+
33+
public function getId(): Id
34+
{
35+
return $this->id;
36+
}
37+
38+
public function setDate(DateTimeImmutable $date): self
39+
{
40+
$this->date = $date;
41+
42+
return $this;
43+
}
44+
45+
public function getDate(): DateTimeImmutable
46+
{
47+
return $this->date;
48+
}
49+
50+
public function setValue(PositiveNumber $value): self
51+
{
52+
$this->value = $value;
53+
54+
return $this;
55+
}
56+
57+
public function getValue(): PositiveNumber
58+
{
59+
return $this->value;
60+
}
61+
62+
public function setSprint(Sprint $sprint): self
63+
{
64+
$this->sprint = $sprint;
65+
66+
return $this;
67+
}
68+
69+
public function getSprint(): Sprint
70+
{
71+
return $this->sprint;
72+
}
73+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Werkspot\JiraDashboard\BurndownWidget\Domain;
5+
6+
use Werkspot\JiraDashboard\SharedKernel\Domain\Exception\EntityNotFoundException;
7+
use Werkspot\JiraDashboard\SharedKernel\Domain\Model\Sprint\Sprint;
8+
9+
interface RemainingPointsRepositoryInterface
10+
{
11+
/**
12+
* @throws EntityNotFoundException
13+
* @return RemainingPoints[]
14+
*/
15+
public function findBySprint(Sprint $sprint): array;
16+
17+
public function upsert(RemainingPoints $confidence): void;
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Werkspot\JiraDashboard\BurndownWidget\Infrastructure\Persistence\InMemory\RemainingPoints;
5+
6+
use Werkspot\JiraDashboard\BurndownWidget\Domain\RemainingPoints;
7+
use Werkspot\JiraDashboard\BurndownWidget\Domain\RemainingPointsRepositoryInterface;
8+
use Werkspot\JiraDashboard\SharedKernel\Domain\Exception\EntityNotFoundException;
9+
use Werkspot\JiraDashboard\SharedKernel\Domain\Model\Sprint\Sprint;
10+
11+
class RemainingPointsRepositoryInMemoryAdapter implements RemainingPointsRepositoryInterface
12+
{
13+
/** @var RemainingPoints[] */
14+
private $inMemoryData = [];
15+
16+
/**
17+
* @param RemainingPoints[]|null $data
18+
*/
19+
public function __construct(array $data = null)
20+
{
21+
foreach ($data as $remainingPoints) {
22+
$this->inMemoryData[$remainingPoints->getDate()->format('Ymd')] = $remainingPoints;
23+
}
24+
25+
ksort($this->inMemoryData, SORT_NUMERIC);
26+
}
27+
28+
/**
29+
* @throws EntityNotFoundException
30+
* @return RemainingPoints[]
31+
*/
32+
public function findBySprint(Sprint $sprint): array
33+
{
34+
$remainingPointsCollection = array_filter(
35+
array_values(
36+
array_map(function(RemainingPoints $remainingPoints) use ($sprint) {
37+
if ($remainingPoints->getSprint()->getId() == $sprint->getId()) {
38+
return $remainingPoints;
39+
}
40+
41+
return null;
42+
}, $this->inMemoryData)
43+
)
44+
);
45+
46+
if (empty($remainingPointsCollection)) {
47+
throw new EntityNotFoundException();
48+
}
49+
50+
return $remainingPointsCollection;
51+
}
52+
53+
public function upsert(RemainingPoints $remainingPoints): void
54+
{
55+
$remainingPointsKey = $remainingPoints->getDate()->format('Ymd');
56+
57+
$this->inMemoryData[$remainingPointsKey] = $remainingPoints;
58+
}
59+
}

src/Werkspot/JiraDashboard/SharedKernel/Infrastructure/Persistence/InMemory/Sprint/SprintRepositoryInMemoryAdapter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public function findAll(): ?array
5555
*/
5656
public function findActive(): Sprint
5757
{
58-
$today = new DateTimeImmutable();
58+
$today = new DateTimeImmutable((new DateTimeImmutable())->format('Y-m-d'));
5959

6060
foreach ($this->inMemoryData as $sprint) {
6161
if ($sprint->getStartDate() <= $today && $sprint->getEndDate() >= $today) {
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Werkspot\Tests\JiraDashboard\BurndownWidget\Unit\Domain;
5+
6+
use DateTimeImmutable;
7+
use PHPUnit\Framework\TestCase;
8+
use Werkspot\JiraDashboard\BurndownWidget\Domain\BurndownWidget;
9+
use Werkspot\JiraDashboard\BurndownWidget\Domain\RemainingPoints;
10+
use Werkspot\JiraDashboard\BurndownWidget\Infrastructure\Persistence\InMemory\RemainingPoints\RemainingPointsRepositoryInMemoryAdapter;
11+
use Werkspot\JiraDashboard\SharedKernel\Domain\Model\Sprint\Sprint;
12+
use Werkspot\JiraDashboard\SharedKernel\Domain\Model\Team\Team;
13+
use Werkspot\JiraDashboard\SharedKernel\Domain\ValueObject\Id;
14+
use Werkspot\JiraDashboard\SharedKernel\Domain\ValueObject\PositiveNumber;
15+
use Werkspot\JiraDashboard\SharedKernel\Domain\ValueObject\ShortText;
16+
use Werkspot\JiraDashboard\SharedKernel\Infrastructure\Persistence\InMemory\Sprint\SprintRepositoryInMemoryAdapter;
17+
18+
class BurndownWidgetTest extends TestCase
19+
{
20+
/**
21+
* @test
22+
*/
23+
public function getRemainingPointsBySprint_whenThereIsASprint_shouldReturnRemainingPointsCollectionOrderedByDate()
24+
{
25+
$sprintRepository = $this->getSprintRepository();
26+
$activeSprint = $sprintRepository->findActive();
27+
28+
$remainingPointsRepository = $this->getRemainingPointsRepository($activeSprint);
29+
30+
$burndownWidget = new BurndownWidget($sprintRepository, $remainingPointsRepository);
31+
$remainingPointsCollection = $burndownWidget->getRemainingPointsBySprint($activeSprint);
32+
33+
$this->assertCount(10, $remainingPointsCollection);
34+
$this->assertInstanceOf(RemainingPoints::class, $remainingPointsCollection[0]);
35+
$this->assertTrue(($remainingPointsCollection[0])->getDate() < ($remainingPointsCollection[1])->getDate());
36+
}
37+
38+
/**
39+
* @test
40+
*/
41+
public function saveNewRemainingPoints_whenDataIsValid_shouldSaveNewRemainingStoryPointsDataToPersistence()
42+
{
43+
$sprintRepository = $this->getSprintRepository();
44+
$activeSprint = $sprintRepository->findActive();
45+
46+
$remainingPointsRepository = $this->getRemainingPointsRepository($activeSprint);
47+
48+
$today = new DateTimeImmutable('today');
49+
50+
$newRemainingPointsValue = PositiveNumber::create(0);
51+
$newRemainingPoints = new RemainingPoints($activeSprint, $today, $newRemainingPointsValue);
52+
53+
$burndownWidget = new BurndownWidget($sprintRepository, $remainingPointsRepository);
54+
$burndownWidget->saveRemainingPoints($newRemainingPoints);
55+
56+
$remainingPointsCollection = $remainingPointsRepository->findBySprint($activeSprint);
57+
58+
$this->assertCount(11, $remainingPointsCollection);
59+
$this->assertEquals($newRemainingPointsValue, ($remainingPointsCollection[10])->getValue());
60+
}
61+
62+
/**
63+
* @test
64+
*/
65+
public function saveRemainingPoints_whenDateAlreadyExists_shouldUpdateRemainingPointsData()
66+
{
67+
$sprintRepository = $this->getSprintRepository();
68+
$activeSprint = $sprintRepository->findActive();
69+
70+
$remainingPointsRepository = $this->getRemainingPointsRepository($activeSprint);
71+
72+
$today = new DateTimeImmutable('today - 1 days');
73+
74+
$updatedRemainingPoints = new RemainingPoints($activeSprint, $today, PositiveNumber::create(0));
75+
76+
$burndownWidget = new BurndownWidget($sprintRepository, $remainingPointsRepository);
77+
$burndownWidget->saveRemainingPoints($updatedRemainingPoints);
78+
79+
$savedRemainingPoints = $remainingPointsRepository->findBySprint($activeSprint);
80+
81+
$this->assertEquals($updatedRemainingPoints, $savedRemainingPoints[9]);
82+
}
83+
84+
/**
85+
* @throws \Exception
86+
*/
87+
private function getSprintRepository(): SprintRepositoryInMemoryAdapter
88+
{
89+
$sprintRepository = new SprintRepositoryInMemoryAdapter([
90+
new Sprint(
91+
Id::create(),
92+
ShortText::create('Sprint title'),
93+
new Team(
94+
Id::create(),
95+
ShortText::create('Team name')
96+
),
97+
new DateTimeImmutable('today - 10 days'),
98+
new DateTimeImmutable('today'),
99+
PositiveNumber::create(1)
100+
),
101+
]);
102+
103+
return $sprintRepository;
104+
}
105+
106+
/**
107+
* @throws \Exception
108+
*/
109+
private function getRemainingPointsRepository(Sprint $sprint): RemainingPointsRepositoryInMemoryAdapter
110+
{
111+
$remainingPointsRepository = new RemainingPointsRepositoryInMemoryAdapter([
112+
new RemainingPoints($sprint, new DateTimeImmutable('today - 10 days'), PositiveNumber::create(30)),
113+
new RemainingPoints($sprint, new DateTimeImmutable('today - 9 days'), PositiveNumber::create(25)),
114+
new RemainingPoints($sprint, new DateTimeImmutable('today - 8 days'), PositiveNumber::create(24)),
115+
new RemainingPoints($sprint, new DateTimeImmutable('today - 7 days'), PositiveNumber::create(19)),
116+
new RemainingPoints($sprint, new DateTimeImmutable('today - 6 days'), PositiveNumber::create(10)),
117+
new RemainingPoints($sprint, new DateTimeImmutable('today - 5 days'), PositiveNumber::create(9)),
118+
new RemainingPoints($sprint, new DateTimeImmutable('today - 4 days'), PositiveNumber::create(9)),
119+
new RemainingPoints($sprint, new DateTimeImmutable('today - 3 days'), PositiveNumber::create(8)),
120+
new RemainingPoints($sprint, new DateTimeImmutable('today - 2 days'), PositiveNumber::create(5)),
121+
new RemainingPoints($sprint, new DateTimeImmutable('today - 1 days'), PositiveNumber::create(3)),
122+
]);
123+
124+
return $remainingPointsRepository;
125+
}
126+
}

0 commit comments

Comments
 (0)