TASK-39: Add ability to top-up balance of given client
This commit also refactors a bit logic behind deducing from balance to have better separation of concerns.
This commit is contained in:
parent
cbfb10ec10
commit
85a6212ef5
@ -20,6 +20,17 @@ Feature:
|
|||||||
And client with id "018edd37-c145-7143-ba91-c191084e4fba" should exist
|
And client with id "018edd37-c145-7143-ba91-c191084e4fba" should exist
|
||||||
And client with id "018edd37-c145-7143-ba91-c191084e4fba" should have balance of 100000
|
And client with id "018edd37-c145-7143-ba91-c191084e4fba" should have balance of 100000
|
||||||
|
|
||||||
|
Scenario: CRM is able to top up existing client
|
||||||
|
Given the request has the following body:
|
||||||
|
"""
|
||||||
|
{
|
||||||
|
"amount": 5000
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
When I send a POST request to "/clients/018edd2e-894a-78d7-b10c-16e05ca933a3/_top-up"
|
||||||
|
Then the response status should be 200
|
||||||
|
And client with id "018edd2e-894a-78d7-b10c-16e05ca933a3" should have balance of 10000
|
||||||
|
|
||||||
Scenario: CRM should not be able to override existing user
|
Scenario: CRM should not be able to override existing user
|
||||||
Given the request has the following body:
|
Given the request has the following body:
|
||||||
"""
|
"""
|
||||||
|
8
src/Contract/TopUpRequestDto.php
Normal file
8
src/Contract/TopUpRequestDto.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Contract;
|
||||||
|
|
||||||
|
readonly class TopUpRequestDto
|
||||||
|
{
|
||||||
|
public function __construct(public int $amount) {}
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Controller;
|
namespace App\Controller;
|
||||||
|
|
||||||
use App\Contract\ClientDto;
|
use App\Contract\ClientDto;
|
||||||
|
use App\Contract\TopUpRequestDto;
|
||||||
use App\Entity\Client;
|
use App\Entity\Client;
|
||||||
use App\Exception\ClientAlreadyExistsException;
|
use App\Exception\ClientAlreadyExistsException;
|
||||||
use App\Service\ClientService;
|
use App\Service\ClientService;
|
||||||
@ -10,6 +11,7 @@ use Symfony\Component\HttpFoundation\Response;
|
|||||||
use Symfony\Component\HttpKernel\Attribute\AsController;
|
use Symfony\Component\HttpKernel\Attribute\AsController;
|
||||||
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
|
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
use Symfony\Component\Uid\Uuid;
|
||||||
|
|
||||||
#[Route(path: '/clients', name: 'clients_')]
|
#[Route(path: '/clients', name: 'clients_')]
|
||||||
#[AsController]
|
#[AsController]
|
||||||
@ -37,4 +39,14 @@ readonly class ClientController
|
|||||||
|
|
||||||
return new Response(status: Response::HTTP_CREATED);
|
return new Response(status: Response::HTTP_CREATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[Route(path: '/{client}/_top-up', name: 'top_up', methods: ['POST'])]
|
||||||
|
public function topUp(
|
||||||
|
#[MapRequestPayload] TopUpRequestDto $topUpRequestDto,
|
||||||
|
Client $client,
|
||||||
|
): Response {
|
||||||
|
$this->clientService->topUpBalance($client, $topUpRequestDto->amount);
|
||||||
|
|
||||||
|
return new Response();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,4 +61,9 @@ class Client
|
|||||||
{
|
{
|
||||||
$this->currentBalance -= $amount;
|
$this->currentBalance -= $amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function topUpBalance(int $amount): void
|
||||||
|
{
|
||||||
|
$this->currentBalance += $amount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,9 +44,17 @@ class ClientService
|
|||||||
return $this->clientRepository->save($client);
|
return $this->clientRepository->save($client);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function save(Client $client): void
|
public function deduceFromBalance(Client $client, int $amount)
|
||||||
{
|
{
|
||||||
|
$client->deduceFromBalance($amount);
|
||||||
|
|
||||||
$this->clientRepository->save($client);
|
$this->clientRepository->save($client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function topUpBalance(Client $client, int $amount)
|
||||||
|
{
|
||||||
|
$client->topUpBalance($amount);
|
||||||
|
|
||||||
|
$this->clientRepository->save($client);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,10 +24,6 @@ readonly class OrderService
|
|||||||
|
|
||||||
$totalPrice = $command->order->getTotalPrice($this->pricingStrategy);
|
$totalPrice = $command->order->getTotalPrice($this->pricingStrategy);
|
||||||
|
|
||||||
$command->client->deduceFromBalance($totalPrice);
|
$this->clientService->deduceFromBalance($command->client, $totalPrice);
|
||||||
|
|
||||||
$this->clientService->save($command->client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -69,31 +69,6 @@ class OrderServiceTest extends TestCase
|
|||||||
$sut->acceptOrder($order);
|
$sut->acceptOrder($order);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testTotalPriceIsDeducedFromClientBalance()
|
|
||||||
{
|
|
||||||
$initialBalance = 10000_00;
|
|
||||||
$price = 6900_00;
|
|
||||||
|
|
||||||
$command = new AcceptOrderCommand(
|
|
||||||
$order = $this->createValidOrderDto(),
|
|
||||||
$client = $this->createClient($initialBalance),
|
|
||||||
);
|
|
||||||
|
|
||||||
$pricingStrategyMock = $this->createMock(PricingStrategy::class);
|
|
||||||
|
|
||||||
$pricingStrategyMock
|
|
||||||
->expects($this->atLeastOnce())
|
|
||||||
->method('calculateTotalPriceOfOrder')
|
|
||||||
->with($order)
|
|
||||||
->willReturn($price);
|
|
||||||
|
|
||||||
$sut = $this->createOrderService(pricingStrategyMock: $pricingStrategyMock);
|
|
||||||
$sut->acceptOrder($command);
|
|
||||||
|
|
||||||
$this->assertEquals($initialBalance, $client->getInitialBalance(), 'Initial balance got changed after placing order');
|
|
||||||
$this->assertEquals($initialBalance - $price, $client->getBalance(), 'Current balance not changed after placing order');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testClientIsUpdatedAfterPlacingOrder()
|
public function testClientIsUpdatedAfterPlacingOrder()
|
||||||
{
|
{
|
||||||
$command = new AcceptOrderCommand(
|
$command = new AcceptOrderCommand(
|
||||||
@ -102,7 +77,7 @@ class OrderServiceTest extends TestCase
|
|||||||
);
|
);
|
||||||
|
|
||||||
$clientServiceMock = $this->createMock(ClientService::class);
|
$clientServiceMock = $this->createMock(ClientService::class);
|
||||||
$clientServiceMock->expects($this->once())->method('save')->with($client);
|
$clientServiceMock->expects($this->once())->method('deduceFromBalance');
|
||||||
|
|
||||||
$sut = $this->createOrderService(clientServiceMock: $clientServiceMock);
|
$sut = $this->createOrderService(clientServiceMock: $clientServiceMock);
|
||||||
$sut->acceptOrder($command);
|
$sut->acceptOrder($command);
|
||||||
|
Loading…
Reference in New Issue
Block a user