Backend migration
This commit is contained in:
114
backend/services/mailService/pom.xml
Normal file
114
backend/services/mailService/pom.xml
Normal file
@@ -0,0 +1,114 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>dev.rheinsw</groupId>
|
||||
<artifactId>rheinsw-backend</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>mailService</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven.compiler.plugin.version}</version>
|
||||
<configuration>
|
||||
<source>${maven.compiler.source}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<!-- Spring Boot starter for REST -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/jakarta.mail/jakarta.mail-api -->
|
||||
<dependency>
|
||||
<groupId>jakarta.mail</groupId>
|
||||
<artifactId>jakarta.mail-api</artifactId>
|
||||
<version>2.1.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.validation</groupId>
|
||||
<artifactId>jakarta.validation-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>33.4.0-jre</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.rheinsw</groupId>
|
||||
<artifactId>shared</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- test suite -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-junit-jupiter</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,18 @@
|
||||
package dev.rheinsw.mail;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* @author Thatsaphorn Atchariyaphap
|
||||
* @since 22.04.25
|
||||
*/
|
||||
@SpringBootApplication(exclude = {
|
||||
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration.class,
|
||||
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration.class
|
||||
})
|
||||
public class MailServiceApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(MailServiceApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package dev.rheinsw.mail.controller;
|
||||
|
||||
import dev.rheinsw.shared.mail.dto.MailRequest;
|
||||
import dev.rheinsw.mail.service.MailService;
|
||||
import jakarta.mail.MessagingException;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
/**
|
||||
* @author Thatsaphorn Atchariyaphap
|
||||
* @since 22.04.25
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/mail")
|
||||
@RequiredArgsConstructor
|
||||
public class MailController {
|
||||
|
||||
private final MailService mailService;
|
||||
|
||||
@PostMapping("/send")
|
||||
public ResponseEntity<String> sendEmail(@RequestBody MailRequest request) {
|
||||
try {
|
||||
mailService.sendEmail(request);
|
||||
return ResponseEntity.ok("Email sent successfully");
|
||||
} catch (MessagingException e) {
|
||||
return ResponseEntity.status(500).body("Failed to send email: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package dev.rheinsw.mail.service;
|
||||
|
||||
import dev.rheinsw.shared.mail.dto.MailRequest;
|
||||
import jakarta.mail.MessagingException;
|
||||
import jakarta.mail.internet.MimeMessage;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author Thatsaphorn Atchariyaphap
|
||||
* @since 22.04.25
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class MailService {
|
||||
|
||||
private final JavaMailSender mailSender;
|
||||
|
||||
public void sendEmail(MailRequest request) throws MessagingException {
|
||||
MimeMessage message = mailSender.createMimeMessage();
|
||||
MimeMessageHelper helper = new MimeMessageHelper(message, true);
|
||||
|
||||
helper.setFrom("noreply@rhein-software.dev");
|
||||
helper.setTo(request.getTo());
|
||||
helper.setSubject(request.getSubject());
|
||||
helper.setText(request.getMessage(), false);
|
||||
|
||||
mailSender.send(message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
server:
|
||||
port: 0 # random port
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: mailService
|
||||
|
||||
mail:
|
||||
host: smtp.resend.com
|
||||
port: 587
|
||||
username: resend
|
||||
password: re_JnLD5ndg_GnKtXcTqskXm1bg7Wxnghna3
|
||||
properties:
|
||||
mail:
|
||||
smtp:
|
||||
auth: true
|
||||
starttls:
|
||||
enable: true
|
||||
default-encoding: UTF-8
|
||||
|
||||
eureka:
|
||||
client:
|
||||
service-url:
|
||||
defaultZone: http://localhost:8761/eureka/
|
||||
@@ -0,0 +1,63 @@
|
||||
package dev.rheinsw.mail.controller;
|
||||
|
||||
import dev.rheinsw.mail.service.MailService;
|
||||
import dev.rheinsw.shared.mail.dto.MailRequest;
|
||||
import jakarta.mail.MessagingException;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.*;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
class MailControllerTest {
|
||||
|
||||
@Mock
|
||||
private MailService mailService;
|
||||
|
||||
@InjectMocks
|
||||
private MailController mailController;
|
||||
|
||||
private AutoCloseable closeable;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
closeable = MockitoAnnotations.openMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendEmail_shouldReturnOk_whenEmailSentSuccessfully() throws MessagingException {
|
||||
// Arrange
|
||||
MailRequest request = new MailRequest("user@example.com", "Test Subject", "Message");
|
||||
|
||||
// Act
|
||||
ResponseEntity<String> response = mailController.sendEmail(request);
|
||||
|
||||
// Assert
|
||||
verify(mailService).sendEmail(request);
|
||||
assertEquals(200, response.getStatusCodeValue());
|
||||
assertEquals("Email sent successfully", response.getBody());
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendEmail_shouldReturnServerError_whenMessagingExceptionThrown() throws MessagingException {
|
||||
// Arrange
|
||||
MailRequest request = new MailRequest("user@example.com", "Test Subject", "Message");
|
||||
doThrow(new MessagingException("SMTP failed")).when(mailService).sendEmail(request);
|
||||
|
||||
// Act
|
||||
ResponseEntity<String> response = mailController.sendEmail(request);
|
||||
|
||||
// Assert
|
||||
verify(mailService).sendEmail(request);
|
||||
assertEquals(500, response.getStatusCodeValue());
|
||||
assertTrue(response.getBody().contains("Failed to send email: SMTP failed"));
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() throws Exception {
|
||||
closeable.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package dev.rheinsw.mail.service;
|
||||
|
||||
import dev.rheinsw.shared.mail.dto.MailRequest;
|
||||
import jakarta.mail.MessagingException;
|
||||
import jakarta.mail.internet.MimeMessage;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.*;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
class MailServiceTest {
|
||||
|
||||
@Mock
|
||||
private JavaMailSender mailSender;
|
||||
|
||||
@InjectMocks
|
||||
private MailService mailService;
|
||||
|
||||
private AutoCloseable closeable;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
closeable = MockitoAnnotations.openMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendEmail_shouldSendMessageSuccessfully() throws MessagingException {
|
||||
// Arrange
|
||||
MailRequest request = new MailRequest("user@example.com", "Hello", "This is a test message.");
|
||||
MimeMessage mimeMessage = mock(MimeMessage.class);
|
||||
when(mailSender.createMimeMessage()).thenReturn(mimeMessage);
|
||||
|
||||
// Act & Assert
|
||||
assertDoesNotThrow(() -> mailService.sendEmail(request));
|
||||
verify(mailSender).send(mimeMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendEmail_shouldThrowMessagingException_whenMailSenderFails() {
|
||||
// Arrange
|
||||
MailRequest request = new MailRequest("user@example.com", "Hello", "This is a test message.");
|
||||
MimeMessage mimeMessage = mock(MimeMessage.class);
|
||||
when(mailSender.createMimeMessage()).thenReturn(mimeMessage);
|
||||
doThrow(new RuntimeException("Simulated failure")).when(mailSender).send(mimeMessage);
|
||||
|
||||
// Act & Assert
|
||||
RuntimeException exception = assertThrows(RuntimeException.class, () -> {
|
||||
mailService.sendEmail(request);
|
||||
});
|
||||
|
||||
assertEquals("Simulated failure", exception.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user