From c190ca0b280c1b0480248402aec0ffce3fb68c74 Mon Sep 17 00:00:00 2001 From: jjongwa Date: Thu, 27 Jul 2023 17:22:40 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20isPlaceUpdated=EC=97=90=20=EB=94=B0?= =?UTF-8?q?=EB=A5=B8=20item=20=EC=88=98=EC=A0=95=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trip/dto/request/ItemUpdateRequest.java | 69 +++++++++++++++++++ .../trip/presentation/ItemController.java | 9 ++- .../hanglog/trip/service/ItemService.java | 43 +++++++----- .../hanglog/trip/service/ItemServiceTest.java | 43 ++++++++++-- 4 files changed, 139 insertions(+), 25 deletions(-) create mode 100644 backend/src/main/java/hanglog/trip/dto/request/ItemUpdateRequest.java diff --git a/backend/src/main/java/hanglog/trip/dto/request/ItemUpdateRequest.java b/backend/src/main/java/hanglog/trip/dto/request/ItemUpdateRequest.java new file mode 100644 index 000000000..0ee349928 --- /dev/null +++ b/backend/src/main/java/hanglog/trip/dto/request/ItemUpdateRequest.java @@ -0,0 +1,69 @@ +package hanglog.trip.dto.request; + +import static hanglog.global.exception.ExceptionCode.INVALID_RATING; + +import hanglog.global.exception.BadRequestException; +import jakarta.validation.constraints.DecimalMax; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.util.List; +import lombok.Getter; + +@Getter +public class ItemUpdateRequest { + + @NotNull(message = "여행 아이템의 타입을 입력해주세요.") + private final Boolean itemType; + + @NotBlank(message = "여행 아이템의 제목을 입력해주세요.") + @Size(max = 50, message = "여행 아이템의 제목은 50자를 초과할 수 없습니다.") + private final String title; + + @DecimalMax(value = "5.0", message = "여행 별점은 5점을 초과할 수 없습니다.") + private final Double rating; + + @Size(max = 255, message = "여행 아이템의 메모는 255자를 초과할 수 없습니다.") + private final String memo; + + @NotNull(message = "여행 아이템이 속한 데이 로그를 입력해주세요.") + private final Long dayLogId; + + @Size(max = 10, message = "여행 아이템의 이미지는 최대 10개까지 첨부할 수 있습니다.") + private final List imageUrls; + + private final Boolean isPlaceUpdated; + + private final PlaceRequest place; + + private final ExpenseRequest expense; + + public ItemUpdateRequest( + final Boolean itemType, + final String title, + final Double rating, + final String memo, + final Long dayLogId, + final List imageUrls, + final Boolean isPlaceUpdated, + final PlaceRequest place, + final ExpenseRequest expense + ) { + validateRatingFormat(rating); + this.itemType = itemType; + this.title = title; + this.rating = rating; + this.memo = memo; + this.dayLogId = dayLogId; + this.imageUrls = imageUrls; + this.isPlaceUpdated = isPlaceUpdated; + this.place = place; + this.expense = expense; + } + + private void validateRatingFormat(final Double value) { + if (value % 0.5 != 0) { + throw new BadRequestException(INVALID_RATING); + } + } +} diff --git a/backend/src/main/java/hanglog/trip/presentation/ItemController.java b/backend/src/main/java/hanglog/trip/presentation/ItemController.java index 53b9cb466..ed87ff3d3 100644 --- a/backend/src/main/java/hanglog/trip/presentation/ItemController.java +++ b/backend/src/main/java/hanglog/trip/presentation/ItemController.java @@ -1,6 +1,7 @@ package hanglog.trip.presentation; import hanglog.trip.dto.request.ItemRequest; +import hanglog.trip.dto.request.ItemUpdateRequest; import hanglog.trip.service.ItemService; import jakarta.validation.Valid; import java.net.URI; @@ -24,7 +25,8 @@ public class ItemController { @PostMapping public ResponseEntity createItem( @PathVariable final Long tripId, - @RequestBody @Valid final ItemRequest itemRequest) { + @RequestBody @Valid final ItemRequest itemRequest + ) { final Long itemId = itemService.save(tripId, itemRequest); return ResponseEntity.created(URI.create("/trips/" + tripId + "/items/" + itemId)).build(); } @@ -33,8 +35,9 @@ public ResponseEntity createItem( public ResponseEntity updateItem( @PathVariable final Long tripId, @PathVariable final Long itemId, - @RequestBody final ItemRequest itemRequest) { - itemService.update(tripId, itemId, itemRequest); + @RequestBody final ItemUpdateRequest itemUpdateRequest + ) { + itemService.update(tripId, itemId, itemUpdateRequest); return ResponseEntity.noContent().build(); } diff --git a/backend/src/main/java/hanglog/trip/service/ItemService.java b/backend/src/main/java/hanglog/trip/service/ItemService.java index 91a4f0c93..54657a879 100644 --- a/backend/src/main/java/hanglog/trip/service/ItemService.java +++ b/backend/src/main/java/hanglog/trip/service/ItemService.java @@ -21,6 +21,7 @@ import hanglog.trip.domain.type.ItemType; import hanglog.trip.dto.request.ExpenseRequest; import hanglog.trip.dto.request.ItemRequest; +import hanglog.trip.dto.request.ItemUpdateRequest; import hanglog.trip.dto.request.PlaceRequest; import hanglog.trip.dto.response.ItemResponse; import java.util.List; @@ -49,9 +50,9 @@ public Long save(final Long tripId, final ItemRequest itemRequest) { getNewItemOrdinal(tripId), itemRequest.getRating(), itemRequest.getMemo(), - getPlaceByItemRequest(itemRequest), + getPlaceByItemRequest(itemRequest.getPlace()), dayLog, - getExpenseByItemRequest(itemRequest), + getExpenseByItemRequest(itemRequest.getExpense()), getImagesByItemRequest(itemRequest) ); validateAlreadyDeleted(item); @@ -66,32 +67,38 @@ private List getImagesByItemRequest(final ItemRequest itemRequest) { .toList(); } - public void update(final Long tripId, final Long itemId, final ItemRequest itemRequest) { - final DayLog dayLog = dayLogRepository.findById(itemRequest.getDayLogId()) + public void update(final Long tripId, final Long itemId, final ItemUpdateRequest itemUpdateRequest) { + final DayLog dayLog = dayLogRepository.findById(itemUpdateRequest.getDayLogId()) .orElseThrow(() -> new BadRequestException(NOT_FOUND_DAY_LOG_ID)); final Item item = itemRepository.findById(itemId) .orElseThrow(() -> new BadRequestException(NOT_FOUND_TRIP_ITEM_ID)); validateAlreadyDeleted(item); - final Item updateditem = new Item( + Place updatedPlace = item.getPlace(); + if (itemUpdateRequest.getIsPlaceUpdated()) { + updatedPlace = getPlaceByItemRequest(itemUpdateRequest.getPlace()); + } + + final Item updatedItem = new Item( itemId, - ItemType.getItemTypeByIsSpot(itemRequest.getItemType()), - itemRequest.getTitle(), + ItemType.getItemTypeByIsSpot(itemUpdateRequest.getItemType()), + itemUpdateRequest.getTitle(), item.getOrdinal(), - itemRequest.getRating(), - itemRequest.getMemo(), - getPlaceByItemRequest(itemRequest), + itemUpdateRequest.getRating(), + itemUpdateRequest.getMemo(), + updatedPlace, dayLog, - getExpenseByItemRequest(itemRequest) + getExpenseByItemRequest(itemUpdateRequest.getExpense()) ); - itemRepository.save(updateditem); + + itemRepository.save(updatedItem); } - private Place getPlaceByItemRequest(final ItemRequest itemRequest) { - if (itemRequest.getPlace() == null) { + private Place getPlaceByItemRequest(final PlaceRequest placeRequest) { + if (placeRequest == null) { return null; } - return createPlaceByPlaceRequest(itemRequest.getPlace()); + return createPlaceByPlaceRequest(placeRequest); } private Place createPlaceByPlaceRequest(final PlaceRequest placeRequest) { @@ -106,11 +113,11 @@ private Place createPlaceByPlaceRequest(final PlaceRequest placeRequest) { ); } - private Expense getExpenseByItemRequest(final ItemRequest itemRequest) { - if (itemRequest.getExpense() == null) { + private Expense getExpenseByItemRequest(final ExpenseRequest expenseRequest) { + if (expenseRequest == null) { return null; } - return createExpenseByExpenseRequest(itemRequest.getExpense()); + return createExpenseByExpenseRequest(expenseRequest); } private Expense createExpenseByExpenseRequest(final ExpenseRequest expenseRequest) { diff --git a/backend/src/test/java/hanglog/trip/service/ItemServiceTest.java b/backend/src/test/java/hanglog/trip/service/ItemServiceTest.java index 30ea0eb2a..26cf92b26 100644 --- a/backend/src/test/java/hanglog/trip/service/ItemServiceTest.java +++ b/backend/src/test/java/hanglog/trip/service/ItemServiceTest.java @@ -17,6 +17,7 @@ import hanglog.trip.domain.type.ItemType; import hanglog.trip.dto.request.ExpenseRequest; import hanglog.trip.dto.request.ItemRequest; +import hanglog.trip.dto.request.ItemUpdateRequest; import hanglog.trip.dto.request.PlaceRequest; import hanglog.trip.dto.response.ItemResponse; import hanglog.trip.fixture.ExpenseFixture; @@ -88,9 +89,42 @@ void save() { assertThat(actualId).isEqualTo(1L); } - @DisplayName("여행 아이템의 정보를 수정한다.") + @DisplayName("여행 아이템의 정보를 수정한다. - 장소가 바뀌지 않은 경우") @Test - void update() { + void update_PlaceNotChange() { + // given + final ExpenseRequest expenseRequest = new ExpenseRequest("EURO", 10000.0, 1L); + final ItemUpdateRequest itemUpdateRequest = new ItemUpdateRequest( + true, + "에펠탑", + 4.5, + "에펠탑을 방문", + 1L, + List.of("imageUrl"), + false, + null, + expenseRequest + ); + + given(itemRepository.save(any())) + .willReturn(ItemFixture.LONDON_EYE_ITEM); + given(itemRepository.findById(any())) + .willReturn(Optional.of(ItemFixture.LONDON_EYE_ITEM)); + given(categoryRepository.findById(any())) + .willReturn(Optional.of(new Category(1L, "문화", "culture"))); + given(dayLogRepository.findById(any())) + .willReturn(Optional.of(new DayLog("첫날", 1, TripFixture.LONDON_TRIP))); + + // when + itemService.update(1L, 1L, itemUpdateRequest); + + // then + verify(itemRepository).save(any()); + } + + @DisplayName("여행 아이템의 정보를 수정한다. - 장소가 바뀐 경우") + @Test + void update_PlaceChange() { // given final PlaceRequest placeRequest = new PlaceRequest( "에펠탑", @@ -99,13 +133,14 @@ void update() { List.of("culture") ); final ExpenseRequest expenseRequest = new ExpenseRequest("EURO", 10000.0, 1L); - final ItemRequest itemRequest = new ItemRequest( + final ItemUpdateRequest itemUpdateRequest = new ItemUpdateRequest( true, "에펠탑", 4.5, "에펠탑을 방문", 1L, List.of("imageUrl"), + false, placeRequest, expenseRequest ); @@ -120,7 +155,7 @@ void update() { .willReturn(Optional.of(new DayLog("첫날", 1, TripFixture.LONDON_TRIP))); // when - itemService.update(1L, 1L, itemRequest); + itemService.update(1L, 1L, itemUpdateRequest); // then verify(itemRepository).save(any());