Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: 환불하는데 돈이 오히려 차감되던 버그 수정과 시니어 등록, 수정 시 폰 번호 중복 확인 로직 추가 #166

Merged
merged 4 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ public interface SeniorRepository extends JpaRepository<Senior, Long> {
Optional<Senior> findByPhoneNumber(String phoneNumber);

List<Senior> findAllByMember(Member member);

boolean existsByPhoneNumber(String phoneNumber);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,6 @@ public ResponseEntity<StringMessageResponse> createHelloCallByGuard(@MemberId Lo
return ResponseEntity.ok(new StringMessageResponse("안부 전화 서비스가 신청되었습니다."));
}

@Operation(summary = "[보호자용] 안부 전화 서비스 수정하기", description = "보호자가 안부 전화 서비스 내용을 수정합니다.")
@PutMapping("/guards/{callId}")
public ResponseEntity<StringMessageResponse> 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<StringMessageResponse> deleteHelloCallByGuard(@MemberId Long memberId, @PathVariable Long callId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<HelloCallDetailUpdateRequest.TimeSlot> 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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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", "[email protected]", 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() {
Expand Down Expand Up @@ -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", "[email protected]", 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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<HelloCallDetailUpdateRequest.TimeSlot> 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<HelloCallDetailUpdateRequest.TimeSlot> 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() {
Expand Down
120 changes: 120 additions & 0 deletions src/test/java/com/example/sinitto/point/service/PointServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}

}