diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/clients/IbgeClient.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/clients/IbgeClient.java index 57baeeaf..01cc27b8 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/clients/IbgeClient.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/clients/IbgeClient.java @@ -1,8 +1,8 @@ package com.pointtils.pointtils.src.application.clients; -import com.pointtils.pointtils.src.application.dto.CityIbgeResponseDTO; +import com.pointtils.pointtils.src.application.dto.responses.CityIbgeResponseDTO; import com.pointtils.pointtils.src.application.dto.StateDataDTO; -import com.pointtils.pointtils.src.application.dto.StateIbgeResponseDTO; +import com.pointtils.pointtils.src.application.dto.responses.StateIbgeResponseDTO; import com.pointtils.pointtils.src.core.domain.exceptions.ClientTimeoutException; import jakarta.persistence.EntityNotFoundException; import lombok.extern.slf4j.Slf4j; diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/AuthController.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/AuthController.java index ed25472a..92e04a75 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/AuthController.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/AuthController.java @@ -8,10 +8,10 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import com.pointtils.pointtils.src.application.dto.LoginRequestDTO; -import com.pointtils.pointtils.src.application.dto.LoginResponseDTO; -import com.pointtils.pointtils.src.application.dto.RefreshTokenRequestDTO; -import com.pointtils.pointtils.src.application.dto.RefreshTokenResponseDTO; +import com.pointtils.pointtils.src.application.dto.requests.LoginRequestDTO; +import com.pointtils.pointtils.src.application.dto.responses.LoginResponseDTO; +import com.pointtils.pointtils.src.application.dto.requests.RefreshTokenRequestDTO; +import com.pointtils.pointtils.src.application.dto.responses.RefreshTokenResponseDTO; import com.pointtils.pointtils.src.application.services.AuthService; import com.pointtils.pointtils.src.core.domain.exceptions.AuthenticationException; import com.pointtils.pointtils.src.infrastructure.configs.LoginAttemptService; diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/EnterpriseController.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/EnterpriseController.java index 011b5747..305d5502 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/EnterpriseController.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/EnterpriseController.java @@ -25,7 +25,7 @@ import java.util.UUID; @RestController -@RequestMapping("/v1/enterprise-users") +@RequestMapping("/v1/enterprises") @AllArgsConstructor @Tag(name = "Enterprise Controller", description = "Endpoints para gerenciamento de usuários empresa") public class EnterpriseController { @@ -58,10 +58,10 @@ public ResponseEntity> findById(@PathVariable @PatchMapping("/{id}") @SecurityRequirement(name = "bearerAuth") @Operation(summary = "Atualiza um usuário empresa por ID") - public ResponseEntity updateUser(@PathVariable UUID id, - @RequestBody @Valid EnterprisePatchRequestDTO dto) { + public ResponseEntity> updateUser(@PathVariable UUID id, + @RequestBody @Valid EnterprisePatchRequestDTO dto) { EnterpriseResponseDTO updated = service.patchEnterprise(id, dto); - return ResponseEntity.ok(updated); + return ResponseEntity.ok(ApiResponse.success("Empresa atualizada com sucesso", updated)); } @DeleteMapping("/{id}") diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/InterpreterController.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/InterpreterController.java index 3e5e8a5f..281043a8 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/InterpreterController.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/InterpreterController.java @@ -4,7 +4,7 @@ import com.pointtils.pointtils.src.application.dto.requests.InterpreterPatchRequestDTO; import com.pointtils.pointtils.src.application.dto.responses.ApiResponse; import com.pointtils.pointtils.src.application.dto.responses.InterpreterResponseDTO; -import com.pointtils.pointtils.src.application.services.InterpreterRegisterService; +import com.pointtils.pointtils.src.application.services.InterpreterService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; @@ -30,7 +30,7 @@ @Tag(name = "Interpreter Controller", description = "Endpoints para gerenciamento de usuários intérprete") public class InterpreterController { - private final InterpreterRegisterService service; + private final InterpreterService service; @PostMapping("/register") @Operation(summary = "Cadastra um usuário intérprete") @@ -67,7 +67,6 @@ public ResponseEntity> updateUser(@PathVaria return ResponseEntity.ok(ApiResponse.success("Intérprete atualizado com sucesso", updated)); } - @DeleteMapping("/{id}") @SecurityRequirement(name = "bearerAuth") @Operation(summary = "Deleta um usuário intérprete por ID") diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/JwtController.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/JwtController.java index 8fa7dbb4..f3606175 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/JwtController.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/JwtController.java @@ -1,6 +1,12 @@ package com.pointtils.pointtils.src.application.controllers; -import org.springframework.beans.factory.annotation.Autowired; +import com.pointtils.pointtils.src.application.dto.TokensDTO; +import com.pointtils.pointtils.src.application.dto.requests.RefreshTokenRequestDTO; +import com.pointtils.pointtils.src.application.dto.responses.RefreshTokenResponseDTO; +import com.pointtils.pointtils.src.infrastructure.configs.JwtService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -9,21 +15,12 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.pointtils.pointtils.src.application.dto.RefreshTokenRequestDTO; -import com.pointtils.pointtils.src.application.dto.RefreshTokenResponseDTO; -import com.pointtils.pointtils.src.application.dto.TokensDTO; -import com.pointtils.pointtils.src.infrastructure.configs.JwtService; - -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; - @RestController +@RequiredArgsConstructor @RequestMapping("/api/jwt") @Tag(name = "JWT Controller", description = "Endpoints para geração e teste de tokens JWT") public class JwtController { - - @Autowired - private JwtService jwtService; + private final JwtService jwtService; @GetMapping("/public") @Operation(summary = "Gera um token de acesso público") @@ -57,11 +54,11 @@ public ResponseEntity refreshToken(@RequestBody Refresh if (request.getRefreshToken() == null || request.getRefreshToken().isBlank()) { throw new com.pointtils.pointtils.src.core.domain.exceptions.AuthenticationException("Refresh token não fornecido"); } - + if (!jwtService.isTokenValid(request.getRefreshToken())) { throw new com.pointtils.pointtils.src.core.domain.exceptions.AuthenticationException("Refresh token inválido ou expirado"); } - + String username = jwtService.getEmailFromToken(request.getRefreshToken()); String newAccessToken = jwtService.generateToken(username); String newRefreshToken = jwtService.generateRefreshToken(username); diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/PersonController.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/PersonController.java index e83a117b..d13aae90 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/PersonController.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/PersonController.java @@ -1,6 +1,6 @@ package com.pointtils.pointtils.src.application.controllers; -import com.pointtils.pointtils.src.application.dto.PersonCreationDTO; +import com.pointtils.pointtils.src.application.dto.requests.PersonCreationRequestDTO; import com.pointtils.pointtils.src.application.dto.PersonDTO; import com.pointtils.pointtils.src.application.dto.requests.PersonPatchRequestDTO; import com.pointtils.pointtils.src.application.dto.responses.ApiResponse; @@ -34,7 +34,7 @@ public class PersonController { @PostMapping("/register") @Operation(summary = "Cadastra um usuário surdo") - public ResponseEntity> createUser(@Valid @RequestBody PersonCreationDTO dto) { + public ResponseEntity> createUser(@Valid @RequestBody PersonCreationRequestDTO dto) { PersonDTO created = service.registerPerson(dto); ApiResponse response = ApiResponse.success("Usuário surdo cadastrado com sucesso", created); return ResponseEntity.status(HttpStatus.CREATED).body(response); diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/SpecialtyController.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/SpecialtyController.java index 31346f3a..f5833983 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/SpecialtyController.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/SpecialtyController.java @@ -1,9 +1,12 @@ package com.pointtils.pointtils.src.application.controllers; -import java.util.List; -import java.util.UUID; +import com.pointtils.pointtils.src.application.dto.requests.UpdateSpecialtyRequestDTO; +import com.pointtils.pointtils.src.application.services.SpecialtyService; +import com.pointtils.pointtils.src.core.domain.entities.Specialty; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; @@ -16,11 +19,9 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.pointtils.pointtils.src.application.dto.UpdateSpecialtyRequestDTO; -import com.pointtils.pointtils.src.application.services.SpecialtyService; -import com.pointtils.pointtils.src.core.domain.entities.Specialty; -import io.swagger.v3.oas.annotations.security.SecurityRequirement; -import lombok.RequiredArgsConstructor; + +import java.util.List; +import java.util.UUID; @RestController @RequestMapping("/v1/specialties") @@ -28,57 +29,53 @@ @SecurityRequirement(name = "bearerAuth") @Tag(name = "Specialty Controller", description = "Endpoints para gerenciamento de especialidades") public class SpecialtyController { - + private final SpecialtyService specialtyService; - + @GetMapping @Operation(summary = "Obtém todas as especialidades") public ResponseEntity> getAllSpecialties() { - try { - List specialties = specialtyService.getAllSpecialties(); - return ResponseEntity.ok(specialties); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); - } + List specialties = specialtyService.getAllSpecialties(); + return ResponseEntity.ok(specialties); } - + @GetMapping("/{id}") @Operation(summary = "Busca uma especialidades por ID") public ResponseEntity getSpecialtyById(@PathVariable UUID id) { Specialty specialty = specialtyService.getSpecialtyById(id); return ResponseEntity.ok(specialty); } - + @GetMapping("/search") @Operation(summary = "Busca especialidades por nome") public ResponseEntity> searchSpecialtiesByName(@RequestParam String name) { List specialties = specialtyService.searchSpecialtiesByName(name); return ResponseEntity.ok(specialties); } - + @PostMapping @Operation(summary = "Cria uma especialidade") public ResponseEntity createSpecialty(@RequestParam String name) { Specialty specialty = specialtyService.createSpecialty(name); return ResponseEntity.status(HttpStatus.CREATED).body(specialty); } - + @PutMapping("/{id}") @Operation(summary = "Atualiza uma especialidade por ID") public ResponseEntity updateSpecialty(@PathVariable UUID id, @RequestParam String name) { Specialty specialty = specialtyService.updateSpecialty(id, name); return ResponseEntity.ok(specialty); } - + @PatchMapping("/{id}") @Operation(summary = "Atualiza parcialmente uma especialidade por ID") public ResponseEntity partialUpdateSpecialty( - @PathVariable UUID id, + @PathVariable UUID id, @RequestBody UpdateSpecialtyRequestDTO request) { Specialty specialty = specialtyService.partialUpdateSpecialty(id, request.getName()); return ResponseEntity.ok(specialty); } - + @DeleteMapping("/{id}") @Operation(summary = "Deleta uma especialidade por ID") public ResponseEntity deleteSpecialty(@PathVariable UUID id) { diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/StateController.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/StateController.java index 6e615254..d53376a4 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/StateController.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/StateController.java @@ -1,6 +1,6 @@ package com.pointtils.pointtils.src.application.controllers; -import com.pointtils.pointtils.src.application.dto.StateResponseDTO; +import com.pointtils.pointtils.src.application.dto.responses.StateResponseDTO; import com.pointtils.pointtils.src.application.services.StateService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.security.SecurityRequirement; diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/UserSpecialtyController.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/UserSpecialtyController.java index 413fe52b..aa2c5fbd 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/UserSpecialtyController.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/UserSpecialtyController.java @@ -3,8 +3,8 @@ import java.util.List; import java.util.UUID; -import com.pointtils.pointtils.src.application.dto.AddUserSpecialtiesRequestDTO; -import com.pointtils.pointtils.src.application.dto.UserSpecialtiesResponseDTO; +import com.pointtils.pointtils.src.application.dto.requests.AddUserSpecialtiesRequestDTO; +import com.pointtils.pointtils.src.application.dto.responses.UserSpecialtiesResponseDTO; import com.pointtils.pointtils.src.application.dto.UserSpecialtyDTO; import com.pointtils.pointtils.src.application.services.UserSpecialtyService; import com.pointtils.pointtils.src.core.domain.entities.UserSpecialty; diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/LocationDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/LocationDTO.java index 45d66677..b4dd0c96 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/LocationDTO.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/LocationDTO.java @@ -1,6 +1,5 @@ package com.pointtils.pointtils.src.application.dto; -import jakarta.validation.constraints.NotBlank; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -21,15 +20,7 @@ public class LocationDTO { private UUID id; - - @NotBlank(message = "UF deve ser preenchida") private String uf; - - @NotBlank(message = "Cidade deve ser preenchida") private String city; - - public LocationDTO(String uf, String city) { - this.uf = uf; - this.city = city; - } + private String neighborhood; } diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/UserDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/UserDTO.java index 1fff8990..c0c4f1e6 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/UserDTO.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/UserDTO.java @@ -6,6 +6,7 @@ import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Data; @@ -18,11 +19,12 @@ public class UserDTO { private UUID id; - @Email(message = "Formato de e-mail inválido") + @Email(message = "Email inválido") @NotBlank(message = "O e-mail é obrigatório") private String email; @Size(max = 11, message = "O telefone deve ter no máximo 11 dígitos") + @Pattern(regexp = "^\\d+$", message = "Número de telefone inválido") private String phone; private String picture; diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/AddUserSpecialtiesRequestDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/AddUserSpecialtiesRequestDTO.java similarity index 83% rename from pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/AddUserSpecialtiesRequestDTO.java rename to pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/AddUserSpecialtiesRequestDTO.java index 65375109..ef24bf83 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/AddUserSpecialtiesRequestDTO.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/AddUserSpecialtiesRequestDTO.java @@ -1,4 +1,4 @@ -package com.pointtils.pointtils.src.application.dto; +package com.pointtils.pointtils.src.application.dto.requests; import java.util.List; import java.util.UUID; diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/EnterprisePatchRequestDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/EnterprisePatchRequestDTO.java index 6aa5a70a..c3355230 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/EnterprisePatchRequestDTO.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/EnterprisePatchRequestDTO.java @@ -1,10 +1,9 @@ package com.pointtils.pointtils.src.application.dto.requests; import com.fasterxml.jackson.annotation.JsonProperty; -import com.pointtils.pointtils.src.application.dto.LocationDTO; -import jakarta.validation.Valid; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -15,26 +14,20 @@ @NoArgsConstructor @AllArgsConstructor public class EnterprisePatchRequestDTO { - @JsonProperty("corporate_reason") - private String corporateReason; - @Pattern(regexp = "^\\d{14}$", message = "CNPJ precisa ter 14 dígitos") - private String cnpj; - - @Email(message = "Email inválido") - private String email; + @JsonProperty("corporate_reason") + private String corporateReason; - private String password; + @Pattern(regexp = "^\\d{14}$", message = "CNPJ precisa ter 14 dígitos") + @Size(min = 14, max = 14, message = "CNPJ deve ter exatamente 14 digitos") + private String cnpj; - @Pattern(regexp = "^\\d+$", message = "Número de telefone inválido") - private String phone; + @Email(message = "Email inválido") + private String email; - private String picture; + @Size(max = 11, message = "O telefone deve ter no máximo 11 dígitos") + @Pattern(regexp = "^\\d+$", message = "Número de telefone inválido") + private String phone; - private String status; - - private String type; - - @Valid - private LocationDTO location; + private String picture; } diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/EnterpriseRequestDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/EnterpriseRequestDTO.java index 9737e31c..5dfff412 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/EnterpriseRequestDTO.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/EnterpriseRequestDTO.java @@ -1,12 +1,10 @@ package com.pointtils.pointtils.src.application.dto.requests; import com.fasterxml.jackson.annotation.JsonProperty; -import com.pointtils.pointtils.src.application.dto.LocationDTO; -import jakarta.validation.Valid; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -17,12 +15,14 @@ @NoArgsConstructor @AllArgsConstructor public class EnterpriseRequestDTO { + @NotBlank(message = "Razão social deve ser preenchida") @JsonProperty("corporate_reason") private String corporateReason; @NotBlank(message = "CNPJ deve ser preenchido") - @Pattern(regexp = "^\\d{14}$", message = "CNPJ inválido") + @Pattern(regexp = "^\\d{14}$", message = "CNPJ precisa ter 14 dígitos") + @Size(min = 14, max = 14, message = "CNPJ deve ter exatamente 14 digitos") private String cnpj; @NotBlank(message = "Email deve ser preenchido") @@ -33,12 +33,9 @@ public class EnterpriseRequestDTO { private String password; @NotBlank(message = "Número de telefone deve ser preenchido") + @Size(max = 11, message = "O telefone deve ter no máximo 11 dígitos") @Pattern(regexp = "^\\d+$", message = "Número de telefone inválido") private String phone; private String picture; - - @NotNull(message = "Localização deve ser preenchida") - @Valid - private LocationDTO location; } diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/InterpreterBasicRequestDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/InterpreterBasicRequestDTO.java index fd049cb2..15a83f8f 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/InterpreterBasicRequestDTO.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/InterpreterBasicRequestDTO.java @@ -1,25 +1,53 @@ package com.pointtils.pointtils.src.application.dto.requests; import com.fasterxml.jackson.annotation.JsonProperty; -import com.pointtils.pointtils.src.application.dto.LocationDTO; - import jakarta.validation.Valid; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import java.time.LocalDate; + @Data @NoArgsConstructor @AllArgsConstructor public class InterpreterBasicRequestDTO { - - @NotNull(message = "Dados pessoais devem ser preenchidos") - @Valid - @JsonProperty("personal_data") - private PersonalRequestDTO personalData; - - @NotNull(message = "Localização deve ser preenchida") + + @NotBlank(message = "Nome deve ser preenchido") + private String name; + + @NotBlank(message = "Email deve ser preenchido") + @Email(message = "Email inválido") + private String email; + + @NotBlank(message = "Senha deve ser preenchida") + private String password; + + @NotBlank(message = "Número de telefone deve ser preenchido") + @Size(max = 11, message = "O telefone deve ter no máximo 11 dígitos") + @Pattern(regexp = "^\\d+$", message = "Número de telefone inválido") + private String phone; + + @NotBlank(message = "Gênero deve ser preenchido") + @Pattern(regexp = "^[MFO]$", message = "Gênero deve ser M,F ou O") + private String gender; + + @NotNull(message = "Data de nascimento deve ser preenchida") + private LocalDate birthday; + + @NotBlank(message = "CPF deve ser preenchido") + @Pattern(regexp = "^\\d{11}$", message = "CPF inválido") + @Size(min = 11, max = 11, message = "CPF deve ter exatamente 11 digitos") + private String cpf; + + private String picture; + @Valid - private LocationDTO location; + @JsonProperty("professional_data") + private ProfessionalDataBasicRequestDTO professionalData; } diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/InterpreterPatchRequestDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/InterpreterPatchRequestDTO.java index 83cd118d..09e7874f 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/InterpreterPatchRequestDTO.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/InterpreterPatchRequestDTO.java @@ -1,27 +1,42 @@ package com.pointtils.pointtils.src.application.dto.requests; import com.fasterxml.jackson.annotation.JsonProperty; -import com.pointtils.pointtils.src.application.dto.LocationDTO; - import jakarta.validation.Valid; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import java.time.LocalDate; +import java.util.List; + @Data @NoArgsConstructor @AllArgsConstructor public class InterpreterPatchRequestDTO { - - @Valid - @JsonProperty("personal_data") - private PersonalPatchRequestDTO personalData; - + + private String name; + + @Email(message = "Email inválido") + private String email; + + @Size(max = 11, message = "O telefone deve ter no máximo 11 dígitos") + @Pattern(regexp = "^\\d+$", message = "Número de telefone inválido") + private String phone; + + @Pattern(regexp = "^[MFO]$", message = "Gênero deve ser M,F ou O") + private String gender; + + private LocalDate birthday; + + private String picture; + @Valid - private LocationDTO location; - + private List locations; + @Valid @JsonProperty("professional_data") - private ProfessionalPatchRequestDTO professionalData; - + private ProfessionalDataPatchRequestDTO professionalData; } diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/InterpreterRequestDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/InterpreterRequestDTO.java deleted file mode 100644 index 128a49e7..00000000 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/InterpreterRequestDTO.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.pointtils.pointtils.src.application.dto.requests; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.pointtils.pointtils.src.application.dto.LocationDTO; - -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class InterpreterRequestDTO { - - @NotNull(message = "Dados pessoais devem ser preenchidos") - @Valid - @JsonProperty("personal_data") - private PersonalRequestDTO personalData; - - @NotNull(message = "Localização deve ser preenchida") - @Valid - private LocationDTO location; - - @NotNull(message = "Dados profissionais devem ser preenchidos") - @Valid - @JsonProperty("professional_data") - private ProfessionalRequestDTO professionalData; - -} diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/LocationRequestDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/LocationRequestDTO.java new file mode 100644 index 00000000..5112ad44 --- /dev/null +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/LocationRequestDTO.java @@ -0,0 +1,21 @@ +package com.pointtils.pointtils.src.application.dto.requests; + +import jakarta.validation.constraints.NotBlank; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class LocationRequestDTO { + + @NotBlank(message = "UF deve ser preenchida") + private String uf; + + @NotBlank(message = "Cidade deve ser preenchida") + private String city; + + @NotBlank(message = "Bairro deve ser preenchido") + private String neighborhood; +} diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/LoginRequestDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/LoginRequestDTO.java similarity index 80% rename from pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/LoginRequestDTO.java rename to pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/LoginRequestDTO.java index 66cbe19c..e33e2b8a 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/LoginRequestDTO.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/LoginRequestDTO.java @@ -1,4 +1,4 @@ -package com.pointtils.pointtils.src.application.dto; +package com.pointtils.pointtils.src.application.dto.requests; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/PersonCreationDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/PersonCreationRequestDTO.java similarity index 79% rename from pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/PersonCreationDTO.java rename to pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/PersonCreationRequestDTO.java index 91d4066e..95a4094b 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/PersonCreationDTO.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/PersonCreationRequestDTO.java @@ -1,11 +1,14 @@ -package com.pointtils.pointtils.src.application.dto; +package com.pointtils.pointtils.src.application.dto.requests; import java.time.LocalDate; import java.util.List; + +import com.pointtils.pointtils.src.application.dto.UserSpecialtyDTO; import com.pointtils.pointtils.src.core.domain.entities.enums.Gender; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Builder; @@ -18,8 +21,8 @@ @Builder @Getter @Setter -public class PersonCreationDTO { - @Email(message = "Formato de e-mail inválido") +public class PersonCreationRequestDTO { + @Email(message = "Email inválido") @NotBlank(message = "O e-mail é obrigatório") private String email; @@ -28,6 +31,7 @@ public class PersonCreationDTO { private String password; @Size(max = 11, message = "O telefone deve ter no máximo 11 dígitos") + @Pattern(regexp = "^\\d+$", message = "Número de telefone inválido") private String phone; private String picture; diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/PersonPatchRequestDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/PersonPatchRequestDTO.java index b751ddf5..ceab0d62 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/PersonPatchRequestDTO.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/PersonPatchRequestDTO.java @@ -2,6 +2,7 @@ import com.pointtils.pointtils.src.core.domain.entities.enums.Gender; import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Data; @@ -18,14 +19,16 @@ public class PersonPatchRequestDTO { private String name; + @Pattern(regexp = "^[MFO]$", message = "Gênero deve ser M,F ou O") private Gender gender; private LocalDate birthday; - @Email(message = "Formato de e-mail inválido") + @Email(message = "Email inválido") private String email; @Size(max = 11, message = "O telefone deve ter no máximo 11 dígitos") + @Pattern(regexp = "^\\d+$", message = "Número de telefone inválido") private String phone; private String picture; diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/PersonalPatchRequestDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/PersonalPatchRequestDTO.java deleted file mode 100644 index 6b198ded..00000000 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/PersonalPatchRequestDTO.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.pointtils.pointtils.src.application.dto.requests; - -import java.time.LocalDate; - -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.Pattern; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class PersonalPatchRequestDTO { - - private String name; - - @Email(message = "Email inválido") - private String email; - - private String password; - - @Pattern(regexp = "^\\d+$", message = "Número de telefone inválido") - private String phone; - - @Pattern(regexp = "^[MFO]$", message = "Gênero deve ser M,F ou O") - private String gender; - - private LocalDate birthday; - - @Pattern(regexp = "^\\d{11}$", message = "CPF inválido") - private String cpf; - - private String picture; -} diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/PersonalRequestDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/PersonalRequestDTO.java deleted file mode 100644 index 70bf1f76..00000000 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/PersonalRequestDTO.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.pointtils.pointtils.src.application.dto.requests; - -import java.time.LocalDate; - -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Pattern; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class PersonalRequestDTO { - - @NotBlank(message = "Nome deve ser preenchido") - private String name; - - @NotBlank(message = "Email deve ser preenchido") - @Email(message = "Email inválido") - private String email; - - @NotBlank(message = "Senha deve ser preenchida") - private String password; - - @NotBlank(message = "Número de telefone deve ser preenchido") - @Pattern(regexp = "^\\d+$", message = "Número de telefone inválido") - private String phone; - - @NotBlank(message = "Gênero deve ser preenchido") - @Pattern(regexp = "^[MFO]$", message = "Gênero deve ser M,F ou O") - private String gender; - - @NotNull(message = "Data de nascimento deve ser preenchida") - private LocalDate birthday; - - @NotBlank(message = "CPF deve ser preenchido") - @Pattern(regexp = "^\\d{11}$", message = "CPF inválido") - private String cpf; - - private String picture; -} diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/ProfessionalDataBasicRequestDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/ProfessionalDataBasicRequestDTO.java new file mode 100644 index 00000000..16e1a360 --- /dev/null +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/ProfessionalDataBasicRequestDTO.java @@ -0,0 +1,19 @@ +package com.pointtils.pointtils.src.application.dto.requests; + +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ProfessionalDataBasicRequestDTO { + + @Pattern(regexp = "^\\d{14}$", message = "CNPJ precisa ter 14 dígitos") + @Size(min = 14, max = 14, message = "CNPJ deve ter exatamente 14 digitos") + private String cnpj; +} diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/ProfessionalPatchRequestDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/ProfessionalDataPatchRequestDTO.java similarity index 86% rename from pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/ProfessionalPatchRequestDTO.java rename to pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/ProfessionalDataPatchRequestDTO.java index d7362f68..fdee0229 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/ProfessionalPatchRequestDTO.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/ProfessionalDataPatchRequestDTO.java @@ -6,6 +6,7 @@ import jakarta.validation.constraints.DecimalMin; import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -15,9 +16,10 @@ @Builder @NoArgsConstructor @AllArgsConstructor -public class ProfessionalPatchRequestDTO { +public class ProfessionalDataPatchRequestDTO { @Pattern(regexp = "^\\d{14}$", message = "CNPJ precisa ter 14 dígitos") + @Size(min = 14, max = 14, message = "CNPJ deve ter exatamente 14 digitos") private String cnpj; @DecimalMin(value = "0.0", message = "Valor mínimo precisa ser positivo") diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/ProfessionalRequestDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/ProfessionalRequestDTO.java deleted file mode 100644 index dbce8b37..00000000 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/ProfessionalRequestDTO.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.pointtils.pointtils.src.application.dto.requests; - -import java.math.BigDecimal; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import jakarta.validation.constraints.DecimalMin; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Pattern; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ProfessionalRequestDTO { - - @NotBlank(message = "CNPJ deve ser preenchido") - @Pattern(regexp = "^\\d{14}$", message = "CNPJ precisa ter 14 dígitos") - private String cnpj; - - @NotNull(message = "Valor mínimo deve ser preenchido") - @DecimalMin(value = "0.0", message = "Valor mínimo precisa ser positivo") - @JsonProperty("min_value") // Mapeia snake_case para camelCase - private BigDecimal minValue; - - @NotNull(message = "Valor máximo deve ser preenchido") - @DecimalMin(value = "0.0", message = "Valor máximo precisa ser positivo") - @JsonProperty("max_value") - private BigDecimal maxValue; - - @NotBlank(message = "Modalidade de atendimento deve ser preenchida") - @Pattern(regexp = "^(presencial|online|ambos)$", message = "Modalidade precisa ser 'presencial', 'online' or 'ambos'") - private String modality; - - private String description; - - @NotNull(message = "Usuário deve informar se autoriza o direito de uso de imagem") - @JsonProperty("image_rights") - private Boolean imageRights; -} diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/RefreshTokenRequestDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/RefreshTokenRequestDTO.java similarity index 88% rename from pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/RefreshTokenRequestDTO.java rename to pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/RefreshTokenRequestDTO.java index db6cae9f..9a4790a8 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/RefreshTokenRequestDTO.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/RefreshTokenRequestDTO.java @@ -1,4 +1,4 @@ -package com.pointtils.pointtils.src.application.dto; +package com.pointtils.pointtils.src.application.dto.requests; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/UpdateSpecialtyRequestDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/UpdateSpecialtyRequestDTO.java similarity index 60% rename from pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/UpdateSpecialtyRequestDTO.java rename to pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/UpdateSpecialtyRequestDTO.java index e92254c4..6a8ffe2b 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/UpdateSpecialtyRequestDTO.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/requests/UpdateSpecialtyRequestDTO.java @@ -1,4 +1,4 @@ -package com.pointtils.pointtils.src.application.dto; +package com.pointtils.pointtils.src.application.dto.requests; import lombok.Data; diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/CityIbgeResponseDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/CityIbgeResponseDTO.java similarity index 84% rename from pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/CityIbgeResponseDTO.java rename to pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/CityIbgeResponseDTO.java index 5963dd68..c8b071d4 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/CityIbgeResponseDTO.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/CityIbgeResponseDTO.java @@ -1,4 +1,4 @@ -package com.pointtils.pointtils.src.application.dto; +package com.pointtils.pointtils.src.application.dto.responses; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/InterpreterResponseDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/InterpreterResponseDTO.java index d7f6f98f..e0ad8e65 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/InterpreterResponseDTO.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/InterpreterResponseDTO.java @@ -2,31 +2,40 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.pointtils.pointtils.src.application.dto.LocationDTO; -import com.pointtils.pointtils.src.application.dto.PersonDTO; - +import com.pointtils.pointtils.src.core.domain.entities.enums.Gender; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import java.time.LocalDate; import java.util.List; import java.util.UUID; @Data +@Builder @NoArgsConstructor @AllArgsConstructor public class InterpreterResponseDTO { - @JsonProperty("id_interpreter") - private UUID idInterpreter; - - private UserResponseDTO user; + // Dados do usuario + private UUID id; + private String email; + private String type; + private String status; + private String phone; + private String picture; - private PersonDTO person; + // Dados da pessoa + private String name; + private Gender gender; + private LocalDate birthday; + private String cpf; - @JsonProperty("professional_info") - private ProfessionalInfoResponseDTO professionalInfo; - - private LocationDTO location; + private List locations; private List specialties; + + @JsonProperty("professional_data") + private ProfessionalDataResponseDTO professionalData; } diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/LoginResponseDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/LoginResponseDTO.java similarity index 63% rename from pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/LoginResponseDTO.java rename to pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/LoginResponseDTO.java index 9b7658b0..caebb681 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/LoginResponseDTO.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/LoginResponseDTO.java @@ -1,5 +1,7 @@ -package com.pointtils.pointtils.src.application.dto; +package com.pointtils.pointtils.src.application.dto.responses; +import com.pointtils.pointtils.src.application.dto.TokensDTO; +import com.pointtils.pointtils.src.application.dto.UserDTO; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/ProfessionalInfoResponseDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/ProfessionalDataResponseDTO.java similarity index 93% rename from pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/ProfessionalInfoResponseDTO.java rename to pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/ProfessionalDataResponseDTO.java index a7ca86c2..4175a8aa 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/ProfessionalInfoResponseDTO.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/ProfessionalDataResponseDTO.java @@ -11,7 +11,7 @@ @Builder @NoArgsConstructor @AllArgsConstructor -public class ProfessionalInfoResponseDTO { +public class ProfessionalDataResponseDTO { private String cnpj; private BigDecimal rating; diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/RefreshTokenResponseDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/RefreshTokenResponseDTO.java similarity index 71% rename from pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/RefreshTokenResponseDTO.java rename to pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/RefreshTokenResponseDTO.java index 36901eed..0871e880 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/RefreshTokenResponseDTO.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/RefreshTokenResponseDTO.java @@ -1,5 +1,6 @@ -package com.pointtils.pointtils.src.application.dto; +package com.pointtils.pointtils.src.application.dto.responses; +import com.pointtils.pointtils.src.application.dto.TokensDTO; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/StateIbgeResponseDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/StateIbgeResponseDTO.java similarity index 86% rename from pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/StateIbgeResponseDTO.java rename to pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/StateIbgeResponseDTO.java index 09c810c5..ef470bcd 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/StateIbgeResponseDTO.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/StateIbgeResponseDTO.java @@ -1,4 +1,4 @@ -package com.pointtils.pointtils.src.application.dto; +package com.pointtils.pointtils.src.application.dto.responses; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/StateResponseDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/StateResponseDTO.java similarity index 71% rename from pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/StateResponseDTO.java rename to pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/StateResponseDTO.java index 7e6a92c8..3f1d029a 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/StateResponseDTO.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/StateResponseDTO.java @@ -1,5 +1,6 @@ -package com.pointtils.pointtils.src.application.dto; +package com.pointtils.pointtils.src.application.dto.responses; +import com.pointtils.pointtils.src.application.dto.StateDataDTO; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/UserSpecialtiesResponseDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/UserSpecialtiesResponseDTO.java similarity index 84% rename from pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/UserSpecialtiesResponseDTO.java rename to pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/UserSpecialtiesResponseDTO.java index bf046c59..9d44aa85 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/UserSpecialtiesResponseDTO.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/UserSpecialtiesResponseDTO.java @@ -1,7 +1,8 @@ -package com.pointtils.pointtils.src.application.dto; +package com.pointtils.pointtils.src.application.dto.responses; import java.util.List; +import com.pointtils.pointtils.src.application.dto.UserSpecialtyDTO; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/mapper/InterpreterMapper.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/mapper/InterpreterMapper.java deleted file mode 100644 index 4f59ab67..00000000 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/mapper/InterpreterMapper.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.pointtils.pointtils.src.application.mapper; - -import com.pointtils.pointtils.src.application.dto.requests.ProfessionalRequestDTO; -import com.pointtils.pointtils.src.core.domain.entities.Interpreter; -import com.pointtils.pointtils.src.core.domain.entities.enums.InterpreterModality; -import lombok.experimental.UtilityClass; - -@UtilityClass -public class InterpreterMapper { - - public static void toDomain(ProfessionalRequestDTO dto, Interpreter interpreter) { - interpreter.setCnpj(dto.getCnpj()); - interpreter.setMinValue(dto.getMinValue()); - interpreter.setMaxValue(dto.getMaxValue()); - interpreter.setModality(InterpreterModality.fromString(dto.getModality())); - interpreter.setDescription(dto.getDescription()); - interpreter.setImageRights(dto.getImageRights()); - } - - public static InterpreterModality toInterpreterModality(String modality) { - return InterpreterModality.fromString(modality); - } - - public static ProfessionalRequestDTO toDto(Interpreter interpreter) { - return ProfessionalRequestDTO.builder() - .cnpj(interpreter.getCnpj()) - .minValue(interpreter.getMinValue()) - .maxValue(interpreter.getMaxValue()) - .modality(interpreter.getModality() != null ? interpreter.getModality().name().toLowerCase() : null) - .description(interpreter.getDescription()) - .imageRights(interpreter.getImageRights()) - .build(); - } -} diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/mapper/InterpreterResponseMapper.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/mapper/InterpreterResponseMapper.java index ee4be799..1e59f9d8 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/mapper/InterpreterResponseMapper.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/mapper/InterpreterResponseMapper.java @@ -1,42 +1,34 @@ package com.pointtils.pointtils.src.application.mapper; -import com.pointtils.pointtils.src.application.dto.PersonDTO; + +import com.pointtils.pointtils.src.application.dto.LocationDTO; import com.pointtils.pointtils.src.application.dto.responses.InterpreterResponseDTO; -import com.pointtils.pointtils.src.application.dto.responses.ProfessionalInfoResponseDTO; +import com.pointtils.pointtils.src.application.dto.responses.ProfessionalDataResponseDTO; import com.pointtils.pointtils.src.application.dto.responses.SpecialtyResponseDTO; -import com.pointtils.pointtils.src.application.dto.responses.UserResponseDTO; import com.pointtils.pointtils.src.core.domain.entities.Interpreter; import org.springframework.stereotype.Component; import java.math.BigDecimal; +import java.util.Collections; import java.util.List; @Component public class InterpreterResponseMapper { public InterpreterResponseDTO toResponseDTO(Interpreter interpreter) { - InterpreterResponseDTO dto = new InterpreterResponseDTO(); - - dto.setIdInterpreter(interpreter.getId()); - - UserResponseDTO userDto = UserResponseDTO.builder() + InterpreterResponseDTO dto = InterpreterResponseDTO.builder() .id(interpreter.getId()) .email(interpreter.getEmail()) .type(interpreter.getType().name()) .status(interpreter.getStatus().toString()) .phone(interpreter.getPhone()) .picture(interpreter.getPicture()) - .build(); - dto.setUser(userDto); - - PersonDTO personDto = PersonDTO.builder() .name(interpreter.getName()) .gender(interpreter.getGender()) .birthday(interpreter.getBirthday()) .cpf(maskCpf(interpreter.getCpf())) .build(); - dto.setPerson(personDto); - ProfessionalInfoResponseDTO professionalDto = ProfessionalInfoResponseDTO.builder() + ProfessionalDataResponseDTO professionalDto = ProfessionalDataResponseDTO.builder() .cnpj(interpreter.getCnpj()) .rating(interpreter.getRating() != null ? interpreter.getRating() : BigDecimal.ZERO) .minValue(interpreter.getMinValue()) @@ -45,21 +37,22 @@ public InterpreterResponseDTO toResponseDTO(Interpreter interpreter) { .description(interpreter.getDescription()) .imageRights(interpreter.getImageRights()) .build(); - dto.setProfessionalInfo(professionalDto); - - // if (interpreter.getLocation() != null) { - // LocationDTO locationDto = LocationDTO.builder() - // .id(interpreter.getLocation().getId()) - // .uf(interpreter.getLocation().getUf()) - // .city(interpreter.getLocation().getCity()) - // .build(); - // dto.setLocation(locationDto); - // } + dto.setProfessionalData(professionalDto); + if (interpreter.getLocations() != null) { + List locationList = interpreter.getLocations().stream() + .map(LocationMapper::toDto) + .toList(); + dto.setLocations(locationList); + } else { + dto.setLocations(Collections.emptyList()); + } - List specialtyDtos = interpreter.getSpecialties() - .stream() - .map(specialty -> SpecialtyResponseDTO.builder().id(specialty.getId()).name(specialty.getName()).build()) + List specialtyDtos = interpreter.getSpecialties().stream() + .map(specialty -> SpecialtyResponseDTO.builder() + .id(specialty.getId()) + .name(specialty.getName()) + .build()) .toList(); dto.setSpecialties(specialtyDtos); diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/mapper/LocationMapper.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/mapper/LocationMapper.java index ca49eab5..fd9e9c3d 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/mapper/LocationMapper.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/mapper/LocationMapper.java @@ -2,6 +2,8 @@ import com.pointtils.pointtils.src.application.dto.LocationDTO; +import com.pointtils.pointtils.src.application.dto.requests.LocationRequestDTO; +import com.pointtils.pointtils.src.core.domain.entities.Interpreter; import com.pointtils.pointtils.src.core.domain.entities.Location; import lombok.experimental.UtilityClass; @@ -11,16 +13,20 @@ public class LocationMapper { public static LocationDTO toDto(Location location) { if (location == null) return null; return LocationDTO.builder() + .id(location.getId()) .uf(location.getUf()) .city(location.getCity()) + .neighborhood(location.getNeighborhood()) .build(); } - public static Location toDomain(LocationDTO locationDTO) { - if (locationDTO == null) return null; + public static Location toDomain(LocationRequestDTO locationRequestDTO, Interpreter interpreter) { + if (locationRequestDTO == null) return null; return Location.builder() - .uf(locationDTO.getUf()) - .city(locationDTO.getCity()) + .uf(locationRequestDTO.getUf()) + .city(locationRequestDTO.getCity()) + .neighborhood(locationRequestDTO.getNeighborhood()) + .interpreter(interpreter) .build(); } } diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/AuthService.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/AuthService.java index cc004dec..24cdc6ae 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/AuthService.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/AuthService.java @@ -2,8 +2,8 @@ import com.pointtils.pointtils.src.core.domain.entities.enums.UserStatus; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; -import com.pointtils.pointtils.src.application.dto.LoginResponseDTO; -import com.pointtils.pointtils.src.application.dto.RefreshTokenResponseDTO; +import com.pointtils.pointtils.src.application.dto.responses.LoginResponseDTO; +import com.pointtils.pointtils.src.application.dto.responses.RefreshTokenResponseDTO; import com.pointtils.pointtils.src.application.dto.TokensDTO; import com.pointtils.pointtils.src.application.dto.UserDTO; import com.pointtils.pointtils.src.core.domain.entities.User; diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/EnterpriseService.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/EnterpriseService.java index 65e4776c..157f8307 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/EnterpriseService.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/EnterpriseService.java @@ -22,71 +22,68 @@ @Transactional @RequiredArgsConstructor public class EnterpriseService { - private static final String ENTERPRISE_NOT_FOUND_MSG = "Empresa não encontrada"; - private final EnterpriseRepository enterpriseRepository; - private final UserRepository userRepository; - private final PasswordEncoder passwordEncoder; + private static final String ENTERPRISE_NOT_FOUND_MSG = "Empresa não encontrada"; + private final EnterpriseRepository enterpriseRepository; + private final UserRepository userRepository; + private final PasswordEncoder passwordEncoder; - public EnterpriseResponseDTO registerEnterprise(EnterpriseRequestDTO dto) { - if (enterpriseRepository.existsByCnpj(dto.getCnpj())) { - throw new DuplicateResourceException("Já existe uma empresa cadastrada com este CNPJ"); - } + public EnterpriseResponseDTO registerEnterprise(EnterpriseRequestDTO dto) { + if (enterpriseRepository.existsByCnpj(dto.getCnpj())) { + throw new DuplicateResourceException("Já existe uma empresa cadastrada com este CNPJ"); + } - if (userRepository.existsByEmail(dto.getEmail())) { - throw new DuplicateResourceException("Já existe um usuário cadastrado com este email"); - } + if (userRepository.existsByEmail(dto.getEmail())) { + throw new DuplicateResourceException("Já existe um usuário cadastrado com este email"); + } - Enterprise enterprise = Enterprise.builder() - .corporateReason(dto.getCorporateReason()) - .cnpj(dto.getCnpj()) - .email(dto.getEmail()) - .password(passwordEncoder.encode(dto.getPassword())) - .phone(dto.getPhone()) - .picture(dto.getPicture()) - .status(UserStatus.ACTIVE) - .type(UserTypeE.ENTERPRISE) - .build(); + Enterprise enterprise = Enterprise.builder() + .corporateReason(dto.getCorporateReason()) + .cnpj(dto.getCnpj()) + .email(dto.getEmail()) + .password(passwordEncoder.encode(dto.getPassword())) + .phone(dto.getPhone()) + .picture(dto.getPicture()) + .status(UserStatus.ACTIVE) + .type(UserTypeE.ENTERPRISE) + .build(); - Enterprise savedEnterprise = enterpriseRepository.save(enterprise); + Enterprise savedEnterprise = enterpriseRepository.save(enterprise); - return new EnterpriseResponseDTO(savedEnterprise); - } + return new EnterpriseResponseDTO(savedEnterprise); + } - public List findAll() { - List enterpriseList = enterpriseRepository.findAllByStatus(UserStatus.ACTIVE); - return enterpriseList.stream() - .map(EnterpriseResponseDTO::new) - .toList(); - } + public List findAll() { + List enterpriseList = enterpriseRepository.findAllByStatus(UserStatus.ACTIVE); + return enterpriseList.stream() + .map(EnterpriseResponseDTO::new) + .toList(); + } - public EnterpriseResponseDTO findById(UUID id) { - Enterprise enterprise = enterpriseRepository.findByIdAndStatus(id, UserStatus.ACTIVE) - .orElseThrow(() -> new EntityNotFoundException(ENTERPRISE_NOT_FOUND_MSG)); - return new EnterpriseResponseDTO(enterprise); - } + public EnterpriseResponseDTO findById(UUID id) { + Enterprise enterprise = enterpriseRepository.findByIdAndStatus(id, UserStatus.ACTIVE) + .orElseThrow(() -> new EntityNotFoundException(ENTERPRISE_NOT_FOUND_MSG)); + return new EnterpriseResponseDTO(enterprise); + } - public EnterpriseResponseDTO patchEnterprise( - UUID id, - EnterprisePatchRequestDTO dto - ) { - Enterprise enterprise = enterpriseRepository.findByIdAndStatus(id, UserStatus.ACTIVE) - .orElseThrow(() -> new EntityNotFoundException(ENTERPRISE_NOT_FOUND_MSG)); + public EnterpriseResponseDTO patchEnterprise(UUID id, EnterprisePatchRequestDTO dto) { + Enterprise enterprise = enterpriseRepository.findByIdAndStatus(id, UserStatus.ACTIVE) + .orElseThrow(() -> new EntityNotFoundException(ENTERPRISE_NOT_FOUND_MSG)); - if (dto.getCorporateReason() != null) enterprise.setCorporateReason(dto.getCorporateReason()); - if (dto.getCnpj() != null) enterprise.setCnpj(dto.getCnpj()); - if (dto.getEmail() != null) enterprise.setEmail(dto.getEmail()); - if (dto.getPhone() != null) enterprise.setPhone(dto.getPhone()); - if (dto.getPicture() != null) enterprise.setPicture(dto.getPicture()); + if (dto.getCorporateReason() != null) enterprise.setCorporateReason(dto.getCorporateReason()); + if (dto.getCnpj() != null) enterprise.setCnpj(dto.getCnpj()); + if (dto.getEmail() != null) enterprise.setEmail(dto.getEmail()); + if (dto.getPhone() != null) enterprise.setPhone(dto.getPhone()); + if (dto.getPicture() != null) enterprise.setPicture(dto.getPicture()); - Enterprise patchedEnterprise = enterpriseRepository.save(enterprise); - return new EnterpriseResponseDTO(patchedEnterprise); - } + Enterprise patchedEnterprise = enterpriseRepository.save(enterprise); + return new EnterpriseResponseDTO(patchedEnterprise); + } - public void delete(UUID id) { - Enterprise enterprise = enterpriseRepository.findById(id) - .orElseThrow(() -> new EntityNotFoundException(ENTERPRISE_NOT_FOUND_MSG)); + public void delete(UUID id) { + Enterprise enterprise = enterpriseRepository.findById(id) + .orElseThrow(() -> new EntityNotFoundException(ENTERPRISE_NOT_FOUND_MSG)); - enterprise.setStatus(UserStatus.INACTIVE); - enterpriseRepository.save(enterprise); - } + enterprise.setStatus(UserStatus.INACTIVE); + enterpriseRepository.save(enterprise); + } } diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/InterpreterRegisterService.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/InterpreterRegisterService.java deleted file mode 100644 index 179fe81f..00000000 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/InterpreterRegisterService.java +++ /dev/null @@ -1,199 +0,0 @@ -package com.pointtils.pointtils.src.application.services; - -import com.pointtils.pointtils.src.application.dto.requests.InterpreterBasicRequestDTO; -import com.pointtils.pointtils.src.application.dto.requests.InterpreterPatchRequestDTO; -import com.pointtils.pointtils.src.application.dto.requests.InterpreterRequestDTO; -import com.pointtils.pointtils.src.application.dto.requests.PersonalPatchRequestDTO; -import com.pointtils.pointtils.src.application.dto.requests.ProfessionalPatchRequestDTO; -import com.pointtils.pointtils.src.application.dto.responses.InterpreterResponseDTO; -import com.pointtils.pointtils.src.application.mapper.InterpreterMapper; -import com.pointtils.pointtils.src.application.mapper.InterpreterResponseMapper; -import com.pointtils.pointtils.src.core.domain.entities.Interpreter; -import com.pointtils.pointtils.src.core.domain.entities.Location; -import com.pointtils.pointtils.src.core.domain.entities.enums.Gender; -import com.pointtils.pointtils.src.core.domain.entities.enums.InterpreterModality; -import com.pointtils.pointtils.src.core.domain.entities.enums.UserStatus; -import com.pointtils.pointtils.src.core.domain.entities.enums.UserTypeE; -import com.pointtils.pointtils.src.infrastructure.repositories.InterpreterRepository; -import jakarta.persistence.EntityNotFoundException; -import lombok.RequiredArgsConstructor; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.math.BigDecimal; -import java.util.List; -import java.util.UUID; - -@Service -@Transactional -@RequiredArgsConstructor -public class InterpreterRegisterService { - - private final InterpreterRepository repository; - private final PasswordEncoder passwordEncoder; - private final InterpreterResponseMapper responseMapper; - - - public InterpreterResponseDTO registerBasic(InterpreterBasicRequestDTO request) { - Interpreter interpreter = Interpreter.builder() - .email(request.getPersonalData().getEmail()) - .password(passwordEncoder.encode(request.getPersonalData().getPassword())) - .phone(request.getPersonalData().getPhone()) - .picture(request.getPersonalData().getPicture()) - .status(UserStatus.PENDING) - .type(UserTypeE.INTERPRETER) - .name(request.getPersonalData().getName()) - .gender(Gender.fromString(request.getPersonalData().getGender())) - .birthday(request.getPersonalData().getBirthday()) - .cpf(request.getPersonalData().getCpf()) - .cnpj(null) - .rating(BigDecimal.ZERO) - .minValue(BigDecimal.ZERO) - .maxValue(BigDecimal.ZERO) - .imageRights(false) - .modality(InterpreterModality.ALL) - .description("") - .build(); - - if (request.getLocation() != null) { - Location location = Location.builder() - .uf(request.getLocation().getUf()) - .city(request.getLocation().getCity()) - .interpreter(interpreter) - .build(); - } - - Interpreter savedInterpreter = repository.save(interpreter); - return responseMapper.toResponseDTO(savedInterpreter); - } - - public InterpreterResponseDTO findById(UUID id) { - Interpreter interpreter = findInterpreterById(id); - return responseMapper.toResponseDTO(interpreter); - } - - public void delete(UUID id) { - Interpreter interpreter = findInterpreterById(id); - interpreter.setStatus(UserStatus.INACTIVE); - repository.save(interpreter); - } - - public List findAll() { - List interpreters = repository.findAll(); - return interpreters.stream() - .map(responseMapper::toResponseDTO) - .toList(); - } - - public InterpreterResponseDTO updateComplete(UUID id, InterpreterRequestDTO dto) { - Interpreter interpreter = findInterpreterById(id); - - if (dto.getPersonalData() != null) { - var personalData = dto.getPersonalData(); - interpreter.setName(personalData.getName()); - interpreter.setEmail(personalData.getEmail()); - interpreter.setPhone(personalData.getPhone()); - interpreter.setPicture(personalData.getPicture()); - interpreter.setBirthday(personalData.getBirthday()); - interpreter.setCpf(personalData.getCpf()); - interpreter.setGender(Gender.fromString(personalData.getGender())); - - if (personalData.getPassword() != null) { - interpreter.setPassword(passwordEncoder.encode(personalData.getPassword())); - } - } - - if (dto.getProfessionalData() != null) { - var professionalData = dto.getProfessionalData(); - interpreter.setCnpj(professionalData.getCnpj()); - interpreter.setMinValue(professionalData.getMinValue()); - interpreter.setMaxValue(professionalData.getMaxValue()); - interpreter.setImageRights(professionalData.getImageRights()); - interpreter.setModality(InterpreterMapper.toInterpreterModality(professionalData.getModality())); - interpreter.setDescription(professionalData.getDescription()); - } - - // updateLocation(dto.getLocation(), interpreter); - - Interpreter updatedInterpreter = repository.save(interpreter); - return responseMapper.toResponseDTO(updatedInterpreter); - } - - public InterpreterResponseDTO updatePartial(UUID id, InterpreterPatchRequestDTO dto) { - Interpreter interpreter = findInterpreterById(id); - updatePersonalPatchRequest(dto.getPersonalData(), interpreter); - updateProfessionalPatchRequest(dto.getProfessionalData(), interpreter); - // updateLocation(dto.getLocation(), interpreter); - - Interpreter updatedInterpreter = repository.save(interpreter); - return responseMapper.toResponseDTO(updatedInterpreter); - } - - private void updatePersonalPatchRequest(PersonalPatchRequestDTO personal, Interpreter interpreter) { - if (personal == null) { - return; - } - if (personal.getName() != null) { - interpreter.setName(personal.getName()); - } - if (personal.getEmail() != null) { - interpreter.setEmail(personal.getEmail()); - } - if (personal.getPhone() != null) { - interpreter.setPhone(personal.getPhone()); - } - if (personal.getBirthday() != null) { - interpreter.setBirthday(personal.getBirthday()); - } - if (personal.getCpf() != null) { - interpreter.setCpf(personal.getCpf()); - } - if (personal.getGender() != null) { - interpreter.setGender(Gender.fromString(personal.getGender())); - } - } - - private void updateProfessionalPatchRequest(ProfessionalPatchRequestDTO dto, Interpreter interpreter) { - if (dto == null) { - return; - } - if (dto.getCnpj() != null) { - interpreter.setCnpj(dto.getCnpj()); - } - if (dto.getMinValue() != null) { - interpreter.setMinValue(dto.getMinValue()); - } - if (dto.getMaxValue() != null) { - interpreter.setMaxValue(dto.getMaxValue()); - } - if (dto.getImageRights() != null) { - interpreter.setImageRights(dto.getImageRights()); - } - if (dto.getModality() != null) { - interpreter.setModality(InterpreterMapper.toInterpreterModality(dto.getModality())); - } - if (dto.getDescription() != null) { - interpreter.setDescription(dto.getDescription()); - } - } - - // private void updateLocation(LocationDTO locationDTO, Interpreter interpreter) { - // if (locationDTO == null) { - // return; - // } - - // Location location = interpreter.getLocation(); - // if (location == null) { - // location = Location.builder().user(interpreter).build(); - // } - // location.setUf(locationDTO.getUf()); - // location.setCity(locationDTO.getCity()); - // interpreter.setLocation(location); - // } - - private Interpreter findInterpreterById(UUID id) { - return repository.findById(id) - .orElseThrow(() -> new EntityNotFoundException("Intérprete não encontrado")); - } -} diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/InterpreterService.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/InterpreterService.java new file mode 100644 index 00000000..01130a17 --- /dev/null +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/InterpreterService.java @@ -0,0 +1,147 @@ +package com.pointtils.pointtils.src.application.services; + +import com.pointtils.pointtils.src.application.dto.requests.InterpreterBasicRequestDTO; +import com.pointtils.pointtils.src.application.dto.requests.InterpreterPatchRequestDTO; +import com.pointtils.pointtils.src.application.dto.requests.LocationRequestDTO; +import com.pointtils.pointtils.src.application.dto.requests.ProfessionalDataPatchRequestDTO; +import com.pointtils.pointtils.src.application.dto.responses.InterpreterResponseDTO; +import com.pointtils.pointtils.src.application.mapper.InterpreterResponseMapper; +import com.pointtils.pointtils.src.application.mapper.LocationMapper; +import com.pointtils.pointtils.src.core.domain.entities.Interpreter; +import com.pointtils.pointtils.src.core.domain.entities.enums.Gender; +import com.pointtils.pointtils.src.core.domain.entities.enums.InterpreterModality; +import com.pointtils.pointtils.src.core.domain.entities.enums.UserStatus; +import com.pointtils.pointtils.src.core.domain.entities.enums.UserTypeE; +import com.pointtils.pointtils.src.infrastructure.repositories.InterpreterRepository; +import jakarta.persistence.EntityNotFoundException; +import lombok.RequiredArgsConstructor; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +@Service +@Transactional +@RequiredArgsConstructor +public class InterpreterService { + + private final InterpreterRepository repository; + private final PasswordEncoder passwordEncoder; + private final InterpreterResponseMapper responseMapper; + + public InterpreterResponseDTO registerBasic(InterpreterBasicRequestDTO request) { + Interpreter interpreter = Interpreter.builder() + .email(request.getEmail()) + .password(passwordEncoder.encode(request.getPassword())) + .phone(request.getPhone()) + .picture(request.getPicture()) + .status(UserStatus.PENDING) + .type(UserTypeE.INTERPRETER) + .name(request.getName()) + .gender(Gender.fromString(request.getGender())) + .birthday(request.getBirthday()) + .cpf(request.getCpf()) + .cnpj(Objects.nonNull(request.getProfessionalData()) ? request.getProfessionalData().getCnpj() : null) + .rating(BigDecimal.ZERO) + .minValue(BigDecimal.ZERO) + .maxValue(BigDecimal.ZERO) + .imageRights(false) + .modality(InterpreterModality.ALL) + .description("") + .build(); + + Interpreter savedInterpreter = repository.save(interpreter); + return responseMapper.toResponseDTO(savedInterpreter); + } + + public InterpreterResponseDTO findById(UUID id) { + Interpreter interpreter = findInterpreterById(id); + return responseMapper.toResponseDTO(interpreter); + } + + public void delete(UUID id) { + Interpreter interpreter = findInterpreterById(id); + interpreter.setStatus(UserStatus.INACTIVE); + repository.save(interpreter); + } + + public List findAll() { + List interpreters = repository.findAll(); + return interpreters.stream() + .map(responseMapper::toResponseDTO) + .toList(); + } + + public InterpreterResponseDTO updatePartial(UUID id, InterpreterPatchRequestDTO dto) { + Interpreter interpreter = findInterpreterById(id); + updatePersonalPatchRequest(dto, interpreter); + updateProfessionalPatchRequest(dto.getProfessionalData(), interpreter); + updateLocation(dto.getLocations(), interpreter); + + Interpreter updatedInterpreter = repository.save(interpreter); + return responseMapper.toResponseDTO(updatedInterpreter); + } + + private void updatePersonalPatchRequest(InterpreterPatchRequestDTO requestDto, Interpreter interpreter) { + if (requestDto.getName() != null) { + interpreter.setName(requestDto.getName()); + } + if (requestDto.getEmail() != null) { + interpreter.setEmail(requestDto.getEmail()); + } + if (requestDto.getPhone() != null) { + interpreter.setPhone(requestDto.getPhone()); + } + if (requestDto.getBirthday() != null) { + interpreter.setBirthday(requestDto.getBirthday()); + } + if (requestDto.getGender() != null) { + interpreter.setGender(Gender.fromString(requestDto.getGender())); + } + // TODO - atualizar foto de perfil + } + + private void updateProfessionalPatchRequest(ProfessionalDataPatchRequestDTO dto, Interpreter interpreter) { + if (dto == null) { + return; + } + if (dto.getCnpj() != null) { + interpreter.setCnpj(dto.getCnpj()); + } + if (dto.getMinValue() != null) { + interpreter.setMinValue(dto.getMinValue()); + } + if (dto.getMaxValue() != null) { + interpreter.setMaxValue(dto.getMaxValue()); + } + if (dto.getImageRights() != null) { + interpreter.setImageRights(dto.getImageRights()); + } + if (dto.getModality() != null) { + interpreter.setModality(InterpreterModality.fromString(dto.getModality())); + } + if (dto.getDescription() != null) { + interpreter.setDescription(dto.getDescription()); + } + } + + private void updateLocation(List locations, Interpreter interpreter) { + if (locations == null) { + return; + } + + interpreter.getLocations().clear(); + locations.stream() + .map(locationDTO -> LocationMapper.toDomain(locationDTO, interpreter)) + .forEach(location -> interpreter.getLocations().add(location)); + } + + private Interpreter findInterpreterById(UUID id) { + return repository.findById(id) + .orElseThrow(() -> new EntityNotFoundException("Intérprete não encontrado")); + } +} diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/PersonService.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/PersonService.java index 47917941..1afe5bf1 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/PersonService.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/PersonService.java @@ -1,6 +1,6 @@ package com.pointtils.pointtils.src.application.services; -import com.pointtils.pointtils.src.application.dto.PersonCreationDTO; +import com.pointtils.pointtils.src.application.dto.requests.PersonCreationRequestDTO; import com.pointtils.pointtils.src.application.dto.PersonDTO; import com.pointtils.pointtils.src.application.dto.requests.PersonPatchRequestDTO; import com.pointtils.pointtils.src.application.mapper.PersonResponseMapper; @@ -11,6 +11,7 @@ import jakarta.persistence.EntityNotFoundException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -24,14 +25,15 @@ public class PersonService { private final PersonRepository personRepository; + private final PasswordEncoder passwordEncoder; private final PersonResponseMapper personResponseMapper; - public PersonDTO registerPerson(PersonCreationDTO dto) { + public PersonDTO registerPerson(PersonCreationRequestDTO dto) { Person person = new Person(); person.setId(person.getId()); person.setEmail(dto.getEmail()); - person.setPassword(dto.getPassword()); + person.setPassword(passwordEncoder.encode(dto.getPassword())); person.setPhone(dto.getPhone()); person.setPicture(dto.getPicture()); person.setStatus(UserStatus.ACTIVE); diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/StateService.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/StateService.java index d7408054..056ece85 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/StateService.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/StateService.java @@ -1,7 +1,7 @@ package com.pointtils.pointtils.src.application.services; import com.pointtils.pointtils.src.application.clients.IbgeClient; -import com.pointtils.pointtils.src.application.dto.StateResponseDTO; +import com.pointtils.pointtils.src.application.dto.responses.StateResponseDTO; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/core/domain/entities/Appointment.java b/pointtils/src/main/java/com/pointtils/pointtils/src/core/domain/entities/Appointment.java index 22d5bc26..d78b8254 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/core/domain/entities/Appointment.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/core/domain/entities/Appointment.java @@ -35,10 +35,10 @@ public class Appointment { @Column(name = "id", updatable = false, nullable = false, columnDefinition = "uuid") private UUID id; - @Column(name = "UF", length = 2, nullable = false) + @Column(name = "UF", length = 2) private String uf; - @Column(name = "city", length = 255, nullable = false) + @Column(name = "city", length = 255) private String city; @Enumerated(EnumType.STRING) diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/core/domain/entities/Interpreter.java b/pointtils/src/main/java/com/pointtils/pointtils/src/core/domain/entities/Interpreter.java index e22b7e0a..144dccc0 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/core/domain/entities/Interpreter.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/core/domain/entities/Interpreter.java @@ -1,11 +1,12 @@ package com.pointtils.pointtils.src.core.domain.entities; import com.pointtils.pointtils.src.core.domain.entities.enums.InterpreterModality; +import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; -import jakarta.persistence.OneToOne; +import jakarta.persistence.OneToMany; import jakarta.persistence.PrimaryKeyJoinColumn; import jakarta.persistence.Table; import lombok.AllArgsConstructor; @@ -19,6 +20,7 @@ import org.hibernate.type.SqlTypes; import java.math.BigDecimal; +import java.util.List; @Entity @Table(name = "interpreter") @@ -49,8 +51,8 @@ public class Interpreter extends Person { @JdbcTypeCode(SqlTypes.NAMED_ENUM) private InterpreterModality modality; - @OneToOne(mappedBy = "interpreter") - private Location location; + @OneToMany(mappedBy = "interpreter", cascade = CascadeType.ALL, orphanRemoval = true) + private List locations; @Column(columnDefinition = "TEXT") private String description; diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/core/domain/entities/Location.java b/pointtils/src/main/java/com/pointtils/pointtils/src/core/domain/entities/Location.java index 25fd4cf0..d947d94b 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/core/domain/entities/Location.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/core/domain/entities/Location.java @@ -6,7 +6,7 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; -import jakarta.persistence.OneToOne; +import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; import lombok.AllArgsConstructor; import lombok.Builder; @@ -34,25 +34,17 @@ public class Location { @Column(name = "id", updatable = false, nullable = false, columnDefinition = "uuid") private UUID id; - @Column(name = "UF", length = 2) + @Column(name = "UF", length = 2, nullable = false) private String uf; - @Column(name = "city", length = 255) + @Column(name = "city", length = 255, nullable = false) private String city; - @OneToOne + @Column(name = "neighborhood", length = 255, nullable = false) + private String neighborhood; + + @ManyToOne @JsonBackReference - @JoinColumn(name = "id", nullable = false) + @JoinColumn(name = "user_id", nullable = false) private Interpreter interpreter; - - public Location(String uf, String city, Interpreter interpreter) { - this.uf = uf; - this.city = city; - this.interpreter = interpreter; - } - - public Location(String uf, String city) { - this.uf = uf; - this.city = city; - } } diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/infrastructure/configs/JwtAuthenticationFilter.java b/pointtils/src/main/java/com/pointtils/pointtils/src/infrastructure/configs/JwtAuthenticationFilter.java index f90e2fed..cf558185 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/infrastructure/configs/JwtAuthenticationFilter.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/infrastructure/configs/JwtAuthenticationFilter.java @@ -3,6 +3,7 @@ import java.io.IOException; import java.util.ArrayList; +import io.jsonwebtoken.Claims; import org.springframework.lang.NonNull; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; @@ -44,24 +45,20 @@ protected void doFilterInternal( // Verificar se o token está na blacklist apenas se não for uma requisição de logout String requestURI = request.getRequestURI(); - if (!isLogoutEndpoint(requestURI)) { - if (memoryBlacklistService.isBlacklisted(token)) { - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - response.getWriter().write("Token inválido"); - return; - } + if (!isLogoutEndpoint(requestURI) && memoryBlacklistService.isBlacklisted(token)) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + response.getWriter().write("Token inválido"); + return; } try { - final String jwt = token; - - if (jwtService.isTokenExpired(jwt)) { + if (jwtService.isTokenExpired(token)) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.getWriter().write("Unauthorized."); return; } - String subject = jwtService.extractClaim(jwt, claims -> claims.getSubject()); + String subject = jwtService.extractClaim(token, Claims::getSubject); UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(subject, null, new ArrayList<>()); SecurityContextHolder.getContext().setAuthentication(authToken); diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/infrastructure/configs/SecurityConfiguration.java b/pointtils/src/main/java/com/pointtils/pointtils/src/infrastructure/configs/SecurityConfiguration.java index 12d64de2..1c69a4f0 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/infrastructure/configs/SecurityConfiguration.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/infrastructure/configs/SecurityConfiguration.java @@ -39,7 +39,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .authorizeHttpRequests(authorize -> authorize .requestMatchers(HttpMethod.POST, "/v1/person/**").permitAll() .requestMatchers(HttpMethod.POST, "/v1/interpreters/**").permitAll() - .requestMatchers(HttpMethod.POST, "/v1/enterprise-users/**").permitAll() + .requestMatchers(HttpMethod.POST, "/v1/enterprises/**").permitAll() .requestMatchers("/v1/specialties/**").permitAll() .requestMatchers("/v1/auth/login").permitAll() .requestMatchers("/v1/auth/refresh").permitAll() diff --git a/pointtils/src/main/resources/db/migration/V4__Update_user_type_and_data.sql b/pointtils/src/main/resources/db/migration/V4__Update_user_type_and_data.sql index 6b74ea6d..b126aadc 100644 --- a/pointtils/src/main/resources/db/migration/V4__Update_user_type_and_data.sql +++ b/pointtils/src/main/resources/db/migration/V4__Update_user_type_and_data.sql @@ -12,17 +12,17 @@ VALUES ON CONFLICT (id) DO NOTHING; -- 3. Inserir usuários adicionais -INSERT INTO user_account (id, email, password, phone, picture, status, type) +INSERT INTO user_account (id, email, password, phone, status, type) VALUES - ('fc2deec4-607d-4535-8d06-0392a09ff02b', 'string', '$2a$10$JBATmY/jM85PlzukMYw4Y.N4BE6LEPHMtSTdoC0K43NE/m6kyxlbC', 'string', 'string', 'ACTIVE', 'PERSON'), - ('4d48ea39-65b5-491a-9b84-12d928f04eeb', 'teste11@teste.com', '$2a$10$xwGI1Hk6/6ySX24xbiLarORWs/JfGXJybpu.YdM4XiI.94lWgVeHm', 'string', 'string', 'ACTIVE', 'PERSON'), - ('0e588986-e77c-47a3-b9e4-5e3cc7ae211b', 'testefinal2@email.com', '$2a$10$D3TRDWl4viBguFVY3.uG5eEkZB.zbTS5892EtmxYI6r75vMzkVF6C', 'string', 'string', 'INACTIVE', 'PERSON') + ('fc2deec4-607d-4535-8d06-0392a09ff02b', 'jose.gustavo.silva@gmail.com', '$2a$10$JBATmY/jM85PlzukMYw4Y.N4BE6LEPHMtSTdoC0K43NE/m6kyxlbC', '51945454545', 'ACTIVE', 'PERSON'), + ('4d48ea39-65b5-491a-9b84-12d928f04eeb', 'thiago.medeiros@gmail.com', '$2a$10$xwGI1Hk6/6ySX24xbiLarORWs/JfGXJybpu.YdM4XiI.94lWgVeHm', '51930204125', 'ACTIVE', 'PERSON'), + ('0e588986-e77c-47a3-b9e4-5e3cc7ae211b', 'carlos.ferreira@gmail.com', '$2a$10$D3TRDWl4viBguFVY3.uG5eEkZB.zbTS5892EtmxYI6r75vMzkVF6C', '54987879952', 'INACTIVE', 'PERSON') ON CONFLICT (id) DO NOTHING; -- 4. Inserir pessoas correspondentes INSERT INTO person (id, name, gender, birthday, cpf) VALUES - ('fc2deec4-607d-4535-8d06-0392a09ff02b', 'string', 'MALE', '2025-09-19', 'string'), - ('4d48ea39-65b5-491a-9b84-12d928f04eeb', 'string', 'MALE', '2025-09-19', ''), - ('0e588986-e77c-47a3-b9e4-5e3cc7ae211b', 'string', 'MALE', '2025-09-19', '4245555') + ('fc2deec4-607d-4535-8d06-0392a09ff02b', 'José Gustavo da Silva', 'MALE', '2000-09-19', '12345678987'), + ('4d48ea39-65b5-491a-9b84-12d928f04eeb', 'Thiago Medeiros', 'MALE', '1991-01-24', '32165432111'), + ('0e588986-e77c-47a3-b9e4-5e3cc7ae211b', 'Carlos Ferreira', 'MALE', '1975-05-12', '42455554466') ON CONFLICT (id) DO NOTHING; \ No newline at end of file diff --git a/pointtils/src/main/resources/db/migration/V5__Update_specialty_names.sql b/pointtils/src/main/resources/db/migration/V5__Update_specialty_names.sql new file mode 100644 index 00000000..c15cc266 --- /dev/null +++ b/pointtils/src/main/resources/db/migration/V5__Update_specialty_names.sql @@ -0,0 +1,15 @@ +-- V5__Update_specialty_names.sql + +-- 1. Atualizar os registros existentes de especialidades para respeitar lista passada pelos stakeholders + +DELETE FROM user_specialties +WHERE specialtie_id IN (SELECT id FROM specialties WHERE name IN ('Libras', 'Tradução Simultânea')); + +DELETE FROM specialties +WHERE name IN ('Libras', 'Tradução Simultânea'); + +INSERT INTO specialties (id, name) VALUES +('f960f5b0-be40-4bff-8625-84fbe6e86588', 'Intérprete de Libras'), +('9e9a0cc0-f968-4852-9683-7fa5c138a5da', 'Guia-intérprete de Libras'), +('6539e352-1742-4f70-a484-c256fc36177a', 'Intérprete Tátil'), +('f7462efe-b4fe-4098-86ae-d1b0290a32f6', 'Intérprete de Sinais Internacionais'); \ No newline at end of file diff --git a/pointtils/src/main/resources/db/migration/V6__Update_address_data.sql b/pointtils/src/main/resources/db/migration/V6__Update_address_data.sql new file mode 100644 index 00000000..f78fdf22 --- /dev/null +++ b/pointtils/src/main/resources/db/migration/V6__Update_address_data.sql @@ -0,0 +1,57 @@ +-- V5__Update_address_data.sql + +-- 1. Adiciona bairro na tabela de localizacao +ALTER TABLE location +ADD COLUMN neighborhood VARCHAR(255); + +-- 2. Atualiza registros de localizacao existentes para preencher bairro +UPDATE location +SET neighborhood = 'Higienópolis' +WHERE city = 'São Paulo' AND neighborhood IS NULL; + +UPDATE location +SET neighborhood = 'Ipanema' +WHERE city = 'Rio de Janeiro' AND neighborhood IS NULL; + +UPDATE location +SET neighborhood = 'Anchieta' +WHERE city = 'Belo Horizonte' AND neighborhood IS NULL; + +-- 3. Atualiza colunas de localizacao para que sejam NOT NULL +ALTER TABLE location +ALTER COLUMN city SET NOT NULL; + +ALTER TABLE location +ALTER COLUMN UF SET NOT NULL; + +ALTER TABLE location +ALTER COLUMN neighborhood SET NOT NULL; + +-- 4. Atualiza colunas de appointment para que sejam nullable, dado que para casos online nao serao preenchidas +ALTER TABLE appointment +ALTER COLUMN UF DROP NOT NULL; + +ALTER TABLE appointment +ALTER COLUMN city DROP NOT NULL; + +-- 5. Adiciona colunas de endereco na tabela de appointment +ALTER TABLE appointment +ADD COLUMN neighborhood VARCHAR(255), +ADD COLUMN street VARCHAR(255), +ADD COLUMN street_number INTEGER, +ADD COLUMN address_details VARCHAR(255); + +-- 6. Atualiza registros de appointment existentes para nao preencher endereco, por ser online +UPDATE appointment +SET UF = NULL, + city = NULL +WHERE UF = 'SP' AND modality = 'ONLINE'; + +-- 7. Remove localizacoes vinculadas a usuarios que nao sao interpretes +DELETE FROM location +WHERE id IN ( + SELECT l.id + FROM location l + LEFT JOIN user_account ua ON l.user_id = ua.id + WHERE ua.type != 'INTERPRETER' +); \ No newline at end of file diff --git a/pointtils/src/test/java/com/pointtils/pointtils/src/application/clients/IbgeClientTest.java b/pointtils/src/test/java/com/pointtils/pointtils/src/application/clients/IbgeClientTest.java index 7aa88a65..4fe23928 100644 --- a/pointtils/src/test/java/com/pointtils/pointtils/src/application/clients/IbgeClientTest.java +++ b/pointtils/src/test/java/com/pointtils/pointtils/src/application/clients/IbgeClientTest.java @@ -1,7 +1,7 @@ package com.pointtils.pointtils.src.application.clients; -import com.pointtils.pointtils.src.application.dto.CityIbgeResponseDTO; -import com.pointtils.pointtils.src.application.dto.StateIbgeResponseDTO; +import com.pointtils.pointtils.src.application.dto.responses.CityIbgeResponseDTO; +import com.pointtils.pointtils.src.application.dto.responses.StateIbgeResponseDTO; import com.pointtils.pointtils.src.core.domain.exceptions.ClientTimeoutException; import jakarta.persistence.EntityNotFoundException; import org.junit.jupiter.api.BeforeEach; diff --git a/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/AuthControllerTest.java b/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/AuthControllerTest.java index 5bbe2d2d..3ea1b980 100644 --- a/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/AuthControllerTest.java +++ b/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/AuthControllerTest.java @@ -1,7 +1,7 @@ package com.pointtils.pointtils.src.application.controllers; -import com.pointtils.pointtils.src.application.dto.LoginResponseDTO; -import com.pointtils.pointtils.src.application.dto.RefreshTokenResponseDTO; +import com.pointtils.pointtils.src.application.dto.responses.LoginResponseDTO; +import com.pointtils.pointtils.src.application.dto.responses.RefreshTokenResponseDTO; import com.pointtils.pointtils.src.application.dto.TokensDTO; import com.pointtils.pointtils.src.application.dto.UserDTO; import com.pointtils.pointtils.src.application.services.AuthService; diff --git a/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/EnterpriseControllerTest.java b/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/EnterpriseControllerTest.java index cb60d5b7..e5924f5d 100644 --- a/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/EnterpriseControllerTest.java +++ b/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/EnterpriseControllerTest.java @@ -1,14 +1,12 @@ package com.pointtils.pointtils.src.application.controllers; import com.fasterxml.jackson.databind.ObjectMapper; -import com.pointtils.pointtils.src.application.dto.LocationDTO; import com.pointtils.pointtils.src.application.dto.requests.EnterprisePatchRequestDTO; import com.pointtils.pointtils.src.application.dto.requests.EnterpriseRequestDTO; import com.pointtils.pointtils.src.core.domain.entities.Enterprise; import com.pointtils.pointtils.src.core.domain.entities.enums.UserStatus; import com.pointtils.pointtils.src.infrastructure.configs.JwtService; import com.pointtils.pointtils.src.infrastructure.repositories.EnterpriseRepository; -import com.pointtils.pointtils.src.infrastructure.repositories.LocationRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -48,9 +46,6 @@ class EnterpriseControllerTest { @Autowired private EnterpriseRepository enterpriseRepository; - @Autowired - private LocationRepository locationRepository; - @MockitoBean private JwtService jwtService; @@ -63,7 +58,6 @@ class EnterpriseControllerTest { private MockMvc mockMvc; private EnterpriseRequestDTO validEnterpriseRequest; private EnterprisePatchRequestDTO validPatchRequest; - private LocationDTO locationDTO; @BeforeEach void setUp() { @@ -74,13 +68,6 @@ void setUp() { when(jwtService.isTokenExpired(anyString())).thenReturn(Boolean.FALSE); enterpriseRepository.deleteAll(); - locationRepository.deleteAll(); - - locationDTO = LocationDTO.builder() - .id(UUID.randomUUID()) - .uf("SP") - .city("São Paulo") - .build(); validEnterpriseRequest = EnterpriseRequestDTO.builder() .corporateReason("Empresa Teste LTDA") @@ -89,7 +76,6 @@ void setUp() { .password("senhaSegura123") .phone("11999887766") .picture("https://example.com/picture.jpg") - .location(locationDTO) .build(); validPatchRequest = EnterprisePatchRequestDTO.builder() @@ -102,7 +88,7 @@ void setUp() { @Test @DisplayName("Deve retornar 400 quando o ID não for um UUID válido no update (PATCH)") void shouldReturnBadRequestWhenIdIsNotValidUUIDOnPatch() throws Exception { - mockMvc.perform(patch("/v1/enterprise-users/{id}", "not-a-uuid") + mockMvc.perform(patch("/v1/enterprises/{id}", "not-a-uuid") .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(validPatchRequest))) @@ -114,7 +100,7 @@ void shouldReturnBadRequestWhenIdIsNotValidUUIDOnPatch() throws Exception { @Test @DisplayName("Deve retornar 201 quando criar empresa com sucesso") void shouldCreateEnterpriseSuccessfully() throws Exception { - mockMvc.perform(post("/v1/enterprise-users/register") + mockMvc.perform(post("/v1/enterprises/register") .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(validEnterpriseRequest))) @@ -141,10 +127,9 @@ void shouldGetUnprocessableEntityWhenCreatingEnterpriseWithInvalidCNPJ() throws .email("empresa@teste.com") .password("senhaSegura123") .phone("11999887766") - .location(locationDTO) .build(); - mockMvc.perform(post("/v1/enterprise-users/register") + mockMvc.perform(post("/v1/enterprises/register") .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(invalidCNPJRequest))) @@ -163,10 +148,9 @@ void shouldGetUnprocessableEntityWhenCreatingEnterpriseWithInvalidEmail() throws .email("email-invalido.com") .password("senhaSegura123") .phone("11999887766") - .location(locationDTO) .build(); - mockMvc.perform(post("/v1/enterprise-users/register") + mockMvc.perform(post("/v1/enterprises/register") .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(invalidEmailRequest))) @@ -185,10 +169,9 @@ void shouldGetUnprocessableEntityWhenCreatingEnterpriseWithInvalidPhone() throws .email("empresa@teste.com") .password("senhaSegura123") .phone("abc123def") - .location(locationDTO) .build(); - mockMvc.perform(post("/v1/enterprise-users/register") + mockMvc.perform(post("/v1/enterprises/register") .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(invalidPhoneRequest))) @@ -209,7 +192,7 @@ void shouldGetBadRequestWhenCreatingEnterpriseWithEmptyRequiredFields() throws E .phone("") .build(); - mockMvc.perform(post("/v1/enterprise-users/register") + mockMvc.perform(post("/v1/enterprises/register") .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(emptyFieldsRequest))) @@ -222,7 +205,7 @@ void shouldGetBadRequestWhenCreatingEnterpriseWithEmptyRequiredFields() throws E @Test @DisplayName("Deve retornar 409 quando criar empresa com CNPJ já existente") void shouldGetConflictWhenCreatingEnterpriseWithExistingCNPJ() throws Exception { - mockMvc.perform(post("/v1/enterprise-users/register") + mockMvc.perform(post("/v1/enterprises/register") .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(validEnterpriseRequest))) @@ -234,10 +217,9 @@ void shouldGetConflictWhenCreatingEnterpriseWithExistingCNPJ() throws Exception .email("novaempresa@teste.com") .password("senhaSegura123") .phone("11999887766") - .location(locationDTO) .build(); - mockMvc.perform(post("/v1/enterprise-users/register") + mockMvc.perform(post("/v1/enterprises/register") .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(duplicateCNPJRequest))) @@ -250,7 +232,7 @@ void shouldGetConflictWhenCreatingEnterpriseWithExistingCNPJ() throws Exception @Test @DisplayName("Deve retornar 409 quando criar empresa com email já existente") void shouldGetConflictWhenCreatingEnterpriseWithExistingEmail() throws Exception { - mockMvc.perform(post("/v1/enterprise-users/register") + mockMvc.perform(post("/v1/enterprises/register") .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(validEnterpriseRequest))) @@ -262,10 +244,9 @@ void shouldGetConflictWhenCreatingEnterpriseWithExistingEmail() throws Exception .email("empresa@teste.com") .password("senhaSegura123") .phone("11999887766") - .location(locationDTO) .build(); - mockMvc.perform(post("/v1/enterprise-users/register") + mockMvc.perform(post("/v1/enterprises/register") .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(duplicateEmailRequest))) @@ -278,13 +259,13 @@ void shouldGetConflictWhenCreatingEnterpriseWithExistingEmail() throws Exception @Test @DisplayName("Deve retornar 200 retornar todas as empresas com sucesso") void shouldReturnAllEnterprisesSuccessfully() throws Exception { - mockMvc.perform(post("/v1/enterprise-users/register") + mockMvc.perform(post("/v1/enterprises/register") .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(validEnterpriseRequest))) .andExpect(status().isCreated()); - mockMvc.perform(get("/v1/enterprise-users") + mockMvc.perform(get("/v1/enterprises") .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) @@ -297,7 +278,7 @@ void shouldReturnAllEnterprisesSuccessfully() throws Exception { @Test @DisplayName("Deve retornar 200 e lista vazia quando não existem empresas") void shouldGetOkWithEmptyArrayWhenNoEnterprisesExist() throws Exception { - mockMvc.perform(get("/v1/enterprise-users") + mockMvc.perform(get("/v1/enterprises") .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) @@ -307,7 +288,7 @@ void shouldGetOkWithEmptyArrayWhenNoEnterprisesExist() throws Exception { @Test @DisplayName("Deve retornar 200 quando encontrar empresa por ID com sucesso") void shouldFindEnterpriseByIdSuccessfully() throws Exception { - mockMvc.perform(post("/v1/enterprise-users/register") + mockMvc.perform(post("/v1/enterprises/register") .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(validEnterpriseRequest))) @@ -316,7 +297,7 @@ void shouldFindEnterpriseByIdSuccessfully() throws Exception { List enterprises = enterpriseRepository.findAll(); UUID createdId = enterprises.get(0).getId(); - mockMvc.perform(get("/v1/enterprise-users/{id}", createdId) + mockMvc.perform(get("/v1/enterprises/{id}", createdId) .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) @@ -333,7 +314,7 @@ void shouldFindEnterpriseByIdSuccessfully() throws Exception { @DisplayName("Deve retornar 404 quando empresa não for encontrada por ID") void shouldGetNotFoundWhenEnterpriseNotFoundById() throws Exception { UUID nonExistentId = UUID.randomUUID(); - mockMvc.perform(get("/v1/enterprise-users/{id}", nonExistentId) + mockMvc.perform(get("/v1/enterprises/{id}", nonExistentId) .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isNotFound()); @@ -342,7 +323,7 @@ void shouldGetNotFoundWhenEnterpriseNotFoundById() throws Exception { @Test @DisplayName("Deve retornar 201 quando atualizar empresa parcialmente com dados válidos") void shouldUpdateEnterprisePartiallyWithValidData() throws Exception { - mockMvc.perform(post("/v1/enterprise-users/register") + mockMvc.perform(post("/v1/enterprises/register") .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(validEnterpriseRequest))) @@ -351,15 +332,17 @@ void shouldUpdateEnterprisePartiallyWithValidData() throws Exception { List enterprises = enterpriseRepository.findAll(); UUID createdId = enterprises.get(0).getId(); - mockMvc.perform(patch("/v1/enterprise-users/{id}", createdId) + mockMvc.perform(patch("/v1/enterprises/{id}", createdId) .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(validPatchRequest))) .andExpect(status().isOk()) - .andExpect(jsonPath("$.id").value(createdId.toString())) - .andExpect(jsonPath("$.corporate_reason").value("Empresa Atualizada LTDA")) - .andExpect(jsonPath("$.email").value("novoemail@teste.com")) - .andExpect(jsonPath("$.phone").value("11888777666")); + .andExpect(jsonPath("$.success").value(Boolean.TRUE)) + .andExpect(jsonPath("$.message").value("Empresa atualizada com sucesso")) + .andExpect(jsonPath("$.data.id").value(createdId.toString())) + .andExpect(jsonPath("$.data.corporate_reason").value("Empresa Atualizada LTDA")) + .andExpect(jsonPath("$.data.email").value("novoemail@teste.com")) + .andExpect(jsonPath("$.data.phone").value("11888777666")); Optional updatedEnterprise = enterpriseRepository.findById(createdId); assertThat(updatedEnterprise).isPresent(); @@ -372,7 +355,7 @@ void shouldUpdateEnterprisePartiallyWithValidData() throws Exception { @DisplayName("Deve retornar 404 quando atualizar empresa inexistente") void shouldGetNotFoundWhenUpdatingNonExistentEnterprise() throws Exception { UUID nonExistentId = UUID.randomUUID(); - mockMvc.perform(patch("/v1/enterprise-users/{id}", nonExistentId) + mockMvc.perform(patch("/v1/enterprises/{id}", nonExistentId) .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(validPatchRequest))) @@ -382,7 +365,7 @@ void shouldGetNotFoundWhenUpdatingNonExistentEnterprise() throws Exception { @Test @DisplayName("Deve retornar 422 quando atualizar empresa com dados inválidos") void shouldGetUnprocessableEntityWhenUpdatingEnterpriseWithInvalidData() throws Exception { - mockMvc.perform(post("/v1/enterprise-users/register") + mockMvc.perform(post("/v1/enterprises/register") .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(validEnterpriseRequest))) @@ -396,7 +379,7 @@ void shouldGetUnprocessableEntityWhenUpdatingEnterpriseWithInvalidData() throws .email("invalid-email") .build(); - mockMvc.perform(patch("/v1/enterprise-users/{id}", createdId) + mockMvc.perform(patch("/v1/enterprises/{id}", createdId) .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(invalidPatchRequest))) @@ -411,7 +394,7 @@ void shouldGetUnprocessableEntityWhenUpdatingEnterpriseWithInvalidData() throws @Test @DisplayName("Deve retornar 204 quando deletar empresa com sucesso") void shouldGetWhenDeleteEnterpriseSuccessfully() throws Exception { - mockMvc.perform(post("/v1/enterprise-users/register") + mockMvc.perform(post("/v1/enterprises/register") .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(validEnterpriseRequest))) @@ -420,7 +403,7 @@ void shouldGetWhenDeleteEnterpriseSuccessfully() throws Exception { List enterprises = enterpriseRepository.findAll(); UUID createdId = enterprises.get(0).getId(); - mockMvc.perform(delete("/v1/enterprise-users/{id}", createdId) + mockMvc.perform(delete("/v1/enterprises/{id}", createdId) .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isNoContent()); @@ -434,7 +417,7 @@ void shouldGetWhenDeleteEnterpriseSuccessfully() throws Exception { @DisplayName("Deve retornar 404 ao tentar deletar uma empresa inexistente") void shouldGetNotFoundAfterTryingToRemoveUnexistingEnterprise() throws Exception { UUID randomUUID = UUID.randomUUID(); - mockMvc.perform(delete("/v1/enterprise-users/{id}", randomUUID) + mockMvc.perform(delete("/v1/enterprises/{id}", randomUUID) .with(user("testuser").roles("USER")) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isNotFound()); diff --git a/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/InterpreterControllerTest.java b/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/InterpreterControllerTest.java index c57638dc..c4aa3935 100644 --- a/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/InterpreterControllerTest.java +++ b/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/InterpreterControllerTest.java @@ -2,15 +2,13 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.pointtils.pointtils.src.application.dto.LocationDTO; -import com.pointtils.pointtils.src.application.dto.PersonDTO; import com.pointtils.pointtils.src.application.dto.requests.InterpreterBasicRequestDTO; import com.pointtils.pointtils.src.application.dto.requests.InterpreterPatchRequestDTO; -import com.pointtils.pointtils.src.application.dto.requests.PersonalRequestDTO; -import com.pointtils.pointtils.src.application.dto.requests.ProfessionalPatchRequestDTO; +import com.pointtils.pointtils.src.application.dto.requests.ProfessionalDataBasicRequestDTO; +import com.pointtils.pointtils.src.application.dto.requests.ProfessionalDataPatchRequestDTO; import com.pointtils.pointtils.src.application.dto.responses.InterpreterResponseDTO; -import com.pointtils.pointtils.src.application.dto.responses.ProfessionalInfoResponseDTO; -import com.pointtils.pointtils.src.application.dto.responses.UserResponseDTO; -import com.pointtils.pointtils.src.application.services.InterpreterRegisterService; +import com.pointtils.pointtils.src.application.dto.responses.ProfessionalDataResponseDTO; +import com.pointtils.pointtils.src.application.services.InterpreterService; import com.pointtils.pointtils.src.core.domain.entities.enums.Gender; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -24,10 +22,16 @@ import java.math.BigDecimal; import java.time.LocalDate; +import java.util.Collections; +import java.util.List; import java.util.UUID; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.when; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; @@ -45,7 +49,7 @@ class InterpreterControllerTest { private ObjectMapper objectMapper; @MockitoBean - private InterpreterRegisterService interpreterRegisterService; + private InterpreterService interpreterService; @Test @DisplayName("Deve cadastrar intérprete com sucesso usando dados básicos") @@ -54,7 +58,7 @@ void deveCadastrarInterpreterComSucessoUsandoDadosBasicos() throws Exception { InterpreterBasicRequestDTO request = createValidBasicRequest(); InterpreterResponseDTO mockResponse = createMockResponse(); - when(interpreterRegisterService.registerBasic(any(InterpreterBasicRequestDTO.class))) + when(interpreterService.registerBasic(any(InterpreterBasicRequestDTO.class))) .thenReturn(mockResponse); // Act & Assert @@ -64,53 +68,34 @@ void deveCadastrarInterpreterComSucessoUsandoDadosBasicos() throws Exception { .andExpect(status().isCreated()) .andExpect(jsonPath("$.success").value(true)) .andExpect(jsonPath("$.message").value("Intérprete cadastrado com sucesso")) - .andExpect(jsonPath("$.data.id_interpreter").exists()) - .andExpect(jsonPath("$.data.user.email").value("interpreter@exemplo.com")) - .andExpect(jsonPath("$.data.person.name").value("João Intérprete")) - .andExpect(jsonPath("$.data.user.type").value("interpreter")) - .andExpect(jsonPath("$.data.user.status").value("pending")); + .andExpect(jsonPath("$.data.id").exists()) + .andExpect(jsonPath("$.data.email").value("interpreter@exemplo.com")) + .andExpect(jsonPath("$.data.name").value("João Intérprete")) + .andExpect(jsonPath("$.data.type").value("interpreter")) + .andExpect(jsonPath("$.data.status").value("pending")); } @Test @DisplayName("Deve retornar 400 quando dados pessoais não forem fornecidos") void deveRetornar400QuandoDadosPessoaisNaoFornecidos() throws Exception { // Arrange - InterpreterBasicRequestDTO request = new InterpreterBasicRequestDTO(); - request.setLocation(new LocationDTO("RS", "Porto Alegre")); - - // Act & Assert - mockMvc.perform(post("/v1/interpreters/register") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(request))) - .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.message").value("Dados inválidos: [Dados pessoais devem ser preenchidos]")); - } - - @Test - @DisplayName("Deve retornar 400 quando localização não for fornecida") - void deveRetornar400QuandoLocalizacaoNaoFornecida() throws Exception { - // Arrange - InterpreterBasicRequestDTO request = new InterpreterBasicRequestDTO(); - request.setPersonalData(createValidPersonalData()); + InterpreterBasicRequestDTO request = createValidBasicRequest(); + request.setName(null); // Act & Assert mockMvc.perform(post("/v1/interpreters/register") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.message").value("Dados inválidos: [Localização deve ser preenchida]")); + .andExpect(jsonPath("$.message").value("Dados inválidos: [Nome deve ser preenchido]")); } @Test @DisplayName("Deve retornar 422 quando email for inválido") void deveRetornar422QuandoEmailForInvalido() throws Exception { // Arrange - PersonalRequestDTO personalData = createValidPersonalData(); - personalData.setEmail("email-invalido"); - - InterpreterBasicRequestDTO request = new InterpreterBasicRequestDTO(); - request.setPersonalData(personalData); - request.setLocation(new LocationDTO("RS", "Porto Alegre")); + InterpreterBasicRequestDTO request = createValidBasicRequest(); + request.setEmail("email-invalido"); // Act & Assert mockMvc.perform(post("/v1/interpreters/register") @@ -124,19 +109,14 @@ void deveRetornar422QuandoEmailForInvalido() throws Exception { @DisplayName("Deve retornar 422 quando CPF for inválido") void deveRetornar422QuandoCpfForInvalido() throws Exception { // Arrange - PersonalRequestDTO personalData = createValidPersonalData(); - personalData.setCpf("123"); // CPF inválido - - InterpreterBasicRequestDTO request = new InterpreterBasicRequestDTO(); - request.setPersonalData(personalData); - request.setLocation(new LocationDTO("RS", "Porto Alegre")); + InterpreterBasicRequestDTO request = createValidBasicRequest(); + request.setCpf("123"); // CPF inválido // Act & Assert mockMvc.perform(post("/v1/interpreters/register") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) - .andExpect(status().isUnprocessableEntity()) - .andExpect(jsonPath("$.message").value("Dados inválidos: [CPF inválido]")); + .andExpect(status().isUnprocessableEntity()); } @Test @@ -146,7 +126,7 @@ void deveCompletarDadosProfissionaisAposCadastroInicial() throws Exception { UUID interpreterId = UUID.randomUUID(); InterpreterPatchRequestDTO patchRequest = new InterpreterPatchRequestDTO(); - ProfessionalPatchRequestDTO professionalData = ProfessionalPatchRequestDTO.builder() + ProfessionalDataPatchRequestDTO professionalData = ProfessionalDataPatchRequestDTO.builder() .cnpj("12345678000195") .minValue(new BigDecimal("100.00")) .maxValue(new BigDecimal("500.00")) @@ -159,7 +139,7 @@ void deveCompletarDadosProfissionaisAposCadastroInicial() throws Exception { InterpreterResponseDTO mockResponse = createMockResponseWithProfessionalData(); - when(interpreterRegisterService.updatePartial(any(UUID.class), any(InterpreterPatchRequestDTO.class))) + when(interpreterService.updatePartial(any(UUID.class), any(InterpreterPatchRequestDTO.class))) .thenReturn(mockResponse); // Act & Assert @@ -169,52 +149,81 @@ void deveCompletarDadosProfissionaisAposCadastroInicial() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$.success").value(true)) .andExpect(jsonPath("$.message").value("Intérprete atualizado com sucesso")) - .andExpect(jsonPath("$.data.professional_info.cnpj").value("12345678000195")) - .andExpect(jsonPath("$.data.professional_info.min_value").value(100.00)) - .andExpect(jsonPath("$.data.professional_info.max_value").value(500.00)) - .andExpect(jsonPath("$.data.professional_info.image_rights").value(true)) - .andExpect(jsonPath("$.data.professional_info.modality").value("presencial")) - .andExpect(jsonPath("$.data.professional_info.description").value("Intérprete experiente em LIBRAS")); + .andExpect(jsonPath("$.data.professional_data.cnpj").value("12345678000195")) + .andExpect(jsonPath("$.data.professional_data.min_value").value(100.00)) + .andExpect(jsonPath("$.data.professional_data.max_value").value(500.00)) + .andExpect(jsonPath("$.data.professional_data.image_rights").value(true)) + .andExpect(jsonPath("$.data.professional_data.modality").value("presencial")) + .andExpect(jsonPath("$.data.professional_data.description").value("Intérprete experiente em LIBRAS")); } - private InterpreterBasicRequestDTO createValidBasicRequest() { - InterpreterBasicRequestDTO request = new InterpreterBasicRequestDTO(); - request.setPersonalData(createValidPersonalData()); - request.setLocation(new LocationDTO("RS", "Porto Alegre")); - return request; + @Test + @DisplayName("Deve encontrar intérprete por ID com sucesso") + void deveBuscarInterpreterPorIdComSucesso() throws Exception { + // Arrange + UUID interpreterId = UUID.randomUUID(); + InterpreterResponseDTO mockResponse = createMockResponse(); + when(interpreterService.findById(interpreterId)).thenReturn(mockResponse); + + // Act & Assert + mockMvc.perform(get("/v1/interpreters/{interpreterId}", interpreterId) + .with(user("testuser").roles("USER")) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.message").value("Intérprete encontrado com sucesso")) + .andExpect(jsonPath("$.data.id").exists()) + .andExpect(jsonPath("$.data.email").value("interpreter@exemplo.com")); } - private PersonalRequestDTO createValidPersonalData() { - return PersonalRequestDTO.builder() - .name("João Intérprete") - .email("interpreter@exemplo.com") - .password("senha123") - .phone("51999999999") - .gender("M") - .birthday(LocalDate.of(1990, 1, 1)) - .cpf("12345678901") - .picture("picture_url") - .build(); + @Test + @DisplayName("Deve deletar intérprete por ID com sucesso") + void deveDeletarInterpreterPorIdComSucesso() throws Exception { + // Arrange + UUID interpreterId = UUID.randomUUID(); + doNothing().when(interpreterService).delete(interpreterId); + + // Act & Assert + mockMvc.perform(delete("/v1/interpreters/{interpreterId}", interpreterId) + .with(user("testuser").roles("USER")) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isNoContent()); } - private InterpreterResponseDTO createMockResponse() { - UserResponseDTO user = UserResponseDTO.builder() - .id(UUID.randomUUID()) - .email("interpreter@exemplo.com") - .type("interpreter") - .status("pending") - .phone("51999999999") - .picture("picture_url") - .build(); + @Test + @DisplayName("Deve encontrar todos os intérpretes com sucesso") + void deveBuscarInterpretesComSucesso() throws Exception { + // Arrange + InterpreterResponseDTO mockResponse = createMockResponse(); + when(interpreterService.findAll()).thenReturn(List.of(mockResponse)); - PersonDTO person = PersonDTO.builder() - .name("João Intérprete") - .gender(Gender.MALE) - .birthday(LocalDate.of(1990, 1, 1)) - .cpf("12345678901") - .build(); + // Act & Assert + mockMvc.perform(get("/v1/interpreters") + .with(user("testuser").roles("USER")) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.message").value("Intérpretes encontrados com sucesso")) + .andExpect(jsonPath("$.data[0].id").exists()) + .andExpect(jsonPath("$.data[0].email").value("interpreter@exemplo.com")); + } + + private InterpreterBasicRequestDTO createValidBasicRequest() { + InterpreterBasicRequestDTO request = new InterpreterBasicRequestDTO(); + request.setName("João Intérprete"); + request.setEmail("interpreter@exemplo.com"); + request.setPassword("senha123"); + request.setPhone("51999999999"); + request.setGender("M"); + request.setBirthday(LocalDate.of(1990, 1, 1)); + request.setCpf("12345678901"); + request.setPicture("picture_url"); + request.setProfessionalData(new ProfessionalDataBasicRequestDTO("12345678000195")); + return request; + } - ProfessionalInfoResponseDTO professionalInfo = ProfessionalInfoResponseDTO.builder() + private InterpreterResponseDTO createMockResponse() { + ProfessionalDataResponseDTO professionalInfo = ProfessionalDataResponseDTO.builder() .cnpj(null) .rating(new BigDecimal("0.0")) .minValue(new BigDecimal("0.0")) @@ -224,35 +233,25 @@ private InterpreterResponseDTO createMockResponse() { .description(null) .build(); - InterpreterResponseDTO response = new InterpreterResponseDTO(); - response.setIdInterpreter(UUID.randomUUID()); - response.setUser(user); - response.setPerson(person); - response.setProfessionalInfo(professionalInfo); - response.setLocation(new LocationDTO("RS", "Porto Alegre")); - response.setSpecialties(null); - - return response; - } - - private InterpreterResponseDTO createMockResponseWithProfessionalData() { - UserResponseDTO user = UserResponseDTO.builder() + return InterpreterResponseDTO.builder() .id(UUID.randomUUID()) .email("interpreter@exemplo.com") .type("interpreter") .status("pending") .phone("51999999999") .picture("picture_url") - .build(); - - PersonDTO person = PersonDTO.builder() .name("João Intérprete") .gender(Gender.MALE) .birthday(LocalDate.of(1990, 1, 1)) .cpf("12345678901") + .locations(List.of(new LocationDTO(UUID.randomUUID(), "RS", "Porto Alegre", "São João"))) + .specialties(Collections.emptyList()) + .professionalData(professionalInfo) .build(); + } - ProfessionalInfoResponseDTO professionalInfo = ProfessionalInfoResponseDTO.builder() + private InterpreterResponseDTO createMockResponseWithProfessionalData() { + ProfessionalDataResponseDTO professionalInfo = ProfessionalDataResponseDTO.builder() .cnpj("12345678000195") .rating(new BigDecimal("0.0")) .minValue(new BigDecimal("100.00")) @@ -262,14 +261,20 @@ private InterpreterResponseDTO createMockResponseWithProfessionalData() { .description("Intérprete experiente em LIBRAS") .build(); - InterpreterResponseDTO response = new InterpreterResponseDTO(); - response.setIdInterpreter(UUID.randomUUID()); - response.setUser(user); - response.setPerson(person); - response.setProfessionalInfo(professionalInfo); - response.setLocation(new LocationDTO("RS", "Porto Alegre")); - response.setSpecialties(null); - - return response; + return InterpreterResponseDTO.builder() + .id(UUID.randomUUID()) + .email("interpreter@exemplo.com") + .type("interpreter") + .status("pending") + .phone("51999999999") + .picture("picture_url") + .name("João Intérprete") + .gender(Gender.MALE) + .birthday(LocalDate.of(1990, 1, 1)) + .cpf("12345678901") + .locations(List.of(new LocationDTO(UUID.randomUUID(), "RS", "Porto Alegre", "São João"))) + .specialties(Collections.emptyList()) + .professionalData(professionalInfo) + .build(); } } diff --git a/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/SpecialtyControllerTest.java b/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/SpecialtyControllerTest.java index c6ff22a3..8db82547 100644 --- a/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/SpecialtyControllerTest.java +++ b/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/SpecialtyControllerTest.java @@ -1,7 +1,7 @@ package com.pointtils.pointtils.src.application.controllers; import com.fasterxml.jackson.databind.ObjectMapper; -import com.pointtils.pointtils.src.application.dto.UpdateSpecialtyRequestDTO; +import com.pointtils.pointtils.src.application.dto.requests.UpdateSpecialtyRequestDTO; import com.pointtils.pointtils.src.application.services.SpecialtyService; import com.pointtils.pointtils.src.core.domain.entities.Specialty; import com.pointtils.pointtils.src.infrastructure.configs.GlobalExceptionHandler; diff --git a/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/StateControllerTest.java b/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/StateControllerTest.java new file mode 100644 index 00000000..cbe6fb70 --- /dev/null +++ b/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/StateControllerTest.java @@ -0,0 +1,95 @@ +package com.pointtils.pointtils.src.application.controllers; + +import com.pointtils.pointtils.src.application.dto.StateDataDTO; +import com.pointtils.pointtils.src.application.dto.responses.StateResponseDTO; +import com.pointtils.pointtils.src.application.services.StateService; +import com.pointtils.pointtils.src.infrastructure.configs.GlobalExceptionHandler; +import com.pointtils.pointtils.src.infrastructure.configs.JwtAuthenticationFilter; +import com.pointtils.pointtils.src.infrastructure.configs.JwtService; +import com.pointtils.pointtils.src.infrastructure.configs.MemoryBlacklistService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Import; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +import java.util.List; + +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.when; +import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@ActiveProfiles("test") +@SpringBootTest(classes = StateController.class) +@Import(JwtAuthenticationFilter.class) +class StateControllerTest { + + @MockitoBean + private JwtService jwtService; + @MockitoBean + private StateService stateService; + @MockitoBean + private MemoryBlacklistService memoryBlacklistService; + @Autowired + private JwtAuthenticationFilter jwtAuthenticationFilter; + @Autowired + private StateController stateController; + private MockMvc mockMvc; + + @BeforeEach + void setup() { + this.mockMvc = MockMvcBuilders.standaloneSetup(stateController) + .setControllerAdvice(new GlobalExceptionHandler()) + .apply(springSecurity(jwtAuthenticationFilter)) + .build(); + when(jwtService.isTokenExpired(anyString())).thenReturn(Boolean.FALSE); + } + + @Test + @DisplayName("Deve retornar 200 e a lista de estados ao chamar o endpoint /v1/states") + void shouldGetOkResponseForGetStatesEndpoint() throws Exception { + StateResponseDTO mockResponse = new StateResponseDTO(true, "Sucesso", + List.of(new StateDataDTO("RS"))); + + when(stateService.getAllStates()).thenReturn(mockResponse); + + mockMvc.perform(MockMvcRequestBuilders + .get("/v1/states") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, "Bearer valid_token")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.message").value("Sucesso")) + .andExpect(jsonPath("$.data[0].name").value("RS")); + } + + @Test + @DisplayName("Deve retornar 200 e a lista de municípios ao chamar o endpoint /v1/states/{id}/cities") + void shouldGetOkResponseForGetCitiesByStateEndpoint() throws Exception { + StateResponseDTO mockResponse = new StateResponseDTO(true, "Sucesso", + List.of(new StateDataDTO("Porto Alegre"))); + + when(stateService.getCitiesByState("RS")).thenReturn(mockResponse); + + mockMvc.perform(MockMvcRequestBuilders + .get("/v1/states/RS/cities") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, "Bearer valid_token")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.message").value("Sucesso")) + .andExpect(jsonPath("$.data[0].name").value("Porto Alegre")); + } +} \ No newline at end of file diff --git a/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/UserSpecialtyControllerTest.java b/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/UserSpecialtyControllerTest.java index 955c1d65..7abec226 100644 --- a/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/UserSpecialtyControllerTest.java +++ b/pointtils/src/test/java/com/pointtils/pointtils/src/application/controllers/UserSpecialtyControllerTest.java @@ -1,7 +1,7 @@ package com.pointtils.pointtils.src.application.controllers; import com.fasterxml.jackson.databind.ObjectMapper; -import com.pointtils.pointtils.src.application.dto.AddUserSpecialtiesRequestDTO; +import com.pointtils.pointtils.src.application.dto.requests.AddUserSpecialtiesRequestDTO; import com.pointtils.pointtils.src.application.dto.UserSpecialtyDTO; import com.pointtils.pointtils.src.application.services.UserSpecialtyService; import com.pointtils.pointtils.src.core.domain.entities.Specialty; diff --git a/pointtils/src/test/java/com/pointtils/pointtils/src/application/dto/RefreshTokenRequestDTOTest.java b/pointtils/src/test/java/com/pointtils/pointtils/src/application/dto/RefreshTokenRequestDTOTest.java index 6336f507..4da68079 100644 --- a/pointtils/src/test/java/com/pointtils/pointtils/src/application/dto/RefreshTokenRequestDTOTest.java +++ b/pointtils/src/test/java/com/pointtils/pointtils/src/application/dto/RefreshTokenRequestDTOTest.java @@ -1,5 +1,6 @@ package com.pointtils.pointtils.src.application.dto; +import com.pointtils.pointtils.src.application.dto.requests.RefreshTokenRequestDTO; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/pointtils/src/test/java/com/pointtils/pointtils/src/application/dto/RefreshTokenResponseDTOTest.java b/pointtils/src/test/java/com/pointtils/pointtils/src/application/dto/RefreshTokenResponseDTOTest.java index 83dcf4bf..f15b064c 100644 --- a/pointtils/src/test/java/com/pointtils/pointtils/src/application/dto/RefreshTokenResponseDTOTest.java +++ b/pointtils/src/test/java/com/pointtils/pointtils/src/application/dto/RefreshTokenResponseDTOTest.java @@ -1,5 +1,6 @@ package com.pointtils.pointtils.src.application.dto; +import com.pointtils.pointtils.src.application.dto.responses.RefreshTokenResponseDTO; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/pointtils/src/test/java/com/pointtils/pointtils/src/application/mapper/LocationMapperTest.java b/pointtils/src/test/java/com/pointtils/pointtils/src/application/mapper/LocationMapperTest.java new file mode 100644 index 00000000..861d23c3 --- /dev/null +++ b/pointtils/src/test/java/com/pointtils/pointtils/src/application/mapper/LocationMapperTest.java @@ -0,0 +1,61 @@ +package com.pointtils.pointtils.src.application.mapper; + +import com.pointtils.pointtils.src.application.dto.LocationDTO; +import com.pointtils.pointtils.src.application.dto.requests.LocationRequestDTO; +import com.pointtils.pointtils.src.core.domain.entities.Interpreter; +import com.pointtils.pointtils.src.core.domain.entities.Location; +import org.junit.jupiter.api.Test; + +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +class LocationMapperTest { + + @Test + void shouldMapLocationToDto() { + Interpreter interpreter = new Interpreter(); + Location location = Location.builder() + .id(UUID.randomUUID()) + .uf("SP") + .city("São Paulo") + .neighborhood("Higienópolis") + .interpreter(interpreter) + .build(); + + LocationDTO actualDTO = LocationMapper.toDto(location); + assertNotNull(actualDTO); + assertEquals("SP", actualDTO.getUf()); + assertEquals("São Paulo", actualDTO.getCity()); + assertEquals("Higienópolis", actualDTO.getNeighborhood()); + } + + @Test + void shouldMapNullLocationToNullDto() { + assertNull(LocationMapper.toDto(null)); + } + + @Test + void shouldMapRequestDtoToLocation() { + Interpreter interpreter = new Interpreter(); + LocationRequestDTO dto = new LocationRequestDTO(); + dto.setUf("SP"); + dto.setCity("São Paulo"); + dto.setNeighborhood("Higienópolis"); + + Location location = LocationMapper.toDomain(dto, interpreter); + assertNotNull(location); + assertEquals("SP", location.getUf()); + assertEquals("São Paulo", location.getCity()); + assertEquals("Higienópolis", location.getNeighborhood()); + assertEquals(interpreter, location.getInterpreter()); + } + + @Test + void shouldMapNullDtoToNullLocation() { + Interpreter interpreter = new Interpreter(); + assertNull(LocationMapper.toDomain(null, interpreter)); + } +} diff --git a/pointtils/src/test/java/com/pointtils/pointtils/src/application/mapper/PersonResponseMapperTest.java b/pointtils/src/test/java/com/pointtils/pointtils/src/application/mapper/PersonResponseMapperTest.java new file mode 100644 index 00000000..3d9d5d33 --- /dev/null +++ b/pointtils/src/test/java/com/pointtils/pointtils/src/application/mapper/PersonResponseMapperTest.java @@ -0,0 +1,79 @@ +package com.pointtils.pointtils.src.application.mapper; + +import com.pointtils.pointtils.src.core.domain.entities.Person; +import com.pointtils.pointtils.src.core.domain.entities.enums.Gender; +import com.pointtils.pointtils.src.core.domain.entities.enums.UserStatus; +import com.pointtils.pointtils.src.core.domain.entities.enums.UserTypeE; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.time.LocalDate; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +class PersonResponseMapperTest { + + private PersonResponseMapper personResponseMapper; + + @BeforeEach + void setUp() { + personResponseMapper = new PersonResponseMapper(); + } + + @Test + @DisplayName("Deve mapear dados da pessoa para DTO e mascarar CPF") + void shouldMapPersonToDtoWithMaskedCPF() { + UUID id = UUID.randomUUID(); + LocalDate birthDate = LocalDate.of(2000, 10, 26); + Person person = Person.builder() + .id(id) + .name("Meu Nome") + .cpf("04884554774") + .email("meuemail@gmail.com") + .password("minhasenha123") + .birthday(birthDate) + .gender(Gender.MALE) + .phone("54963636363") + .picture("minhafoto") + .status(UserStatus.ACTIVE) + .type(UserTypeE.PERSON) + .build(); + + var actualDTO = personResponseMapper.toResponseDTO(person); + assertEquals(id, actualDTO.getId()); + assertEquals("Meu Nome", actualDTO.getName()); + assertEquals("048.***.***-74", actualDTO.getCpf()); + assertEquals("meuemail@gmail.com", actualDTO.getEmail()); + assertEquals(Gender.MALE, actualDTO.getGender()); + assertEquals("54963636363", actualDTO.getPhone()); + assertEquals("minhafoto", actualDTO.getPicture()); + assertEquals(birthDate, actualDTO.getBirthday()); + assertEquals(UserStatus.ACTIVE, actualDTO.getStatus()); + assertEquals(UserTypeE.PERSON, actualDTO.getType()); + } + + @Test + @DisplayName("Deve mapear dados da pessoa para DTO sem mascarar CPF se for nulo") + void shouldNotMaskNullCPF() { + UUID id = UUID.randomUUID(); + Person person = Person.builder().id(id).build(); + + var actualDTO = personResponseMapper.toResponseDTO(person); + assertEquals(id, actualDTO.getId()); + assertNull(actualDTO.getCpf()); + } + + @Test + @DisplayName("Deve mapear dados da pessoa para DTO sem mascarar CPF não tiver 11 dígitos") + void shouldNotMaskInvalidCPF() { + UUID id = UUID.randomUUID(); + Person person = Person.builder().id(id).cpf("123").build(); + + var actualDTO = personResponseMapper.toResponseDTO(person); + assertEquals(id, actualDTO.getId()); + assertEquals("123", actualDTO.getCpf()); + } +} diff --git a/pointtils/src/test/java/com/pointtils/pointtils/src/application/services/AuthServiceTest.java b/pointtils/src/test/java/com/pointtils/pointtils/src/application/services/AuthServiceTest.java index 5a8b762f..c55d2598 100644 --- a/pointtils/src/test/java/com/pointtils/pointtils/src/application/services/AuthServiceTest.java +++ b/pointtils/src/test/java/com/pointtils/pointtils/src/application/services/AuthServiceTest.java @@ -1,8 +1,8 @@ package com.pointtils.pointtils.src.application.services; -import com.pointtils.pointtils.src.application.dto.LoginRequestDTO; -import com.pointtils.pointtils.src.application.dto.LoginResponseDTO; -import com.pointtils.pointtils.src.application.dto.RefreshTokenResponseDTO; +import com.pointtils.pointtils.src.application.dto.requests.LoginRequestDTO; +import com.pointtils.pointtils.src.application.dto.responses.LoginResponseDTO; +import com.pointtils.pointtils.src.application.dto.responses.RefreshTokenResponseDTO; import com.pointtils.pointtils.src.core.domain.entities.Person; import com.pointtils.pointtils.src.core.domain.entities.enums.UserStatus; import com.pointtils.pointtils.src.core.domain.entities.enums.UserTypeE; diff --git a/pointtils/src/test/java/com/pointtils/pointtils/src/application/services/EnterpriseServiceTest.java b/pointtils/src/test/java/com/pointtils/pointtils/src/application/services/EnterpriseServiceTest.java index dfbbeba9..6052e912 100644 --- a/pointtils/src/test/java/com/pointtils/pointtils/src/application/services/EnterpriseServiceTest.java +++ b/pointtils/src/test/java/com/pointtils/pointtils/src/application/services/EnterpriseServiceTest.java @@ -4,27 +4,29 @@ import com.pointtils.pointtils.src.application.dto.requests.EnterpriseRequestDTO; import com.pointtils.pointtils.src.application.dto.responses.EnterpriseResponseDTO; import com.pointtils.pointtils.src.core.domain.entities.Enterprise; -import com.pointtils.pointtils.src.application.dto.LocationDTO; import com.pointtils.pointtils.src.core.domain.entities.enums.UserStatus; import com.pointtils.pointtils.src.core.domain.entities.enums.UserTypeE; import com.pointtils.pointtils.src.core.domain.exceptions.DuplicateResourceException; import com.pointtils.pointtils.src.infrastructure.repositories.EnterpriseRepository; import com.pointtils.pointtils.src.infrastructure.repositories.UserRepository; import jakarta.persistence.EntityNotFoundException; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.MockitoAnnotations; +import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.security.crypto.password.PasswordEncoder; import java.util.List; import java.util.Optional; import java.util.UUID; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.when; +@ExtendWith(MockitoExtension.class) class EnterpriseServiceTest { @Mock private EnterpriseRepository enterpriseRepository; @@ -35,11 +37,6 @@ class EnterpriseServiceTest { @InjectMocks private EnterpriseService enterpriseService; - @BeforeEach - void setUp() { - MockitoAnnotations.openMocks(this); - } - @Test void registerEnterprise_shouldSaveAndReturnResponseDTO() { EnterpriseRequestDTO dto = new EnterpriseRequestDTO(); @@ -49,10 +46,6 @@ void registerEnterprise_shouldSaveAndReturnResponseDTO() { dto.setPassword("pass"); dto.setPhone("123456789"); dto.setPicture("pic.png"); - LocationDTO locationDTO = new LocationDTO(); - locationDTO.setUf("RS"); - locationDTO.setCity("Porto Alegre"); - dto.setLocation(locationDTO); when(enterpriseRepository.existsByCnpj(dto.getCnpj())).thenReturn(false); when(userRepository.existsByEmail(dto.getEmail())).thenReturn(false); diff --git a/pointtils/src/test/java/com/pointtils/pointtils/src/application/services/InterpreterServiceTest.java b/pointtils/src/test/java/com/pointtils/pointtils/src/application/services/InterpreterServiceTest.java new file mode 100644 index 00000000..aa2a06c4 --- /dev/null +++ b/pointtils/src/test/java/com/pointtils/pointtils/src/application/services/InterpreterServiceTest.java @@ -0,0 +1,240 @@ +package com.pointtils.pointtils.src.application.services; + +import com.pointtils.pointtils.src.application.dto.requests.InterpreterBasicRequestDTO; +import com.pointtils.pointtils.src.application.dto.requests.InterpreterPatchRequestDTO; +import com.pointtils.pointtils.src.application.dto.requests.LocationRequestDTO; +import com.pointtils.pointtils.src.application.dto.requests.ProfessionalDataBasicRequestDTO; +import com.pointtils.pointtils.src.application.dto.requests.ProfessionalDataPatchRequestDTO; +import com.pointtils.pointtils.src.application.dto.responses.InterpreterResponseDTO; +import com.pointtils.pointtils.src.application.mapper.InterpreterResponseMapper; +import com.pointtils.pointtils.src.core.domain.entities.Interpreter; +import com.pointtils.pointtils.src.core.domain.entities.Location; +import com.pointtils.pointtils.src.core.domain.entities.enums.Gender; +import com.pointtils.pointtils.src.core.domain.entities.enums.InterpreterModality; +import com.pointtils.pointtils.src.core.domain.entities.enums.UserStatus; +import com.pointtils.pointtils.src.infrastructure.repositories.InterpreterRepository; +import jakarta.persistence.EntityNotFoundException; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.security.crypto.password.PasswordEncoder; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class InterpreterServiceTest { + + @Mock + private InterpreterRepository repository; + @Mock + private PasswordEncoder passwordEncoder; + @Mock + private InterpreterResponseMapper responseMapper; + @InjectMocks + private InterpreterService service; + + @Test + void shouldRegisterNewInterpreter() { + Interpreter interpreter = new Interpreter(); + InterpreterResponseDTO mappedResponse = new InterpreterResponseDTO(); + ArgumentCaptor interpreterArgumentCaptor = ArgumentCaptor.forClass(Interpreter.class); + when(repository.save(interpreterArgumentCaptor.capture())).thenReturn(interpreter); + when(responseMapper.toResponseDTO(interpreter)).thenReturn(mappedResponse); + when(passwordEncoder.encode("senha123")).thenReturn("hashedPassword"); + + assertEquals(mappedResponse, service.registerBasic(createValidBasicRequest())); + assertEquals("João Intérprete", interpreterArgumentCaptor.getValue().getName()); + assertEquals("interpreter@exemplo.com", interpreterArgumentCaptor.getValue().getEmail()); + assertEquals("51999999999", interpreterArgumentCaptor.getValue().getPhone()); + assertEquals("hashedPassword", interpreterArgumentCaptor.getValue().getPassword()); + assertEquals("PENDING", interpreterArgumentCaptor.getValue().getStatus().name()); + assertEquals("INTERPRETER", interpreterArgumentCaptor.getValue().getType().name()); + assertEquals("picture_url", interpreterArgumentCaptor.getValue().getPicture()); + assertEquals("MALE", interpreterArgumentCaptor.getValue().getGender().name()); + assertEquals("1990-01-01", interpreterArgumentCaptor.getValue().getBirthday().toString()); + assertEquals(BigDecimal.ZERO, interpreterArgumentCaptor.getValue().getRating()); + assertEquals(BigDecimal.ZERO, interpreterArgumentCaptor.getValue().getMinValue()); + assertEquals(BigDecimal.ZERO, interpreterArgumentCaptor.getValue().getMaxValue()); + assertEquals("", interpreterArgumentCaptor.getValue().getDescription()); + assertEquals("ALL", interpreterArgumentCaptor.getValue().getModality().name()); + assertFalse(interpreterArgumentCaptor.getValue().getImageRights()); + } + + @Test + void shouldFindAll() { + UUID id = UUID.randomUUID(); + Interpreter foundInterpreter = Interpreter.builder().id(id).build(); + InterpreterResponseDTO mappedResponse = InterpreterResponseDTO.builder().id(id).build(); + when(repository.findAll()).thenReturn(List.of(foundInterpreter)); + when(responseMapper.toResponseDTO(foundInterpreter)).thenReturn(mappedResponse); + + assertThat(service.findAll()) + .hasSize(1) + .contains(mappedResponse); + } + + @Test + void shouldFindById() { + UUID id = UUID.randomUUID(); + Interpreter foundInterpreter = Interpreter.builder().id(id).build(); + InterpreterResponseDTO mappedResponse = InterpreterResponseDTO.builder().id(id).build(); + when(repository.findById(id)).thenReturn(Optional.of(foundInterpreter)); + when(responseMapper.toResponseDTO(foundInterpreter)).thenReturn(mappedResponse); + + assertEquals(mappedResponse, service.findById(id)); + } + + @Test + void shouldThrowExceptionIfFindByIdHasNoInterpreter() { + UUID id = UUID.randomUUID(); + when(repository.findById(id)).thenReturn(Optional.empty()); + + assertThrows(EntityNotFoundException.class, () -> service.findById(id)); + } + + @Test + void shouldDeleteById() { + UUID id = UUID.randomUUID(); + Interpreter foundInterpreter = Interpreter.builder().id(id).build(); + ArgumentCaptor interpreterArgumentCaptor = ArgumentCaptor.forClass(Interpreter.class); + when(repository.findById(id)).thenReturn(Optional.of(foundInterpreter)); + when(repository.save(interpreterArgumentCaptor.capture())).thenReturn(foundInterpreter); + + assertDoesNotThrow(() -> service.delete(id)); + assertEquals(UserStatus.INACTIVE, interpreterArgumentCaptor.getValue().getStatus()); + } + + @Test + void shouldThrowExceptionIfDeleteByIdHasNoInterpreter() { + UUID id = UUID.randomUUID(); + when(repository.findById(id)).thenReturn(Optional.empty()); + + assertThrows(EntityNotFoundException.class, () -> service.delete(id)); + } + + @Test + void shouldUpdateAllInterpreterData() { + UUID interpreterId = UUID.randomUUID(); + Interpreter foundInterpreter = Interpreter.builder().id(interpreterId).build(); + Location oldLocation = Location.builder() + .id(UUID.randomUUID()) + .uf("RS") + .city("Porto Alegre") + .neighborhood("São João") + .interpreter(foundInterpreter) + .build(); + foundInterpreter.setLocations(new ArrayList<>(List.of(oldLocation))); + InterpreterResponseDTO mappedResponse = InterpreterResponseDTO.builder().id(interpreterId).build(); + ArgumentCaptor interpreterArgumentCaptor = ArgumentCaptor.forClass(Interpreter.class); + + when(repository.findById(interpreterId)).thenReturn(Optional.of(foundInterpreter)); + when(repository.save(interpreterArgumentCaptor.capture())).thenReturn(foundInterpreter); + when(responseMapper.toResponseDTO(foundInterpreter)).thenReturn(mappedResponse); + + assertEquals(mappedResponse, service.updatePartial(interpreterId, createValidPatchRequest())); + assertEquals("Novo Nome", interpreterArgumentCaptor.getValue().getName()); + assertEquals("novo.nome@email.com", interpreterArgumentCaptor.getValue().getEmail()); + assertEquals("51988888888", interpreterArgumentCaptor.getValue().getPhone()); + assertEquals(Gender.FEMALE, interpreterArgumentCaptor.getValue().getGender()); + assertEquals("98765432000196", interpreterArgumentCaptor.getValue().getCnpj()); + assertEquals(InterpreterModality.ONLINE, interpreterArgumentCaptor.getValue().getModality()); + assertEquals(250, interpreterArgumentCaptor.getValue().getMinValue().doubleValue()); + assertEquals(500, interpreterArgumentCaptor.getValue().getMaxValue().doubleValue()); + assertEquals("Teste", interpreterArgumentCaptor.getValue().getDescription()); + assertFalse(interpreterArgumentCaptor.getValue().getImageRights()); + assertThat(interpreterArgumentCaptor.getValue().getLocations()) + .hasSize(1) + .anyMatch(loc -> loc.getUf().equals("SP") && + loc.getCity().equals("São Paulo") && + loc.getNeighborhood().equals("Higienópolis") && + loc.getInterpreter().getId().equals(interpreterId) + ); + } + + @Test + void shouldUpdateInterpreterLocationById() { + UUID interpreterId = UUID.randomUUID(); + Interpreter foundInterpreter = Interpreter.builder().id(interpreterId).build(); + Location oldLocation = Location.builder() + .id(UUID.randomUUID()) + .uf("RS") + .city("Porto Alegre") + .neighborhood("São João") + .interpreter(foundInterpreter) + .build(); + foundInterpreter.setLocations(new ArrayList<>(List.of(oldLocation))); + InterpreterResponseDTO mappedResponse = InterpreterResponseDTO.builder().id(interpreterId).build(); + ArgumentCaptor interpreterArgumentCaptor = ArgumentCaptor.forClass(Interpreter.class); + + when(repository.findById(interpreterId)).thenReturn(Optional.of(foundInterpreter)); + when(repository.save(interpreterArgumentCaptor.capture())).thenReturn(foundInterpreter); + when(responseMapper.toResponseDTO(foundInterpreter)).thenReturn(mappedResponse); + + assertEquals(mappedResponse, service.updatePartial(interpreterId, createLocationPatchRequest())); + assertThat(interpreterArgumentCaptor.getValue().getLocations()) + .hasSize(1) + .anyMatch(loc -> loc.getUf().equals("SP") && + loc.getCity().equals("São Paulo") && + loc.getNeighborhood().equals("Higienópolis") && + loc.getInterpreter().getId().equals(interpreterId) + ); + } + + private InterpreterBasicRequestDTO createValidBasicRequest() { + InterpreterBasicRequestDTO request = new InterpreterBasicRequestDTO(); + request.setName("João Intérprete"); + request.setEmail("interpreter@exemplo.com"); + request.setPassword("senha123"); + request.setPhone("51999999999"); + request.setGender("M"); + request.setBirthday(LocalDate.of(1990, 1, 1)); + request.setCpf("12345678901"); + request.setPicture("picture_url"); + request.setProfessionalData(new ProfessionalDataBasicRequestDTO("12345678000195")); + return request; + } + + private InterpreterPatchRequestDTO createValidPatchRequest() { + InterpreterPatchRequestDTO requestDTO = createLocationPatchRequest(); + requestDTO.setName("Novo Nome"); + requestDTO.setEmail("novo.nome@email.com"); + requestDTO.setGender("F"); + requestDTO.setPicture("nova foto"); + requestDTO.setPhone("51988888888"); + requestDTO.setBirthday(LocalDate.of(2000, 5, 23)); + requestDTO.setProfessionalData(createValidProfessionalDataPatchRequest()); + return requestDTO; + } + + private InterpreterPatchRequestDTO createLocationPatchRequest() { + InterpreterPatchRequestDTO requestDTO = new InterpreterPatchRequestDTO(); + requestDTO.setLocations(List.of(new LocationRequestDTO("SP", "São Paulo", "Higienópolis"))); + return requestDTO; + } + + private ProfessionalDataPatchRequestDTO createValidProfessionalDataPatchRequest() { + ProfessionalDataPatchRequestDTO professionalData = new ProfessionalDataPatchRequestDTO(); + professionalData.setCnpj("98765432000196"); + professionalData.setDescription("Teste"); + professionalData.setImageRights(Boolean.FALSE); + professionalData.setMinValue(BigDecimal.valueOf(250)); + professionalData.setMaxValue(BigDecimal.valueOf(500)); + professionalData.setModality("ONLINE"); + return professionalData; + } +} diff --git a/pointtils/src/test/java/com/pointtils/pointtils/src/core/domain/entities/enums/AppointmentModalityTest.java b/pointtils/src/test/java/com/pointtils/pointtils/src/core/domain/entities/enums/AppointmentModalityTest.java new file mode 100644 index 00000000..ee13a748 --- /dev/null +++ b/pointtils/src/test/java/com/pointtils/pointtils/src/core/domain/entities/enums/AppointmentModalityTest.java @@ -0,0 +1,27 @@ +package com.pointtils.pointtils.src.core.domain.entities.enums; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class AppointmentModalityTest { + + @Test + void shouldGetOnlineFromNullValue() { + assertEquals(AppointmentModality.ONLINE, AppointmentModality.fromString(null)); + } + + @ParameterizedTest + @CsvSource({ + "online, ONLINE", + "remoto, ONLINE", + "presencial, PERSONALLY", + "personally, PERSONALLY", + "unknown, ONLINE" + }) + void shouldGetModalityFromStringValue(String input, String expected) { + assertEquals(AppointmentModality.valueOf(expected), AppointmentModality.fromString(input)); + } +} \ No newline at end of file diff --git a/pointtils/src/test/java/com/pointtils/pointtils/src/core/domain/entities/enums/GenderTest.java b/pointtils/src/test/java/com/pointtils/pointtils/src/core/domain/entities/enums/GenderTest.java new file mode 100644 index 00000000..cc5d045c --- /dev/null +++ b/pointtils/src/test/java/com/pointtils/pointtils/src/core/domain/entities/enums/GenderTest.java @@ -0,0 +1,26 @@ +package com.pointtils.pointtils.src.core.domain.entities.enums; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class GenderTest { + + @Test + void shouldGetOthersFromNullValue() { + assertEquals(Gender.OTHERS, Gender.fromString(null)); + } + + @ParameterizedTest + @CsvSource({ + "O, OTHERS", + "F, FEMALE", + "M, MALE", + "X, OTHERS" + }) + void shouldGetGenderFromStringValue(String input, String expected) { + assertEquals(Gender.valueOf(expected), Gender.fromString(input)); + } +} \ No newline at end of file diff --git a/pointtils/src/test/java/com/pointtils/pointtils/src/core/domain/entities/enums/InterpreterModalityTest.java b/pointtils/src/test/java/com/pointtils/pointtils/src/core/domain/entities/enums/InterpreterModalityTest.java new file mode 100644 index 00000000..c2ced166 --- /dev/null +++ b/pointtils/src/test/java/com/pointtils/pointtils/src/core/domain/entities/enums/InterpreterModalityTest.java @@ -0,0 +1,26 @@ +package com.pointtils.pointtils.src.core.domain.entities.enums; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class InterpreterModalityTest { + + @Test + void shouldGetAllFromNullValue() { + assertEquals(InterpreterModality.ALL, InterpreterModality.fromString(null)); + } + + @ParameterizedTest + @CsvSource({ + "online, ONLINE", + "presencial, PERSONALLY", + "ambos, ALL", + "unknown, ALL" + }) + void shouldGetModalityFromStringValue(String input, String expected) { + assertEquals(InterpreterModality.valueOf(expected), InterpreterModality.fromString(input)); + } +} \ No newline at end of file diff --git a/pointtils/src/test/java/com/pointtils/pointtils/src/infrastructure/configs/GlobalExceptionHandlerTest.java b/pointtils/src/test/java/com/pointtils/pointtils/src/infrastructure/configs/GlobalExceptionHandlerTest.java index a8cf0fdd..76927354 100644 --- a/pointtils/src/test/java/com/pointtils/pointtils/src/infrastructure/configs/GlobalExceptionHandlerTest.java +++ b/pointtils/src/test/java/com/pointtils/pointtils/src/infrastructure/configs/GlobalExceptionHandlerTest.java @@ -1,16 +1,23 @@ package com.pointtils.pointtils.src.infrastructure.configs; -import static org.junit.jupiter.api.Assertions.*; - +import com.pointtils.pointtils.src.core.domain.exceptions.AuthenticationException; +import com.pointtils.pointtils.src.core.domain.exceptions.ClientTimeoutException; +import com.pointtils.pointtils.src.core.domain.exceptions.UserSpecialtyException; +import jakarta.persistence.EntityNotFoundException; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.ConstraintViolationException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import com.pointtils.pointtils.src.core.domain.exceptions.AuthenticationException; -import com.pointtils.pointtils.src.core.domain.exceptions.UserSpecialtyException; +import java.util.Set; -import jakarta.persistence.EntityNotFoundException; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; class GlobalExceptionHandlerTest { @@ -223,4 +230,66 @@ void errorResponseConstructor_ShouldSetAllFields() { assertEquals(message, errorResponse.getMessage()); assertEquals(timestamp, errorResponse.getTimestamp()); } + + @Test + void handleInternalErrorException_ShouldReturnInternalServerError() { + // Arrange + InternalError ex = new InternalError("Internal error"); + + // Act + ResponseEntity response = + globalExceptionHandler.handleInternalError(ex); + + // Assert + assertNotNull(response); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); + assertEquals("Internal error", response.getBody().getMessage()); + } + + @Test + void handleClientTimeoutException_ShouldReturnGatewayTimeout() { + // Arrange + ClientTimeoutException ex = new ClientTimeoutException("Timeout"); + + // Act + ResponseEntity response = + globalExceptionHandler.handleClientTimeoutException(ex); + + // Assert + assertNotNull(response); + assertEquals(HttpStatus.GATEWAY_TIMEOUT, response.getStatusCode()); + assertEquals("Timeout", response.getBody().getMessage()); + } + + @Test + void handleConstraintViolationException_ShouldReturnBadRequest_WithoutConstraintViolationMessages() { + // Arrange + ConstraintViolationException ex = new ConstraintViolationException("Error", Set.of()); + + // Act + ResponseEntity response = + globalExceptionHandler.handleConstraintViolationException(ex); + + // Assert + assertNotNull(response); + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + assertEquals("Error", response.getBody().getMessage()); + } + + @Test + void handleConstraintViolationException_ShouldReturnBadRequest_WithConstraintViolationMessages() { + // Arrange + ConstraintViolation mockViolation = mock(ConstraintViolation.class); + when(mockViolation.getMessage()).thenReturn("Violation message"); + ConstraintViolationException ex = new ConstraintViolationException("Error", Set.of(mockViolation)); + + // Act + ResponseEntity response = + globalExceptionHandler.handleConstraintViolationException(ex); + + // Assert + assertNotNull(response); + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + assertEquals("Violation message", response.getBody().getMessage()); + } }