diff --git a/src/ProductVote/Controller/ArticleDetailsController.php b/src/ProductVote/Controller/ArticleDetailsController.php
index 45ae514..b1390f9 100644
--- a/src/ProductVote/Controller/ArticleDetailsController.php
+++ b/src/ProductVote/Controller/ArticleDetailsController.php
@@ -10,8 +10,7 @@
namespace OxidEsales\ModuleTemplate\ProductVote\Controller;
use OxidEsales\Eshop\Application\Model\User;
-use OxidEsales\ModuleTemplate\ProductVote\Dao\ProductVoteDaoInterface;
-use OxidEsales\ModuleTemplate\ProductVote\DataType\ProductVote;
+use OxidEsales\ModuleTemplate\ProductVote\Service\VoteServiceInterface;
/**
* @extendable-class
@@ -35,39 +34,23 @@ public function voteDown(): void
public function resetVote(): void
{
- $userId = $this->getUserId();
- if (!$userId) {
+ $user = $this->getUser();
+ if (!($user instanceof User)) {
return;
}
- $productVoteDao = $this->getProductVoteDao();
- $productVoteDao->resetProductVote($this->getProduct()->getId(), $userId);
+ $voteService = $this->getService(VoteServiceInterface::class);
+ $voteService->resetProductVote($this->getProduct(), $user);
}
private function vote(bool $isUp): void
- {
- $userId = $this->getUserId();
- if (!$userId) {
- return;
- }
-
- $productVoteDao = $this->getProductVoteDao();
- $vote = new ProductVote($this->getProduct()->getId(), $userId, $isUp);
- $productVoteDao->setProductVote($vote);
- }
-
- private function getUserId(): ?string
{
$user = $this->getUser();
if (!($user instanceof User)) {
- return null;
+ return;
}
- return $user->getId();
- }
-
- private function getProductVoteDao(): ProductVoteDaoInterface
- {
- return $this->getService(ProductVoteDaoInterface::class);
+ $voteService = $this->getService(VoteServiceInterface::class);
+ $voteService->setProductVote($this->getProduct(), $user, $isUp);
}
}
diff --git a/src/ProductVote/Dao/ProductVoteDao.php b/src/ProductVote/Dao/ProductVoteDao.php
index c897426..a0a8293 100644
--- a/src/ProductVote/Dao/ProductVoteDao.php
+++ b/src/ProductVote/Dao/ProductVoteDao.php
@@ -12,8 +12,7 @@
use Doctrine\DBAL\Result;
use OxidEsales\EshopCommunity\Internal\Framework\Database\QueryBuilderFactoryInterface;
use OxidEsales\ModuleTemplate\ProductVote\DataMapper\ProductVoteDataMapperInterface;
-use OxidEsales\ModuleTemplate\ProductVote\DataType\ProductVote;
-use RuntimeException;
+use OxidEsales\ModuleTemplate\ProductVote\DataType\ProductVoteInterface;
readonly class ProductVoteDao implements ProductVoteDaoInterface
{
@@ -23,7 +22,7 @@ public function __construct(
) {
}
- public function getProductVote(string $productId, string $userId): ?ProductVote
+ public function getProductVote(string $productId, string $userId): ?ProductVoteInterface
{
$queryBuilder = $this->queryBuilderFactory->create();
$queryBuilder
@@ -40,12 +39,10 @@ public function getProductVote(string $productId, string $userId): ?ProductVote
'userId' => $userId,
]);
+ /** @var Result $result */
$result = $queryBuilder->execute();
- if (!($result instanceof Result)) {
- throw new RuntimeException('Query returned error.');
- }
-
$row = $result->fetchAssociative();
+
if ($row === false) {
return null;
}
@@ -53,9 +50,9 @@ public function getProductVote(string $productId, string $userId): ?ProductVote
return $this->dataMapper->map($row);
}
- public function setProductVote(ProductVote $vote): void
+ public function setProductVote(ProductVoteInterface $vote): void
{
- $this->resetProductVote($vote->productId, $vote->userId);
+ $this->resetProductVote($vote->getProductId(), $vote->getUserId());
$queryBuilder = $this->queryBuilderFactory->create();
$queryBuilder
@@ -68,9 +65,9 @@ public function setProductVote(ProductVote $vote): void
])
->setParameters([
'oxid' => uniqid(),
- 'productId' => $vote->productId,
- 'userId' => $vote->userId,
- 'vote' => (int)$vote->vote,
+ 'productId' => $vote->getProductId(),
+ 'userId' => $vote->getUserId(),
+ 'vote' => (int)$vote->isVoteUp(),
])
->execute();
}
diff --git a/src/ProductVote/Dao/ProductVoteDaoInterface.php b/src/ProductVote/Dao/ProductVoteDaoInterface.php
index 477912c..a44d103 100644
--- a/src/ProductVote/Dao/ProductVoteDaoInterface.php
+++ b/src/ProductVote/Dao/ProductVoteDaoInterface.php
@@ -9,12 +9,12 @@
namespace OxidEsales\ModuleTemplate\ProductVote\Dao;
-use OxidEsales\ModuleTemplate\ProductVote\DataType\ProductVote;
+use OxidEsales\ModuleTemplate\ProductVote\DataType\ProductVoteInterface;
interface ProductVoteDaoInterface
{
- public function getProductVote(string $productId, string $userId): ?ProductVote;
+ public function getProductVote(string $productId, string $userId): ?ProductVoteInterface;
- public function setProductVote(ProductVote $vote): void;
+ public function setProductVote(ProductVoteInterface $vote): void;
public function resetProductVote(string $productId, string $userId): void;
}
diff --git a/src/ProductVote/Dao/ResultDao.php b/src/ProductVote/Dao/VoteResultDao.php
similarity index 65%
rename from src/ProductVote/Dao/ResultDao.php
rename to src/ProductVote/Dao/VoteResultDao.php
index 06adabd..dfa2f6d 100644
--- a/src/ProductVote/Dao/ResultDao.php
+++ b/src/ProductVote/Dao/VoteResultDao.php
@@ -9,20 +9,21 @@
namespace OxidEsales\ModuleTemplate\ProductVote\Dao;
+use Doctrine\DBAL\Result;
use OxidEsales\EshopCommunity\Internal\Framework\Database\QueryBuilderFactoryInterface;
-use OxidEsales\ModuleTemplate\ProductVote\DataMapper\ResultDataMapperInterface;
-use OxidEsales\ModuleTemplate\ProductVote\DataType\Result;
-use RuntimeException;
+use OxidEsales\ModuleTemplate\ProductVote\DataMapper\VoteResultDataMapperInterface;
+use OxidEsales\ModuleTemplate\ProductVote\DataType\VoteResult;
+use OxidEsales\ModuleTemplate\ProductVote\DataType\VoteResultInterface;
-readonly class ResultDao implements ResultDaoInterface
+readonly class VoteResultDao implements VoteResultDaoInterface
{
public function __construct(
private QueryBuilderFactoryInterface $queryBuilderFactory,
- private ResultDataMapperInterface $dataMapper,
+ private VoteResultDataMapperInterface $dataMapper,
) {
}
- public function getProductVoteResult(string $productId): Result
+ public function getProductVoteResult(string $productId): VoteResultInterface
{
$queryBuilder = $this->queryBuilderFactory->create();
$queryBuilder
@@ -38,15 +39,12 @@ public function getProductVoteResult(string $productId): Result
'productId' => $productId,
]);
+ /** @var Result $queryResult */
$queryResult = $queryBuilder->execute();
- if (!($queryResult instanceof \Doctrine\DBAL\Result)) {
- throw new RuntimeException('Query returned error.');
- }
-
$row = $queryResult->fetchAssociative();
if (!$row) {
- return new Result($productId, 0, 0);
+ return new VoteResult($productId, 0, 0);
}
return $this->dataMapper->map($row);
}
diff --git a/src/ProductVote/Dao/ResultDaoInterface.php b/src/ProductVote/Dao/VoteResultDaoInterface.php
similarity index 51%
rename from src/ProductVote/Dao/ResultDaoInterface.php
rename to src/ProductVote/Dao/VoteResultDaoInterface.php
index 94ceddb..16f4c1d 100644
--- a/src/ProductVote/Dao/ResultDaoInterface.php
+++ b/src/ProductVote/Dao/VoteResultDaoInterface.php
@@ -9,9 +9,9 @@
namespace OxidEsales\ModuleTemplate\ProductVote\Dao;
-use OxidEsales\ModuleTemplate\ProductVote\DataType\Result;
+use OxidEsales\ModuleTemplate\ProductVote\DataType\VoteResultInterface;
-interface ResultDaoInterface
+interface VoteResultDaoInterface
{
- public function getProductVoteResult(string $productId): array|Result;
+ public function getProductVoteResult(string $productId): VoteResultInterface;
}
diff --git a/src/ProductVote/DataMapper/ResultDataMapper.php b/src/ProductVote/DataMapper/VoteResultDataMapper.php
similarity index 60%
rename from src/ProductVote/DataMapper/ResultDataMapper.php
rename to src/ProductVote/DataMapper/VoteResultDataMapper.php
index d692b46..f85d53f 100644
--- a/src/ProductVote/DataMapper/ResultDataMapper.php
+++ b/src/ProductVote/DataMapper/VoteResultDataMapper.php
@@ -9,17 +9,17 @@
namespace OxidEsales\ModuleTemplate\ProductVote\DataMapper;
-use OxidEsales\ModuleTemplate\ProductVote\DataType\Result;
+use OxidEsales\ModuleTemplate\ProductVote\DataType\VoteResult;
use OxidEsales\ModuleTemplate\ProductVote\Exception\MapDataTypeException;
-readonly class ResultDataMapper implements ResultDataMapperInterface
+readonly class VoteResultDataMapper implements VoteResultDataMapperInterface
{
- public function map(array $data): Result
+ public function map(array $data): VoteResult
{
if (!isset($data['ProductId']) || !isset($data['VoteUp']) || !isset($data['VoteDown'])) {
throw new MapDataTypeException();
}
- return new Result($data['ProductId'], (int)$data['VoteUp'], (int)$data['VoteDown']);
+ return new VoteResult($data['ProductId'], (int)$data['VoteUp'], (int)$data['VoteDown']);
}
}
diff --git a/src/ProductVote/DataMapper/ResultDataMapperInterface.php b/src/ProductVote/DataMapper/VoteResultDataMapperInterface.php
similarity index 56%
rename from src/ProductVote/DataMapper/ResultDataMapperInterface.php
rename to src/ProductVote/DataMapper/VoteResultDataMapperInterface.php
index 1037b95..7466971 100644
--- a/src/ProductVote/DataMapper/ResultDataMapperInterface.php
+++ b/src/ProductVote/DataMapper/VoteResultDataMapperInterface.php
@@ -9,9 +9,9 @@
namespace OxidEsales\ModuleTemplate\ProductVote\DataMapper;
-use OxidEsales\ModuleTemplate\ProductVote\DataType\Result;
+use OxidEsales\ModuleTemplate\ProductVote\DataType\VoteResult;
-interface ResultDataMapperInterface
+interface VoteResultDataMapperInterface
{
- public function map(array $data): Result;
+ public function map(array $data): VoteResult;
}
diff --git a/src/ProductVote/DataType/ProductVote.php b/src/ProductVote/DataType/ProductVote.php
index d456fd1..238d660 100644
--- a/src/ProductVote/DataType/ProductVote.php
+++ b/src/ProductVote/DataType/ProductVote.php
@@ -9,7 +9,7 @@
namespace OxidEsales\ModuleTemplate\ProductVote\DataType;
-readonly class ProductVote
+readonly class ProductVote implements ProductVoteInterface
{
public function __construct(
public string $productId,
@@ -17,4 +17,19 @@ public function __construct(
public bool $vote,
) {
}
+
+ public function getProductId(): string
+ {
+ return $this->productId;
+ }
+
+ public function getUserId(): string
+ {
+ return $this->userId;
+ }
+
+ public function isVoteUp(): bool
+ {
+ return $this->vote;
+ }
}
diff --git a/src/ProductVote/DataType/Result.php b/src/ProductVote/DataType/ProductVoteInterface.php
similarity index 55%
rename from src/ProductVote/DataType/Result.php
rename to src/ProductVote/DataType/ProductVoteInterface.php
index 2280702..f39ba31 100644
--- a/src/ProductVote/DataType/Result.php
+++ b/src/ProductVote/DataType/ProductVoteInterface.php
@@ -9,12 +9,9 @@
namespace OxidEsales\ModuleTemplate\ProductVote\DataType;
-readonly class Result
+interface ProductVoteInterface
{
- public function __construct(
- public string $productId,
- public int $voteUp,
- public int $voteDown,
- ) {
- }
+ public function getProductId(): string;
+ public function getUserId(): string;
+ public function isVoteUp(): bool;
}
diff --git a/src/ProductVote/DataType/VoteResult.php b/src/ProductVote/DataType/VoteResult.php
new file mode 100644
index 0000000..6ddaafc
--- /dev/null
+++ b/src/ProductVote/DataType/VoteResult.php
@@ -0,0 +1,35 @@
+productId;
+ }
+
+ public function getVoteUp(): int
+ {
+ return $this->voteUp;
+ }
+
+ public function getVoteDown(): int
+ {
+ return $this->voteDown;
+ }
+}
diff --git a/src/ProductVote/DataType/VoteResultInterface.php b/src/ProductVote/DataType/VoteResultInterface.php
new file mode 100644
index 0000000..34f42f8
--- /dev/null
+++ b/src/ProductVote/DataType/VoteResultInterface.php
@@ -0,0 +1,17 @@
+productVoteDao->getProductVote($product->getId(), $user->getId());
+ }
+
+ public function setProductVote(Article $product, User $user, bool $vote): void
+ {
+ $vote = new ProductVote($product->getId(), $user->getId(), $vote);
+ $this->productVoteDao->setProductVote($vote);
+ }
+
+ public function resetProductVote(Article $product, User $user): void
+ {
+ $this->productVoteDao->resetProductVote($product->getId(), $user->getId());
+ }
+
+ public function getProductVoteResult(Article $product): VoteResultInterface
+ {
+ return $this->voteResultDao->getProductVoteResult($product->getId());
+ }
+}
diff --git a/src/ProductVote/Service/VoteServiceInterface.php b/src/ProductVote/Service/VoteServiceInterface.php
new file mode 100644
index 0000000..74ea2f2
--- /dev/null
+++ b/src/ProductVote/Service/VoteServiceInterface.php
@@ -0,0 +1,24 @@
+prepareVoteData();
+ $this->oemtPrepareVoteData();
return parent::render();
}
- public function prepareVoteData(): void
+ public function oemtPrepareVoteData(): void
{
/** @var Article $product */
$product = $this->getProduct();
/** @var User $user */
$user = $this->getUser();
+ $voteService = $this->getService(VoteServiceInterface::class);
+
if ($user instanceof User) {
- $productVoteDao = $this->getProductVoteDao();
- $this->_aViewData['productVote'] = $productVoteDao->getProductVote($product->getId(), $user->getId());
+ $this->_aViewData['productVote'] = $voteService->getProductVote($product, $user);
}
- $resultDao = $this->getProductVoteResultDao();
- $this->_aViewData['productVoteResult'] = $resultDao->getProductVoteResult($product->getId());
- }
-
- private function getProductVoteDao(): ProductVoteDaoInterface
- {
- return $this->getService(ProductVoteDaoInterface::class);
- }
-
- private function getProductVoteResultDao(): ResultDaoInterface
- {
- return $this->getService(ResultDaoInterface::class);
+ $this->_aViewData['productVoteResult'] = $voteService->getProductVoteResult($product);
}
}
diff --git a/src/ProductVote/services.yaml b/src/ProductVote/services.yaml
index e46c3cd..631b6ed 100644
--- a/src/ProductVote/services.yaml
+++ b/src/ProductVote/services.yaml
@@ -5,14 +5,16 @@ services:
OxidEsales\ModuleTemplate\ProductVote\Dao\ProductVoteDaoInterface:
class: OxidEsales\ModuleTemplate\ProductVote\Dao\ProductVoteDao
- public: true
- OxidEsales\ModuleTemplate\ProductVote\Dao\ResultDaoInterface:
- class: OxidEsales\ModuleTemplate\ProductVote\Dao\ResultDao
- public: true
+ OxidEsales\ModuleTemplate\ProductVote\Dao\VoteResultDaoInterface:
+ class: OxidEsales\ModuleTemplate\ProductVote\Dao\VoteResultDao
OxidEsales\ModuleTemplate\ProductVote\DataMapper\ProductVoteDataMapperInterface:
class: OxidEsales\ModuleTemplate\ProductVote\DataMapper\ProductVoteDataMapper
- OxidEsales\ModuleTemplate\ProductVote\DataMapper\ResultDataMapperInterface:
- class: OxidEsales\ModuleTemplate\ProductVote\DataMapper\ResultDataMapper
+ OxidEsales\ModuleTemplate\ProductVote\DataMapper\VoteResultDataMapperInterface:
+ class: OxidEsales\ModuleTemplate\ProductVote\DataMapper\VoteResultDataMapper
+
+ OxidEsales\ModuleTemplate\ProductVote\Service\VoteServiceInterface:
+ class: OxidEsales\ModuleTemplate\ProductVote\Service\VoteService
+ public: true
diff --git a/tests/Integration/ProductVote/Controller/ArticleDetailsControllerTest.php b/tests/Integration/ProductVote/Controller/ArticleDetailsControllerTest.php
index 3548a1e..8651c53 100644
--- a/tests/Integration/ProductVote/Controller/ArticleDetailsControllerTest.php
+++ b/tests/Integration/ProductVote/Controller/ArticleDetailsControllerTest.php
@@ -12,11 +12,9 @@
use OxidEsales\Eshop\Application\Model\Article;
use OxidEsales\Eshop\Application\Model\User;
use OxidEsales\ModuleTemplate\ProductVote\Controller\ArticleDetailsController;
-use OxidEsales\ModuleTemplate\ProductVote\Dao\ProductVoteDaoInterface;
-use OxidEsales\ModuleTemplate\ProductVote\DataType\ProductVote;
+use OxidEsales\ModuleTemplate\ProductVote\Service\VoteServiceInterface;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
-use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\MockObject\Stub;
use PHPUnit\Framework\TestCase;
@@ -29,15 +27,28 @@ final class ArticleDetailsControllerTest extends TestCase
#[Test]
public function voteNotLoggedIn(): void
{
- $daoSpy = $this->createMock(ProductVoteDaoInterface::class);
- $daoSpy
+ $voteServiceSpy = $this->createMock(VoteServiceInterface::class);
+ $voteServiceSpy
->expects($this->never())
->method('setProductVote');
- $daoSpy
+ $voteServiceSpy
->expects($this->never())
->method('resetProductVote');
- $sut = $this->getSutMock($daoSpy, null, $this->getProductStub());
+ $sut = $this
+ ->getMockBuilder(ArticleDetailsController::class)
+ ->onlyMethods(['getService', 'getProduct', 'getUser'])
+ ->getMock();
+ $sut
+ ->method('getService')
+ ->with(VoteServiceInterface::class)
+ ->willReturn($voteServiceSpy);
+ $sut
+ ->method('getUser')
+ ->willReturn(null);
+ $sut
+ ->method('getProduct')
+ ->willReturn($this->getProductStub());
$sut->voteUp();
$sut->voteDown();
@@ -47,11 +58,13 @@ public function voteNotLoggedIn(): void
#[Test]
public function voteUp(): void
{
- $daoSpy = $this->getDaoSpy(
+ $voteServiceSpy = $this->getVoteServiceSpy(
'setProductVote',
- new ProductVote(self::TEST_PRODUCT_ID, self::TEST_USER_ID, true)
+ $this->getProductStub(),
+ $this->getUserStub(),
+ true,
);
- $sut = $this->getSutMock($daoSpy, $this->getUserStub(), $this->getProductStub());
+ $sut = $this->getSutMock($voteServiceSpy);
$sut->voteUp();
}
@@ -59,11 +72,13 @@ public function voteUp(): void
#[Test]
public function voteDown(): void
{
- $daoSpy = $this->getDaoSpy(
+ $voteServiceSpy = $this->getVoteServiceSpy(
'setProductVote',
- new ProductVote(self::TEST_PRODUCT_ID, self::TEST_USER_ID, false)
+ $this->getProductStub(),
+ $this->getUserStub(),
+ false,
);
- $sut = $this->getSutMock($daoSpy, $this->getUserStub(), $this->getProductStub());
+ $sut = $this->getSutMock($voteServiceSpy);
$sut->voteDown();
}
@@ -71,15 +86,19 @@ public function voteDown(): void
#[Test]
public function resetVote(): void
{
- $daoSpy = $this->getDaoSpy('resetProductVote', self::TEST_PRODUCT_ID, self::TEST_USER_ID);
- $sut = $this->getSutMock($daoSpy, $this->getUserStub(), $this->getProductStub());
+ $voteServiceSpy = $this->getVoteServiceSpy(
+ 'resetProductVote',
+ $this->getProductStub(),
+ $this->getUserStub(),
+ );
+ $sut = $this->getSutMock($voteServiceSpy);
$sut->resetVote();
}
- private function getDaoSpy(string $method, mixed ...$arguments): ProductVoteDaoInterface|MockObject
+ private function getVoteServiceSpy(string $method, mixed ...$arguments): VoteServiceInterface
{
- $daoSpy = $this->createMock(ProductVoteDaoInterface::class);
+ $daoSpy = $this->createMock(VoteServiceInterface::class);
$daoSpy
->expects($this->once())
->method($method)
@@ -109,23 +128,22 @@ private function getUserStub(): User|Stub
}
private function getSutMock(
- ProductVoteDaoInterface|MockObject $daoSpy,
- Stub|User|null $userStub,
- Article|Stub $productStub,
- ): ArticleDetailsController|MockObject {
+ VoteServiceInterface $voteServiceSpy,
+ ): ArticleDetailsController {
$sut = $this
->getMockBuilder(ArticleDetailsController::class)
->onlyMethods(['getService', 'getProduct', 'getUser'])
->getMock();
$sut
->method('getService')
- ->with(ProductVoteDaoInterface::class)->willReturn($daoSpy);
+ ->with(VoteServiceInterface::class)
+ ->willReturn($voteServiceSpy);
$sut
->method('getUser')
- ->willReturn($userStub);
+ ->willReturn($this->getUserStub());
$sut
->method('getProduct')
- ->willReturn($productStub);
+ ->willReturn($this->getProductStub());
return $sut;
}
diff --git a/tests/Integration/ProductVote/Dao/ResultDaoTest.php b/tests/Integration/ProductVote/Dao/ResultDaoTest.php
index b40f065..7465346 100644
--- a/tests/Integration/ProductVote/Dao/ResultDaoTest.php
+++ b/tests/Integration/ProductVote/Dao/ResultDaoTest.php
@@ -10,13 +10,13 @@
namespace OxidEsales\ModuleTemplate\Tests\Integration\ProductVote\Dao;
use OxidEsales\EshopCommunity\Tests\Integration\IntegrationTestCase;
-use OxidEsales\ModuleTemplate\ProductVote\Dao\ResultDao;
-use OxidEsales\ModuleTemplate\ProductVote\Dao\ResultDaoInterface;
-use OxidEsales\ModuleTemplate\ProductVote\DataType\Result;
+use OxidEsales\ModuleTemplate\ProductVote\Dao\VoteResultDao;
+use OxidEsales\ModuleTemplate\ProductVote\Dao\VoteResultDaoInterface;
+use OxidEsales\ModuleTemplate\ProductVote\DataType\VoteResult;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
-#[CoversClass(ResultDao::class)]
+#[CoversClass(VoteResultDao::class)]
final class ResultDaoTest extends IntegrationTestCase
{
use DaoTestTrait;
@@ -24,10 +24,10 @@ final class ResultDaoTest extends IntegrationTestCase
#[Test]
public function calculateNoVotes(): void
{
- $sut = $this->get(ResultDaoInterface::class);
+ $sut = $this->get(VoteResultDaoInterface::class);
$result = $sut->getProductVoteResult(self::TEST_PRODUCT_ID);
- $this->assertEquals(new Result(self::TEST_PRODUCT_ID, 0, 0), $result);
+ $this->assertEquals(new VoteResult(self::TEST_PRODUCT_ID, 0, 0), $result);
}
#[Test]
@@ -35,9 +35,9 @@ public function calculateVoteResult(): void
{
$this->executeInsertVoteQuery(true, 'user_1');
- $sut = $this->get(ResultDaoInterface::class);
+ $sut = $this->get(VoteResultDaoInterface::class);
$result = $sut->getProductVoteResult(self::TEST_PRODUCT_ID);
- $this->assertEquals(new Result(self::TEST_PRODUCT_ID, 1, 0), $result);
+ $this->assertEquals(new VoteResult(self::TEST_PRODUCT_ID, 1, 0), $result);
}
#[Test]
@@ -51,8 +51,8 @@ public function calculateVotesResult(): void
$this->executeInsertVoteQuery(true, 'user_6'); // 3/3
$this->executeInsertVoteQuery(true, 'user_7'); // 4/3
- $sut = $this->get(ResultDaoInterface::class);
+ $sut = $this->get(VoteResultDaoInterface::class);
$result = $sut->getProductVoteResult(self::TEST_PRODUCT_ID);
- $this->assertEquals(new Result(self::TEST_PRODUCT_ID, 4, 3), $result);
+ $this->assertEquals(new VoteResult(self::TEST_PRODUCT_ID, 4, 3), $result);
}
}
diff --git a/tests/Integration/ProductVote/Widget/ArticleDetailsTest.php b/tests/Integration/ProductVote/Widget/ArticleDetailsTest.php
index 3c4c239..4872d08 100644
--- a/tests/Integration/ProductVote/Widget/ArticleDetailsTest.php
+++ b/tests/Integration/ProductVote/Widget/ArticleDetailsTest.php
@@ -11,10 +11,9 @@
use OxidEsales\Eshop\Application\Model\Article;
use OxidEsales\Eshop\Application\Model\User;
-use OxidEsales\ModuleTemplate\ProductVote\Dao\ProductVoteDaoInterface;
-use OxidEsales\ModuleTemplate\ProductVote\Dao\ResultDaoInterface;
use OxidEsales\ModuleTemplate\ProductVote\DataType\ProductVote;
-use OxidEsales\ModuleTemplate\ProductVote\DataType\Result;
+use OxidEsales\ModuleTemplate\ProductVote\DataType\VoteResult;
+use OxidEsales\ModuleTemplate\ProductVote\Service\VoteServiceInterface;
use OxidEsales\ModuleTemplate\ProductVote\Widget\ArticleDetails;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
@@ -37,12 +36,14 @@ public function prepareDataNotLoggedIn(): void
->willReturn(null);
$sut
->method('getService')
- ->with(ResultDaoInterface::class)->willReturn($this->getResultDaoStub());
+ ->with(VoteServiceInterface::class)
+ ->willReturn($this->getVoteServiceStub());
- $sut->prepareVoteData();
+ $sut->oemtPrepareVoteData();
$viewData = $sut->getViewData();
- $this->assertEquals($this->getResultDataType(), $viewData['productVoteResult']);
+ $this->assertEquals($this->getVoteResultDataType(), $viewData['productVoteResult']);
+ $this->assertArrayNotHasKey('productVote', $viewData);
}
#[Test]
@@ -54,15 +55,13 @@ public function prepareDataLoggedIn(): void
->willReturn($this->getUserStub());
$sut
->method('getService')
- ->willReturnMap([
- [ProductVoteDaoInterface::class, $this->getProductVoteDaoStub()],
- [ResultDaoInterface::class, $this->getResultDaoStub()],
- ]);
+ ->with(VoteServiceInterface::class)
+ ->willReturn($this->getVoteServiceStub());
- $sut->prepareVoteData();
+ $sut->oemtPrepareVoteData();
$viewData = $sut->getViewData();
- $this->assertEquals($this->getResultDataType(), $viewData['productVoteResult']);
+ $this->assertEquals($this->getVoteResultDataType(), $viewData['productVoteResult']);
$this->assertEquals($this->getProductVoteDataType(), $viewData['productVote']);
}
@@ -99,12 +98,15 @@ private function getUserStub(): User|Stub
return $userStub;
}
- private function getProductVoteDaoStub(): ProductVoteDaoInterface|Stub
+ private function getVoteServiceStub(): VoteServiceInterface
{
- $stub = $this->createStub(ProductVoteDaoInterface::class);
+ $stub = $this->createStub(VoteServiceInterface::class);
$stub
->method('getProductVote')
->willReturn($this->getProductVoteDataType());
+ $stub
+ ->method('getProductVoteResult')
+ ->willReturn($this->getVoteResultDataType());
return $stub;
}
@@ -114,18 +116,8 @@ private function getProductVoteDataType(): ProductVote
return new ProductVote(self::TEST_PRODUCT_ID, self::TEST_USER_ID, true);
}
- private function getResultDaoStub(): ResultDaoInterface|Stub
- {
- $stub = $this->createStub(ResultDaoInterface::class);
- $stub
- ->method('getProductVoteResult')
- ->willReturn($this->getResultDataType());
-
- return $stub;
- }
-
- private function getResultDataType(): Result
+ private function getVoteResultDataType(): VoteResult
{
- return new Result(self::TEST_PRODUCT_ID, 3, 2);
+ return new VoteResult(self::TEST_PRODUCT_ID, 3, 2);
}
}
diff --git a/tests/Unit/ProductVote/DataMapper/ResultDataMapperTest.php b/tests/Unit/ProductVote/DataMapper/ResultDataMapperTest.php
index 3324f51..f454187 100644
--- a/tests/Unit/ProductVote/DataMapper/ResultDataMapperTest.php
+++ b/tests/Unit/ProductVote/DataMapper/ResultDataMapperTest.php
@@ -10,22 +10,22 @@
namespace OxidEsales\ModuleTemplate\Tests\Unit\ProductVote\DataMapper;
use Generator;
-use OxidEsales\ModuleTemplate\ProductVote\DataMapper\ResultDataMapper;
-use OxidEsales\ModuleTemplate\ProductVote\DataType\Result;
+use OxidEsales\ModuleTemplate\ProductVote\DataMapper\VoteResultDataMapper;
+use OxidEsales\ModuleTemplate\ProductVote\DataType\VoteResult;
use OxidEsales\ModuleTemplate\ProductVote\Exception\MapDataTypeException;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
-#[CoversClass(ResultDataMapper::class)]
+#[CoversClass(VoteResultDataMapper::class)]
final class ResultDataMapperTest extends TestCase
{
#[Test]
#[DataProvider('mapMalformedDataProvider')]
public function mapMalformedData(array $data): void
{
- $sut = new ResultDataMapper();
+ $sut = new VoteResultDataMapper();
$this->expectException(MapDataTypeException::class);
$sut->map($data);
@@ -45,16 +45,16 @@ public static function mapMalformedDataProvider(): Generator
#[Test]
#[DataProvider('mapDataProvider')]
- public function mapData(Result $expectedResult, array $data): void
+ public function mapData(VoteResult $expectedResult, array $data): void
{
- $sut = new ResultDataMapper();
+ $sut = new VoteResultDataMapper();
$this->assertEquals($expectedResult, $sut->map($data));
}
public static function mapDataProvider(): Generator
{
yield [
- 'expectedResult' => new Result(
+ 'expectedResult' => new VoteResult(
'test_product_id',
2,
3,
@@ -67,7 +67,7 @@ public static function mapDataProvider(): Generator
];
yield [
- 'expectedResult' => new Result(
+ 'expectedResult' => new VoteResult(
'another_product_id',
100,
0,
diff --git a/tests/Unit/ProductVote/Service/VoteServiceTest.php b/tests/Unit/ProductVote/Service/VoteServiceTest.php
new file mode 100644
index 0000000..0e299fe
--- /dev/null
+++ b/tests/Unit/ProductVote/Service/VoteServiceTest.php
@@ -0,0 +1,121 @@
+createMock(ProductVoteDaoInterface::class);
+ $productVoteDaoSpy
+ ->expects($this->once())
+ ->method('getProductVote')
+ ->with(self::TEST_PRODUCT_ID, self::TEST_USER_ID)
+ ->willReturn($this->getProductVoteDataType());
+
+ $sut = $this->getSut(productVoteDao: $productVoteDaoSpy);
+ $productVote = $sut->getProductVote($this->getProductStub(), $this->getUserStub());
+
+ $this->assertEquals($productVote, $this->getProductVoteDataType());
+ }
+
+ public function testSetProductVote(): void
+ {
+ $productVoteDaoSpy = $this->createMock(ProductVoteDaoInterface::class);
+ $productVoteDaoSpy
+ ->expects($this->once())
+ ->method('setProductVote')
+ ->with($this->getProductVoteDataType());
+
+ $sut = $this->getSut(productVoteDao: $productVoteDaoSpy);
+ $sut->setProductVote($this->getProductStub(), $this->getUserStub(), true);
+ }
+
+ public function testResetProductVote(): void
+ {
+ $productVoteDaoSpy = $this->createMock(ProductVoteDaoInterface::class);
+ $productVoteDaoSpy
+ ->expects($this->once())
+ ->method('resetProductVote')
+ ->with(self::TEST_PRODUCT_ID, self::TEST_USER_ID);
+
+ $sut = $this->getSut(productVoteDao: $productVoteDaoSpy);
+ $sut->resetProductVote($this->getProductStub(), $this->getUserStub());
+ }
+
+ public function testGetProductVoteResult(): void
+ {
+ $voteResultDaoSpy = $this->createMock(VoteResultDaoInterface::class);
+ $voteResultDaoSpy
+ ->expects($this->once())
+ ->method('getProductVoteResult')
+ ->with(self::TEST_PRODUCT_ID)
+ ->willReturn($this->getVoteResultDataType());
+
+ $sut = $this->getSut(voteResultDao: $voteResultDaoSpy);
+ $voteResult = $sut->getProductVoteResult($this->getProductStub());
+
+ $this->assertEquals($voteResult, $this->getVoteResultDataType());
+ }
+
+ private function getSut(
+ ?ProductVoteDaoInterface $productVoteDao = null,
+ ?VoteResultDaoInterface $voteResultDao = null,
+ ): VoteService {
+ return new VoteService(
+ productVoteDao: $productVoteDao ?? $this->createStub(ProductVoteDaoInterface::class),
+ voteResultDao: $voteResultDao ?? $this->createStub(VoteResultDaoInterface::class),
+ );
+ }
+
+ private function getProductStub(): Article
+ {
+ $productStub = $this->createStub(Article::class);
+ $productStub
+ ->method('getId')
+ ->willReturn(self::TEST_PRODUCT_ID);
+
+ return $productStub;
+ }
+
+ private function getUserStub(): User
+ {
+ $userStub = $this->createStub(User::class);
+ $userStub
+ ->method('getId')
+ ->willReturn(self::TEST_USER_ID);
+
+ return $userStub;
+ }
+
+ private function getProductVoteDataType(): ProductVote
+ {
+ return new ProductVote(self::TEST_PRODUCT_ID, self::TEST_USER_ID, true);
+ }
+
+ private function getVoteResultDataType(): VoteResult
+ {
+ return new VoteResult(self::TEST_PRODUCT_ID, 3, 2);
+ }
+}
diff --git a/views/twig/extensions/themes/default/page/details/inc/productmain.html.twig b/views/twig/extensions/themes/default/page/details/inc/productmain.html.twig
index 2e090a8..eec031f 100644
--- a/views/twig/extensions/themes/default/page/details/inc/productmain.html.twig
+++ b/views/twig/extensions/themes/default/page/details/inc/productmain.html.twig
@@ -4,14 +4,15 @@
{{ parent() }}
{% if oViewConf.getUser() %}
{% set baseLink = oViewConf.getSelfLink() ~ 'cl=' ~ oViewConf.getTopActiveClassName() ~ '&anid=' ~ oDetailsProduct.oxarticles__oxnid.value %}
-
- {{ productVote.vote ? '👍' : '🖒' }} ({{ productVoteResult.voteUp }})
+ {% set hue = ';filter:hue-rotate(300deg)' %}
+
+ 👍 ({{ productVoteResult.voteUp }})
-
- {{ productVote and (not productVote.vote) ? '👎' : '🖓' }} ({{ productVoteResult.voteDown }})
+
+ 👎 ({{ productVoteResult.voteDown }})
{% else %}
- 🖒 ({{ productVoteResult.voteUp }})
- 🖓 ({{ productVoteResult.voteDown }})
+ 👍 ({{ productVoteResult.voteUp }})
+ 👎 ({{ productVoteResult.voteDown }})
{% endif %}
{% endblock %}