Skip to content

Commit

Permalink
Merge branch 'develop-be' into feature/#25-read-visit
Browse files Browse the repository at this point in the history
  • Loading branch information
devhoya97 authored Jul 25, 2024
2 parents 3524df8 + 9a75f74 commit 58960dd
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
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;
Expand Down Expand Up @@ -59,4 +60,12 @@ public ResponseEntity<Void> updateTravel(
travelService.updateTravel(travelRequest, travelId);
return ResponseEntity.ok().build();
}

@DeleteMapping("/{travelId}")
public ResponseEntity<Void> deleteTravel(
@PathVariable @Min(value = 1L, message = "여행 식별자는 양수로 이루어져야 합니다.") Long travelId,
@MemberId Long memberId) {
travelService.deleteTravel(travelId);
return ResponseEntity.ok().build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.staccato.visit.domain.Visit;
import com.staccato.visit.domain.VisitImage;
import com.staccato.visit.repository.VisitImageRepository;
import com.staccato.visit.repository.VisitLogRepository;
import com.staccato.visit.repository.VisitRepository;
import com.staccato.visit.service.dto.response.VisitResponse;

Expand All @@ -31,6 +32,7 @@ public class TravelService {
private final TravelRepository travelRepository;
private final TravelMemberRepository travelMemberRepository;
private final VisitRepository visitRepository;
private final VisitLogRepository visitLogRepository;
private final MemberRepository memberRepository;
private final VisitImageRepository visitImageRepository;

Expand All @@ -55,14 +57,6 @@ private Member getMemberById(long memberId) {
.orElseThrow(() -> new IllegalArgumentException("Invalid Operation"));
}

@Transactional
public void updateTravel(TravelRequest travelRequest, Long travelId) {
Travel updatedTravel = travelRequest.toTravel();
Travel originTravel = getTravelById(travelId);
List<Visit> visits = visitRepository.findAllByTravelIdAndIsDeletedIsFalse(travelId);
originTravel.update(updatedTravel, visits);
}

public TravelResponses readAllTravels(long memberId, Integer year) {
return Optional.ofNullable(year)
.map(y -> readAllByYear(memberId, y))
Expand All @@ -86,6 +80,34 @@ private TravelResponses getTravelResponses(List<TravelMember> travelMembers) {
return TravelResponses.from(travels);
}

@Transactional
public void updateTravel(TravelRequest travelRequest, Long travelId) {
Travel updatedTravel = travelRequest.toTravel();
Travel originTravel = getTravelById(travelId);
List<Visit> visits = visitRepository.findAllByTravelIdAndIsDeletedIsFalse(travelId);
originTravel.update(updatedTravel, visits);
}

@Transactional
public void deleteTravel(Long travelId) {
validateVisitExistsByTravelId(travelId);
visitRepository.findAllByTravelIdAndIsDeletedIsFalse(travelId)
.forEach(visit -> deleteVisits(visit.getId()));
travelRepository.deleteById(travelId);
}

private void validateVisitExistsByTravelId(Long travelId) {
if (visitRepository.existsByTravelId(travelId)) {
throw new StaccatoException("해당 여행 상세에 방문 기록이 남아있어 삭제할 수 없습니다.");
}
}

private void deleteVisits(long visitId) {
visitLogRepository.deleteByVisitId(visitId);
visitImageRepository.deleteByVisitId(visitId);
visitRepository.deleteById(visitId);
}

public TravelDetailResponse readTravelById(long travelId) {
Travel travel = getTravelById(travelId);
List<VisitResponse> visitResponses = getVisitResponses(visitRepository.findAllByTravelIdAndIsDeletedIsFalse(travelId));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.util.List;

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 com.staccato.visit.domain.Visit;
Expand All @@ -11,4 +13,11 @@ public interface VisitRepository extends JpaRepository<Visit, Long> {
List<Visit> findAllByTravelIdAndIsDeletedIsFalse(@Param("travelId") long travelId);

long countByPinIdAndIsDeletedIsFalse(Long pinId);

@Modifying(clearAutomatically = true)
@Query("UPDATE Visit vi SET vi.isDeleted = true WHERE vi.travel.id = :travelId")
void deleteByTravelId(@Param("travelId") Long travelId);

@Query("SELECT CASE WHEN COUNT(v) > 0 THEN true ELSE false END FROM Visit v WHERE v.travel.id = :travelId")
boolean existsByTravelId(@Param("travelId") Long travelId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -254,4 +254,21 @@ private TravelRequest createTravelRequest(int year) {
LocalDate.of(year, 7, 1),
LocalDate.of(year, 7, 10));
}

@DisplayName("사용자가 여행 상세 삭제를 요청하면, 여행 상세를 삭제한다.")
@Test
void deleteTravel() {
// given
Long travelId = 1L;
TravelRequest travelRequest = new TravelRequest("https://example.com/travels/geumohrm.jpg", "2023 여름 휴가", "친구들과 함께한 여름 휴가 여행", LocalDate.of(2023, 7, 1), LocalDate.of(2023, 7, 10));
createTravel(travelRequest);

// when & then
RestAssured.given().pathParam("travelId", travelId).log().all()
.header(HttpHeaders.AUTHORIZATION, USER_AUTHORIZATION)
.contentType(ContentType.JSON)
.when().delete("/travels/{travelId}")
.then().log().all()
.assertThat().statusCode(HttpStatus.OK.value());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,15 +133,8 @@ private Visit saveVisit(Pin pin, long otherId) {
@Test
void updateTravel() {
// given
Long travelId = 1L;
Travel originTravel = new Travel(
"https://example.com/travels/geumohrm.jpg",
"2023 여름 휴가",
"친구들과 함께한 여름 휴가 여행",
LocalDate.of(2023, 7, 1),
LocalDate.of(2023, 7, 10)
);
travelRepository.save(originTravel);
Travel travel = createAndSaveTravel(2023);
Long travelId = travel.getId();
TravelRequest updatedTravel = new TravelRequest(
"https://example.com/travels/geumohrm.jpg",
"2023 신나는 여름 휴가",
Expand All @@ -152,36 +145,69 @@ void updateTravel() {

// when
travelService.updateTravel(updatedTravel, travelId);
Travel travel = travelRepository.findById(travelId).get();
Travel foundedTravel = travelRepository.findById(travelId).get();

// then
assertAll(
() -> assertThat(travel.getId()).isEqualTo(travelId),
() -> assertThat(travel.getTitle()).isEqualTo(updatedTravel.travelTitle()),
() -> assertThat(travel.getDescription()).isEqualTo(updatedTravel.description()),
() -> assertThat(travel.getStartAt()).isEqualTo(updatedTravel.startAt()),
() -> assertThat(travel.getEndAt()).isEqualTo(updatedTravel.endAt())
() -> assertThat(foundedTravel.getId()).isEqualTo(travelId),
() -> assertThat(foundedTravel.getTitle()).isEqualTo(updatedTravel.travelTitle()),
() -> assertThat(foundedTravel.getDescription()).isEqualTo(updatedTravel.description()),
() -> assertThat(foundedTravel.getStartAt()).isEqualTo(updatedTravel.startAt()),
() -> assertThat(foundedTravel.getEndAt()).isEqualTo(updatedTravel.endAt())
);
}

private Travel createAndSaveTravel(int year) {
Travel travel = new Travel(
"https://example.com/travels/geumohrm.jpg",
year + " 여름 휴가",
"친구들과 함께한 여름 휴가 여행",
LocalDate.of(year, 7, 1),
LocalDate.of(year, 7, 10)
);
return travelRepository.save(travel);
}

@DisplayName("존재하지 않는 여행 상세를 수정하려 할 경우 예외가 발생한다.")
@Test
void failUpdateTravel() {
// given
TravelRequest travelRequest = new TravelRequest(
"https://example.com/travels/geumohrm.jpg",
"2023 여름 휴가",
"친구들과 함께한 여름 휴가 여행",
LocalDate.of(2023, 7, 1),
LocalDate.of(2023, 7, 10)
);
TravelRequest travelRequest = createTravelRequest(2023);

// when & then
assertThatThrownBy(() -> travelService.updateTravel(travelRequest, 1L))
.isInstanceOf(StaccatoException.class)
.hasMessage("요청하신 여행을 찾을 수 없어요.");
}

@DisplayName("여행 식별값을 통해 여행 상세를 삭제한다.")
@Test
void deleteTravel() {
// given
Travel travel = createAndSaveTravel(2023);

// when
travelService.deleteTravel(travel.getId());

// then
Travel foundTravel = travelRepository.findById(travel.getId()).get();
assertThat(foundTravel.getIsDeleted()).isTrue();
}

@DisplayName("방문기록이 존재하는 여행 상세에 삭제를 시도할 경우 예외가 발생한다.")
@Test
void failDeleteTravel() {
// given
Travel travel = createAndSaveTravel(2023);
Pin pin = pinRepository.save(Pin.builder().place("Sample Place").address("Sample Address").build());
visitRepository.save(Visit.builder().visitedAt(LocalDate.now()).pin(pin).travel(travel).build());

// when & then
assertThatThrownBy(() -> travelService.deleteTravel(travel.getId()))
.isInstanceOf(StaccatoException.class)
.hasMessage("해당 여행 상세에 방문 기록이 남아있어 삭제할 수 없습니다.");
}

@DisplayName("존재하지 않는 여행 상세를 조회하려고 할 경우 예외가 발생한다.")
@Test
void failReadTravel() {
Expand Down

0 comments on commit 58960dd

Please sign in to comment.