moving security package and relevant files over to proprietary

This commit is contained in:
Dario Ghunney Ware
2025-05-09 16:48:48 +01:00
parent 3d312c2fd1
commit 58937a6e91
87 changed files with 1758 additions and 857 deletions

View File

@@ -0,0 +1,267 @@
package stirling.software.proprietary.security;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import stirling.software.common.model.ApplicationProperties;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class CustomLogoutSuccessHandlerTest {
@Mock private ApplicationProperties applicationProperties;
@InjectMocks private CustomLogoutSuccessHandler customLogoutSuccessHandler;
@Test
void testSuccessfulLogout() throws IOException {
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
String logoutPath = "logout=true";
when(response.isCommitted()).thenReturn(false);
when(request.getContextPath()).thenReturn("");
when(response.encodeRedirectURL(logoutPath)).thenReturn(logoutPath);
customLogoutSuccessHandler.onLogoutSuccess(request, response, null);
verify(response).sendRedirect(logoutPath);
}
@Test
void testSuccessfulLogoutViaOAuth2() throws IOException {
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
OAuth2AuthenticationToken oAuth2AuthenticationToken = mock(OAuth2AuthenticationToken.class);
ApplicationProperties.Security security = mock(ApplicationProperties.Security.class);
ApplicationProperties.Security.OAUTH2 oauth =
mock(ApplicationProperties.Security.OAUTH2.class);
when(response.isCommitted()).thenReturn(false);
when(request.getParameter("oAuth2AuthenticationErrorWeb")).thenReturn(null);
when(request.getParameter("errorOAuth")).thenReturn(null);
when(request.getScheme()).thenReturn("http");
when(request.getServerName()).thenReturn("localhost");
when(request.getServerPort()).thenReturn(8080);
when(request.getContextPath()).thenReturn("");
when(applicationProperties.getSecurity()).thenReturn(security);
when(security.getOauth2()).thenReturn(oauth);
when(oAuth2AuthenticationToken.getAuthorizedClientRegistrationId()).thenReturn("test");
customLogoutSuccessHandler.onLogoutSuccess(request, response, oAuth2AuthenticationToken);
verify(response).sendRedirect("http://localhost:8080/login?logout=true");
}
@Test
void testUserIsDisabledRedirect() throws IOException {
String error = "userIsDisabled";
String url = "http://localhost:8080";
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
OAuth2AuthenticationToken authentication = mock(OAuth2AuthenticationToken.class);
ApplicationProperties.Security security = mock(ApplicationProperties.Security.class);
ApplicationProperties.Security.OAUTH2 oauth =
mock(ApplicationProperties.Security.OAUTH2.class);
when(response.isCommitted()).thenReturn(false);
when(request.getParameter("oAuth2AuthenticationErrorWeb")).thenReturn(null);
when(request.getParameter("errorOAuth")).thenReturn(null);
when(request.getParameter("oAuth2AutoCreateDisabled")).thenReturn(null);
when(request.getParameter("oAuth2AdminBlockedUser")).thenReturn(null);
when(request.getParameter(error)).thenReturn("true");
when(request.getScheme()).thenReturn("http");
when(request.getServerName()).thenReturn("localhost");
when(request.getServerPort()).thenReturn(8080);
when(request.getContextPath()).thenReturn("");
when(applicationProperties.getSecurity()).thenReturn(security);
when(security.getOauth2()).thenReturn(oauth);
when(authentication.getAuthorizedClientRegistrationId()).thenReturn("test");
customLogoutSuccessHandler.onLogoutSuccess(request, response, authentication);
verify(response).sendRedirect(url + "/login?errorOAuth=" + error);
}
@Test
void testUserAlreadyExistsWebRedirect() throws IOException {
String error = "oAuth2AuthenticationErrorWeb";
String errorPath = "userAlreadyExistsWeb";
String url = "http://localhost:8080";
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
OAuth2AuthenticationToken authentication = mock(OAuth2AuthenticationToken.class);
ApplicationProperties.Security security = mock(ApplicationProperties.Security.class);
ApplicationProperties.Security.OAUTH2 oauth =
mock(ApplicationProperties.Security.OAUTH2.class);
when(response.isCommitted()).thenReturn(false);
when(request.getParameter(error)).thenReturn("true");
when(request.getScheme()).thenReturn("http");
when(request.getServerName()).thenReturn("localhost");
when(request.getServerPort()).thenReturn(8080);
when(request.getContextPath()).thenReturn("");
when(applicationProperties.getSecurity()).thenReturn(security);
when(security.getOauth2()).thenReturn(oauth);
when(authentication.getAuthorizedClientRegistrationId()).thenReturn("test");
customLogoutSuccessHandler.onLogoutSuccess(request, response, authentication);
verify(response).sendRedirect(url + "/login?errorOAuth=" + errorPath);
}
@Test
void testErrorOAuthRedirect() throws IOException {
String error = "testError";
String url = "http://localhost:8080";
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
OAuth2AuthenticationToken authentication = mock(OAuth2AuthenticationToken.class);
ApplicationProperties.Security security = mock(ApplicationProperties.Security.class);
ApplicationProperties.Security.OAUTH2 oauth =
mock(ApplicationProperties.Security.OAUTH2.class);
when(response.isCommitted()).thenReturn(false);
when(request.getParameter("oAuth2AuthenticationErrorWeb")).thenReturn(null);
when(request.getParameter("errorOAuth")).thenReturn("!!!" + error + "!!!");
when(request.getScheme()).thenReturn("http");
when(request.getServerName()).thenReturn("localhost");
when(request.getServerPort()).thenReturn(8080);
when(request.getContextPath()).thenReturn("");
when(applicationProperties.getSecurity()).thenReturn(security);
when(security.getOauth2()).thenReturn(oauth);
when(authentication.getAuthorizedClientRegistrationId()).thenReturn("test");
customLogoutSuccessHandler.onLogoutSuccess(request, response, authentication);
verify(response).sendRedirect(url + "/login?errorOAuth=" + error);
}
@Test
void testOAuth2AutoCreateDisabled() throws IOException {
String error = "oAuth2AutoCreateDisabled";
String url = "http://localhost:8080";
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
OAuth2AuthenticationToken authentication = mock(OAuth2AuthenticationToken.class);
ApplicationProperties.Security security = mock(ApplicationProperties.Security.class);
ApplicationProperties.Security.OAUTH2 oauth =
mock(ApplicationProperties.Security.OAUTH2.class);
when(response.isCommitted()).thenReturn(false);
when(request.getParameter("oAuth2AuthenticationErrorWeb")).thenReturn(null);
when(request.getParameter("errorOAuth")).thenReturn(null);
when(request.getParameter(error)).thenReturn("true");
when(request.getContextPath()).thenReturn(url);
when(request.getScheme()).thenReturn("http");
when(request.getServerName()).thenReturn("localhost");
when(request.getServerPort()).thenReturn(8080);
when(request.getContextPath()).thenReturn("");
when(applicationProperties.getSecurity()).thenReturn(security);
when(security.getOauth2()).thenReturn(oauth);
when(authentication.getAuthorizedClientRegistrationId()).thenReturn("test");
customLogoutSuccessHandler.onLogoutSuccess(request, response, authentication);
verify(response).sendRedirect(url + "/login?errorOAuth=" + error);
}
@Test
void testOAuth2Error() throws IOException {
String error = "test";
String url = "http://localhost:8080";
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
OAuth2AuthenticationToken authentication = mock(OAuth2AuthenticationToken.class);
ApplicationProperties.Security security = mock(ApplicationProperties.Security.class);
ApplicationProperties.Security.OAUTH2 oauth =
mock(ApplicationProperties.Security.OAUTH2.class);
when(response.isCommitted()).thenReturn(false);
when(request.getParameter("oAuth2AuthenticationErrorWeb")).thenReturn(null);
when(request.getParameter("errorOAuth")).thenReturn(null);
when(request.getParameter("oAuth2AutoCreateDisabled")).thenReturn(null);
when(request.getParameter("oAuth2AdminBlockedUser")).thenReturn(null);
when(request.getParameter("userIsDisabled")).thenReturn(null);
when(request.getParameter("error")).thenReturn("!@$!@£" + error + "£$%^*$");
when(request.getScheme()).thenReturn("http");
when(request.getServerName()).thenReturn("localhost");
when(request.getServerPort()).thenReturn(8080);
when(request.getContextPath()).thenReturn("");
when(applicationProperties.getSecurity()).thenReturn(security);
when(security.getOauth2()).thenReturn(oauth);
when(authentication.getAuthorizedClientRegistrationId()).thenReturn("test");
customLogoutSuccessHandler.onLogoutSuccess(request, response, authentication);
verify(response).sendRedirect(url + "/login?errorOAuth=" + error);
}
@Test
void testOAuth2BadCredentialsError() throws IOException {
String error = "badCredentials";
String url = "http://localhost:8080";
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
OAuth2AuthenticationToken authentication = mock(OAuth2AuthenticationToken.class);
ApplicationProperties.Security security = mock(ApplicationProperties.Security.class);
ApplicationProperties.Security.OAUTH2 oauth =
mock(ApplicationProperties.Security.OAUTH2.class);
when(response.isCommitted()).thenReturn(false);
when(request.getParameter("oAuth2AuthenticationErrorWeb")).thenReturn(null);
when(request.getParameter("errorOAuth")).thenReturn(null);
when(request.getParameter("oAuth2AutoCreateDisabled")).thenReturn(null);
when(request.getParameter("oAuth2AdminBlockedUser")).thenReturn(null);
when(request.getParameter("userIsDisabled")).thenReturn(null);
when(request.getParameter("error")).thenReturn(null);
when(request.getParameter(error)).thenReturn("true");
when(request.getScheme()).thenReturn("http");
when(request.getServerName()).thenReturn("localhost");
when(request.getServerPort()).thenReturn(8080);
when(request.getContextPath()).thenReturn("");
when(applicationProperties.getSecurity()).thenReturn(security);
when(security.getOauth2()).thenReturn(oauth);
when(authentication.getAuthorizedClientRegistrationId()).thenReturn("test");
customLogoutSuccessHandler.onLogoutSuccess(request, response, authentication);
verify(response).sendRedirect(url + "/login?errorOAuth=" + error);
}
@Test
void testOAuth2AdminBlockedUser() throws IOException {
String error = "oAuth2AdminBlockedUser";
String url = "http://localhost:8080";
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
OAuth2AuthenticationToken authentication = mock(OAuth2AuthenticationToken.class);
ApplicationProperties.Security security = mock(ApplicationProperties.Security.class);
ApplicationProperties.Security.OAUTH2 oauth =
mock(ApplicationProperties.Security.OAUTH2.class);
when(response.isCommitted()).thenReturn(false);
when(request.getParameter("oAuth2AuthenticationErrorWeb")).thenReturn(null);
when(request.getParameter("errorOAuth")).thenReturn(null);
when(request.getParameter("oAuth2AutoCreateDisabled")).thenReturn(null);
when(request.getParameter(error)).thenReturn("true");
when(request.getScheme()).thenReturn("http");
when(request.getServerName()).thenReturn("localhost");
when(request.getServerPort()).thenReturn(8080);
when(request.getContextPath()).thenReturn("");
when(applicationProperties.getSecurity()).thenReturn(security);
when(security.getOauth2()).thenReturn(oauth);
when(authentication.getAuthorizedClientRegistrationId()).thenReturn("test");
customLogoutSuccessHandler.onLogoutSuccess(request, response, authentication);
verify(response).sendRedirect(url + "/login?errorOAuth=" + error);
}
}

View File

@@ -0,0 +1,83 @@
package stirling.software.proprietary.security.configuration;
import javax.sql.DataSource;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import stirling.software.common.model.ApplicationProperties;
import stirling.software.common.model.exception.UnsupportedProviderException;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class DatabaseConfigTest {
@Mock private ApplicationProperties.Datasource datasource;
private DatabaseConfig databaseConfig;
@BeforeEach
void setUp() {
databaseConfig = new DatabaseConfig(datasource, true);
}
@Test
void testDataSource_whenRunningEEIsFalse() throws UnsupportedProviderException {
databaseConfig = new DatabaseConfig(datasource, false);
var result = databaseConfig.dataSource();
assertInstanceOf(DataSource.class, result);
}
@Test
void testDefaultConfigurationForDataSource() throws UnsupportedProviderException {
when(datasource.isEnableCustomDatabase()).thenReturn(false);
var result = databaseConfig.dataSource();
assertInstanceOf(DataSource.class, result);
}
@Test
void testCustomUrlForDataSource() throws UnsupportedProviderException {
when(datasource.isEnableCustomDatabase()).thenReturn(true);
when(datasource.getCustomDatabaseUrl()).thenReturn("jdbc:postgresql://mockUrl");
when(datasource.getUsername()).thenReturn("test");
when(datasource.getPassword()).thenReturn("pass");
var result = databaseConfig.dataSource();
assertInstanceOf(DataSource.class, result);
}
@Test
void testCustomConfigurationForDataSource() throws UnsupportedProviderException {
when(datasource.isEnableCustomDatabase()).thenReturn(true);
when(datasource.getCustomDatabaseUrl()).thenReturn("");
when(datasource.getType()).thenReturn("postgresql");
when(datasource.getHostName()).thenReturn("test");
when(datasource.getPort()).thenReturn(1234);
when(datasource.getName()).thenReturn("test_db");
when(datasource.getUsername()).thenReturn("test");
when(datasource.getPassword()).thenReturn("pass");
var result = databaseConfig.dataSource();
assertInstanceOf(DataSource.class, result);
}
@ParameterizedTest(name = "Exception thrown when the DB type [{arguments}] is not supported")
@ValueSource(strings = {"oracle", "mysql", "mongoDb"})
void exceptionThrown_whenDBTypeIsUnsupported(String datasourceType) {
when(datasource.isEnableCustomDatabase()).thenReturn(true);
when(datasource.getCustomDatabaseUrl()).thenReturn("");
when(datasource.getType()).thenReturn(datasourceType);
assertThrows(UnsupportedProviderException.class, () -> databaseConfig.dataSource());
}
}

View File

@@ -0,0 +1,95 @@
package stirling.software.proprietary.security.controller.api;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doThrow;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.stream.Stream;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.mail.MailSendException;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import jakarta.mail.MessagingException;
import stirling.software.proprietary.security.model.api.Email;
import stirling.software.proprietary.security.service.EmailService;
@ExtendWith(MockitoExtension.class)
class EmailControllerTest {
private MockMvc mockMvc;
@Mock private EmailService emailService;
@InjectMocks private EmailController emailController;
@BeforeEach
void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(emailController).build();
}
@ParameterizedTest(name = "Case {index}: exception={0}, includeTo={1}")
@MethodSource("emailParams")
void shouldHandleEmailRequests(
Exception serviceException,
boolean includeTo,
int expectedStatus,
String expectedContent)
throws Exception {
if (serviceException == null) {
doNothing().when(emailService).sendEmailWithAttachment(any(Email.class));
} else {
doThrow(serviceException).when(emailService).sendEmailWithAttachment(any(Email.class));
}
var request =
multipart("/api/v1/general/send-email")
.file("fileInput", "dummy-content".getBytes())
.param("subject", "Test Email")
.param("body", "This is a test email.");
if (includeTo) {
request = request.param("to", "test@example.com");
}
mockMvc.perform(request)
.andExpect(status().is(expectedStatus))
.andExpect(content().string(expectedContent));
}
static Stream<Arguments> emailParams() {
return Stream.of(
// success case
Arguments.of(null, true, 200, "Email sent successfully"),
// generic messaging error
Arguments.of(
new MessagingException("Failed to send email"),
true,
500,
"Failed to send email: Failed to send email"),
// missing 'to' results in MailSendException
Arguments.of(
new MailSendException("Invalid Addresses"),
false,
500,
"Invalid Addresses"),
// invalid email address formatting
Arguments.of(
new MessagingException("Invalid Addresses"),
true,
500,
"Failed to send email: Invalid Addresses"));
}
}

View File

@@ -0,0 +1,172 @@
package stirling.software.proprietary.security.service;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.web.multipart.MultipartFile;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import stirling.software.common.model.ApplicationProperties;
import stirling.software.proprietary.security.model.api.Email;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
public class EmailServiceTest {
@Mock private JavaMailSender mailSender;
@Mock private ApplicationProperties applicationProperties;
@Mock private ApplicationProperties.Mail mailProperties;
@Mock private MultipartFile fileInput;
@InjectMocks private EmailService emailService;
@Test
void testSendEmailWithAttachment() throws MessagingException {
// Mock the values returned by ApplicationProperties
when(applicationProperties.getMail()).thenReturn(mailProperties);
when(mailProperties.getFrom()).thenReturn("no-reply@stirling-software.com");
// Create a mock Email object
Email email = new Email();
email.setTo("test@example.com");
email.setSubject("Test Email");
email.setBody("This is a test email.");
email.setFileInput(fileInput);
// Mock MultipartFile behavior
when(fileInput.getOriginalFilename()).thenReturn("testFile.txt");
// Mock MimeMessage
MimeMessage mimeMessage = mock(MimeMessage.class);
// Configure mailSender to return the mocked MimeMessage
when(mailSender.createMimeMessage()).thenReturn(mimeMessage);
// Call the service method
emailService.sendEmailWithAttachment(email);
// Verify that the email was sent using mailSender
verify(mailSender).send(mimeMessage);
}
@Test
void testSendEmailWithAttachmentThrowsExceptionForMissingFilename() throws MessagingException {
Email email = new Email();
email.setTo("test@example.com");
email.setSubject("Test Email");
email.setBody("This is a test email.");
email.setFileInput(fileInput);
when(fileInput.isEmpty()).thenReturn(false);
when(fileInput.getOriginalFilename()).thenReturn("");
try {
emailService.sendEmailWithAttachment(email);
fail("Expected MessagingException to be thrown");
} catch (MessagingException e) {
assertEquals("An attachment is required to send the email.", e.getMessage());
}
}
@Test
void testSendEmailWithAttachmentThrowsExceptionForMissingFilenameNull()
throws MessagingException {
Email email = new Email();
email.setTo("test@example.com");
email.setSubject("Test Email");
email.setBody("This is a test email.");
email.setFileInput(fileInput);
when(fileInput.isEmpty()).thenReturn(false);
when(fileInput.getOriginalFilename()).thenReturn(null);
try {
emailService.sendEmailWithAttachment(email);
fail("Expected MessagingException to be thrown");
} catch (MessagingException e) {
assertEquals("An attachment is required to send the email.", e.getMessage());
}
}
@Test
void testSendEmailWithAttachmentThrowsExceptionForMissingFile() throws MessagingException {
Email email = new Email();
email.setTo("test@example.com");
email.setSubject("Test Email");
email.setBody("This is a test email.");
email.setFileInput(fileInput);
when(fileInput.isEmpty()).thenReturn(true);
try {
emailService.sendEmailWithAttachment(email);
fail("Expected MessagingException to be thrown");
} catch (MessagingException e) {
assertEquals("An attachment is required to send the email.", e.getMessage());
}
}
@Test
void testSendEmailWithAttachmentThrowsExceptionForMissingFileNull() throws MessagingException {
Email email = new Email();
email.setTo("test@example.com");
email.setSubject("Test Email");
email.setBody("This is a test email.");
email.setFileInput(null); // Missing file
try {
emailService.sendEmailWithAttachment(email);
fail("Expected MessagingException to be thrown");
} catch (MessagingException e) {
assertEquals("An attachment is required to send the email.", e.getMessage());
}
}
@Test
void testSendEmailWithAttachmentThrowsExceptionForInvalidAddressNull()
throws MessagingException {
Email email = new Email();
email.setTo(null); // Invalid address
email.setSubject("Test Email");
email.setBody("This is a test email.");
email.setFileInput(fileInput);
try {
emailService.sendEmailWithAttachment(email);
fail("Expected MailSendException to be thrown");
} catch (MessagingException e) {
assertEquals("Invalid Addresses", e.getMessage());
}
}
@Test
void testSendEmailWithAttachmentThrowsExceptionForInvalidAddressEmpty()
throws MessagingException {
Email email = new Email();
email.setTo(""); // Invalid address
email.setSubject("Test Email");
email.setBody("This is a test email.");
email.setFileInput(fileInput);
try {
emailService.sendEmailWithAttachment(email);
fail("Expected MailSendException to be thrown");
} catch (MessagingException e) {
assertEquals("Invalid Addresses", e.getMessage());
}
}
}

View File

@@ -0,0 +1,55 @@
package stirling.software.proprietary.security.service;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Properties;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import stirling.software.common.model.ApplicationProperties;
import stirling.software.proprietary.security.configuration.MailConfig;
class MailConfigTest {
private ApplicationProperties.Mail mailProps;
@BeforeEach
void initMailProperties() {
mailProps = mock(ApplicationProperties.Mail.class);
when(mailProps.getHost()).thenReturn("smtp.example.com");
when(mailProps.getPort()).thenReturn(587);
when(mailProps.getUsername()).thenReturn("user@example.com");
when(mailProps.getPassword()).thenReturn("password");
}
@Test
void shouldConfigureJavaMailSenderWithCorrectProperties() {
ApplicationProperties appProps = mock(ApplicationProperties.class);
when(appProps.getMail()).thenReturn(mailProps);
MailConfig config = new MailConfig(appProps);
JavaMailSender sender = config.javaMailSender();
assertInstanceOf(JavaMailSenderImpl.class, sender);
JavaMailSenderImpl impl = (JavaMailSenderImpl) sender;
Properties props = impl.getJavaMailProperties();
assertAll(
"SMTP configuration",
() -> assertEquals("smtp.example.com", impl.getHost()),
() -> assertEquals(587, impl.getPort()),
() -> assertEquals("user@example.com", impl.getUsername()),
() -> assertEquals("password", impl.getPassword()),
() -> assertEquals("UTF-8", impl.getDefaultEncoding()),
() -> assertEquals("true", props.getProperty("mail.smtp.auth")),
() -> assertEquals("true", props.getProperty("mail.smtp.starttls.enable")));
}
}