From 26b1e99469326ea0e686376a0accddcb1eed9bcc Mon Sep 17 00:00:00 2001 From: koo Date: Wed, 15 Feb 2023 23:54:20 +0900 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20ArchiveMapper=20=EA=B0=9D=EC=B2=B4?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kilometer/backend/controller/ArchiveController.java | 2 +- .../kilometer/domain/archive/service/ArchiveMapper.java | 9 +++++++++ .../domain/archive/{ => service}/ArchiveService.java | 6 +++++- .../main/java/com/kilometer/domain/item/ItemService.java | 2 +- .../com/kilometer/domain/archive/ArchiveServiceTest.java | 1 + 5 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveMapper.java rename kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/{ => service}/ArchiveService.java (98%) diff --git a/kilometer-backend-api/src/main/java/com/kilometer/backend/controller/ArchiveController.java b/kilometer-backend-api/src/main/java/com/kilometer/backend/controller/ArchiveController.java index bf8f19de..1e4f48ef 100644 --- a/kilometer-backend-api/src/main/java/com/kilometer/backend/controller/ArchiveController.java +++ b/kilometer-backend-api/src/main/java/com/kilometer/backend/controller/ArchiveController.java @@ -1,6 +1,6 @@ package com.kilometer.backend.controller; -import com.kilometer.domain.archive.ArchiveService; +import com.kilometer.domain.archive.service.ArchiveService; import com.kilometer.domain.archive.dto.ArchiveDeleteResponse; import com.kilometer.domain.archive.dto.ArchiveDetailResponse; import com.kilometer.domain.archive.dto.ArchiveInfo; diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveMapper.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveMapper.java new file mode 100644 index 00000000..d90162fe --- /dev/null +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveMapper.java @@ -0,0 +1,9 @@ +package com.kilometer.domain.archive.service; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional(readOnly = true) +public class ArchiveMapper { +} diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveService.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveService.java similarity index 98% rename from kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveService.java rename to kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveService.java index cf057565..9e85c47e 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveService.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveService.java @@ -1,6 +1,9 @@ -package com.kilometer.domain.archive; +package com.kilometer.domain.archive.service; import com.google.common.base.Preconditions; +import com.kilometer.domain.archive.ArchiveAggregateConverter; +import com.kilometer.domain.archive.ArchiveEntity; +import com.kilometer.domain.archive.ArchiveRepository; import com.kilometer.domain.archive.archiveImage.ArchiveImageEntity; import com.kilometer.domain.archive.archiveImage.ArchiveImageService; import com.kilometer.domain.archive.domain.Archive; @@ -59,6 +62,7 @@ public class ArchiveService { private final PagingStatusService pagingStatusService; private final ArchiveAggregateConverter archiveAggregateConverter; private final LikeService likeService; + private final ArchiveMapper archiveMapper; @Transactional public ArchiveInfo save(Long userId, ArchiveRequest archiveRequest) { diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/item/ItemService.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/item/ItemService.java index 6f67c91f..627784d7 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/item/ItemService.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/item/ItemService.java @@ -1,7 +1,7 @@ package com.kilometer.domain.item; import com.google.common.base.Preconditions; -import com.kilometer.domain.archive.ArchiveService; +import com.kilometer.domain.archive.service.ArchiveService; import com.kilometer.domain.item.domain.Item; import com.kilometer.domain.item.dto.DetailResponse; import com.kilometer.domain.item.dto.ItemInfoDto; diff --git a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/ArchiveServiceTest.java b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/ArchiveServiceTest.java index c10eece6..e89da02b 100644 --- a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/ArchiveServiceTest.java +++ b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/ArchiveServiceTest.java @@ -17,6 +17,7 @@ import com.kilometer.domain.archive.exception.ArchiveUnauthorizedException; import com.kilometer.domain.archive.exception.ArchiveValidationException; import com.kilometer.domain.archive.request.ArchiveRequest; +import com.kilometer.domain.archive.service.ArchiveService; import com.kilometer.domain.item.ItemEntity; import com.kilometer.domain.item.ItemRepository; import com.kilometer.domain.item.enumType.ExhibitionType; From 183a305a3a54379bdd9a3269114fbc23532f59f9 Mon Sep 17 00:00:00 2001 From: koo Date: Thu, 16 Feb 2023 00:27:35 +0900 Subject: [PATCH 2/6] =?UTF-8?q?refactor:=20=EC=95=84=EC=B9=B4=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=20=EC=83=9D=EC=84=B1=EA=B3=BC=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=ED=95=98=EC=97=AC=20Repository=20=EC=A0=91=EA=B7=BC=EC=9D=B4?= =?UTF-8?q?=20=ED=95=84=EC=9A=94=ED=95=9C=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=EC=9D=84=20ArchiveEntityMapper=20=EA=B0=9D=EC=B2=B4?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/archive/service/ArchiveMapper.java | 38 ++++++ .../archive/service/ArchiveService.java | 25 +--- .../kilometer/domain/item/ItemRepository.java | 3 +- .../domain/archive/ArchiveServiceTest.java | 11 +- .../archive/service/ArchiveMapperTest.java | 122 ++++++++++++++++++ 5 files changed, 168 insertions(+), 31 deletions(-) create mode 100644 kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveMapperTest.java diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveMapper.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveMapper.java index d90162fe..417541ac 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveMapper.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveMapper.java @@ -1,9 +1,47 @@ package com.kilometer.domain.archive.service; +import com.kilometer.domain.archive.ArchiveRepository; +import com.kilometer.domain.archive.domain.Archive; +import com.kilometer.domain.archive.exception.ArchiveValidationException; +import com.kilometer.domain.archive.request.ArchiveRequest; +import com.kilometer.domain.item.ItemRepository; +import com.kilometer.domain.item.enumType.ExposureType; +import com.kilometer.domain.item.exception.ItemExposureOffException; +import com.kilometer.domain.item.exception.ItemNotFoundException; +import com.kilometer.domain.user.User; +import com.kilometer.domain.user.UserRepository; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service @Transactional(readOnly = true) +@RequiredArgsConstructor public class ArchiveMapper { + + private final ArchiveRepository archiveRepository; + private final UserRepository userRepository; + private final ItemRepository itemRepository; + + public Archive mapToArchive(Long userId, ArchiveRequest archiveRequest) { + Archive archive = archiveRequest.toDomain(); + User user = userRepository.findById(userId) + .orElseThrow(() -> new IllegalArgumentException("저장되지 않은 사용자 입니다.")); + + if (archiveRepository.existsByItemIdAndUserId(archiveRequest.getItemId(), userId)) { + throw new ArchiveValidationException(String.format("이미 등록한 Archive가 있습니다. sItemId : %d / UserId : %d", + archiveRequest.getItemId(), userId)); + } + + itemRepository.findExposureById(archiveRequest.getItemId()) + .map(mapping -> { + if (mapping.getExposureType() == ExposureType.OFF) { + throw new ItemExposureOffException(); + } + return mapping; + }) + .orElseThrow(ItemNotFoundException::new); + + return archive; + } } diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveService.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveService.java index 9e85c47e..4b40e11b 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveService.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveService.java @@ -29,9 +29,6 @@ import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceService; import com.kilometer.domain.item.ItemEntity; import com.kilometer.domain.item.ItemRepository; -import com.kilometer.domain.item.enumType.ExposureType; -import com.kilometer.domain.item.exception.ItemExposureOffException; -import com.kilometer.domain.item.exception.ItemNotFoundException; import com.kilometer.domain.paging.PagingStatusService; import com.kilometer.domain.paging.RequestPagingStatus; import com.kilometer.domain.paging.ResponsePagingStatus; @@ -55,7 +52,6 @@ public class ArchiveService { private final UserService userService; - private final ItemRepository itemRepository; private final ArchiveRepository archiveRepository; private final ArchiveImageService archiveImageService; private final UserVisitPlaceService userVisitPlaceService; @@ -66,22 +62,11 @@ public class ArchiveService { @Transactional public ArchiveInfo save(Long userId, ArchiveRequest archiveRequest) { - validateArchiveRequest(archiveRequest, userId); - - Archive archive = archiveRequest.toDomain(); + Archive archive = archiveMapper.mapToArchive(userId, archiveRequest); UserResponse userResponse = userService.findById(userId) .orElseThrow(() -> new IllegalArgumentException("잘못된 사용자 정보 입니다.")); - itemRepository.findExposureById(archiveRequest.getItemId()) - .map(mapping -> { - if (mapping.getExposureType() == ExposureType.OFF) { - throw new ItemExposureOffException(); - } - return mapping; - }) - .orElseThrow(ItemNotFoundException::new); - ArchiveEntity archiveEntity = saveArchive(archiveRequest, userId, archiveRequest.getItemId()); Long archiveId = archiveEntity.getId(); @@ -223,14 +208,6 @@ public Long findArchiveIdByItemIdAndUserId(Long itemId, Long userId) { .orElse(null); } - - private void validateArchiveRequest(ArchiveRequest archiveRequest, Long userId) { - Preconditions.checkArgument( - !archiveRepository.existsByItemIdAndUserId(archiveRequest.getItemId(), userId), - String.format("기 등록한 Archive가 있습니다. sItemId : %d / UserId : %d", - archiveRequest.getItemId(), userId)); - } - private ArchiveEntity saveArchive(ArchiveRequest archiveRequest, Long userId, Long itemId) { ArchiveEntity archiveEntity = archiveRequest.makeArchive(); archiveEntity.setUser(User.builder().id(userId).build()); diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/item/ItemRepository.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/item/ItemRepository.java index 57723a82..5d1f4e7d 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/item/ItemRepository.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/item/ItemRepository.java @@ -1,9 +1,8 @@ package com.kilometer.domain.item; -import org.springframework.data.jpa.repository.JpaRepository; - import java.util.List; import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; public interface ItemRepository extends JpaRepository, ItemRepositoryCustom { diff --git a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/ArchiveServiceTest.java b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/ArchiveServiceTest.java index e89da02b..e352eca9 100644 --- a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/ArchiveServiceTest.java +++ b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/ArchiveServiceTest.java @@ -72,19 +72,20 @@ void saveArchive() { } @Test - @DisplayName("아카이브 정보를 등록할때, 이미 등록한 Archive를 다시 등록하려 하면 예외가 발생한다..") + @DisplayName("아카이브 정보를 등록할때, 이미 등록한 Archive를 다시 등록하려 하면 예외가 발생한다.") void saveArchive_duplicate() { // given User 회원 = 회원가입을_한다(); ItemEntity 아이템 = 아이템을_등록한다(); ArchiveRequest request = new ArchiveRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); - - archiveService.save(회원.getId(), request); + ArchiveInfo 아카이브_생성_응답 = archiveService.save(회원.getId(), request); // when & then assertThatThrownBy(() -> archiveService.save(회원.getId(), request)) - .isInstanceOf(IllegalArgumentException.class); + .isInstanceOf(ArchiveValidationException.class) + .hasMessage( + String.format("이미 등록한 Archive가 있습니다. sItemId : %d / UserId : %d", 아카이브_생성_응답.getId(), 회원.getId())); } @Test @@ -132,7 +133,7 @@ void saveArchive_notExistUser() { // when & then assertThatThrownBy(() -> archiveService.save(invalidUserId, request)) .isInstanceOf(IllegalArgumentException.class) - .hasMessage("잘못된 사용자 정보 입니다."); + .hasMessage("저장되지 않은 사용자 입니다."); } @Test diff --git a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveMapperTest.java b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveMapperTest.java new file mode 100644 index 00000000..f56660d3 --- /dev/null +++ b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveMapperTest.java @@ -0,0 +1,122 @@ +package com.kilometer.domain.archive.service; + +import static com.kilometer.common.statics.Statics.아카이브_공개_설정; +import static com.kilometer.common.statics.Statics.아카이브_별점; +import static com.kilometer.common.statics.Statics.아카이브_코멘트; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import com.kilometer.common.annotation.SpringTestWithData; +import com.kilometer.domain.archive.dto.ArchiveInfo; +import com.kilometer.domain.archive.dto.PlaceInfo; +import com.kilometer.domain.archive.exception.ArchiveValidationException; +import com.kilometer.domain.archive.request.ArchiveRequest; +import com.kilometer.domain.item.ItemEntity; +import com.kilometer.domain.item.ItemRepository; +import com.kilometer.domain.item.enumType.ExhibitionType; +import com.kilometer.domain.item.enumType.ExposureType; +import com.kilometer.domain.item.enumType.FeeType; +import com.kilometer.domain.item.enumType.RegionType; +import com.kilometer.domain.item.exception.ItemExposureOffException; +import com.kilometer.domain.user.User; +import com.kilometer.domain.user.UserRepository; +import com.kilometer.exception.KilometerErrorCode; +import java.time.LocalDate; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +@SpringTestWithData +class ArchiveMapperTest { + + private final List 방문_사진 = List.of("photoUrls"); + private final List 근처_맛집 = List.of(new PlaceInfo("FOOD", "맛집", "address", "roadAddress")); + + @Autowired + private ArchiveMapper archiveMapper; + + @Autowired + private ArchiveService archiveService; + + @Autowired + private UserRepository userRepository; + + @Autowired + private ItemRepository itemRepository; + + @Test + @DisplayName("아카이브 엔티티를 매핑 할 때, 사용자가 존재하지 않으면 예외가 발생한다.") + void mapToArchiveEntity() { + // given + Long invalidUserId = 1L; + + ItemEntity 아이템 = 아이템을_등록한다(); + ArchiveRequest request = new ArchiveRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + 근처_맛집); + + // when & then + assertThatThrownBy(() -> archiveMapper.mapToArchive(invalidUserId, request)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("저장되지 않은 사용자 입니다."); + } + + @Test + @DisplayName("아카이브 정보를 등록할때, 이미 등록한 Archive를 다시 등록하려 하면 예외가 발생한다.") + void saveArchive_duplicate() { + // given + User 회원 = 회원가입을_한다(); + ItemEntity 아이템 = 아이템을_등록한다(); + ArchiveRequest request = new ArchiveRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + 근처_맛집); + ArchiveInfo 아카이브_생성_응답 = archiveService.save(회원.getId(), request); + + // when & then + assertThatThrownBy(() -> archiveMapper.mapToArchive(회원.getId(), request)) + .isInstanceOf(ArchiveValidationException.class) + .hasMessage( + String.format("이미 등록한 Archive가 있습니다. sItemId : %d / UserId : %d", 아카이브_생성_응답.getId(), 회원.getId())); + } + + @Test + @DisplayName("아카이브 정보를 등록할때, 미전시 전시글에 아카이브를 등록하려 하면 예외가 발생한다.") + void saveArchive_exposureOffItem() { + // given + User user = 회원가입을_한다(); + ItemEntity item = ItemEntity.builder().exposureType(ExposureType.OFF).build(); + itemRepository.save(item); + ArchiveRequest request = new ArchiveRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); + + // when + ItemExposureOffException actual = assertThrows(ItemExposureOffException.class, + () -> archiveMapper.mapToArchive(user.getId(), request)); + + // then + assertEquals(actual.getErrorCode(), KilometerErrorCode.ITEM_EXPOSURE_OFF); + } + + private User 회원가입을_한다() { + User user = User.builder() + .name("user") + .email("user@email.com") + .build(); + return userRepository.save(user); + } + + private ItemEntity 아이템을_등록한다() { + ItemEntity item = ItemEntity.builder() + .exposureType(ExposureType.ON) + .exhibitionType(ExhibitionType.EXHIBITION) + .regionType(RegionType.CHUNGCHEONG) + .feeType(FeeType.FREE) + .listImageUrl("listImageUrl") + .thumbnailImageUrl("thumbnailImageUrl") + .title("title") + .placeName("placeName") + .startDate(LocalDate.now()) + .endDate(LocalDate.now()) + .build(); + return itemRepository.save(item); + } +} From 575089d353ca6592b0111bdd627c944ba308cee6 Mon Sep 17 00:00:00 2001 From: koo Date: Thu, 16 Feb 2023 01:09:17 +0900 Subject: [PATCH 3/6] =?UTF-8?q?refactor:=20=EC=95=84=EC=B9=B4=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=EB=A5=BC=20=EB=93=B1=EB=A1=9D=ED=95=98=EB=8A=94=20API?= =?UTF-8?q?=20=EB=82=B4=EB=B6=80=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../archive/ArchiveAggregateConverter.java | 29 ++++++++------- .../domain/archive/ArchiveEntity.java | 20 ++++++++++ .../archiveImage/ArchiveImageEntity.java | 2 +- .../archiveImage/ArchiveImageService.java | 2 +- .../domain/archive/domain/Archive.java | 28 ++++++++++++++ .../domain/archive/domain/ArchiveImage.java | 7 ++++ .../domain/userVisitPlace/UserVisitPlace.java | 10 +++++ ...veMapper.java => ArchiveEntityMapper.java} | 37 ++++++++++++------- .../archive/service/ArchiveService.java | 31 ++++++---------- .../userVisitPlace/UserVisitPlaceEntity.java | 2 +- .../userVisitPlace/UserVisitPlaceService.java | 2 +- ...Test.java => ArchiveEntityMapperTest.java} | 30 ++------------- 12 files changed, 124 insertions(+), 76 deletions(-) rename kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/{ArchiveMapper.java => ArchiveEntityMapper.java} (53%) rename kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/{ArchiveMapperTest.java => ArchiveEntityMapperTest.java} (74%) diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveAggregateConverter.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveAggregateConverter.java index 1309ca48..ba69ef71 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveAggregateConverter.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveAggregateConverter.java @@ -8,22 +8,20 @@ import com.kilometer.domain.archive.dto.ItemArchiveDto; import com.kilometer.domain.archive.dto.MyArchiveDto; import com.kilometer.domain.archive.dto.MyArchiveInfo; +import com.kilometer.domain.archive.like.dto.ArchiveLike; +import com.kilometer.domain.archive.like.dto.ArchiveLikeGenerator; import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceEntity; import com.kilometer.domain.badge.ItemBadge; import com.kilometer.domain.badge.ItemBadgeGenerator; import com.kilometer.domain.item.dto.ItemSummary; import com.kilometer.domain.item.enumType.ExhibitionType; -import com.kilometer.domain.archive.like.dto.ArchiveLike; -import com.kilometer.domain.archive.like.dto.ArchiveLikeGenerator; import com.kilometer.domain.linkInfo.LinkInfo; -import com.kilometer.domain.user.dto.UserResponse; +import com.kilometer.domain.user.User; import com.kilometer.domain.util.ApiUrlUtils; import com.kilometer.domain.util.FrontUrlUtils; - import java.util.List; import java.util.Map; import java.util.stream.Collectors; - import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; @@ -35,7 +33,8 @@ public class ArchiveAggregateConverter { private final ItemBadgeGenerator itemBadgeGenerator; public ArchiveInfo convertArchiveInfo(ItemArchiveDto itemArchiveDto, - List archiveImageEntities, List userVisitPlaceEntities) { + List archiveImageEntities, + List userVisitPlaceEntities) { Map placeTypes = convertFoodAndCafe(userVisitPlaceEntities); @@ -86,20 +85,21 @@ public ArchiveInfo convertArchiveInfo(ArchiveEntity archiveEntity, .build(); } - public ArchiveInfo convertArchiveInfo(ArchiveEntity archiveEntity, UserResponse userResponse, - List archiveImageEntities, List userVisitPlaceEntities) { + public ArchiveInfo convertArchiveInfo(ArchiveEntity archiveEntity) { - Map placeTypes = convertFoodAndCafe(userVisitPlaceEntities); + Map placeTypes = convertFoodAndCafe(archiveEntity.getUserVisitPlaces()); ArchiveLike archiveLike = archiveLikeGenerator.generateArchiveLike(archiveEntity.getId()); - List photoUrls = archiveImageEntities.stream() + List photoUrls = archiveEntity.getArchiveImages().stream() .map(ArchiveImageEntity::getImageUrl) .collect(Collectors.toList()); + User user = archiveEntity.getUser(); + return ArchiveInfo.builder() .id(archiveEntity.getId()) - .userProfileUrl(userResponse.getImageUrl()) - .userName(userResponse.getName()) + .userProfileUrl(user.getImageUrl()) + .userName(user.getName()) .updatedAt(archiveEntity.getUpdatedAt()) .starRating(archiveEntity.getStarRating()) .likeCount(archiveEntity.getLikeCount()) @@ -112,7 +112,7 @@ public ArchiveInfo convertArchiveInfo(ArchiveEntity archiveEntity, UserResponse } public MyArchiveInfo convertMyArchiveInfo(MyArchiveDto myArchiveDto, - boolean existImages, List userVisitPlaceEntities) { + boolean existImages, List userVisitPlaceEntities) { ItemBadge itemBadge = itemBadgeGenerator.generateTypeItemBadge(ExhibitionType.EXHIBITION); @@ -129,7 +129,8 @@ public MyArchiveInfo convertMyArchiveInfo(MyArchiveDto myArchiveDto, } public ArchiveDetailResponse convertArchiveDetail(ArchiveDetailDto archiveDetailDto, - List visitPlaces, List archiveImageEntities) { + List visitPlaces, + List archiveImageEntities) { ItemBadge itemBadge = itemBadgeGenerator.generateTypeItemBadge( archiveDetailDto.getItemExhibitionType()); Map placeTypes = convertFoodAndCafe(visitPlaces); diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveEntity.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveEntity.java index 5c261cdf..23f27e02 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveEntity.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveEntity.java @@ -1,9 +1,12 @@ package com.kilometer.domain.archive; +import com.kilometer.domain.archive.archiveImage.ArchiveImageEntity; import com.kilometer.domain.archive.request.ArchiveRequest; +import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceEntity; import com.kilometer.domain.item.ItemEntity; import com.kilometer.domain.user.User; import java.time.LocalDateTime; +import java.util.List; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; @@ -12,6 +15,7 @@ import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; import javax.persistence.Table; import lombok.AccessLevel; import lombok.AllArgsConstructor; @@ -65,6 +69,22 @@ public class ArchiveEntity { @JoinColumn(name = "item") private ItemEntity item; + @OneToMany(mappedBy = "archiveEntity") + private List archiveImages; + + @OneToMany(mappedBy = "archiveEntity") + private List userVisitPlaces; + + public void addArchiveImages(final List archiveImages) { + this.archiveImages = archiveImages; + archiveImages.forEach(archiveImage -> archiveImage.initArchiveEntity(this)); + } + + public void addUserVisitPlaces(final List userVisitPlaces) { + this.userVisitPlaces = userVisitPlaces; + userVisitPlaces.forEach(userVisitPlace -> userVisitPlace.initArchiveEntity(this)); + } + public void setUser(User user) { this.user = user; } diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/archiveImage/ArchiveImageEntity.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/archiveImage/ArchiveImageEntity.java index 6bf63e82..fc1bf42a 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/archiveImage/ArchiveImageEntity.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/archiveImage/ArchiveImageEntity.java @@ -47,7 +47,7 @@ public class ArchiveImageEntity { @JoinColumn(name = "archive") private ArchiveEntity archiveEntity; - public void setArchiveEntity(ArchiveEntity archiveEntity) { + public void initArchiveEntity(ArchiveEntity archiveEntity) { this.archiveEntity = archiveEntity; } } diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/archiveImage/ArchiveImageService.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/archiveImage/ArchiveImageService.java index 63136075..3372519e 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/archiveImage/ArchiveImageService.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/archiveImage/ArchiveImageService.java @@ -23,7 +23,7 @@ public List saveAll(List archiveImageEnt return List.of(); } ArchiveEntity archiveEntity = ArchiveEntity.builder().id(archiveId).build(); - archiveImageEntities.forEach(archiveImage -> archiveImage.setArchiveEntity(archiveEntity)); + archiveImageEntities.forEach(archiveImage -> archiveImage.initArchiveEntity(archiveEntity)); return archiveImageRepository.saveAll(archiveImageEntities); } @Transactional diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/domain/Archive.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/domain/Archive.java index 49065cfd..b1a9226c 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/domain/Archive.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/domain/Archive.java @@ -1,10 +1,16 @@ package com.kilometer.domain.archive.domain; +import com.kilometer.domain.archive.ArchiveEntity; +import com.kilometer.domain.archive.archiveImage.ArchiveImageEntity; import com.kilometer.domain.archive.domain.archiveFilter.ArchiveFilter; import com.kilometer.domain.archive.domain.userVisitPlace.UserVisitPlace; import com.kilometer.domain.archive.exception.ArchiveValidationException; +import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceEntity; +import com.kilometer.domain.item.ItemEntity; +import com.kilometer.domain.user.User; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import lombok.Getter; @Getter @@ -51,4 +57,26 @@ private static void validateStarRating(final int starRating) { throw new ArchiveValidationException("별점은 0~5 사이의 양수이어야 합니다."); } } + + public ArchiveEntity toEntity(final User user, final ItemEntity itemEntity) { + return ArchiveEntity.builder() + .comment(this.getComment()) + .starRating(this.getStarRating()) + .isVisibleAtItem(this.isVisibleAtItem()) + .user(user) + .item(itemEntity) + .build(); + } + + public List createArchiveImageEntities() { + return this.archiveImages.stream() + .map(ArchiveImage::toEntity) + .collect(Collectors.toList()); + } + + public List createUserVisitPlaceEntities() { + return this.userVisitPlaces.stream() + .map(UserVisitPlace::toEntity) + .collect(Collectors.toList()); + } } diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/domain/ArchiveImage.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/domain/ArchiveImage.java index 188e6094..feba2d69 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/domain/ArchiveImage.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/domain/ArchiveImage.java @@ -1,5 +1,6 @@ package com.kilometer.domain.archive.domain; +import com.kilometer.domain.archive.archiveImage.ArchiveImageEntity; import com.kilometer.domain.archive.exception.ArchiveValidationException; import lombok.Getter; @@ -22,4 +23,10 @@ private static void validateImageUrl(final String imageUrl) { throw new ArchiveValidationException("이미지 링크가 없습니다."); } } + + public ArchiveImageEntity toEntity() { + return ArchiveImageEntity.builder() + .imageUrl(this.imageUrl) + .build(); + } } diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/domain/userVisitPlace/UserVisitPlace.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/domain/userVisitPlace/UserVisitPlace.java index a582f225..8698258c 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/domain/userVisitPlace/UserVisitPlace.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/domain/userVisitPlace/UserVisitPlace.java @@ -1,6 +1,7 @@ package com.kilometer.domain.archive.domain.userVisitPlace; import com.kilometer.domain.archive.exception.ArchiveValidationException; +import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceEntity; import lombok.Getter; @Getter @@ -36,4 +37,13 @@ private static void validate(final String placeName, final String address, final throw new ArchiveValidationException("입력된 도로명 주소가 없습니다."); } } + + public UserVisitPlaceEntity toEntity() { + return UserVisitPlaceEntity.builder() + .placeType(this.placeType) + .placeName(this.placeName) + .address(this.address) + .roadAddress(this.roadAddress) + .build(); + } } diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveMapper.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveEntityMapper.java similarity index 53% rename from kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveMapper.java rename to kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveEntityMapper.java index 417541ac..40653a06 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveMapper.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveEntityMapper.java @@ -1,9 +1,9 @@ package com.kilometer.domain.archive.service; -import com.kilometer.domain.archive.ArchiveRepository; +import com.kilometer.domain.archive.ArchiveEntity; import com.kilometer.domain.archive.domain.Archive; -import com.kilometer.domain.archive.exception.ArchiveValidationException; import com.kilometer.domain.archive.request.ArchiveRequest; +import com.kilometer.domain.item.ItemEntity; import com.kilometer.domain.item.ItemRepository; import com.kilometer.domain.item.enumType.ExposureType; import com.kilometer.domain.item.exception.ItemExposureOffException; @@ -17,23 +17,33 @@ @Service @Transactional(readOnly = true) @RequiredArgsConstructor -public class ArchiveMapper { +public class ArchiveEntityMapper { - private final ArchiveRepository archiveRepository; private final UserRepository userRepository; private final ItemRepository itemRepository; - public Archive mapToArchive(Long userId, ArchiveRequest archiveRequest) { + public ArchiveEntity mapToArchiveEntity(final Long userId, final ArchiveRequest archiveRequest) { Archive archive = archiveRequest.toDomain(); - User user = userRepository.findById(userId) - .orElseThrow(() -> new IllegalArgumentException("저장되지 않은 사용자 입니다.")); + + ArchiveEntity archiveEntity = createArchiveEntity(userId, archiveRequest.getItemId(), archive); + archiveEntity.addArchiveImages(archive.createArchiveImageEntities()); + archiveEntity.addUserVisitPlaces(archive.createUserVisitPlaceEntities()); + return archiveEntity; + } - if (archiveRepository.existsByItemIdAndUserId(archiveRequest.getItemId(), userId)) { - throw new ArchiveValidationException(String.format("이미 등록한 Archive가 있습니다. sItemId : %d / UserId : %d", - archiveRequest.getItemId(), userId)); - } + private ArchiveEntity createArchiveEntity(final Long userId, final Long itemId, final Archive archive) { + User user = getUser(userId); + ItemEntity itemEntity = getItem(itemId); + return archive.toEntity(user, itemEntity); + } - itemRepository.findExposureById(archiveRequest.getItemId()) + private User getUser(final Long userId) { + return userRepository.findById(userId) + .orElseThrow(() -> new IllegalArgumentException("저장되지 않은 사용자 입니다.")); + } + + private ItemEntity getItem(final Long itemId) { + itemRepository.findExposureById(itemId) .map(mapping -> { if (mapping.getExposureType() == ExposureType.OFF) { throw new ItemExposureOffException(); @@ -42,6 +52,7 @@ public Archive mapToArchive(Long userId, ArchiveRequest archiveRequest) { }) .orElseThrow(ItemNotFoundException::new); - return archive; + return itemRepository.findById(itemId) + .orElseThrow(ItemNotFoundException::new); } } diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveService.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveService.java index 4b40e11b..15ef3b1e 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveService.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveService.java @@ -20,6 +20,7 @@ import com.kilometer.domain.archive.dto.MyArchiveResponse; import com.kilometer.domain.archive.exception.ArchiveNotFoundException; import com.kilometer.domain.archive.exception.ArchiveUnauthorizedException; +import com.kilometer.domain.archive.exception.ArchiveValidationException; import com.kilometer.domain.archive.generator.ArchiveRatingCalculator; import com.kilometer.domain.archive.like.LikeService; import com.kilometer.domain.archive.like.dto.LikeDto; @@ -28,13 +29,10 @@ import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceEntity; import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceService; import com.kilometer.domain.item.ItemEntity; -import com.kilometer.domain.item.ItemRepository; import com.kilometer.domain.paging.PagingStatusService; import com.kilometer.domain.paging.RequestPagingStatus; import com.kilometer.domain.paging.ResponsePagingStatus; import com.kilometer.domain.user.User; -import com.kilometer.domain.user.UserService; -import com.kilometer.domain.user.dto.UserResponse; import com.kilometer.domain.util.FrontUrlUtils; import java.util.List; import java.util.Objects; @@ -51,32 +49,27 @@ @RequiredArgsConstructor public class ArchiveService { - private final UserService userService; private final ArchiveRepository archiveRepository; private final ArchiveImageService archiveImageService; private final UserVisitPlaceService userVisitPlaceService; private final PagingStatusService pagingStatusService; private final ArchiveAggregateConverter archiveAggregateConverter; private final LikeService likeService; - private final ArchiveMapper archiveMapper; + private final ArchiveEntityMapper archiveEntityMapper; @Transactional public ArchiveInfo save(Long userId, ArchiveRequest archiveRequest) { - Archive archive = archiveMapper.mapToArchive(userId, archiveRequest); - - UserResponse userResponse = userService.findById(userId) - .orElseThrow(() -> new IllegalArgumentException("잘못된 사용자 정보 입니다.")); - - ArchiveEntity archiveEntity = saveArchive(archiveRequest, userId, archiveRequest.getItemId()); - - Long archiveId = archiveEntity.getId(); - List archiveImageEntities = archiveRequest.makeArchiveImages(); - List userVisitPlaceEntities = archiveRequest.makeVisitedPlace(); - archiveImageService.saveAll(archiveImageEntities, archiveId); - userVisitPlaceService.saveAll(userVisitPlaceEntities, archiveId); + validateNotDuplicateArchive(userId, archiveRequest.getItemId()); + ArchiveEntity archiveEntity = archiveEntityMapper.mapToArchiveEntity(userId, archiveRequest); + ArchiveEntity savedArchiveEntity = archiveRepository.save(archiveEntity); + return archiveAggregateConverter.convertArchiveInfo(savedArchiveEntity); + } - return archiveAggregateConverter.convertArchiveInfo(archiveEntity, userResponse, archiveImageEntities, - userVisitPlaceEntities); + private void validateNotDuplicateArchive(Long userId, Long itemId) { + if (archiveRepository.existsByItemIdAndUserId(itemId, userId)) { + throw new ArchiveValidationException(String.format("이미 등록한 Archive가 있습니다. sItemId : %d / UserId : %d", + itemId, userId)); + } } @Transactional diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/userVisitPlace/UserVisitPlaceEntity.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/userVisitPlace/UserVisitPlaceEntity.java index 7f01e028..2551bc84 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/userVisitPlace/UserVisitPlaceEntity.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/userVisitPlace/UserVisitPlaceEntity.java @@ -57,7 +57,7 @@ public class UserVisitPlaceEntity { @Builder.Default private boolean isDeleted = false; - public void setArchiveEntity(ArchiveEntity archiveEntity) { + public void initArchiveEntity(ArchiveEntity archiveEntity) { this.archiveEntity = archiveEntity; } } diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/userVisitPlace/UserVisitPlaceService.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/userVisitPlace/UserVisitPlaceService.java index 59adcccf..d1333ea0 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/userVisitPlace/UserVisitPlaceService.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/userVisitPlace/UserVisitPlaceService.java @@ -18,7 +18,7 @@ public class UserVisitPlaceService { public List saveAll(List userVisitPlaceEntities, Long archiveId) { if (!userVisitPlaceEntities.isEmpty()) { ArchiveEntity archiveEntity = ArchiveEntity.builder().id(archiveId).build(); - userVisitPlaceEntities.forEach(userVisitPlace -> userVisitPlace.setArchiveEntity(archiveEntity)); + userVisitPlaceEntities.forEach(userVisitPlace -> userVisitPlace.initArchiveEntity(archiveEntity)); userVisitPlaceRepository.saveAll(userVisitPlaceEntities); } return userVisitPlaceEntities; diff --git a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveMapperTest.java b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveEntityMapperTest.java similarity index 74% rename from kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveMapperTest.java rename to kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveEntityMapperTest.java index f56660d3..8a8d4555 100644 --- a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveMapperTest.java +++ b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveEntityMapperTest.java @@ -8,9 +8,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import com.kilometer.common.annotation.SpringTestWithData; -import com.kilometer.domain.archive.dto.ArchiveInfo; import com.kilometer.domain.archive.dto.PlaceInfo; -import com.kilometer.domain.archive.exception.ArchiveValidationException; import com.kilometer.domain.archive.request.ArchiveRequest; import com.kilometer.domain.item.ItemEntity; import com.kilometer.domain.item.ItemRepository; @@ -29,16 +27,13 @@ import org.springframework.beans.factory.annotation.Autowired; @SpringTestWithData -class ArchiveMapperTest { +class ArchiveEntityMapperTest { private final List 방문_사진 = List.of("photoUrls"); private final List 근처_맛집 = List.of(new PlaceInfo("FOOD", "맛집", "address", "roadAddress")); @Autowired - private ArchiveMapper archiveMapper; - - @Autowired - private ArchiveService archiveService; + private ArchiveEntityMapper archiveEntityMapper; @Autowired private UserRepository userRepository; @@ -57,28 +52,11 @@ void mapToArchiveEntity() { 근처_맛집); // when & then - assertThatThrownBy(() -> archiveMapper.mapToArchive(invalidUserId, request)) + assertThatThrownBy(() -> archiveEntityMapper.mapToArchiveEntity(invalidUserId, request)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("저장되지 않은 사용자 입니다."); } - @Test - @DisplayName("아카이브 정보를 등록할때, 이미 등록한 Archive를 다시 등록하려 하면 예외가 발생한다.") - void saveArchive_duplicate() { - // given - User 회원 = 회원가입을_한다(); - ItemEntity 아이템 = 아이템을_등록한다(); - ArchiveRequest request = new ArchiveRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, - 근처_맛집); - ArchiveInfo 아카이브_생성_응답 = archiveService.save(회원.getId(), request); - - // when & then - assertThatThrownBy(() -> archiveMapper.mapToArchive(회원.getId(), request)) - .isInstanceOf(ArchiveValidationException.class) - .hasMessage( - String.format("이미 등록한 Archive가 있습니다. sItemId : %d / UserId : %d", 아카이브_생성_응답.getId(), 회원.getId())); - } - @Test @DisplayName("아카이브 정보를 등록할때, 미전시 전시글에 아카이브를 등록하려 하면 예외가 발생한다.") void saveArchive_exposureOffItem() { @@ -90,7 +68,7 @@ void saveArchive_exposureOffItem() { // when ItemExposureOffException actual = assertThrows(ItemExposureOffException.class, - () -> archiveMapper.mapToArchive(user.getId(), request)); + () -> archiveEntityMapper.mapToArchiveEntity(user.getId(), request)); // then assertEquals(actual.getErrorCode(), KilometerErrorCode.ITEM_EXPOSURE_OFF); From e42c7288721222f505fcc9e42ce649a2a649f99f Mon Sep 17 00:00:00 2001 From: koo Date: Tue, 21 Feb 2023 17:56:14 +0900 Subject: [PATCH 4/6] =?UTF-8?q?test:=20=EC=95=84=EC=B9=B4=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=20=EC=A0=80=EC=9E=A5=20API=20=EA=B8=B0=EB=8A=A5?= =?UTF-8?q?=EC=97=90=20=EB=8C=80=ED=95=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/archive/ArchiveEntity.java | 5 +- .../archive/service/ArchiveEntityMapper.java | 22 ++--- .../com/kilometer/domain/item/ItemEntity.java | 7 ++ .../user/exception/UserNotFoundException.java | 20 +++++ .../exception/KilometerErrorCode.java | 3 +- .../domain/archive/ArchiveEntityTest.java | 51 +++++++++++ .../archive/domain/ArchiveImageTest.java | 22 ++++- .../domain/archive/domain/ArchiveTest.java | 75 +++++++++++++--- .../archive/domain/UserVisitPlaceTest.java | 30 +++++-- .../service/ArchiveEntityMapperTest.java | 90 +++++++++++++------ .../{ => service}/ArchiveServiceTest.java | 39 +++++++- 11 files changed, 295 insertions(+), 69 deletions(-) create mode 100644 kilometer-backend-domain/src/main/java/com/kilometer/domain/user/exception/UserNotFoundException.java create mode 100644 kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/ArchiveEntityTest.java rename kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/{ => service}/ArchiveServiceTest.java (89%) diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveEntity.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveEntity.java index 23f27e02..7b235c0c 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveEntity.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveEntity.java @@ -7,6 +7,7 @@ import com.kilometer.domain.user.User; import java.time.LocalDateTime; import java.util.List; +import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; @@ -69,10 +70,10 @@ public class ArchiveEntity { @JoinColumn(name = "item") private ItemEntity item; - @OneToMany(mappedBy = "archiveEntity") + @OneToMany(mappedBy = "archiveEntity", cascade = CascadeType.PERSIST) private List archiveImages; - @OneToMany(mappedBy = "archiveEntity") + @OneToMany(mappedBy = "archiveEntity", cascade = CascadeType.PERSIST) private List userVisitPlaces; public void addArchiveImages(final List archiveImages) { diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveEntityMapper.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveEntityMapper.java index 40653a06..70494f5a 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveEntityMapper.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveEntityMapper.java @@ -5,11 +5,10 @@ import com.kilometer.domain.archive.request.ArchiveRequest; import com.kilometer.domain.item.ItemEntity; import com.kilometer.domain.item.ItemRepository; -import com.kilometer.domain.item.enumType.ExposureType; -import com.kilometer.domain.item.exception.ItemExposureOffException; import com.kilometer.domain.item.exception.ItemNotFoundException; import com.kilometer.domain.user.User; import com.kilometer.domain.user.UserRepository; +import com.kilometer.domain.user.exception.UserNotFoundException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -24,7 +23,7 @@ public class ArchiveEntityMapper { public ArchiveEntity mapToArchiveEntity(final Long userId, final ArchiveRequest archiveRequest) { Archive archive = archiveRequest.toDomain(); - + ArchiveEntity archiveEntity = createArchiveEntity(userId, archiveRequest.getItemId(), archive); archiveEntity.addArchiveImages(archive.createArchiveImageEntities()); archiveEntity.addUserVisitPlaces(archive.createUserVisitPlaceEntities()); @@ -39,20 +38,13 @@ private ArchiveEntity createArchiveEntity(final Long userId, final Long itemId, private User getUser(final Long userId) { return userRepository.findById(userId) - .orElseThrow(() -> new IllegalArgumentException("저장되지 않은 사용자 입니다.")); + .orElseThrow(() -> new UserNotFoundException("저장되지 않은 사용자 입니다.")); } private ItemEntity getItem(final Long itemId) { - itemRepository.findExposureById(itemId) - .map(mapping -> { - if (mapping.getExposureType() == ExposureType.OFF) { - throw new ItemExposureOffException(); - } - return mapping; - }) - .orElseThrow(ItemNotFoundException::new); - - return itemRepository.findById(itemId) - .orElseThrow(ItemNotFoundException::new); + ItemEntity itemEntity = itemRepository.findById(itemId) + .orElseThrow(() -> new ItemNotFoundException("저장되지 않은 아이템 입니다.")); + itemEntity.validateExposureTypeIsOn(); + return itemEntity; } } diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/item/ItemEntity.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/item/ItemEntity.java index 7465c1e1..0cbb98fe 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/item/ItemEntity.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/item/ItemEntity.java @@ -7,6 +7,7 @@ import com.kilometer.domain.item.enumType.ExposureType; import com.kilometer.domain.item.enumType.FeeType; import com.kilometer.domain.item.enumType.RegionType; +import com.kilometer.domain.item.exception.ItemExposureOffException; import com.kilometer.domain.item.itemDetail.ItemDetail; import com.kilometer.domain.item.itemDetailImage.ItemDetailImage; import java.time.LocalDate; @@ -194,6 +195,12 @@ public void setItemDetail(ItemDetail itemDetail) { this.itemDetail = itemDetail; } + public void validateExposureTypeIsOn() { + if (this.exposureType.equals(ExposureType.OFF)) { + throw new ItemExposureOffException("미전시 아이템은 아카이빙 할 수 없습니다."); + } + } + public ItemEntity plusPickCount() { this.pickCount++; return this; diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/user/exception/UserNotFoundException.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/user/exception/UserNotFoundException.java new file mode 100644 index 00000000..3728d949 --- /dev/null +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/user/exception/UserNotFoundException.java @@ -0,0 +1,20 @@ +package com.kilometer.domain.user.exception; + +import com.kilometer.exception.KilometerErrorCode; +import com.kilometer.exception.KilometerException; + +public class UserNotFoundException extends KilometerException { + + public UserNotFoundException() { + super(""); + } + + public UserNotFoundException(String message) { + super(message); + } + + @Override + public KilometerErrorCode getErrorCode() { + return KilometerErrorCode.USER_NOT_FOUND; + } +} diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/exception/KilometerErrorCode.java b/kilometer-backend-domain/src/main/java/com/kilometer/exception/KilometerErrorCode.java index aaa5dd7a..2f69799d 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/exception/KilometerErrorCode.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/exception/KilometerErrorCode.java @@ -8,7 +8,8 @@ public enum KilometerErrorCode { ITEM_EXPOSURE_OFF("ALT-017", "해당 컨텐츠는 관리자에 의해 삭제되었습니다."), ARCHIVE_VALIDATION_EXCEPTION("ALT-018", "요청이 잘못되었습니다."), ARCHIVE_UNAUTHORIZED_EXCEPTION("ALT-019", "권한이 존재하지 않습니다."), - ITEM_NOT_FOUND("ALT-020", "존재 하지 않는 컨텐츠입니다."); + ITEM_NOT_FOUND("ALT-020", "존재 하지 않는 컨텐츠입니다."), + USER_NOT_FOUND("ATL-021", "회원이 존재하지 않습니다."); @Getter private final String code; diff --git a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/ArchiveEntityTest.java b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/ArchiveEntityTest.java new file mode 100644 index 00000000..9608405e --- /dev/null +++ b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/ArchiveEntityTest.java @@ -0,0 +1,51 @@ +package com.kilometer.domain.archive; + +import static com.kilometer.common.statics.Statics.아카이브_이미지_URL; +import static com.kilometer.common.statics.Statics.카페_이름; +import static org.assertj.core.api.Assertions.assertThat; + +import com.kilometer.domain.archive.archiveImage.ArchiveImageEntity; +import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceEntity; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class ArchiveEntityTest { + + private final ArchiveImageEntity 전시회_사진 = ArchiveImageEntity.builder() + .imageUrl(아카이브_이미지_URL) + .build(); + private final UserVisitPlaceEntity 근처_맛집_사진 = UserVisitPlaceEntity.builder() + .placeName(카페_이름) + .build(); + private final List 전시회_사진들 = List.of(전시회_사진); + private final List 근처_맛집_사진들 = List.of(근처_맛집_사진); + + @Test + @DisplayName("ArchiveEntity에 ArchiveImageEntities를 추가한다.") + void addArchiveImages() { + // given + ArchiveEntity archiveEntity = ArchiveEntity.builder() + .build(); + + // when + archiveEntity.addArchiveImages(전시회_사진들); + + // then + assertThat(archiveEntity.getArchiveImages()).hasSize(1); + } + + @Test + @DisplayName("ArchiveEntity에 UserVisitPlaces를 추가한다.") + void addUserVisitPlaces() { + // given + ArchiveEntity archiveEntity = ArchiveEntity.builder() + .build(); + + // when + archiveEntity.addUserVisitPlaces(근처_맛집_사진들); + + // then + assertThat(archiveEntity.getUserVisitPlaces()).hasSize(1); + } +} diff --git a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/domain/ArchiveImageTest.java b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/domain/ArchiveImageTest.java index d5fd9e13..aa82683c 100644 --- a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/domain/ArchiveImageTest.java +++ b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/domain/ArchiveImageTest.java @@ -4,6 +4,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import com.kilometer.domain.archive.archiveImage.ArchiveImageEntity; import com.kilometer.domain.archive.exception.ArchiveValidationException; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -28,8 +29,8 @@ void createArchiveImage_null() { // when & then assertThatThrownBy(() -> ArchiveImage.createArchiveImage(invalidImageUrl)) - .isInstanceOf(ArchiveValidationException.class) - .hasMessage("이미지 링크가 없습니다."); + .isInstanceOf(ArchiveValidationException.class) + .hasMessage("이미지 링크가 없습니다."); } @Test @@ -40,7 +41,20 @@ void createArchiveImage_blank() { // when & then assertThatThrownBy(() -> ArchiveImage.createArchiveImage(invalidImageUrl)) - .isInstanceOf(ArchiveValidationException.class) - .hasMessage("이미지 링크가 없습니다."); + .isInstanceOf(ArchiveValidationException.class) + .hasMessage("이미지 링크가 없습니다."); + } + + @Test + @DisplayName("ArchiveImage를 Entity 객체로 변환 한다.") + void toEntity() { + // given + ArchiveImage archiveImage = ArchiveImage.createArchiveImage(아카이브_이미지_URL); + + // when + ArchiveImageEntity actual = archiveImage.toEntity(); + + // then + assertThat(actual).isInstanceOf(ArchiveImageEntity.class); } } diff --git a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/domain/ArchiveTest.java b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/domain/ArchiveTest.java index 9f616ff4..f39ca7bb 100644 --- a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/domain/ArchiveTest.java +++ b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/domain/ArchiveTest.java @@ -2,20 +2,32 @@ import static com.kilometer.common.statics.Statics.아카이브_공개_설정; import static com.kilometer.common.statics.Statics.아카이브_별점; +import static com.kilometer.common.statics.Statics.아카이브_이미지_URL; import static com.kilometer.common.statics.Statics.아카이브_코멘트; +import static com.kilometer.common.statics.Statics.장소_종류; +import static com.kilometer.common.statics.Statics.카페_도로명_주소; +import static com.kilometer.common.statics.Statics.카페_이름; +import static com.kilometer.common.statics.Statics.카페_지번_주소; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import com.kilometer.domain.archive.ArchiveEntity; +import com.kilometer.domain.archive.archiveImage.ArchiveImageEntity; import com.kilometer.domain.archive.domain.userVisitPlace.UserVisitPlace; import com.kilometer.domain.archive.exception.ArchiveValidationException; +import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceEntity; +import com.kilometer.domain.item.ItemEntity; +import com.kilometer.domain.user.User; import java.util.List; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; public class ArchiveTest { - private final List 전시회_사진들 = List.of(); - private final List 근처_맛집_사진들 = List.of(); + private final ArchiveImage 전시회_사진 = ArchiveImage.createArchiveImage(아카이브_이미지_URL); + private final UserVisitPlace 근처_맛집_사진 = UserVisitPlace.createUserVisitPlace(장소_종류, 카페_이름, 카페_지번_주소, 카페_도로명_주소); + private final List 전시회_사진들 = List.of(전시회_사진); + private final List 근처_맛집_사진들 = List.of(근처_맛집_사진); @Test @DisplayName("Archive를 생성한다.") @@ -35,8 +47,8 @@ void commentIsNotNull() { // when & then assertThatThrownBy(() -> Archive.createArchive(invalidComment, 아카이브_별점, 아카이브_공개_설정, 전시회_사진들, 근처_맛집_사진들)) - .isInstanceOf(ArchiveValidationException.class) - .hasMessage("입력된 comment가 없습니다."); + .isInstanceOf(ArchiveValidationException.class) + .hasMessage("입력된 comment가 없습니다."); } @Test @@ -47,8 +59,8 @@ void archiveStarRatingIsNotNegative() { // when & then assertThatThrownBy(() -> Archive.createArchive(아카이브_코멘트, invalidStarRating, 아카이브_공개_설정, 전시회_사진들, 근처_맛집_사진들)) - .isInstanceOf(ArchiveValidationException.class) - .hasMessage("별점은 0~5 사이의 양수이어야 합니다."); + .isInstanceOf(ArchiveValidationException.class) + .hasMessage("별점은 0~5 사이의 양수이어야 합니다."); } @Test @@ -59,8 +71,8 @@ void archiveStarRatingIsPositiveOutOfRange() { // when & then assertThatThrownBy(() -> Archive.createArchive(아카이브_코멘트, invalidStarRating, 아카이브_공개_설정, 전시회_사진들, 근처_맛집_사진들)) - .isInstanceOf(ArchiveValidationException.class) - .hasMessage("별점은 0~5 사이의 양수이어야 합니다."); + .isInstanceOf(ArchiveValidationException.class) + .hasMessage("별점은 0~5 사이의 양수이어야 합니다."); } @Test @@ -71,7 +83,50 @@ void validateCommentField() { // when & then assertThatThrownBy(() -> Archive.createArchive(금칙어가_포함된_코멘트, 아카이브_별점, 아카이브_공개_설정, 전시회_사진들, 근처_맛집_사진들)) - .isInstanceOf(ArchiveValidationException.class) - .hasMessage("입력된 comment에 금칙어가 포함되어 있습니다."); + .isInstanceOf(ArchiveValidationException.class) + .hasMessage("입력된 comment에 금칙어가 포함되어 있습니다."); + } + + @Test + @DisplayName("Archive를 Entity 객체로 변환 한다.") + void toEntity() { + // given + User user = User.builder() + .build(); + ItemEntity itemEntity = ItemEntity.builder() + .build(); + Archive archive = Archive.createArchive(아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 전시회_사진들, 근처_맛집_사진들); + + // when + ArchiveEntity actual = archive.toEntity(user, itemEntity); + + // then + assertThat(actual).isInstanceOf(ArchiveEntity.class); + } + + @Test + @DisplayName("ArchiveImageEntity들을 생성한다.") + void createArchiveImageEntities() { + // given + Archive archive = Archive.createArchive(아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 전시회_사진들, 근처_맛집_사진들); + + // when + List archiveImageEntities = archive.createArchiveImageEntities(); + + // then + assertThat(archiveImageEntities).hasSize(1); + } + + @Test + @DisplayName("UserVisitPlaceEntity들을 생성한다.") + void createUserVisitPlaceEntities() { + // given + Archive archive = Archive.createArchive(아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 전시회_사진들, 근처_맛집_사진들); + + // when + List userVisitPlaceEntities = archive.createUserVisitPlaceEntities(); + + // then + assertThat(userVisitPlaceEntities).hasSize(1); } } diff --git a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/domain/UserVisitPlaceTest.java b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/domain/UserVisitPlaceTest.java index 6e4629c5..b69dd64a 100644 --- a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/domain/UserVisitPlaceTest.java +++ b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/domain/UserVisitPlaceTest.java @@ -9,6 +9,7 @@ import com.kilometer.domain.archive.domain.userVisitPlace.UserVisitPlace; import com.kilometer.domain.archive.exception.ArchiveValidationException; +import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceEntity; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -32,8 +33,8 @@ void createUserVisitPlace_emptyPlace() { // when & then assertThatThrownBy(() -> UserVisitPlace.createUserVisitPlace(invalidPlaceType, 카페_이름, 카페_지번_주소, 카페_도로명_주소)) - .isInstanceOf(ArchiveValidationException.class) - .hasMessage("일치하는 방문 장소 종류가 없습니다."); + .isInstanceOf(ArchiveValidationException.class) + .hasMessage("일치하는 방문 장소 종류가 없습니다."); } @Test @@ -44,8 +45,8 @@ void createUserVisitPlace_emptyName() { // when & then assertThatThrownBy(() -> UserVisitPlace.createUserVisitPlace(장소_종류, invalidCafeName, 카페_지번_주소, 카페_도로명_주소)) - .isInstanceOf(ArchiveValidationException.class) - .hasMessage("입력된 장소명이 없습니다."); + .isInstanceOf(ArchiveValidationException.class) + .hasMessage("입력된 장소명이 없습니다."); } @Test @@ -56,8 +57,8 @@ void createUserVisitPlace_emptyAddress() { // when & then assertThatThrownBy(() -> UserVisitPlace.createUserVisitPlace(장소_종류, 카페_이름, invalidCafeAddress, 카페_도로명_주소)) - .isInstanceOf(ArchiveValidationException.class) - .hasMessage("입력된 지번 주소가 없습니다."); + .isInstanceOf(ArchiveValidationException.class) + .hasMessage("입력된 지번 주소가 없습니다."); } @Test @@ -68,7 +69,20 @@ void createUserVisitPlace_emptyRoadAddress() { // when & then assertThatThrownBy(() -> UserVisitPlace.createUserVisitPlace(장소_종류, 카페_이름, 카페_지번_주소, invalidRoadAddress)) - .isInstanceOf(ArchiveValidationException.class) - .hasMessage("입력된 도로명 주소가 없습니다."); + .isInstanceOf(ArchiveValidationException.class) + .hasMessage("입력된 도로명 주소가 없습니다."); + } + + @Test + @DisplayName("UserVisitPlace를 Entity 객체로 변환 한다.") + void toEntity() { + // given + UserVisitPlace userVisitPlace = UserVisitPlace.createUserVisitPlace(장소_종류, 카페_이름, 카페_지번_주소, 카페_도로명_주소); + + // when + UserVisitPlaceEntity actual = userVisitPlace.toEntity(); + + // then + assertThat(actual).isInstanceOf(UserVisitPlaceEntity.class); } } diff --git a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveEntityMapperTest.java b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveEntityMapperTest.java index 8a8d4555..e57589fa 100644 --- a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveEntityMapperTest.java +++ b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveEntityMapperTest.java @@ -3,11 +3,14 @@ import static com.kilometer.common.statics.Statics.아카이브_공개_설정; import static com.kilometer.common.statics.Statics.아카이브_별점; import static com.kilometer.common.statics.Statics.아카이브_코멘트; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import com.kilometer.common.annotation.SpringTestWithData; +import com.kilometer.domain.archive.ArchiveEntity; import com.kilometer.domain.archive.dto.PlaceInfo; import com.kilometer.domain.archive.request.ArchiveRequest; import com.kilometer.domain.item.ItemEntity; @@ -19,6 +22,7 @@ import com.kilometer.domain.item.exception.ItemExposureOffException; import com.kilometer.domain.user.User; import com.kilometer.domain.user.UserRepository; +import com.kilometer.domain.user.exception.UserNotFoundException; import com.kilometer.exception.KilometerErrorCode; import java.time.LocalDate; import java.util.List; @@ -42,59 +46,95 @@ class ArchiveEntityMapperTest { private ItemRepository itemRepository; @Test - @DisplayName("아카이브 엔티티를 매핑 할 때, 사용자가 존재하지 않으면 예외가 발생한다.") + @DisplayName("아카이브 엔티티를 매핑한다.") void mapToArchiveEntity() { + // given + User user = 회원가입을_한다(); + ItemEntity item = 전시_아이템을_등록한다(); + ArchiveRequest request = new ArchiveRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); + + // when + ArchiveEntity actual = archiveEntityMapper.mapToArchiveEntity(user.getId(), request); + + // then + assertAll( + () -> assertThat(actual.getComment()).isEqualTo(아카이브_코멘트), + () -> assertThat(actual.getStarRating()).isEqualTo(아카이브_별점), + () -> assertThat(actual.getUser().getId()).isEqualTo(user.getId()), + () -> assertThat(actual.getItem().getId()).isEqualTo(item.getId()) + ); + } + + @Test + @DisplayName("아카이브 엔티티를 매핑 할 때, 사용자가 존재하지 않으면 예외가 발생한다.") + void mapToArchiveEntity_notExistUser() { // given Long invalidUserId = 1L; - ItemEntity 아이템 = 아이템을_등록한다(); + ItemEntity 아이템 = 전시_아이템을_등록한다(); ArchiveRequest request = new ArchiveRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, - 근처_맛집); + 근처_맛집); // when & then assertThatThrownBy(() -> archiveEntityMapper.mapToArchiveEntity(invalidUserId, request)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("저장되지 않은 사용자 입니다."); + .isInstanceOf(UserNotFoundException.class) + .hasMessage("저장되지 않은 사용자 입니다."); } @Test - @DisplayName("아카이브 정보를 등록할때, 미전시 전시글에 아카이브를 등록하려 하면 예외가 발생한다.") - void saveArchive_exposureOffItem() { + @DisplayName("아카이브 엔티티를 매핑 할 때, 미전시 전시글에 아카이브를 등록하려 하면 예외가 발생한다.") + void mapToArchiveEntity_exposureOffItem() { // given User user = 회원가입을_한다(); - ItemEntity item = ItemEntity.builder().exposureType(ExposureType.OFF).build(); - itemRepository.save(item); + ItemEntity item = 미전시_아이템을_등록한다(); ArchiveRequest request = new ArchiveRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); // when ItemExposureOffException actual = assertThrows(ItemExposureOffException.class, - () -> archiveEntityMapper.mapToArchiveEntity(user.getId(), request)); + () -> archiveEntityMapper.mapToArchiveEntity(user.getId(), request)); // then assertEquals(actual.getErrorCode(), KilometerErrorCode.ITEM_EXPOSURE_OFF); + assertEquals(actual.getMessage(), "미전시 아이템은 아카이빙 할 수 없습니다."); } private User 회원가입을_한다() { User user = User.builder() - .name("user") - .email("user@email.com") - .build(); + .name("user") + .email("user@email.com") + .build(); return userRepository.save(user); } - private ItemEntity 아이템을_등록한다() { + private ItemEntity 전시_아이템을_등록한다() { + ItemEntity item = ItemEntity.builder() + .exposureType(ExposureType.ON) + .exhibitionType(ExhibitionType.EXHIBITION) + .regionType(RegionType.CHUNGCHEONG) + .feeType(FeeType.FREE) + .listImageUrl("listImageUrl") + .thumbnailImageUrl("thumbnailImageUrl") + .title("title") + .placeName("placeName") + .startDate(LocalDate.now()) + .endDate(LocalDate.now()) + .build(); + return itemRepository.save(item); + } + + private ItemEntity 미전시_아이템을_등록한다() { ItemEntity item = ItemEntity.builder() - .exposureType(ExposureType.ON) - .exhibitionType(ExhibitionType.EXHIBITION) - .regionType(RegionType.CHUNGCHEONG) - .feeType(FeeType.FREE) - .listImageUrl("listImageUrl") - .thumbnailImageUrl("thumbnailImageUrl") - .title("title") - .placeName("placeName") - .startDate(LocalDate.now()) - .endDate(LocalDate.now()) - .build(); + .exposureType(ExposureType.OFF) + .exhibitionType(ExhibitionType.EXHIBITION) + .regionType(RegionType.CHUNGCHEONG) + .feeType(FeeType.FREE) + .listImageUrl("listImageUrl") + .thumbnailImageUrl("thumbnailImageUrl") + .title("title") + .placeName("placeName") + .startDate(LocalDate.now()) + .endDate(LocalDate.now()) + .build(); return itemRepository.save(item); } } diff --git a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/ArchiveServiceTest.java b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveServiceTest.java similarity index 89% rename from kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/ArchiveServiceTest.java rename to kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveServiceTest.java index e352eca9..16cff866 100644 --- a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/ArchiveServiceTest.java +++ b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveServiceTest.java @@ -1,4 +1,4 @@ -package com.kilometer.domain.archive; +package com.kilometer.domain.archive.service; import static com.kilometer.common.statics.Statics.금칙어가_포함된_아카이브_코멘트; import static com.kilometer.common.statics.Statics.아카이브_공개_설정; @@ -11,13 +11,16 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import com.kilometer.common.annotation.SpringTestWithData; +import com.kilometer.domain.archive.archiveImage.ArchiveImageEntity; +import com.kilometer.domain.archive.archiveImage.ArchiveImageRepository; import com.kilometer.domain.archive.dto.ArchiveInfo; import com.kilometer.domain.archive.dto.PlaceInfo; import com.kilometer.domain.archive.exception.ArchiveNotFoundException; import com.kilometer.domain.archive.exception.ArchiveUnauthorizedException; import com.kilometer.domain.archive.exception.ArchiveValidationException; import com.kilometer.domain.archive.request.ArchiveRequest; -import com.kilometer.domain.archive.service.ArchiveService; +import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceEntity; +import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceRepository; import com.kilometer.domain.item.ItemEntity; import com.kilometer.domain.item.ItemRepository; import com.kilometer.domain.item.enumType.ExhibitionType; @@ -28,6 +31,7 @@ import com.kilometer.domain.item.exception.ItemNotFoundException; import com.kilometer.domain.user.User; import com.kilometer.domain.user.UserRepository; +import com.kilometer.domain.user.exception.UserNotFoundException; import com.kilometer.exception.KilometerErrorCode; import java.time.LocalDate; import java.util.List; @@ -44,6 +48,12 @@ public class ArchiveServiceTest { @Autowired private ArchiveService archiveService; + @Autowired + private ArchiveImageRepository archiveImageRepository; + + @Autowired + private UserVisitPlaceRepository userVisitPlaceRepository; + @Autowired private UserRepository userRepository; @@ -71,6 +81,26 @@ void saveArchive() { ); } + @Test + @DisplayName("아카이브와 관련한 정보를 등록 할 때, 아카이브 이미지와 방문장소도 같이 저장된다.") + void saveArchive_archiveImageAndUserVisitPlace() { + // given + User 회원 = 회원가입을_한다(); + ItemEntity 아이템 = 아이템을_등록한다(); + ArchiveRequest request = new ArchiveRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + 근처_맛집); + + // when + ArchiveInfo archiveInfo = archiveService.save(회원.getId(), request); + + // then + ArchiveImageEntity archiveImageEntity = archiveImageRepository.findById(1L).get(); + UserVisitPlaceEntity userVisitPlaceEntity = userVisitPlaceRepository.findById(1L).get(); + + assertThat(archiveImageEntity.getId()).isEqualTo(1L); + assertThat(userVisitPlaceEntity.getId()).isEqualTo(1L); + } + @Test @DisplayName("아카이브 정보를 등록할때, 이미 등록한 Archive를 다시 등록하려 하면 예외가 발생한다.") void saveArchive_duplicate() { @@ -85,7 +115,8 @@ void saveArchive_duplicate() { assertThatThrownBy(() -> archiveService.save(회원.getId(), request)) .isInstanceOf(ArchiveValidationException.class) .hasMessage( - String.format("이미 등록한 Archive가 있습니다. sItemId : %d / UserId : %d", 아카이브_생성_응답.getId(), 회원.getId())); + String.format("이미 등록한 Archive가 있습니다. sItemId : %d / UserId : %d", 아카이브_생성_응답.getId(), + 회원.getId())); } @Test @@ -132,7 +163,7 @@ void saveArchive_notExistUser() { // when & then assertThatThrownBy(() -> archiveService.save(invalidUserId, request)) - .isInstanceOf(IllegalArgumentException.class) + .isInstanceOf(UserNotFoundException.class) .hasMessage("저장되지 않은 사용자 입니다."); } From de68d04c6cbcf268238509bbadbe53f4a16f82ff Mon Sep 17 00:00:00 2001 From: koo Date: Tue, 21 Feb 2023 18:07:32 +0900 Subject: [PATCH 5/6] =?UTF-8?q?refactor:=20=EC=95=84=EC=B9=B4=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=20=EB=93=B1=EB=A1=9D=20API=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=EC=9D=98=20=EC=9A=94=EC=B2=AD=20dto=EB=A5=BC=20ArchiveRequest?= =?UTF-8?q?=EC=97=90=EC=84=9C=20ArchiveCreateRequest=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/controller/ArchiveController.java | 3 +- .../archive/request/ArchiveCreateRequest.java | 42 ++++++++++ .../archive/service/ArchiveEntityMapper.java | 8 +- .../archive/service/ArchiveService.java | 7 +- .../service/ArchiveEntityMapperTest.java | 76 ++++++++++--------- .../archive/service/ArchiveServiceTest.java | 27 +++---- 6 files changed, 105 insertions(+), 58 deletions(-) create mode 100644 kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/request/ArchiveCreateRequest.java diff --git a/kilometer-backend-api/src/main/java/com/kilometer/backend/controller/ArchiveController.java b/kilometer-backend-api/src/main/java/com/kilometer/backend/controller/ArchiveController.java index 1e4f48ef..4eaab28c 100644 --- a/kilometer-backend-api/src/main/java/com/kilometer/backend/controller/ArchiveController.java +++ b/kilometer-backend-api/src/main/java/com/kilometer/backend/controller/ArchiveController.java @@ -1,5 +1,6 @@ package com.kilometer.backend.controller; +import com.kilometer.domain.archive.request.ArchiveCreateRequest; import com.kilometer.domain.archive.service.ArchiveService; import com.kilometer.domain.archive.dto.ArchiveDeleteResponse; import com.kilometer.domain.archive.dto.ArchiveDetailResponse; @@ -60,7 +61,7 @@ public ArchiveDetailResponse archive( @PostMapping(ApiUrlUtils.ARCHIVE_ROOT) @ApiOperation(value = "신규 아카이브 등록") public ArchiveInfo saveArchive( - @ApiParam(value = "등록할 아카이브 데이터", required = true) @RequestBody ArchiveRequest request) { + @ApiParam(value = "등록할 아카이브 데이터", required = true) @RequestBody ArchiveCreateRequest request) { long userId = getLoginUserId(); return archiveService.save(userId, request); } diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/request/ArchiveCreateRequest.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/request/ArchiveCreateRequest.java new file mode 100644 index 00000000..d745b874 --- /dev/null +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/request/ArchiveCreateRequest.java @@ -0,0 +1,42 @@ +package com.kilometer.domain.archive.request; + +import com.kilometer.domain.archive.domain.Archive; +import com.kilometer.domain.archive.domain.ArchiveImage; +import com.kilometer.domain.archive.domain.userVisitPlace.UserVisitPlace; +import com.kilometer.domain.archive.dto.PlaceInfo; +import java.util.List; +import java.util.stream.Collectors; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor +public class ArchiveCreateRequest { + + private Long itemId; + private String comment; + private int starRating; + private boolean isVisibleAtItem; + private List photoUrls; + private List placeInfos; + + public Archive toDomain() { + return Archive.createArchive( + this.comment, this.starRating, this.isVisibleAtItem, toArchiveImages(), toUserVisitPlace()); + } + + public List toArchiveImages() { + return this.photoUrls.stream() + .map(ArchiveImage::createArchiveImage) + .collect(Collectors.toList()); + } + + public List toUserVisitPlace() { + return this.placeInfos.stream() + .map(PlaceInfo::toDomain) + .collect(Collectors.toList()); + } +} diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveEntityMapper.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveEntityMapper.java index 70494f5a..1d5bb186 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveEntityMapper.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveEntityMapper.java @@ -2,7 +2,7 @@ import com.kilometer.domain.archive.ArchiveEntity; import com.kilometer.domain.archive.domain.Archive; -import com.kilometer.domain.archive.request.ArchiveRequest; +import com.kilometer.domain.archive.request.ArchiveCreateRequest; import com.kilometer.domain.item.ItemEntity; import com.kilometer.domain.item.ItemRepository; import com.kilometer.domain.item.exception.ItemNotFoundException; @@ -21,10 +21,10 @@ public class ArchiveEntityMapper { private final UserRepository userRepository; private final ItemRepository itemRepository; - public ArchiveEntity mapToArchiveEntity(final Long userId, final ArchiveRequest archiveRequest) { - Archive archive = archiveRequest.toDomain(); + public ArchiveEntity mapToArchiveEntity(final Long userId, final ArchiveCreateRequest request) { + Archive archive = request.toDomain(); - ArchiveEntity archiveEntity = createArchiveEntity(userId, archiveRequest.getItemId(), archive); + ArchiveEntity archiveEntity = createArchiveEntity(userId, request.getItemId(), archive); archiveEntity.addArchiveImages(archive.createArchiveImageEntities()); archiveEntity.addUserVisitPlaces(archive.createUserVisitPlaceEntities()); return archiveEntity; diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveService.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveService.java index 15ef3b1e..a63f1e64 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveService.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveService.java @@ -25,6 +25,7 @@ import com.kilometer.domain.archive.like.LikeService; import com.kilometer.domain.archive.like.dto.LikeDto; import com.kilometer.domain.archive.like.dto.LikeResponse; +import com.kilometer.domain.archive.request.ArchiveCreateRequest; import com.kilometer.domain.archive.request.ArchiveRequest; import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceEntity; import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceService; @@ -58,9 +59,9 @@ public class ArchiveService { private final ArchiveEntityMapper archiveEntityMapper; @Transactional - public ArchiveInfo save(Long userId, ArchiveRequest archiveRequest) { - validateNotDuplicateArchive(userId, archiveRequest.getItemId()); - ArchiveEntity archiveEntity = archiveEntityMapper.mapToArchiveEntity(userId, archiveRequest); + public ArchiveInfo save(final Long userId, final ArchiveCreateRequest request) { + validateNotDuplicateArchive(userId, request.getItemId()); + ArchiveEntity archiveEntity = archiveEntityMapper.mapToArchiveEntity(userId, request); ArchiveEntity savedArchiveEntity = archiveRepository.save(archiveEntity); return archiveAggregateConverter.convertArchiveInfo(savedArchiveEntity); } diff --git a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveEntityMapperTest.java b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveEntityMapperTest.java index e57589fa..972856a1 100644 --- a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveEntityMapperTest.java +++ b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveEntityMapperTest.java @@ -12,7 +12,7 @@ import com.kilometer.common.annotation.SpringTestWithData; import com.kilometer.domain.archive.ArchiveEntity; import com.kilometer.domain.archive.dto.PlaceInfo; -import com.kilometer.domain.archive.request.ArchiveRequest; +import com.kilometer.domain.archive.request.ArchiveCreateRequest; import com.kilometer.domain.item.ItemEntity; import com.kilometer.domain.item.ItemRepository; import com.kilometer.domain.item.enumType.ExhibitionType; @@ -51,17 +51,18 @@ void mapToArchiveEntity() { // given User user = 회원가입을_한다(); ItemEntity item = 전시_아이템을_등록한다(); - ArchiveRequest request = new ArchiveRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); + ArchiveCreateRequest request = new ArchiveCreateRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + 근처_맛집); // when ArchiveEntity actual = archiveEntityMapper.mapToArchiveEntity(user.getId(), request); // then assertAll( - () -> assertThat(actual.getComment()).isEqualTo(아카이브_코멘트), - () -> assertThat(actual.getStarRating()).isEqualTo(아카이브_별점), - () -> assertThat(actual.getUser().getId()).isEqualTo(user.getId()), - () -> assertThat(actual.getItem().getId()).isEqualTo(item.getId()) + () -> assertThat(actual.getComment()).isEqualTo(아카이브_코멘트), + () -> assertThat(actual.getStarRating()).isEqualTo(아카이브_별점), + () -> assertThat(actual.getUser().getId()).isEqualTo(user.getId()), + () -> assertThat(actual.getItem().getId()).isEqualTo(item.getId()) ); } @@ -72,13 +73,13 @@ void mapToArchiveEntity_notExistUser() { Long invalidUserId = 1L; ItemEntity 아이템 = 전시_아이템을_등록한다(); - ArchiveRequest request = new ArchiveRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, - 근처_맛집); + ArchiveCreateRequest request = new ArchiveCreateRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + 근처_맛집); // when & then assertThatThrownBy(() -> archiveEntityMapper.mapToArchiveEntity(invalidUserId, request)) - .isInstanceOf(UserNotFoundException.class) - .hasMessage("저장되지 않은 사용자 입니다."); + .isInstanceOf(UserNotFoundException.class) + .hasMessage("저장되지 않은 사용자 입니다."); } @Test @@ -87,11 +88,12 @@ void mapToArchiveEntity_exposureOffItem() { // given User user = 회원가입을_한다(); ItemEntity item = 미전시_아이템을_등록한다(); - ArchiveRequest request = new ArchiveRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); + ArchiveCreateRequest request = new ArchiveCreateRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + 근처_맛집); // when ItemExposureOffException actual = assertThrows(ItemExposureOffException.class, - () -> archiveEntityMapper.mapToArchiveEntity(user.getId(), request)); + () -> archiveEntityMapper.mapToArchiveEntity(user.getId(), request)); // then assertEquals(actual.getErrorCode(), KilometerErrorCode.ITEM_EXPOSURE_OFF); @@ -100,41 +102,41 @@ void mapToArchiveEntity_exposureOffItem() { private User 회원가입을_한다() { User user = User.builder() - .name("user") - .email("user@email.com") - .build(); + .name("user") + .email("user@email.com") + .build(); return userRepository.save(user); } private ItemEntity 전시_아이템을_등록한다() { ItemEntity item = ItemEntity.builder() - .exposureType(ExposureType.ON) - .exhibitionType(ExhibitionType.EXHIBITION) - .regionType(RegionType.CHUNGCHEONG) - .feeType(FeeType.FREE) - .listImageUrl("listImageUrl") - .thumbnailImageUrl("thumbnailImageUrl") - .title("title") - .placeName("placeName") - .startDate(LocalDate.now()) - .endDate(LocalDate.now()) - .build(); + .exposureType(ExposureType.ON) + .exhibitionType(ExhibitionType.EXHIBITION) + .regionType(RegionType.CHUNGCHEONG) + .feeType(FeeType.FREE) + .listImageUrl("listImageUrl") + .thumbnailImageUrl("thumbnailImageUrl") + .title("title") + .placeName("placeName") + .startDate(LocalDate.now()) + .endDate(LocalDate.now()) + .build(); return itemRepository.save(item); } private ItemEntity 미전시_아이템을_등록한다() { ItemEntity item = ItemEntity.builder() - .exposureType(ExposureType.OFF) - .exhibitionType(ExhibitionType.EXHIBITION) - .regionType(RegionType.CHUNGCHEONG) - .feeType(FeeType.FREE) - .listImageUrl("listImageUrl") - .thumbnailImageUrl("thumbnailImageUrl") - .title("title") - .placeName("placeName") - .startDate(LocalDate.now()) - .endDate(LocalDate.now()) - .build(); + .exposureType(ExposureType.OFF) + .exhibitionType(ExhibitionType.EXHIBITION) + .regionType(RegionType.CHUNGCHEONG) + .feeType(FeeType.FREE) + .listImageUrl("listImageUrl") + .thumbnailImageUrl("thumbnailImageUrl") + .title("title") + .placeName("placeName") + .startDate(LocalDate.now()) + .endDate(LocalDate.now()) + .build(); return itemRepository.save(item); } } diff --git a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveServiceTest.java b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveServiceTest.java index 16cff866..de46a664 100644 --- a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveServiceTest.java +++ b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveServiceTest.java @@ -18,6 +18,7 @@ import com.kilometer.domain.archive.exception.ArchiveNotFoundException; import com.kilometer.domain.archive.exception.ArchiveUnauthorizedException; import com.kilometer.domain.archive.exception.ArchiveValidationException; +import com.kilometer.domain.archive.request.ArchiveCreateRequest; import com.kilometer.domain.archive.request.ArchiveRequest; import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceEntity; import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceRepository; @@ -66,7 +67,7 @@ void saveArchive() { // given User 회원 = 회원가입을_한다(); ItemEntity 아이템 = 아이템을_등록한다(); - ArchiveRequest request = new ArchiveRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + ArchiveCreateRequest request = new ArchiveCreateRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); // when @@ -87,7 +88,7 @@ void saveArchive_archiveImageAndUserVisitPlace() { // given User 회원 = 회원가입을_한다(); ItemEntity 아이템 = 아이템을_등록한다(); - ArchiveRequest request = new ArchiveRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + ArchiveCreateRequest request = new ArchiveCreateRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); // when @@ -107,7 +108,7 @@ void saveArchive_duplicate() { // given User 회원 = 회원가입을_한다(); ItemEntity 아이템 = 아이템을_등록한다(); - ArchiveRequest request = new ArchiveRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + ArchiveCreateRequest request = new ArchiveCreateRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); ArchiveInfo 아카이브_생성_응답 = archiveService.save(회원.getId(), request); @@ -127,7 +128,7 @@ void saveArchive_nullPhotoUrls() { ItemEntity 아이템 = 아이템을_등록한다(); List invalidPhotoUrls = null; - ArchiveRequest request = new ArchiveRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, invalidPhotoUrls, + ArchiveCreateRequest request = new ArchiveCreateRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, invalidPhotoUrls, 근처_맛집); // when & then @@ -143,7 +144,7 @@ void saveArchive_nullPhotoInfos() { ItemEntity 아이템 = 아이템을_등록한다(); List invalidPhotoInfos = null; - ArchiveRequest request = new ArchiveRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + ArchiveCreateRequest request = new ArchiveCreateRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, invalidPhotoInfos); // when & then @@ -158,7 +159,7 @@ void saveArchive_notExistUser() { Long invalidUserId = 1L; ItemEntity 아이템 = 아이템을_등록한다(); - ArchiveRequest request = new ArchiveRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + ArchiveCreateRequest request = new ArchiveCreateRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); // when & then @@ -173,7 +174,7 @@ void saveArchive_forbiddenCommentWord() { // given User 회원 = 회원가입을_한다(); ItemEntity 아이템 = 아이템을_등록한다(); - ArchiveRequest request = new ArchiveRequest(아이템.getId(), 금칙어가_포함된_아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + ArchiveCreateRequest request = new ArchiveCreateRequest(아이템.getId(), 금칙어가_포함된_아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); // when & then @@ -188,7 +189,7 @@ void saveArchive_notExistsItem() { // given Long invalidItemId = -1L; User user = 회원가입을_한다(); - ArchiveRequest request = new ArchiveRequest(invalidItemId, 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); + ArchiveCreateRequest request = new ArchiveCreateRequest(invalidItemId, 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); // when ItemNotFoundException actual = assertThrows(ItemNotFoundException.class, @@ -205,7 +206,7 @@ void saveArchive_exposureOffItem() { User user = 회원가입을_한다(); ItemEntity item = ItemEntity.builder().exposureType(ExposureType.OFF).build(); itemRepository.save(item); - ArchiveRequest request = new ArchiveRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); + ArchiveCreateRequest request = new ArchiveCreateRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); // when ItemExposureOffException actual = assertThrows(ItemExposureOffException.class, @@ -221,7 +222,7 @@ void updateArchive() { // given User user = 회원가입을_한다(); ItemEntity item = 아이템을_등록한다(); - ArchiveRequest request = new ArchiveRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); + ArchiveCreateRequest request = new ArchiveCreateRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); ArchiveInfo savedArchive = archiveService.save(user.getId(), request); // when @@ -244,7 +245,7 @@ void updateArchive_forbiddenComment() { // given User user = 회원가입을_한다(); ItemEntity item = 아이템을_등록한다(); - ArchiveRequest request = new ArchiveRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); + ArchiveCreateRequest request = new ArchiveCreateRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); ArchiveInfo savedArchive = archiveService.save(user.getId(), request); ArchiveRequest updateRequest = new ArchiveRequest(null, 금칙어가_포함된_아카이브_코멘트, 3, false, List.of(), List.of()); @@ -261,7 +262,7 @@ void updateArchive_unauthorized() { // given User user = 회원가입을_한다(); ItemEntity item = 아이템을_등록한다(); - ArchiveRequest request = new ArchiveRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); + ArchiveCreateRequest request = new ArchiveCreateRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); ArchiveInfo savedArchive = archiveService.save(user.getId(), request); // when @@ -280,7 +281,7 @@ void updateArchive_archiveNotExists() { // given User user = 회원가입을_한다(); ItemEntity item = 아이템을_등록한다(); - ArchiveRequest request = new ArchiveRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); + ArchiveCreateRequest request = new ArchiveCreateRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); ArchiveInfo savedArchive = archiveService.save(user.getId(), request); // when From fcb3a72339f8f3927ad287c445874c424abc5049 Mon Sep 17 00:00:00 2001 From: koo Date: Tue, 21 Feb 2023 20:42:38 +0900 Subject: [PATCH 6/6] =?UTF-8?q?refactor:=20=EC=95=84=EC=B9=B4=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=EB=A5=BC=20=EC=88=98=EC=A0=95=ED=95=98=EB=8A=94=20API?= =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5=EC=9D=98=20=EB=82=B4=EB=B6=80=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/controller/ArchiveController.java | 4 +- .../archive/ArchiveAggregateConverter.java | 34 ++------ .../domain/archive/ArchiveEntity.java | 37 +++++---- .../domain/archive/ArchiveRepository.java | 8 ++ .../archiveImage/ArchiveImageEntity.java | 2 +- .../archiveImage/ArchiveImageService.java | 13 --- .../domain/archive/domain/Archive.java | 29 ++++++- .../archive/request/ArchiveRequest.java | 82 ------------------- .../archive/request/ArchiveUpdateRequest.java | 45 ++++++++++ .../archive/service/ArchiveEntityMapper.java | 4 +- .../archive/service/ArchiveService.java | 57 ++----------- .../userVisitPlace/UserVisitPlaceService.java | 11 --- .../com/kilometer/common/statics/Statics.java | 4 + .../domain/archive/ArchiveEntityTest.java | 37 ++++++++- .../domain/archive/domain/ArchiveTest.java | 2 +- .../archive/service/ArchiveServiceTest.java | 74 ++++++++++++----- 16 files changed, 214 insertions(+), 229 deletions(-) delete mode 100644 kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/request/ArchiveRequest.java create mode 100644 kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/request/ArchiveUpdateRequest.java diff --git a/kilometer-backend-api/src/main/java/com/kilometer/backend/controller/ArchiveController.java b/kilometer-backend-api/src/main/java/com/kilometer/backend/controller/ArchiveController.java index 4eaab28c..a76edc72 100644 --- a/kilometer-backend-api/src/main/java/com/kilometer/backend/controller/ArchiveController.java +++ b/kilometer-backend-api/src/main/java/com/kilometer/backend/controller/ArchiveController.java @@ -9,7 +9,7 @@ import com.kilometer.domain.archive.dto.ArchiveSortType; import com.kilometer.domain.archive.dto.MyArchiveResponse; import com.kilometer.domain.archive.like.dto.LikeResponse; -import com.kilometer.domain.archive.request.ArchiveRequest; +import com.kilometer.domain.archive.request.ArchiveUpdateRequest; import com.kilometer.domain.dto.GeneralResponse; import com.kilometer.domain.paging.RequestPagingStatus; import com.kilometer.domain.util.ApiUrlUtils; @@ -70,7 +70,7 @@ public ArchiveInfo saveArchive( @ApiOperation(value = "아카이브 수정") public ArchiveInfo updateArchive( @ApiParam(value = "수정할 아카이브 아이디", required = true) @PathVariable Long archiveId, - @ApiParam(value = "수정할 아카이브 데이터", required = true) @RequestBody ArchiveRequest request) { + @ApiParam(value = "수정할 아카이브 데이터", required = true) @RequestBody ArchiveUpdateRequest request) { long userId = getLoginUserId(); return archiveService.update(userId, archiveId, request); } diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveAggregateConverter.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveAggregateConverter.java index ba69ef71..d1b09f57 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveAggregateConverter.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveAggregateConverter.java @@ -24,8 +24,10 @@ import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; @Component +@Transactional @RequiredArgsConstructor public class ArchiveAggregateConverter { @@ -58,40 +60,14 @@ public ArchiveInfo convertArchiveInfo(ItemArchiveDto itemArchiveDto, .build(); } - public ArchiveInfo convertArchiveInfo(ArchiveEntity archiveEntity, - List archiveImageEntities, - List userVisitPlaceEntities) { - - Map placeTypes = convertFoodAndCafe(userVisitPlaceEntities); - - ArchiveLike archiveLike = archiveLikeGenerator.generateArchiveLike(archiveEntity.getId()); - - List photoUrls = archiveImageEntities.stream() - .map(ArchiveImageEntity::getImageUrl) - .collect(Collectors.toList()); - - return ArchiveInfo.builder() - .id(archiveEntity.getId()) - .userProfileUrl(archiveEntity.getUser().getImageUrl()) - .userName(archiveEntity.getUser().getName()) - .updatedAt(archiveEntity.getUpdatedAt()) - .starRating(archiveEntity.getStarRating()) - .likeCount(archiveEntity.getLikeCount()) - .heart(archiveLike) - .comment(archiveEntity.getComment()) - .food(placeTypes.getOrDefault(PlaceType.FOOD, "")) - .cafe(placeTypes.getOrDefault(PlaceType.CAFE, "")) - .photoUrls(photoUrls) - .build(); - } - - public ArchiveInfo convertArchiveInfo(ArchiveEntity archiveEntity) { + public ArchiveInfo convertArchiveInfo(final ArchiveEntity archiveEntity) { Map placeTypes = convertFoodAndCafe(archiveEntity.getUserVisitPlaces()); ArchiveLike archiveLike = archiveLikeGenerator.generateArchiveLike(archiveEntity.getId()); - List photoUrls = archiveEntity.getArchiveImages().stream() + List photoUrls = archiveEntity.getArchiveImages() + .stream() .map(ArchiveImageEntity::getImageUrl) .collect(Collectors.toList()); User user = archiveEntity.getUser(); diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveEntity.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveEntity.java index 7b235c0c..5f753f55 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveEntity.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveEntity.java @@ -1,11 +1,11 @@ package com.kilometer.domain.archive; import com.kilometer.domain.archive.archiveImage.ArchiveImageEntity; -import com.kilometer.domain.archive.request.ArchiveRequest; import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceEntity; import com.kilometer.domain.item.ItemEntity; import com.kilometer.domain.user.User; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; @@ -70,22 +70,35 @@ public class ArchiveEntity { @JoinColumn(name = "item") private ItemEntity item; - @OneToMany(mappedBy = "archiveEntity", cascade = CascadeType.PERSIST) - private List archiveImages; + @OneToMany(mappedBy = "archiveEntity", cascade = {CascadeType.PERSIST, CascadeType.MERGE}, + fetch = FetchType.LAZY, orphanRemoval = true) + private final List archiveImages = new ArrayList<>(); - @OneToMany(mappedBy = "archiveEntity", cascade = CascadeType.PERSIST) - private List userVisitPlaces; + @OneToMany(mappedBy = "archiveEntity", cascade = {CascadeType.PERSIST, CascadeType.MERGE}, + fetch = FetchType.LAZY, orphanRemoval = true) + private final List userVisitPlaces = new ArrayList<>(); - public void addArchiveImages(final List archiveImages) { - this.archiveImages = archiveImages; + public void initArchiveImages(final List archiveImages) { + this.archiveImages.clear(); + this.archiveImages.addAll(archiveImages); archiveImages.forEach(archiveImage -> archiveImage.initArchiveEntity(this)); } - public void addUserVisitPlaces(final List userVisitPlaces) { - this.userVisitPlaces = userVisitPlaces; + public void initUserVisitPlaces(final List userVisitPlaces) { + this.userVisitPlaces.clear(); + this.userVisitPlaces.addAll(userVisitPlaces); userVisitPlaces.forEach(userVisitPlace -> userVisitPlace.initArchiveEntity(this)); } + public void update(final String comment, final int starRating, final boolean isVisibleAtItem, + final List archiveImages, final List userVisitPlaces) { + this.comment = comment; + this.starRating = starRating; + this.isVisibleAtItem = isVisibleAtItem; + initArchiveImages(archiveImages); + initUserVisitPlaces(userVisitPlaces); + } + public void setUser(User user) { this.user = user; } @@ -94,12 +107,6 @@ public void setItem(ItemEntity item) { this.item = item; } - public void update(ArchiveRequest request) { - this.comment = request.getComment(); - this.isVisibleAtItem = request.isVisibleAtItem(); - this.starRating = request.getStarRating(); - } - public ArchiveEntity plusLikeCount() { this.likeCount++; return this; diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveRepository.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveRepository.java index 18b09951..c41e551b 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveRepository.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/ArchiveRepository.java @@ -1,5 +1,6 @@ package com.kilometer.domain.archive; +import com.kilometer.domain.archive.exception.ArchiveNotFoundException; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; @@ -7,5 +8,12 @@ public interface ArchiveRepository extends JpaRepository, A Optional findByItemIdAndUserId(Long itemId, Long userId); + Optional findByIdAndUserId(final Long id, final Long userId); + boolean existsByItemIdAndUserId(Long itemId, Long userId); + + default ArchiveEntity getByIdAndUserId(final Long id, final Long userId) { + return this.findByIdAndUserId(id, userId) + .orElseThrow(() -> new ArchiveNotFoundException("해당 회원에게 일치하는 아카이브가 없습니다.")); + } } diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/archiveImage/ArchiveImageEntity.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/archiveImage/ArchiveImageEntity.java index fc1bf42a..f6329767 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/archiveImage/ArchiveImageEntity.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/archiveImage/ArchiveImageEntity.java @@ -47,7 +47,7 @@ public class ArchiveImageEntity { @JoinColumn(name = "archive") private ArchiveEntity archiveEntity; - public void initArchiveEntity(ArchiveEntity archiveEntity) { + public void initArchiveEntity(final ArchiveEntity archiveEntity) { this.archiveEntity = archiveEntity; } } diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/archiveImage/ArchiveImageService.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/archiveImage/ArchiveImageService.java index 3372519e..e2de4103 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/archiveImage/ArchiveImageService.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/archiveImage/ArchiveImageService.java @@ -1,11 +1,8 @@ package com.kilometer.domain.archive.archiveImage; import com.google.common.base.Preconditions; -import com.kilometer.domain.archive.ArchiveEntity; import java.util.List; import lombok.RequiredArgsConstructor; - - import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -16,16 +13,6 @@ public class ArchiveImageService { private final ArchiveImageRepository archiveImageRepository; - @Transactional - public List saveAll(List archiveImageEntities, Long archiveId) { - Preconditions.checkNotNull(archiveImageEntities, "Archive images must not be null"); - if(archiveImageEntities.isEmpty()) { - return List.of(); - } - ArchiveEntity archiveEntity = ArchiveEntity.builder().id(archiveId).build(); - archiveImageEntities.forEach(archiveImage -> archiveImage.initArchiveEntity(archiveEntity)); - return archiveImageRepository.saveAll(archiveImageEntities); - } @Transactional public void deleteAllByArchiveId(Long archiveId) { Preconditions.checkNotNull(archiveId, "Archive id must not be null : " + archiveId); diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/domain/Archive.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/domain/Archive.java index b1a9226c..ab5bb179 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/domain/Archive.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/domain/Archive.java @@ -19,6 +19,7 @@ public class Archive { private static final int MAX_STAR_RATING = 5; private static final int MIN_STAR_RATING = 1; + private final Long id; private final String comment; private final int starRating; private final boolean isVisibleAtItem; @@ -26,8 +27,9 @@ public class Archive { private final List archiveImages; private final List userVisitPlaces; - private Archive(final String comment, final int starRating, final boolean isVisibleAtItem, + private Archive(final Long id, final String comment, final int starRating, final boolean isVisibleAtItem, final List archiveImages, final List userVisitPlaces) { + this.id = id; this.comment = comment; this.starRating = starRating; this.isVisibleAtItem = isVisibleAtItem; @@ -40,7 +42,22 @@ public static Archive createArchive(final String comment, final int starRating, final List userVisitPlaces) { validateComment(comment); validateStarRating(starRating); - return new Archive(comment, starRating, isVisibleAtItem, archiveImages, userVisitPlaces); + return new Archive(null, comment, starRating, isVisibleAtItem, archiveImages, userVisitPlaces); + } + + public static Archive createArchiveForUpdate(final Long id, final String comment, final int starRating, + final boolean isVisibleAtItem, final List archiveImages, + final List userVisitPlaces) { + validateId(id); + validateComment(comment); + validateStarRating(starRating); + return new Archive(id, comment, starRating, isVisibleAtItem, archiveImages, userVisitPlaces); + } + + private static void validateId(final Long id) { + if (id == null) { + throw new ArchiveValidationException("입력된 id가 없습니다."); + } } private static void validateComment(final String comment) { @@ -62,13 +79,13 @@ public ArchiveEntity toEntity(final User user, final ItemEntity itemEntity) { return ArchiveEntity.builder() .comment(this.getComment()) .starRating(this.getStarRating()) - .isVisibleAtItem(this.isVisibleAtItem()) + .isVisibleAtItem(this.getIsVisibleAtItem()) .user(user) .item(itemEntity) .build(); } - public List createArchiveImageEntities() { + public List toArchiveImageEntities() { return this.archiveImages.stream() .map(ArchiveImage::toEntity) .collect(Collectors.toList()); @@ -79,4 +96,8 @@ public List createUserVisitPlaceEntities() { .map(UserVisitPlace::toEntity) .collect(Collectors.toList()); } + + public boolean getIsVisibleAtItem() { + return isVisibleAtItem; + } } diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/request/ArchiveRequest.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/request/ArchiveRequest.java deleted file mode 100644 index 9fb368d0..00000000 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/request/ArchiveRequest.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.kilometer.domain.archive.request; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.kilometer.domain.archive.ArchiveEntity; -import com.kilometer.domain.archive.archiveImage.ArchiveImageEntity; -import com.kilometer.domain.archive.domain.Archive; -import com.kilometer.domain.archive.domain.ArchiveImage; -import com.kilometer.domain.archive.domain.userVisitPlace.PlaceType; -import com.kilometer.domain.archive.domain.userVisitPlace.UserVisitPlace; -import com.kilometer.domain.archive.dto.PlaceInfo; -import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceEntity; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@JsonIgnoreProperties(ignoreUnknown = true) -public class ArchiveRequest { - - private Long itemId; - private String comment; - private int starRating; - private boolean isVisibleAtItem; - private List photoUrls; - private List placeInfos; - - public ArchiveEntity makeArchive() { - return ArchiveEntity.builder() - .comment(this.getComment()) - .starRating(this.getStarRating()) - .isVisibleAtItem(this.isVisibleAtItem()) - .build(); - } - - - public List makeArchiveImages() { - List images = new ArrayList<>(); - this.getPhotoUrls().forEach(url -> { - ArchiveImageEntity photo = ArchiveImageEntity.builder().imageUrl(url).build(); - images.add(photo); - }); - return images; - } - - public List makeVisitedPlace() { - List places = new ArrayList<>(); - for (PlaceInfo info : this.getPlaceInfos()) { - UserVisitPlaceEntity visitPlace = UserVisitPlaceEntity.builder() - .placeType(PlaceType.valueOf(info.getPlaceType())) - .placeName(info.getName()) - .address(info.getAddress()) - .roadAddress(info.getRoadAddress()) - .build(); - places.add(visitPlace); - } - return places; - } - - public Archive toDomain() { - return Archive.createArchive( - this.comment, this.starRating, this.isVisibleAtItem, archiveImages(), userVisitPlace()); - } - - public List archiveImages() { - return this.photoUrls.stream() - .map(ArchiveImage::createArchiveImage) - .collect(Collectors.toList()); - } - - public List userVisitPlace() { - return this.placeInfos.stream() - .map(PlaceInfo::toDomain) - .collect(Collectors.toList()); - } -} diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/request/ArchiveUpdateRequest.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/request/ArchiveUpdateRequest.java new file mode 100644 index 00000000..50e0fc0b --- /dev/null +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/request/ArchiveUpdateRequest.java @@ -0,0 +1,45 @@ +package com.kilometer.domain.archive.request; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kilometer.domain.archive.domain.Archive; +import com.kilometer.domain.archive.domain.ArchiveImage; +import com.kilometer.domain.archive.domain.userVisitPlace.UserVisitPlace; +import com.kilometer.domain.archive.dto.PlaceInfo; +import java.util.List; +import java.util.stream.Collectors; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class ArchiveUpdateRequest { + + private Long itemId; + private String comment; + private int starRating; + private boolean isVisibleAtItem; + private List photoUrls; + private List placeInfos; + + public Archive toDomain(final Long archiveId) { + return Archive.createArchiveForUpdate( + archiveId, this.comment, this.starRating, this.isVisibleAtItem, archiveImages(), userVisitPlace()); + } + + public List archiveImages() { + return this.photoUrls.stream() + .map(ArchiveImage::createArchiveImage) + .collect(Collectors.toList()); + } + + public List userVisitPlace() { + return this.placeInfos.stream() + .map(PlaceInfo::toDomain) + .collect(Collectors.toList()); + } +} diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveEntityMapper.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveEntityMapper.java index 1d5bb186..cd853981 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveEntityMapper.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveEntityMapper.java @@ -25,8 +25,8 @@ public ArchiveEntity mapToArchiveEntity(final Long userId, final ArchiveCreateRe Archive archive = request.toDomain(); ArchiveEntity archiveEntity = createArchiveEntity(userId, request.getItemId(), archive); - archiveEntity.addArchiveImages(archive.createArchiveImageEntities()); - archiveEntity.addUserVisitPlaces(archive.createUserVisitPlaceEntities()); + archiveEntity.initArchiveImages(archive.toArchiveImageEntities()); + archiveEntity.initUserVisitPlaces(archive.createUserVisitPlaceEntities()); return archiveEntity; } diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveService.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveService.java index a63f1e64..aca7b7ec 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveService.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveService.java @@ -19,24 +19,20 @@ import com.kilometer.domain.archive.dto.MyArchiveInfo; import com.kilometer.domain.archive.dto.MyArchiveResponse; import com.kilometer.domain.archive.exception.ArchiveNotFoundException; -import com.kilometer.domain.archive.exception.ArchiveUnauthorizedException; import com.kilometer.domain.archive.exception.ArchiveValidationException; import com.kilometer.domain.archive.generator.ArchiveRatingCalculator; import com.kilometer.domain.archive.like.LikeService; import com.kilometer.domain.archive.like.dto.LikeDto; import com.kilometer.domain.archive.like.dto.LikeResponse; import com.kilometer.domain.archive.request.ArchiveCreateRequest; -import com.kilometer.domain.archive.request.ArchiveRequest; +import com.kilometer.domain.archive.request.ArchiveUpdateRequest; import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceEntity; import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceService; -import com.kilometer.domain.item.ItemEntity; import com.kilometer.domain.paging.PagingStatusService; import com.kilometer.domain.paging.RequestPagingStatus; import com.kilometer.domain.paging.ResponsePagingStatus; -import com.kilometer.domain.user.User; import com.kilometer.domain.util.FrontUrlUtils; import java.util.List; -import java.util.Objects; import java.util.function.Function; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; @@ -74,29 +70,14 @@ private void validateNotDuplicateArchive(Long userId, Long itemId) { } @Transactional - public ArchiveInfo update(Long userId, Long archiveId, ArchiveRequest request) { - Preconditions.checkNotNull(userId, "id must not be null"); - Preconditions.checkNotNull(archiveId, "Archive id must not be null"); - - Archive archive = request.toDomain(); - - ArchiveEntity archiveEntity = archiveRepository.findById(archiveId) - .orElseThrow(ArchiveNotFoundException::new); - - if (!Objects.equals(archiveEntity.getUser().getId(), userId)) { - throw new ArchiveUnauthorizedException(); - } - - List archiveImageEntities = request.makeArchiveImages(); - List userVisitPlaceEntities = request.makeVisitedPlace(); - - updateArchiveImages(archiveImageEntities, archiveId); - updateUserVisitPlace(userVisitPlaceEntities, archiveId); - - archiveEntity.update(request); - - return archiveAggregateConverter.convertArchiveInfo(archiveEntity, archiveImageEntities, - userVisitPlaceEntities); + public ArchiveInfo update(final Long userId, final Long archiveId, final ArchiveUpdateRequest request) { + Archive archive = request.toDomain(archiveId); + ArchiveEntity archiveEntity = archiveRepository.getByIdAndUserId(archive.getId(), userId); + archiveEntity.update(archive.getComment(), archive.getStarRating(), archive.getIsVisibleAtItem(), + archive.toArchiveImageEntities(), archive.createUserVisitPlaceEntities()); + + ArchiveEntity updatedArchiveEntity = archiveRepository.save(archiveEntity); + return archiveAggregateConverter.convertArchiveInfo(updatedArchiveEntity); } public ArchiveResponse findAllByItemIdAndUserId(Long itemId, Long userId, @@ -202,26 +183,6 @@ public Long findArchiveIdByItemIdAndUserId(Long itemId, Long userId) { .orElse(null); } - private ArchiveEntity saveArchive(ArchiveRequest archiveRequest, Long userId, Long itemId) { - ArchiveEntity archiveEntity = archiveRequest.makeArchive(); - archiveEntity.setUser(User.builder().id(userId).build()); - archiveEntity.setItem(ItemEntity.builder().id(itemId).build()); - archiveRepository.save(archiveEntity); - return archiveEntity; - } - - private List updateArchiveImages(List newArchiveImageEntities, - Long archiveId) { - archiveImageService.deleteAllByArchiveId(archiveId); - return archiveImageService.saveAll(newArchiveImageEntities, archiveId); - } - - private List updateUserVisitPlace(List newUserVisitPlaceEntities, - Long archiveId) { - userVisitPlaceService.deleteAllByArchiveId(archiveId); - return userVisitPlaceService.saveAll(newUserVisitPlaceEntities, archiveId); - } - private void updateArchiveLikeCount(boolean status, Long archiveId) { if (status) { updateArchiveLikeCount(ArchiveEntity::plusLikeCount, archiveId); diff --git a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/userVisitPlace/UserVisitPlaceService.java b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/userVisitPlace/UserVisitPlaceService.java index d1333ea0..f755874b 100644 --- a/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/userVisitPlace/UserVisitPlaceService.java +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/userVisitPlace/UserVisitPlaceService.java @@ -1,7 +1,6 @@ package com.kilometer.domain.archive.userVisitPlace; import com.google.common.base.Preconditions; -import com.kilometer.domain.archive.ArchiveEntity; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -14,16 +13,6 @@ public class UserVisitPlaceService { private final UserVisitPlaceRepository userVisitPlaceRepository; - @Transactional - public List saveAll(List userVisitPlaceEntities, Long archiveId) { - if (!userVisitPlaceEntities.isEmpty()) { - ArchiveEntity archiveEntity = ArchiveEntity.builder().id(archiveId).build(); - userVisitPlaceEntities.forEach(userVisitPlace -> userVisitPlace.initArchiveEntity(archiveEntity)); - userVisitPlaceRepository.saveAll(userVisitPlaceEntities); - } - return userVisitPlaceEntities; - } - @Transactional public void deleteAllByArchiveId(Long archiveId) { Preconditions.checkNotNull(archiveId, "Archive id must not be null : " + archiveId); diff --git a/kilometer-backend-domain/src/test/groovy/com/kilometer/common/statics/Statics.java b/kilometer-backend-domain/src/test/groovy/com/kilometer/common/statics/Statics.java index e1d22b9b..3e3917d8 100644 --- a/kilometer-backend-domain/src/test/groovy/com/kilometer/common/statics/Statics.java +++ b/kilometer-backend-domain/src/test/groovy/com/kilometer/common/statics/Statics.java @@ -8,6 +8,10 @@ public class Statics { public static final int 아카이브_별점 = 1; public static final boolean 아카이브_공개_설정 = true; + public static final String 새로운_아카이브_코멘트 = "new comment"; + public static final int 새로운_아카이브_별점 = 3; + public static final boolean 아카이브_비공개_설정 = false; + // Archive Image 관련 상수 public static final String 아카이브_이미지_URL = "아카이브 이미지"; diff --git a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/ArchiveEntityTest.java b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/ArchiveEntityTest.java index 9608405e..9d94523b 100644 --- a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/ArchiveEntityTest.java +++ b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/ArchiveEntityTest.java @@ -1,8 +1,15 @@ package com.kilometer.domain.archive; +import static com.kilometer.common.statics.Statics.새로운_아카이브_별점; +import static com.kilometer.common.statics.Statics.새로운_아카이브_코멘트; +import static com.kilometer.common.statics.Statics.아카이브_공개_설정; +import static com.kilometer.common.statics.Statics.아카이브_별점; +import static com.kilometer.common.statics.Statics.아카이브_비공개_설정; import static com.kilometer.common.statics.Statics.아카이브_이미지_URL; +import static com.kilometer.common.statics.Statics.아카이브_코멘트; import static com.kilometer.common.statics.Statics.카페_이름; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; import com.kilometer.domain.archive.archiveImage.ArchiveImageEntity; import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceEntity; @@ -29,7 +36,7 @@ void addArchiveImages() { .build(); // when - archiveEntity.addArchiveImages(전시회_사진들); + archiveEntity.initArchiveImages(전시회_사진들); // then assertThat(archiveEntity.getArchiveImages()).hasSize(1); @@ -43,9 +50,35 @@ void addUserVisitPlaces() { .build(); // when - archiveEntity.addUserVisitPlaces(근처_맛집_사진들); + archiveEntity.initUserVisitPlaces(근처_맛집_사진들); // then assertThat(archiveEntity.getUserVisitPlaces()).hasSize(1); } + + @Test + @DisplayName("ArchiveEntity를 수정한다.") + void update() { + // given + ArchiveEntity archiveEntity = ArchiveEntity.builder() + .comment(아카이브_코멘트) + .isVisibleAtItem(아카이브_공개_설정) + .starRating(아카이브_별점) + .build(); + + archiveEntity.initArchiveImages(전시회_사진들); + archiveEntity.initUserVisitPlaces(근처_맛집_사진들); + + // when + archiveEntity.update(새로운_아카이브_코멘트, 새로운_아카이브_별점, 아카이브_비공개_설정, 전시회_사진들, 근처_맛집_사진들); + + // then + assertAll( + () -> assertThat(archiveEntity.getComment()).isEqualTo(새로운_아카이브_코멘트), + () -> assertThat(archiveEntity.getStarRating()).isEqualTo(새로운_아카이브_별점), + () -> assertThat(archiveEntity.isVisibleAtItem()).isEqualTo(아카이브_비공개_설정), + () -> assertThat(archiveEntity.getArchiveImages()).hasSize(1), + () -> assertThat(archiveEntity.getUserVisitPlaces()).hasSize(1) + ); + } } diff --git a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/domain/ArchiveTest.java b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/domain/ArchiveTest.java index f39ca7bb..058c319f 100644 --- a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/domain/ArchiveTest.java +++ b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/domain/ArchiveTest.java @@ -111,7 +111,7 @@ void createArchiveImageEntities() { Archive archive = Archive.createArchive(아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 전시회_사진들, 근처_맛집_사진들); // when - List archiveImageEntities = archive.createArchiveImageEntities(); + List archiveImageEntities = archive.toArchiveImageEntities(); // then assertThat(archiveImageEntities).hasSize(1); diff --git a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveServiceTest.java b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveServiceTest.java index de46a664..f9416856 100644 --- a/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveServiceTest.java +++ b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveServiceTest.java @@ -16,10 +16,9 @@ import com.kilometer.domain.archive.dto.ArchiveInfo; import com.kilometer.domain.archive.dto.PlaceInfo; import com.kilometer.domain.archive.exception.ArchiveNotFoundException; -import com.kilometer.domain.archive.exception.ArchiveUnauthorizedException; import com.kilometer.domain.archive.exception.ArchiveValidationException; import com.kilometer.domain.archive.request.ArchiveCreateRequest; -import com.kilometer.domain.archive.request.ArchiveRequest; +import com.kilometer.domain.archive.request.ArchiveUpdateRequest; import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceEntity; import com.kilometer.domain.archive.userVisitPlace.UserVisitPlaceRepository; import com.kilometer.domain.item.ItemEntity; @@ -128,7 +127,8 @@ void saveArchive_nullPhotoUrls() { ItemEntity 아이템 = 아이템을_등록한다(); List invalidPhotoUrls = null; - ArchiveCreateRequest request = new ArchiveCreateRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, invalidPhotoUrls, + ArchiveCreateRequest request = new ArchiveCreateRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, + invalidPhotoUrls, 근처_맛집); // when & then @@ -174,7 +174,8 @@ void saveArchive_forbiddenCommentWord() { // given User 회원 = 회원가입을_한다(); ItemEntity 아이템 = 아이템을_등록한다(); - ArchiveCreateRequest request = new ArchiveCreateRequest(아이템.getId(), 금칙어가_포함된_아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + ArchiveCreateRequest request = new ArchiveCreateRequest(아이템.getId(), 금칙어가_포함된_아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, + 방문_사진, 근처_맛집); // when & then @@ -189,7 +190,8 @@ void saveArchive_notExistsItem() { // given Long invalidItemId = -1L; User user = 회원가입을_한다(); - ArchiveCreateRequest request = new ArchiveCreateRequest(invalidItemId, 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); + ArchiveCreateRequest request = new ArchiveCreateRequest(invalidItemId, 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + 근처_맛집); // when ItemNotFoundException actual = assertThrows(ItemNotFoundException.class, @@ -206,7 +208,8 @@ void saveArchive_exposureOffItem() { User user = 회원가입을_한다(); ItemEntity item = ItemEntity.builder().exposureType(ExposureType.OFF).build(); itemRepository.save(item); - ArchiveCreateRequest request = new ArchiveCreateRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); + ArchiveCreateRequest request = new ArchiveCreateRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + 근처_맛집); // when ItemExposureOffException actual = assertThrows(ItemExposureOffException.class, @@ -222,33 +225,61 @@ void updateArchive() { // given User user = 회원가입을_한다(); ItemEntity item = 아이템을_등록한다(); - ArchiveCreateRequest request = new ArchiveCreateRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); + ArchiveCreateRequest request = new ArchiveCreateRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + 근처_맛집); ArchiveInfo savedArchive = archiveService.save(user.getId(), request); // when - ArchiveRequest updateRequest = new ArchiveRequest(null, "수정된 아카이브 코멘트", 3, false, List.of(), List.of()); + ArchiveUpdateRequest updateRequest = new ArchiveUpdateRequest(null, "수정된 아카이브 코멘트", 3, false, 방문_사진, + 근처_맛집); ArchiveInfo actual = archiveService.update(user.getId(), savedArchive.getId(), updateRequest); // then assertAll( () -> assertThat(actual.getComment()).isEqualTo("수정된 아카이브 코멘트"), () -> assertThat(actual.getStarRating()).isEqualTo(3), - () -> assertThat(actual.getPhotoUrls()).isEmpty(), - () -> assertThat(actual.getFood()).isBlank(), + () -> assertThat(actual.getPhotoUrls()).hasSize(1), + () -> assertThat(actual.getFood()).isEqualTo("맛집"), () -> assertThat(actual.getCafe()).isBlank() ); } + @Test + @DisplayName("아카이브를 수정 할 때, 아카이브 이미지와 방문 사진도 함께 수정된다.") + void updateArchive_withArchiveImageAndUserVisitPlace() { + // given + User user = 회원가입을_한다(); + ItemEntity item = 아이템을_등록한다(); + ArchiveCreateRequest request = new ArchiveCreateRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, List.of(), + List.of()); + ArchiveInfo savedArchive = archiveService.save(user.getId(), request); + + ArchiveUpdateRequest updateRequest = new ArchiveUpdateRequest(null, "수정된 아카이브 코멘트", 3, false, 방문_사진, + 근처_맛집); + + // when + archiveService.update(user.getId(), savedArchive.getId(), updateRequest); + + // then + ArchiveImageEntity archiveImageEntity = archiveImageRepository.findById(1L).get(); + UserVisitPlaceEntity userVisitPlaceEntity = userVisitPlaceRepository.findById(1L).get(); + + assertThat(archiveImageEntity.getId()).isEqualTo(1L); + assertThat(userVisitPlaceEntity.getId()).isEqualTo(1L); + } + @Test @DisplayName("아카이브를 수정할 때, 수정하려는 코멘트에 금칙어가 포함되면 예외가 발생한다.") void updateArchive_forbiddenComment() { // given User user = 회원가입을_한다(); ItemEntity item = 아이템을_등록한다(); - ArchiveCreateRequest request = new ArchiveCreateRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); + ArchiveCreateRequest request = new ArchiveCreateRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + 근처_맛집); ArchiveInfo savedArchive = archiveService.save(user.getId(), request); - ArchiveRequest updateRequest = new ArchiveRequest(null, 금칙어가_포함된_아카이브_코멘트, 3, false, List.of(), List.of()); + ArchiveUpdateRequest updateRequest = new ArchiveUpdateRequest(null, 금칙어가_포함된_아카이브_코멘트, 3, false, List.of(), + List.of()); // then assertThatThrownBy(() -> archiveService.update(user.getId(), savedArchive.getId(), updateRequest)) @@ -262,17 +293,20 @@ void updateArchive_unauthorized() { // given User user = 회원가입을_한다(); ItemEntity item = 아이템을_등록한다(); - ArchiveCreateRequest request = new ArchiveCreateRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); + ArchiveCreateRequest request = new ArchiveCreateRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + 근처_맛집); ArchiveInfo savedArchive = archiveService.save(user.getId(), request); - // when - ArchiveRequest updateRequest = new ArchiveRequest(null, "수정된 아카이브 코멘트", 3, false, List.of(), List.of()); + ArchiveUpdateRequest updateRequest = new ArchiveUpdateRequest(null, "수정된 아카이브 코멘트", 3, false, List.of(), + List.of()); Long invalidUserId = -1L; - ArchiveUnauthorizedException actualException = assertThrows(ArchiveUnauthorizedException.class, + + // when + ArchiveNotFoundException actualException = assertThrows(ArchiveNotFoundException.class, () -> archiveService.update(invalidUserId, savedArchive.getId(), updateRequest)); // then - assertEquals(actualException.getErrorCode(), KilometerErrorCode.ARCHIVE_UNAUTHORIZED_EXCEPTION); + assertEquals(actualException.getErrorCode(), KilometerErrorCode.ARCHIVE_NOT_FOUND); } @Test @@ -281,11 +315,13 @@ void updateArchive_archiveNotExists() { // given User user = 회원가입을_한다(); ItemEntity item = 아이템을_등록한다(); - ArchiveCreateRequest request = new ArchiveCreateRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); + ArchiveCreateRequest request = new ArchiveCreateRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + 근처_맛집); ArchiveInfo savedArchive = archiveService.save(user.getId(), request); // when - ArchiveRequest updateRequest = new ArchiveRequest(null, "수정된 아카이브 코멘트", 3, false, List.of(), List.of()); + ArchiveUpdateRequest updateRequest = new ArchiveUpdateRequest(null, "수정된 아카이브 코멘트", 3, false, List.of(), + List.of()); Long invalidArchiveId = -1L; ArchiveNotFoundException actualException = assertThrows(ArchiveNotFoundException.class, () -> archiveService.update(user.getId(), invalidArchiveId, updateRequest));