From edab1cc338a65c8db80ceb478bb5b74ab14b247c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=A7=84=ED=98=B8?= Date: Thu, 1 Aug 2024 13:03:59 +0900 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=EC=95=A1=EC=85=98=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 지출 삭제 가능, 인원 삭제는 아직입니다. --- .../haengdong/application/ActionService.java | 21 +++++++++++++----- .../domain/action/ActionRepository.java | 2 ++ .../domain/action/BillActionRepository.java | 4 ++++ .../exception/HaengdongErrorCode.java | 2 +- .../presentation/ActionController.java | 11 ++++++++++ .../application/ActionServiceTest.java | 22 ++++++++++++++----- .../presentation/ActionControllerTest.java | 10 +++++++++ 7 files changed, 61 insertions(+), 11 deletions(-) diff --git a/server/src/main/java/server/haengdong/application/ActionService.java b/server/src/main/java/server/haengdong/application/ActionService.java index bda638756..4aac2d38b 100644 --- a/server/src/main/java/server/haengdong/application/ActionService.java +++ b/server/src/main/java/server/haengdong/application/ActionService.java @@ -1,14 +1,12 @@ package server.haengdong.application; import java.util.List; +import java.util.Optional; + import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import server.haengdong.application.response.MemberBillReportAppResponse; -import server.haengdong.domain.action.BillAction; -import server.haengdong.domain.action.BillActionRepository; -import server.haengdong.domain.action.MemberAction; -import server.haengdong.domain.action.MemberActionRepository; -import server.haengdong.domain.action.MemberBillReport; +import server.haengdong.domain.action.*; import server.haengdong.domain.event.Event; import server.haengdong.domain.event.EventRepository; import server.haengdong.exception.HaengdongErrorCode; @@ -21,6 +19,7 @@ public class ActionService { private final BillActionRepository billActionRepository; private final MemberActionRepository memberActionRepository; private final EventRepository eventRepository; + private final ActionRepository actionRepository; public List getMemberBillReports(String token) { Event event = eventRepository.findByToken(token) @@ -34,4 +33,16 @@ public List getMemberBillReports(String token) { .map(entry -> new MemberBillReportAppResponse(entry.getKey(), entry.getValue())) .toList(); } + + public void deleteAction(String token, Long actionId) { + Event event = eventRepository.findByToken(token) + .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.NOT_FOUND_EVENT)); + Action action = actionRepository.findByIdAndEvent(actionId, event) + .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.NOT_FOUND_ACTION)); + Optional billAction = billActionRepository.findByAction(action); + if (billAction.isPresent()) { + billActionRepository.delete(billAction.get()); + return; + } + } } diff --git a/server/src/main/java/server/haengdong/domain/action/ActionRepository.java b/server/src/main/java/server/haengdong/domain/action/ActionRepository.java index c2138e42f..2fde0ffa6 100644 --- a/server/src/main/java/server/haengdong/domain/action/ActionRepository.java +++ b/server/src/main/java/server/haengdong/domain/action/ActionRepository.java @@ -18,4 +18,6 @@ public interface ActionRepository extends JpaRepository { LIMIT 1 """) Optional findLastByEvent(@Param("event") Event event); + + Optional findByIdAndEvent(Long id, Event event); } diff --git a/server/src/main/java/server/haengdong/domain/action/BillActionRepository.java b/server/src/main/java/server/haengdong/domain/action/BillActionRepository.java index 1ad7416aa..468d03061 100644 --- a/server/src/main/java/server/haengdong/domain/action/BillActionRepository.java +++ b/server/src/main/java/server/haengdong/domain/action/BillActionRepository.java @@ -1,6 +1,8 @@ package server.haengdong.domain.action; import java.util.List; +import java.util.Optional; + import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @@ -11,4 +13,6 @@ public interface BillActionRepository extends JpaRepository { @EntityGraph(attributePaths = {"action"}) List findByAction_Event(Event event); + + Optional findByAction(Action action); } diff --git a/server/src/main/java/server/haengdong/exception/HaengdongErrorCode.java b/server/src/main/java/server/haengdong/exception/HaengdongErrorCode.java index 052b97fe2..289009170 100644 --- a/server/src/main/java/server/haengdong/exception/HaengdongErrorCode.java +++ b/server/src/main/java/server/haengdong/exception/HaengdongErrorCode.java @@ -12,7 +12,7 @@ public enum HaengdongErrorCode { INVALID_MEMBER_OUT_ACTION("MA_003", "현재 참여하고 있지 않는 인원이 존재합니다."), NOT_FOUND_EVENT("EV_400", "존재하지 않는 행사입니다."), INTERNAL_SERVER_ERROR("S_001", "서버 내부에서 에러가 발생했습니다."), - ; + NOT_FOUND_ACTION("AC_400", "존재하지 않는 액션입니다."); private final String code; private final String message; diff --git a/server/src/main/java/server/haengdong/presentation/ActionController.java b/server/src/main/java/server/haengdong/presentation/ActionController.java index 657cb567e..533560280 100644 --- a/server/src/main/java/server/haengdong/presentation/ActionController.java +++ b/server/src/main/java/server/haengdong/presentation/ActionController.java @@ -3,6 +3,7 @@ import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @@ -23,4 +24,14 @@ public ResponseEntity getMemberBillReports(@PathVaria return ResponseEntity.ok() .body(MemberBillReportsResponse.of(memberBillReports)); } + + @DeleteMapping("/api/events/{eventId}/actions/{actionId}") + public ResponseEntity deleteAction( + @PathVariable("eventId") String token, + @PathVariable("actionId") Long actionId + ) { + actionService.deleteAction(token, actionId); + + return ResponseEntity.noContent().build(); + } } diff --git a/server/src/test/java/server/haengdong/application/ActionServiceTest.java b/server/src/test/java/server/haengdong/application/ActionServiceTest.java index ac2dc4f4f..0b2e21f60 100644 --- a/server/src/test/java/server/haengdong/application/ActionServiceTest.java +++ b/server/src/test/java/server/haengdong/application/ActionServiceTest.java @@ -12,11 +12,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import server.haengdong.application.response.MemberBillReportAppResponse; -import server.haengdong.domain.action.Action; -import server.haengdong.domain.action.BillAction; -import server.haengdong.domain.action.BillActionRepository; -import server.haengdong.domain.action.MemberAction; -import server.haengdong.domain.action.MemberActionRepository; +import server.haengdong.domain.action.*; import server.haengdong.domain.event.Event; import server.haengdong.domain.event.EventRepository; import server.haengdong.exception.HaengdongErrorCode; @@ -76,4 +72,20 @@ void getMemberBillReports1() { .isInstanceOf(HaengdongException.class) .hasMessage(HaengdongErrorCode.NOT_FOUND_EVENT.getMessage()); } + + @DisplayName("액션을 삭제합니다.") + @Test + void deleteAction() { + Event event = new Event("potato", "potatoHi"); + eventRepository.save(event); + + Action action = new Action(event, 1L); + MemberAction memberAction = new MemberAction(action, "웨디", MemberActionStatus.IN, 1L); + MemberAction savedMemberAction = memberActionRepository.save(memberAction); + Long memberActionId = savedMemberAction.getId(); + + actionService.deleteAction("potatoHi", memberActionId); + + assertThat(memberActionRepository.findById(memberActionId)).isEmpty(); + } } diff --git a/server/src/test/java/server/haengdong/presentation/ActionControllerTest.java b/server/src/test/java/server/haengdong/presentation/ActionControllerTest.java index 739ac4962..0ae3cc2e2 100644 --- a/server/src/test/java/server/haengdong/presentation/ActionControllerTest.java +++ b/server/src/test/java/server/haengdong/presentation/ActionControllerTest.java @@ -3,6 +3,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -46,4 +47,13 @@ void getMemberBillReports() throws Exception { .andExpect(MockMvcResultMatchers.jsonPath("$.reports[1].price").value(equalTo(200_000))); } + + @DisplayName("액션을 삭제한다.") + @Test + void deleteAction() throws Exception { + mockMvc.perform(delete("/api/events/{eventId}/actions/{actionId}", "token", "1") + .accept(MediaType.APPLICATION_JSON)) + .andDo(print()) + .andExpect(status().isNoContent()); + } } From f798c9baefaf93eea1544e3a640661b999579dab Mon Sep 17 00:00:00 2001 From: 3juhwan <13selfesteem91@naver.com> Date: Thu, 1 Aug 2024 13:48:19 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feat:=20=EB=A9=A4=EB=B2=84=20=EC=95=A1?= =?UTF-8?q?=EC=85=98=20=EC=82=AD=EC=A0=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: pakxe Co-authored-by: 3juhwan <13selfesteem91@naver.com> Co-authored-by: kunsanglee --- .../server/haengdong/application/ActionService.java | 13 +++++++++++-- .../domain/action/MemberActionRepository.java | 3 +++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/server/haengdong/application/ActionService.java b/server/src/main/java/server/haengdong/application/ActionService.java index 4aac2d38b..7fae107ba 100644 --- a/server/src/main/java/server/haengdong/application/ActionService.java +++ b/server/src/main/java/server/haengdong/application/ActionService.java @@ -2,11 +2,16 @@ import java.util.List; import java.util.Optional; - import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import server.haengdong.application.response.MemberBillReportAppResponse; -import server.haengdong.domain.action.*; +import server.haengdong.domain.action.Action; +import server.haengdong.domain.action.ActionRepository; +import server.haengdong.domain.action.BillAction; +import server.haengdong.domain.action.BillActionRepository; +import server.haengdong.domain.action.MemberAction; +import server.haengdong.domain.action.MemberActionRepository; +import server.haengdong.domain.action.MemberBillReport; import server.haengdong.domain.event.Event; import server.haengdong.domain.event.EventRepository; import server.haengdong.exception.HaengdongErrorCode; @@ -40,9 +45,13 @@ public void deleteAction(String token, Long actionId) { Action action = actionRepository.findByIdAndEvent(actionId, event) .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.NOT_FOUND_ACTION)); Optional billAction = billActionRepository.findByAction(action); + Optional memberAction = memberActionRepository.findByAction(action); + if (billAction.isPresent()) { billActionRepository.delete(billAction.get()); return; } + + memberAction.ifPresent(memberActionRepository::delete); } } diff --git a/server/src/main/java/server/haengdong/domain/action/MemberActionRepository.java b/server/src/main/java/server/haengdong/domain/action/MemberActionRepository.java index 6c4769e61..134eddf0f 100644 --- a/server/src/main/java/server/haengdong/domain/action/MemberActionRepository.java +++ b/server/src/main/java/server/haengdong/domain/action/MemberActionRepository.java @@ -1,6 +1,7 @@ package server.haengdong.domain.action; import java.util.List; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -12,4 +13,6 @@ public interface MemberActionRepository extends JpaRepository findAllByEvent(@Param("event") Event event); + + Optional findByAction(Action action); } From 595fac38727407612eeea1cc0184395b1001f96e Mon Sep 17 00:00:00 2001 From: kunsanglee Date: Fri, 2 Aug 2024 17:15:12 +0900 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20=EB=A7=B4=EB=B2=84=20=EC=95=A1?= =?UTF-8?q?=EC=85=98=20=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../haengdong/application/ActionService.java | 20 ------- .../application/MemberActionService.java | 12 +++++ .../domain/action/MemberActionRepository.java | 9 ++++ .../exception/HaengdongErrorCode.java | 5 +- .../presentation/ActionController.java | 11 ---- .../presentation/MemberActionController.java | 11 ++++ .../application/ActionServiceTest.java | 35 ++++++------ .../application/BillActionServiceTest.java | 14 ++++- .../application/MemberActionServiceTest.java | 54 +++++++++++++++++-- .../presentation/ActionControllerTest.java | 10 ---- .../MemberActionControllerTest.java | 18 +++++-- 11 files changed, 132 insertions(+), 67 deletions(-) diff --git a/server/src/main/java/server/haengdong/application/ActionService.java b/server/src/main/java/server/haengdong/application/ActionService.java index 7fae107ba..bda638756 100644 --- a/server/src/main/java/server/haengdong/application/ActionService.java +++ b/server/src/main/java/server/haengdong/application/ActionService.java @@ -1,12 +1,9 @@ package server.haengdong.application; import java.util.List; -import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import server.haengdong.application.response.MemberBillReportAppResponse; -import server.haengdong.domain.action.Action; -import server.haengdong.domain.action.ActionRepository; import server.haengdong.domain.action.BillAction; import server.haengdong.domain.action.BillActionRepository; import server.haengdong.domain.action.MemberAction; @@ -24,7 +21,6 @@ public class ActionService { private final BillActionRepository billActionRepository; private final MemberActionRepository memberActionRepository; private final EventRepository eventRepository; - private final ActionRepository actionRepository; public List getMemberBillReports(String token) { Event event = eventRepository.findByToken(token) @@ -38,20 +34,4 @@ public List getMemberBillReports(String token) { .map(entry -> new MemberBillReportAppResponse(entry.getKey(), entry.getValue())) .toList(); } - - public void deleteAction(String token, Long actionId) { - Event event = eventRepository.findByToken(token) - .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.NOT_FOUND_EVENT)); - Action action = actionRepository.findByIdAndEvent(actionId, event) - .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.NOT_FOUND_ACTION)); - Optional billAction = billActionRepository.findByAction(action); - Optional memberAction = memberActionRepository.findByAction(action); - - if (billAction.isPresent()) { - billActionRepository.delete(billAction.get()); - return; - } - - memberAction.ifPresent(memberActionRepository::delete); - } } diff --git a/server/src/main/java/server/haengdong/application/MemberActionService.java b/server/src/main/java/server/haengdong/application/MemberActionService.java index f893bd08d..c53c5174a 100644 --- a/server/src/main/java/server/haengdong/application/MemberActionService.java +++ b/server/src/main/java/server/haengdong/application/MemberActionService.java @@ -58,4 +58,16 @@ private Event findEvent(String token) { return eventRepository.findByToken(token) .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.NOT_FOUND_EVENT)); } + + @Transactional + public void deleteMemberAction(String token, Long actionId) { + Event event = eventRepository.findByToken(token) + .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.NOT_FOUND_EVENT)); + Action action = actionRepository.findByIdAndEvent(actionId, event) + .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.NOT_FOUND_ACTION)); + MemberAction memberAction = memberActionRepository.findByAction(action) + .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.NOT_FOUND_MEMBER_ACTION)); + + memberActionRepository.deleteAllByMemberAction(memberAction.getMemberName(), memberAction.getSequence()); + } } diff --git a/server/src/main/java/server/haengdong/domain/action/MemberActionRepository.java b/server/src/main/java/server/haengdong/domain/action/MemberActionRepository.java index 134eddf0f..9e69e5e67 100644 --- a/server/src/main/java/server/haengdong/domain/action/MemberActionRepository.java +++ b/server/src/main/java/server/haengdong/domain/action/MemberActionRepository.java @@ -3,6 +3,7 @@ import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @@ -15,4 +16,12 @@ public interface MemberActionRepository extends JpaRepository findAllByEvent(@Param("event") Event event); Optional findByAction(Action action); + + @Modifying + @Query(""" + delete + from MemberAction m + where m.memberName = :memberName and m.action.sequence >= :sequence + """) + void deleteAllByMemberAction(String memberName, Long sequence); } diff --git a/server/src/main/java/server/haengdong/exception/HaengdongErrorCode.java b/server/src/main/java/server/haengdong/exception/HaengdongErrorCode.java index 289009170..55e48661a 100644 --- a/server/src/main/java/server/haengdong/exception/HaengdongErrorCode.java +++ b/server/src/main/java/server/haengdong/exception/HaengdongErrorCode.java @@ -10,9 +10,10 @@ public enum HaengdongErrorCode { DUPLICATED_MEMBER_ACTION("MA_001", "중복된 인원이 존재합니다."), INVALID_MEMBER_IN_ACTION("MA_002", "현재 참여하고 있는 인원이 존재합니다."), INVALID_MEMBER_OUT_ACTION("MA_003", "현재 참여하고 있지 않는 인원이 존재합니다."), + NOT_FOUND_MEMBER_ACTION("MA_400", "존재하지 않는 멤버 액션입니다."), NOT_FOUND_EVENT("EV_400", "존재하지 않는 행사입니다."), - INTERNAL_SERVER_ERROR("S_001", "서버 내부에서 에러가 발생했습니다."), - NOT_FOUND_ACTION("AC_400", "존재하지 않는 액션입니다."); + NOT_FOUND_ACTION("AC_400", "존재하지 않는 액션입니다."), + INTERNAL_SERVER_ERROR("S_001", "서버 내부에서 에러가 발생했습니다."); private final String code; private final String message; diff --git a/server/src/main/java/server/haengdong/presentation/ActionController.java b/server/src/main/java/server/haengdong/presentation/ActionController.java index 533560280..657cb567e 100644 --- a/server/src/main/java/server/haengdong/presentation/ActionController.java +++ b/server/src/main/java/server/haengdong/presentation/ActionController.java @@ -3,7 +3,6 @@ import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @@ -24,14 +23,4 @@ public ResponseEntity getMemberBillReports(@PathVaria return ResponseEntity.ok() .body(MemberBillReportsResponse.of(memberBillReports)); } - - @DeleteMapping("/api/events/{eventId}/actions/{actionId}") - public ResponseEntity deleteAction( - @PathVariable("eventId") String token, - @PathVariable("actionId") Long actionId - ) { - actionService.deleteAction(token, actionId); - - return ResponseEntity.noContent().build(); - } } diff --git a/server/src/main/java/server/haengdong/presentation/MemberActionController.java b/server/src/main/java/server/haengdong/presentation/MemberActionController.java index c12370d86..e2c61b33f 100644 --- a/server/src/main/java/server/haengdong/presentation/MemberActionController.java +++ b/server/src/main/java/server/haengdong/presentation/MemberActionController.java @@ -3,6 +3,7 @@ import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -36,4 +37,14 @@ public ResponseEntity getCurrentMembers(@PathVariable("e return ResponseEntity.ok() .body(CurrentMembersResponse.of(currentMembers)); } + + @DeleteMapping("/api/events/{eventId}/actions/{actionId}/members") + public ResponseEntity deleteMemberAction( + @PathVariable("eventId") String token, + @PathVariable("actionId") Long actionId + ) { + memberActionService.deleteMemberAction(token, actionId); + + return ResponseEntity.ok().build(); + } } diff --git a/server/src/test/java/server/haengdong/application/ActionServiceTest.java b/server/src/test/java/server/haengdong/application/ActionServiceTest.java index 0b2e21f60..a05141b9b 100644 --- a/server/src/test/java/server/haengdong/application/ActionServiceTest.java +++ b/server/src/test/java/server/haengdong/application/ActionServiceTest.java @@ -7,12 +7,18 @@ import static server.haengdong.domain.action.MemberActionStatus.OUT; import java.util.List; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import server.haengdong.application.response.MemberBillReportAppResponse; -import server.haengdong.domain.action.*; +import server.haengdong.domain.action.Action; +import server.haengdong.domain.action.ActionRepository; +import server.haengdong.domain.action.BillAction; +import server.haengdong.domain.action.BillActionRepository; +import server.haengdong.domain.action.MemberAction; +import server.haengdong.domain.action.MemberActionRepository; import server.haengdong.domain.event.Event; import server.haengdong.domain.event.EventRepository; import server.haengdong.exception.HaengdongErrorCode; @@ -27,12 +33,23 @@ class ActionServiceTest { @Autowired private EventRepository eventRepository; + @Autowired + private ActionRepository actionRepository; + @Autowired private BillActionRepository billActionRepository; @Autowired private MemberActionRepository memberActionRepository; + @AfterEach + void tearDown() { + billActionRepository.deleteAllInBatch(); + memberActionRepository.deleteAllInBatch(); + actionRepository.deleteAllInBatch(); + eventRepository.deleteAllInBatch(); + } + @DisplayName("참여자별 정산 현황을 조회한다.") @Test void getMemberBillReports() { @@ -72,20 +89,4 @@ void getMemberBillReports1() { .isInstanceOf(HaengdongException.class) .hasMessage(HaengdongErrorCode.NOT_FOUND_EVENT.getMessage()); } - - @DisplayName("액션을 삭제합니다.") - @Test - void deleteAction() { - Event event = new Event("potato", "potatoHi"); - eventRepository.save(event); - - Action action = new Action(event, 1L); - MemberAction memberAction = new MemberAction(action, "웨디", MemberActionStatus.IN, 1L); - MemberAction savedMemberAction = memberActionRepository.save(memberAction); - Long memberActionId = savedMemberAction.getId(); - - actionService.deleteAction("potatoHi", memberActionId); - - assertThat(memberActionRepository.findById(memberActionId)).isEmpty(); - } } diff --git a/server/src/test/java/server/haengdong/application/BillActionServiceTest.java b/server/src/test/java/server/haengdong/application/BillActionServiceTest.java index 195d4bdd9..e519eb5ac 100644 --- a/server/src/test/java/server/haengdong/application/BillActionServiceTest.java +++ b/server/src/test/java/server/haengdong/application/BillActionServiceTest.java @@ -5,14 +5,16 @@ import static org.assertj.core.api.Assertions.tuple; import java.util.List; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import server.haengdong.application.request.BillActionAppRequest; +import server.haengdong.domain.action.ActionRepository; import server.haengdong.domain.action.BillAction; -import server.haengdong.domain.event.Event; import server.haengdong.domain.action.BillActionRepository; +import server.haengdong.domain.event.Event; import server.haengdong.domain.event.EventRepository; import server.haengdong.exception.HaengdongException; @@ -22,12 +24,22 @@ class BillActionServiceTest { @Autowired private BillActionService billActionService; + @Autowired + private ActionRepository actionRepository; + @Autowired private EventRepository eventRepository; @Autowired private BillActionRepository billActionRepository; + @AfterEach + void tearDown() { + billActionRepository.deleteAllInBatch(); + actionRepository.deleteAllInBatch(); + eventRepository.deleteAllInBatch(); + } + @DisplayName("지출 내역을 생성한다.") @Test void saveAllBillAction() { diff --git a/server/src/test/java/server/haengdong/application/MemberActionServiceTest.java b/server/src/test/java/server/haengdong/application/MemberActionServiceTest.java index 7212e300d..fc00e2262 100644 --- a/server/src/test/java/server/haengdong/application/MemberActionServiceTest.java +++ b/server/src/test/java/server/haengdong/application/MemberActionServiceTest.java @@ -1,7 +1,9 @@ package server.haengdong.application; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.tuple; import static server.haengdong.domain.action.MemberActionStatus.IN; import static server.haengdong.domain.action.MemberActionStatus.OUT; @@ -17,6 +19,7 @@ import server.haengdong.domain.action.ActionRepository; import server.haengdong.domain.action.MemberAction; import server.haengdong.domain.action.MemberActionRepository; +import server.haengdong.domain.action.MemberActionStatus; import server.haengdong.domain.event.Event; import server.haengdong.domain.event.EventRepository; import server.haengdong.exception.HaengdongException; @@ -48,7 +51,7 @@ void tearDown() { void saveMemberActionTest() { Event event = eventRepository.save(new Event("test", "TOKEN")); Action action = new Action(event, 1L); - MemberAction memberAction = new MemberAction(action, "망쵸", IN, 1L); + MemberAction memberAction = createMemberAction(action, "망쵸", IN, 1L); memberActionRepository.save(memberAction); assertThatCode(() -> memberActionService.saveMemberAction("TOKEN", new MemberActionsSaveAppRequest( @@ -61,11 +64,11 @@ void saveMemberActionTest() { void saveMemberActionTest1() { Event event = eventRepository.save(new Event("test", "TOKEN")); Action actionOne = new Action(event, 1L); - MemberAction memberActionOne = new MemberAction(actionOne, "망쵸", IN, 1L); + MemberAction memberActionOne = createMemberAction(actionOne, "망쵸", IN, 1L); memberActionRepository.save(memberActionOne); Action actionTwo = new Action(event, 2L); - MemberAction memberActionTwo = new MemberAction(actionTwo, "망쵸", OUT, 1L); + MemberAction memberActionTwo = createMemberAction(actionTwo, "망쵸", OUT, 1L); memberActionRepository.save(memberActionTwo); assertThatCode(() -> memberActionService.saveMemberAction("TOKEN", new MemberActionsSaveAppRequest( @@ -89,4 +92,49 @@ void getCurrentMembers() { assertThatThrownBy(() -> memberActionService.getCurrentMembers("token")) .isInstanceOf(HaengdongException.class); } + + @DisplayName("이벤트에 속한 멤버 액션을 삭제하면 이후에 기록된 해당 참여자의 모든 멤버 액션을 삭제한다.") + @Test + void deleteMemberAction() { + String token = "TOKEN"; + Event event = new Event("행동대장 회식", token); + eventRepository.save(event); + Action action = Action.createFirst(event); + MemberAction memberAction1 = createMemberAction(action, "토다리", IN, 1L); + Action targetAction = action.next(); + MemberAction memberAction2 = createMemberAction(targetAction, "토다리", OUT, 2L); + MemberAction memberAction3 = createMemberAction(action.next(), "쿠키", IN, 3L); + MemberAction memberAction4 = createMemberAction(action.next(), "웨디", IN, 4L); + MemberAction memberAction5 = createMemberAction(action.next(), "토다리", IN, 5L); + MemberAction memberAction6 = createMemberAction(action.next(), "토다리", OUT, 6L); + MemberAction memberAction7 = createMemberAction(action.next(), "쿠키", OUT, 7L); + memberActionRepository.saveAll( + List.of(memberAction1, + memberAction2, + memberAction3, + memberAction4, + memberAction5, + memberAction6, + memberAction7) + ); + + memberActionService.deleteMemberAction(token, targetAction.getId()); + List memberActions = memberActionRepository.findAll(); + + assertThat(memberActions).hasSize(4) + .extracting("id", "memberName", "status") + .containsExactly( + tuple(memberAction1.getId(), "토다리", IN), + tuple(memberAction3.getId(), "쿠키", IN), + tuple(memberAction4.getId(), "웨디", IN), + tuple(memberAction7.getId(), "쿠키", OUT) + ); + } + + private static MemberAction createMemberAction(Action action, + String memberName, + MemberActionStatus memberActionStatus, + long memberGroupId) { + return new MemberAction(action, memberName, memberActionStatus, memberGroupId); + } } diff --git a/server/src/test/java/server/haengdong/presentation/ActionControllerTest.java b/server/src/test/java/server/haengdong/presentation/ActionControllerTest.java index 0ae3cc2e2..739ac4962 100644 --- a/server/src/test/java/server/haengdong/presentation/ActionControllerTest.java +++ b/server/src/test/java/server/haengdong/presentation/ActionControllerTest.java @@ -3,7 +3,6 @@ import static org.hamcrest.Matchers.equalTo; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -47,13 +46,4 @@ void getMemberBillReports() throws Exception { .andExpect(MockMvcResultMatchers.jsonPath("$.reports[1].price").value(equalTo(200_000))); } - - @DisplayName("액션을 삭제한다.") - @Test - void deleteAction() throws Exception { - mockMvc.perform(delete("/api/events/{eventId}/actions/{actionId}", "token", "1") - .accept(MediaType.APPLICATION_JSON)) - .andDo(print()) - .andExpect(status().isNoContent()); - } } diff --git a/server/src/test/java/server/haengdong/presentation/MemberActionControllerTest.java b/server/src/test/java/server/haengdong/presentation/MemberActionControllerTest.java index ad8787cc6..acab2f6cc 100644 --- a/server/src/test/java/server/haengdong/presentation/MemberActionControllerTest.java +++ b/server/src/test/java/server/haengdong/presentation/MemberActionControllerTest.java @@ -3,9 +3,11 @@ import static org.hamcrest.Matchers.equalTo; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import com.fasterxml.jackson.databind.ObjectMapper; @@ -17,7 +19,6 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import server.haengdong.application.MemberActionService; import server.haengdong.application.response.CurrentMemberAppResponse; import server.haengdong.presentation.request.MemberActionsSaveRequest; @@ -61,7 +62,18 @@ void getCurrentMembers() throws Exception { .accept(MediaType.APPLICATION_JSON)) .andDo(print()) .andExpect(status().isOk()) - .andExpect(MockMvcResultMatchers.jsonPath("$.members[0].name").value(equalTo("소하"))) - .andExpect(MockMvcResultMatchers.jsonPath("$.members[1].name").value(equalTo("토다리"))); + .andExpect(jsonPath("$.members[0].name").value(equalTo("소하"))) + .andExpect(jsonPath("$.members[1].name").value(equalTo("토다리"))); + } + + @DisplayName("이벤트에 속한 멤버 액션을 삭제하면 이후에 기록된 해당 참여자의 모든 멤버 액션을 삭제한다.") + @Test + void deleteMemberAction() throws Exception { + String token = "TOKEN"; + Long memberActionId = 2L; + + mockMvc.perform(delete(String.format("/api/events/%s/actions/%d/members", token, memberActionId))) + .andDo(print()) + .andExpect(status().isOk()); } } From 27b2bc2b1680eb61a2b97783c5be47fae2209961 Mon Sep 17 00:00:00 2001 From: kunsanglee Date: Sat, 3 Aug 2024 17:17:57 +0900 Subject: [PATCH 4/5] =?UTF-8?q?refactor:=20api=20=EB=A7=A4=EA=B0=9C?= =?UTF-8?q?=EB=B3=80=EC=88=98=EC=97=90=20=EA=B0=92=20=EB=84=A3=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../haengdong/presentation/MemberActionControllerTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/test/java/server/haengdong/presentation/MemberActionControllerTest.java b/server/src/test/java/server/haengdong/presentation/MemberActionControllerTest.java index acab2f6cc..22840f091 100644 --- a/server/src/test/java/server/haengdong/presentation/MemberActionControllerTest.java +++ b/server/src/test/java/server/haengdong/presentation/MemberActionControllerTest.java @@ -70,9 +70,9 @@ void getCurrentMembers() throws Exception { @Test void deleteMemberAction() throws Exception { String token = "TOKEN"; - Long memberActionId = 2L; + Long actionId = 2L; - mockMvc.perform(delete(String.format("/api/events/%s/actions/%d/members", token, memberActionId))) + mockMvc.perform(delete("/api/events/{token}/actions/{actionId}/members", token, actionId)) .andDo(print()) .andExpect(status().isOk()); } From 99c073b568ece26ce3e4f0dd8f6a11dc2b8ecbfb Mon Sep 17 00:00:00 2001 From: kunsanglee Date: Sun, 4 Aug 2024 01:36:12 +0900 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=EC=97=90=20action=20=EC=98=AC=EB=B0=94?= =?UTF-8?q?=EB=A5=B4=EA=B2=8C=20=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/MemberActionService.java | 3 ++- .../domain/action/MemberActionRepository.java | 2 +- .../application/MemberActionServiceTest.java | 25 ++++++++++--------- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/server/src/main/java/server/haengdong/application/MemberActionService.java b/server/src/main/java/server/haengdong/application/MemberActionService.java index c53c5174a..64858d8d4 100644 --- a/server/src/main/java/server/haengdong/application/MemberActionService.java +++ b/server/src/main/java/server/haengdong/application/MemberActionService.java @@ -68,6 +68,7 @@ public void deleteMemberAction(String token, Long actionId) { MemberAction memberAction = memberActionRepository.findByAction(action) .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.NOT_FOUND_MEMBER_ACTION)); - memberActionRepository.deleteAllByMemberAction(memberAction.getMemberName(), memberAction.getSequence()); + memberActionRepository.deleteAllByMemberNameAndMinSequence(memberAction.getMemberName(), + memberAction.getSequence()); } } diff --git a/server/src/main/java/server/haengdong/domain/action/MemberActionRepository.java b/server/src/main/java/server/haengdong/domain/action/MemberActionRepository.java index 9e69e5e67..51248f305 100644 --- a/server/src/main/java/server/haengdong/domain/action/MemberActionRepository.java +++ b/server/src/main/java/server/haengdong/domain/action/MemberActionRepository.java @@ -23,5 +23,5 @@ public interface MemberActionRepository extends JpaRepository= :sequence """) - void deleteAllByMemberAction(String memberName, Long sequence); + void deleteAllByMemberNameAndMinSequence(String memberName, Long sequence); } diff --git a/server/src/test/java/server/haengdong/application/MemberActionServiceTest.java b/server/src/test/java/server/haengdong/application/MemberActionServiceTest.java index fc00e2262..9639f9570 100644 --- a/server/src/test/java/server/haengdong/application/MemberActionServiceTest.java +++ b/server/src/test/java/server/haengdong/application/MemberActionServiceTest.java @@ -99,15 +99,14 @@ void deleteMemberAction() { String token = "TOKEN"; Event event = new Event("행동대장 회식", token); eventRepository.save(event); - Action action = Action.createFirst(event); - MemberAction memberAction1 = createMemberAction(action, "토다리", IN, 1L); - Action targetAction = action.next(); + MemberAction memberAction1 = createMemberAction(new Action(event, 1L), "토다리", IN, 1L); + Action targetAction = new Action(event, 2L); MemberAction memberAction2 = createMemberAction(targetAction, "토다리", OUT, 2L); - MemberAction memberAction3 = createMemberAction(action.next(), "쿠키", IN, 3L); - MemberAction memberAction4 = createMemberAction(action.next(), "웨디", IN, 4L); - MemberAction memberAction5 = createMemberAction(action.next(), "토다리", IN, 5L); - MemberAction memberAction6 = createMemberAction(action.next(), "토다리", OUT, 6L); - MemberAction memberAction7 = createMemberAction(action.next(), "쿠키", OUT, 7L); + MemberAction memberAction3 = createMemberAction(new Action(event, 3L), "쿠키", IN, 3L); + MemberAction memberAction4 = createMemberAction(new Action(event, 4L), "웨디", IN, 4L); + MemberAction memberAction5 = createMemberAction(new Action(event, 5L), "토다리", IN, 5L); + MemberAction memberAction6 = createMemberAction(new Action(event, 6L), "토다리", OUT, 6L); + MemberAction memberAction7 = createMemberAction(new Action(event, 7L), "쿠키", OUT, 7L); memberActionRepository.saveAll( List.of(memberAction1, memberAction2, @@ -131,10 +130,12 @@ void deleteMemberAction() { ); } - private static MemberAction createMemberAction(Action action, - String memberName, - MemberActionStatus memberActionStatus, - long memberGroupId) { + private MemberAction createMemberAction( + Action action, + String memberName, + MemberActionStatus memberActionStatus, + long memberGroupId + ) { return new MemberAction(action, memberName, memberActionStatus, memberGroupId); } }