Skip to content

Commit

Permalink
Merge pull request #80 from Bamdoliro/feat/#75
Browse files Browse the repository at this point in the history
Feat/#75
jyj1289 authored May 28, 2024
2 parents c10ec57 + fddf9a3 commit d8b3e46
Showing 11 changed files with 414 additions and 17 deletions.
2 changes: 2 additions & 0 deletions src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
@@ -25,4 +25,6 @@ include::form.adoc[]

include::fair.adoc[]

include::message.adoc[]

include::enum.adoc[]
24 changes: 24 additions & 0 deletions src/docs/asciidoc/message.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
== 그룹별 메세지 보내기

=== 메시지 보내기
메세지를 보낼 원서의 상태를 입력해 메시지를 보낼 수 있습니다.

==== 요청 형식

===== Request Header
include::{snippets}/message-controller-test/원서가_접수된_학생들에게_메시지를_보낸다/request-headers.adoc[]

===== Request Body
include::{snippets}/message-controller-test/원서가_접수된_학생들에게_메시지를_보낸다/request-fields.adoc[]

==== 요청
===== 접수된 원서를 가진 사용자에게 메시지 보내기
include::{snippets}/message-controller-test/원서가_접수된_학생들에게_메시지를_보낸다/http-request.adoc[]

==== 응답

===== 정상 응답
include::{snippets}/message-controller-test/원서가_접수된_학생들에게_메시지를_보낸다/http-response.adoc[]

===== 입력한 상태의 원서가 없거나 상태를 잘못 입력한 경우
include::{snippets}/message-controller-test/해당제출상태인_원서가_없으면_오류가난다/http-response.adoc[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.bamdoliro.maru.application.message;

import com.bamdoliro.maru.domain.form.domain.Form;
import com.bamdoliro.maru.infrastructure.message.SendMessageService;
import com.bamdoliro.maru.infrastructure.persistence.form.FormRepository;
import com.bamdoliro.maru.presentation.message.dto.request.SendMessageRequest;
import com.bamdoliro.maru.shared.annotation.UseCase;
import lombok.RequiredArgsConstructor;

import java.util.List;

@RequiredArgsConstructor
@UseCase
public class SendMessageUseCase {

private final FormRepository formRepository;
private final SendMessageService sendMessageService;

public void execute(SendMessageRequest request) {
List<Form> formList = formRepository.findByStatus(request.getStatus());
List<String> phoneNumberList = formList.stream()
.map(form -> form.getUser().getPhoneNumber())
.toList();
sendMessageService.execute(phoneNumberList, request.getText(), request.getTitle());
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.bamdoliro.maru.infrastructure.message;

import com.bamdoliro.maru.infrastructure.message.exception.FailedToSendException;
import com.bamdoliro.maru.infrastructure.persistence.form.FormRepository;
import com.bamdoliro.maru.shared.config.properties.MessageProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -9,13 +10,16 @@
import net.nurigo.sdk.message.service.DefaultMessageService;
import org.springframework.stereotype.Service;

import java.util.List;

@Slf4j
@RequiredArgsConstructor
@Service
public class SendMessageService {

private final MessageProperties messageProperties;
private final DefaultMessageService messageService;
private final FormRepository formRepository;

public void execute(String to, String text) {
Message message = createMessage(to, text);
@@ -28,6 +32,13 @@ public void execute(String to, String text, String title) {
sendOneMessage(message);
}

public void execute(List<String> phoneNumberList, String text, String title) {
List<Message> messageList = phoneNumberList.stream()
.map(phoneNumber -> createMessage(phoneNumber, text))
.peek(message -> message.setSubject(title)).toList();
sendManyMessages(messageList);
}

private Message createMessage(String to, String text) {
Message message = new Message();
message.setFrom(messageProperties.getFrom());
@@ -38,9 +49,16 @@ private Message createMessage(String to, String text) {

private void sendOneMessage(Message message) {
try {
messageService.sendOne(
new SingleMessageSendingRequest(message)
);
messageService.sendOne(new SingleMessageSendingRequest(message));
} catch (Exception e) {
log.error(e.getMessage());
throw new FailedToSendException();
}
}

private void sendManyMessages(List<Message> messageList) {
try {
messageService.send(messageList, false, false);
} catch (Exception e) {
log.error(e.getMessage());
throw new FailedToSendException();
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.bamdoliro.maru.presentation.message;

import com.bamdoliro.maru.application.message.SendMessageUseCase;
import com.bamdoliro.maru.domain.user.domain.User;
import com.bamdoliro.maru.infrastructure.message.SendMessageService;
import com.bamdoliro.maru.presentation.message.dto.request.SendMessageRequest;
import com.bamdoliro.maru.shared.auth.AuthenticationPrincipal;
import com.bamdoliro.maru.shared.auth.Authority;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

@RequiredArgsConstructor
@RequestMapping("/message")
@RestController
public class MessageController {

private final SendMessageUseCase sendMessageUseCase;

@ResponseStatus(HttpStatus.NO_CONTENT)
@PostMapping("/status")
public void sendMessageByStatus(
@AuthenticationPrincipal(authority = Authority.ADMIN) User user,
@RequestBody @Valid SendMessageRequest request
) {
sendMessageUseCase.execute(request);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.bamdoliro.maru.presentation.message.dto.request;

import com.bamdoliro.maru.domain.form.domain.type.FormStatus;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class SendMessageRequest {

@NotBlank(message = "필수값입니다.")
private String title;

@NotBlank(message = "필수값입니다.")
private String text;

@NotNull(message = "필수값입니다.")
private FormStatus status;
}
Original file line number Diff line number Diff line change
@@ -29,7 +29,9 @@ public void addCorsMappings(CorsRegistry registry) {
"http://localhost:3001",
"http://localhost:3002",
"https://maru.bamdoliro.com",
"https://admin.maru.bamdoliro.com"
"https://admin.maru.bamdoliro.com",
"https://maru-user.vercel.app",
"https://maru-admin.vercel.app"
)
.allowedMethods(
HttpMethod.GET.name(),
2 changes: 1 addition & 1 deletion src/main/resources/banner.txt
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@
_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|
"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'

Contributors - @gimhanul, @hsem4717
Contributors - @gimhanul, @hsem4717, @jyj1289, @cabbage16
SpringBoot - ${spring-boot.version}
Java - ${java.version}

Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
package com.bamdoliro.maru.application.message;

import com.bamdoliro.maru.domain.form.domain.Form;
import com.bamdoliro.maru.domain.form.domain.type.FormStatus;
import com.bamdoliro.maru.domain.form.domain.type.FormType;
import com.bamdoliro.maru.infrastructure.message.SendMessageService;
import com.bamdoliro.maru.infrastructure.message.exception.FailedToSendException;
import com.bamdoliro.maru.infrastructure.persistence.form.FormRepository;
import com.bamdoliro.maru.presentation.message.dto.request.SendMessageRequest;
import com.bamdoliro.maru.shared.fixture.FormFixture;
import org.junit.jupiter.api.Assertions;
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 java.util.List;

import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.willThrow;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
public class SendMessageUseCaseTest {

@InjectMocks
private SendMessageUseCase sendMessageUseCase;

@Mock
private SendMessageService sendMessageService;

@Mock
private FormRepository formRepository;

@Test
void 원서를_최종제출한_학생들에게_메시지를_보낸다(){

//given
Form form = FormFixture.createForm(FormType.REGULAR);
form.submit("https://maru.bamdoliro.com/pdf/1");
given(formRepository.findByStatus(FormStatus.FINAL_SUBMITTED)).willReturn(List.of(form));
SendMessageRequest request = new SendMessageRequest("부산소마고 공지사항", "테스트입니다", FormStatus.FINAL_SUBMITTED);

//when
sendMessageUseCase.execute(request);

//then
verify(formRepository, times(1)).findByStatus(FormStatus.FINAL_SUBMITTED);
verify(sendMessageService, times(1)).execute(List.of(form.getUser().getPhoneNumber()), request.getText(), request.getTitle());
}

@Test
void 원서를_승인받은_학생들에게_메시지를_보낸다(){

//given
Form form = FormFixture.createForm(FormType.REGULAR);
form.approve();
given(formRepository.findByStatus(FormStatus.APPROVED)).willReturn(List.of(form));
SendMessageRequest request = new SendMessageRequest("부산소마고 공지사항", "테스트입니다", FormStatus.APPROVED);

//when
sendMessageUseCase.execute(request);

//then
verify(formRepository, times(1)).findByStatus(FormStatus.APPROVED);
verify(sendMessageService, times(1)).execute(List.of(form.getUser().getPhoneNumber()), request.getText(), request.getTitle());
}

@Test
void 원서를_반려받은_학생들에게_메시지를_보낸다(){

//given
Form form = FormFixture.createForm(FormType.REGULAR);
form.reject();
given(formRepository.findByStatus(FormStatus.REJECTED)).willReturn(List.of(form));
SendMessageRequest request = new SendMessageRequest("부산소마고 공지사항", "학생들의 원서가 조건을 충족하지 못해 반려되었습니다.", FormStatus.REJECTED);

//when
sendMessageUseCase.execute(request);

//then
verify(formRepository, times(1)).findByStatus(FormStatus.REJECTED);
verify(sendMessageService, times(1)).execute(List.of(form.getUser().getPhoneNumber()), request.getText(), request.getTitle());
}

@Test
void 원서를_접수한_학생들에게_메시지를_보낸다(){

//given
Form form = FormFixture.createForm(FormType.REGULAR);
form.receive();
given(formRepository.findByStatus(FormStatus.RECEIVED)).willReturn(List.of(form));
SendMessageRequest request = new SendMessageRequest("부산소마고 공지사항", "제출하신 원서가 접수되었습니다.", FormStatus.RECEIVED);

//when
sendMessageUseCase.execute(request);

//then
verify(formRepository, times(1)).findByStatus(FormStatus.RECEIVED);
verify(sendMessageService, times(1)).execute(List.of(form.getUser().getPhoneNumber()), request.getText(), request.getTitle());
}

@Test
void 제1차_합격자들에게_메시지를_보낸다(){

//given
Form form = FormFixture.createForm(FormType.REGULAR);
form.firstPass();
given(formRepository.findByStatus(FormStatus.FIRST_PASSED)).willReturn(List.of(form));
SendMessageRequest request = new SendMessageRequest("부산소마고 공지사항", "1차 전형에 합격하신것을 축하드립니다. 면접 장소를 확인하시고 꼭 제시간에 방문하시길 바라겠습니다,", FormStatus.FIRST_PASSED);

//when
sendMessageUseCase.execute(request);

//then
verify(formRepository, times(1)).findByStatus(FormStatus.FIRST_PASSED);
verify(sendMessageService, times(1)).execute(List.of(form.getUser().getPhoneNumber()), request.getText(), request.getTitle());
}

@Test
void 제1차_불합격자들에게_메시지를_보낸다(){

//given
Form form = FormFixture.createForm(FormType.REGULAR);
form.firstFail();
given(formRepository.findByStatus(FormStatus.FIRST_FAILED)).willReturn(List.of(form));
SendMessageRequest request = new SendMessageRequest("부산소마고 공지사항", "1차 전형에 불합격하신것에 대해 유감입니당~", FormStatus.FIRST_FAILED);

//when
sendMessageUseCase.execute(request);

//then
verify(formRepository, times(1)).findByStatus(FormStatus.FIRST_FAILED);
verify(sendMessageService, times(1)).execute(List.of(form.getUser().getPhoneNumber()), request.getText(), request.getTitle());
}

@Test
void 제2차전형에_불참한_학생들에게_메시지를_보낸다(){

//given
Form form = FormFixture.createForm(FormType.REGULAR);
form.noShow();
given(formRepository.findByStatus(FormStatus.NO_SHOW)).willReturn(List.of(form));
SendMessageRequest request = new SendMessageRequest("부산소마고 공지사항", "해당 지원자들은 2차전형에 '불참'하였으므로 패널티가 있을 예정입니다.", FormStatus.NO_SHOW);

//when
sendMessageUseCase.execute(request);

//then
verify(formRepository, times(1)).findByStatus(FormStatus.NO_SHOW);
verify(sendMessageService, times(1)).execute(List.of(form.getUser().getPhoneNumber()), request.getText(), request.getTitle());
}

@Test
void 최종합격자들에게_메시지를_보낸다(){

//given
Form form = FormFixture.createForm(FormType.REGULAR);
form.pass();
given(formRepository.findByStatus(FormStatus.PASSED)).willReturn(List.of(form));
SendMessageRequest request = new SendMessageRequest("부산소마고 공지사항", "합격하였습니다. 축하드립니다.", FormStatus.PASSED);

//when
sendMessageUseCase.execute(request);

//then
verify(formRepository, times(1)).findByStatus(FormStatus.PASSED);
verify(sendMessageService, times(1)).execute(List.of(form.getUser().getPhoneNumber()), request.getText(), request.getTitle());
}

@Test
void 최종불합격자들에게_메시지를_보낸다(){

//given
Form form = FormFixture.createForm(FormType.REGULAR);
form.fail();
given(formRepository.findByStatus(FormStatus.FAILED)).willReturn(List.of(form));
SendMessageRequest request = new SendMessageRequest("부산소마고 공지사항", "불합격", FormStatus.FAILED);

//when
sendMessageUseCase.execute(request);

//then
verify(formRepository, times(1)).findByStatus(FormStatus.FAILED);
verify(sendMessageService, times(1)).execute(List.of(form.getUser().getPhoneNumber()), request.getText(), request.getTitle());
}

@Test
void 보낼메시지대상이_존재하지_않으면_오류가_발생한다(){

//given
willThrow(new FailedToSendException()).given(formRepository).findByStatus(FormStatus.SUBMITTED);
SendMessageRequest request = new SendMessageRequest("부산소마고 공지사항", "제출이 완료되었습니다.", FormStatus.SUBMITTED);

//when and then
Assertions.assertThrows(FailedToSendException.class,
() -> sendMessageUseCase.execute(request));
verify(formRepository, times(1)).findByStatus(FormStatus.SUBMITTED);
verify(sendMessageService, never()).execute(anyList(), anyString(), anyString());
}
}
Loading

0 comments on commit d8b3e46

Please sign in to comment.