diff --git a/src/main/java/com/challenge/api/controller/challenge/request/ChallengeCancelRequest.java b/src/main/java/com/challenge/api/controller/challenge/request/ChallengeCancelRequest.java index e154821..d453dfa 100644 --- a/src/main/java/com/challenge/api/controller/challenge/request/ChallengeCancelRequest.java +++ b/src/main/java/com/challenge/api/controller/challenge/request/ChallengeCancelRequest.java @@ -2,6 +2,7 @@ import com.challenge.api.service.challenge.request.ChallengeCancelServiceRequest; import jakarta.validation.constraints.NotBlank; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -12,6 +13,11 @@ public class ChallengeCancelRequest { @NotBlank(message = "취소일은 필수 입력 값입니다.") private String cancelDate; + @Builder + private ChallengeCancelRequest(String cancelDate) { + this.cancelDate = cancelDate; + } + public ChallengeCancelServiceRequest toServiceRequest() { return ChallengeCancelServiceRequest.builder() .cancelDate(cancelDate) diff --git a/src/main/java/com/challenge/api/service/challenge/ChallengeService.java b/src/main/java/com/challenge/api/service/challenge/ChallengeService.java index de9ea87..985e253 100644 --- a/src/main/java/com/challenge/api/service/challenge/ChallengeService.java +++ b/src/main/java/com/challenge/api/service/challenge/ChallengeService.java @@ -98,9 +98,11 @@ public ChallengeResponse cancelChallenge(Member member, Long challengeId, Challe Challenge challenge = challengeRepository.getReferenceById(challengeId); + // validation Record record = recordValidator.hasRecordFor(challenge, DateUtils.toLocalDate(request.getCancelDate())); - challenge.getRecords().remove(record); + // 기록 삭제 + challenge.getRecords().remove(record); return ChallengeResponse.of(challenge); } diff --git a/src/main/java/com/challenge/domain/challenge/Challenge.java b/src/main/java/com/challenge/domain/challenge/Challenge.java index cc4759a..bfbd8fb 100644 --- a/src/main/java/com/challenge/domain/challenge/Challenge.java +++ b/src/main/java/com/challenge/domain/challenge/Challenge.java @@ -6,7 +6,16 @@ import com.challenge.domain.category.Category; import com.challenge.domain.member.Member; import com.challenge.domain.record.Record; -import jakarta.persistence.*; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; @@ -26,7 +35,7 @@ public class Challenge extends BaseDateTimeEntity { @Column(name = "challenge_id") private Long id; - @OneToMany(mappedBy = "challenge") + @OneToMany(mappedBy = "challenge", cascade = CascadeType.REMOVE, orphanRemoval = true) private List records = new ArrayList<>(); @ManyToOne(fetch = FetchType.LAZY) diff --git a/src/test/java/com/challenge/api/service/challenge/ChallengeServiceTest.java b/src/test/java/com/challenge/api/service/challenge/ChallengeServiceTest.java index 54b6b4d..283f563 100644 --- a/src/test/java/com/challenge/api/service/challenge/ChallengeServiceTest.java +++ b/src/test/java/com/challenge/api/service/challenge/ChallengeServiceTest.java @@ -1,10 +1,10 @@ package com.challenge.api.service.challenge; +import com.challenge.api.controller.challenge.request.ChallengeCancelRequest; import com.challenge.api.controller.challenge.request.ChallengeCreateRequest; +import com.challenge.api.controller.challenge.request.ChallengeQueryRequest; import com.challenge.api.service.challenge.request.ChallengeAchieveServiceRequest; -import com.challenge.api.service.challenge.request.ChallengeCancelServiceRequest; import com.challenge.api.service.challenge.request.ChallengeCreateServiceRequest; -import com.challenge.api.service.challenge.request.ChallengeQueryServiceRequest; import com.challenge.api.service.challenge.request.ChallengeUpdateServiceRequest; import com.challenge.api.service.challenge.response.ChallengeResponse; import com.challenge.domain.category.Category; @@ -77,7 +77,7 @@ void getChallenges() { Category category = createCategory("카테고리"); categoryRepository.save(category); - ChallengeQueryServiceRequest request = ChallengeQueryServiceRequest.builder() + ChallengeQueryRequest request = ChallengeQueryRequest.builder() .queryDate(targetDate) .build(); @@ -90,7 +90,7 @@ void getChallenges() { challengeRepository.saveAll(List.of(challenge1, challenge2, challenge3)); // when - List challenges = challengeService.getChallenges(member, request); + List challenges = challengeService.getChallenges(member, request.toServiceRequest()); // then assertThat(challenges).hasSize(2) @@ -188,7 +188,7 @@ void achieveChallenge() { ); } - @DisplayName("챌린지를 취소한다.") + @DisplayName("챌린지 달성을 취소한다.") @Test void cancelChallenge() { // given @@ -198,7 +198,7 @@ void cancelChallenge() { Category category = createCategory("카테고리"); categoryRepository.save(category); - ChallengeCreateServiceRequest request = ChallengeCreateServiceRequest.builder() + ChallengeCreateRequest challengeCreateRequest = ChallengeCreateRequest.builder() .title("제목") .durationInWeeks(2) .weeklyGoalCount(3) @@ -207,30 +207,82 @@ void cancelChallenge() { .content("내용") .build(); - Challenge challenge = Challenge.create(member, category, request, LocalDateTime.of(2024, 11, 11, 10, 10, 30)); - challengeRepository.save(challenge); - - Record record1 = createRecord(challenge, LocalDate.of(2024, 11, 11)); - Record record2 = createRecord(challenge, LocalDate.of(2024, 11, 12)); - Record record3 = createRecord(challenge, LocalDate.of(2024, 11, 13)); - recordRepository.saveAll(List.of(record1, record2, record3)); + Challenge challenge1 = Challenge.create( + member, + category, + challengeCreateRequest.toServiceRequest(), + LocalDateTime.of(2024, 11, 11, 10, 10, 30) + ); + Challenge challenge2 = Challenge.create( + member, + category, + challengeCreateRequest.toServiceRequest(), + LocalDateTime.of(2024, 12, 1, 10, 10, 30) + ); + challengeRepository.saveAll(List.of(challenge1, challenge2)); - ChallengeCancelServiceRequest cancelRequest = ChallengeCancelServiceRequest.builder() + // 챌린지 달성 + challengeService.achieveChallenge(member, challenge1.getId(), + ChallengeAchieveServiceRequest.builder().achieveDate("2024-11-11").build()); + challengeService.achieveChallenge(member, challenge1.getId(), + ChallengeAchieveServiceRequest.builder().achieveDate("2024-11-12").build()); + challengeService.achieveChallenge(member, challenge1.getId(), + ChallengeAchieveServiceRequest.builder().achieveDate("2024-11-13").build()); + + challengeService.achieveChallenge(member, challenge2.getId(), + ChallengeAchieveServiceRequest.builder().achieveDate("2024-12-02").build()); + challengeService.achieveChallenge(member, challenge2.getId(), + ChallengeAchieveServiceRequest.builder().achieveDate("2024-12-03").build()); + + // 챌린지 취소 + ChallengeCancelRequest challengeCancelRequest1 = ChallengeCancelRequest.builder() .cancelDate("2024-11-13") .build(); + ChallengeCancelRequest challengeCancelRequest2 = ChallengeCancelRequest.builder() + .cancelDate("2024-12-03") + .build(); - // when - ChallengeResponse challengeResponse = challengeService.cancelChallenge( + // when - 취소된 챌린지 상태 확인 + ChallengeResponse challengeResponse1 = challengeService.cancelChallenge( member, - challenge.getId(), - cancelRequest + challenge1.getId(), + challengeCancelRequest1.toServiceRequest() + ); + ChallengeResponse challengeResponse2 = challengeService.cancelChallenge( + member, + challenge2.getId(), + challengeCancelRequest2.toServiceRequest() ); - // then - assertThat(challengeResponse.getId()).isNotNull(); - assertThat(challengeResponse.getTitle()).isEqualTo("제목"); - assertThat(challengeResponse.getRecord().getSuccessDates()) + // then - 취소된 챌린지 검증 + assertThat(challengeResponse1.getId()).isNotNull(); + assertThat(challengeResponse1.getTitle()).isEqualTo("제목"); + assertThat(challengeResponse1.getRecord().getSuccessDates()) .containsExactlyInAnyOrder("2024-11-11", "2024-11-12"); + + assertThat(challengeResponse2.getId()).isNotNull(); + assertThat(challengeResponse2.getTitle()).isEqualTo("제목"); + assertThat(challengeResponse2.getRecord().getSuccessDates()) + .containsExactlyInAnyOrder("2024-12-02"); + + // given - 모든 챌린지 조회를 위한 요청 request + ChallengeQueryRequest challengeQueryRequest = ChallengeQueryRequest.builder() + .queryDate("2024-12-28") + .build(); + + // when - 모든 챌린지 조회 + List challenges = challengeService.getChallenges( + member, + challengeQueryRequest.toServiceRequest() + ); + + // then - 조회된 챌린지들에 대한 검증 + assertThat(challenges).hasSize(2) + .extracting("record.successDates") + .containsExactlyInAnyOrder( + List.of("2024-11-11", "2024-11-12"), + List.of("2024-12-02") + ); } @DisplayName("챌린지를 수정한다.")