TASK-37: Add ability to accept new clients from CRM
This commit is contained in:
		
							parent
							
								
									8a3068419e
								
							
						
					
					
						commit
						d6fdec2a8b
					
				
							
								
								
									
										34
									
								
								features/crm-user-sync.feature
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								features/crm-user-sync.feature
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| Feature: | ||||
|   The CRM system is able to send information about new Clients to the service | ||||
| 
 | ||||
|   Background: | ||||
|     Given there exist following clients: | ||||
|       | clientId                             | name   | initialBalance | currentBalance | | ||||
|       | 018edd2e-894a-78d7-b10c-16e05ca933a3 | Kacper | 10000          | 5000           | | ||||
| 
 | ||||
|   Scenario: CRM is able to create new clients | ||||
|     Given the request has the following body: | ||||
|       """ | ||||
|       { | ||||
|         "clientId": "018edd37-c145-7143-ba91-c191084e4fba", | ||||
|         "name": "Jan", | ||||
|         "balance": 100000 | ||||
|       } | ||||
|       """ | ||||
|     When I send a POST request to "/clients" | ||||
|     Then the response status should be 201 | ||||
|     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 should not be able to override existing user | ||||
|     Given the request has the following body: | ||||
|       """ | ||||
|       { | ||||
|         "clientId": "018edd2e-894a-78d7-b10c-16e05ca933a3", | ||||
|         "name": "Kacper", | ||||
|         "balance": 100000 | ||||
|       } | ||||
|       """ | ||||
|     When I send a POST request to "/clients" | ||||
|     Then the response status should be 409 | ||||
|     And client with id "018edd2e-894a-78d7-b10c-16e05ca933a3" should exist | ||||
							
								
								
									
										40
									
								
								src/Controller/ClientController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/Controller/ClientController.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | ||||
| <?php | ||||
| 
 | ||||
| namespace App\Controller; | ||||
| 
 | ||||
| use App\Contract\ClientDto; | ||||
| use App\Entity\Client; | ||||
| use App\Exception\ClientAlreadyExistsException; | ||||
| use App\Service\ClientService; | ||||
| use Symfony\Component\HttpFoundation\Response; | ||||
| use Symfony\Component\HttpKernel\Attribute\AsController; | ||||
| use Symfony\Component\HttpKernel\Attribute\MapRequestPayload; | ||||
| use Symfony\Component\Routing\Attribute\Route; | ||||
| 
 | ||||
| #[Route(path: '/clients', name: 'clients_')]
 | ||||
| #[AsController]
 | ||||
| readonly class ClientController | ||||
| { | ||||
|     public function __construct( | ||||
|         private ClientService $clientService, | ||||
|     ) { | ||||
|     } | ||||
| 
 | ||||
|     #[Route(name: 'create', methods: ['POST'])]
 | ||||
|     public function create(#[MapRequestPayload] ClientDto $clientDto): Response
 | ||||
|     { | ||||
|         $client = new Client( | ||||
|             clientId: $clientDto->getClientId(), | ||||
|             name: $clientDto->getName(), | ||||
|             initialBalance: $clientDto->getBalance(), | ||||
|         ); | ||||
| 
 | ||||
|         try { | ||||
|             $this->clientService->createNewClient($client); | ||||
|         } catch (ClientAlreadyExistsException) { | ||||
|             return new Response(status: Response::HTTP_CONFLICT); | ||||
|         } | ||||
| 
 | ||||
|         return new Response(status: Response::HTTP_CREATED); | ||||
|     } | ||||
| } | ||||
| @ -18,9 +18,13 @@ class Client | ||||
|         #[ORM\Column]
 | ||||
|         private ?string $name = null, | ||||
| 
 | ||||
|         #[ORM\Column]
 | ||||
|         private ?int $initialBalance = null, | ||||
| 
 | ||||
|         #[ORM\Column]
 | ||||
|         private ?int $currentBalance = null, | ||||
|     ) { | ||||
|         $this->currentBalance ??= $this->initialBalance; | ||||
|     } | ||||
| 
 | ||||
|     public function getClientId(): ?Uuid | ||||
| @ -38,6 +42,16 @@ class Client | ||||
|         $this->name = $name; | ||||
|     } | ||||
| 
 | ||||
|     public function getInitialBalance(): ?int | ||||
|     { | ||||
|         return $this->initialBalance; | ||||
|     } | ||||
| 
 | ||||
|     public function setInitialBalance(?int $initialBalance): void | ||||
|     { | ||||
|         $this->initialBalance = $initialBalance; | ||||
|     } | ||||
| 
 | ||||
|     public function getBalance(): ?int | ||||
|     { | ||||
|         return $this->currentBalance; | ||||
|  | ||||
							
								
								
									
										7
									
								
								src/Exception/ClientAlreadyExistsException.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/Exception/ClientAlreadyExistsException.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| <?php | ||||
| 
 | ||||
| namespace App\Exception; | ||||
| 
 | ||||
| class ClientAlreadyExistsException extends \LogicException | ||||
| { | ||||
| } | ||||
| @ -21,28 +21,11 @@ class ClientRepository extends ServiceEntityRepository | ||||
|         parent::__construct($registry, Client::class); | ||||
|     } | ||||
| 
 | ||||
|     //    /**
 | ||||
|     //     * @return Client[] Returns an array of Client objects
 | ||||
|     //     */
 | ||||
|     //    public function findByExampleField($value): array
 | ||||
|     //    {
 | ||||
|     //        return $this->createQueryBuilder('c')
 | ||||
|     //            ->andWhere('c.exampleField = :val')
 | ||||
|     //            ->setParameter('val', $value)
 | ||||
|     //            ->orderBy('c.id', 'ASC')
 | ||||
|     //            ->setMaxResults(10)
 | ||||
|     //            ->getQuery()
 | ||||
|     //            ->getResult()
 | ||||
|     //        ;
 | ||||
|     //    }
 | ||||
|     public function save(Client $client): Client | ||||
|     { | ||||
|         $this->getEntityManager()->persist($client); | ||||
|         $this->getEntityManager()->flush(); | ||||
| 
 | ||||
|     //    public function findOneBySomeField($value): ?Client
 | ||||
|     //    {
 | ||||
|     //        return $this->createQueryBuilder('c')
 | ||||
|     //            ->andWhere('c.exampleField = :val')
 | ||||
|     //            ->setParameter('val', $value)
 | ||||
|     //            ->getQuery()
 | ||||
|     //            ->getOneOrNullResult()
 | ||||
|     //        ;
 | ||||
|     //    }
 | ||||
|         return $client; | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										28
									
								
								src/Service/ClientService.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/Service/ClientService.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | ||||
| <?php | ||||
| 
 | ||||
| namespace App\Service; | ||||
| 
 | ||||
| use App\Entity\Client; | ||||
| use App\Exception\ClientAlreadyExistsException; | ||||
| use App\Repository\ClientRepository; | ||||
| 
 | ||||
| class ClientService | ||||
| { | ||||
|     public function __construct( | ||||
|         public readonly ClientRepository $clientRepository | ||||
|     ) { | ||||
|     } | ||||
| 
 | ||||
|     public function createNewClient(Client $client): Client | ||||
|     { | ||||
|         $existing = $this->clientRepository->find($client->getClientId()); | ||||
| 
 | ||||
|         if ($existing !== null) { | ||||
|             throw new ClientAlreadyExistsException( | ||||
|                 message: sprintf('Client with id "%s" already exists.', $client->getClientId()->toRfc4122()) | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         return $this->clientRepository->save($client); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										82
									
								
								tests/Behat/ClientsContext.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								tests/Behat/ClientsContext.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,82 @@ | ||||
| <?php | ||||
| 
 | ||||
| namespace App\Tests\Behat; | ||||
| 
 | ||||
| use App\Entity\Client; | ||||
| use App\Repository\ClientRepository; | ||||
| use Behat\Behat\Context\Context; | ||||
| use Behat\Behat\Tester\Exception\PendingException; | ||||
| use Behat\Gherkin\Node\TableNode; | ||||
| use Doctrine\ORM\EntityManagerInterface; | ||||
| use PHPUnit\Framework\Assert; | ||||
| use Symfony\Component\Uid\Uuid; | ||||
| 
 | ||||
| class ClientsContext implements Context | ||||
| { | ||||
|     private array $clients; | ||||
| 
 | ||||
|     public function __construct( | ||||
|         protected readonly ClientRepository $clientRepository, | ||||
|     ) {} | ||||
| 
 | ||||
|     /** | ||||
|      * @BeforeScenario | ||||
|      */ | ||||
|     public function clean() | ||||
|     { | ||||
|         $this->clientRepository | ||||
|             ->createQueryBuilder('c') | ||||
|             ->delete() | ||||
|             ->getQuery() | ||||
|             ->execute(); | ||||
| 
 | ||||
|         $this->clients = []; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @Given /^there exist following clients:$/ | ||||
|      */ | ||||
|     public function thereExistFollowingClients(TableNode $table) | ||||
|     { | ||||
|         foreach ($table as $row) { | ||||
|             $client = $this->getClient($row['clientId']); | ||||
| 
 | ||||
|             if (!$client) { | ||||
|                 $client = new Client( | ||||
|                     clientId: Uuid::fromRfc4122($row['clientId']), | ||||
|                     name: $row['name'], | ||||
|                     initialBalance: intval($row['initialBalance']), | ||||
|                     currentBalance: intval($row['currentBalance']), | ||||
|                 ); | ||||
| 
 | ||||
|                 $this->clientRepository->save($client); | ||||
|             } | ||||
| 
 | ||||
|             $this->clients[$client->getClientId()->toRfc4122()] = $client; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public function getClient(string $id): ?Client | ||||
|     { | ||||
|         return $this->clients[$id] ??= $this->clientRepository->find(Uuid::fromRfc4122($id)); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @Given /^client with id "([^"]+)" should exist$/
 | ||||
|      */ | ||||
|     public function clientWithIdShouldExist(string $clientId) | ||||
|     { | ||||
|         Assert::assertNotNull($this->getClient($clientId)); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @Given /^client with id "([^"]+)" should have balance of (\d+)$/
 | ||||
|      */ | ||||
|     public function clientWithIdShouldHaveBalanceOf(string $clientId, int $balance) | ||||
|     { | ||||
|         $client = $this->getClient($clientId); | ||||
| 
 | ||||
|         Assert::assertEquals($client->getBalance(), $balance); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user