Skip to content

Commit 0db4027

Browse files
committed
ArticleCounterの実クラス
1 parent b16ccab commit 0db4027

8 files changed

Lines changed: 167 additions & 2 deletions

File tree

src/Entity/PostCount.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace App\Entity;
44

5+
use App\Model\PostCountInterface;
56
use Doctrine\ORM\Mapping as ORM;
67

78
/**
@@ -10,7 +11,7 @@
1011
* @ORM\UniqueConstraint(columns={"post_date"}
1112
* )})
1213
*/
13-
class PostCount
14+
class PostCount implements PostCountInterface
1415
{
1516
/**
1617
* @ORM\Id()
@@ -57,4 +58,9 @@ public function setPostCount(int $postCount): self
5758

5859
return $this;
5960
}
61+
62+
public function countUp(): void
63+
{
64+
$this->postCount++;
65+
}
6066
}

src/Model/ArticleInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,6 @@ interface ArticleInterface
77
public function setName(string $name): self;
88

99
public function setBody(string $body): self;
10+
11+
public function getCreatedAt(): ?\DateTimeInterface;
1012
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace App\Model;
4+
5+
interface PostCountFinderInterface
6+
{
7+
public function findOneByPostDateOrCreate(\DateTimeInterface $postDate): PostCountInterface;
8+
}

src/Model/PostCountInterface.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace App\Model;
4+
5+
interface PostCountInterface
6+
{
7+
public function countUp(): void;
8+
}

src/Repository/PostCountRepository.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace App\Repository;
44

55
use App\Entity\PostCount;
6+
use App\Model\PostCountFinderInterface;
7+
use App\Model\PostCountInterface;
68
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
79
use Doctrine\Persistence\ManagerRegistry;
810

@@ -12,13 +14,29 @@
1214
* @method PostCount[] findAll()
1315
* @method PostCount[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
1416
*/
15-
class PostCountRepository extends ServiceEntityRepository
17+
class PostCountRepository extends ServiceEntityRepository implements PostCountFinderInterface
1618
{
1719
public function __construct(ManagerRegistry $registry)
1820
{
1921
parent::__construct($registry, PostCount::class);
2022
}
2123

24+
public function findOneByPostDateOrCreate(\DateTimeInterface $postedDate): PostCountInterface
25+
{
26+
$targetCount = $this->findOneBy([
27+
'postDate' => $postedDate,
28+
]);
29+
if (!$targetCount) {
30+
$targetCount = new PostCount();
31+
$targetCount
32+
->setPostDate($postedDate)
33+
->setPostCount(0)
34+
;
35+
}
36+
37+
return $targetCount;
38+
}
39+
2240
// /**
2341
// * @return PostCount[] Returns an array of PostCount objects
2442
// */

src/Service/ArticleCounter.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
namespace App\Service;
4+
5+
use App\Entity\Article;
6+
use App\Model\ArticleCounterInterface;
7+
use App\Model\ArticleInterface;
8+
use App\Model\PostCountFinderInterface;
9+
use Doctrine\ORM\EntityManagerInterface;
10+
11+
class ArticleCounter implements ArticleCounterInterface
12+
{
13+
/**
14+
* @var PostCountFinderInterface
15+
*/
16+
private $postCountFinder;
17+
18+
/**
19+
* @var EntityManagerInterface
20+
*/
21+
private $em;
22+
23+
/**
24+
* @param PostCountFinderInterface $postCountFinder
25+
* @param EntityManagerInterface $em
26+
*/
27+
public function __construct(PostCountFinderInterface $postCountFinder, EntityManagerInterface $em)
28+
{
29+
$this->postCountFinder = $postCountFinder;
30+
$this->em = $em;
31+
}
32+
33+
public function count(ArticleInterface $article): void
34+
{
35+
/** @var Article $article */
36+
$postCount = $this->postCountFinder->findOneByPostDateOrCreate($article->getCreatedAt());
37+
$postCount->countUp();
38+
39+
$this->em->persist($postCount);
40+
$this->em->flush();
41+
}
42+
43+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace App\Tests\Functional\Repository\PostCountRepositoryTest;
4+
5+
use App\Entity\PostCount;
6+
use App\Repository\PostCountRepository;
7+
use Liip\TestFixturesBundle\Test\FixturesTrait;
8+
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
9+
10+
class FindOneByPostDateOrCreateTest extends KernelTestCase
11+
{
12+
use FixturesTrait;
13+
14+
protected function setUp(): void
15+
{
16+
$this->loadFixtureFiles([
17+
__DIR__.'/../../../../var/fixtures/Repository/PostCountRepository/find_one_by_post_date_or_create.yaml',
18+
]);
19+
static::ensureKernelShutdown();
20+
}
21+
22+
public function test_既存PostCountがある場合()
23+
{
24+
$actual = $this->getSUT()->findOneByPostDateOrCreate(new \DateTimeImmutable('2020-09-01'));
25+
$this->assertEquals(1, $actual->getPostCount(), '保存されているエンティティが出てきている');
26+
}
27+
28+
public function test_既存PostCountがない場合()
29+
{
30+
$actual = $this->getSUT()->findOneByPostDateOrCreate(new \DateTimeImmutable('2020-09-02'));
31+
$this->assertNull($actual->getId());
32+
$this->assertNotNull($actual->getPostDate(), '日付はセット済');
33+
$this->assertEquals(null, $actual->getPostCount(), 'newされたばかりなのでnull');
34+
}
35+
36+
private function getSUT(): PostCountRepository
37+
{
38+
static::bootKernel();
39+
40+
return self::$kernel->getContainer()->get('doctrine')->getManager()->getRepository(PostCount::class);
41+
}
42+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace App\Tests\Service;
4+
5+
use App\Model\ArticleInterface;
6+
use App\Model\PostCountFinderInterface;
7+
use App\Model\PostCountInterface;
8+
use App\Service\ArticleCounter;
9+
use Doctrine\ORM\EntityManagerInterface;
10+
use PHPUnit\Framework\TestCase;
11+
12+
class ArticleCounterTest extends TestCase
13+
{
14+
public function test()
15+
{
16+
$createdAt = new \DateTimeImmutable('2020-09-01');
17+
$articleP = $this->prophesize(ArticleInterface::class);
18+
$articleP->getCreatedAt()->willReturn($createdAt)->shouldBeCalled();
19+
$article = $articleP->reveal();
20+
21+
$postCountP = $this->prophesize(PostCountInterface::class);
22+
$postCountP->countUp()->shouldBeCalled();
23+
$postCount = $postCountP->reveal();
24+
25+
$finderP = $this->prophesize(PostCountFinderInterface::class);
26+
$emP = $this->prophesize(EntityManagerInterface::class);
27+
28+
$finderP->findOneByPostDateOrCreate($createdAt)->willReturn($postCount)->shouldBeCalled();
29+
$emP->persist($postCount)->shouldBeCalled();
30+
$emP->flush()->shouldBeCalled();
31+
32+
$SUT = new ArticleCounter(
33+
$finderP->reveal(),
34+
$emP->reveal()
35+
);
36+
$SUT->count($article);
37+
}
38+
}

0 commit comments

Comments
 (0)