diff --git a/pom.xml b/pom.xml
index c14905c..6d44c88 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,13 +1,17 @@
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
+
+ jar
+
org.springframework.boot
spring-boot-starter-parent
- 3.4.0
+ 3.4.2
+
com.stelliocode
backend
0.0.1-SNAPSHOT
@@ -28,17 +32,13 @@
17
+ 0.8.11
org.springframework.boot
spring-boot-starter-data-jpa
-
- io.jsonwebtoken
- jjwt
- 0.9.1
-
org.springframework.boot
spring-boot-starter-security
@@ -47,11 +47,11 @@
org.springframework.boot
spring-boot-starter-validation
+
org.springframework.boot
spring-boot-starter-web
-
org.postgresql
postgresql
@@ -74,8 +74,31 @@
org.springframework.boot
- spring-boot-configuration-processor
- true
+ spring-boot-starter-mail
+
+
+ io.jsonwebtoken
+ jjwt-api
+ 0.11.5
+
+
+ io.jsonwebtoken
+ jjwt-impl
+ 0.11.5
+ runtime
+
+
+ io.jsonwebtoken
+ jjwt-jackson
+ 0.11.5
+ runtime
+
+
+
+ jakarta.servlet
+ jakarta.servlet-api
+ 6.0.0
+ provided
@@ -105,7 +128,25 @@
+
+ org.jacoco
+ jacoco-maven-plugin
+ ${jacoco.version}
+
+
+
+ prepare-agent
+
+
+
+ report
+ test
+
+ report
+
+
+
+
-
diff --git a/src/main/java/com/stelliocode/backend/config/JwtAuthenticationFilter.java b/src/main/java/com/stelliocode/backend/config/JwtAuthenticationFilter.java
index e4496e0..4e87db0 100644
--- a/src/main/java/com/stelliocode/backend/config/JwtAuthenticationFilter.java
+++ b/src/main/java/com/stelliocode/backend/config/JwtAuthenticationFilter.java
@@ -11,6 +11,7 @@
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
+
import java.io.IOException;
@Component
diff --git a/src/main/java/com/stelliocode/backend/config/MailConfig.java b/src/main/java/com/stelliocode/backend/config/MailConfig.java
new file mode 100644
index 0000000..6ee6bfc
--- /dev/null
+++ b/src/main/java/com/stelliocode/backend/config/MailConfig.java
@@ -0,0 +1,32 @@
+package com.stelliocode.backend.config;
+
+
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.mail.javamail.JavaMailSenderImpl;
+
+import java.util.Properties;
+
+@Configuration
+public class MailConfig {
+
+ @Bean
+ public JavaMailSender javaMailSender() {
+ JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
+ mailSender.setHost("smtp.gmail.com"); // Servidor SMTP do Gmail
+ mailSender.setPort(587); // Porta para TLS
+
+ // Credenciais do e-mail
+ mailSender.setUsername("seu-email@gmail.com"); // Substitua pelo seu e-mail
+ mailSender.setPassword("sua-senha"); // Substitua pela sua senha
+
+ // Propriedades adicionais
+ Properties props = mailSender.getJavaMailProperties();
+ props.put("mail.smtp.auth", "true"); // Autenticação SMTP
+ props.put("mail.smtp.starttls.enable", "true"); // Habilita STARTTLS
+
+ return mailSender;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/stelliocode/backend/config/SecurityConfig.java b/src/main/java/com/stelliocode/backend/config/SecurityConfig.java
index 786b797..68621a4 100644
--- a/src/main/java/com/stelliocode/backend/config/SecurityConfig.java
+++ b/src/main/java/com/stelliocode/backend/config/SecurityConfig.java
@@ -1,32 +1,19 @@
+
+
package com.stelliocode.backend.config;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
-import org.springframework.web.cors.CorsConfiguration;
-import org.springframework.web.cors.CorsConfigurationSource;
-import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
-
-import java.util.Arrays;
-import java.util.List;
+import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@Configuration
-@EnableWebSecurity
public class SecurityConfig {
private final JwtAuthenticationFilter jwtAuthenticationFilter;
- // Use the correct configuration for the origin
- @Value("${app.cors.allowed-origin}")
- private String[] allowedOrigins;
-
- // Constructor injection for JwtAuthenticationFilter
public SecurityConfig(JwtAuthenticationFilter jwtAuthenticationFilter) {
this.jwtAuthenticationFilter = jwtAuthenticationFilter;
}
@@ -34,33 +21,14 @@ public SecurityConfig(JwtAuthenticationFilter jwtAuthenticationFilter) {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
- .csrf(csrf -> csrf.disable())
- .cors(cors -> cors.configurationSource(corsConfigurationSource()))
+ .csrf(csrf -> csrf.disable()) // Desabilita CSRF (útil para APIs stateless)
.authorizeHttpRequests(auth -> auth
- .requestMatchers("/api/public/**").permitAll()
- .anyRequest().authenticated()
+ .requestMatchers(new AntPathRequestMatcher("/api/public/**")).permitAll() // Permite acesso público
+ .anyRequest().authenticated() // Exige autenticação para outros endpoints
)
- .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
+ .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); // Adiciona o filtro JWT
return http.build();
}
-
- @Bean
- public CorsConfigurationSource corsConfigurationSource() {
- CorsConfiguration configuration = new CorsConfiguration();
- configuration.setAllowedOrigins(List.of(allowedOrigins)); // Fix variable name
- configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
- configuration.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type"));
- configuration.setExposedHeaders(Arrays.asList("Authorization"));
- configuration.setAllowCredentials(true);
-
- UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
- source.registerCorsConfiguration("/**", configuration);
- return source;
- }
-
- @Bean
- public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
- return authConfig.getAuthenticationManager();
- }
}
+
diff --git a/src/main/java/com/stelliocode/backend/model/MeetingRequest.java b/src/main/java/com/stelliocode/backend/model/MeetingRequest.java
new file mode 100644
index 0000000..f083bc2
--- /dev/null
+++ b/src/main/java/com/stelliocode/backend/model/MeetingRequest.java
@@ -0,0 +1,189 @@
+package com.stelliocode.backend.model;
+
+import jakarta.persistence.*;
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import java.time.LocalDateTime;
+import java.util.Objects;
+
+/**
+ * Representa uma solicitação de reunião feita por um cliente.
+ */
+@Entity
+@Table(name = "meeting_requests")
+public class MeetingRequest {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @NotBlank
+ @Column(nullable = false, length = 100)
+ private String clientId;
+
+ @NotBlank
+ @Column(nullable = false, length = 100)
+ private String clientName;
+
+ @Email
+ @NotBlank
+ @Column(nullable = false, length = 100)
+ private String clientEmail;
+
+ @NotBlank
+ @Column(nullable = false, length = 20)
+ private String clientPhone;
+
+ @NotBlank
+ @Column(nullable = false, length = 100)
+ private String title; // Adicionado o campo title
+
+ @NotNull
+ @Column(nullable = false)
+ private LocalDateTime meetingDateTime;
+
+ @Enumerated(EnumType.STRING)
+ @Column(nullable = false)
+ private Status status;
+
+ @Size(max = 500, message = "As notas não podem ter mais de 500 caracteres")
+ @Column(length = 500)
+ private String notes;
+
+ public MeetingRequest() {
+ this.status = Status.PENDENTE; // Define o status padrão como "PENDENTE"
+ }
+
+ public MeetingRequest(String clientId, String clientName, String clientEmail, String clientPhone, String title, LocalDateTime meetingDateTime, String notes) {
+ this.clientId = clientId;
+ this.clientName = clientName;
+ this.clientEmail = clientEmail;
+ this.clientPhone = clientPhone;
+ this.title = title; // Inicializa o campo title
+ this.meetingDateTime = meetingDateTime;
+ this.notes = notes;
+ this.status = Status.PENDENTE; // Define o status padrão como "PENDENTE"
+ }
+
+ public enum Status {
+ PENDENTE("Pendente"),
+ ACEITA("Aceita"),
+ RECUSADA("Recusada"),
+ REALIZADA("Realizada");
+
+ private final String descricao;
+
+ Status(String descricao) {
+ this.descricao = descricao;
+ }
+
+ public String getDescricao() {
+ return descricao;
+ }
+ }
+
+ // Getters e Setters
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getClientId() {
+ return clientId;
+ }
+
+ public void setClientId(String clientId) {
+ this.clientId = clientId;
+ }
+
+ public String getClientName() {
+ return clientName;
+ }
+
+ public void setClientName(String clientName) {
+ this.clientName = clientName;
+ }
+
+ public String getClientEmail() {
+ return clientEmail;
+ }
+
+ public void setClientEmail(String clientEmail) {
+ this.clientEmail = clientEmail;
+ }
+
+ public String getClientPhone() {
+ return clientPhone;
+ }
+
+ public void setClientPhone(String clientPhone) {
+ this.clientPhone = clientPhone;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public LocalDateTime getMeetingDateTime() {
+ return meetingDateTime;
+ }
+
+ public void setMeetingDateTime(LocalDateTime meetingDateTime) {
+ this.meetingDateTime = meetingDateTime;
+ }
+
+ public Status getStatus() {
+ return status;
+ }
+
+ public void setStatus(Status status) {
+ this.status = status;
+ }
+
+ public String getNotes() {
+ return notes;
+ }
+
+ public void setNotes(String notes) {
+ this.notes = notes;
+ }
+
+ @Override
+ public String toString() {
+ return "MeetingRequest{" +
+ "id=" + id +
+ ", clientId='" + clientId + '\'' +
+ ", clientName='" + clientName + '\'' +
+ ", clientEmail='" + clientEmail + '\'' +
+ ", clientPhone='" + clientPhone + '\'' +
+ ", title='" + title + '\'' +
+ ", meetingDateTime=" + meetingDateTime +
+ ", status=" + status +
+ ", notes='" + notes + '\'' +
+ '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ MeetingRequest that = (MeetingRequest) o;
+ return Objects.equals(id, that.id) &&
+ Objects.equals(clientId, that.clientId) &&
+ Objects.equals(meetingDateTime, that.meetingDateTime);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, clientId, meetingDateTime);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/stelliocode/backend/repository/MeetingRequestRepository.java b/src/main/java/com/stelliocode/backend/repository/MeetingRequestRepository.java
new file mode 100644
index 0000000..7b0642e
--- /dev/null
+++ b/src/main/java/com/stelliocode/backend/repository/MeetingRequestRepository.java
@@ -0,0 +1,13 @@
+package com.stelliocode.backend.repository;
+
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import com.stelliocode.backend.model.MeetingRequest;
+import java.util.List;
+
+public interface MeetingRequestRepository extends JpaRepository {
+ // JpaRepository oferece métodos CRUD padrão
+ List findByStatus(MeetingRequest.Status status);
+}
+
+
diff --git a/src/main/java/com/stelliocode/backend/service/EmailService.java b/src/main/java/com/stelliocode/backend/service/EmailService.java
new file mode 100644
index 0000000..55c91b6
--- /dev/null
+++ b/src/main/java/com/stelliocode/backend/service/EmailService.java
@@ -0,0 +1,92 @@
+package com.stelliocode.backend.service;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.mail.SimpleMailMessage;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+@Service
+public class EmailService {
+
+ private static final Logger logger = LoggerFactory.getLogger(EmailService.class);
+
+ @Autowired
+ private JavaMailSender emailSender;
+
+ public void sendSimpleMessage(String to, String subject, String text) {
+ // Validação dos parâmetros
+ if (!StringUtils.hasText(to)) {
+ throw new IllegalArgumentException("O endereço de email do destinatário não pode estar vazio");
+ }
+ if (!StringUtils.hasText(subject)) {
+ throw new IllegalArgumentException("O assunto do email não pode estar vazio");
+ }
+ if (!StringUtils.hasText(text)) {
+ throw new IllegalArgumentException("O conteúdo do email não pode estar vazio");
+ }
+
+ try {
+ SimpleMailMessage message = new SimpleMailMessage();
+ message.setTo(to);
+ message.setSubject(subject);
+ message.setText(text);
+
+ emailSender.send(message);
+ logger.info("Email enviado com sucesso para: {}", to);
+ } catch (Exception e) {
+ logger.error("Erro ao enviar email para: {} - Erro: {}", to, e.getMessage());
+ throw new RuntimeException("Falha ao enviar email", e);
+ }
+ }
+}
+
+//package com.stelliocode.backend.service;
+//
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.mail.SimpleMailMessage;
+//import org.springframework.mail.javamail.JavaMailSender;
+//import org.springframework.stereotype.Service;
+//import org.springframework.util.StringUtils;
+//
+//
+//
+//@Service
+//public class EmailService {
+//
+// private static final Logger logger = LoggerFactory.getLogger(EmailService.class);
+//
+// @Autowired
+// private JavaMailSender emailSender;
+//
+// public void sendSimpleMessage(String to, String subject, String text) {
+// try {
+// // Validação dos parâmetros
+// if (!StringUtils.hasText(to)) {
+// throw new IllegalArgumentException("O endereço de email do destinatário não pode estar vazio");
+// }
+// if (!StringUtils.hasText(subject)) {
+// throw new IllegalArgumentException("O assunto do email não pode estar vazio");
+// }
+// if (!StringUtils.hasText(text)) {
+// throw new IllegalArgumentException("O conteúdo do email não pode estar vazio");
+// }
+//
+// SimpleMailMessage message = new SimpleMailMessage();
+// message.setTo(to);
+// message.setSubject(subject);
+// message.setText(text);
+//
+// emailSender.send(message);
+// logger.info("Email enviado com sucesso para: {}", to);
+// } catch (Exception e) {
+// logger.error("Erro ao enviar email para: {} - Erro: {}", to, e.getMessage());
+// throw new RuntimeException("Falha ao enviar email", e);
+// }
+// }
+//}
+//
diff --git a/src/main/java/com/stelliocode/backend/service/MeetingRequestService.java b/src/main/java/com/stelliocode/backend/service/MeetingRequestService.java
new file mode 100644
index 0000000..97bbbca
--- /dev/null
+++ b/src/main/java/com/stelliocode/backend/service/MeetingRequestService.java
@@ -0,0 +1,61 @@
+package com.stelliocode.backend.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.stelliocode.backend.model.MeetingRequest;
+import com.stelliocode.backend.repository.MeetingRequestRepository;
+
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Optional;
+
+@Service // Marca a classe como um serviço Spring
+public class MeetingRequestService {
+
+ @Autowired // Injeta o repositório automaticamente
+ private MeetingRequestRepository repository;
+
+ // Salva uma nova solicitação de reunião
+ public MeetingRequest saveMeetingRequest(MeetingRequest meetingRequest) {
+ if (meetingRequest == null) {
+ throw new IllegalArgumentException("MeetingRequest não pode ser nulo");
+ }
+ meetingRequest.setStatus(MeetingRequest.Status.PENDENTE); // Define o status inicial como "Pendente"
+ return repository.save(meetingRequest); // Salva no banco de dados
+ }
+
+ // Retorna todas as solicitações de reunião
+ public List getAllMeetingRequests() {
+ return repository.findAll(); // Busca todas as entradas no banco de dados
+ }
+
+ // Atualiza o status de uma solicitação de reunião
+ public MeetingRequest updateMeetingRequestStatus(Long id, MeetingRequest.Status status) {
+ if (id == null || status == null) {
+ throw new IllegalArgumentException("ID e Status não podem ser nulos");
+ }
+ MeetingRequest meetingRequest = repository.findById(id)
+ .orElseThrow(() -> new NoSuchElementException("MeetingRequest com ID " + id + " não encontrada"));
+ meetingRequest.setStatus(status); // Define o novo status
+ return repository.save(meetingRequest); // Salva a atualização no banco de dados
+ }
+
+ // Deleta uma solicitação de reunião
+ public void deleteMeetingRequest(Long id) {
+ if (id == null) {
+ throw new IllegalArgumentException("ID não pode ser nulo");
+ }
+ if (!repository.existsById(id)) {
+ throw new NoSuchElementException("MeetingRequest com ID " + id + " não encontrada");
+ }
+ repository.deleteById(id); // Remove a entrada do banco de dados
+ }
+
+ // Método adicional para buscar solicitações por status
+ public List getMeetingRequestsByStatus(MeetingRequest.Status status) {
+ if (status == null) {
+ throw new IllegalArgumentException("Status não pode ser nulo");
+ }
+ return repository.findByStatus(status);
+ }
+}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index c613173..cb73788 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -2,7 +2,7 @@ spring:
datasource:
url: ${DB_URL:jdbc:postgresql://localhost:5432/stelliocode}
username: ${DB_USERNAME:postgres}
- password: ${DB_PASSWORD:postgres}
+ password: ${DB_PASSWORD:1234}
jpa:
hibernate:
ddl-auto: update
diff --git a/src/test/java/com/stelliocode/backend/service/EmailServiceTest.java b/src/test/java/com/stelliocode/backend/service/EmailServiceTest.java
new file mode 100644
index 0000000..b8ab4e6
--- /dev/null
+++ b/src/test/java/com/stelliocode/backend/service/EmailServiceTest.java
@@ -0,0 +1,95 @@
+package com.stelliocode.backend.service;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.mail.SimpleMailMessage;
+import org.springframework.mail.javamail.JavaMailSender;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+public class EmailServiceTest {
+
+ @Mock
+ private JavaMailSender emailSender;
+
+ @InjectMocks
+ private EmailService emailService;
+
+ @BeforeEach
+ public void setUp() {
+ MockitoAnnotations.openMocks(this); // Inicializa os mocks
+ }
+
+ @Test
+ public void testSendSimpleMessage_Success() {
+ String to = "destinatario@example.com";
+ String subject = "Assunto do Email";
+ String text = "Conteúdo do Email";
+
+ emailService.sendSimpleMessage(to, subject, text);
+
+ verify(emailSender, times(1)).send(any(SimpleMailMessage.class));
+ }
+
+ @Test
+ public void testSendSimpleMessage_EmptyTo() {
+ String to = "";
+ String subject = "Assunto do Email";
+ String text = "Conteúdo do Email";
+
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> {
+ emailService.sendSimpleMessage(to, subject, text);
+ });
+
+ assertEquals("O endereço de email do destinatário não pode estar vazio", exception.getMessage());
+ verify(emailSender, never()).send(any(SimpleMailMessage.class));
+ }
+
+ @Test
+ public void testSendSimpleMessage_EmptySubject() {
+ String to = "destinatario@example.com";
+ String subject = "";
+ String text = "Conteúdo do Email";
+
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> {
+ emailService.sendSimpleMessage(to, subject, text);
+ });
+
+ assertEquals("O assunto do email não pode estar vazio", exception.getMessage());
+ verify(emailSender, never()).send(any(SimpleMailMessage.class));
+ }
+
+ @Test
+ public void testSendSimpleMessage_EmptyText() {
+ String to = "destinatario@example.com";
+ String subject = "Assunto do Email";
+ String text = "";
+
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> {
+ emailService.sendSimpleMessage(to, subject, text);
+ });
+
+ assertEquals("O conteúdo do email não pode estar vazio", exception.getMessage());
+ verify(emailSender, never()).send(any(SimpleMailMessage.class));
+ }
+
+ @Test
+ public void testSendSimpleMessage_Exception() {
+ String to = "destinatario@example.com";
+ String subject = "Assunto do Email";
+ String text = "Conteúdo do Email";
+
+ doThrow(new RuntimeException("Erro ao enviar email")).when(emailSender).send(any(SimpleMailMessage.class));
+
+ RuntimeException exception = assertThrows(RuntimeException.class, () -> {
+ emailService.sendSimpleMessage(to, subject, text);
+ });
+
+ assertEquals("Falha ao enviar email", exception.getMessage());
+ verify(emailSender, times(1)).send(any(SimpleMailMessage.class));
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/stelliocode/backend/service/MeetingRequestServiceTest.java b/src/test/java/com/stelliocode/backend/service/MeetingRequestServiceTest.java
new file mode 100644
index 0000000..e1950a8
--- /dev/null
+++ b/src/test/java/com/stelliocode/backend/service/MeetingRequestServiceTest.java
@@ -0,0 +1,190 @@
+package com.stelliocode.backend.service;
+
+import com.stelliocode.backend.model.MeetingRequest;
+import com.stelliocode.backend.repository.MeetingRequestRepository;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Optional;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+public class MeetingRequestServiceTest {
+
+ @Mock
+ private MeetingRequestRepository repository;
+
+ @InjectMocks
+ private MeetingRequestService service;
+
+ @BeforeEach
+ public void setUp() {
+ MockitoAnnotations.openMocks(this); // Inicializa os mocks
+ }
+
+ // Teste para salvar uma MeetingRequest com sucesso
+ @Test
+ public void testSaveMeetingRequest_Success() {
+ MeetingRequest meetingRequest = new MeetingRequest();
+ meetingRequest.setId(1L);
+ meetingRequest.setTitle("Reunião de Planejamento");
+
+ when(repository.save(any(MeetingRequest.class))).thenReturn(meetingRequest);
+
+ MeetingRequest savedRequest = service.saveMeetingRequest(meetingRequest);
+
+ assertNotNull(savedRequest);
+ assertEquals(MeetingRequest.Status.PENDENTE, savedRequest.getStatus()); // Verifica o status padrão
+ assertEquals("Reunião de Planejamento", savedRequest.getTitle());
+ verify(repository, times(1)).save(meetingRequest); // Verifica se o repositório foi chamado
+ }
+
+ // Teste para salvar uma MeetingRequest nula
+ @Test
+ public void testSaveMeetingRequest_NullRequest() {
+ assertThrows(IllegalArgumentException.class, () -> {
+ service.saveMeetingRequest(null);
+ });
+ verify(repository, never()).save(any()); // Verifica se o repositório NÃO foi chamado
+ }
+
+ // Teste para buscar todas as MeetingRequests
+ @Test
+ public void testGetAllMeetingRequests() {
+ MeetingRequest meetingRequest1 = new MeetingRequest();
+ meetingRequest1.setId(1L);
+ meetingRequest1.setTitle("Reunião 1");
+
+ MeetingRequest meetingRequest2 = new MeetingRequest();
+ meetingRequest2.setId(2L);
+ meetingRequest2.setTitle("Reunião 2");
+
+ when(repository.findAll()).thenReturn(List.of(meetingRequest1, meetingRequest2));
+
+ List requests = service.getAllMeetingRequests();
+
+ assertNotNull(requests);
+ assertEquals(2, requests.size());
+ assertEquals("Reunião 1", requests.get(0).getTitle());
+ assertEquals("Reunião 2", requests.get(1).getTitle());
+ verify(repository, times(1)).findAll(); // Verifica se o repositório foi chamado
+ }
+
+ // Teste para atualizar o status de uma MeetingRequest com sucesso
+ @Test
+ public void testUpdateMeetingRequestStatus_Success() {
+ MeetingRequest meetingRequest = new MeetingRequest();
+ meetingRequest.setId(1L);
+ meetingRequest.setStatus(MeetingRequest.Status.PENDENTE);
+
+ when(repository.findById(1L)).thenReturn(Optional.of(meetingRequest));
+ when(repository.save(any(MeetingRequest.class))).thenReturn(meetingRequest);
+
+ MeetingRequest updatedRequest = service.updateMeetingRequestStatus(1L, MeetingRequest.Status.ACEITA);
+
+ assertNotNull(updatedRequest);
+ assertEquals(MeetingRequest.Status.ACEITA, updatedRequest.getStatus());
+ verify(repository, times(1)).findById(1L); // Verifica se o repositório foi chamado
+ verify(repository, times(1)).save(meetingRequest); // Verifica se o repositório foi chamado
+ }
+
+ // Teste para atualizar o status de uma MeetingRequest com ID inválido
+ @Test
+ public void testUpdateMeetingRequestStatus_InvalidId() {
+ when(repository.findById(1L)).thenReturn(Optional.empty());
+
+ assertThrows(NoSuchElementException.class, () -> {
+ service.updateMeetingRequestStatus(1L, MeetingRequest.Status.ACEITA);
+ });
+ verify(repository, times(1)).findById(1L); // Verifica se o repositório foi chamado
+ verify(repository, never()).save(any()); // Verifica se o repositório NÃO foi chamado
+ }
+
+ // Teste para deletar uma MeetingRequest com sucesso
+ @Test
+ public void testDeleteMeetingRequest_Success() {
+ when(repository.existsById(1L)).thenReturn(true);
+ doNothing().when(repository).deleteById(1L);
+
+ assertDoesNotThrow(() -> {
+ service.deleteMeetingRequest(1L);
+ });
+
+ verify(repository, times(1)).existsById(1L); // Verifica se o repositório foi chamado
+ verify(repository, times(1)).deleteById(1L); // Verifica se o repositório foi chamado
+ }
+
+ // Teste para deletar uma MeetingRequest com ID inválido
+ @Test
+ public void testDeleteMeetingRequest_InvalidId() {
+ when(repository.existsById(1L)).thenReturn(false);
+
+ assertThrows(NoSuchElementException.class, () -> {
+ service.deleteMeetingRequest(1L);
+ });
+ verify(repository, times(1)).existsById(1L); // Verifica se o repositório foi chamado
+ verify(repository, never()).deleteById(any()); // Verifica se o repositório NÃO foi chamado
+ }
+
+ // Teste para buscar MeetingRequests por status
+ @Test
+ public void testGetMeetingRequestsByStatus() {
+ MeetingRequest meetingRequest1 = new MeetingRequest();
+ meetingRequest1.setId(1L);
+ meetingRequest1.setStatus(MeetingRequest.Status.ACEITA);
+
+ MeetingRequest meetingRequest2 = new MeetingRequest();
+ meetingRequest2.setId(2L);
+ meetingRequest2.setStatus(MeetingRequest.Status.ACEITA);
+
+ when(repository.findByStatus(MeetingRequest.Status.ACEITA))
+ .thenReturn(List.of(meetingRequest1, meetingRequest2));
+
+ List requests = service.getMeetingRequestsByStatus(MeetingRequest.Status.ACEITA);
+
+ assertNotNull(requests);
+ assertEquals(2, requests.size());
+ assertEquals(MeetingRequest.Status.ACEITA, requests.get(0).getStatus());
+ assertEquals(MeetingRequest.Status.ACEITA, requests.get(1).getStatus());
+ verify(repository, times(1)).findByStatus(MeetingRequest.Status.ACEITA); // Verifica se o repositório foi chamado
+ }
+
+ // Teste para buscar MeetingRequests por status nulo
+ @Test
+ public void testGetMeetingRequestsByStatus_NullStatus() {
+ assertThrows(IllegalArgumentException.class, () -> {
+ service.getMeetingRequestsByStatus(null);
+ });
+ verify(repository, never()).findByStatus(any()); // Verifica se o repositório NÃO foi chamado
+ }
+
+ // Teste para atualizar o status de uma MeetingRequest com status nulo
+ @Test
+ public void testUpdateMeetingRequestStatus_NullStatus() {
+ MeetingRequest meetingRequest = new MeetingRequest();
+ meetingRequest.setId(1L);
+ meetingRequest.setStatus(MeetingRequest.Status.PENDENTE);
+
+ when(repository.findById(1L)).thenReturn(Optional.of(meetingRequest));
+
+ assertThrows(IllegalArgumentException.class, () -> {
+ service.updateMeetingRequestStatus(1L, null);
+ });
+ verify(repository, never()).save(any()); // Verifica se o repositório NÃO foi chamado
+ }
+
+ // Teste para atualizar o status de uma MeetingRequest com ID nulo
+ @Test
+ public void testUpdateMeetingRequestStatus_NullId() {
+ assertThrows(IllegalArgumentException.class, () -> {
+ service.updateMeetingRequestStatus(null, MeetingRequest.Status.ACEITA);
+ });
+ verify(repository, never()).findById(any()); // Verifica se o repositório NÃO foi chamado
+ }
+}
\ No newline at end of file