-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat/i89 ✨ Adiciona suporte para criação e manipulação da entidade De…
…posit Inclui DepositDTO, DepositEntityService e implementação, uma fábrica de depósitos e testes. A implementação adiciona validações para dados do depósito e usa um repositório para persistência.
- Loading branch information
1 parent
689ff88
commit 1554bd2
Showing
5 changed files
with
333 additions
and
0 deletions.
There are no files selected for viewing
37 changes: 37 additions & 0 deletions
37
src/main/java/diegosneves/github/conectardoacoes/adapters/rest/dto/DepositDTO.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package diegosneves.github.conectardoacoes.adapters.rest.dto; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.Setter; | ||
|
||
/** | ||
* A classe {@link DepositDTO} é um Data Transfer Object (DTO) que fornece uma maneira simples de transportar dados entre processos. | ||
* Ele é responsável por representar a entidade "Doação" em operações onde apenas uma transferência de dados simples é necessária, | ||
* sem comportamentos adicionais. | ||
* <p> | ||
* <p>A classe {@link DepositDTO} inclui duas propriedades:</p> | ||
* <ol> | ||
* <li><code>description</code> - Uma string que descreve a doação.</li> | ||
* <li><code>amount</code> - Um inteiro que representa a quantidade da doação.</li> | ||
* </ol> | ||
* <p> | ||
* Ela contém os construtores {@code @AllArgsConstructor} e {@code @NoArgsConstructor}, que permitem a criação de instâncias com todos os atributos ou sem nenhum atributo, respectivamente. | ||
* Além disso, possui os métodos {@code @getter} e {@code @setter} para cada propriedade, permitindo a recuperação e modificação de cada propriedade, respectivamente. | ||
* A anotação {@code @Builder} implementa o padrão <b>Builder</b> para criar objetos da classe de maneira mais legível e segura. | ||
* | ||
* @author diegoneves | ||
* @since 1.3.0 | ||
*/ | ||
@AllArgsConstructor | ||
@NoArgsConstructor | ||
@Getter | ||
@Setter | ||
@Builder | ||
public class DepositDTO { | ||
|
||
private String description; | ||
private Integer amount; | ||
|
||
} |
44 changes: 44 additions & 0 deletions
44
src/main/java/diegosneves/github/conectardoacoes/adapters/rest/factory/DepositFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package diegosneves.github.conectardoacoes.adapters.rest.factory; | ||
|
||
import diegosneves.github.conectardoacoes.adapters.rest.model.DepositEntity; | ||
import diegosneves.github.conectardoacoes.core.utils.UuidUtils; | ||
|
||
/** | ||
* A classe {@code DepositFactory} é responsável por criar instâncias da {@link DepositEntity}. | ||
* <p> | ||
* Esta classe é utilitária e não pode ser instanciada, ou seja, todos os seus métodos são estáticos. | ||
* O principal método desta classe é o {@code createDepositEntity}, que gera uma instância de {@link DepositEntity} | ||
* utilizando um UUID gerado, uma descrição e um valor fornecidos. | ||
* </p> | ||
* <p> | ||
* Uso típico: | ||
* <pre>{@code | ||
* DepositEntity deposit = DepositFactory.createDepositEntity("Depósito de exemplo", 100); | ||
* }</pre> | ||
* | ||
* @author diegoneves | ||
* @since 1.3.0 | ||
* @see DepositEntity | ||
*/ | ||
public class DepositFactory { | ||
|
||
private DepositFactory() { | ||
} | ||
|
||
/** | ||
* Cria uma nova instância de {@link DepositEntity} com uma descrição fornecida e um valor. | ||
* <p> | ||
* Este método gera um novo UUID usando {@link UuidUtils#generateUuid()} e cria uma nova | ||
* instância de {@link DepositEntity} com o UUID gerado, a descrição fornecida e o valor fornecido. | ||
* </p> | ||
* | ||
* @param description Uma {@link String} representando a descrição do depósito. | ||
* @param amount Um {@link Integer} representando o valor do depósito. | ||
* @return A nova instância de {@link DepositEntity} criada com o UUID gerado, a descrição fornecida e o valor fornecido. | ||
* @throws IllegalArgumentException se a descrição ou o valor forem nulos. | ||
*/ | ||
public static DepositEntity createDepositEntity(String description, Integer amount) { | ||
return new DepositEntity(UuidUtils.generateUuid(), description, amount); | ||
} | ||
|
||
} |
27 changes: 27 additions & 0 deletions
27
...n/java/diegosneves/github/conectardoacoes/adapters/rest/service/DepositEntityService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package diegosneves.github.conectardoacoes.adapters.rest.service; | ||
|
||
import diegosneves.github.conectardoacoes.adapters.rest.dto.DepositDTO; | ||
import diegosneves.github.conectardoacoes.adapters.rest.model.DepositEntity; | ||
|
||
/** | ||
* Interface de serviço para operações relacionadas à entidade de depósito. | ||
* <p> | ||
* Esta interface define os métodos necessários para a criação e manipulação | ||
* de objetos do tipo {@link DepositEntity}. | ||
* | ||
* @author diegoneves | ||
* @since 1.3.0 | ||
*/ | ||
public interface DepositEntityService { | ||
|
||
/** | ||
* Cria uma nova instância de {@link DepositEntity} com base nos dados fornecidos | ||
* pelo objeto {@link DepositDTO}. | ||
* | ||
* @param dto Objeto de transferência de dados contendo as informações necessárias | ||
* para a criação de um novo depósito. | ||
* @return A nova instância de {@link DepositEntity} criada com os dados fornecidos. | ||
*/ | ||
DepositEntity create(DepositDTO dto); | ||
|
||
} |
89 changes: 89 additions & 0 deletions
89
...egosneves/github/conectardoacoes/adapters/rest/service/impl/DepositEntityServiceImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package diegosneves.github.conectardoacoes.adapters.rest.service.impl; | ||
|
||
import diegosneves.github.conectardoacoes.adapters.rest.dto.DepositDTO; | ||
import diegosneves.github.conectardoacoes.adapters.rest.exception.DepositEntityFailuresException; | ||
import diegosneves.github.conectardoacoes.adapters.rest.factory.DepositFactory; | ||
import diegosneves.github.conectardoacoes.adapters.rest.model.DepositEntity; | ||
import diegosneves.github.conectardoacoes.adapters.rest.repository.DepositRepository; | ||
import diegosneves.github.conectardoacoes.adapters.rest.service.DepositEntityService; | ||
import diegosneves.github.conectardoacoes.core.utils.ValidationUtils; | ||
import org.springframework.stereotype.Service; | ||
|
||
/** | ||
* Classe de implementação do serviço de entidade de depósito. | ||
* | ||
* <p> | ||
* Esta classe fornece a implementação das operações de criação relacionadas à entidade | ||
* de depósito. Ela utiliza o repositório de depósitos ({@link DepositRepository}) | ||
* para salvar a nova entidade de depósito criada. | ||
* </p> | ||
* | ||
* <p> | ||
* A constante {@code DEPOSIT_VALIDATION_ERROR} representa um código específico de erro | ||
* de validação dos depósitos. | ||
* </p> | ||
* | ||
* <p> | ||
* As operações de criação de depósitos utilizam a fábrica de depósitos | ||
* ({@link DepositFactory}) para instanciar novos objetos de depósito a partir dos dados | ||
* de transferência (DTO - Data Transfer Object). | ||
* </p> | ||
* | ||
* <p> | ||
* Esta classe é anotada com {@code @Service} para indicar que é um componente de serviço | ||
* Spring, tornando-a detectável para a injeção de dependência. | ||
* </p> | ||
* | ||
* @author diegoneves | ||
* @see DepositEntityService | ||
* @see DepositRepository | ||
* @see DepositFactory | ||
* @since 1.3.0 | ||
*/ | ||
@Service | ||
public class DepositEntityServiceImpl implements DepositEntityService { | ||
|
||
private static final int DEFAULT_AMOUNT = 1; | ||
public static final Integer DEPOSIT_VALIDATION_ERROR = 39; | ||
|
||
private final DepositRepository depositRepository; | ||
|
||
public DepositEntityServiceImpl(DepositRepository depositRepository) { | ||
this.depositRepository = depositRepository; | ||
} | ||
|
||
@Override | ||
public DepositEntity create(DepositDTO dto) { | ||
depositValidate(dto); | ||
DepositEntity newDeposit = DepositFactory.createDepositEntity(dto.getDescription(), dto.getAmount()); | ||
return this.depositRepository.save(newDeposit); | ||
} | ||
|
||
/** | ||
* Valida o objeto {@link DepositDTO} para garantir que está devidamente populado | ||
* e contém dados válidos. | ||
* <p> | ||
* A validação inclui a verificação se o DTO e seus campos de descrição e valor | ||
* não são nulos ou vazios. Também garante que o valor não seja menor que o valor | ||
* padrão, atualizando-o se necessário. | ||
* </p> | ||
* | ||
* @param dto o objeto {@link DepositDTO} a ser validado. | ||
* Não deve ser nulo e deve conter uma descrição e um valor não nulos/não vazios. | ||
* @throws DepositEntityFailuresException se algum dos campos (dto, descrição, valor) | ||
* forem nulos ou vazios. | ||
* @implNote O método {@link ValidationUtils#validateNotNullOrEmpty(Object, Integer, Class)} é utilizado | ||
* para realizar as verificações de validação, lançando a exceção {@link DepositEntityFailuresException} | ||
* com o código de erro específico {@code DEPOSIT_VALIDATION_ERROR} se alguma regra de validação for violada. | ||
*/ | ||
private static void depositValidate(DepositDTO dto) { | ||
ValidationUtils.validateNotNullOrEmpty(dto, DEPOSIT_VALIDATION_ERROR, DepositEntityFailuresException.class); | ||
ValidationUtils.validateNotNullOrEmpty(dto.getDescription(), DEPOSIT_VALIDATION_ERROR, DepositEntityFailuresException.class); | ||
ValidationUtils.validateNotNullOrEmpty(dto.getAmount(), DEPOSIT_VALIDATION_ERROR, DepositEntityFailuresException.class); | ||
if (dto.getAmount() < DEFAULT_AMOUNT) { | ||
dto.setAmount(DEFAULT_AMOUNT); | ||
} | ||
} | ||
|
||
|
||
} |
136 changes: 136 additions & 0 deletions
136
...neves/github/conectardoacoes/adapters/rest/service/impl/DepositEntityServiceImplTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
package diegosneves.github.conectardoacoes.adapters.rest.service.impl; | ||
|
||
import diegosneves.github.conectardoacoes.adapters.rest.dto.DepositDTO; | ||
import diegosneves.github.conectardoacoes.adapters.rest.enums.ExceptionDetails; | ||
import diegosneves.github.conectardoacoes.adapters.rest.exception.DepositEntityFailuresException; | ||
import diegosneves.github.conectardoacoes.adapters.rest.model.DepositEntity; | ||
import diegosneves.github.conectardoacoes.adapters.rest.repository.DepositRepository; | ||
import diegosneves.github.conectardoacoes.core.utils.UuidUtils; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.ExtendWith; | ||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.ValueSource; | ||
import org.mockito.ArgumentCaptor; | ||
import org.mockito.Captor; | ||
import org.mockito.InjectMocks; | ||
import org.mockito.Mock; | ||
import org.springframework.test.context.junit.jupiter.SpringExtension; | ||
|
||
import static org.junit.jupiter.api.Assertions.*; | ||
import static org.mockito.ArgumentMatchers.any; | ||
import static org.mockito.Mockito.never; | ||
import static org.mockito.Mockito.times; | ||
import static org.mockito.Mockito.verify; | ||
import static org.mockito.Mockito.when; | ||
|
||
@ExtendWith(SpringExtension.class) | ||
class DepositEntityServiceImplTest { | ||
|
||
public static final String DEPOSIT_UUID = "0f46f5b9-ab37-478b-86f5-b9ab37878b33"; | ||
public static final String DESCRIPTION = "Item 01"; | ||
public static final int AMOUNT = 1; | ||
|
||
|
||
@InjectMocks | ||
private DepositEntityServiceImpl service; | ||
|
||
@Mock | ||
private DepositRepository repository; | ||
|
||
@Captor | ||
private ArgumentCaptor<DepositEntity> depositCaptor; | ||
|
||
private DepositDTO depositDTO; | ||
private DepositEntity depositEntity; | ||
|
||
@BeforeEach | ||
void setUp() { | ||
this.depositDTO = new DepositDTO(DESCRIPTION, AMOUNT); | ||
this.depositEntity = new DepositEntity(DEPOSIT_UUID, DESCRIPTION, AMOUNT); | ||
} | ||
|
||
@Test | ||
void shouldCreateAndSaveDepositEntitySuccessfully() { | ||
when(this.repository.save(any(DepositEntity.class))).thenReturn(this.depositEntity); | ||
|
||
DepositEntity actual = this.service.create(this.depositDTO); | ||
|
||
verify(this.repository, times(1)).save(this.depositCaptor.capture()); | ||
|
||
assertNotNull(actual); | ||
assertEquals(DEPOSIT_UUID, actual.getId()); | ||
assertEquals(DESCRIPTION, actual.getDescription()); | ||
assertEquals(AMOUNT, actual.getAmount()); | ||
DepositEntity capturedDeposit = this.depositCaptor.getValue(); | ||
assertNotNull(capturedDeposit); | ||
assertNotNull(capturedDeposit.getId()); | ||
assertTrue(UuidUtils.isValidUUID(capturedDeposit.getId())); | ||
assertEquals(DESCRIPTION, capturedDeposit.getDescription()); | ||
assertEquals(AMOUNT, capturedDeposit.getAmount()); | ||
} | ||
|
||
@ParameterizedTest | ||
@ValueSource(ints = {0, -3, -58}) | ||
void shouldSetMinimumAmountAndSaveDepositEntityWhenInvalidAmountProvided(Integer value) { | ||
this.depositDTO.setAmount(value); | ||
when(this.repository.save(any(DepositEntity.class))).thenReturn(this.depositEntity); | ||
|
||
DepositEntity actual = this.service.create(this.depositDTO); | ||
|
||
verify(this.repository, times(1)).save(this.depositCaptor.capture()); | ||
|
||
assertNotNull(actual); | ||
assertEquals(DEPOSIT_UUID, actual.getId()); | ||
assertEquals(DESCRIPTION, actual.getDescription()); | ||
assertEquals(AMOUNT, actual.getAmount()); | ||
DepositEntity capturedDeposit = this.depositCaptor.getValue(); | ||
assertNotNull(capturedDeposit); | ||
assertNotNull(capturedDeposit.getId()); | ||
assertTrue(UuidUtils.isValidUUID(capturedDeposit.getId())); | ||
assertEquals(DESCRIPTION, capturedDeposit.getDescription()); | ||
assertEquals(AMOUNT, capturedDeposit.getAmount()); | ||
} | ||
|
||
@Test | ||
void shouldThrowExceptionWhenDescriptionIsNull(){ | ||
this.depositDTO.setDescription(null); | ||
|
||
DepositEntityFailuresException exception = assertThrows(DepositEntityFailuresException.class, () -> this.service.create(this.depositDTO)); | ||
|
||
verify(repository, never()).save(any(DepositEntity.class)); | ||
|
||
assertNotNull(exception); | ||
assertEquals(ExceptionDetails.getExceptionDetails(DepositEntityServiceImpl.DEPOSIT_VALIDATION_ERROR).formatErrorMessage(), exception.getMessage()); | ||
assertNull(exception.getCause()); | ||
} | ||
|
||
@ParameterizedTest | ||
@ValueSource(strings = {"", " "}) | ||
void shouldThrowExceptionWhenDescriptionIsEmptyOrBlank(String value){ | ||
this.depositDTO.setDescription(value); | ||
|
||
DepositEntityFailuresException exception = assertThrows(DepositEntityFailuresException.class, () -> this.service.create(this.depositDTO)); | ||
|
||
verify(repository, never()).save(any(DepositEntity.class)); | ||
|
||
assertNotNull(exception); | ||
assertEquals(ExceptionDetails.getExceptionDetails(DepositEntityServiceImpl.DEPOSIT_VALIDATION_ERROR).formatErrorMessage(), exception.getMessage()); | ||
assertNull(exception.getCause()); | ||
} | ||
|
||
@Test | ||
void shouldThrowExceptionWhenAmountIsNull(){ | ||
this.depositDTO.setAmount(null); | ||
|
||
DepositEntityFailuresException exception = assertThrows(DepositEntityFailuresException.class, () -> this.service.create(this.depositDTO)); | ||
|
||
verify(repository, never()).save(any(DepositEntity.class)); | ||
|
||
assertNotNull(exception); | ||
assertEquals(ExceptionDetails.getExceptionDetails(DepositEntityServiceImpl.DEPOSIT_VALIDATION_ERROR).formatErrorMessage(), exception.getMessage()); | ||
assertNull(exception.getCause()); | ||
} | ||
|
||
|
||
} |