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..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,6 +1,7 @@ package com.kilometer.backend.controller; -import com.kilometer.domain.archive.ArchiveService; +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; import com.kilometer.domain.archive.dto.ArchiveInfo; @@ -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/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..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 @@ -1,9 +1,13 @@ 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.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; @@ -12,6 +16,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 +70,22 @@ public class ArchiveEntity { @JoinColumn(name = "item") private ItemEntity item; + @OneToMany(mappedBy = "archiveEntity", cascade = CascadeType.PERSIST) + private List archiveImages; + + @OneToMany(mappedBy = "archiveEntity", cascade = CascadeType.PERSIST) + 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 b023ffc5..9747f021 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; import org.junit.platform.commons.util.StringUtils; @@ -23,4 +24,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 bcd5d964..2a0de79c 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; import org.junit.platform.commons.util.StringUtils; @@ -37,4 +38,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/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 new file mode 100644 index 00000000..1d5bb186 --- /dev/null +++ b/kilometer-backend-domain/src/main/java/com/kilometer/domain/archive/service/ArchiveEntityMapper.java @@ -0,0 +1,50 @@ +package com.kilometer.domain.archive.service; + +import com.kilometer.domain.archive.ArchiveEntity; +import com.kilometer.domain.archive.domain.Archive; +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; +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; + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class ArchiveEntityMapper { + + private final UserRepository userRepository; + private final ItemRepository itemRepository; + + public ArchiveEntity mapToArchiveEntity(final Long userId, final ArchiveCreateRequest request) { + Archive archive = request.toDomain(); + + ArchiveEntity archiveEntity = createArchiveEntity(userId, request.getItemId(), archive); + archiveEntity.addArchiveImages(archive.createArchiveImageEntities()); + archiveEntity.addUserVisitPlaces(archive.createUserVisitPlaceEntities()); + return archiveEntity; + } + + 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); + } + + private User getUser(final Long userId) { + return userRepository.findById(userId) + .orElseThrow(() -> new UserNotFoundException("저장되지 않은 사용자 입니다.")); + } + + private ItemEntity getItem(final Long itemId) { + ItemEntity itemEntity = itemRepository.findById(itemId) + .orElseThrow(() -> new ItemNotFoundException("저장되지 않은 아이템 입니다.")); + itemEntity.validateExposureTypeIsOn(); + return itemEntity; + } +} 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 85% 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..a63f1e64 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; @@ -17,24 +20,20 @@ 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.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.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; 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,43 +50,27 @@ @RequiredArgsConstructor public class ArchiveService { - private final UserService userService; - private final ItemRepository itemRepository; 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 ArchiveEntityMapper archiveEntityMapper; @Transactional - public ArchiveInfo save(Long userId, ArchiveRequest archiveRequest) { - validateArchiveRequest(archiveRequest, userId); - - Archive archive = archiveRequest.toDomain(); - - 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(); - List archiveImageEntities = archiveRequest.makeArchiveImages(); - List userVisitPlaceEntities = archiveRequest.makeVisitedPlace(); - archiveImageService.saveAll(archiveImageEntities, archiveId); - userVisitPlaceService.saveAll(userVisitPlaceEntities, archiveId); + 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); + } - 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 @@ -219,14 +202,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/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/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/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/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/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 new file mode 100644 index 00000000..972856a1 --- /dev/null +++ b/kilometer-backend-domain/src/test/groovy/com/kilometer/domain/archive/service/ArchiveEntityMapperTest.java @@ -0,0 +1,142 @@ +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.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.ArchiveCreateRequest; +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.domain.user.exception.UserNotFoundException; +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 ArchiveEntityMapperTest { + + private final List 방문_사진 = List.of("photoUrls"); + private final List 근처_맛집 = List.of(new PlaceInfo("FOOD", "맛집", "address", "roadAddress")); + + @Autowired + private ArchiveEntityMapper archiveEntityMapper; + + @Autowired + private UserRepository userRepository; + + @Autowired + private ItemRepository itemRepository; + + @Test + @DisplayName("아카이브 엔티티를 매핑한다.") + void mapToArchiveEntity() { + // given + User user = 회원가입을_한다(); + ItemEntity item = 전시_아이템을_등록한다(); + 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()) + ); + } + + @Test + @DisplayName("아카이브 엔티티를 매핑 할 때, 사용자가 존재하지 않으면 예외가 발생한다.") + void mapToArchiveEntity_notExistUser() { + // given + Long invalidUserId = 1L; + + ItemEntity 아이템 = 전시_아이템을_등록한다(); + ArchiveCreateRequest request = new ArchiveCreateRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + 근처_맛집); + + // when & then + assertThatThrownBy(() -> archiveEntityMapper.mapToArchiveEntity(invalidUserId, request)) + .isInstanceOf(UserNotFoundException.class) + .hasMessage("저장되지 않은 사용자 입니다."); + } + + @Test + @DisplayName("아카이브 엔티티를 매핑 할 때, 미전시 전시글에 아카이브를 등록하려 하면 예외가 발생한다.") + void mapToArchiveEntity_exposureOffItem() { + // given + User user = 회원가입을_한다(); + ItemEntity item = 미전시_아이템을_등록한다(); + ArchiveCreateRequest request = new ArchiveCreateRequest(item.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + 근처_맛집); + + // when + ItemExposureOffException actual = assertThrows(ItemExposureOffException.class, + () -> 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(); + 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); + } + + 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(); + 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 71% 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 c10eece6..de46a664 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,12 +11,17 @@ 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.ArchiveCreateRequest; import com.kilometer.domain.archive.request.ArchiveRequest; +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; @@ -27,6 +32,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; @@ -43,6 +49,12 @@ public class ArchiveServiceTest { @Autowired private ArchiveService archiveService; + @Autowired + private ArchiveImageRepository archiveImageRepository; + + @Autowired + private UserVisitPlaceRepository userVisitPlaceRepository; + @Autowired private UserRepository userRepository; @@ -55,7 +67,7 @@ void saveArchive() { // given User 회원 = 회원가입을_한다(); ItemEntity 아이템 = 아이템을_등록한다(); - ArchiveRequest request = new ArchiveRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + ArchiveCreateRequest request = new ArchiveCreateRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); // when @@ -71,19 +83,41 @@ void saveArchive() { } @Test - @DisplayName("아카이브 정보를 등록할때, 이미 등록한 Archive를 다시 등록하려 하면 예외가 발생한다..") - void saveArchive_duplicate() { + @DisplayName("아카이브와 관련한 정보를 등록 할 때, 아카이브 이미지와 방문장소도 같이 저장된다.") + void saveArchive_archiveImageAndUserVisitPlace() { // given User 회원 = 회원가입을_한다(); ItemEntity 아이템 = 아이템을_등록한다(); - ArchiveRequest request = new ArchiveRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + ArchiveCreateRequest request = new ArchiveCreateRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); - archiveService.save(회원.getId(), request); + // 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() { + // given + User 회원 = 회원가입을_한다(); + ItemEntity 아이템 = 아이템을_등록한다(); + ArchiveCreateRequest request = new ArchiveCreateRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + 근처_맛집); + 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 @@ -94,7 +128,7 @@ void saveArchive_nullPhotoUrls() { ItemEntity 아이템 = 아이템을_등록한다(); List invalidPhotoUrls = null; - ArchiveRequest request = new ArchiveRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, invalidPhotoUrls, + ArchiveCreateRequest request = new ArchiveCreateRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, invalidPhotoUrls, 근처_맛집); // when & then @@ -110,7 +144,7 @@ void saveArchive_nullPhotoInfos() { ItemEntity 아이템 = 아이템을_등록한다(); List invalidPhotoInfos = null; - ArchiveRequest request = new ArchiveRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + ArchiveCreateRequest request = new ArchiveCreateRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, invalidPhotoInfos); // when & then @@ -125,13 +159,13 @@ void saveArchive_notExistUser() { Long invalidUserId = 1L; ItemEntity 아이템 = 아이템을_등록한다(); - ArchiveRequest request = new ArchiveRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + ArchiveCreateRequest request = new ArchiveCreateRequest(아이템.getId(), 아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); // when & then assertThatThrownBy(() -> archiveService.save(invalidUserId, request)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("잘못된 사용자 정보 입니다."); + .isInstanceOf(UserNotFoundException.class) + .hasMessage("저장되지 않은 사용자 입니다."); } @Test @@ -140,7 +174,7 @@ void saveArchive_forbiddenCommentWord() { // given User 회원 = 회원가입을_한다(); ItemEntity 아이템 = 아이템을_등록한다(); - ArchiveRequest request = new ArchiveRequest(아이템.getId(), 금칙어가_포함된_아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, + ArchiveCreateRequest request = new ArchiveCreateRequest(아이템.getId(), 금칙어가_포함된_아카이브_코멘트, 아카이브_별점, 아카이브_공개_설정, 방문_사진, 근처_맛집); // when & then @@ -155,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, @@ -172,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, @@ -188,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 @@ -211,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()); @@ -228,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 @@ -247,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