diff --git a/features/crm-user-sync.feature b/features/crm-user-sync.feature new file mode 100644 index 0000000..95d4aea --- /dev/null +++ b/features/crm-user-sync.feature @@ -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 diff --git a/src/Controller/ClientController.php b/src/Controller/ClientController.php new file mode 100644 index 0000000..16cdd3c --- /dev/null +++ b/src/Controller/ClientController.php @@ -0,0 +1,40 @@ +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); + } +} diff --git a/src/Entity/Client.php b/src/Entity/Client.php index c657ae3..1e6d81f 100644 --- a/src/Entity/Client.php +++ b/src/Entity/Client.php @@ -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; diff --git a/src/Exception/ClientAlreadyExistsException.php b/src/Exception/ClientAlreadyExistsException.php new file mode 100644 index 0000000..aa0c6b8 --- /dev/null +++ b/src/Exception/ClientAlreadyExistsException.php @@ -0,0 +1,7 @@ +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; + } } diff --git a/src/Service/ClientService.php b/src/Service/ClientService.php new file mode 100644 index 0000000..c2beaf8 --- /dev/null +++ b/src/Service/ClientService.php @@ -0,0 +1,28 @@ +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); + } +} diff --git a/tests/Behat/ClientsContext.php b/tests/Behat/ClientsContext.php new file mode 100644 index 0000000..4916768 --- /dev/null +++ b/tests/Behat/ClientsContext.php @@ -0,0 +1,82 @@ +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); + } + +}