From 6f8c72fe975d3707576e117573add192e7f3a334 Mon Sep 17 00:00:00 2001 From: "Marcio J. Costa" <87935294+MarcioCosta013@users.noreply.github.com> Date: Sat, 13 Dec 2025 03:56:57 -0300 Subject: [PATCH 1/2] Feature/implement test repository (#5) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test(BaseIntegrationTest): Criando a Base para testes usando conteiner Mysql para ser o mais semelhante possivel com o de producao * feat(Dockenizando): Dockerzinado a aplicacao para está preparada para subir para prod * feat(BaseIntegrationTest): Iniciando a implementacao dos testes usando o testconteiner com mysql * fix(testconteiner/docker): resolvendo erro de comunicacao do testconteine com o docker * feat(RepositoryTest):Refactorando o banco de dados de Testconteiner para H2 em memoria e criando os testes de Peladeiro, Fut,Banimento e Cartoes repositories * test(organizando diretorios de pastas): Separando os testes unitarios dos testes de intregracao e etc * test(organizando diretorios): alterei os nomes dos testes de integracao para o final IT; configurei o spotbugs para verificar os codigos antes de enviar o PR; add arquivo de filtro do spotbugs; * refactor:(mapeando DTOS): -Mapeando os atributos dos DTOs para os models; -Ignorando os atributos de models que nao vao ser usados nos DTOs; -alterei os nomes dos atributos nos DTOs para ficarem iguais ao da classe model para facilitaro mapeamento; -refatorei os locais onde usava o nome antigo dos atributos dos DTOs para o nome novo; --- VemProFutApi/Docker-compose.yml | 52 ++- VemProFutApi/Dockerfile | 8 +- VemProFutApi/excludeFilter.xml | 35 ++ VemProFutApi/mysql-init/init.sql | 8 + VemProFutApi/pom.xml | 41 +- .../configs/OAuth2LoginSuccessHandler.java | 3 +- .../vemprofut/controllers/FutController.java | 58 ++- .../controllers/PeladeiroController.java | 20 +- .../request/SaveFutRequestDTO.java | 2 +- .../response/CartoesResponseDTO.java | 2 +- .../response/SavePeladeiroResponseDTO.java | 2 +- .../response/UpdatePeladeiroResponseDTO.java | 3 +- .../com/vemprofut/mappers/ICartoesMapper.java | 3 + .../br/com/vemprofut/mappers/IFutMapper.java | 10 + .../vemprofut/mappers/IMappersDefault.java | 19 +- .../vemprofut/mappers/IPeladeiroMapper.java | 17 + .../com/vemprofut/models/BanimentoModel.java | 15 +- .../br/com/vemprofut/models/CartoesModel.java | 10 + .../models/DTOs/CartaoCountProjection.java | 1 + .../com/vemprofut/models/DTOs/CartoesDTO.java | 3 +- .../com/vemprofut/models/DTOs/EditorDTO.java | 2 +- .../br/com/vemprofut/models/DTOs/FutDTO.java | 2 +- .../br/com/vemprofut/models/EditorModel.java | 5 + .../br/com/vemprofut/models/FutModel.java | 17 + .../com/vemprofut/models/PeladeiroModel.java | 21 +- .../repositories/BanimentoRepository.java | 8 +- .../repositories/CartoesRepository.java | 8 +- .../repositories/EditorRepository.java | 2 +- .../services/implementacao/FutService.java | 2 +- .../services/query/ICartoesQueryService.java | 6 - .../implementacao/BanimentoQueryService.java | 8 +- .../implementacao/CartoesQueryService.java | 22 +- .../main/resources/application-dev.properties | 60 ++- .../resources/application-prod.properties | 39 ++ .../src/main/resources/application.properties | 61 --- ..._table_partidas_contrains_fk_partidas2.sql | 4 +- ...__alter_table_gols_constraint_fk_gols2.sql | 4 +- ...__alter_table_gols_constraint_fk_gols3.sql | 4 + ...200__alter_table_gols_constraint_gols3,sql | 4 - ...articipapeladeiro_contraint_participa1.sql | 2 +- ...icipapeladeiro_contraint_fk_participa2.sql | 2 +- ...er_table_estapeladeio_constraint_esta1.sql | 2 +- ...able_estapeladeiro_constraint_fk_esta2.sql | 2 +- ...ter_table_editor_constraint_fk_editor1.sql | 2 +- ...ter_table_editor_constraint_fk_editor2.sql | 2 +- ...2511241710__alter_table_fk_banimento_2.sql | 2 +- ...2511241712__alter_table_fk_banimento_3.sql | 2 +- .../vemprofut/VemProFutApplicationTests.java | 12 - .../repositories/BanimentoRepositoryIT.java | 152 +++++++ .../repositories/CartoesRepositoryIT.java | 424 ++++++++++++++++++ .../repositories/EditorRepositoryIT.java | 90 ++++ .../repositories/FutRepositoryIT.java | 78 ++++ .../repositories/PeladeiroRepositoryIT.java | 147 ++++++ .../resources/application-test.properties | 12 + 54 files changed, 1325 insertions(+), 197 deletions(-) create mode 100644 VemProFutApi/excludeFilter.xml create mode 100644 VemProFutApi/mysql-init/init.sql create mode 100644 VemProFutApi/src/main/resources/application-prod.properties create mode 100644 VemProFutApi/src/main/resources/db/migration/V202511092200__alter_table_gols_constraint_fk_gols3.sql delete mode 100644 VemProFutApi/src/main/resources/db/migration/V202511092200__alter_table_gols_constraint_gols3,sql delete mode 100644 VemProFutApi/src/test/java/br/com/vemprofut/VemProFutApplicationTests.java create mode 100644 VemProFutApi/src/test/java/br/com/vemprofut/integration/repositories/BanimentoRepositoryIT.java create mode 100644 VemProFutApi/src/test/java/br/com/vemprofut/integration/repositories/CartoesRepositoryIT.java create mode 100644 VemProFutApi/src/test/java/br/com/vemprofut/integration/repositories/EditorRepositoryIT.java create mode 100644 VemProFutApi/src/test/java/br/com/vemprofut/integration/repositories/FutRepositoryIT.java create mode 100644 VemProFutApi/src/test/java/br/com/vemprofut/integration/repositories/PeladeiroRepositoryIT.java create mode 100644 VemProFutApi/src/test/resources/application-test.properties diff --git a/VemProFutApi/Docker-compose.yml b/VemProFutApi/Docker-compose.yml index 27b2827..8f6b081 100644 --- a/VemProFutApi/Docker-compose.yml +++ b/VemProFutApi/Docker-compose.yml @@ -1,32 +1,62 @@ services: # Serviço do Banco de Dados MySQL db: - image: mysql:8.0 + image: mysql:8.0.32 container_name: vemprofut-db restart: always ports: - - "3306:3306" + - "3307:3306" + env_file: + - .env environment: - MYSQL_DATABASE: ${MYSQL_DATABASE} - MYSQL_USER: ${MYSQL_USER} - MYSQL_PASSWORD: ${MYSQL_PASSWORD} MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} + MYSQL_DATABASE: ${MYSQL_DATABASE} volumes: - vemprofut-db-data:/var/lib/mysql + - ./mysql-init:/docker-entrypoint-initdb.d # criar o usuario automaticamente dentro do container MySQL + + # 👇 Healthcheck para garantir que o MySQL está pronto + healthcheck: + test: ["CMD-SHELL", "mysqladmin ping -h localhost -uroot -p$MYSQL_ROOT_PASSWORD"] + interval: 10s + timeout: 5s + retries: 15 + start_period: 30s # Serviço da API VemProFut api: build: . container_name: vemprofut-api + env_file: + - .env restart: on-failure + depends_on: + db: + condition: service_healthy ports: - "8080:8080" - depends_on: - - db environment: - SPRING_DATASOURCE_URL: ${SPRING_DATASOURCE_URL} - SPRING_DATASOURCE_USERNAME: ${MYSQL_USER} - SPRING_DATASOURCE_PASSWORD: ${MYSQL_PASSWORD} + SPRING_PROFILES_ACTIVE: prod + + # Conexão com MySQL com URL do banco dentro da rede Docker + SPRING_DATASOURCE_USERNAME: ${SPRING_DATASOURCE_USERNAME} + SPRING_DATASOURCE_PASSWORD: ${MYSQL_ROOT_PASSWORD} + SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/${MYSQL_DATABASE}?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC&connectTimeout=30000&socketTimeout=60000 + + # Flyway - tenta reconectar várias vezes enquanto MySQL inicializa + SPRING_FLYWAY_CONNECT_RETRIES: 10 + SPRING_FLYWAY_CONNECT_RETRIES_INTERVAL: 5s + + # Auth0 - Dessa forma, o Spring vai ler direto do ambiente, sem precisar de '.properties' para mapear + SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_AUTH0_CLIENT_ID: ${AUTH0_CLIENT_ID} + SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_AUTH0_CLIENT_SECRET: ${AUTH0_CLIENT_SECRET} + SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_AUTH0_ISSUER_URI: ${AUTH0_ISSUER} + SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI: ${AUTH0_ISSUER} + + # Forca Spring Boot a ouvir em todas interfaces (necessario para Docker) + SERVER_ADDRESS: 0.0.0.0 + SERVER_PORT: 8080 + SERVER_SERVLET_SESSION_COOKIE_SECURE: false volumes: - vemprofut-db-data: # garante que os dados do banco de dados não sejam perdidos quando o contêiner do MySQL for reiniciado. + vemprofut-db-data: # garante que os dados do DB não sejam perdidos quando o contêiner do MySQL for reiniciado. diff --git a/VemProFutApi/Dockerfile b/VemProFutApi/Dockerfile index 1faa1cc..8f0609d 100644 --- a/VemProFutApi/Dockerfile +++ b/VemProFutApi/Dockerfile @@ -1,3 +1,4 @@ +# ===================== Builder (Maven + JDK 21) ======================== # Utilizei uma abordagem de múltiplos estágios (multi-stage build), que gera uma imagem final muito menor e mais segura. # Estágio 1: Build da aplicação com Maven e JDK 21 FROM maven:3.9-eclipse-temurin-21 AS builder @@ -11,11 +12,16 @@ RUN mvn dependency:go-offline # Copia o restante do código-fonte e constrói o JAR COPY src ./src -RUN mvn clean install -DskipTests +RUN mvn clean package -DskipTests +#package mais adequado que install quando construindo imagem... + +# ===================== Runtime (JRE 21) ========================== # Estágio 2: Criação da imagem final com JRE FROM eclipse-temurin:21-jre-jammy WORKDIR /app + COPY --from=builder /app/target/VemProFut-0.0.1-SNAPSHOT.jar app.jar + EXPOSE 8080 ENTRYPOINT ["java", "-jar", "app.jar"] diff --git a/VemProFutApi/excludeFilter.xml b/VemProFutApi/excludeFilter.xml new file mode 100644 index 0000000..64356c8 --- /dev/null +++ b/VemProFutApi/excludeFilter.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/VemProFutApi/mysql-init/init.sql b/VemProFutApi/mysql-init/init.sql new file mode 100644 index 0000000..4f8138c --- /dev/null +++ b/VemProFutApi/mysql-init/init.sql @@ -0,0 +1,8 @@ +-- Cria o usuário +CREATE USER IF NOT EXISTS 'vpfadm'@'%' IDENTIFIED BY 'root123'; + +-- Dá permissões no banco +GRANT ALL PRIVILEGES ON vemprofutdb.* TO 'vpfadm'@'%'; + +-- Atualiza permissões +FLUSH PRIVILEGES; \ No newline at end of file diff --git a/VemProFutApi/pom.xml b/VemProFutApi/pom.xml index 6399b1a..fa31b61 100644 --- a/VemProFutApi/pom.xml +++ b/VemProFutApi/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.7 + 3.4.0 br.com.vemprofut @@ -29,6 +29,7 @@ 21 + org.springframework.boot @@ -46,6 +47,7 @@ com.mysql mysql-connector-j + 8.0.32 runtime @@ -83,6 +85,7 @@ org.flywaydb flyway-core + 10.20.0 @@ -118,11 +121,25 @@ 10.6 - - + + + + + + com.h2database + h2 + test + + + junit + junit + test + + @@ -180,19 +197,25 @@ - + - org.apache.maven.plugins - maven-pmd-plugin - 3.21.0 + com.github.spotbugs + spotbugs-maven-plugin + 4.8.3.0 - true + Max + Low + true + true + ${project.build.directory}/spotbugs + ${project.basedir}/excludeFilter.xml verify check + spotbugs @@ -200,4 +223,4 @@ - + \ No newline at end of file diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/configs/OAuth2LoginSuccessHandler.java b/VemProFutApi/src/main/java/br/com/vemprofut/configs/OAuth2LoginSuccessHandler.java index 0047d74..1381d0d 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/configs/OAuth2LoginSuccessHandler.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/configs/OAuth2LoginSuccessHandler.java @@ -12,7 +12,6 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService; import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; @@ -25,7 +24,7 @@ public class OAuth2LoginSuccessHandler implements AuthenticationSuccessHandler { // Agora vamos interceptar o retorno do Auth0... private final PeladeiroRepository peladeiroRepository; - private final OAuth2AuthorizedClientService authorizedClientService; + // private final OAuth2AuthorizedClientService authorizedClientService; private final IHistoricoPeladeiroService historicoPeladeiroService; private final IHistoricoPeladeiroMapper historicoPeladeiroMapper; diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/controllers/FutController.java b/VemProFutApi/src/main/java/br/com/vemprofut/controllers/FutController.java index b90f325..59df0f1 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/controllers/FutController.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/controllers/FutController.java @@ -5,7 +5,6 @@ import br.com.vemprofut.models.FutModel; import br.com.vemprofut.services.IFutService; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import java.util.List; import lombok.AllArgsConstructor; @@ -15,7 +14,6 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; - @RestController @RequestMapping("fut/") @AllArgsConstructor @@ -25,7 +23,9 @@ public class FutController { // =============== CRUD basico ========================== @PostMapping - @Operation(summary = "Cadastra um novo Fut", tags = {"FutController - CRUD Básico"}) + @Operation( + summary = "Cadastra um novo Fut", + tags = {"FutController - CRUD Básico"}) public ResponseEntity create( @Valid @RequestBody final SaveFutRequestDTO requestDTO) { var response = futService.create(requestDTO); @@ -33,13 +33,17 @@ public ResponseEntity create( } @GetMapping("{id}") - @Operation(summary = "Busca um Fut pelo ID", tags = {"FutController - CRUD Básico"}) + @Operation( + summary = "Busca um Fut pelo ID", + tags = {"FutController - CRUD Básico"}) public ResponseEntity findByFut(@PathVariable final Long id) { return ResponseEntity.ok(futService.findById(id)); } @PutMapping("{id}") - @Operation(summary = "Altera um Fut já cadastrado, informando o id", tags = {"FutController - CRUD Básico"}) + @Operation( + summary = "Altera um Fut já cadastrado, informando o id", + tags = {"FutController - CRUD Básico"}) public ResponseEntity update( @PathVariable final Long id, UpdateFutRequestDTO dto) { var obj = futService.update(id, dto); @@ -47,7 +51,9 @@ public ResponseEntity update( } @DeleteMapping("{id}") - @Operation(summary = "Apaga um Fut por meio do id, cuidado! ", tags = {"FutController - CRUD Básico"}) + @Operation( + summary = "Apaga um Fut por meio do id, cuidado! ", + tags = {"FutController - CRUD Básico"}) public ResponseEntity delete(@PathVariable final Long id) { futService.delete(id); return ResponseEntity.noContent().build(); @@ -56,7 +62,9 @@ public ResponseEntity delete(@PathVariable final Long id) { // =================== acoes partidas ======================= @PostMapping("partida") - @Operation(summary = "Criar uma nova partida...", tags = {"FutController - Ações Partidas"}) + @Operation( + summary = "Criar uma nova partida...", + tags = {"FutController - Ações Partidas"}) public ResponseEntity criarPartida( @RequestBody SavePartidaRequestDTO requestDTO) { FutModel futModel = futService.findByIdModel(requestDTO.futId()); @@ -65,7 +73,9 @@ public ResponseEntity criarPartida( } @PostMapping("partidaslist") - @Operation(summary = "Cria varias partidas de uma só vez, todas com resultados preenchidos", tags = {"FutController - Ações Partidas"}) + @Operation( + summary = "Cria varias partidas de uma só vez, todas com resultados preenchidos", + tags = {"FutController - Ações Partidas"}) public ResponseEntity> criarPartidasLista( @RequestBody List requestDTO) { return ResponseEntity.status(HttpStatus.CREATED).body(futService.criarPartidasList(requestDTO)); @@ -74,7 +84,9 @@ public ResponseEntity> criarPartidasLista( // ================ lista peladeiro ===================== @PostMapping("add-peladeiro") - @Operation(summary = "Adiciona um peladeiro a lista de peladeiros cadastrado no fut", tags = {"FutController - Lista de Peladeiros"}) + @Operation( + summary = "Adiciona um peladeiro a lista de peladeiros cadastrado no fut", + tags = {"FutController - Lista de Peladeiros"}) public ResponseEntity adicionarPeladeiroLista( @RequestBody AddPeladeiroInFutListRequestDTO addPeladeiroRequestDTO) { futService.addPeladeiro(addPeladeiroRequestDTO); @@ -82,7 +94,9 @@ public ResponseEntity adicionarPeladeiroLista( } @GetMapping("lista-peladeiros/{idFut}") - @Operation(summary = "busca a lista de todos peldadeiros cadastrados no fut", tags = {"FutController - Lista de Peladeiros"}) + @Operation( + summary = "busca a lista de todos peldadeiros cadastrados no fut", + tags = {"FutController - Lista de Peladeiros"}) public ResponseEntity> listarPeladeirosCadastrados( @PathVariable final Long idFut) { return ResponseEntity.ok().body(futService.listarPeladeiroCadastradosFut(idFut)); @@ -91,7 +105,9 @@ public ResponseEntity> listarPeladeirosCadastrados( // =============== lista Editores =========================== @PostMapping("add-editor") - @Operation(summary = "Adiciona um Editor a lista de editores de um fut em especifico", tags = {"FutController - Lista de Editores do Fut"}) + @Operation( + summary = "Adiciona um Editor a lista de editores de um fut em especifico", + tags = {"FutController - Lista de Editores do Fut"}) public ResponseEntity adicionarEditorLista( @RequestBody AddEditorInFutListResquestDTO editor) { futService.addEditor(editor); @@ -99,7 +115,9 @@ public ResponseEntity adicionarEditorLista( } @GetMapping("lista-editores/{idFut}") - @Operation(summary = "busca a lista de editores de um fut em especifico", tags = {"FutController - Lista de Editores do Fut"}) + @Operation( + summary = "busca a lista de editores de um fut em especifico", + tags = {"FutController - Lista de Editores do Fut"}) public ResponseEntity> listarEditoresFut( @PathVariable final Long idFut) { @@ -109,7 +127,9 @@ public ResponseEntity> listarEditoresFut( // ================= upload arquivos fotos ================== @PostMapping(value = "uploadFoto/{id}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - @Operation(summary = "Para enviar a foto de capa do Fut", tags = {"FutController - Upload de Imagens"}) + @Operation( + summary = "Para enviar a foto de capa do Fut", + tags = {"FutController - Upload de Imagens"}) public ResponseEntity uploadFotoFut( @PathVariable Long id, @RequestPart("file") MultipartFile file) { futService.atualizarFotoCapa(id, file); @@ -119,21 +139,27 @@ public ResponseEntity uploadFotoFut( // ======================== Banimentos ======================= @PostMapping(value = "addBanimento") - @Operation(summary = "Adicionando um peladeiro da lista para o banimento", tags = {"FutController - Banimento no Fut"}) + @Operation( + summary = "Adicionando um peladeiro da lista para o banimento", + tags = {"FutController - Banimento no Fut"}) public ResponseEntity adicionarBanimento(@RequestBody SaveBanimentoRequestDTO dto) { futService.addBanimentoList(dto); return ResponseEntity.noContent().build(); } @GetMapping("lista-banidos/{idFut}") - @Operation(summary = "Busca a lista de Banidos do Fut em questao", tags = {"FutController - Banimento no Fut"}) + @Operation( + summary = "Busca a lista de Banidos do Fut em questao", + tags = {"FutController - Banimento no Fut"}) public ResponseEntity> buscarListaBanidos( @PathVariable Long idFut) { return ResponseEntity.ok().body(futService.findAllBanidos(idFut)); } @DeleteMapping("delete-banimento/{idFut}/{idPeladeiro}") - @Operation(summary = "retira um peladeiro da lista de banidos", tags = {"FutController - Banimento no Fut"}) + @Operation( + summary = "retira um peladeiro da lista de banidos", + tags = {"FutController - Banimento no Fut"}) public ResponseEntity retirandoBanimento( @PathVariable Long idFut, @PathVariable Long idPeladeiro) { futService.removeBanido(idPeladeiro, idFut); diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/controllers/PeladeiroController.java b/VemProFutApi/src/main/java/br/com/vemprofut/controllers/PeladeiroController.java index 4e57a49..0e7e4f7 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/controllers/PeladeiroController.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/controllers/PeladeiroController.java @@ -23,7 +23,9 @@ public class PeladeiroController { private final IPeladeiroService peladeiroService; @PostMapping - @Operation(summary = "Cadastra um novo peladeiro", tags = {"PeladeiroController"}) + @Operation( + summary = "Cadastra um novo peladeiro", + tags = {"PeladeiroController"}) public ResponseEntity create( @Valid @RequestBody final SavePeladeiroRequestDTO requestDTO) { var obj = peladeiroService.create(requestDTO); @@ -31,14 +33,18 @@ public ResponseEntity create( } @GetMapping("{id}") - @Operation(summary = "Busca um Peladeiro pelo id", tags = {"PeladeiroController"}) + @Operation( + summary = "Busca um Peladeiro pelo id", + tags = {"PeladeiroController"}) public ResponseEntity findById(@PathVariable final Long id) { var obj = peladeiroService.findById(id); return ResponseEntity.ok(obj); } @PutMapping("{id}") - @Operation(summary = "Faz alteraçoes no Peladeiro cujo id é informado.", tags = {"PeladeiroController"}) + @Operation( + summary = "Faz alteraçoes no Peladeiro cujo id é informado.", + tags = {"PeladeiroController"}) public ResponseEntity update( @PathVariable final Long id, @Valid @RequestBody UpdatePeladeiroRequestDTO dto) { peladeiroService.update(id, dto); @@ -46,14 +52,18 @@ public ResponseEntity update( } @DeleteMapping("{id}") - @Operation(summary = "Deleta o peladeiro cujo id foi informado. Cuidado!", tags = {"PeladeiroController"}) + @Operation( + summary = "Deleta o peladeiro cujo id foi informado. Cuidado!", + tags = {"PeladeiroController"}) public ResponseEntity delete(@PathVariable final Long id) { peladeiroService.delete(id); return ResponseEntity.noContent().build(); } @PostMapping(value = "uploadFoto/{id}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - @Operation(summary = "Caso nao logado pelo gmail, enviar a foto do perfil", tags = {"PeladeiroController"}) + @Operation( + summary = "Caso nao logado pelo gmail, enviar a foto do perfil", + tags = {"PeladeiroController"}) public ResponseEntity uploadFotoPeladeiro( @PathVariable Long id, @RequestPart("file") MultipartFile file) throws IOException { peladeiroService.atualizarFoto(id, file); diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/controllers/request/SaveFutRequestDTO.java b/VemProFutApi/src/main/java/br/com/vemprofut/controllers/request/SaveFutRequestDTO.java index 53bc28d..f4d8874 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/controllers/request/SaveFutRequestDTO.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/controllers/request/SaveFutRequestDTO.java @@ -8,4 +8,4 @@ public record SaveFutRequestDTO( @PositiveOrZero Integer jogadoresPorTime, @PositiveOrZero Integer tempoMaxPartida, @PositiveOrZero Integer maxGolsVitoria, - @PositiveOrZero Long administradorPeladeiroId) {} + @PositiveOrZero Long administradorPeladeiro) {} diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/controllers/response/CartoesResponseDTO.java b/VemProFutApi/src/main/java/br/com/vemprofut/controllers/response/CartoesResponseDTO.java index 95ec35e..36b9ee7 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/controllers/response/CartoesResponseDTO.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/controllers/response/CartoesResponseDTO.java @@ -3,4 +3,4 @@ import br.com.vemprofut.models.enuns.TipoCartao; public record CartoesResponseDTO( - Long id, Long partidaId, Long peladeiroId, Long futId, TipoCartao tipoCartao) {} + Long id, Long partida, Long peladeiro, Long fut, TipoCartao tipoCartao) {} diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/controllers/response/SavePeladeiroResponseDTO.java b/VemProFutApi/src/main/java/br/com/vemprofut/controllers/response/SavePeladeiroResponseDTO.java index 0ed4f04..64a52b3 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/controllers/response/SavePeladeiroResponseDTO.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/controllers/response/SavePeladeiroResponseDTO.java @@ -12,7 +12,7 @@ public record SavePeladeiroResponseDTO( @JsonProperty("peDominante") String peDominante, @JsonProperty("whatsapp") String whatsapp, @JsonProperty("historicoPeladeiro") Long historicoPeladeiro, - @JsonProperty("foto_url") String foto_url, + @JsonProperty("fotoUrl") String fotoUrl, @JsonProperty("partidasIDs") List partidas, @JsonProperty("futsIDs") List futs, @JsonProperty("cartoes") List cartoes) {} diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/controllers/response/UpdatePeladeiroResponseDTO.java b/VemProFutApi/src/main/java/br/com/vemprofut/controllers/response/UpdatePeladeiroResponseDTO.java index 30e21a8..02fcf35 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/controllers/response/UpdatePeladeiroResponseDTO.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/controllers/response/UpdatePeladeiroResponseDTO.java @@ -8,4 +8,5 @@ public record UpdatePeladeiroResponseDTO( @JsonProperty("apelido") String apelido, @JsonProperty("descricao") String descricao, @JsonProperty("whatsapp") String whatsapp, - @JsonProperty("peDominante") String peDominante) {} + @JsonProperty("peDominante") String peDominante, + @JsonProperty("fotoURL") String fotoUrl) {} diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/mappers/ICartoesMapper.java b/VemProFutApi/src/main/java/br/com/vemprofut/mappers/ICartoesMapper.java index bfbfede..0017fdc 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/mappers/ICartoesMapper.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/mappers/ICartoesMapper.java @@ -1,5 +1,6 @@ package br.com.vemprofut.mappers; +import br.com.vemprofut.controllers.response.CartoesResponseDTO; import br.com.vemprofut.models.CartoesModel; import br.com.vemprofut.models.DTOs.CartoesDTO; import org.mapstruct.Mapper; @@ -24,4 +25,6 @@ Esses dois campos (`cartoesPartida` e `cartoesPeladeiro`) são listas de objetos // De Entity/Model --> DTO CartoesDTO toDTO(CartoesModel model); + + CartoesResponseDTO toResponseDTO(CartoesModel model); } diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/mappers/IFutMapper.java b/VemProFutApi/src/main/java/br/com/vemprofut/mappers/IFutMapper.java index 21e7077..b15083f 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/mappers/IFutMapper.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/mappers/IFutMapper.java @@ -7,6 +7,7 @@ import br.com.vemprofut.models.DTOs.FutDTO; import br.com.vemprofut.models.FutModel; import org.mapstruct.Mapper; +import org.mapstruct.Mapping; @Mapper( componentModel = "spring", @@ -14,8 +15,17 @@ public interface IFutMapper { // DTO --> Model + @Mapping(target = "foto_url", ignore = true) + @Mapping(target = "banidos", ignore = true) FutModel toModel(FutDTO dto); + @Mapping(target = "id", ignore = true) + @Mapping(target = "foto_url", ignore = true) + @Mapping(target = "historicoFutId", ignore = true) + @Mapping(target = "editores", ignore = true) + @Mapping(target = "peladeiros", ignore = true) + @Mapping(target = "cartoes", ignore = true) + @Mapping(target = "banidos", ignore = true) FutModel saveRequestToModel(SaveFutRequestDTO dto); SaveFutResponseDTO toSaveResponse(FutModel dto); diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/mappers/IMappersDefault.java b/VemProFutApi/src/main/java/br/com/vemprofut/mappers/IMappersDefault.java index 87e60ae..b848a69 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/mappers/IMappersDefault.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/mappers/IMappersDefault.java @@ -1,5 +1,6 @@ package br.com.vemprofut.mappers; +import br.com.vemprofut.controllers.response.CartoesResponseDTO; import br.com.vemprofut.controllers.response.CartoesResumoResponseDTO; import br.com.vemprofut.controllers.response.PeladeiroResponseDTO; import br.com.vemprofut.models.CartoesModel; @@ -64,6 +65,18 @@ default CartoesResumoResponseDTO mapResumoCartoes(List cartoes) { return resultados; } + default CartoesResponseDTO mapResponceCartoesDTO(CartoesModel model) { + CartoesResponseDTO cartoesResponseDTO = + new CartoesResponseDTO( + model.getId(), + model.getPartida().getId(), + model.getPeladeiro().getId(), + model.getFut().getId(), + model.getTipoCartao()); + + return cartoesResponseDTO; + } + // ========================EDITOR===================== // Converte EditorModel -> Long (pegando o id) @@ -179,8 +192,8 @@ default PeladeiroResponseDTO mapModelToResponse(PeladeiroModel model) { // return new PeladeiroNameIdResponseDTO(peladeiroId, nome); // } - //======================Banimento================================= - //TODO: coversao de peladeiro para o long no DTODetails - //TODO: coversao de fut para o long no DTODetails + // ======================Banimento================================= + // TODO: coversao de peladeiro para o long no DTODetails + // TODO: coversao de fut para o long no DTODetails } diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/mappers/IPeladeiroMapper.java b/VemProFutApi/src/main/java/br/com/vemprofut/mappers/IPeladeiroMapper.java index 3a9c9a1..454e824 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/mappers/IPeladeiroMapper.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/mappers/IPeladeiroMapper.java @@ -18,6 +18,12 @@ public interface IPeladeiroMapper { // DTO --> Model + @Mapping(target = "administra", ignore = true) + @Mapping(target = "editores", ignore = true) + @Mapping(target = "fotoUrl", ignore = true) + @Mapping(target = "golsPeladeiro", ignore = true) + @Mapping(target = "banimentos", ignore = true) + @Mapping(target = "authProvider", ignore = true) PeladeiroModel toModel(PeladeiroDTO dto); @BeanMapping( @@ -32,10 +38,21 @@ public interface IPeladeiroMapper { PeladeiroDetailResponse modelToDetailsDTO(PeladeiroModel model); @Mapping(target = "id", ignore = true) + @Mapping(target = "historicoPeladeiro", ignore = true) + @Mapping(target = "partidas", ignore = true) + @Mapping(target = "cartoes", ignore = true) + @Mapping(target = "futs", ignore = true) + @Mapping(target = "administra", ignore = true) + @Mapping(target = "editores", ignore = true) + @Mapping(target = "fotoUrl", ignore = true) + @Mapping(target = "golsPeladeiro", ignore = true) + @Mapping(target = "banimentos", ignore = true) + @Mapping(target = "authProvider", ignore = true) PeladeiroModel saveRequestToModel(SavePeladeiroRequestDTO dto); UpdatePeladeiroResponseDTO modelToUpdateResponse(PeladeiroModel model); + @Mapping(target = "fotoUrl", ignore = true) SavePeladeiroResponseDTO modelToSaveResponse(PeladeiroModel model); @Mapping(source = "id", target = "peladeiroId") diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/models/BanimentoModel.java b/VemProFutApi/src/main/java/br/com/vemprofut/models/BanimentoModel.java index 9b56881..8dac986 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/models/BanimentoModel.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/models/BanimentoModel.java @@ -2,7 +2,6 @@ import jakarta.persistence.*; import java.time.LocalDate; -import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -11,10 +10,22 @@ @Table(name = "banimento") @Getter @Setter -@AllArgsConstructor @NoArgsConstructor public class BanimentoModel { + public BanimentoModel( + String motivo, + LocalDate dataBanimento, + LocalDate dataFimBanimento, + PeladeiroModel peladeiro, + FutModel fut) { + this.motivo = motivo; + this.dataBanimento = dataBanimento; + this.dataFimBanimento = dataFimBanimento; + this.peladeiro = peladeiro; + this.fut = fut; + } + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id_banimento") diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/models/CartoesModel.java b/VemProFutApi/src/main/java/br/com/vemprofut/models/CartoesModel.java index f5e8ae2..3d67694 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/models/CartoesModel.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/models/CartoesModel.java @@ -3,14 +3,24 @@ import br.com.vemprofut.models.enuns.TipoCartao; import jakarta.persistence.*; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; @Entity @Table(name = "cartoes_peladeiro") @Getter @Setter +@NoArgsConstructor public class CartoesModel { + public CartoesModel( + PartidasModel partida, PeladeiroModel peladeiro, FutModel fut, TipoCartao tipoCartao) { + this.partida = partida; + this.peladeiro = peladeiro; + this.fut = fut; + this.tipoCartao = tipoCartao; + } + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id_cartoes_peladeiro") diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/models/DTOs/CartaoCountProjection.java b/VemProFutApi/src/main/java/br/com/vemprofut/models/DTOs/CartaoCountProjection.java index dc9d8db..6dd1420 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/models/DTOs/CartaoCountProjection.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/models/DTOs/CartaoCountProjection.java @@ -2,6 +2,7 @@ import br.com.vemprofut.models.enuns.TipoCartao; +// Essa interface está em DTOs porque ela representa um objeto de transferência de dados. public interface CartaoCountProjection { TipoCartao getTipo(); diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/models/DTOs/CartoesDTO.java b/VemProFutApi/src/main/java/br/com/vemprofut/models/DTOs/CartoesDTO.java index 15c353c..b7563f0 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/models/DTOs/CartoesDTO.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/models/DTOs/CartoesDTO.java @@ -2,5 +2,4 @@ import br.com.vemprofut.models.enuns.TipoCartao; -public record CartoesDTO( - Long id, Long partidaId, Long peladeiroId, Long futId, TipoCartao tipoCartao) {} +public record CartoesDTO(Long id, Long partida, Long peladeiro, Long fut, TipoCartao tipoCartao) {} diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/models/DTOs/EditorDTO.java b/VemProFutApi/src/main/java/br/com/vemprofut/models/DTOs/EditorDTO.java index fb50131..027f37a 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/models/DTOs/EditorDTO.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/models/DTOs/EditorDTO.java @@ -1,3 +1,3 @@ package br.com.vemprofut.models.DTOs; -public record EditorDTO(Long id, Long peladeiroId, Long futId) {} +public record EditorDTO(Long id, Long peladeiro, Long fut) {} diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/models/DTOs/FutDTO.java b/VemProFutApi/src/main/java/br/com/vemprofut/models/DTOs/FutDTO.java index c9a63f8..d7f1eb5 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/models/DTOs/FutDTO.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/models/DTOs/FutDTO.java @@ -9,7 +9,7 @@ public record FutDTO( Integer tempoMaxPartida, Integer maxGolsVitoria, Long historicoFutId, - Long administradorPeladeiroId, + Long administradorPeladeiro, List editores, List peladeiros, List cartoes) {} diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/models/EditorModel.java b/VemProFutApi/src/main/java/br/com/vemprofut/models/EditorModel.java index b18fcca..f1b2e5d 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/models/EditorModel.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/models/EditorModel.java @@ -12,6 +12,11 @@ @NoArgsConstructor public class EditorModel { + public EditorModel(PeladeiroModel peladeiro, FutModel fut) { + this.peladeiro = peladeiro; + this.fut = fut; + } + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id_editor") diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/models/FutModel.java b/VemProFutApi/src/main/java/br/com/vemprofut/models/FutModel.java index 5e36f06..0d316eb 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/models/FutModel.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/models/FutModel.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.List; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; @@ -11,8 +12,24 @@ @Table(name = "fut") @Getter @Setter +@NoArgsConstructor public class FutModel { + public FutModel( + String nome, + Integer jogadoresPorTime, + Integer tempoMaxPartida, + Integer maxGolsVitoria, + HistoricoFutModel historicoFutId, + PeladeiroModel administradorPeladeiro) { + this.nome = nome; + this.jogadoresPorTime = jogadoresPorTime; + this.tempoMaxPartida = tempoMaxPartida; + this.maxGolsVitoria = maxGolsVitoria; + this.historicoFutId = historicoFutId; + this.administradorPeladeiro = administradorPeladeiro; + } + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id_fut") diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/models/PeladeiroModel.java b/VemProFutApi/src/main/java/br/com/vemprofut/models/PeladeiroModel.java index 00be016..bd1176c 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/models/PeladeiroModel.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/models/PeladeiroModel.java @@ -3,16 +3,31 @@ import jakarta.persistence.*; import java.util.ArrayList; import java.util.List; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; +import lombok.*; @Entity @Table(name = "peladeiro") @Getter @Setter +@NoArgsConstructor +@AllArgsConstructor public class PeladeiroModel { + public PeladeiroModel( + String nome, + String email, + String apelido, + String descricao, + String whatsapp, + String peDominante) { + this.nome = nome; + this.email = email; + this.apelido = apelido; + this.descricao = descricao; + this.whatsapp = whatsapp; + this.peDominante = peDominante; + } + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id_peladeiro") diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/repositories/BanimentoRepository.java b/VemProFutApi/src/main/java/br/com/vemprofut/repositories/BanimentoRepository.java index 3b30e88..d5c14d6 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/repositories/BanimentoRepository.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/repositories/BanimentoRepository.java @@ -11,13 +11,13 @@ public interface BanimentoRepository extends JpaRepository @Query( """ - SELECT b FROM BanimentoModel b WHERE b.fut = :idFut AND b.peladeiro = :idPeladeiro - """) + SELECT b FROM BanimentoModel b WHERE b.fut = :idFut AND b.peladeiro = :idPeladeiro + """) Optional buscarBanimentoFutPeladeiro( @Param("idFut") Long idFut, @Param("idPeladeiro") Long idPeladeiro); @Query(""" - SELECT b FROM BanimentoModel b WHERE b.fut = :idFut - """) + SELECT b FROM BanimentoModel b WHERE b.fut = :idFut + """) List buscarListBanidos(@Param("idFut") Long idFut); } diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/repositories/CartoesRepository.java b/VemProFutApi/src/main/java/br/com/vemprofut/repositories/CartoesRepository.java index 9a055e9..f0855df 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/repositories/CartoesRepository.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/repositories/CartoesRepository.java @@ -24,17 +24,17 @@ SELECT c.tipoCartao AS tipo, COUNT(c) AS quantidade FROM CartoesModel c WHERE c.peladeiro.id = :peladeiroId GROUP BY c.tipoCartao - """) + """) List countByTipoAndPeladeiro(@Param("peladeiroId") Long peladeiroId); @Query( """ SELECT c.tipoCartao AS tipo, COUNT(c) AS quantidade FROM CartoesModel c - WHERE c.fut.id = :futId + WHERE c.fut.id = :fut GROUP BY c.tipoCartao - """) - List countByTipoAndFut(@Param("futId") Long futId); + """) + List countByTipoAndFut(@Param("fut") Long futId); /* Agora o retorno já vem fortemente tipado: cada item da lista é um 'CartaoCountProjection' com getTipo() diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/repositories/EditorRepository.java b/VemProFutApi/src/main/java/br/com/vemprofut/repositories/EditorRepository.java index d8bf585..92b99e8 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/repositories/EditorRepository.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/repositories/EditorRepository.java @@ -13,7 +13,7 @@ public interface EditorRepository extends JpaRepository { @Query( """ SELECT e FROM EditorModel e WHERE e.peladeiro = :peladeiro AND e.fut= :fut - """) + """) EditorModel findByPeladeiroAndFut( @Param("peladeiro") PeladeiroModel peladeiroModel, @Param("fut") FutModel futModel); diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/services/implementacao/FutService.java b/VemProFutApi/src/main/java/br/com/vemprofut/services/implementacao/FutService.java index 8a418dd..3aa0c5f 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/services/implementacao/FutService.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/services/implementacao/FutService.java @@ -60,7 +60,7 @@ public class FutService implements IFutService { @Transactional public SaveFutResponseDTO create(SaveFutRequestDTO dto) { queryService.verifyNomeFutExist(dto.nome()); - var peladeiro = peladeiroQueryService.verifyPeladeiroExist(dto.administradorPeladeiroId()); + var peladeiro = peladeiroQueryService.verifyPeladeiroExist(dto.administradorPeladeiro()); FutModel saved = repository.save(mapper.saveRequestToModel(dto)); diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/services/query/ICartoesQueryService.java b/VemProFutApi/src/main/java/br/com/vemprofut/services/query/ICartoesQueryService.java index d55d01a..1839fa9 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/services/query/ICartoesQueryService.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/services/query/ICartoesQueryService.java @@ -2,15 +2,9 @@ import br.com.vemprofut.models.CartoesModel; import br.com.vemprofut.models.DTOs.CartoesDTO; -import br.com.vemprofut.models.DTOs.PartidasDTO; -import br.com.vemprofut.models.DTOs.PeladeiroDTO; public interface ICartoesQueryService { - void verifyPeladeiroExist(PeladeiroDTO peladeiroDTO); - - void verifyPartidasExist(PartidasDTO partidasDTO); - void verifyEntitiesExist(CartoesDTO dto); CartoesModel verityCartoesExist(Long id); diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/services/query/implementacao/BanimentoQueryService.java b/VemProFutApi/src/main/java/br/com/vemprofut/services/query/implementacao/BanimentoQueryService.java index a7a031e..95900bb 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/services/query/implementacao/BanimentoQueryService.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/services/query/implementacao/BanimentoQueryService.java @@ -7,16 +7,16 @@ import br.com.vemprofut.models.BanimentoModel; import br.com.vemprofut.repositories.BanimentoRepository; import br.com.vemprofut.services.query.IBanimentoQueryService; -import org.springframework.stereotype.Service; - import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; @Service public class BanimentoQueryService implements IBanimentoQueryService { - private BanimentoRepository repository; + @Autowired private BanimentoRepository repository; - private IBanimentoMapper mapper; + @Autowired private IBanimentoMapper mapper; @Override public void verifyPeladeiroBanidoExist(Long idFut, Long idPeladeiro) { diff --git a/VemProFutApi/src/main/java/br/com/vemprofut/services/query/implementacao/CartoesQueryService.java b/VemProFutApi/src/main/java/br/com/vemprofut/services/query/implementacao/CartoesQueryService.java index c63bd04..20bd3ec 100644 --- a/VemProFutApi/src/main/java/br/com/vemprofut/services/query/implementacao/CartoesQueryService.java +++ b/VemProFutApi/src/main/java/br/com/vemprofut/services/query/implementacao/CartoesQueryService.java @@ -3,37 +3,25 @@ import br.com.vemprofut.exceptions.NotFoundException; import br.com.vemprofut.models.CartoesModel; import br.com.vemprofut.models.DTOs.CartoesDTO; -import br.com.vemprofut.models.DTOs.PartidasDTO; -import br.com.vemprofut.models.DTOs.PeladeiroDTO; import br.com.vemprofut.repositories.CartoesRepository; import br.com.vemprofut.services.query.ICartoesQueryService; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class CartoesQueryService implements ICartoesQueryService { - private CartoesRepository repository; - - @Override - public void verifyPeladeiroExist(PeladeiroDTO peladeiroDTO) { - // TODO: implementar - } - - @Override - public void verifyPartidasExist(PartidasDTO partidasDTO) { - // TODO: implementar - } + @Autowired private CartoesRepository repository; // Verifica se o peladeiro, partida e fut existem public void verifyEntitiesExist(CartoesDTO dto) { - if (!repository.existsById(dto.peladeiroId())) + if (!repository.existsById(dto.peladeiro())) throw new IllegalArgumentException("Peladeiro não encontrado"); - if (!repository.existsById(dto.partidaId())) + if (!repository.existsById(dto.partida())) throw new IllegalArgumentException("Partida não encontrada"); - if (!repository.existsById(dto.futId())) - throw new IllegalArgumentException("Fut não encontrado"); + if (!repository.existsById(dto.fut())) throw new IllegalArgumentException("Fut não encontrado"); } public CartoesModel verityCartoesExist(Long id) { diff --git a/VemProFutApi/src/main/resources/application-dev.properties b/VemProFutApi/src/main/resources/application-dev.properties index 0f1ce81..425cb0e 100644 --- a/VemProFutApi/src/main/resources/application-dev.properties +++ b/VemProFutApi/src/main/resources/application-dev.properties @@ -1,11 +1,49 @@ -spring: - jpa: - show-sql: true - properties: - hibernate: - format_sql: true - devtools: - remote: - secret: 123 - restart: - trigger-file: trigger.txt \ No newline at end of file +spring.application.name=VemProFut + +###################################################### +# == BANCO LOCAL (MySQL Rodando Localmente) ========== +###################################################### +spring.datasource.url=jdbc:mysql://localhost:3306/vemprofutdb?createDatabaseIfNotExist=true&allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC +spring.datasource.username=root +spring.datasource.password=root123 + +spring.jpa.hibernate.ddl-auto=none + + +###################################################### +# == LOGS (DEV: Mais detalhados) ===================== +###################################################### +logging.level.root=INFO +logging.level.br.com.vemprofut=DEBUG + +# Mostra queries SQL (util para dev, mas nao tao agressivo) +logging.level.log.hibernate.SQL=DEBUG +logging.level.log.hibernate.type.descritor.sql.BasicBinder=TRACE + + +###################################################### +# == FLYWAY ========================================== +###################################################### +spring.flyway.enabled=true +spring.flyway.locations=classpath:db/migration + + +###################################################### +# == AUTH0 (Somente para DEV) ======================== +###################################################### +spring.security.oauth2.client.registration.auth0.client-id=jcmpSdlqwwakcitekSVmh0F0Hw6BEcf7 +spring.security.oauth2.client.registration.auth0.client-secret=QWUV1hzjq3fgZy0vNuv_ir9Svsv11JeAw241YuPpMcCCeP7kdTbgajsaptfk52Mx +spring.security.oauth2.client.registration.auth0.redirect-uri=http://localhost:8080/login/oauth2/code/{registrationId} + +spring.security.oauth2.resourceserver.jwt.issuer-uri=https://dev-6nhln802vsqkhnfm.us.auth0.com/ + +spring.security.oauth2.client.registration.auth0.authorization-grant-type=authorization_code +spring.security.oauth2.client.registration.auth0.scope=openid,profile,email + +# Provedor (provider) configurado para o nome 'auth0' +spring.security.oauth2.client.provider.auth0.issuer-uri=https://dev-6nhln802vsqkhnfm.us.auth0.com/ + +###################################################### +# == UPLOAD LOCAL ==================================== +###################################################### +app.upload.dir=uploads diff --git a/VemProFutApi/src/main/resources/application-prod.properties b/VemProFutApi/src/main/resources/application-prod.properties new file mode 100644 index 0000000..be2aa8f --- /dev/null +++ b/VemProFutApi/src/main/resources/application-prod.properties @@ -0,0 +1,39 @@ +spring.application.name=VemProFut + +# MYSQL via Docker Compose +spring.datasource.url=${SPRING_DATASOURCE_URL} +spring.datasource.username=${SPRING_DATASOURCE_USERNAME} +spring.datasource.password=${SPRING_DATASOURCE_PASSWORD} + +spring.jpa.hibernate.ddl-auto=none + +spring.flyway.enabled=true +spring.flyway.locations=classpath:db/migration +spring.flyway.fail-on-missing-locations=false +spring.flyway.connect-retries=10 +spring.flyway.connect-retries-interval=5s + +# LOGS NO CONSOLE (padrao Docker) +logging.level.root=INFO +logging.level.org.springframework=INFO + +# Upload definido por volume +app.upload.dir=/app/uploads + +# ----------- Auth0 / OAuth2 ----------- +# Client registration +spring.security.oauth2.client.registration.auth0.client-id=${AUTH0_CLIENT_ID} +spring.security.oauth2.client.registration.auth0.client-secret=${AUTH0_CLIENT_SECRET} +spring.security.oauth2.client.registration.auth0.scope=openid,profile,email +spring.security.oauth2.client.registration.auth0.redirect-uri={baseUrl}/login/oauth2/code/auth0 + +# Provider configuration +spring.security.oauth2.client.provider.auth0.issuer-uri=${AUTH0_ISSUER} + +# Resource server JWT (para valida\u00E7\u00E3o de tokens) +spring.security.oauth2.resourceserver.jwt.issuer-uri=${AUTH0_ISSUER} + +# For\u00E7a API a aceitar conex\u00F5es externas (necess\u00E1rio no Docker) +server.address=0.0.0.0 +server.port=8080 +server.servlet.session.cookie.secure=false diff --git a/VemProFutApi/src/main/resources/application.properties b/VemProFutApi/src/main/resources/application.properties index 917ad11..d20414d 100644 --- a/VemProFutApi/src/main/resources/application.properties +++ b/VemProFutApi/src/main/resources/application.properties @@ -1,62 +1 @@ -spring.application.name=VemProFut -spring.datasource.url=${SPRING_DATASOURCE_URL:jdbc:mysql://localhost:3306/vemprofutdb?createDatabaseIfNotExist=true&allowPublicKeyRetrieval=true&useSSL=false&serverTimeZone=UTC} -spring.datasource.username=${SPRING_DATASOURCE_USERNAME:root} -spring.datasource.password=${SPRING_DATASOURCE_PASSWORD:root123} - spring.profiles.active=${SPRING_PROFILES_ACTIVE:dev} - -spring.jpa.hibernate.ddl-auto=none - -############################################### -# == Ativando logs de excecoes do Spring ====== -############################################### - -logging.level.org.springframework.aop=DEBUG -logging.level.org.springframework.transaction=DEBUG -logging.level.org.hibernate.SQL=DEBUG -logging.level.org.hibernate.type.descriptor.sql=TRACE - -############################################### -#================ Flyway ====================== -############################################### -spring.flyway.enabled=true -spring.flyway.locations=classpath:db/migration - -############################################################### -# == Logger SLF4J para salvar os logs de erro e etc...========= -############################################################### - -logging.level.root=INFO -logging.level.br.com.vemprofut=DEBUG -logging.level.org.flywaydb=DEBUG - -logging.file.name=logs/vemprofut.log -logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n - -logging.logback.rollingpolicy.file-name-pattern=logs/vemprofut-%d{yyyy-MM-dd}.log -logging.logback.rollingpolicy.max-file-size=10MB -logging.logback.rollingpolicy.max-history=10 - -############################################### -# ========== OAuth2 Client (Auth0) ============ -############################################### - -spring.security.oauth2.client.registration.auth0.client-id=jcmpSdlqwwakcitekSVmh0F0Hw6BEcf7 -spring.security.oauth2.client.registration.auth0.client-secret=QWUV1hzjq3fgZy0vNuv_ir9Svsv11JeAw241YuPpMcCCeP7kdTbgajsaptfk52Mx -spring.security.oauth2.client.registration.auth0.scope=openid, profile, email -spring.security.oauth2.client.registration.auth0.redirect-uri=http://localhost:8080/login/oauth2/code/{registrationId} -spring.security.oauth2.client.registration.auth0.authorization-grant-type=authorization_code - -spring.security.oauth2.client.provider.auth0.issuer-uri=https://dev-6nhln802vsqkhnfm.us.auth0.com/ - - -############################################### -# ===== Resource Server (JWT Validation) ====== -############################################### - -spring.security.oauth2.resourceserver.jwt.issuer-uri=https://dev-6nhln802vsqkhnfm.us.auth0.com/ - -############################################### -# ======== Salvar Foto Localmente ============= -############################################### -app.upload.dir=uploads diff --git a/VemProFutApi/src/main/resources/db/migration/V202511092157__alter_table_partidas_contrains_fk_partidas2.sql b/VemProFutApi/src/main/resources/db/migration/V202511092157__alter_table_partidas_contrains_fk_partidas2.sql index 39c69a9..3ddbe2a 100644 --- a/VemProFutApi/src/main/resources/db/migration/V202511092157__alter_table_partidas_contrains_fk_partidas2.sql +++ b/VemProFutApi/src/main/resources/db/migration/V202511092157__alter_table_partidas_contrains_fk_partidas2.sql @@ -1,4 +1,4 @@ -ALTER TABLE Partidas ADD CONSTRAINT FK_Partidas_2 +ALTER TABLE partidas ADD CONSTRAINT FK_Partidas_2 FOREIGN KEY (fk_fut) - REFERENCES Fut (id_fut) + REFERENCES fut (id_fut) ON DELETE CASCADE; \ No newline at end of file diff --git a/VemProFutApi/src/main/resources/db/migration/V202511092159__alter_table_gols_constraint_fk_gols2.sql b/VemProFutApi/src/main/resources/db/migration/V202511092159__alter_table_gols_constraint_fk_gols2.sql index d458781..5bf7507 100644 --- a/VemProFutApi/src/main/resources/db/migration/V202511092159__alter_table_gols_constraint_fk_gols2.sql +++ b/VemProFutApi/src/main/resources/db/migration/V202511092159__alter_table_gols_constraint_fk_gols2.sql @@ -1,4 +1,4 @@ -ALTER TABLE Gols_Partida ADD CONSTRAINT FK_Gols_Partida_2 +ALTER TABLE gols_partida ADD CONSTRAINT FK_Gols_Partida_2 FOREIGN KEY (fk_peladeiro) - REFERENCES Peladeiro (id_peladeiro) + REFERENCES peladeiro (id_peladeiro) ON DELETE CASCADE; \ No newline at end of file diff --git a/VemProFutApi/src/main/resources/db/migration/V202511092200__alter_table_gols_constraint_fk_gols3.sql b/VemProFutApi/src/main/resources/db/migration/V202511092200__alter_table_gols_constraint_fk_gols3.sql new file mode 100644 index 0000000..8cb57f8 --- /dev/null +++ b/VemProFutApi/src/main/resources/db/migration/V202511092200__alter_table_gols_constraint_fk_gols3.sql @@ -0,0 +1,4 @@ +ALTER TABLE gols_partida ADD CONSTRAINT FK_Gols_Partida_3 + FOREIGN KEY (fk_partida) + REFERENCES partidas (id_partida) + ON DELETE CASCADE; \ No newline at end of file diff --git a/VemProFutApi/src/main/resources/db/migration/V202511092200__alter_table_gols_constraint_gols3,sql b/VemProFutApi/src/main/resources/db/migration/V202511092200__alter_table_gols_constraint_gols3,sql deleted file mode 100644 index 9c70e59..0000000 --- a/VemProFutApi/src/main/resources/db/migration/V202511092200__alter_table_gols_constraint_gols3,sql +++ /dev/null @@ -1,4 +0,0 @@ -ALTER TABLE Gols_Partida ADD CONSTRAINT FK_Gols_Partida_2 - FOREIGN KEY (fk_partida) - REFERENCES Partida (id_partida) - ON DELETE CASCADE; \ No newline at end of file diff --git a/VemProFutApi/src/main/resources/db/migration/V202511092204__alter_table_participapeladeiro_contraint_participa1.sql b/VemProFutApi/src/main/resources/db/migration/V202511092204__alter_table_participapeladeiro_contraint_participa1.sql index 5ef06e9..78c3bb6 100644 --- a/VemProFutApi/src/main/resources/db/migration/V202511092204__alter_table_participapeladeiro_contraint_participa1.sql +++ b/VemProFutApi/src/main/resources/db/migration/V202511092204__alter_table_participapeladeiro_contraint_participa1.sql @@ -1,4 +1,4 @@ ALTER TABLE participa_peladeiro_fut ADD CONSTRAINT FK_participa_peladeiro_fut_1 FOREIGN KEY (fk_fut) - REFERENCES Fut (id_fut) + REFERENCES fut (id_fut) ON DELETE CASCADE; diff --git a/VemProFutApi/src/main/resources/db/migration/V202511092205__alter_table_participapeladeiro_contraint_fk_participa2.sql b/VemProFutApi/src/main/resources/db/migration/V202511092205__alter_table_participapeladeiro_contraint_fk_participa2.sql index e7e9510..5278845 100644 --- a/VemProFutApi/src/main/resources/db/migration/V202511092205__alter_table_participapeladeiro_contraint_fk_participa2.sql +++ b/VemProFutApi/src/main/resources/db/migration/V202511092205__alter_table_participapeladeiro_contraint_fk_participa2.sql @@ -1,4 +1,4 @@ ALTER TABLE participa_peladeiro_fut ADD CONSTRAINT FK_participa_peladeiro_fut_2 FOREIGN KEY (fk_peladeiro) - REFERENCES Peladeiro (id_peladeiro) + REFERENCES peladeiro (id_peladeiro) ON DELETE CASCADE; diff --git a/VemProFutApi/src/main/resources/db/migration/V202511092206__alter_table_estapeladeio_constraint_esta1.sql b/VemProFutApi/src/main/resources/db/migration/V202511092206__alter_table_estapeladeio_constraint_esta1.sql index a838639..6da82e3 100644 --- a/VemProFutApi/src/main/resources/db/migration/V202511092206__alter_table_estapeladeio_constraint_esta1.sql +++ b/VemProFutApi/src/main/resources/db/migration/V202511092206__alter_table_estapeladeio_constraint_esta1.sql @@ -1,4 +1,4 @@ ALTER TABLE esta_peladeiro_partidas ADD CONSTRAINT FK_esta_peladeiro_partidas_1 FOREIGN KEY (fk_partidas) - REFERENCES Partidas (id_partida) + REFERENCES partidas (id_partida) ON DELETE CASCADE; diff --git a/VemProFutApi/src/main/resources/db/migration/V202511092208__alter_table_estapeladeiro_constraint_fk_esta2.sql b/VemProFutApi/src/main/resources/db/migration/V202511092208__alter_table_estapeladeiro_constraint_fk_esta2.sql index 62e90c6..c4f1a39 100644 --- a/VemProFutApi/src/main/resources/db/migration/V202511092208__alter_table_estapeladeiro_constraint_fk_esta2.sql +++ b/VemProFutApi/src/main/resources/db/migration/V202511092208__alter_table_estapeladeiro_constraint_fk_esta2.sql @@ -1,4 +1,4 @@ ALTER TABLE esta_peladeiro_partidas ADD CONSTRAINT FK_esta_peladeiro_partidas_2 FOREIGN KEY (fk_peladeiro) - REFERENCES Peladeiro (id_peladeiro) + REFERENCES peladeiro (id_peladeiro) ON DELETE CASCADE; diff --git a/VemProFutApi/src/main/resources/db/migration/V202511092212__alter_table_editor_constraint_fk_editor1.sql b/VemProFutApi/src/main/resources/db/migration/V202511092212__alter_table_editor_constraint_fk_editor1.sql index 2fb84f8..37cb6d1 100644 --- a/VemProFutApi/src/main/resources/db/migration/V202511092212__alter_table_editor_constraint_fk_editor1.sql +++ b/VemProFutApi/src/main/resources/db/migration/V202511092212__alter_table_editor_constraint_fk_editor1.sql @@ -1,4 +1,4 @@ ALTER TABLE editores_fut ADD CONSTRAINT FK_Editor_1 FOREIGN KEY (fk_fut) - REFERENCES Fut (id_fut) + REFERENCES fut (id_fut) ON DELETE CASCADE; \ No newline at end of file diff --git a/VemProFutApi/src/main/resources/db/migration/V202511092213__alter_table_editor_constraint_fk_editor2.sql b/VemProFutApi/src/main/resources/db/migration/V202511092213__alter_table_editor_constraint_fk_editor2.sql index 09e2f68..18699ae 100644 --- a/VemProFutApi/src/main/resources/db/migration/V202511092213__alter_table_editor_constraint_fk_editor2.sql +++ b/VemProFutApi/src/main/resources/db/migration/V202511092213__alter_table_editor_constraint_fk_editor2.sql @@ -1,4 +1,4 @@ ALTER TABLE editores_fut ADD CONSTRAINT FK_Editor_2 FOREIGN KEY (fk_peladeiro) - REFERENCES Peladeiro (id_peladeiro) + REFERENCES peladeiro (id_peladeiro) ON DELETE CASCADE; \ No newline at end of file diff --git a/VemProFutApi/src/main/resources/db/migration/V202511241710__alter_table_fk_banimento_2.sql b/VemProFutApi/src/main/resources/db/migration/V202511241710__alter_table_fk_banimento_2.sql index 135e5fb..f152c3c 100644 --- a/VemProFutApi/src/main/resources/db/migration/V202511241710__alter_table_fk_banimento_2.sql +++ b/VemProFutApi/src/main/resources/db/migration/V202511241710__alter_table_fk_banimento_2.sql @@ -1,4 +1,4 @@ ALTER TABLE banimento ADD CONSTRAINT FK_banimento_2 FOREIGN KEY (fk_peladeiro) - REFERENCES Peladeiro (id_peladeiro) + REFERENCES peladeiro (id_peladeiro) ON DELETE SET NULL; \ No newline at end of file diff --git a/VemProFutApi/src/main/resources/db/migration/V202511241712__alter_table_fk_banimento_3.sql b/VemProFutApi/src/main/resources/db/migration/V202511241712__alter_table_fk_banimento_3.sql index 6a41c75..95618c9 100644 --- a/VemProFutApi/src/main/resources/db/migration/V202511241712__alter_table_fk_banimento_3.sql +++ b/VemProFutApi/src/main/resources/db/migration/V202511241712__alter_table_fk_banimento_3.sql @@ -1,4 +1,4 @@ ALTER TABLE banimento ADD CONSTRAINT FK_banimento_3 FOREIGN KEY (fk_fut) - REFERENCES Fut (id_fut) + REFERENCES fut (id_fut) ON DELETE SET NULL; \ No newline at end of file diff --git a/VemProFutApi/src/test/java/br/com/vemprofut/VemProFutApplicationTests.java b/VemProFutApi/src/test/java/br/com/vemprofut/VemProFutApplicationTests.java deleted file mode 100644 index 8b8c5d1..0000000 --- a/VemProFutApi/src/test/java/br/com/vemprofut/VemProFutApplicationTests.java +++ /dev/null @@ -1,12 +0,0 @@ -package br.com.vemprofut; - -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class VemProFutApplicationTests { - - // @Test - // void contextLoads() { - // } - -} diff --git a/VemProFutApi/src/test/java/br/com/vemprofut/integration/repositories/BanimentoRepositoryIT.java b/VemProFutApi/src/test/java/br/com/vemprofut/integration/repositories/BanimentoRepositoryIT.java new file mode 100644 index 0000000..19f9e2c --- /dev/null +++ b/VemProFutApi/src/test/java/br/com/vemprofut/integration/repositories/BanimentoRepositoryIT.java @@ -0,0 +1,152 @@ +package br.com.vemprofut.integration.repositories; + +import static org.junit.jupiter.api.Assertions.*; + +import br.com.vemprofut.configs.OAuth2LoginSuccessHandler; +import br.com.vemprofut.models.BanimentoModel; +import br.com.vemprofut.models.FutModel; +import br.com.vemprofut.models.PeladeiroModel; +import br.com.vemprofut.repositories.BanimentoRepository; +import br.com.vemprofut.repositories.FutRepository; +import br.com.vemprofut.repositories.PeladeiroRepository; +import br.com.vemprofut.services.implementacao.UploadLocalService; +import jakarta.transaction.Transactional; +import java.time.LocalDate; +import java.util.List; +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.security.oauth2.client.OAuth2AuthorizedClientService; +import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; +import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.bean.override.mockito.MockitoBean; + +@SpringBootTest +@Transactional +@ActiveProfiles("test") +public class BanimentoRepositoryIT { + + @MockitoBean private OAuth2AuthorizedClientService authorizedClientService; + + // Opcional: Mocka o próprio Handler para evitar que ele tente rodar lógica + @MockitoBean private OAuth2LoginSuccessHandler oAuth2LoginSuccessHandler; + + @MockitoBean private ClientRegistrationRepository clientRegistrationRepository; + + @MockitoBean private JwtDecoder jwtDecoder; + + @MockitoBean private UploadLocalService uploadLocalService; + + @Autowired BanimentoRepository banimentoRepository; + + @Autowired PeladeiroRepository peladeiroRepository; + + @Autowired FutRepository futRepository; + + @Test + @DisplayName("Deve gerar salvar um banimento e retornar um id") + public void save_quandoBanimentoValido_retornaIdGerado() { + FutModel futModel = futRepository.saveAndFlush(new FutModel()); + PeladeiroModel peladeiroModel = + peladeiroRepository.saveAndFlush( + new PeladeiroModel( + "João da Silva", + "joao@test.com", + "Apelido", + "descricao qualquer", + "81999999999", + "Destro")); + + BanimentoModel banimentoModel = + new BanimentoModel( + "quebrou a perna do amigo", + LocalDate.of(2025, 11, 9), + LocalDate.of(2026, 11, 9), + peladeiroModel, + futModel); + + BanimentoModel banimentoSalvo = banimentoRepository.save(banimentoModel); + + assertNotNull(banimentoSalvo.getId()); + assertTrue(banimentoSalvo.getId() > 0); + } + + @Test + @DisplayName("Deve buscar todos os os banimentos") + public void findAll_quandoExistemRegistros_retornaListaComTodos() { + FutModel futModel1 = futRepository.saveAndFlush(new FutModel()); + FutModel futModel2 = futRepository.saveAndFlush(new FutModel()); + PeladeiroModel peladeiroModel1 = + peladeiroRepository.saveAndFlush( + new PeladeiroModel( + "João da Silva", + "joao@test.com", + "Apelido", + "descricao qualquer", + "81999999999", + "Destro")); + PeladeiroModel peladeiroModel2 = + peladeiroRepository.saveAndFlush( + new PeladeiroModel( + "João da Silva2", + "joao2@test.com", + "Apelido2", + "descricao qualquer2", + "81999999999", + "Destro")); + + BanimentoModel banimentoModel1 = + new BanimentoModel( + "quebrou a perna do amigo", + LocalDate.of(2025, 11, 9), + LocalDate.of(2026, 11, 9), + peladeiroModel1, + futModel1); + BanimentoModel banimentoModel2 = + new BanimentoModel( + "quebrou o ombro do amigo", + LocalDate.of(2025, 11, 9), + LocalDate.of(2026, 11, 9), + peladeiroModel2, + futModel2); + + banimentoRepository.saveAndFlush(banimentoModel1); + banimentoRepository.saveAndFlush(banimentoModel2); + + List todos = banimentoRepository.findAll(); + + assertTrue(todos.size() >= 2); + } + + @Test + @DisplayName("Deve apagar um banimento pelo numero do ID") + public void deleteById_quandoIdBanimentoExistir_registroRemovido() { + FutModel futModel = futRepository.saveAndFlush(new FutModel()); + PeladeiroModel peladeiroModel = + peladeiroRepository.saveAndFlush( + new PeladeiroModel( + "João da Silva", + "joao@test.com", + "Apelido", + "descricao qualquer", + "81999999999", + "Destro")); + + BanimentoModel banimentoModel = + new BanimentoModel( + "quebrou a perna do amigo", + LocalDate.of(2025, 11, 9), + LocalDate.of(2026, 11, 9), + peladeiroModel, + futModel); + + BanimentoModel banimentoSalvo = banimentoRepository.saveAndFlush(banimentoModel); + + Long id = banimentoSalvo.getId(); + + banimentoRepository.deleteById(id); + assertFalse(banimentoRepository.findById(id).isPresent()); + } +} diff --git a/VemProFutApi/src/test/java/br/com/vemprofut/integration/repositories/CartoesRepositoryIT.java b/VemProFutApi/src/test/java/br/com/vemprofut/integration/repositories/CartoesRepositoryIT.java new file mode 100644 index 0000000..a79912a --- /dev/null +++ b/VemProFutApi/src/test/java/br/com/vemprofut/integration/repositories/CartoesRepositoryIT.java @@ -0,0 +1,424 @@ +package br.com.vemprofut.integration.repositories; + +import static org.junit.jupiter.api.Assertions.*; + +import br.com.vemprofut.configs.OAuth2LoginSuccessHandler; +import br.com.vemprofut.models.CartoesModel; +import br.com.vemprofut.models.DTOs.CartaoCountProjection; +import br.com.vemprofut.models.FutModel; +import br.com.vemprofut.models.PartidasModel; +import br.com.vemprofut.models.PeladeiroModel; +import br.com.vemprofut.models.enuns.TipoCartao; +import br.com.vemprofut.repositories.CartoesRepository; +import br.com.vemprofut.repositories.FutRepository; +import br.com.vemprofut.repositories.PartidasRepository; +import br.com.vemprofut.repositories.PeladeiroRepository; +import br.com.vemprofut.services.implementacao.UploadLocalService; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +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.security.oauth2.client.OAuth2AuthorizedClientService; +import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; +import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.transaction.annotation.Transactional; + +@SpringBootTest +@Transactional +@ActiveProfiles("test") +public class CartoesRepositoryIT { + + @MockitoBean private OAuth2AuthorizedClientService authorizedClientService; + + // Opcional: Mocka o próprio Handler para evitar que ele tente rodar lógica + @MockitoBean private OAuth2LoginSuccessHandler oAuth2LoginSuccessHandler; + + @MockitoBean private ClientRegistrationRepository clientRegistrationRepository; + + @MockitoBean private UploadLocalService uploadLocalService; + + @MockitoBean private JwtDecoder jwtDecoder; + + @Autowired CartoesRepository cartoesRepository; + + @Autowired PartidasRepository partidasRepository; + + @Autowired FutRepository futRepository; + + @Autowired PeladeiroRepository peladeiroRepository; + + @Test + @DisplayName("Deve criar um novo cartao ligado ao peladeiro e a partida") + void save_quandoCartaoValido_retornaIdGerado() { + + PartidasModel partidasModel = partidasRepository.saveAndFlush(new PartidasModel()); + + FutModel futModel = futRepository.saveAndFlush(new FutModel()); + + PeladeiroModel peladeiroModel = + peladeiroRepository.saveAndFlush( + new PeladeiroModel( + "João da Silva", + "joao@test.com", + "Apelido", + "descricao qualquer", + "81999999999", + "Destro")); + + CartoesModel cartoesModel = + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel, peladeiroModel, futModel, TipoCartao.AMARELO)); + + assertNotNull(cartoesModel.getId()); + assertTrue(cartoesModel.getId() > 0); + } + + @Test + @DisplayName("Deve buscar todos cartoes e retorna em uma lista") + void findAll_quandoCartoesExistem_retornaListaCartao() { + PartidasModel partidasModel = partidasRepository.saveAndFlush(new PartidasModel()); + PartidasModel partidasModel2 = partidasRepository.saveAndFlush(new PartidasModel()); + + FutModel futModel = futRepository.saveAndFlush(new FutModel()); + FutModel futModel2 = futRepository.saveAndFlush(new FutModel()); + + PeladeiroModel peladeiroModel = + peladeiroRepository.saveAndFlush( + new PeladeiroModel( + "João da Silva", + "joao@test.com", + "Apelido", + "descricao qualquer", + "81999999999", + "Destro")); + + PeladeiroModel peladeiroModel2 = + peladeiroRepository.saveAndFlush( + new PeladeiroModel( + "João da Silva2", + "joao2@test.com", + "Apelido", + "descricao qualquer2", + "81999999999", + "Destro")); + + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel, peladeiroModel, futModel, TipoCartao.AMARELO)); + + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel2, peladeiroModel2, futModel2, TipoCartao.AMARELO)); + + List todos = cartoesRepository.findAll(); + + assertTrue(todos.size() >= 2); + } + + @Test + @DisplayName("Deve buscar um cartao pelo IDe retornar um Optional") + void findById_quandoCartaoExiste_retornaCartao() { + PartidasModel partidasModel = partidasRepository.saveAndFlush(new PartidasModel()); + + FutModel futModel = futRepository.saveAndFlush(new FutModel()); + + PeladeiroModel peladeiroModel = + peladeiroRepository.saveAndFlush( + new PeladeiroModel( + "João da Silva", + "joao@test.com", + "Apelido", + "descricao qualquer", + "81999999999", + "Destro")); + + CartoesModel cartoesModel = + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel, peladeiroModel, futModel, TipoCartao.AMARELO)); + + Long id = cartoesModel.getId(); + + assertTrue(cartoesRepository.findById(id).isPresent()); + } + + @Test + @DisplayName("Deve buscar um cartao pelo ID e retornar um Optional vazio") + void findById_quandoCartaoExiste_retornaOptinalVazio() { + PartidasModel partidasModel = partidasRepository.saveAndFlush(new PartidasModel()); + + FutModel futModel = futRepository.saveAndFlush(new FutModel()); + + PeladeiroModel peladeiroModel = + peladeiroRepository.saveAndFlush( + new PeladeiroModel( + "João da Silva", + "joao@test.com", + "Apelido", + "descricao qualquer", + "81999999999", + "Destro")); + + CartoesModel cartoesModel = + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel, peladeiroModel, futModel, TipoCartao.AMARELO)); + + Long id = 99999L; + + assertTrue(cartoesRepository.findById(id).isEmpty()); + } + + @Test + @DisplayName("Deve buscar todos os cartoes de um Peladeiro especifico") + void findByPeladeiro_quandoCartoesDoPeladeiroExistem_retornaListCartoes() { + PartidasModel partidasModel = partidasRepository.saveAndFlush(new PartidasModel()); + + FutModel futModel = futRepository.saveAndFlush(new FutModel()); + + PeladeiroModel peladeiroModel = + peladeiroRepository.saveAndFlush( + new PeladeiroModel( + "João da Silva", + "joao@test.com", + "Apelido", + "descricao qualquer", + "81999999999", + "Destro")); + + PeladeiroModel peladeiroModel2 = + peladeiroRepository.saveAndFlush( + new PeladeiroModel( + "Paulo Silva", + "paulo@test.com", + "Apelido", + "descricao qualquer2", + "81999999999", + "Destro")); + + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel, peladeiroModel, futModel, TipoCartao.AMARELO)); + + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel, peladeiroModel, futModel, TipoCartao.AZUL)); + + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel, peladeiroModel2, futModel, TipoCartao.AMARELO)); + + List todosCartoesPeladeiro = cartoesRepository.findByPeladeiro(peladeiroModel); + + assertEquals(2, todosCartoesPeladeiro.size()); + } + + @Test + @DisplayName("Deve buscar todos os cartoes de uma Partida especifico") + void findByPartida_quandoCartoesExistem_retornaListCartoes() { + PartidasModel partidasModel = partidasRepository.saveAndFlush(new PartidasModel()); + PartidasModel partidasModel2 = partidasRepository.saveAndFlush(new PartidasModel()); + + FutModel futModel = futRepository.saveAndFlush(new FutModel()); + + PeladeiroModel peladeiroModel = + peladeiroRepository.saveAndFlush( + new PeladeiroModel( + "João da Silva", + "joao@test.com", + "Apelido", + "descricao qualquer", + "81999999999", + "Destro")); + + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel, peladeiroModel, futModel, TipoCartao.AMARELO)); + + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel, peladeiroModel, futModel, TipoCartao.AZUL)); + + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel2, peladeiroModel, futModel, TipoCartao.AMARELO)); + + List todosCartoesPeladeiro = cartoesRepository.findByPartida(partidasModel); + + assertEquals(2, todosCartoesPeladeiro.size()); + } + + @Test + @DisplayName("Deve buscar todos os cartoes de um Peladeiro especifico") + void findByFut_quandoCartoesExistem_retornaListCartoes() { + PartidasModel partidasModel = partidasRepository.saveAndFlush(new PartidasModel()); + + FutModel futModel = futRepository.saveAndFlush(new FutModel()); + FutModel futModel2 = futRepository.saveAndFlush(new FutModel()); + + PeladeiroModel peladeiroModel = + peladeiroRepository.saveAndFlush( + new PeladeiroModel( + "João da Silva", + "joao@test.com", + "Apelido", + "descricao qualquer", + "81999999999", + "Destro")); + + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel, peladeiroModel, futModel, TipoCartao.AMARELO)); + + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel, peladeiroModel, futModel, TipoCartao.AZUL)); + + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel, peladeiroModel, futModel2, TipoCartao.AMARELO)); + + List todosCartoesPeladeiro = cartoesRepository.findByFut(futModel); + + assertEquals(2, todosCartoesPeladeiro.size()); + } + + @Test + @DisplayName("Deve retornar a quantidade de total de cada cartao de um peladeiro especifico") + void countByTipoAndPeladeiro_quandoCartoesExistem_retornaListCartoesPeladeiroContado() { + + PeladeiroModel peladeiroModel = + peladeiroRepository.saveAndFlush( + new PeladeiroModel( + "João da Silva", + "joao@test.com", + "Apelido", + "descricao qualquer", + "81999999999", + "Destro")); + + PeladeiroModel peladeiroModel2 = + peladeiroRepository.saveAndFlush( + new PeladeiroModel( + "Paulo Silva", + "paulo@test.com", + "Apelido", + "descricao qualquer2", + "81999999999", + "Destro")); + + FutModel futModel = futRepository.saveAndFlush(new FutModel()); + FutModel futModel2 = futRepository.saveAndFlush(new FutModel()); + + PartidasModel partidasModel = partidasRepository.saveAndFlush(new PartidasModel()); + PartidasModel partidasModel2 = partidasRepository.saveAndFlush(new PartidasModel()); + + // dados peladeiro 1 + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel, peladeiroModel, futModel, TipoCartao.AMARELO)); + + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel, peladeiroModel, futModel, TipoCartao.AZUL)); + + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel2, peladeiroModel, futModel2, TipoCartao.AMARELO)); + + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel2, peladeiroModel, futModel2, TipoCartao.VERMELHO)); + + // Dados peladeiro 2 + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel, peladeiroModel2, futModel, TipoCartao.AMARELO)); + + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel, peladeiroModel2, futModel, TipoCartao.AZUL)); + + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel2, peladeiroModel2, futModel2, TipoCartao.AMARELO)); + + List contagem = + cartoesRepository.countByTipoAndPeladeiro(peladeiroModel.getId()); + + // Transformar em mapa para facilitar + Map resultado = + Arrays.stream(TipoCartao.values()) + .collect( + Collectors.toMap( + tipo -> tipo, + tipo -> + contagem.stream() + .filter(c -> c.getTipo() == tipo) + .map(CartaoCountProjection::getQuantidade) + .findFirst() + .orElse(0L))); + + assertEquals(2, resultado.get(TipoCartao.AMARELO)); + assertEquals(1, resultado.get(TipoCartao.AZUL)); + assertEquals(1, resultado.get(TipoCartao.VERMELHO)); + } + + @Test + @DisplayName("Deve retornar a quantidade de total de cada cartao de um Fut especifico") + void countByTipoAndFut__quandoCartoesExistem_retornaListCartoesFutContado() { + PeladeiroModel peladeiroModel = + peladeiroRepository.saveAndFlush( + new PeladeiroModel( + "João da Silva", + "joao@test.com", + "Apelido", + "descricao qualquer", + "81999999999", + "Destro")); + + PeladeiroModel peladeiroModel2 = + peladeiroRepository.saveAndFlush( + new PeladeiroModel( + "Paulo Silva", + "paulo@test.com", + "Apelido", + "descricao qualquer2", + "81999999999", + "Destro")); + + FutModel futModel = futRepository.saveAndFlush(new FutModel()); + FutModel futModel2 = futRepository.saveAndFlush(new FutModel()); + + PartidasModel partidasModel = partidasRepository.saveAndFlush(new PartidasModel()); + PartidasModel partidasModel2 = partidasRepository.saveAndFlush(new PartidasModel()); + + // dados Fut 1 + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel, peladeiroModel, futModel, TipoCartao.AMARELO)); + + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel, peladeiroModel2, futModel, TipoCartao.AMARELO)); + + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel, peladeiroModel, futModel, TipoCartao.AZUL)); + + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel, peladeiroModel2, futModel, TipoCartao.AZUL)); + + // Dados fut 2 + + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel2, peladeiroModel2, futModel2, TipoCartao.AMARELO)); + + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel2, peladeiroModel, futModel2, TipoCartao.VERMELHO)); + + cartoesRepository.saveAndFlush( + new CartoesModel(partidasModel2, peladeiroModel, futModel2, TipoCartao.AMARELO)); + + List contagem = cartoesRepository.countByTipoAndFut(futModel.getId()); + + // Transformar em mapa para facilitar + Map resultado = + Arrays.stream(TipoCartao.values()) + .collect( + Collectors.toMap( + tipo -> tipo, + tipo -> + contagem.stream() + .filter(c -> c.getTipo() == tipo) + .map(CartaoCountProjection::getQuantidade) + .findFirst() + .orElse(0L))); + assertEquals(2, resultado.get(TipoCartao.AMARELO)); + assertEquals(2, resultado.get(TipoCartao.AZUL)); + assertEquals(0, resultado.get(TipoCartao.VERMELHO)); + } +} diff --git a/VemProFutApi/src/test/java/br/com/vemprofut/integration/repositories/EditorRepositoryIT.java b/VemProFutApi/src/test/java/br/com/vemprofut/integration/repositories/EditorRepositoryIT.java new file mode 100644 index 0000000..a06fb0d --- /dev/null +++ b/VemProFutApi/src/test/java/br/com/vemprofut/integration/repositories/EditorRepositoryIT.java @@ -0,0 +1,90 @@ +package br.com.vemprofut.integration.repositories; + +import static org.junit.jupiter.api.Assertions.*; + +import br.com.vemprofut.configs.OAuth2LoginSuccessHandler; +import br.com.vemprofut.models.EditorModel; +import br.com.vemprofut.models.FutModel; +import br.com.vemprofut.models.PeladeiroModel; +import br.com.vemprofut.repositories.EditorRepository; +import br.com.vemprofut.repositories.FutRepository; +import br.com.vemprofut.repositories.PeladeiroRepository; +import br.com.vemprofut.services.implementacao.UploadLocalService; +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.security.oauth2.client.OAuth2AuthorizedClientService; +import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; +import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.transaction.annotation.Transactional; + +@SpringBootTest +@Transactional +@ActiveProfiles("test") +public class EditorRepositoryIT { + + @MockitoBean private OAuth2AuthorizedClientService authorizedClientService; + + @MockitoBean private OAuth2LoginSuccessHandler oAuth2LoginSuccessHandler; + + @MockitoBean private ClientRegistrationRepository clientRegistrationRepository; + + @MockitoBean private UploadLocalService uploadLocalService; + + @MockitoBean private JwtDecoder jwtDecoder; + + @Autowired EditorRepository editorRepository; + + @Autowired PeladeiroRepository peladeiroRepository; + + @Autowired FutRepository futRepository; + + @Test + @DisplayName("Deve salvar um novo Editor em um Fut especifico") + void save_quandoEditorValido_retornaEditorSalvo() { + + FutModel futModel = futRepository.saveAndFlush(new FutModel()); + + PeladeiroModel peladeiroModel = + peladeiroRepository.saveAndFlush( + new PeladeiroModel( + "Marcio Teste", + "teste@test.com", + "Ronaldo", + "o cara nota 10", + "81992235678", + "Destro")); + + EditorModel editorModel = + editorRepository.saveAndFlush(new EditorModel(peladeiroModel, futModel)); + + assertNotNull(editorModel.getId()); + assertTrue(editorModel.getId() > 0); + } + + @Test + @DisplayName("Deve buscar e retornar um Editor salvo") + void findById_quandoEditorExiste_retornaEditorSalvo() { + FutModel futModel = futRepository.saveAndFlush(new FutModel()); + + PeladeiroModel peladeiroModel = + peladeiroRepository.saveAndFlush( + new PeladeiroModel( + "Marcio Teste", + "teste@test.com", + "Ronaldo", + "o cara nota 10", + "81992235678", + "Destro")); + + EditorModel editorModel = + editorRepository.saveAndFlush(new EditorModel(peladeiroModel, futModel)); + + Long id = editorModel.getId(); + + assertTrue(editorRepository.findById(id).isPresent()); + } +} diff --git a/VemProFutApi/src/test/java/br/com/vemprofut/integration/repositories/FutRepositoryIT.java b/VemProFutApi/src/test/java/br/com/vemprofut/integration/repositories/FutRepositoryIT.java new file mode 100644 index 0000000..569aeeb --- /dev/null +++ b/VemProFutApi/src/test/java/br/com/vemprofut/integration/repositories/FutRepositoryIT.java @@ -0,0 +1,78 @@ +package br.com.vemprofut.integration.repositories; + +import static org.junit.jupiter.api.Assertions.*; + +import br.com.vemprofut.configs.OAuth2LoginSuccessHandler; +import br.com.vemprofut.models.FutModel; +import br.com.vemprofut.repositories.FutRepository; +import br.com.vemprofut.services.implementacao.UploadLocalService; +import jakarta.transaction.Transactional; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService; +import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; +import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.bean.override.mockito.MockitoBean; + +@SpringBootTest +@Transactional +@ActiveProfiles("test") +public class FutRepositoryIT { + + @MockitoBean private OAuth2AuthorizedClientService authorizedClientService; + + @MockitoBean private OAuth2LoginSuccessHandler oAuth2LoginSuccessHandler; + + @MockitoBean private ClientRegistrationRepository clientRegistrationRepository; + + @MockitoBean private UploadLocalService uploadLocalService; + + @MockitoBean private JwtDecoder jwtDecoder; + + @Autowired FutRepository futRepository; + + @Test + // @DisplayName("deve gerar um Fut e retornar um id") + public void deveSalvarFut() { + + FutModel futModel = new FutModel("Fut teste", 4, 10, 2, null, null); + + FutModel salvo = futRepository.save(futModel); + + assertNotNull(salvo.getId()); + assertTrue(salvo.getId() > 0); + } + + @Test + // @DisplayName("findById deve retornar Optional vazio para id inexistente") + public void findByIdInexistente() { + Optional encontrado = futRepository.findById(9999L); + assertTrue(encontrado.isEmpty()); + } + + @Test + // @DisplayName("Deve retornar uma lista de Peladeiro") + public void findAllDeveRetornaListaFut() { + futRepository.saveAndFlush(new FutModel("Fut teste1", 4, 10, 2, null, null)); + futRepository.saveAndFlush(new FutModel("Fut teste2", 4, 10, 2, null, null)); + + List lista = futRepository.findAll(); + assertTrue(lista.size() >= 2); + } + + @Test + // @DisplayName("deve deletar um registro") + public void deleteFut() { + FutModel f = futRepository.saveAndFlush(new FutModel("Fut teste1", 4, 10, 2, null, null)); + + Long id = f.getId(); + futRepository.deleteById(id); + assertFalse(futRepository.findById(id).isPresent()); + } + + // TODO: implementar os testes de Fut buscarFutComListPeladeiros e buscarFutComListEditores +} diff --git a/VemProFutApi/src/test/java/br/com/vemprofut/integration/repositories/PeladeiroRepositoryIT.java b/VemProFutApi/src/test/java/br/com/vemprofut/integration/repositories/PeladeiroRepositoryIT.java new file mode 100644 index 0000000..826b7a5 --- /dev/null +++ b/VemProFutApi/src/test/java/br/com/vemprofut/integration/repositories/PeladeiroRepositoryIT.java @@ -0,0 +1,147 @@ +package br.com.vemprofut.integration.repositories; + +import static org.junit.jupiter.api.Assertions.*; + +import br.com.vemprofut.configs.OAuth2LoginSuccessHandler; +import br.com.vemprofut.models.PeladeiroModel; +import br.com.vemprofut.repositories.PeladeiroRepository; +import br.com.vemprofut.services.implementacao.UploadLocalService; +import jakarta.transaction.Transactional; +import java.util.List; +import java.util.Optional; +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.security.oauth2.client.OAuth2AuthorizedClientService; +import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; +import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.bean.override.mockito.MockitoBean; + +@SpringBootTest +@Transactional +@ActiveProfiles("test") +public class PeladeiroRepositoryIT { + /* + - Isso roda usando MySQL real via Docker + - Isso roda com Flyway + - Sem mocks — integração real + + Porque: + - Garante que o código realmente funciona no mesmo banco da produção. + - Evita problemas de comportamento diferente entre H2 <-> MySQL. + - Torna o ambiente de Dev ≈ Prod. + */ + // Mocka o serviço que o Spring não está encontrando + /* + Ao usar o @MockitoBean, você diz ao Spring: Não se preocupe em criar essa dependência real; + use um objeto de simulação (mock) no lugar para que o contexto possa ser inicializado. + */ + @MockitoBean private OAuth2AuthorizedClientService authorizedClientService; + + // Opcional: Mocka o próprio Handler para evitar que ele tente rodar lógica + @MockitoBean private OAuth2LoginSuccessHandler oAuth2LoginSuccessHandler; + + @MockitoBean private ClientRegistrationRepository clientRegistrationRepository; + + @MockitoBean private UploadLocalService uploadLocalService; + + @MockitoBean private JwtDecoder jwtDecoder; + + @Autowired PeladeiroRepository peladeiroRepository; + + @Test + @DisplayName("Deve gerar salvar um paladeiro e retornar um id") + public void save_quandoPeladeiroValido_retornaIdGerado() { + PeladeiroModel peladeiroModel = + new PeladeiroModel( + "Marcio Teste", "teste@test.com", "Ronaldo", "o cara nota 10", "81992235678", "Destro"); + + PeladeiroModel salvo = peladeiroRepository.save(peladeiroModel); + + assertNotNull(salvo.getId()); + assertTrue(salvo.getId() > 0); + } + + @Test + @DisplayName("findById deve retornar Optional vazio para id inexistente") + public void findById_quandoIdInexistente_retornaOptionalVazio() { + Optional encontrado = peladeiroRepository.findById(9999L); + assertTrue(encontrado.isEmpty()); + } + + @Test + @DisplayName("findAll deve retornar lista com todos os Peladeiros") + public void findAll_quandoExistemRegistros_retornaListaComTodos() { + peladeiroRepository.saveAndFlush( + new PeladeiroModel("A", "a@test.com", "A", "333", "81555555555", "Destro")); + peladeiroRepository.saveAndFlush( + new PeladeiroModel("B", "b@test.com", "B", "444", "82000000000", "Destro")); + + List todos = peladeiroRepository.findAll(); + assertTrue(todos.size() >= 2); + } + + @Test + @DisplayName("deleteById deve remover um registro existente") + public void deleteById_quandoIdExistente_registroEhRemovido() { + PeladeiroModel p = + peladeiroRepository.saveAndFlush( + new PeladeiroModel("C", "c@test.com", "C", "", "3", "Destro")); + Long id = p.getId(); + peladeiroRepository.deleteById(id); + assertFalse(peladeiroRepository.findById(id).isPresent()); + } + + @Test + @DisplayName("deve retorna de o email ja foi castrado ou nao") + public void existsByEmail_quandoEmailCadastrado_retornaTrue() { + peladeiroRepository.saveAndFlush( + new PeladeiroModel("C", "test@test.com", "C", "", "3", "Destro")); + String email = "test@test.com"; + Boolean exist = peladeiroRepository.existsByEmail(email); + + assertTrue(exist); + } + + @Test + @DisplayName("deve retorna falso de o email ja foi castrado ou nao") + public void existsByEmail_quandoEmailNaoCadastrado_retornaFalse() { + peladeiroRepository.saveAndFlush( + new PeladeiroModel("C", "test@test.com", "C", "", "3", "Destro")); + String email = "test2@test.com"; + Boolean exist = peladeiroRepository.existsByEmail(email); + + assertFalse(exist); + } + + @Test + // @DisplayName("Deve retornar um Peladeiro ao pesquisar pelo email") + public void buscarPeladeiroPeloEmailRetornaPeladeiro() { + PeladeiroModel p = + peladeiroRepository.saveAndFlush( + new PeladeiroModel("C", "test@test.com", "C", "descricao", "377777777777", "Destro")); + String email = "test@test.com"; + PeladeiroModel peladeiroModel = peladeiroRepository.findByEmail(email); + + assertEquals(p.getNome(), peladeiroModel.getNome()); + assertEquals(p.getEmail(), peladeiroModel.getEmail()); + assertEquals(p.getApelido(), peladeiroModel.getApelido()); + assertEquals(p.getWhatsapp(), peladeiroModel.getWhatsapp()); + assertEquals(p.getDescricao(), peladeiroModel.getDescricao()); + assertEquals(p.getPeDominante(), peladeiroModel.getPeDominante()); + } + + @Test + // @DisplayName("Deve retornar null ao buscar um peladeiro pelo email") + public void buscarPeladeiroPeloEmailRetornaNull() { + PeladeiroModel p = + peladeiroRepository.saveAndFlush( + new PeladeiroModel("C", "test@test.com", "C", "descricao", "377777777777", "Destro")); + String email = "test1@test.com"; + PeladeiroModel peladeiroModel = peladeiroRepository.findByEmail(email); + + assertNull(peladeiroModel); + } +} diff --git a/VemProFutApi/src/test/resources/application-test.properties b/VemProFutApi/src/test/resources/application-test.properties new file mode 100644 index 0000000..dd082b7 --- /dev/null +++ b/VemProFutApi/src/test/resources/application-test.properties @@ -0,0 +1,12 @@ +# MODE=MySQL = Isso faz o H2 emular a sintaxe do MySQL (tipos, fun\u00E7\u00F5es, etc.), permitindo que suas migra\u00E7\u00F5es rodem sem precisar reescrev\u00EA-las. +spring.datasource.url=jdbc:h2:mem:testdb;MODE=MySQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE +spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password= + +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect +spring.jpa.hibernate.ddl-auto=none + +# Flyway +spring.flyway.enabled=true +spring.flyway.locations=classpath:db/migration From 7c34e945c6b6543cacba56f382da5b805f382b62 Mon Sep 17 00:00:00 2001 From: "Marcio J. Costa" <87935294+MarcioCosta013@users.noreply.github.com> Date: Sat, 13 Dec 2025 23:35:41 -0300 Subject: [PATCH 2/2] Feature/implement test repository (#10) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test(BaseIntegrationTest): Criando a Base para testes usando conteiner Mysql para ser o mais semelhante possivel com o de producao * feat(Dockenizando): Dockerzinado a aplicacao para está preparada para subir para prod * feat(BaseIntegrationTest): Iniciando a implementacao dos testes usando o testconteiner com mysql * fix(testconteiner/docker): resolvendo erro de comunicacao do testconteine com o docker * feat(RepositoryTest):Refactorando o banco de dados de Testconteiner para H2 em memoria e criando os testes de Peladeiro, Fut,Banimento e Cartoes repositories * test(organizando diretorios de pastas): Separando os testes unitarios dos testes de intregracao e etc * test(organizando diretorios): alterei os nomes dos testes de integracao para o final IT; configurei o spotbugs para verificar os codigos antes de enviar o PR; add arquivo de filtro do spotbugs; * refactor:(mapeando DTOS): -Mapeando os atributos dos DTOs para os models; -Ignorando os atributos de models que nao vao ser usados nos DTOs; -alterei os nomes dos atributos nos DTOs para ficarem iguais ao da classe model para facilitaro mapeamento; -refatorei os locais onde usava o nome antigo dos atributos dos DTOs para o nome novo;