diff --git a/src/main/java/com/verby/indp/domain/common/event/MailSendEvent.java b/src/main/java/com/verby/indp/domain/common/event/MailSendEvent.java deleted file mode 100644 index e3e34dd..0000000 --- a/src/main/java/com/verby/indp/domain/common/event/MailSendEvent.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.verby.indp.domain.common.event; - -import com.verby.indp.domain.notification.dto.Mail; - -public record MailSendEvent( - Mail mail -) { -} diff --git a/src/main/java/com/verby/indp/domain/contact/event/ContactMailEvent.java b/src/main/java/com/verby/indp/domain/contact/event/ContactMailEvent.java new file mode 100644 index 0000000..2712ec1 --- /dev/null +++ b/src/main/java/com/verby/indp/domain/contact/event/ContactMailEvent.java @@ -0,0 +1,9 @@ +package com.verby.indp.domain.contact.event; + +import com.verby.indp.domain.notification.dto.ContactMail; + +public record ContactMailEvent( + ContactMail request +) { + +} diff --git a/src/main/java/com/verby/indp/domain/contact/service/ContactService.java b/src/main/java/com/verby/indp/domain/contact/service/ContactService.java index f4bda99..b06aedd 100644 --- a/src/main/java/com/verby/indp/domain/contact/service/ContactService.java +++ b/src/main/java/com/verby/indp/domain/contact/service/ContactService.java @@ -1,10 +1,10 @@ package com.verby.indp.domain.contact.service; -import com.verby.indp.domain.common.event.MailSendEvent; -import com.verby.indp.domain.notification.dto.Mail; +import com.verby.indp.domain.contact.event.ContactMailEvent; import com.verby.indp.domain.contact.Contact; import com.verby.indp.domain.contact.dto.request.RegisterContactRequest; import com.verby.indp.domain.contact.repository.ContactRepository; +import com.verby.indp.domain.notification.dto.ContactMail; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationEventPublisher; @@ -27,13 +27,15 @@ public long registerContact(RegisterContactRequest request) { Contact contact = new Contact(request.userName(), request.content(), request.phoneNumber()); Contact persistContact = contactRepository.save(contact); - Mail mail = new Mail(to, "[버비] 문의가 들어왔어요!", - "문의 내용: " + request.content() + "\n" + - "문의자 성함: " + request.userName() + "\n" + - "문의자 연락처: " + request.phoneNumber() + "\n"); - applicationEventPublisher.publishEvent(new MailSendEvent(mail)); + sendMail(request); return persistContact.getContactId(); } + private void sendMail(RegisterContactRequest request) { + ContactMail contactMailRequest = ContactMail.of(to, request.content(), + request.userName(), request.phoneNumber()); + applicationEventPublisher.publishEvent(new ContactMailEvent(contactMailRequest)); + } + } diff --git a/src/main/java/com/verby/indp/domain/mail/dto/Mail.java b/src/main/java/com/verby/indp/domain/mail/dto/Mail.java new file mode 100644 index 0000000..d710cfe --- /dev/null +++ b/src/main/java/com/verby/indp/domain/mail/dto/Mail.java @@ -0,0 +1,21 @@ +package com.verby.indp.domain.mail.dto; + +import com.verby.indp.domain.notification.MailNotification; + +public record Mail( + long id, + String to, + String subject, + String text +) { + + public static Mail from(MailNotification notification) { + return new Mail( + notification.getMailNotificationId(), + notification.getReceiverEmail(), + notification.getSubject(), + notification.getText() + ); + } + +} diff --git a/src/main/java/com/verby/indp/domain/mail/service/MailService.java b/src/main/java/com/verby/indp/domain/mail/service/MailService.java new file mode 100644 index 0000000..e1e3fad --- /dev/null +++ b/src/main/java/com/verby/indp/domain/mail/service/MailService.java @@ -0,0 +1,9 @@ +package com.verby.indp.domain.mail.service; + +import com.verby.indp.domain.mail.dto.Mail; + +public interface MailService { + + void sendMail(Mail mail); + +} diff --git a/src/main/java/com/verby/indp/domain/notification/service/MailSendListener.java b/src/main/java/com/verby/indp/domain/mail/service/SendMailListener.java similarity index 61% rename from src/main/java/com/verby/indp/domain/notification/service/MailSendListener.java rename to src/main/java/com/verby/indp/domain/mail/service/SendMailListener.java index 414f9b0..b162f7f 100644 --- a/src/main/java/com/verby/indp/domain/notification/service/MailSendListener.java +++ b/src/main/java/com/verby/indp/domain/mail/service/SendMailListener.java @@ -1,21 +1,22 @@ -package com.verby.indp.domain.notification.service; +package com.verby.indp.domain.mail.service; import static org.springframework.transaction.event.TransactionPhase.AFTER_COMMIT; -import com.verby.indp.domain.common.event.MailSendEvent; +import com.verby.indp.domain.notification.event.SendMailEvent; import lombok.RequiredArgsConstructor; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.event.TransactionalEventListener; @Service @RequiredArgsConstructor -public class MailSendListener { +public class SendMailListener { private final MailService mailService; + @Async @TransactionalEventListener(phase = AFTER_COMMIT) - public void handleMailSendEvent(MailSendEvent event) { + public void handleSendMailEvent(SendMailEvent event) { mailService.sendMail(event.mail()); } - } diff --git a/src/main/java/com/verby/indp/domain/notification/Notification.java b/src/main/java/com/verby/indp/domain/notification/MailNotification.java similarity index 75% rename from src/main/java/com/verby/indp/domain/notification/Notification.java rename to src/main/java/com/verby/indp/domain/notification/MailNotification.java index ea9ca8f..0992b3f 100644 --- a/src/main/java/com/verby/indp/domain/notification/Notification.java +++ b/src/main/java/com/verby/indp/domain/notification/MailNotification.java @@ -11,15 +11,15 @@ import lombok.NoArgsConstructor; @Entity -@Table(name = "notification") +@Getter +@Table(name = "mail_notification") @NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) -public class Notification extends BaseTimeEntity { +public class MailNotification extends BaseTimeEntity { @Id - @Getter @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "notification_id") - private Long notificationId; + @Column(name = "mail_notification_id") + private Long mailNotificationId; @Column(name = "subject") private String subject; @@ -30,7 +30,7 @@ public class Notification extends BaseTimeEntity { @Column(name = "receiver_email") private String receiverEmail; - public Notification(String subject, String text, String receiverEmail) { + public MailNotification(String subject, String text, String receiverEmail) { this.subject = subject; this.text = text; this.receiverEmail = receiverEmail; diff --git a/src/main/java/com/verby/indp/domain/notification/dto/ContactMail.java b/src/main/java/com/verby/indp/domain/notification/dto/ContactMail.java new file mode 100644 index 0000000..a39c9f3 --- /dev/null +++ b/src/main/java/com/verby/indp/domain/notification/dto/ContactMail.java @@ -0,0 +1,19 @@ +package com.verby.indp.domain.notification.dto; + +public record ContactMail( + String to, + String content, + String userName, + String phoneNumber +) { + + public static ContactMail of( + String to, + String content, + String userName, + String phoneNumber + ) { + return new ContactMail(to, content, userName, phoneNumber); + } + +} diff --git a/src/main/java/com/verby/indp/domain/notification/dto/Mail.java b/src/main/java/com/verby/indp/domain/notification/dto/Mail.java deleted file mode 100644 index e2988e6..0000000 --- a/src/main/java/com/verby/indp/domain/notification/dto/Mail.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.verby.indp.domain.notification.dto; - -public record Mail( - String to, - String subject, - String text -) { - -} diff --git a/src/main/java/com/verby/indp/domain/notification/dto/RecommendationMail.java b/src/main/java/com/verby/indp/domain/notification/dto/RecommendationMail.java new file mode 100644 index 0000000..0bf1e3d --- /dev/null +++ b/src/main/java/com/verby/indp/domain/notification/dto/RecommendationMail.java @@ -0,0 +1,20 @@ +package com.verby.indp.domain.notification.dto; + +public record RecommendationMail( + String to, + String information, + String phoneNumber, + String storeName, + String storeAddress +) { + public static RecommendationMail of( + String to, + String information, + String phoneNumber, + String storeName, + String storeAddress + ) { + return new RecommendationMail(to, information, phoneNumber, storeName, storeAddress); + } + +} diff --git a/src/main/java/com/verby/indp/domain/notification/event/SendMailEvent.java b/src/main/java/com/verby/indp/domain/notification/event/SendMailEvent.java new file mode 100644 index 0000000..833c85b --- /dev/null +++ b/src/main/java/com/verby/indp/domain/notification/event/SendMailEvent.java @@ -0,0 +1,7 @@ +package com.verby.indp.domain.notification.event; + +import com.verby.indp.domain.mail.dto.Mail; + +public record SendMailEvent(Mail mail) { + +} diff --git a/src/main/java/com/verby/indp/domain/notification/repository/NotificationRepository.java b/src/main/java/com/verby/indp/domain/notification/repository/NotificationRepository.java new file mode 100644 index 0000000..0a4cad8 --- /dev/null +++ b/src/main/java/com/verby/indp/domain/notification/repository/NotificationRepository.java @@ -0,0 +1,8 @@ +package com.verby.indp.domain.notification.repository; + +import com.verby.indp.domain.notification.MailNotification; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface NotificationRepository extends JpaRepository { + +} diff --git a/src/main/java/com/verby/indp/domain/notification/service/ContactMailListener.java b/src/main/java/com/verby/indp/domain/notification/service/ContactMailListener.java new file mode 100644 index 0000000..07091d2 --- /dev/null +++ b/src/main/java/com/verby/indp/domain/notification/service/ContactMailListener.java @@ -0,0 +1,23 @@ +package com.verby.indp.domain.notification.service; + +import static org.springframework.transaction.event.TransactionPhase.AFTER_COMMIT; + +import com.verby.indp.domain.contact.event.ContactMailEvent; +import lombok.RequiredArgsConstructor; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import org.springframework.transaction.event.TransactionalEventListener; + +@Service +@RequiredArgsConstructor +public class ContactMailListener { + + private final NotificationService notificationService; + + @Async + @TransactionalEventListener(phase = AFTER_COMMIT) + public void handleContactMailEvent(ContactMailEvent event) { + notificationService.sendContactMail(event.request()); + } + +} diff --git a/src/main/java/com/verby/indp/domain/notification/service/MailService.java b/src/main/java/com/verby/indp/domain/notification/service/MailService.java deleted file mode 100644 index 22e5ce7..0000000 --- a/src/main/java/com/verby/indp/domain/notification/service/MailService.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.verby.indp.domain.notification.service; - -import com.verby.indp.domain.notification.dto.Mail; - -public interface MailService { - - void sendMail(Mail mail); - -} diff --git a/src/main/java/com/verby/indp/domain/notification/service/NotificationService.java b/src/main/java/com/verby/indp/domain/notification/service/NotificationService.java new file mode 100644 index 0000000..d9dc7a2 --- /dev/null +++ b/src/main/java/com/verby/indp/domain/notification/service/NotificationService.java @@ -0,0 +1,48 @@ +package com.verby.indp.domain.notification.service; + +import com.verby.indp.domain.notification.MailNotification; +import com.verby.indp.domain.mail.dto.Mail; +import com.verby.indp.domain.notification.dto.ContactMail; +import com.verby.indp.domain.notification.dto.RecommendationMail; +import com.verby.indp.domain.notification.event.SendMailEvent; +import com.verby.indp.domain.notification.repository.NotificationRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class NotificationService { + + private final NotificationRepository notificationRepository; + private final ApplicationEventPublisher applicationEventPublisher; + + @Transactional + public void sendContactMail(ContactMail request) { + MailNotification mailNotification = new MailNotification("[버비] 문의가 들어왔어요!", + "문의 내용: " + request.content() + "\n" + + "문의자 성함: " + request.userName() + "\n" + + "문의자 연락처: " + request.phoneNumber() + "\n", request.to()); + MailNotification persistMailNotification = notificationRepository.save(mailNotification); + sendMail(persistMailNotification); + } + + @Transactional + public void sendRecommendationMail(RecommendationMail request) { + MailNotification mailNotification = new MailNotification("[버비] 인디피 서비스에 음악이 추천되었어요!", + "추천 음악 정보: " + request.information() + "\n" + + "추천인 연락처: " + request.phoneNumber() + "\n" + + "매장 이름: " + request.storeName() + "\n" + + "매장 주소: " + request.storeAddress() + "\n", request.to()); + MailNotification persistMailNotification = notificationRepository.save(mailNotification); + sendMail(persistMailNotification); + } + + private void sendMail(MailNotification persistMailNotification) { + Mail mail = Mail.from(persistMailNotification); + applicationEventPublisher.publishEvent(new SendMailEvent(mail)); + } + +} diff --git a/src/main/java/com/verby/indp/domain/notification/service/RecommendationMailListener.java b/src/main/java/com/verby/indp/domain/notification/service/RecommendationMailListener.java new file mode 100644 index 0000000..9f3aa68 --- /dev/null +++ b/src/main/java/com/verby/indp/domain/notification/service/RecommendationMailListener.java @@ -0,0 +1,23 @@ +package com.verby.indp.domain.notification.service; + +import static org.springframework.transaction.event.TransactionPhase.AFTER_COMMIT; + +import com.verby.indp.domain.recommendation.event.RecommendationMailEvent; +import lombok.RequiredArgsConstructor; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import org.springframework.transaction.event.TransactionalEventListener; + +@Service +@RequiredArgsConstructor +public class RecommendationMailListener { + + private final NotificationService notificationService; + + @Async + @TransactionalEventListener(phase = AFTER_COMMIT) + public void handleRecommendationMailEvent(RecommendationMailEvent event) { + notificationService.sendRecommendationMail(event.request()); + } + +} diff --git a/src/main/java/com/verby/indp/domain/recommendation/event/RecommendationMailEvent.java b/src/main/java/com/verby/indp/domain/recommendation/event/RecommendationMailEvent.java new file mode 100644 index 0000000..5ac697e --- /dev/null +++ b/src/main/java/com/verby/indp/domain/recommendation/event/RecommendationMailEvent.java @@ -0,0 +1,8 @@ +package com.verby.indp.domain.recommendation.event; + +import com.verby.indp.domain.notification.dto.RecommendationMail; + +public record RecommendationMailEvent( + RecommendationMail request +) { +} diff --git a/src/main/java/com/verby/indp/domain/recommendation/service/RecommendationService.java b/src/main/java/com/verby/indp/domain/recommendation/service/RecommendationService.java index 74be5a6..18e9d4c 100644 --- a/src/main/java/com/verby/indp/domain/recommendation/service/RecommendationService.java +++ b/src/main/java/com/verby/indp/domain/recommendation/service/RecommendationService.java @@ -1,8 +1,8 @@ package com.verby.indp.domain.recommendation.service; -import com.verby.indp.domain.common.event.MailSendEvent; +import com.verby.indp.domain.recommendation.event.RecommendationMailEvent; import com.verby.indp.domain.common.exception.NotFoundException; -import com.verby.indp.domain.notification.dto.Mail; +import com.verby.indp.domain.notification.dto.RecommendationMail; import com.verby.indp.domain.recommendation.Recommendation; import com.verby.indp.domain.recommendation.dto.request.RegisterRecommendationRequest; import com.verby.indp.domain.recommendation.repository.RecommendationRepository; @@ -29,17 +29,14 @@ public class RecommendationService { @Transactional public long registerRecommendation(RegisterRecommendationRequest request) { Store store = getStore(request); + Recommendation recommendation = new Recommendation(store, request.information(), request.phoneNumber()); - Recommendation persistRecommendation = recommendationRepository.save(recommendation); - Mail mail = new Mail(to, "[버비] 인디피 서비스에 음악이 추천되었어요!", - "추천 음악 정보: " + request.information() + "\n" + - "추천인 연락처: " + request.phoneNumber() + "\n" + - "매장 이름: " + store.getName() + "\n" + - "매장 주소: " + store.getAddress() + "\n"); - applicationEventPublisher.publishEvent(new MailSendEvent(mail)); + RecommendationMail recommendationMail = RecommendationMail.of(to, + request.information(), request.phoneNumber(), store.getName(), store.getAddress()); + applicationEventPublisher.publishEvent(new RecommendationMailEvent(recommendationMail)); return persistRecommendation.getRecommendationId(); } diff --git a/src/main/java/com/verby/indp/global/config/AsyncConfig.java b/src/main/java/com/verby/indp/global/config/AsyncConfig.java index 0e0f45b..cdbe1f1 100644 --- a/src/main/java/com/verby/indp/global/config/AsyncConfig.java +++ b/src/main/java/com/verby/indp/global/config/AsyncConfig.java @@ -1,23 +1,10 @@ package com.verby.indp.global.config; -import java.util.concurrent.Executor; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @EnableAsync @Configuration public class AsyncConfig { - @Bean(name = "asyncEmailSendExecutor") - public Executor asyncEmailSendExecutor() { - ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); - executor.setCorePoolSize(2); - executor.setMaxPoolSize(10); - executor.setQueueCapacity(100); - executor.setThreadNamePrefix("Executor-"); - return executor; - } - } diff --git a/src/main/java/com/verby/indp/global/mail/SpringMailService.java b/src/main/java/com/verby/indp/global/mail/SpringMailService.java index 393ced1..d35504c 100644 --- a/src/main/java/com/verby/indp/global/mail/SpringMailService.java +++ b/src/main/java/com/verby/indp/global/mail/SpringMailService.java @@ -1,7 +1,7 @@ package com.verby.indp.global.mail; -import com.verby.indp.domain.notification.dto.Mail; -import com.verby.indp.domain.notification.service.MailService; +import com.verby.indp.domain.mail.dto.Mail; +import com.verby.indp.domain.mail.service.MailService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.mail.MailAuthenticationException; @@ -9,7 +9,6 @@ import org.springframework.mail.MailSendException; import org.springframework.mail.MailSender; import org.springframework.mail.SimpleMailMessage; -import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; @Slf4j @@ -22,7 +21,6 @@ public class SpringMailService implements MailService { private final MailSender mailSender; @Override - @Async("asyncEmailSendExecutor") public void sendMail(Mail mail) { SimpleMailMessage message = new SimpleMailMessage(); @@ -30,22 +28,21 @@ public void sendMail(Mail mail) { message.setSubject(mail.subject()); message.setText(mail.text()); - send(message); + send(mail.id(), message); } - private void send(SimpleMailMessage message) { - int count = 0; - for (; count < MAX_RETRY_COUNT; count++) { + private void send(long id, SimpleMailMessage message) { + for (int count = 0; count < MAX_RETRY_COUNT; count++) { try { mailSender.send(message); return; } catch (MailParseException | MailAuthenticationException exception) { - log.error("메일 전송을 실패하였습니다.", exception); + log.error("메일 전송을 실패하였습니다. mailNotificationId: {}", id, exception); return; } catch (MailSendException exception) { - log.warn("메일 전송을 실패하였습니다. 재시도합니다. 재시도 횟수: {}", count, exception); + log.warn("메일 전송을 실패하였습니다. 재시도합니다. mailNotificationId: {} 재시도 횟수: {}", id, count, exception); } } - log.error("메일 전송에 실패하였습니다. 재시도 횟수: {}", count); + log.error("메일 전송에 실패하였습니다. mailNotificationId: {} 재시도 횟수: {}", id, MAX_RETRY_COUNT); } } diff --git a/src/test/java/com/verby/indp/acceptance/ContactAcceptanceTest.java b/src/test/java/com/verby/indp/acceptance/ContactAcceptanceTest.java index ccd8d96..654695a 100644 --- a/src/test/java/com/verby/indp/acceptance/ContactAcceptanceTest.java +++ b/src/test/java/com/verby/indp/acceptance/ContactAcceptanceTest.java @@ -3,27 +3,17 @@ import static com.verby.indp.domain.contact.fixture.ContactFixture.contact; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - import com.verby.indp.acceptance.support.ContactSupporter; -import com.verby.indp.domain.notification.dto.Mail; -import com.verby.indp.domain.notification.service.MailService; import com.verby.indp.domain.contact.Contact; import com.verby.indp.domain.contact.dto.request.RegisterContactRequest; import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.springframework.boot.test.mock.mockito.MockBean; @DisplayName("contact 인수 테스트") class ContactAcceptanceTest extends BaseAcceptanceTest { - @MockBean - private MailService mailService; - @Test @DisplayName("문의 내용을 등록한다.") void registerContact() { @@ -38,7 +28,6 @@ void registerContact() { // then assertThat(result.statusCode()).isEqualTo(201); assertThat(result.header("Location")).isNotBlank(); - verify(mailService, times(1)).sendMail(any(Mail.class)); } } diff --git a/src/test/java/com/verby/indp/acceptance/RecommendationAcceptanceTest.java b/src/test/java/com/verby/indp/acceptance/RecommendationAcceptanceTest.java index 2e5f13e..3f7f3e5 100644 --- a/src/test/java/com/verby/indp/acceptance/RecommendationAcceptanceTest.java +++ b/src/test/java/com/verby/indp/acceptance/RecommendationAcceptanceTest.java @@ -2,13 +2,8 @@ import static com.verby.indp.domain.store.fixture.StoreFixture.store; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; import com.verby.indp.acceptance.support.RecommendationSupporter; -import com.verby.indp.domain.notification.dto.Mail; -import com.verby.indp.domain.notification.service.MailService; import com.verby.indp.domain.recommendation.dto.request.RegisterRecommendationRequest; import com.verby.indp.domain.store.Store; import com.verby.indp.domain.store.repository.StoreRepository; @@ -17,7 +12,6 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; @DisplayName("recommendation 인수 테스트") class RecommendationAcceptanceTest extends BaseAcceptanceTest { @@ -25,9 +19,6 @@ class RecommendationAcceptanceTest extends BaseAcceptanceTest { @Autowired private StoreRepository storeRepository; - @MockBean - private MailService mailService; - @Test @DisplayName("추천 음악 정보를 등록한다.") void registerRecommendation() { @@ -48,7 +39,6 @@ void registerRecommendation() { // then assertThat(result.statusCode()).isEqualTo(201); assertThat(result.header("Location")).isNotBlank(); - verify(mailService, times(1)).sendMail(any(Mail.class)); } } diff --git a/src/test/java/com/verby/indp/domain/common/notification/mail/MailServiceTest.java b/src/test/java/com/verby/indp/domain/common/notification/mail/MailServiceTest.java index d58c961..3c7a315 100644 --- a/src/test/java/com/verby/indp/domain/common/notification/mail/MailServiceTest.java +++ b/src/test/java/com/verby/indp/domain/common/notification/mail/MailServiceTest.java @@ -5,7 +5,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import com.verby.indp.domain.notification.dto.Mail; +import com.verby.indp.domain.mail.dto.Mail; import com.verby.indp.global.mail.SpringMailService; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -35,7 +35,7 @@ class SendMail { @DisplayName("성공: 메일을 전송한다.") void sendMail() { // given - Mail mail = new Mail("to", "subject", "text"); + Mail mail = new Mail(1L, "to", "subject", "text"); // when mailService.sendMail(mail); @@ -48,7 +48,7 @@ void sendMail() { @DisplayName("성공: 메일을 전송 실패시 재시도한다.") void reSendMailWhenSendFail() { // given - Mail mail = new Mail("to", "subject", "text"); + Mail mail = new Mail(1L, "to", "subject", "text"); int MAX_RETRY_COUNT = 5; doThrow(new MailSendException("메일 전송 실패")).when(mailSender).send(any(SimpleMailMessage.class)); diff --git a/src/test/java/com/verby/indp/domain/contact/service/ContactServiceTest.java b/src/test/java/com/verby/indp/domain/contact/service/ContactServiceTest.java index 02d1d8f..2e676f3 100644 --- a/src/test/java/com/verby/indp/domain/contact/service/ContactServiceTest.java +++ b/src/test/java/com/verby/indp/domain/contact/service/ContactServiceTest.java @@ -6,7 +6,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import com.verby.indp.domain.common.event.MailSendEvent; +import com.verby.indp.domain.contact.event.ContactMailEvent; import com.verby.indp.domain.contact.Contact; import com.verby.indp.domain.contact.dto.request.RegisterContactRequest; import com.verby.indp.domain.contact.repository.ContactRepository; @@ -53,7 +53,7 @@ void registerContact() { // then verify(contactRepository, times(1)).save(any(Contact.class)); - verify(applicationEventPublisher, times(1)).publishEvent(any(MailSendEvent.class)); + verify(applicationEventPublisher, times(1)).publishEvent(any(ContactMailEvent.class)); } } diff --git a/src/test/java/com/verby/indp/domain/notification/NotificationTest.java b/src/test/java/com/verby/indp/domain/notification/NotificationTest.java index 53c9a11..a204193 100644 --- a/src/test/java/com/verby/indp/domain/notification/NotificationTest.java +++ b/src/test/java/com/verby/indp/domain/notification/NotificationTest.java @@ -23,7 +23,7 @@ void newNotification() { // when Exception exception = catchException( - () -> new Notification(to, subject, text)); + () -> new MailNotification(to, subject, text)); // then assertThat(exception).isNull(); diff --git a/src/test/java/com/verby/indp/domain/notification/service/NotificationServiceTest.java b/src/test/java/com/verby/indp/domain/notification/service/NotificationServiceTest.java new file mode 100644 index 0000000..7dfa7d7 --- /dev/null +++ b/src/test/java/com/verby/indp/domain/notification/service/NotificationServiceTest.java @@ -0,0 +1,84 @@ +package com.verby.indp.domain.notification.service; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.verby.indp.domain.notification.MailNotification; +import com.verby.indp.domain.notification.dto.ContactMail; +import com.verby.indp.domain.notification.dto.RecommendationMail; +import com.verby.indp.domain.notification.event.SendMailEvent; +import com.verby.indp.domain.notification.repository.NotificationRepository; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +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.context.ApplicationEventPublisher; +import org.springframework.test.util.ReflectionTestUtils; + +@ExtendWith(MockitoExtension.class) +class NotificationServiceTest { + + @InjectMocks + private NotificationService notificationService; + + @Mock + private NotificationRepository notificationRepository; + + @Mock + private ApplicationEventPublisher applicationEventPublisher; + + @Nested + @DisplayName("sendContactMail 메소드 실행 시") + class SendContactMail { + + @Test + @DisplayName("성공: 문의 메일을 전송한다.") + void sendContactMail() { + // given + ContactMail contactMail = new ContactMail("userName", "content", "phoneNumber", "to"); + MailNotification mailNotification = new MailNotification("subject", "text", "to"); + ReflectionTestUtils.setField(mailNotification, "mailNotificationId", 1L); + + when(notificationRepository.save(any(MailNotification.class))).thenReturn(mailNotification); + + // when + notificationService.sendContactMail(contactMail); + + // then + verify(notificationRepository, times(1)).save(any(MailNotification.class)); + verify(applicationEventPublisher, times(1)).publishEvent(any(SendMailEvent.class)); + } + + } + + @Nested + @DisplayName("sendRecommendationMail 메소드 실행 시") + class SendRecommendationMail { + + @Test + @DisplayName("성공: 문의 메일을 전송한다.") + void sendContactMail() { + // given + RecommendationMail recommendationMail = new RecommendationMail("to", "information", + "01012341234", "storeName", "storeAddress"); + MailNotification mailNotification = new MailNotification("subject", "text", "to"); + ReflectionTestUtils.setField(mailNotification, "mailNotificationId", 1L); + + when(notificationRepository.save(any(MailNotification.class))).thenReturn(mailNotification); + + // when + notificationService.sendRecommendationMail(recommendationMail); + + // then + verify(notificationRepository, times(1)).save(any(MailNotification.class)); + verify(applicationEventPublisher, times(1)).publishEvent(any(SendMailEvent.class)); + } + + } + +} \ No newline at end of file diff --git a/src/test/java/com/verby/indp/domain/recommendation/service/RecommendationServiceTest.java b/src/test/java/com/verby/indp/domain/recommendation/service/RecommendationServiceTest.java index ecfe36b..cc65055 100644 --- a/src/test/java/com/verby/indp/domain/recommendation/service/RecommendationServiceTest.java +++ b/src/test/java/com/verby/indp/domain/recommendation/service/RecommendationServiceTest.java @@ -10,10 +10,10 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import com.verby.indp.domain.common.event.MailSendEvent; import com.verby.indp.domain.common.exception.NotFoundException; import com.verby.indp.domain.recommendation.Recommendation; import com.verby.indp.domain.recommendation.dto.request.RegisterRecommendationRequest; +import com.verby.indp.domain.recommendation.event.RecommendationMailEvent; import com.verby.indp.domain.recommendation.repository.RecommendationRepository; import com.verby.indp.domain.store.Store; import com.verby.indp.domain.store.repository.StoreRepository; @@ -68,7 +68,7 @@ void registerRecommendation() { // then verify(recommendationRepository, times(1)).save(any(Recommendation.class)); - verify(applicationEventPublisher, times(1)).publishEvent(any(MailSendEvent.class)); + verify(applicationEventPublisher, times(1)).publishEvent(any(RecommendationMailEvent.class)); } @Test