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 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
|
||||
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;
|
||||
|
||||
use App\Contract\ClientDto;
|
||||
use App\Contract\TopUpRequestDto;
|
||||
use App\Entity\Client;
|
||||
use App\Exception\ClientAlreadyExistsException;
|
||||
use App\Service\ClientService;
|
||||
@ -10,6 +11,7 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Attribute\AsController;
|
||||
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
use Symfony\Component\Uid\Uuid;
|
||||
|
||||
#[Route(path: '/clients', name: 'clients_')]
|
||||
#[AsController]
|
||||
@ -37,4 +39,14 @@ readonly class ClientController
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public function topUpBalance(int $amount): void
|
||||
{
|
||||
$this->currentBalance += $amount;
|
||||
}
|
||||
}
|
||||
|
@ -44,9 +44,17 @@ class ClientService
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
$command->client->deduceFromBalance($totalPrice);
|
||||
|
||||
$this->clientService->save($command->client);
|
||||
$this->clientService->deduceFromBalance($command->client, $totalPrice);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -69,31 +69,6 @@ class OrderServiceTest extends TestCase
|
||||
$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()
|
||||
{
|
||||
$command = new AcceptOrderCommand(
|
||||
@ -102,7 +77,7 @@ class OrderServiceTest extends TestCase
|
||||
);
|
||||
|
||||
$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->acceptOrder($command);
|
||||
|
Loading…
Reference in New Issue
Block a user