Skip to content

Commit

Permalink
smtp mail support (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
m-adawi authored Oct 7, 2023
1 parent 8c29ac1 commit bae777b
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 17 deletions.
4 changes: 4 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
</dependencies>

<dependencyManagement>
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/org/otherband/Utils.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package org.otherband;

import org.otherband.email.VerificationLinkEmailRequest;
import org.otherband.exceptions.UserInputException;
import org.otherband.letter.RecommendationLetterController;

import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;

public class Utils {

Expand All @@ -11,4 +15,11 @@ private Utils() {
public static void validateNotBlank(String field, String fieldName) {
if (isBlank(field)) throw UserInputException.formatted("[%s] cannot be blank", fieldName);
}

public static String buildLetterVerificationLink(VerificationLinkEmailRequest verificationLinkEmailRequest) {
return linkTo(methodOn(RecommendationLetterController.class)
.verify(verificationLinkEmailRequest.getLetterId(),
verificationLinkEmailRequest.getTokenId(),
verificationLinkEmailRequest.getSecretToken())).withSelfRel().toString();
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
package org.otherband.email.simulation;

import org.otherband.Utils;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import org.otherband.email.EmailService;
import org.otherband.email.VerificationLinkEmailRequest;
import org.otherband.letter.RecommendationLetterController;

import java.util.UUID;

import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
import static org.otherband.email.simulation.SimulatedEmailsRepository.SimulatedEmail;

@Component
Expand All @@ -23,23 +19,17 @@ public EmailServiceSimulator(SimulatedEmailsRepository emailsRepository) {

@Override
public void sendLetterVerificationLink(VerificationLinkEmailRequest verificationLinkEmailRequest) {
emailsRepository.save(buildEmail(verificationLinkEmailRequest.getLetterId(),
verificationLinkEmailRequest.getTokenId(),
verificationLinkEmailRequest.getSecretToken(),
verificationLinkEmailRequest.getReceiverEmail()));
emailsRepository.save(buildEmail(verificationLinkEmailRequest));
}

private static SimulatedEmail buildEmail(String letterId, String tokenId, String secretToken, String receiverAddress) {
private static SimulatedEmail buildEmail(VerificationLinkEmailRequest verificationLinkEmailRequest) {
SimulatedEmail simulatedEmail = new SimulatedEmail();
simulatedEmail.setId(UUID.randomUUID().toString());
simulatedEmail.setEmailTitle(String.format("Verification link for recommendation letter [%s]", letterId));
simulatedEmail.setEmailBody(buildLink(letterId, tokenId, secretToken));
simulatedEmail.setReceiverAddress(receiverAddress);
simulatedEmail.setEmailTitle(String.format("Verification link for recommendation letter [%s]",
verificationLinkEmailRequest.getLetterId()));
simulatedEmail.setEmailBody(Utils.buildLetterVerificationLink(verificationLinkEmailRequest));
simulatedEmail.setReceiverAddress(verificationLinkEmailRequest.getReceiverEmail());
return simulatedEmail;
}

private static String buildLink(String letterId, String tokenId, String secretToken) {
return linkTo(methodOn(RecommendationLetterController.class)
.verify(letterId, tokenId, secretToken)).withSelfRel().toString();
}
}
32 changes: 32 additions & 0 deletions src/main/java/org/otherband/email/smtp/SMTPEmailService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.otherband.email.smtp;

import org.otherband.Utils;
import org.otherband.email.EmailService;
import org.otherband.email.VerificationLinkEmailRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

@Profile("production")
@Service
public class SMTPEmailService implements EmailService {
private final String mailUserName;
private final JavaMailSender mailSender;

public SMTPEmailService(@Value("${spring.mail.username}") String mailUserName, JavaMailSender mailSender) {
this.mailUserName = mailUserName;
this.mailSender = mailSender;
}

@Override
public void sendLetterVerificationLink(VerificationLinkEmailRequest verificationLinkEmailRequest) {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(mailUserName);
message.setTo(verificationLinkEmailRequest.getReceiverEmail());
message.setText(Utils.buildLetterVerificationLink(verificationLinkEmailRequest));
message.setSubject("Recommendation letter verification link");
mailSender.send(message);
}
}
4 changes: 4 additions & 0 deletions src/main/resources/application-mail.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=<SMTP username>
spring.mail.password=<SMTP password>
49 changes: 49 additions & 0 deletions src/test/java/org/otherband/email/smtp/SMTPEmailServiceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.otherband.email.smtp;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.otherband.email.VerificationLinkEmailRequest;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

class SMTPEmailServiceTest {
private static final String EXPECTED_ID = "LETTER_ID";
public static final String EXPECTED_RECEIVER_EMAIL = "[email protected]";
public static final String TOKEN_ID = "TOKEN_ID";
public static final String SECRET = "SECRET";
private SMTPEmailService service;
private final static String SENDER_EMAIL = "[email protected]";
private JavaMailSender mailSender;

@BeforeEach
void setup() {
mailSender = mock(JavaMailSender.class);
service = new SMTPEmailService(SENDER_EMAIL, mailSender);
}

@Test
void testSendVerificationEmail() {
VerificationLinkEmailRequest verificationLinkEmailRequest = buildRequest();
service.sendLetterVerificationLink(verificationLinkEmailRequest);
ArgumentCaptor<SimpleMailMessage> argumentCaptor = ArgumentCaptor.forClass(SimpleMailMessage.class);
verify(mailSender).send(argumentCaptor.capture());
SimpleMailMessage sentMessage = argumentCaptor.getValue();
assertArrayEquals(new String[]{EXPECTED_RECEIVER_EMAIL}, sentMessage.getTo());
assertEquals("Recommendation letter verification link", sentMessage.getSubject());
assertTrue(sentMessage.getText().contains("/api/v1/recommendation-letter/verify/LETTER_ID/TOKEN_ID/SECRET"));
}

private static VerificationLinkEmailRequest buildRequest() {
VerificationLinkEmailRequest request = new VerificationLinkEmailRequest();
request.setLetterId(EXPECTED_ID);
request.setTokenId(TOKEN_ID);
request.setSecretToken(SECRET);
request.setReceiverEmail(EXPECTED_RECEIVER_EMAIL);
return request;
}
}

0 comments on commit bae777b

Please sign in to comment.