From c6a0c0d481ab2e9a52b5adb7da2120ac351c675b Mon Sep 17 00:00:00 2001 From: Seonghun Jeong <119427233+zzoe2346@users.noreply.github.com> Date: Wed, 6 Nov 2024 19:22:13 +0900 Subject: [PATCH] =?UTF-8?q?Fix:=20=ED=99=98=EB=B6=88=ED=95=98=EB=8A=94?= =?UTF-8?q?=EB=8D=B0=20=EB=8F=88=EC=9D=B4=20=EC=98=A4=ED=9E=88=EB=A0=A4=20?= =?UTF-8?q?=EC=B0=A8=EA=B0=90=EB=90=98=EB=8D=98=20=EB=B2=84=EA=B7=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=EA=B3=BC=20=EC=8B=9C=EB=8B=88=EC=96=B4=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D,=20=EC=88=98=EC=A0=95=20=EC=8B=9C=20?= =?UTF-8?q?=ED=8F=B0=20=EB=B2=88=ED=98=B8=20=EC=A4=91=EB=B3=B5=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80=20(#166)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 환불하는데 돈이 오히려 차감되던 버그 수정 * feat: 시니어 등록, 수정 시 폰 번호 중복 확인 로직 추가 * remove: 안부전화 수정 api 제거 --- .../guard/repository/SeniorRepository.java | 2 + .../sinitto/guard/service/GuardService.java | 8 ++ .../controller/HelloCallController.java | 9 -- .../helloCall/service/HelloCallService.java | 27 ---- .../sinitto/point/service/PointService.java | 2 +- .../guard/service/GuardServiceTest.java | 30 +++++ .../service/HelloCallServiceTest.java | 36 ------ .../point/service/PointServiceTest.java | 120 ++++++++++++++++++ 8 files changed, 161 insertions(+), 73 deletions(-) diff --git a/src/main/java/com/example/sinitto/guard/repository/SeniorRepository.java b/src/main/java/com/example/sinitto/guard/repository/SeniorRepository.java index 71309097..92547b6c 100644 --- a/src/main/java/com/example/sinitto/guard/repository/SeniorRepository.java +++ b/src/main/java/com/example/sinitto/guard/repository/SeniorRepository.java @@ -17,4 +17,6 @@ public interface SeniorRepository extends JpaRepository { Optional findByPhoneNumber(String phoneNumber); List findAllByMember(Member member); + + boolean existsByPhoneNumber(String phoneNumber); } diff --git a/src/main/java/com/example/sinitto/guard/service/GuardService.java b/src/main/java/com/example/sinitto/guard/service/GuardService.java index 6a2c38af..e620d930 100644 --- a/src/main/java/com/example/sinitto/guard/service/GuardService.java +++ b/src/main/java/com/example/sinitto/guard/service/GuardService.java @@ -59,6 +59,10 @@ public void createSenior(Long memberId, SeniorRequest seniorRequest) { ); if (member.isSinitto()) throw new BadRequestException("보호자만 이용할 수 있습니다."); + if(seniorRepository.existsByPhoneNumber(seniorRequest.seniorPhoneNumber())) { + throw new BadRequestException("이미 등록되어 있는 전화번호 입니다."); + } + Senior senior = new Senior(seniorRequest.seniorName(), seniorRequest.seniorPhoneNumber(), member); seniorRepository.save(senior); @@ -86,6 +90,10 @@ public void updateSenior(Long memberId, Long seniorId, SeniorRequest seniorReque () -> new NotFoundException("이메일에 해당하는 시니어를 찾을 수 없습니다.") ); + if(seniorRepository.existsByPhoneNumber(seniorRequest.seniorPhoneNumber())) { + throw new BadRequestException("이미 등록되어 있는 전화번호 입니다."); + } + senior.updateSenior(seniorRequest.seniorName(), seniorRequest.seniorPhoneNumber()); } diff --git a/src/main/java/com/example/sinitto/helloCall/controller/HelloCallController.java b/src/main/java/com/example/sinitto/helloCall/controller/HelloCallController.java index fd8ba62c..5d04ded6 100644 --- a/src/main/java/com/example/sinitto/helloCall/controller/HelloCallController.java +++ b/src/main/java/com/example/sinitto/helloCall/controller/HelloCallController.java @@ -74,15 +74,6 @@ public ResponseEntity createHelloCallByGuard(@MemberId Lo return ResponseEntity.ok(new StringMessageResponse("안부 전화 서비스가 신청되었습니다.")); } - @Operation(summary = "[보호자용] 안부 전화 서비스 수정하기", description = "보호자가 안부 전화 서비스 내용을 수정합니다.") - @PutMapping("/guards/{callId}") - public ResponseEntity updateHelloCallByGuard(@MemberId Long memberId, @PathVariable Long callId, @RequestBody HelloCallDetailUpdateRequest helloCallDetailUpdateRequest) { - - helloCallService.updateHelloCallByGuard(memberId, callId, helloCallDetailUpdateRequest); - - return ResponseEntity.ok(new StringMessageResponse("안부 전화 서비스 내용이 수정되었습니다.")); - } - @Operation(summary = "[보호자용] 안부 전화 서비스 삭제하기", description = "보호자가 안부 전화 서비스 신청을 취소합니다.") @DeleteMapping("/guards/{callId}") public ResponseEntity deleteHelloCallByGuard(@MemberId Long memberId, @PathVariable Long callId) { diff --git a/src/main/java/com/example/sinitto/helloCall/service/HelloCallService.java b/src/main/java/com/example/sinitto/helloCall/service/HelloCallService.java index 3c824faf..e6bf80d8 100644 --- a/src/main/java/com/example/sinitto/helloCall/service/HelloCallService.java +++ b/src/main/java/com/example/sinitto/helloCall/service/HelloCallService.java @@ -122,33 +122,6 @@ public HelloCallDetailResponse readHelloCallDetail(Long helloCallId) { helloCall.getSenior().getPhoneNumber(), helloCall.getPrice(), helloCall.getServiceTime()); } - @Transactional - public void updateHelloCallByGuard(Long memberId, Long helloCallId, HelloCallDetailUpdateRequest helloCallDetailUpdateRequest) { - HelloCall helloCall = helloCallRepository.findById(helloCallId) - .orElseThrow(() -> new NotFoundException("id에 해당하는 안부전화 정보를 찾을 수 없습니다.")); - - Member member = memberRepository.findById(memberId) - .orElseThrow(() -> new NotFoundException("id에 해당하는 멤버를 찾을 수 없습니다.")); - - helloCall.checkGuardIsCorrect(member); - - helloCall.updateHelloCall(helloCallDetailUpdateRequest.startDate(), helloCallDetailUpdateRequest.endDate(), - helloCallDetailUpdateRequest.price(), helloCallDetailUpdateRequest.serviceTime(), helloCallDetailUpdateRequest.requirement()); - - updateTimeSlots(helloCall, helloCallDetailUpdateRequest.timeSlots()); - } - - private void updateTimeSlots(HelloCall helloCall, List updatedTimeSlots) { - timeSlotRepository.deleteAllByHelloCall(helloCall); - helloCall.getTimeSlots().clear(); - - for (HelloCallDetailUpdateRequest.TimeSlot updatedSlot : updatedTimeSlots) { - TimeSlot newTimeSlot = new TimeSlot(updatedSlot.dayName(), updatedSlot.startTime(), updatedSlot.endTime(), helloCall); - timeSlotRepository.save(newTimeSlot); - helloCall.getTimeSlots().add(newTimeSlot); - } - } - @Transactional public void deleteHellCallByGuard(Long memberId, Long helloCallId) { HelloCall helloCall = helloCallRepository.findById(helloCallId) diff --git a/src/main/java/com/example/sinitto/point/service/PointService.java b/src/main/java/com/example/sinitto/point/service/PointService.java index a8dbbc5d..15ed05b4 100644 --- a/src/main/java/com/example/sinitto/point/service/PointService.java +++ b/src/main/java/com/example/sinitto/point/service/PointService.java @@ -154,7 +154,7 @@ public void refundPointByDelete(Long memberId, int price, PointLog.Content conte throw new BadRequestException("포인트가 부족합니다."); } - point.deduct(price); + point.earn(price); pointLogRepository.save( new PointLog( diff --git a/src/test/java/com/example/sinitto/guard/service/GuardServiceTest.java b/src/test/java/com/example/sinitto/guard/service/GuardServiceTest.java index 9a02c8d8..d8dc017b 100644 --- a/src/test/java/com/example/sinitto/guard/service/GuardServiceTest.java +++ b/src/test/java/com/example/sinitto/guard/service/GuardServiceTest.java @@ -115,6 +115,20 @@ void createSeniorTestWhenSinittoDoThis() { assertThrows(BadRequestException.class, () -> guardService.createSenior(memberId, seniorRequest)); } + @Test + @DisplayName("createSenior 테스트 - 이미 등록된 번호로 시니어 생성하면 예외를 발생시켜야한다.") + void createSeniorTestFailWhenDuplicatedPhoneNumber() { + // Given + Long memberId = 1L; + Member member = new Member("testName", "01012345678", "test@mail.com", false); + SeniorRequest seniorRequest = new SeniorRequest("testSeniorName", "01011111111"); + when(memberRepository.findById(memberId)).thenReturn(Optional.of(member)); + when(seniorRepository.existsByPhoneNumber("01011111111")).thenReturn(true); + + // When, Then + assertThrows(BadRequestException.class, () -> guardService.createSenior(memberId, seniorRequest)); + } + @Test @DisplayName("readSeniors 메소드 테스트") void readSeniorsTest() { @@ -177,6 +191,22 @@ void updateSeniorTest() { verify(senior, times(1)).updateSenior(request.seniorName(), request.seniorPhoneNumber()); } + @Test + @DisplayName("updateSenior 메소드 테스트 - 이미 등록된 번호로 수정시 예외가 발생해야한다.") + void updateSeniorTestFailWhenDuplicatedPhoneNumber() { + //given + Long memberId = 1L; + Long seniorId = 2L; + Member member = new Member("testName", "01012345678", "test@mail.com", true); + Senior senior = mock(Senior.class); + SeniorRequest request = new SeniorRequest("newSeniorName", "01011111111"); + + when(seniorRepository.findByIdAndMemberId(seniorId, memberId)).thenReturn(Optional.of(senior)); + when(seniorRepository.existsByPhoneNumber("01011111111")).thenReturn(true); + //when then + assertThrows(BadRequestException.class, () -> guardService.updateSenior(memberId, seniorId, request)); + } + @Test @DisplayName("deleteSenior 메소드 테스트") void deleteSeniorTest() { diff --git a/src/test/java/com/example/sinitto/hellocall/service/HelloCallServiceTest.java b/src/test/java/com/example/sinitto/hellocall/service/HelloCallServiceTest.java index ef93fc08..4cd52cb5 100644 --- a/src/test/java/com/example/sinitto/hellocall/service/HelloCallServiceTest.java +++ b/src/test/java/com/example/sinitto/hellocall/service/HelloCallServiceTest.java @@ -192,42 +192,6 @@ void readHelloCallDetailWhenHelloCallIsNotExist() { assertThrows(NotFoundException.class, () -> helloCallService.readHelloCallDetail(helloCallId)); } - @Test - @DisplayName("updateHelloCallByGuard 메소드 테스트 - HelloCall이 없을 때") - void updateHelloCallByGuardTestWhenHelloCallIsNotExist() { - //given - Long memberId = 1L; - Long helloCallId = 2L; - List timeSlots = new ArrayList<>(); - timeSlots.add(new HelloCallDetailUpdateRequest.TimeSlot("월", LocalTime.now(), LocalTime.now().plusHours(2))); - HelloCallDetailUpdateRequest helloCallDetailUpdateRequest = new HelloCallDetailUpdateRequest(LocalDate.now(), LocalDate.now().plusDays(7), timeSlots, 1000, 10, "testRequirement"); - - when(helloCallRepository.findById(helloCallId)).thenReturn(Optional.empty()); - - //when, then - assertThrows(NotFoundException.class, () -> helloCallService.updateHelloCallByGuard(memberId, helloCallId, helloCallDetailUpdateRequest)); - } - - @Test - @DisplayName("updateHelloCallByGuard 메소드 테스트 - member가 없을 때") - void updateHelloCallByGuardTestWhenMemberIsNotExist() { - //given - Member member = mock(Member.class); - Long memberId = 1L; - Senior senior = new Senior("testSeniorName", "01012345678", member); - Long helloCallId = 2L; - List timeSlots = new ArrayList<>(); - timeSlots.add(new HelloCallDetailUpdateRequest.TimeSlot("월", LocalTime.now(), LocalTime.now().plusHours(2))); - HelloCallDetailUpdateRequest helloCallDetailUpdateRequest = new HelloCallDetailUpdateRequest(LocalDate.now(), LocalDate.now().plusDays(7), timeSlots, 1000, 10, "testRequirement"); - HelloCall helloCall = new HelloCall(LocalDate.now(), LocalDate.now().plusDays(7), 500, 10, "testRequirement", senior); - - when(helloCallRepository.findById(helloCallId)).thenReturn(Optional.of(helloCall)); - when(memberRepository.findById(memberId)).thenReturn(Optional.empty()); - - //when, then - assertThrows(NotFoundException.class, () -> helloCallService.updateHelloCallByGuard(memberId, helloCallId, helloCallDetailUpdateRequest)); - } - @Test @DisplayName("deleteHellCallByGuard 메소드 테스트") void deleteHellCallByGuardTest() { diff --git a/src/test/java/com/example/sinitto/point/service/PointServiceTest.java b/src/test/java/com/example/sinitto/point/service/PointServiceTest.java index 05632ae3..035b2f81 100644 --- a/src/test/java/com/example/sinitto/point/service/PointServiceTest.java +++ b/src/test/java/com/example/sinitto/point/service/PointServiceTest.java @@ -232,4 +232,124 @@ void savePointWithdrawRequest4() { assertThrows(BadRequestException.class, () -> pointService.savePointWithdrawRequest(1L, 10000)); } } + + @Nested + @DisplayName("포인트 적립 테스트") + class EarnPointTest { + @Test + @DisplayName("포인트 적립 성공한다.") + void earnPoint1() { + //given + Point point = mock(Point.class); + when(pointRepository.findByMemberId(1L)).thenReturn(Optional.of(point)); + + //when + pointService.earnPoint(1L, 10000, PointLog.Content.COMPLETE_HELLO_CALL_AND_EARN); + + //then + verify(point).earn(10000); + verify(pointLogRepository).save(any(PointLog.class)); + } + + @Test + @DisplayName("멤버에 연관된 포인트가 없으면 예외를 발생시켜야한다.") + void earnPoint2() { + //given + when(pointRepository.findByMemberId(1L)).thenReturn(Optional.empty()); + + + //when then + assertThrows(NotFoundException.class, () -> pointService.earnPoint(1L, 10000, PointLog.Content.COMPLETE_CALLBACK_AND_EARN)); + } + } + + @Nested + @DisplayName("포인트 차감 테스트") + class DeductPointTest { + + @Test + @DisplayName("포인트 차감 성공한다.") + void deductPoint1() { + //given + Point point = mock(Point.class); + when(pointRepository.findByMemberIdWithWriteLock(1L)).thenReturn(Optional.of(point)); + when(point.isSufficientForDeduction(10000)).thenReturn(true); + + //when + pointService.deductPoint(1L, 10000, PointLog.Content.SPEND_COMPLETE_CALLBACK); + + //then + verify(point).deduct(10000); + verify(pointLogRepository).save(any(PointLog.class)); + } + + @Test + @DisplayName("멤버에 연관된 포인트가 없으면 예외를 발생시켜야한다.") + void deductPoint2() { + //given + when(pointRepository.findByMemberIdWithWriteLock(1L)).thenReturn(Optional.empty()); + + //when then + + assertThrows(NotFoundException.class, () -> pointService.deductPoint(1L, 10000, PointLog.Content.SPEND_COMPLETE_CALLBACK)); + } + + @Test + @DisplayName("포인트가 부족하면 예외를 발생시켜야한다.") + void deductPoint3() { + + //given + Point point = mock(Point.class); + when(pointRepository.findByMemberIdWithWriteLock(1L)).thenReturn(Optional.of(point)); + when(point.isSufficientForDeduction(10000)).thenReturn(false); + + //when then + assertThrows(BadRequestException.class, () -> pointService.deductPoint(1L, 10000, PointLog.Content.SPEND_COMPLETE_HELLO_CALL)); + } + } + + @Nested + @DisplayName("포인트 환불 테스트") + class RefundPointByDeleteTest { + + @Test + @DisplayName("포인트 환불 성공한다. 성공하면 포인트가 되돌아 온다(적립)") + void refundPointByDelete1() { + //given + Point point = mock(Point.class); + when(pointRepository.findByMemberIdWithWriteLock(1L)).thenReturn(Optional.of(point)); + when(point.isSufficientForDeduction(10000)).thenReturn(true); + + //when + pointService.refundPointByDelete(1L, 10000, PointLog.Content.SPEND_CANCEL_HELLO_CALL); + + //then + verify(point).earn(10000); + verify(pointLogRepository).save(any(PointLog.class)); + } + + + @Test + @DisplayName("멤버에 연관된 포인트가 없으면 예외를 발생시켜야한다.") + void refundPointByDelete2() { + //given + when(pointRepository.findByMemberIdWithWriteLock(1L)).thenReturn(Optional.empty()); + + //when then + assertThrows(NotFoundException.class, () -> pointService.refundPointByDelete(1L, 10000, PointLog.Content.SPEND_CANCEL_HELLO_CALL)); + } + + @Test + @DisplayName("포인트가 부족하면 예외를 발생시켜야한다.") + void refundPointByDelete3() { + //given + Point point = mock(Point.class); + when(pointRepository.findByMemberIdWithWriteLock(1L)).thenReturn(Optional.of(point)); + when(point.isSufficientForDeduction(10000)).thenReturn(false); + + //when then + assertThrows(BadRequestException.class, () -> pointService.refundPointByDelete(1L, 10000, PointLog.Content.SPEND_CANCEL_HELLO_CALL)); + } + } + }