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]
 |         #[ORM\Column]
 | ||||||
|         private ?string $name = null, |         private ?string $name = null, | ||||||
| 
 | 
 | ||||||
|  |         #[ORM\Column]
 | ||||||
|  |         private ?int $initialBalance = null, | ||||||
|  | 
 | ||||||
|         #[ORM\Column]
 |         #[ORM\Column]
 | ||||||
|         private ?int $currentBalance = null, |         private ?int $currentBalance = null, | ||||||
|     ) { |     ) { | ||||||
|  |         $this->currentBalance ??= $this->initialBalance; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public function getClientId(): ?Uuid |     public function getClientId(): ?Uuid | ||||||
| @ -38,6 +42,16 @@ class Client | |||||||
|         $this->name = $name; |         $this->name = $name; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public function getInitialBalance(): ?int | ||||||
|  |     { | ||||||
|  |         return $this->initialBalance; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function setInitialBalance(?int $initialBalance): void | ||||||
|  |     { | ||||||
|  |         $this->initialBalance = $initialBalance; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public function getBalance(): ?int |     public function getBalance(): ?int | ||||||
|     { |     { | ||||||
|         return $this->currentBalance; |         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); |         parent::__construct($registry, Client::class); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     //    /**
 |     public function save(Client $client): Client | ||||||
|     //     * @return Client[] Returns an array of Client objects
 |     { | ||||||
|     //     */
 |         $this->getEntityManager()->persist($client); | ||||||
|     //    public function findByExampleField($value): array
 |         $this->getEntityManager()->flush(); | ||||||
|     //    {
 |  | ||||||
|     //        return $this->createQueryBuilder('c')
 |  | ||||||
|     //            ->andWhere('c.exampleField = :val')
 |  | ||||||
|     //            ->setParameter('val', $value)
 |  | ||||||
|     //            ->orderBy('c.id', 'ASC')
 |  | ||||||
|     //            ->setMaxResults(10)
 |  | ||||||
|     //            ->getQuery()
 |  | ||||||
|     //            ->getResult()
 |  | ||||||
|     //        ;
 |  | ||||||
|     //    }
 |  | ||||||
| 
 | 
 | ||||||
|     //    public function findOneBySomeField($value): ?Client
 |         return $client; | ||||||
|     //    {
 |     } | ||||||
|     //        return $this->createQueryBuilder('c')
 |  | ||||||
|     //            ->andWhere('c.exampleField = :val')
 |  | ||||||
|     //            ->setParameter('val', $value)
 |  | ||||||
|     //            ->getQuery()
 |  | ||||||
|     //            ->getOneOrNullResult()
 |  | ||||||
|     //        ;
 |  | ||||||
|     //    }
 |  | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										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