diff --git a/src/main/java/com/ject/studytrip/trip/application/facade/TripFacade.java b/src/main/java/com/ject/studytrip/trip/application/facade/TripFacade.java index 5d2b4bb..3c3d896 100644 --- a/src/main/java/com/ject/studytrip/trip/application/facade/TripFacade.java +++ b/src/main/java/com/ject/studytrip/trip/application/facade/TripFacade.java @@ -47,7 +47,7 @@ public TripInfo createTrip(Long memberId, CreateTripRequest request) { @Transactional public void updateTrip(Long memberId, Long tripId, UpdateTripRequest request) { Member member = memberService.getMember(memberId); - Trip trip = tripService.getTrip(tripId); + Trip trip = tripService.getValidTrip(member.getId(), tripId); tripService.updateTrip(member.getId(), trip, request); @@ -59,7 +59,7 @@ public void updateTrip(Long memberId, Long tripId, UpdateTripRequest request) { @Transactional public void deleteTrip(Long memberId, Long tripId) { Member member = memberService.getMember(memberId); - Trip trip = tripService.getTrip(tripId); + Trip trip = tripService.getValidTrip(member.getId(), tripId); tripService.deleteTrip(member.getId(), trip); // TODO : 추후 엔티티가 생성되면, 여행과 관련된 엔티티를 모두 soft delete 하는 로직 추가 @@ -88,8 +88,10 @@ public Slice getTripsByMember(Long memberId, int page, int size) { return new SliceImpl<>(tripInfos, tripSlice.getPageable(), tripSlice.hasNext()); } - public TripDetail getTrip(Long tripId) { - Trip trip = tripService.getTrip(tripId); + public TripDetail getTrip(Long memberId, Long tripId) { + Member member = memberService.getMember(memberId); + Trip trip = tripService.getValidTrip(member.getId(), tripId); + int dDay = calculateDDay(trip.getEndDate()); int progress = calculateProgress(trip.getTotalStamps(), trip.getCompletedStamps()); diff --git a/src/main/java/com/ject/studytrip/trip/application/service/TripService.java b/src/main/java/com/ject/studytrip/trip/application/service/TripService.java index ed26833..1ddb70c 100644 --- a/src/main/java/com/ject/studytrip/trip/application/service/TripService.java +++ b/src/main/java/com/ject/studytrip/trip/application/service/TripService.java @@ -45,9 +45,7 @@ public void updateTrip(Long memberId, Trip trip, UpdateTripRequest request) { TripCategory category = null; if (request.category() != null) category = TripCategory.from(request.category()); - TripPolicy.validateOwner(memberId, trip); TripPolicy.validateEndDateIsNotBeforeStartDate(trip.getStartDate(), request.endDate()); - TripPolicy.validateNotDeleted(trip); trip.update(request.name(), request.memo(), category, request.endDate()); } @@ -61,22 +59,15 @@ public void decreaseTotalStamps(Trip trip) { } public void deleteTrip(Long memberId, Trip trip) { - TripPolicy.validateOwner(memberId, trip); - trip.updateDeletedAt(); // TODO : 삭제는 로직을 더 구상해본 후 추후 리팩토링 } public Trip getTrip(Long tripId) { - Trip trip = - tripRepository - .findById(tripId) - .orElseThrow(() -> new CustomException(TripErrorCode.TRIP_NOT_FOUND)); - - TripPolicy.validateNotDeleted(trip); - - return trip; + return tripRepository + .findById(tripId) + .orElseThrow(() -> new CustomException(TripErrorCode.TRIP_NOT_FOUND)); } public Trip getValidTrip(Long memberId, Long tripId) { diff --git a/src/main/java/com/ject/studytrip/trip/presentation/controller/TripController.java b/src/main/java/com/ject/studytrip/trip/presentation/controller/TripController.java index 5b5015e..0a4d4cf 100644 --- a/src/main/java/com/ject/studytrip/trip/presentation/controller/TripController.java +++ b/src/main/java/com/ject/studytrip/trip/presentation/controller/TripController.java @@ -102,8 +102,9 @@ public ResponseEntity loadTrips( @Operation(summary = "여행 상세 조회", description = "특정 여행을 조회하는 API 입니다.") @GetMapping("/{tripId}") public ResponseEntity loadTripDetail( + @AuthenticationPrincipal String memberId, @PathVariable @NotNull(message = "여행 ID는 필수 요청 파라미터입니다.") Long tripId) { - TripDetail result = tripFacade.getTrip(tripId); + TripDetail result = tripFacade.getTrip(Long.valueOf(memberId), tripId); return ResponseEntity.status(HttpStatus.OK) .body( diff --git a/src/test/java/com/ject/studytrip/trip/application/service/TripServiceTest.java b/src/test/java/com/ject/studytrip/trip/application/service/TripServiceTest.java index cb45bfe..447dbd9 100644 --- a/src/test/java/com/ject/studytrip/trip/application/service/TripServiceTest.java +++ b/src/test/java/com/ject/studytrip/trip/application/service/TripServiceTest.java @@ -158,19 +158,6 @@ void shouldUpdateTrip() { assertThat(trip.getName()).isEqualTo(TRIP_NAME); } - @Test - @DisplayName("수정할 권한이 없는 사용자일 경우 예외가 발생한다") - void shouldThrowExceptionWhenNoPermission() { - // given - Member newMember = MemberFixture.createMemberFromKakao(); - UpdateTripRequest request = new UpdateTripRequestFixture().build(); - - // When & Then - assertThatThrownBy(() -> tripService.updateTrip(newMember.getId(), trip, request)) - .isInstanceOf(CustomException.class) - .hasMessageContaining(TripErrorCode.NOT_TRIP_OWNER.getMessage()); - } - @Test @DisplayName("여행 종료일이 시작일보다 이전일 경우 예외가 발생한다") void shouldThrowExceptionWhenEndDateIsBeforeStartDate() { @@ -187,19 +174,6 @@ void shouldThrowExceptionWhenEndDateIsBeforeStartDate() { TripErrorCode.TRIP_END_DATE_BEFORE_START_DATE.getMessage()); } - @Test - @DisplayName("이미 삭제된 여행일 경우 예외가 발생한다") - void shouldThrowExceptionWhenAlreadyDeleted() { - // given - Trip deleted = TripFixture.createDeletedTrip(member); - UpdateTripRequest request = new UpdateTripRequestFixture().build(); - - // When & Then - assertThatThrownBy(() -> tripService.updateTrip(member.getId(), deleted, request)) - .isInstanceOf(CustomException.class) - .hasMessageContaining(TripErrorCode.TRIP_ALREADY_DELETED.getMessage()); - } - @Test @DisplayName("여행의 총 스탬프 수를 +1 증가시킨다") void shouldIncreaseTotalStamps() { @@ -240,18 +214,6 @@ void shouldDeleteTripForUpdateDeletedAt() { // then assertThat(trip.getDeletedAt()).isNotNull(); } - - @Test - @DisplayName("삭제할 권한이 없는 경우 예외가 발생한다") - void shouldThrowExceptionWhenNoPermission() { - // given - Member newMember = MemberFixture.createMemberFromKakao(); - - // when & then - assertThatThrownBy(() -> tripService.deleteTrip(newMember.getId(), trip)) - .isInstanceOf(CustomException.class) - .hasMessage(TripErrorCode.NOT_TRIP_OWNER.getMessage()); - } } @Nested @@ -272,6 +234,33 @@ void shouldGetTripByTripIdReturnTrip() { assertThat(result.getId()).isEqualTo(trip.getId()); } + @Test + @DisplayName("특정 여행 ID로 DB에서 조회한 후 유효한 여행을 반환한다") + void shouldGetTripByTripIdReturnValidTrip() { + // given + given(tripRepository.findById(trip.getId())).willReturn(Optional.of(trip)); + + // when + Trip result = tripService.getValidTrip(member.getId(), trip.getId()); + + // then + assertThat(result).isNotNull(); + assertThat(result.getId()).isEqualTo(trip.getId()); + } + + @Test + @DisplayName("여행의 소유자가 아닐 경우 예외가 발생한다") + void shouldThrowExceptionWhenNotTripOwner() { + // given + Member newMember = MemberFixture.createMemberFromKakao(); + given(tripRepository.findById(trip.getId())).willReturn(Optional.of(trip)); + + // When & Then + assertThatThrownBy(() -> tripService.getValidTrip(newMember.getId(), trip.getId())) + .isInstanceOf(CustomException.class) + .hasMessageContaining(TripErrorCode.NOT_TRIP_OWNER.getMessage()); + } + @Test @DisplayName("이미 삭제된 여행일 경우 예외가 발생한다") void shouldThrowExceptionWhenAlreadyTrip() { @@ -280,7 +269,7 @@ void shouldThrowExceptionWhenAlreadyTrip() { given(tripRepository.findById(any())).willReturn(Optional.of(deleted)); // when & then - assertThatThrownBy(() -> tripService.getTrip(trip.getId())) + assertThatThrownBy(() -> tripService.getValidTrip(member.getId(), deleted.getId())) .isInstanceOf(CustomException.class) .hasMessage(TripErrorCode.TRIP_ALREADY_DELETED.getMessage()); } diff --git a/src/test/java/com/ject/studytrip/trip/presentation/controller/TripControllerIntegrationTest.java b/src/test/java/com/ject/studytrip/trip/presentation/controller/TripControllerIntegrationTest.java index 67eee71..14b9ff5 100644 --- a/src/test/java/com/ject/studytrip/trip/presentation/controller/TripControllerIntegrationTest.java +++ b/src/test/java/com/ject/studytrip/trip/presentation/controller/TripControllerIntegrationTest.java @@ -581,6 +581,20 @@ void shouldThrowExceptionWhenInvalidTripId() throws Exception { resultActions.andExpect(status().is(TripErrorCode.TRIP_NOT_FOUND.getStatus().value())); } + @Test + @DisplayName("여행의 소유자가 아닐 경우 403 예외가 발생한다") + void shouldThrowExceptionWhenNotTripOwner() throws Exception { + // given + Member newMember = memberTestHelper.saveMember("test@gmail.com", "test"); + Trip newTrip = tripTestHelper.saveTrip(newMember, TripCategory.COURSE); + + // when + ResultActions resultActions = getResultActions(token, newTrip.getId()); + + // then + resultActions.andExpect(status().is(TripErrorCode.NOT_TRIP_OWNER.getStatus().value())); + } + @Test @DisplayName("이미 삭제된 여행일 경우 400 예외가 발생한다") void shouldThrowExceptionWhenAlreadyDeleted() throws Exception {