diff --git a/src/Service/CalculationService.php b/src/Service/CalculationService.php index c673f3b8..75d5d064 100644 --- a/src/Service/CalculationService.php +++ b/src/Service/CalculationService.php @@ -43,7 +43,7 @@ * user_margin: float, * groups: ServiceGroupType[]} */ -final class CalculationService implements ServiceSubscriberInterface +class CalculationService implements ServiceSubscriberInterface { use MathTrait; use ServiceMethodsSubscriberTrait; diff --git a/tests/DatabaseTrait.php b/tests/DatabaseTrait.php index fd8f7431..98d8c290 100644 --- a/tests/DatabaseTrait.php +++ b/tests/DatabaseTrait.php @@ -85,12 +85,10 @@ protected function deleteEntity(?EntityInterface $entity): null */ protected function getManager(): EntityManager { - /** @var ManagerRegistry $registry */ + /** @psalm-var ManagerRegistry $registry */ $registry = static::getContainer()->get('doctrine'); - /** @var EntityManager $manager */ - $manager = $registry->getManager(); - - return $manager; + /** @psalm-var EntityManager */ + return $registry->getManager(); } } diff --git a/tests/Generator/CalculationGeneratorTest.php b/tests/Generator/CalculationGeneratorTest.php new file mode 100644 index 00000000..87472573 --- /dev/null +++ b/tests/Generator/CalculationGeneratorTest.php @@ -0,0 +1,99 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace App\Tests\Generator; + +use App\Entity\CalculationState; +use App\Generator\AbstractEntityGenerator; +use App\Generator\CalculationGenerator; +use App\Service\CalculationService; +use App\Tests\EntityTrait\CalculationStateTrait; +use App\Tests\EntityTrait\ProductTrait; +use Doctrine\ORM\Exception\ORMException; +use PHPUnit\Framework\Attributes\CoversClass; + +/** + * @extends GeneratorTestCase + */ +#[CoversClass(AbstractEntityGenerator::class)] +#[CoversClass(CalculationGenerator::class)] +class CalculationGeneratorTest extends GeneratorTestCase +{ + use CalculationStateTrait; + use ProductTrait; + + private CalculationService $service; + + protected function setUp(): void + { + parent::setUp(); + $this->service = $this->getService(CalculationService::class); + $this->service->setTranslator($this->translator); + } + + public function testNegativeCount(): void + { + $generator = $this->createGenerator(); + $actual = $generator->generate(-1, true); + self::assertValidateResults($actual, false, 0); + } + + /** + * @throws ORMException + */ + public function testNotSimulate(): void + { + $this->getCalculationState(); + $product = $this->getProduct(); + $product->setPrice(0.0); + $this->manager->flush(); + + $generator = $this->createGenerator(); + $actual = $generator->generate(1, false); + self::assertValidateResults($actual, true, 1); + } + + /** + * @throws ORMException + */ + public function testNotSimulateError(): void + { + $this->deleteCalculationState(); + $generator = $this->createGenerator(); + $actual = $generator->generate(1, false); + self::assertValidateResults($actual, false, 0); + } + + public function testOne(): void + { + $generator = $this->createGenerator(); + $actual = $generator->generate(1, true); + self::assertValidateResults($actual, true, 1); + } + + protected function createGenerator(): CalculationGenerator + { + $generator = new CalculationGenerator($this->manager, $this->fakerService, $this->service); + + return $this->updateGenerator($generator); + } + + private function deleteCalculationState(): void + { + $repository = $this->manager->getRepository(CalculationState::class); + $entities = $repository->findAll(); + foreach ($entities as $entity) { + $repository->remove($entity); + } + $this->manager->flush(); + } +} diff --git a/tests/Generator/CustomerGeneratorTest.php b/tests/Generator/CustomerGeneratorTest.php new file mode 100644 index 00000000..94b1e47f --- /dev/null +++ b/tests/Generator/CustomerGeneratorTest.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace App\Tests\Generator; + +use App\Generator\AbstractEntityGenerator; +use App\Generator\CustomerGenerator; +use PHPUnit\Framework\Attributes\CoversClass; + +/** + * @extends GeneratorTestCase + */ +#[CoversClass(AbstractEntityGenerator::class)] +#[CoversClass(CustomerGenerator::class)] +class CustomerGeneratorTest extends GeneratorTestCase +{ + public function testNegativeCount(): void + { + $generator = $this->createGenerator(); + $actual = $generator->generate(-1, true); + self::assertValidateResults($actual, false, 0); + } + + public function testNotSimulate(): void + { + $generator = $this->createGenerator(); + $actual = $generator->generate(1, false); + self::assertValidateResults($actual, true, 1); + } + + public function testOne(): void + { + $generator = $this->createGenerator(); + $actual = $generator->generate(1, true); + self::assertValidateResults($actual, true, 1); + } + + protected function createGenerator(): CustomerGenerator + { + $generator = new CustomerGenerator($this->manager, $this->fakerService); + + return $this->updateGenerator($generator); + } +} diff --git a/tests/Generator/GeneratorTestCase.php b/tests/Generator/GeneratorTestCase.php new file mode 100644 index 00000000..e04b75d8 --- /dev/null +++ b/tests/Generator/GeneratorTestCase.php @@ -0,0 +1,84 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace App\Tests\Generator; + +use App\Generator\AbstractEntityGenerator; +use App\Service\FakerService; +use App\Tests\DatabaseTrait; +use App\Tests\KernelServiceTestCase; +use App\Utils\StringUtils; +use Doctrine\ORM\EntityManagerInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Contracts\Translation\TranslatorInterface; + +/** + * @template TGenerator of AbstractEntityGenerator + */ +abstract class GeneratorTestCase extends KernelServiceTestCase +{ + use DatabaseTrait; + + protected FakerService $fakerService; + protected LoggerInterface $logger; + protected EntityManagerInterface $manager; + protected TranslatorInterface $translator; + + protected function setUp(): void + { + parent::setUp(); + $this->logger = $this->createMock(LoggerInterface::class); + $this->translator = $this->createMock(TranslatorInterface::class); + $this->manager = $this->getService(EntityManagerInterface::class); + $this->fakerService = $this->getService(FakerService::class); + } + + protected static function assertValidateResults(JsonResponse $actual, bool $expected, int $count): array + { + $content = $actual->getContent(); + self::assertIsString($content); + + $actual = StringUtils::decodeJson($content); + self::assertArrayHasKey('result', $actual); + self::assertSame($expected, $actual['result']); + if ($count <= 0) { + return $actual; + } + + self::assertArrayHasKey('count', $actual); + self::assertSame($count, $actual['count']); + self::assertArrayHasKey('items', $actual); + self::assertIsArray($actual['items']); + self::assertCount($count, $actual['items']); + + return $actual; + } + + /** + * @psalm-return TGenerator + */ + abstract protected function createGenerator(): AbstractEntityGenerator; + + /** + * @psalm-param TGenerator $generator + * + * @psalm-return TGenerator + */ + protected function updateGenerator(AbstractEntityGenerator $generator): AbstractEntityGenerator + { + $generator->setTranslator($this->translator); + $generator->setLogger($this->logger); + + return $generator; + } +} diff --git a/tests/Generator/ProductGeneratorTest.php b/tests/Generator/ProductGeneratorTest.php new file mode 100644 index 00000000..5cb3e1b4 --- /dev/null +++ b/tests/Generator/ProductGeneratorTest.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace App\Tests\Generator; + +use App\Generator\AbstractEntityGenerator; +use App\Generator\ProductGenerator; +use App\Tests\EntityTrait\CategoryTrait; +use Doctrine\ORM\Exception\ORMException; +use PHPUnit\Framework\Attributes\CoversClass; + +/** + * @extends GeneratorTestCase + */ +#[CoversClass(AbstractEntityGenerator::class)] +#[CoversClass(ProductGenerator::class)] +class ProductGeneratorTest extends GeneratorTestCase +{ + use CategoryTrait; + + public function testNegativeCount(): void + { + $generator = $this->createGenerator(); + $actual = $generator->generate(-1, true); + self::assertValidateResults($actual, false, 0); + } + + /** + * @throws ORMException + */ + public function testNotSimulate(): void + { + $this->getCategory(); + $generator = $this->createGenerator(); + $actual = $generator->generate(1, false); + self::assertValidateResults($actual, true, 1); + } + + public function testOne(): void + { + $generator = $this->createGenerator(); + $actual = $generator->generate(1, true); + self::assertValidateResults($actual, true, 1); + } + + protected function createGenerator(): ProductGenerator + { + $generator = new ProductGenerator($this->manager, $this->fakerService); + + return $this->updateGenerator($generator); + } +}