Skip to content

Commit 3430708

Browse files
Merge pull request #161 from Femcoders-SleepUp/refactor/async-email
Refactor/async email
2 parents 41d40dc + 1f20360 commit 3430708

5 files changed

Lines changed: 53 additions & 19 deletions

File tree

pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,13 @@
166166
<version>3.1.0</version> <!-- or latest -->
167167
</dependency>
168168

169+
<dependency>
170+
<groupId>org.awaitility</groupId>
171+
<artifactId>awaitility</artifactId>
172+
<version>4.2.0</version>
173+
<scope>test</scope>
174+
</dependency>
175+
169176
</dependencies>
170177
<dependencyManagement>
171178
<dependencies>

src/main/java/com/SleepUp/SU/utils/email/EmailServiceHelper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,4 @@ public String setAccommodationUrl(Accommodation accommodation) {
9797
public String getDashboardUrl() {
9898
return DASHBOARD_URL;
9999
}
100-
}
100+
}

src/main/java/com/SleepUp/SU/utils/email/EmailServiceImpl.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.SleepUp.SU.utils.email;
22

3+
import com.SleepUp.SU.accommodation.entity.Accommodation;
34
import com.SleepUp.SU.reservation.entity.Reservation;
45
import com.SleepUp.SU.user.entity.User;
56
import jakarta.mail.MessagingException;
@@ -8,6 +9,7 @@
89
import lombok.extern.slf4j.Slf4j;
910
import org.springframework.mail.javamail.JavaMailSender;
1011
import org.springframework.mail.javamail.MimeMessageHelper;
12+
import org.springframework.scheduling.annotation.Async;
1113
import org.springframework.stereotype.Service;
1214
import org.thymeleaf.context.Context;
1315
import org.thymeleaf.spring6.SpringTemplateEngine;
@@ -26,6 +28,7 @@ public class EmailServiceImpl implements EmailService {
2628
private final EmailServiceHelper emailHelper;
2729

2830
@Override
31+
@Async
2932
public void sendWelcomeEmail(User user) {
3033
if (!emailHelper.canSendEmails(user)) return;
3134

@@ -40,6 +43,7 @@ public void sendWelcomeEmail(User user) {
4043
}
4144

4245
@Override
46+
@Async
4347
public void sendOwnerReservedNotification(Reservation reservation) {
4448
if (!emailHelper.canSendReservationEmails(reservation)) return;
4549

@@ -58,6 +62,7 @@ public void sendOwnerReservedNotification(Reservation reservation) {
5862
}
5963

6064
@Override
65+
@Async
6166
public void sendGuestReservationConfirmationEmail(Reservation reservation, BigDecimal discountAmount) {
6267
if (!emailHelper.canSendReservationEmails(reservation)) return;
6368

@@ -73,6 +78,7 @@ public void sendGuestReservationConfirmationEmail(Reservation reservation, BigDe
7378
}
7479

7580
@Override
81+
@Async
7682
public void sendGuestReservationReminderEmail(Reservation reservation) {
7783
if (!emailHelper.canSendReservationEmails(reservation)) return;
7884

@@ -88,6 +94,7 @@ public void sendGuestReservationReminderEmail(Reservation reservation) {
8894
}
8995

9096
@Override
97+
@Async
9198
public void sendOwnerReservationReminderEmail(Reservation reservation) {
9299
if (!emailHelper.canSendReservationEmails(reservation)) return;
93100

@@ -103,6 +110,7 @@ public void sendOwnerReservationReminderEmail(Reservation reservation) {
103110
}
104111

105112
@Override
113+
@Async
106114
public void sendCancellationConfirmationEmail(Reservation reservation) {
107115
if (!emailHelper.canSendReservationEmails(reservation)) return;
108116

@@ -118,6 +126,7 @@ public void sendCancellationConfirmationEmail(Reservation reservation) {
118126
}
119127

120128
@Override
129+
@Async
121130
public void sendCancellationByOwnerNotificationEmail(Reservation reservation) {
122131
if (!emailHelper.canSendReservationEmails(reservation)) return;
123132

@@ -133,6 +142,7 @@ public void sendCancellationByOwnerNotificationEmail(Reservation reservation) {
133142
}
134143

135144
@Override
145+
@Async
136146
public void sendCancellationNotificationToOwnerEmail(Reservation reservation) {
137147
if (!emailHelper.canSendReservationEmails(reservation)) return;
138148

@@ -152,6 +162,7 @@ private void sendEmail(String toEmail, String subject, String templateName, Cont
152162
MimeMessageHelper helper = new MimeMessageHelper(message, true, UTF8_ENCODING);
153163

154164
String htmlContent = templateEngine.process(templateName, context);
165+
155166
helper.setTo(toEmail);
156167
helper.setSubject(subject);
157168
helper.setText(htmlContent, true);

src/test/java/com/SleepUp/SU/auth/AuthControllerTest.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.SleepUp.SU.user.entity.CustomUserDetails;
66
import com.SleepUp.SU.user.entity.User;
77
import com.SleepUp.SU.user.repository.UserRepository;
8+
import com.SleepUp.SU.utils.email.EmailService;
89
import com.fasterxml.jackson.databind.ObjectMapper;
910
import com.jayway.jsonpath.JsonPath;
1011
import jakarta.mail.internet.MimeMessage;
@@ -22,7 +23,8 @@
2223
import org.springframework.test.context.bean.override.mockito.MockitoBean;
2324
import org.springframework.test.web.servlet.MockMvc;
2425
import org.springframework.transaction.annotation.Transactional;
25-
26+
import org.thymeleaf.context.Context;
27+
import org.thymeleaf.spring6.SpringTemplateEngine;
2628

2729
import static org.hamcrest.Matchers.hasLength;
2830
import static org.mockito.Mockito.*;
@@ -62,6 +64,12 @@ public class AuthControllerTest {
6264
@MockitoBean
6365
private JavaMailSender mailSender;
6466

67+
@MockitoBean
68+
private SpringTemplateEngine templateEngine;
69+
70+
@MockitoBean
71+
private EmailService emailService;
72+
6573
private CustomUserDetails principal;
6674

6775
@BeforeEach
@@ -76,11 +84,11 @@ class RegisterTests {
7684

7785
@Test
7886
void register_validRequest_shouldReturnCreatedUser() throws Exception {
79-
JavaMailSenderImpl javaMailSenderImpl = new JavaMailSenderImpl();
80-
MimeMessage mimeMessage = javaMailSenderImpl.createMimeMessage();
87+
MimeMessage mimeMessage = new JavaMailSenderImpl().createMimeMessage();
8188

8289
when(mailSender.createMimeMessage()).thenReturn(mimeMessage);
83-
doNothing().when(mailSender).send(any(MimeMessage.class));
90+
doNothing().when(emailService).sendWelcomeEmail(any(User.class));
91+
when(templateEngine.process(anyString(), any(Context.class))).thenReturn("html");
8492

8593
UserRequest request = new UserRequest("newUser", "New Name", "new@email.com", "password123");
8694

@@ -92,10 +100,9 @@ void register_validRequest_shouldReturnCreatedUser() throws Exception {
92100
.andExpect(jsonPath("$.email").value("new@email.com"))
93101
.andExpect(jsonPath("$.name").value("New Name"));
94102

95-
verify(mailSender, times(1)).send(any(MimeMessage.class));
103+
verify(emailService, times(1)).sendWelcomeEmail(any(User.class));
96104
}
97105

98-
99106
@Test
100107
void register_invalidRequest_shouldReturnBadRequest() throws Exception {
101108
String invalidJson = """
@@ -196,4 +203,4 @@ void logout_withAuthentication_shouldReturnMessage() throws Exception {
196203
}
197204

198205
}
199-
}
206+
}

src/test/java/com/SleepUp/SU/utils/EmailServiceMailHogIntegrationTest.java

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,32 @@
33
import com.SleepUp.SU.accommodation.entity.Accommodation;
44
import com.SleepUp.SU.reservation.entity.Reservation;
55
import com.SleepUp.SU.user.entity.User;
6-
import com.SleepUp.SU.utils.email.EmailServiceImpl;
6+
import com.SleepUp.SU.utils.email.EmailService;
77
import jakarta.mail.MessagingException;
88
import org.junit.jupiter.api.BeforeEach;
99
import org.junit.jupiter.api.Test;
1010
import org.springframework.beans.factory.annotation.Autowired;
1111
import org.springframework.boot.test.context.SpringBootTest;
12+
import org.springframework.mail.javamail.JavaMailSender;
13+
import org.springframework.scheduling.annotation.EnableAsync;
1214
import org.springframework.test.context.ActiveProfiles;
1315

1416
import java.math.BigDecimal;
1517
import java.time.LocalDate;
18+
import java.util.concurrent.TimeUnit;
19+
20+
import static org.awaitility.Awaitility.await;
1621

1722
@SpringBootTest
1823
@ActiveProfiles("test")
24+
@EnableAsync
1925
public class EmailServiceMailHogIntegrationTest {
2026

2127
@Autowired
22-
private EmailServiceImpl emailService;
28+
private EmailService emailService;
29+
30+
@Autowired
31+
private JavaMailSender mailSender;
2332

2433
private User owner;
2534
private User guest;
@@ -53,48 +62,48 @@ void setUp() {
5362
@Test
5463
public void integration_sendWelcomeEmail_shouldNotThrowException() throws MessagingException, InterruptedException {
5564
emailService.sendWelcomeEmail(guest);
56-
Thread.sleep(1000);
65+
await().atMost(5, TimeUnit.SECONDS).pollDelay(100, TimeUnit.MILLISECONDS).until(() -> true);
5766
}
5867

5968
@Test
6069
public void integration_sendOwnerReservedNotification_shouldNotThrowException() throws MessagingException, InterruptedException {
6170
emailService.sendOwnerReservedNotification(reservation);
62-
Thread.sleep(1000);
71+
await().atMost(5, TimeUnit.SECONDS).pollDelay(100, TimeUnit.MILLISECONDS).until(() -> true);
6372
}
6473

6574
@Test
6675
public void integration_sendGuestReservationConfirmationEmail_shouldNotThrowException() throws MessagingException, InterruptedException {
6776
emailService.sendGuestReservationConfirmationEmail(reservation, new BigDecimal("100.00"));
68-
Thread.sleep(1000);
77+
await().atMost(5, TimeUnit.SECONDS).pollDelay(100, TimeUnit.MILLISECONDS).until(() -> true);
6978
}
7079

7180
@Test
7281
public void integration_sendGuestReservationReminderEmail_shouldNotThrowException() throws MessagingException, InterruptedException {
7382
emailService.sendGuestReservationReminderEmail(reservation);
74-
Thread.sleep(1000);
83+
await().atMost(5, TimeUnit.SECONDS).pollDelay(100, TimeUnit.MILLISECONDS).until(() -> true);
7584
}
7685

7786
@Test
7887
public void integration_sendOwnerReservationReminderEmail_shouldNotThrowException() throws MessagingException, InterruptedException {
7988
emailService.sendOwnerReservationReminderEmail(reservation);
80-
Thread.sleep(1000);
89+
await().atMost(5, TimeUnit.SECONDS).pollDelay(100, TimeUnit.MILLISECONDS).until(() -> true);
8190
}
8291

8392
@Test
8493
public void integration_sendCancellationConfirmationEmail_shouldNotThrowException() throws MessagingException, InterruptedException {
8594
emailService.sendCancellationConfirmationEmail(reservation);
86-
Thread.sleep(1000);
95+
await().atMost(5, TimeUnit.SECONDS).pollDelay(100, TimeUnit.MILLISECONDS).until(() -> true);
8796
}
8897

8998
@Test
9099
public void integration_sendCancellationByOwnerNotificationEmail_shouldNotThrowException() throws MessagingException, InterruptedException {
91100
emailService.sendCancellationByOwnerNotificationEmail(reservation);
92-
Thread.sleep(1000);
101+
await().atMost(5, TimeUnit.SECONDS).pollDelay(100, TimeUnit.MILLISECONDS).until(() -> true);
93102
}
94103

95104
@Test
96105
public void integration_sendCancellationNotificationToOwnerEmail_shouldNotThrowException() throws MessagingException, InterruptedException {
97106
emailService.sendCancellationNotificationToOwnerEmail(reservation);
98-
Thread.sleep(1000);
107+
await().atMost(5, TimeUnit.SECONDS).pollDelay(100, TimeUnit.MILLISECONDS).until(() -> true);
99108
}
100-
}
109+
}

0 commit comments

Comments
 (0)