Skip to content

Commit

Permalink
Add command to get voucher count for User
Browse files Browse the repository at this point in the history
  • Loading branch information
y3n4 committed Feb 6, 2025
1 parent f958fa8 commit 4b31e1c
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 0 deletions.
49 changes: 49 additions & 0 deletions src/Command/VoucherCountCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

namespace App\Command;

use App\Entity\User;
use App\Entity\Voucher;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Security\Core\Exception\UserNotFoundException;

#[AsCommand(name: 'app:voucher:count')]
class VoucherCountCommand extends Command
{
public function __construct(
private readonly EntityManagerInterface $manager,
) {
parent::__construct();
}

protected function configure(): void
{
$this
->setDescription('Get count of unredeemed vouchers for a specific user')
->addOption('user', 'u', InputOption::VALUE_REQUIRED, 'User whose vouchers are counted')
->addOption('redeemed', 'p', InputOption::VALUE_NONE, 'Show count of redeemed vouchers');
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$email = $input->getOption('user');

if (empty($email) || null === $user = $this->manager->getRepository(User::class)->findByEmail($email)) {
throw new UserNotFoundException(sprintf('User with email %s not found!', $email));
}

if (false === $input->getOption('redeemed')) {
$count = $this->manager->getRepository(Voucher::class)->countUnredeemedVouchersByUser($user);
$output->write(sprintf($count));
} else {
$count = $this->manager->getRepository(Voucher::class)->countRedeemedVouchersByUser($user);
$output->write(sprintf($count));
}
return 0;
}
}
23 changes: 23 additions & 0 deletions src/Repository/VoucherRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,29 @@ public function countUnredeemedVouchers(): int
return $this->matching(Criteria::create()->where(Criteria::expr()->eq('redeemedTime', null)))->count();
}


/**
* Returns the number of redeemed vouchers per user.
*/
public function countRedeemedVouchersByUser(User $user): int
{
return $this->matching(Criteria::create()
->where(Criteria::expr()->eq('user', $user))
->andWhere(Criteria::expr()->neq('redeemedTime', null)))
->count();
}

/**
* Returns the number of unredeemed vouchers per user.
*/
public function countUnredeemedVouchersByUser(User $user): int
{
return $this->matching(Criteria::create()
->where(Criteria::expr()->eq('user', $user))
->andWhere(Criteria::expr()->eq('redeemedTime', null)))
->count();
}

/**
* Finds all vouchers for a given user.
*
Expand Down
93 changes: 93 additions & 0 deletions tests/Command/VoucherCountCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

namespace App\Tests\Command;

use App\Command\VoucherCountCommand;
use App\Creator\VoucherCreator;
use App\Entity\User;
use App\Entity\Voucher;
use App\Exception\ValidationException;
use App\Repository\UserRepository;
use App\Repository\VoucherRepository;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Component\Security\Core\Exception\UserNotFoundException;

class VoucherCountCommandTest extends TestCase
{
private VoucherCountCommand $command;
private UserRepository $userRepository;
private VoucherRepository $voucherRepository;

public function setUp(): void
{
$manager = $this->createMock(EntityManagerInterface::class);
$this->repository = $this->createMock(UserRepository::class);
$manager->method('getRepository')->willReturn($this->repository);

$this->command = new VoucherCountCommand($manager);
}

public function testExecuteWithUnknownUser(): void
{
$this->repository->method('findByEmail')
->willReturn(null);

$application = new Application();
$application->add($this->command);

$command = $application->find('app:voucher:count');
$commandTester = new CommandTester($command);

$this->expectException(UserNotFoundException::class);
$commandTester->execute([
'--user' => '[email protected]',
]);

$output = $commandTester->getDisplay();
self::assertStringContainsString('', $output);
}

public function testExecuteWithUser(): void
{
$user = new User();
$user->setEmail('[email protected]');
$this->userRepository->method('findByEmail')
->willReturn($user);

$this->voucherRepository->method('countUnredeemedVouchersByUser')
->willReturn(2);

$this->voucherRepository->method('countRedeemedVouchersByUser')
->willReturn(5);

$application = new Application();
$application->add($this->command);

$command = $application->find('app:voucher:count');
$commandTester = new CommandTester($command);

// Test counting unredeemed vouchers
$commandTester->execute([
'--user' => $user->getEmail(),
]);

$commandTester->assertCommandIsSuccessful();

$output = $commandTester->getDisplay();
$this->assertStringContainsString('2', $output);

// Test counting redeemed vouchers
$commandTester->execute([
'--user' => $user->getEmail(),
'--redeemed',
]);

$commandTester->assertCommandIsSuccessful();

$output = $commandTester->getDisplay();
$this->assertStringContainsString('5', $output);
}
}

0 comments on commit 4b31e1c

Please sign in to comment.