From 652033b96339b5f534b5a66cadc32bc4508ce787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A1=B0=EC=9E=AC=EC=A4=91?= <126754298+m-a-king@users.noreply.github.com> Date: Mon, 9 Dec 2024 12:12:04 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat(VolunteerApplyStatusChangeEvent):=20?= =?UTF-8?q?=EA=B1=B0=EC=A0=88=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 이전 상태와 현 상태 비교 검증. - 중복 코드 최소화. --- .../VolunteerApplyStatusChangeEvent.java | 16 ++++++++++++++ .../service/ApproveVolunteerApplyService.java | 22 +++++++------------ .../service/RejectVolunteerApplyService.java | 21 ++++++++++++++++-- 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/somemore/volunteerapply/event/VolunteerApplyStatusChangeEvent.java b/src/main/java/com/somemore/volunteerapply/event/VolunteerApplyStatusChangeEvent.java index bbfc62569..6d5d2995e 100644 --- a/src/main/java/com/somemore/volunteerapply/event/VolunteerApplyStatusChangeEvent.java +++ b/src/main/java/com/somemore/volunteerapply/event/VolunteerApplyStatusChangeEvent.java @@ -5,7 +5,9 @@ import com.somemore.global.common.event.ServerEvent; import com.somemore.global.common.event.ServerEventType; import com.somemore.notification.domain.NotificationSubType; +import com.somemore.recruitboard.domain.RecruitBoard; import com.somemore.volunteerapply.domain.ApplyStatus; +import com.somemore.volunteerapply.domain.VolunteerApply; import lombok.Getter; import lombok.experimental.SuperBuilder; @@ -40,4 +42,18 @@ public VolunteerApplyStatusChangeEvent( this.oldStatus = oldStatus; this.newStatus = newStatus; } + + public static VolunteerApplyStatusChangeEvent from(VolunteerApply apply, RecruitBoard recruitBoard, ApplyStatus oldStatus) { + + return VolunteerApplyStatusChangeEvent.builder() + .type(ServerEventType.NOTIFICATION) + .subType(NotificationSubType.VOLUNTEER_APPLY_STATUS_CHANGE) + .volunteerId(apply.getVolunteerId()) + .volunteerApplyId(apply.getId()) + .centerId(recruitBoard.getCenterId()) + .recruitBoardId(recruitBoard.getId()) + .oldStatus(oldStatus) + .newStatus(apply.getStatus()) + .build(); + } } diff --git a/src/main/java/com/somemore/volunteerapply/service/ApproveVolunteerApplyService.java b/src/main/java/com/somemore/volunteerapply/service/ApproveVolunteerApplyService.java index ba350d39b..f97c73572 100644 --- a/src/main/java/com/somemore/volunteerapply/service/ApproveVolunteerApplyService.java +++ b/src/main/java/com/somemore/volunteerapply/service/ApproveVolunteerApplyService.java @@ -1,9 +1,7 @@ package com.somemore.volunteerapply.service; import com.somemore.global.common.event.ServerEventPublisher; -import com.somemore.global.common.event.ServerEventType; import com.somemore.global.exception.BadRequestException; -import com.somemore.notification.domain.NotificationSubType; import com.somemore.recruitboard.domain.RecruitBoard; import com.somemore.recruitboard.usecase.query.RecruitBoardQueryUseCase; import com.somemore.volunteerapply.domain.ApplyStatus; @@ -65,18 +63,14 @@ private void validateBoardStatus(RecruitBoard recruitBoard) { } } - private void publishVolunteerApplyStatusChangeEvent(VolunteerApply apply, RecruitBoard recruitBoard, ApplyStatus oldStatus) { - VolunteerApplyStatusChangeEvent event = VolunteerApplyStatusChangeEvent.builder() - .type(ServerEventType.NOTIFICATION) - .subType(NotificationSubType.VOLUNTEER_APPLY_STATUS_CHANGE) - .volunteerId(apply.getVolunteerId()) - .volunteerApplyId(apply.getId()) - .centerId(recruitBoard.getCenterId()) - .recruitBoardId(recruitBoard.getId()) - .oldStatus(oldStatus) - .newStatus(apply.getStatus()) - .build(); + private void publishVolunteerApplyStatusChangeEvent(VolunteerApply apply, + RecruitBoard recruitBoard, + ApplyStatus oldStatus) { - serverEventPublisher.publish(event); + if (apply.getStatus() == oldStatus) { + return; + } + + serverEventPublisher.publish(VolunteerApplyStatusChangeEvent.from(apply, recruitBoard, oldStatus)); } } diff --git a/src/main/java/com/somemore/volunteerapply/service/RejectVolunteerApplyService.java b/src/main/java/com/somemore/volunteerapply/service/RejectVolunteerApplyService.java index d8a0da337..b48ce5de3 100644 --- a/src/main/java/com/somemore/volunteerapply/service/RejectVolunteerApplyService.java +++ b/src/main/java/com/somemore/volunteerapply/service/RejectVolunteerApplyService.java @@ -5,10 +5,13 @@ import static com.somemore.global.exception.ExceptionMessage.UNAUTHORIZED_RECRUIT_BOARD; import static com.somemore.volunteerapply.domain.ApplyStatus.REJECTED; +import com.somemore.global.common.event.ServerEventPublisher; import com.somemore.global.exception.BadRequestException; import com.somemore.recruitboard.domain.RecruitBoard; import com.somemore.recruitboard.usecase.query.RecruitBoardQueryUseCase; +import com.somemore.volunteerapply.domain.ApplyStatus; import com.somemore.volunteerapply.domain.VolunteerApply; +import com.somemore.volunteerapply.event.VolunteerApplyStatusChangeEvent; import com.somemore.volunteerapply.repository.VolunteerApplyRepository; import com.somemore.volunteerapply.usecase.RejectVolunteerApplyUseCase; import java.util.UUID; @@ -23,20 +26,24 @@ public class RejectVolunteerApplyService implements RejectVolunteerApplyUseCase private final VolunteerApplyRepository volunteerApplyRepository; private final RecruitBoardQueryUseCase recruitBoardQueryUseCase; + private final ServerEventPublisher serverEventPublisher; @Override public void reject(Long id, UUID centerId) { - VolunteerApply apply = getApply(id); + VolunteerApply apply = getVolunteerApply(id); RecruitBoard recruitBoard = recruitBoardQueryUseCase.getById(apply.getRecruitBoardId()); validateWriter(recruitBoard, centerId); validateBoardStatus(recruitBoard); + ApplyStatus oldStatus = apply.getStatus(); apply.changeStatus(REJECTED); volunteerApplyRepository.save(apply); + + publishVolunteerApplyStatusChangeEvent(apply, recruitBoard, oldStatus); } - private VolunteerApply getApply(Long id) { + private VolunteerApply getVolunteerApply(Long id) { return volunteerApplyRepository.findById(id).orElseThrow( () -> new BadRequestException(NOT_EXISTS_VOLUNTEER_APPLY) ); @@ -55,4 +62,14 @@ private void validateBoardStatus(RecruitBoard recruitBoard) { } } + private void publishVolunteerApplyStatusChangeEvent(VolunteerApply apply, + RecruitBoard recruitBoard, + ApplyStatus oldStatus) { + + if (apply.getStatus() == oldStatus) { + return; + } + + serverEventPublisher.publish(VolunteerApplyStatusChangeEvent.from(apply, recruitBoard, oldStatus)); + } } From 0854249e851191af39500dcbb4727eb421cfad96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A1=B0=EC=9E=AC=EC=A4=91?= <126754298+m-a-king@users.noreply.github.com> Date: Mon, 9 Dec 2024 12:43:42 +0900 Subject: [PATCH 2/3] =?UTF-8?q?test(VolunteerStatusChangeEvent):=20?= =?UTF-8?q?=EB=B4=89=EC=82=AC=EC=83=81=ED=83=9C=EB=B3=80=EA=B2=BD=EC=9D=B4?= =?UTF-8?q?=EB=B2=A4=ED=8A=B8=20=EB=B0=9C=EC=83=9D=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 이전 상태와 현 상태가 동일하다면 이벤트가 발생하지 않음. --- .../ApproveVolunteerApplyServiceTest.java | 95 ++++++++++++++++--- .../RejectVolunteerApplyServiceTest.java | 95 ++++++++++++++++--- 2 files changed, 167 insertions(+), 23 deletions(-) diff --git a/src/test/java/com/somemore/volunteerapply/service/ApproveVolunteerApplyServiceTest.java b/src/test/java/com/somemore/volunteerapply/service/ApproveVolunteerApplyServiceTest.java index 8835c5e87..28d614f48 100644 --- a/src/test/java/com/somemore/volunteerapply/service/ApproveVolunteerApplyServiceTest.java +++ b/src/test/java/com/somemore/volunteerapply/service/ApproveVolunteerApplyServiceTest.java @@ -1,31 +1,41 @@ package com.somemore.volunteerapply.service; -import static com.somemore.common.fixture.RecruitBoardFixture.createCompletedRecruitBoard; -import static com.somemore.common.fixture.RecruitBoardFixture.createRecruitBoard; -import static com.somemore.global.exception.ExceptionMessage.UNAUTHORIZED_RECRUIT_BOARD; -import static com.somemore.recruitboard.domain.VolunteerCategory.OTHER; -import static com.somemore.volunteerapply.domain.ApplyStatus.APPROVED; -import static com.somemore.volunteerapply.domain.ApplyStatus.WAITING; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - import com.somemore.IntegrationTestSupport; +import com.somemore.global.common.event.ServerEventPublisher; import com.somemore.global.exception.BadRequestException; import com.somemore.global.exception.ExceptionMessage; import com.somemore.recruitboard.domain.RecruitBoard; import com.somemore.recruitboard.repository.RecruitBoardRepository; +import com.somemore.recruitboard.usecase.query.RecruitBoardQueryUseCase; import com.somemore.volunteerapply.domain.VolunteerApply; +import com.somemore.volunteerapply.event.VolunteerApplyStatusChangeEvent; import com.somemore.volunteerapply.repository.VolunteerApplyRepository; -import java.util.UUID; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; +import java.util.UUID; + +import static com.somemore.common.fixture.RecruitBoardFixture.createCompletedRecruitBoard; +import static com.somemore.common.fixture.RecruitBoardFixture.createRecruitBoard; +import static com.somemore.global.exception.ExceptionMessage.UNAUTHORIZED_RECRUIT_BOARD; +import static com.somemore.recruitboard.domain.VolunteerCategory.OTHER; +import static com.somemore.volunteerapply.domain.ApplyStatus.APPROVED; +import static com.somemore.volunteerapply.domain.ApplyStatus.WAITING; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + @Transactional class ApproveVolunteerApplyServiceTest extends IntegrationTestSupport { - @Autowired private ApproveVolunteerApplyService approveVolunteerApplyService; @Autowired @@ -34,6 +44,22 @@ class ApproveVolunteerApplyServiceTest extends IntegrationTestSupport { @Autowired private RecruitBoardRepository recruitBoardRepository; + @Autowired + private RecruitBoardQueryUseCase recruitBoardQueryUseCase; + + + ServerEventPublisher serverEventPublisher; + + @BeforeEach + void setUp() { + serverEventPublisher = mock(ServerEventPublisher.class); + approveVolunteerApplyService = new ApproveVolunteerApplyService( + volunteerApplyRepository, + recruitBoardQueryUseCase, + serverEventPublisher + ); + } + @DisplayName("봉사 지원을 승인할 수 있다.") @Test void approve() { @@ -96,6 +122,52 @@ void approveWithAlreadyCompletedRecruit() { .hasMessage(ExceptionMessage.RECRUIT_BOARD_ALREADY_COMPLETED.getMessage()); } + @DisplayName("지원 상태가 변경되지 않은 경우 이벤트 퍼블리셔가 호출되지 않는다.") + @Test + void approveWithSameStatusDoesNotPublishEvent() { + // given + UUID centerId = UUID.randomUUID(); + + RecruitBoard board = createRecruitBoard(centerId); + recruitBoardRepository.save(board); + + VolunteerApply apply = createApply(board.getId()); + apply.changeStatus(APPROVED); + volunteerApplyRepository.save(apply); + + // when + approveVolunteerApplyService.approve(apply.getId(), centerId); + + // then + verify(serverEventPublisher, never()).publish(any()); + VolunteerApply approvedApply = volunteerApplyRepository.findById(apply.getId()).orElseThrow(); + assertThat(approvedApply.getStatus()).isEqualTo(APPROVED); + } + + @DisplayName("지원 상태가 변경된 경우 이벤트 퍼블리셔가 호출된다.") + @Test + void approveWithDifferentStatusPublishesEvent() { + // given + UUID centerId = UUID.randomUUID(); + + RecruitBoard board = createRecruitBoard(centerId); + recruitBoardRepository.save(board); + + VolunteerApply apply = createApply(board.getId()); + volunteerApplyRepository.save(apply); + + // when + approveVolunteerApplyService.approve(apply.getId(), centerId); + + // then + ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(VolunteerApplyStatusChangeEvent.class); + verify(serverEventPublisher, times(1)).publish(eventCaptor.capture()); + + VolunteerApplyStatusChangeEvent capturedEvent = eventCaptor.getValue(); + assertThat(capturedEvent).isNotNull(); + assertThat(capturedEvent.getVolunteerApplyId()).isEqualTo(apply.getId()); + } + private VolunteerApply createApply(Long recruitBoardId) { return VolunteerApply.builder() .volunteerId(UUID.randomUUID()) @@ -104,5 +176,4 @@ private VolunteerApply createApply(Long recruitBoardId) { .attended(false) .build(); } - } diff --git a/src/test/java/com/somemore/volunteerapply/service/RejectVolunteerApplyServiceTest.java b/src/test/java/com/somemore/volunteerapply/service/RejectVolunteerApplyServiceTest.java index 665dc276e..51568150c 100644 --- a/src/test/java/com/somemore/volunteerapply/service/RejectVolunteerApplyServiceTest.java +++ b/src/test/java/com/somemore/volunteerapply/service/RejectVolunteerApplyServiceTest.java @@ -1,31 +1,42 @@ package com.somemore.volunteerapply.service; -import static com.somemore.common.fixture.RecruitBoardFixture.createCompletedRecruitBoard; -import static com.somemore.common.fixture.RecruitBoardFixture.createRecruitBoard; -import static com.somemore.global.exception.ExceptionMessage.UNAUTHORIZED_RECRUIT_BOARD; -import static com.somemore.recruitboard.domain.VolunteerCategory.OTHER; -import static com.somemore.volunteerapply.domain.ApplyStatus.REJECTED; -import static com.somemore.volunteerapply.domain.ApplyStatus.WAITING; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - import com.somemore.IntegrationTestSupport; +import com.somemore.global.common.event.ServerEventPublisher; import com.somemore.global.exception.BadRequestException; import com.somemore.global.exception.ExceptionMessage; import com.somemore.recruitboard.domain.RecruitBoard; import com.somemore.recruitboard.repository.RecruitBoardRepository; +import com.somemore.recruitboard.usecase.query.RecruitBoardQueryUseCase; import com.somemore.volunteerapply.domain.VolunteerApply; +import com.somemore.volunteerapply.event.VolunteerApplyStatusChangeEvent; import com.somemore.volunteerapply.repository.VolunteerApplyRepository; -import java.util.UUID; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; +import java.util.UUID; + +import static com.somemore.common.fixture.RecruitBoardFixture.createCompletedRecruitBoard; +import static com.somemore.common.fixture.RecruitBoardFixture.createRecruitBoard; +import static com.somemore.global.exception.ExceptionMessage.UNAUTHORIZED_RECRUIT_BOARD; +import static com.somemore.recruitboard.domain.VolunteerCategory.OTHER; +import static com.somemore.volunteerapply.domain.ApplyStatus.APPROVED; +import static com.somemore.volunteerapply.domain.ApplyStatus.REJECTED; +import static com.somemore.volunteerapply.domain.ApplyStatus.WAITING; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + @Transactional class RejectVolunteerApplyServiceTest extends IntegrationTestSupport { - @Autowired private RejectVolunteerApplyService rejectVolunteerApplyService; @Autowired @@ -34,6 +45,22 @@ class RejectVolunteerApplyServiceTest extends IntegrationTestSupport { @Autowired private RecruitBoardRepository recruitBoardRepository; + @Autowired + private RecruitBoardQueryUseCase recruitBoardQueryUseCase; + + + ServerEventPublisher serverEventPublisher; + + @BeforeEach + void setUp() { + serverEventPublisher = mock(ServerEventPublisher.class); + rejectVolunteerApplyService = new RejectVolunteerApplyService( + volunteerApplyRepository, + recruitBoardQueryUseCase, + serverEventPublisher + ); + } + @DisplayName("봉사 지원을 거절할 수 있다.") @Test void reject() { @@ -96,6 +123,52 @@ void rejectWithAlreadyCompletedRecruit() { .hasMessage(ExceptionMessage.RECRUIT_BOARD_ALREADY_COMPLETED.getMessage()); } + @DisplayName("지원 상태가 변경되지 않은 경우 이벤트 퍼블리셔가 호출되지 않는다.") + @Test + void approveWithSameStatusDoesNotPublishEvent() { + // given + UUID centerId = UUID.randomUUID(); + + RecruitBoard board = createRecruitBoard(centerId); + recruitBoardRepository.save(board); + + VolunteerApply apply = createApply(board.getId()); + apply.changeStatus(REJECTED); + volunteerApplyRepository.save(apply); + + // when + rejectVolunteerApplyService.reject(apply.getId(), centerId); + + // then + verify(serverEventPublisher, never()).publish(any()); + VolunteerApply approvedApply = volunteerApplyRepository.findById(apply.getId()).orElseThrow(); + assertThat(approvedApply.getStatus()).isEqualTo(REJECTED); + } + + @DisplayName("지원 상태가 변경된 경우 이벤트 퍼블리셔가 호출된다.") + @Test + void approveWithDifferentStatusPublishesEvent() { + // given + UUID centerId = UUID.randomUUID(); + + RecruitBoard board = createRecruitBoard(centerId); + recruitBoardRepository.save(board); + + VolunteerApply apply = createApply(board.getId()); + volunteerApplyRepository.save(apply); + + // when + rejectVolunteerApplyService.reject(apply.getId(), centerId); + + // then + ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(VolunteerApplyStatusChangeEvent.class); + verify(serverEventPublisher, times(1)).publish(eventCaptor.capture()); + + VolunteerApplyStatusChangeEvent capturedEvent = eventCaptor.getValue(); + assertThat(capturedEvent).isNotNull(); + assertThat(capturedEvent.getVolunteerApplyId()).isEqualTo(apply.getId()); + } + private VolunteerApply createApply(Long recruitBoardId) { return VolunteerApply.builder() .volunteerId(UUID.randomUUID()) From 0a4f3160ec8f60d01f7733ab85f1e59db54fb335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A1=B0=EC=9E=AC=EC=A4=91?= <126754298+m-a-king@users.noreply.github.com> Date: Mon, 9 Dec 2024 14:32:13 +0900 Subject: [PATCH 3/3] =?UTF-8?q?refactor(VolunteerApplyStatusChangeService)?= =?UTF-8?q?:=20=EC=A4=91=EB=B3=B5=20=EC=BD=94=EB=93=9C=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - approve와 reject usecase를 한 구현체에서 해결 --- .../service/RejectVolunteerApplyService.java | 75 ------------------- ...=> VolunteerApplyStatusChangeService.java} | 19 +++-- ...olunteerApplyStatusChangeServiceTest.java} | 2 +- ...olunteerApplyStatusChangeServiceTest.java} | 16 ++-- ...olunteerApplyStatusChangeServiceTest.java} | 17 ++--- 5 files changed, 31 insertions(+), 98 deletions(-) delete mode 100644 src/main/java/com/somemore/volunteerapply/service/RejectVolunteerApplyService.java rename src/main/java/com/somemore/volunteerapply/service/{ApproveVolunteerApplyService.java => VolunteerApplyStatusChangeService.java} (84%) rename src/test/java/com/somemore/volunteerapply/service/{ApplyVolunteerApplyServiceTest.java => ApplyVolunteerApplyStatusChangeServiceTest.java} (97%) rename src/test/java/com/somemore/volunteerapply/service/{ApproveVolunteerApplyServiceTest.java => ApproveVolunteerApplyStatusChangeServiceTest.java} (90%) rename src/test/java/com/somemore/volunteerapply/service/{RejectVolunteerApplyServiceTest.java => RejectVolunteerApplyStatusChangeServiceTest.java} (90%) diff --git a/src/main/java/com/somemore/volunteerapply/service/RejectVolunteerApplyService.java b/src/main/java/com/somemore/volunteerapply/service/RejectVolunteerApplyService.java deleted file mode 100644 index b48ce5de3..000000000 --- a/src/main/java/com/somemore/volunteerapply/service/RejectVolunteerApplyService.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.somemore.volunteerapply.service; - -import static com.somemore.global.exception.ExceptionMessage.NOT_EXISTS_VOLUNTEER_APPLY; -import static com.somemore.global.exception.ExceptionMessage.RECRUIT_BOARD_ALREADY_COMPLETED; -import static com.somemore.global.exception.ExceptionMessage.UNAUTHORIZED_RECRUIT_BOARD; -import static com.somemore.volunteerapply.domain.ApplyStatus.REJECTED; - -import com.somemore.global.common.event.ServerEventPublisher; -import com.somemore.global.exception.BadRequestException; -import com.somemore.recruitboard.domain.RecruitBoard; -import com.somemore.recruitboard.usecase.query.RecruitBoardQueryUseCase; -import com.somemore.volunteerapply.domain.ApplyStatus; -import com.somemore.volunteerapply.domain.VolunteerApply; -import com.somemore.volunteerapply.event.VolunteerApplyStatusChangeEvent; -import com.somemore.volunteerapply.repository.VolunteerApplyRepository; -import com.somemore.volunteerapply.usecase.RejectVolunteerApplyUseCase; -import java.util.UUID; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@RequiredArgsConstructor -@Transactional -@Service -public class RejectVolunteerApplyService implements RejectVolunteerApplyUseCase { - - private final VolunteerApplyRepository volunteerApplyRepository; - private final RecruitBoardQueryUseCase recruitBoardQueryUseCase; - private final ServerEventPublisher serverEventPublisher; - - @Override - public void reject(Long id, UUID centerId) { - VolunteerApply apply = getVolunteerApply(id); - RecruitBoard recruitBoard = recruitBoardQueryUseCase.getById(apply.getRecruitBoardId()); - - validateWriter(recruitBoard, centerId); - validateBoardStatus(recruitBoard); - - ApplyStatus oldStatus = apply.getStatus(); - apply.changeStatus(REJECTED); - volunteerApplyRepository.save(apply); - - publishVolunteerApplyStatusChangeEvent(apply, recruitBoard, oldStatus); - } - - private VolunteerApply getVolunteerApply(Long id) { - return volunteerApplyRepository.findById(id).orElseThrow( - () -> new BadRequestException(NOT_EXISTS_VOLUNTEER_APPLY) - ); - } - - private void validateWriter(RecruitBoard recruitBoard, UUID centerId) { - if (recruitBoard.isWriter(centerId)) { - return; - } - throw new BadRequestException(UNAUTHORIZED_RECRUIT_BOARD); - } - - private void validateBoardStatus(RecruitBoard recruitBoard) { - if (recruitBoard.isCompleted()) { - throw new BadRequestException(RECRUIT_BOARD_ALREADY_COMPLETED); - } - } - - private void publishVolunteerApplyStatusChangeEvent(VolunteerApply apply, - RecruitBoard recruitBoard, - ApplyStatus oldStatus) { - - if (apply.getStatus() == oldStatus) { - return; - } - - serverEventPublisher.publish(VolunteerApplyStatusChangeEvent.from(apply, recruitBoard, oldStatus)); - } -} diff --git a/src/main/java/com/somemore/volunteerapply/service/ApproveVolunteerApplyService.java b/src/main/java/com/somemore/volunteerapply/service/VolunteerApplyStatusChangeService.java similarity index 84% rename from src/main/java/com/somemore/volunteerapply/service/ApproveVolunteerApplyService.java rename to src/main/java/com/somemore/volunteerapply/service/VolunteerApplyStatusChangeService.java index f97c73572..0c0a2be86 100644 --- a/src/main/java/com/somemore/volunteerapply/service/ApproveVolunteerApplyService.java +++ b/src/main/java/com/somemore/volunteerapply/service/VolunteerApplyStatusChangeService.java @@ -9,6 +9,7 @@ import com.somemore.volunteerapply.event.VolunteerApplyStatusChangeEvent; import com.somemore.volunteerapply.repository.VolunteerApplyRepository; import com.somemore.volunteerapply.usecase.ApproveVolunteerApplyUseCase; +import com.somemore.volunteerapply.usecase.RejectVolunteerApplyUseCase; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -19,11 +20,12 @@ import static com.somemore.global.exception.ExceptionMessage.RECRUIT_BOARD_ALREADY_COMPLETED; import static com.somemore.global.exception.ExceptionMessage.UNAUTHORIZED_RECRUIT_BOARD; import static com.somemore.volunteerapply.domain.ApplyStatus.APPROVED; +import static com.somemore.volunteerapply.domain.ApplyStatus.REJECTED; @RequiredArgsConstructor @Transactional @Service -public class ApproveVolunteerApplyService implements ApproveVolunteerApplyUseCase { +public class VolunteerApplyStatusChangeService implements ApproveVolunteerApplyUseCase, RejectVolunteerApplyUseCase { private final VolunteerApplyRepository volunteerApplyRepository; private final RecruitBoardQueryUseCase recruitBoardQueryUseCase; @@ -31,6 +33,15 @@ public class ApproveVolunteerApplyService implements ApproveVolunteerApplyUseCas @Override public void approve(Long id, UUID centerId) { + changeApplyStatus(id, centerId, APPROVED); + } + + @Override + public void reject(Long id, UUID centerId) { + changeApplyStatus(id, centerId, REJECTED); + } + + private void changeApplyStatus(Long id, UUID centerId, ApplyStatus newStatus) { VolunteerApply apply = getVolunteerApply(id); RecruitBoard recruitBoard = recruitBoardQueryUseCase.getById(apply.getRecruitBoardId()); @@ -38,7 +49,7 @@ public void approve(Long id, UUID centerId) { validateBoardStatus(recruitBoard); ApplyStatus oldStatus = apply.getStatus(); - apply.changeStatus(APPROVED); + apply.changeStatus(newStatus); volunteerApplyRepository.save(apply); publishVolunteerApplyStatusChangeEvent(apply, recruitBoard, oldStatus); @@ -66,11 +77,9 @@ private void validateBoardStatus(RecruitBoard recruitBoard) { private void publishVolunteerApplyStatusChangeEvent(VolunteerApply apply, RecruitBoard recruitBoard, ApplyStatus oldStatus) { - if (apply.getStatus() == oldStatus) { return; } - serverEventPublisher.publish(VolunteerApplyStatusChangeEvent.from(apply, recruitBoard, oldStatus)); } -} +} \ No newline at end of file diff --git a/src/test/java/com/somemore/volunteerapply/service/ApplyVolunteerApplyServiceTest.java b/src/test/java/com/somemore/volunteerapply/service/ApplyVolunteerApplyStatusChangeServiceTest.java similarity index 97% rename from src/test/java/com/somemore/volunteerapply/service/ApplyVolunteerApplyServiceTest.java rename to src/test/java/com/somemore/volunteerapply/service/ApplyVolunteerApplyStatusChangeServiceTest.java index 1b7099008..6a082e10a 100644 --- a/src/test/java/com/somemore/volunteerapply/service/ApplyVolunteerApplyServiceTest.java +++ b/src/test/java/com/somemore/volunteerapply/service/ApplyVolunteerApplyStatusChangeServiceTest.java @@ -22,7 +22,7 @@ import org.springframework.transaction.annotation.Transactional; @Transactional -class ApplyVolunteerApplyServiceTest extends IntegrationTestSupport { +class ApplyVolunteerApplyStatusChangeServiceTest extends IntegrationTestSupport { @Autowired private ApplyVolunteerApplyService volunteerApplyCommandService; diff --git a/src/test/java/com/somemore/volunteerapply/service/ApproveVolunteerApplyServiceTest.java b/src/test/java/com/somemore/volunteerapply/service/ApproveVolunteerApplyStatusChangeServiceTest.java similarity index 90% rename from src/test/java/com/somemore/volunteerapply/service/ApproveVolunteerApplyServiceTest.java rename to src/test/java/com/somemore/volunteerapply/service/ApproveVolunteerApplyStatusChangeServiceTest.java index 28d614f48..6c5b541ff 100644 --- a/src/test/java/com/somemore/volunteerapply/service/ApproveVolunteerApplyServiceTest.java +++ b/src/test/java/com/somemore/volunteerapply/service/ApproveVolunteerApplyStatusChangeServiceTest.java @@ -34,9 +34,9 @@ import static org.mockito.Mockito.verify; @Transactional -class ApproveVolunteerApplyServiceTest extends IntegrationTestSupport { +class ApproveVolunteerApplyStatusChangeServiceTest extends IntegrationTestSupport { - private ApproveVolunteerApplyService approveVolunteerApplyService; + private VolunteerApplyStatusChangeService volunteerApplyStatusChangeService; @Autowired private VolunteerApplyRepository volunteerApplyRepository; @@ -53,7 +53,7 @@ class ApproveVolunteerApplyServiceTest extends IntegrationTestSupport { @BeforeEach void setUp() { serverEventPublisher = mock(ServerEventPublisher.class); - approveVolunteerApplyService = new ApproveVolunteerApplyService( + volunteerApplyStatusChangeService = new VolunteerApplyStatusChangeService( volunteerApplyRepository, recruitBoardQueryUseCase, serverEventPublisher @@ -73,7 +73,7 @@ void approve() { volunteerApplyRepository.save(apply); // when - approveVolunteerApplyService.approve(apply.getId(), centerId); + volunteerApplyStatusChangeService.approve(apply.getId(), centerId); // then VolunteerApply approve = volunteerApplyRepository.findById(apply.getId()).orElseThrow(); @@ -97,7 +97,7 @@ void approveWithWrongCenter() { // when // then assertThatThrownBy( - () -> approveVolunteerApplyService.approve(id, wrongCenterId) + () -> volunteerApplyStatusChangeService.approve(id, wrongCenterId) ).isInstanceOf(BadRequestException.class) .hasMessage(UNAUTHORIZED_RECRUIT_BOARD.getMessage()); } @@ -117,7 +117,7 @@ void approveWithAlreadyCompletedRecruit() { // when // then assertThatThrownBy( - () -> approveVolunteerApplyService.approve(id, centerId) + () -> volunteerApplyStatusChangeService.approve(id, centerId) ).isInstanceOf(BadRequestException.class) .hasMessage(ExceptionMessage.RECRUIT_BOARD_ALREADY_COMPLETED.getMessage()); } @@ -136,7 +136,7 @@ void approveWithSameStatusDoesNotPublishEvent() { volunteerApplyRepository.save(apply); // when - approveVolunteerApplyService.approve(apply.getId(), centerId); + volunteerApplyStatusChangeService.approve(apply.getId(), centerId); // then verify(serverEventPublisher, never()).publish(any()); @@ -157,7 +157,7 @@ void approveWithDifferentStatusPublishesEvent() { volunteerApplyRepository.save(apply); // when - approveVolunteerApplyService.approve(apply.getId(), centerId); + volunteerApplyStatusChangeService.approve(apply.getId(), centerId); // then ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(VolunteerApplyStatusChangeEvent.class); diff --git a/src/test/java/com/somemore/volunteerapply/service/RejectVolunteerApplyServiceTest.java b/src/test/java/com/somemore/volunteerapply/service/RejectVolunteerApplyStatusChangeServiceTest.java similarity index 90% rename from src/test/java/com/somemore/volunteerapply/service/RejectVolunteerApplyServiceTest.java rename to src/test/java/com/somemore/volunteerapply/service/RejectVolunteerApplyStatusChangeServiceTest.java index 51568150c..c929a0acf 100644 --- a/src/test/java/com/somemore/volunteerapply/service/RejectVolunteerApplyServiceTest.java +++ b/src/test/java/com/somemore/volunteerapply/service/RejectVolunteerApplyStatusChangeServiceTest.java @@ -23,7 +23,6 @@ import static com.somemore.common.fixture.RecruitBoardFixture.createRecruitBoard; import static com.somemore.global.exception.ExceptionMessage.UNAUTHORIZED_RECRUIT_BOARD; import static com.somemore.recruitboard.domain.VolunteerCategory.OTHER; -import static com.somemore.volunteerapply.domain.ApplyStatus.APPROVED; import static com.somemore.volunteerapply.domain.ApplyStatus.REJECTED; import static com.somemore.volunteerapply.domain.ApplyStatus.WAITING; import static org.assertj.core.api.Assertions.assertThat; @@ -35,9 +34,9 @@ import static org.mockito.Mockito.verify; @Transactional -class RejectVolunteerApplyServiceTest extends IntegrationTestSupport { +class RejectVolunteerApplyStatusChangeServiceTest extends IntegrationTestSupport { - private RejectVolunteerApplyService rejectVolunteerApplyService; + private VolunteerApplyStatusChangeService volunteerApplyStatusChangeService; @Autowired private VolunteerApplyRepository volunteerApplyRepository; @@ -54,7 +53,7 @@ class RejectVolunteerApplyServiceTest extends IntegrationTestSupport { @BeforeEach void setUp() { serverEventPublisher = mock(ServerEventPublisher.class); - rejectVolunteerApplyService = new RejectVolunteerApplyService( + volunteerApplyStatusChangeService = new VolunteerApplyStatusChangeService( volunteerApplyRepository, recruitBoardQueryUseCase, serverEventPublisher @@ -74,7 +73,7 @@ void reject() { volunteerApplyRepository.save(apply); // when - rejectVolunteerApplyService.reject(apply.getId(), centerId); + volunteerApplyStatusChangeService.reject(apply.getId(), centerId); // then VolunteerApply approve = volunteerApplyRepository.findById(apply.getId()).orElseThrow(); @@ -98,7 +97,7 @@ void rejectWithWrongCenter() { // when // then assertThatThrownBy( - () -> rejectVolunteerApplyService.reject(id, wrongCenterId) + () -> volunteerApplyStatusChangeService.reject(id, wrongCenterId) ).isInstanceOf(BadRequestException.class) .hasMessage(UNAUTHORIZED_RECRUIT_BOARD.getMessage()); } @@ -118,7 +117,7 @@ void rejectWithAlreadyCompletedRecruit() { // when // then assertThatThrownBy( - () -> rejectVolunteerApplyService.reject(id, centerId) + () -> volunteerApplyStatusChangeService.reject(id, centerId) ).isInstanceOf(BadRequestException.class) .hasMessage(ExceptionMessage.RECRUIT_BOARD_ALREADY_COMPLETED.getMessage()); } @@ -137,7 +136,7 @@ void approveWithSameStatusDoesNotPublishEvent() { volunteerApplyRepository.save(apply); // when - rejectVolunteerApplyService.reject(apply.getId(), centerId); + volunteerApplyStatusChangeService.reject(apply.getId(), centerId); // then verify(serverEventPublisher, never()).publish(any()); @@ -158,7 +157,7 @@ void approveWithDifferentStatusPublishesEvent() { volunteerApplyRepository.save(apply); // when - rejectVolunteerApplyService.reject(apply.getId(), centerId); + volunteerApplyStatusChangeService.reject(apply.getId(), centerId); // then ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(VolunteerApplyStatusChangeEvent.class);