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