added unit tests for TbMailSender, refactred error handling in TbMailSender

This commit is contained in:
dashevchenko 2023-08-22 15:57:10 +03:00
parent a0228bdf45
commit 3e329d5f01
2 changed files with 112 additions and 12 deletions

View File

@ -28,8 +28,6 @@ import org.springframework.lang.Nullable;
import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.thingsboard.server.common.data.AdminSettings; import org.thingsboard.server.common.data.AdminSettings;
import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.mail.MailOauth2Provider; import org.thingsboard.server.common.data.mail.MailOauth2Provider;
import org.thingsboard.server.dao.exception.IncorrectParameterException; import org.thingsboard.server.dao.exception.IncorrectParameterException;
@ -71,24 +69,28 @@ public class TbMailSender extends JavaMailSenderImpl {
} }
@Override @Override
public void doSend(MimeMessage[] mimeMessages, @Nullable Object[] originalMessages) { protected void doSend(MimeMessage[] mimeMessages, @Nullable Object[] originalMessages) {
updateOauth2PasswordIfExpired(); updateOauth2PasswordIfExpired();
doSendSuper(mimeMessages, originalMessages);
}
protected void doSendSuper(MimeMessage[] mimeMessages, Object[] originalMessages) {
super.doSend(mimeMessages, originalMessages); super.doSend(mimeMessages, originalMessages);
} }
@Override @Override
public void testConnection() throws MessagingException { public void testConnection() throws MessagingException {
updateOauth2PasswordIfExpired(); updateOauth2PasswordIfExpired();
testConnectionSuper();
}
public void testConnectionSuper() throws MessagingException {
super.testConnection(); super.testConnection();
} }
private void updateOauth2PasswordIfExpired() { public void updateOauth2PasswordIfExpired() {
if (oauth2Enabled && (System.currentTimeMillis() > tokenExpires)){ if (oauth2Enabled && (System.currentTimeMillis() > tokenExpires)){
try { refreshAccessToken();
refreshAccessToken();
} catch (ThingsboardException e) {
throw new RuntimeException(e);
}
setPassword(accessToken); setPassword(accessToken);
} }
} }
@ -138,7 +140,7 @@ public class TbMailSender extends JavaMailSenderImpl {
return javaMailProperties; return javaMailProperties;
} }
public void refreshAccessToken() throws ThingsboardException { public void refreshAccessToken() {
lock.lock(); lock.lock();
try { try {
if (System.currentTimeMillis() > tokenExpires) { if (System.currentTimeMillis() > tokenExpires) {
@ -164,8 +166,8 @@ public class TbMailSender extends JavaMailSenderImpl {
tokenExpires = System.currentTimeMillis() + (tokenResponse.getExpiresInSeconds().intValue() * 1000); tokenExpires = System.currentTimeMillis() + (tokenResponse.getExpiresInSeconds().intValue() * 1000);
} }
} catch (Exception e) { } catch (Exception e) {
log.warn("Unable to retrieve access token: {}", e.getMessage()); log.error("Unable to retrieve access token: {}", e.getMessage());
throw new ThingsboardException("Error while retrieving access token: " + e.getMessage(), ThingsboardErrorCode.GENERAL); throw new RuntimeException("Error while retrieving access token: " + e.getMessage());
} finally { } finally {
lock.unlock(); lock.unlock();
} }

View File

@ -0,0 +1,98 @@
package org.thingsboard.server.service.mail;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import org.thingsboard.common.util.JacksonUtil;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@RunWith(MockitoJUnitRunner.class)
public class TbMailSenderTest {
@Test
public void testDoSendSendMail() {
ObjectNode jsonConfig = getBasicMailConfig();
TbMailSender tbMailSender = spy(new TbMailSender(mock(TbMailContextComponent.class), jsonConfig));
MimeMessage mimeMsg = new MimeMessage(Session.getInstance(new Properties()));
List<MimeMessage> mimeMessages = new ArrayList<>(1);
mimeMessages.add(mimeMsg);
Mockito.doNothing().when(tbMailSender).updateOauth2PasswordIfExpired();
Mockito.doNothing().when(tbMailSender).doSendSuper(any(), any());
tbMailSender.doSend(mimeMessages.toArray(new MimeMessage[0]), null);
Mockito.verify(tbMailSender, times(1)).updateOauth2PasswordIfExpired();
}
@Test
public void testTestConnection() throws MessagingException {
ObjectNode jsonConfig = getBasicMailConfig();
TbMailSender tbMailSender = spy(new TbMailSender(mock(TbMailContextComponent.class), jsonConfig));
Mockito.doNothing().when(tbMailSender).updateOauth2PasswordIfExpired();
Mockito.doNothing().when(tbMailSender).testConnectionSuper();
tbMailSender.testConnection();
Mockito.verify(tbMailSender, times(1)).updateOauth2PasswordIfExpired();
}
@Test
public void testUpdateOauth2PasswordIfExpiredIfOauth2Enabled() {
ObjectNode jsonConfig = getOauth2Config();
TbMailSender tbMailSender = spy(new TbMailSender(mock(TbMailContextComponent.class), jsonConfig));
Mockito.doNothing().when(tbMailSender).refreshAccessToken();
tbMailSender.updateOauth2PasswordIfExpired();
Mockito.verify(tbMailSender, times(1)).refreshAccessToken();
Mockito.verify(tbMailSender, times(1)).setPassword(any());
}
@Test
public void testUpdateOauth2PasswordIfExpiredIfOauth2Disabled() {
ObjectNode jsonConfig = getBasicMailConfig();
TbMailSender tbMailSender = spy(new TbMailSender(mock(TbMailContextComponent.class), jsonConfig));
tbMailSender.updateOauth2PasswordIfExpired();
Mockito.verify(tbMailSender, Mockito.never()).refreshAccessToken();
Mockito.verify(tbMailSender, Mockito.never()).setPassword(any());
}
private static ObjectNode getOauth2Config() {
ObjectNode jsonConfig = JacksonUtil.newObjectNode();
jsonConfig.put("smtpProtocol", "smtps");
jsonConfig.put("timeout", "1000");
jsonConfig.put("enableOauth2", true);
jsonConfig.put("smtpHost", "smtp.gmail.com");
jsonConfig.put("smtpPort", "465");
jsonConfig.put("username", "testUser");
return jsonConfig;
}
private static ObjectNode getBasicMailConfig() {
ObjectNode jsonConfig = JacksonUtil.newObjectNode();
jsonConfig.put("smtpProtocol", "smtps");
jsonConfig.put("timeout", "1000");
jsonConfig.put("smtpHost", "smtp.gmail.com");
jsonConfig.put("smtpPort", "465");
jsonConfig.put("username", "testUser");
return jsonConfig;
}
}