diff --git a/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/controller/GoalRoomCheckFeedController.java b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/controller/GoalRoomCheckFeedController.java new file mode 100644 index 000000000..d8aa7a310 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/controller/GoalRoomCheckFeedController.java @@ -0,0 +1,45 @@ +package co.kirikiri.checkfeed.controller; + +import co.kirikiri.checkfeed.service.GoalRoomCheckFeedService; +import co.kirikiri.checkfeed.service.dto.request.CheckFeedRequest; +import co.kirikiri.checkfeed.service.dto.response.GoalRoomCheckFeedResponse; +import co.kirikiri.common.interceptor.Authenticated; +import co.kirikiri.common.resolver.MemberIdentifier; +import java.net.URI; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/goal-rooms/{goalRoomId}/checkFeeds") +@RequiredArgsConstructor +public class GoalRoomCheckFeedController { + + private final GoalRoomCheckFeedService goalRoomCheckFeedService; + + @PostMapping(consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}) + @Authenticated + public ResponseEntity createCheckFeed(@MemberIdentifier final String identifier, + @PathVariable("goalRoomId") final Long goalRoomId, + @ModelAttribute final CheckFeedRequest checkFeedRequest) { + final String imageUrl = goalRoomCheckFeedService.createCheckFeed(identifier, goalRoomId, checkFeedRequest); + return ResponseEntity.created(URI.create(imageUrl)).build(); + } + + @GetMapping + @Authenticated + public ResponseEntity> findGoalRoomCheckFeeds( + @MemberIdentifier final String identifier, + @PathVariable("goalRoomId") final Long goalRoomId) { + final List response = goalRoomCheckFeedService.findGoalRoomCheckFeeds(identifier, + goalRoomId); + return ResponseEntity.ok(response); + } +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/CheckFeed.java b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/domain/CheckFeed.java similarity index 56% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/CheckFeed.java rename to backend/kirikiri/src/main/java/co/kirikiri/checkfeed/domain/CheckFeed.java index f77f8fe01..0fa5ac4fb 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/CheckFeed.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/domain/CheckFeed.java @@ -1,18 +1,14 @@ -package co.kirikiri.domain.goalroom; +package co.kirikiri.checkfeed.domain; -import co.kirikiri.domain.BaseCreatedTimeEntity; -import co.kirikiri.domain.ImageContentType; -import jakarta.persistence.CascadeType; +import co.kirikiri.common.entity.BaseCreatedTimeEntity; +import co.kirikiri.common.type.ImageContentType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; -import jakarta.persistence.FetchType; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; +import java.time.LocalDateTime; import lombok.AccessLevel; import lombok.NoArgsConstructor; -import java.time.LocalDateTime; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -30,31 +26,26 @@ public class CheckFeed extends BaseCreatedTimeEntity { private String description; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "goal_room_roadmap_node_id", nullable = false) - private GoalRoomRoadmapNode goalRoomRoadmapNode; + private Long goalRoomRoadmapNodeId; - @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST) - @JoinColumn(name = "goal_room_member_id", nullable = false) - private GoalRoomMember goalRoomMember; + private Long goalRoomMemberId; public CheckFeed(final String serverFilePath, final ImageContentType imageContentType, final String originalFileName, final String description, - final GoalRoomRoadmapNode goalRoomRoadmapNode, final GoalRoomMember goalRoomMember) { - this(serverFilePath, imageContentType, originalFileName, description, goalRoomRoadmapNode, goalRoomMember, + final Long goalRoomRoadmapNodeId, final Long goalRoomMemberId) { + this(serverFilePath, imageContentType, originalFileName, description, goalRoomRoadmapNodeId, goalRoomMemberId, null); } public CheckFeed(final String serverFilePath, final ImageContentType imageContentType, final String originalFileName, final String description, - final GoalRoomRoadmapNode goalRoomRoadmapNode, final GoalRoomMember goalRoomMember, final - LocalDateTime createdAt) { + final Long goalRoomRoadmapNodeId, final Long goalRoomMemberId, final LocalDateTime createdAt) { this.serverFilePath = serverFilePath; this.imageContentType = imageContentType; this.originalFileName = originalFileName; this.description = description; - this.goalRoomRoadmapNode = goalRoomRoadmapNode; - this.goalRoomMember = goalRoomMember; + this.goalRoomRoadmapNodeId = goalRoomRoadmapNodeId; + this.goalRoomMemberId = goalRoomMemberId; this.createdAt = createdAt; } @@ -66,7 +57,7 @@ public String getDescription() { return description; } - public GoalRoomMember getGoalRoomMember() { - return goalRoomMember; + public Long getGoalRoomMemberId() { + return goalRoomMemberId; } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/persistence/CheckFeedRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/persistence/CheckFeedRepository.java new file mode 100644 index 000000000..9ce009102 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/persistence/CheckFeedRepository.java @@ -0,0 +1,35 @@ +package co.kirikiri.checkfeed.persistence; + +import co.kirikiri.checkfeed.domain.CheckFeed; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +public interface CheckFeedRepository extends JpaRepository { + + @Query("SELECT cf" + + " FROM CheckFeed cf" + + " WHERE cf.goalRoomMemberId = :goalRoomMemberId" + + " AND cf.createdAt >= :start" + + " AND cf.createdAt < :end") + Optional findByGoalRoomMemberIdAndDateTime(final Long goalRoomMemberId, final LocalDateTime start, + final LocalDateTime end); + + @Query("SELECT COUNT(cf)" + + " FROM CheckFeed cf" + + " WHERE cf.goalRoomMemberId = :goalRoomMemberId" + + " AND cf.goalRoomRoadmapNodeId = :goalRoomRoadmapNodeId") + int countByGoalRoomMemberIdAndGoalRoomRoadmapNodeId(final Long goalRoomMemberId, final Long goalRoomRoadmapNodeId); + + @Query(value = "SELECT cf.* FROM check_feed as cf " + + "LEFT JOIN goal_room_member as gm ON cf.goal_room_member_id = gm.id " + + "JOIN goal_room as g ON gm.goal_room_id = g.id " + + "WHERE g.id = :goalRoomId " + + "ORDER BY cf.created_at DESC ", nativeQuery = true) + List findByGoalRoomIdOrderByCreatedAtDesc(@Param("goalRoomId") final Long goalRoomId); + + List findByGoalRoomRoadmapNodeIdOrderByCreatedAtDesc(final Long goalRoomRoadmapNodeId); +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/DashBoardCheckFeedServiceImpl.java b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/DashBoardCheckFeedServiceImpl.java new file mode 100644 index 000000000..797a1a459 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/DashBoardCheckFeedServiceImpl.java @@ -0,0 +1,60 @@ +package co.kirikiri.checkfeed.service; + +import co.kirikiri.checkfeed.domain.CheckFeed; +import co.kirikiri.checkfeed.persistence.CheckFeedRepository; +import co.kirikiri.common.aop.ExceptionConvert; +import co.kirikiri.common.service.FileService; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNode; +import co.kirikiri.goalroom.service.DashBoardCheckFeedService; +import co.kirikiri.goalroom.service.dto.response.DashBoardCheckFeedResponse; +import java.net.URL; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpMethod; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +@RequiredArgsConstructor +@ExceptionConvert +public class DashBoardCheckFeedServiceImpl implements DashBoardCheckFeedService { + + private final CheckFeedRepository checkFeedRepository; + private final FileService fileService; + + @Override + @Transactional(readOnly = true) + public List findCheckFeedsByNodeAndGoalRoomStatus(final GoalRoom goalRoom, + final Optional currentGoalRoomRoadmapNode) { + final List checkFeeds = findCheckFeeds(goalRoom, currentGoalRoomRoadmapNode); + return makeCheckFeedResponses(checkFeeds); + } + + private List findCheckFeeds(final GoalRoom goalRoom, + final Optional currentGoalRoomRoadmapNode) { + if (goalRoom.isCompleted()) { + return checkFeedRepository.findByGoalRoomIdOrderByCreatedAtDesc(goalRoom.getId()); + } + if (goalRoom.isRunning() && currentGoalRoomRoadmapNode.isPresent()) { + return checkFeedRepository.findByGoalRoomRoadmapNodeIdOrderByCreatedAtDesc( + currentGoalRoomRoadmapNode.get().getId()); + } + return Collections.emptyList(); + } + + private List makeCheckFeedResponses(final List checkFeeds) { + return checkFeeds.stream() + .map(this::makeCheckFeedResponse) + .toList(); + } + + private DashBoardCheckFeedResponse makeCheckFeedResponse(final CheckFeed checkFeed) { + final URL checkFeedImageUrl = fileService.generateUrl(checkFeed.getServerFilePath(), HttpMethod.GET); + return new DashBoardCheckFeedResponse(checkFeed.getId(), checkFeedImageUrl.toExternalForm(), + checkFeed.getDescription(), checkFeed.getCreatedAt().toLocalDate()); + } +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/GoalRoomCheckFeedService.java b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/GoalRoomCheckFeedService.java new file mode 100644 index 000000000..cc3602e94 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/GoalRoomCheckFeedService.java @@ -0,0 +1,213 @@ +package co.kirikiri.checkfeed.service; + +import co.kirikiri.checkfeed.domain.CheckFeed; +import co.kirikiri.checkfeed.persistence.CheckFeedRepository; +import co.kirikiri.checkfeed.service.dto.CheckFeedDto; +import co.kirikiri.checkfeed.service.dto.CheckFeedMemberDto; +import co.kirikiri.checkfeed.service.dto.GoalRoomCheckFeedDto; +import co.kirikiri.checkfeed.service.dto.request.CheckFeedRequest; +import co.kirikiri.checkfeed.service.dto.response.GoalRoomCheckFeedResponse; +import co.kirikiri.checkfeed.service.mapper.CheckFeedMapper; +import co.kirikiri.common.aop.ExceptionConvert; +import co.kirikiri.common.exception.BadRequestException; +import co.kirikiri.common.exception.ForbiddenException; +import co.kirikiri.common.exception.NotFoundException; +import co.kirikiri.common.service.FilePathGenerator; +import co.kirikiri.common.service.FileService; +import co.kirikiri.common.service.dto.FileInformation; +import co.kirikiri.common.type.ImageContentType; +import co.kirikiri.common.type.ImageDirType; +import co.kirikiri.domain.member.Member; +import co.kirikiri.domain.member.vo.Identifier; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomMember; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNode; +import co.kirikiri.goalroom.persistence.GoalRoomMemberRepository; +import co.kirikiri.goalroom.persistence.GoalRoomRepository; +import co.kirikiri.persistence.member.MemberRepository; +import java.net.URL; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpMethod; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +@Service +@Transactional +@RequiredArgsConstructor +@ExceptionConvert +public class GoalRoomCheckFeedService { + + private final CheckFeedRepository checkFeedRepository; + private final GoalRoomRepository goalRoomRepository; + private final GoalRoomMemberRepository goalRoomMemberRepository; + private final MemberRepository memberRepository; + private final FileService fileService; + private final FilePathGenerator filePathGenerator; + + public String createCheckFeed(final String identifier, final Long goalRoomId, + final CheckFeedRequest checkFeedRequest) { + final MultipartFile checkFeedImage = checkFeedRequest.image(); + validateEmptyImage(checkFeedImage); + + final GoalRoom goalRoom = findGoalRoomWithNodesById(goalRoomId); + final GoalRoomMember goalRoomMember = findGoalRoomMemberByGoalRoomAndIdentifier(goalRoom, identifier); + final GoalRoomRoadmapNode currentNode = getNodeByDate(goalRoom); + final int currentMemberCheckCount = checkFeedRepository.countByGoalRoomMemberIdAndGoalRoomRoadmapNodeId( + goalRoomMember.getId(), currentNode.getId()); + validateCheckCount(currentMemberCheckCount, goalRoomMember, currentNode); + updateAccomplishmentRate(goalRoom, goalRoomMember, currentMemberCheckCount); + + final String path = filePathGenerator.makeFilePath(ImageDirType.CHECK_FEED, + checkFeedImage.getOriginalFilename()); + saveCheckFeed(checkFeedRequest, checkFeedImage, goalRoomMember, currentNode, path); + + final FileInformation fileInformation = FileInformation.from(checkFeedImage); + fileService.save(path, fileInformation); + return fileService.generateUrl(path, HttpMethod.GET).toExternalForm(); + } + + private void validateEmptyImage(final MultipartFile image) { + if (image.isEmpty()) { + throw new BadRequestException("인증 피드 등록 시 이미지가 반드시 포함되어야 합니다."); + } + + if (image.getOriginalFilename() == null) { + throw new BadRequestException("파일 이름은 반드시 포함되어야 합니다."); + } + } + + private GoalRoom findGoalRoomWithNodesById(final Long goalRoomId) { + return goalRoomRepository.findByIdWithNodes(goalRoomId) + .orElseThrow(() -> new NotFoundException("존재하지 않는 골룸입니다. goalRoomId = " + goalRoomId)); + } + + private GoalRoomMember findGoalRoomMemberByGoalRoomAndIdentifier(final GoalRoom goalRoom, final String identifier) { + final Member member = findMemberByIdentifier(identifier); + return goalRoomMemberRepository.findByGoalRoomAndMemberId(goalRoom, member.getId()) + .orElseThrow(() -> new NotFoundException("골룸에 해당 사용자가 존재하지 않습니다. 사용자 아이디 = " + identifier)); + } + + private Member findMemberByIdentifier(final String identifier) { + return memberRepository.findByIdentifier(new Identifier(identifier)) + .orElseThrow(() -> new NotFoundException("존재하지 않는 회원입니다. identifier = " + identifier)); + } + + private GoalRoomRoadmapNode getNodeByDate(final GoalRoom goalRoom) { + return goalRoom.findNodeByDate(LocalDate.now()) + .orElseThrow(() -> new BadRequestException("인증 피드는 노드 기간 내에만 작성할 수 있습니다.")); + } + + private void validateCheckCount(final int memberCheckCount, final GoalRoomMember member, + final GoalRoomRoadmapNode goalRoomRoadmapNode) { + validateNodeCheckCount(memberCheckCount, goalRoomRoadmapNode); + validateTodayCheckCount(member); + } + + private void validateNodeCheckCount(final int memberCheckCount, + final GoalRoomRoadmapNode goalRoomRoadmapNode) { + if (memberCheckCount >= goalRoomRoadmapNode.getCheckCount()) { + throw new BadRequestException( + "이번 노드에는 최대 " + goalRoomRoadmapNode.getCheckCount() + "번만 인증 피드를 등록할 수 있습니다."); + } + } + + private void validateTodayCheckCount(final GoalRoomMember goalRoomMember) { + final LocalDate today = LocalDate.now(); + final LocalDateTime todayStart = today.atStartOfDay(); + final LocalDateTime todayEnd = today.plusDays(1).atStartOfDay(); + if (checkFeedRepository.findByGoalRoomMemberIdAndDateTime(goalRoomMember.getId(), todayStart, todayEnd) + .isPresent()) { + throw new BadRequestException("이미 오늘 인증 피드를 등록하였습니다."); + } + } + + private void updateAccomplishmentRate(final GoalRoom goalRoom, final GoalRoomMember goalRoomMember, + final int pastCheckCount) { + final int wholeCheckCount = goalRoom.getAllCheckCount(); + final int memberCheckCount = pastCheckCount + 1; + final Double accomplishmentRate = 100 * memberCheckCount / (double) wholeCheckCount; + goalRoomMember.updateAccomplishmentRate(accomplishmentRate); + } + + private void saveCheckFeed(final CheckFeedRequest checkFeedRequest, final MultipartFile checkFeedImage, + final GoalRoomMember goalRoomMember, final GoalRoomRoadmapNode currentNode, + final String path) { + checkFeedRepository.save( + new CheckFeed(path, ImageContentType.findImageContentType(checkFeedImage.getContentType()), + checkFeedImage.getOriginalFilename(), checkFeedRequest.description(), currentNode.getId(), + goalRoomMember.getId())); + } + + @Transactional(readOnly = true) + public List findGoalRoomCheckFeeds(final String identifier, final Long goalRoomId) { + final GoalRoom goalRoom = findGoalRoomWithNodesById(goalRoomId); + validateJoinedMemberInRunningGoalRoom(goalRoom, identifier); + final Optional currentGoalRoomRoadmapNode = findCurrentGoalRoomNode(goalRoom); + final List checkFeeds = findCheckFeedsByGoalRoomRoadmapNode(goalRoom, + currentGoalRoomRoadmapNode); + final List goalRoomCheckFeedDtos = makeGoalRoomCheckFeedDtos(checkFeeds); + return CheckFeedMapper.convertToGoalRoomCheckFeedResponses(goalRoomCheckFeedDtos); + } + + private void validateJoinedMemberInRunningGoalRoom(final GoalRoom goalRoom, final String identifier) { + final Member member = findMemberByIdentifier(identifier); + if (goalRoomMemberRepository.findByGoalRoomAndMemberId(goalRoom, member.getId()) + .isEmpty()) { + throw new ForbiddenException("골룸에 참여하지 않은 회원입니다."); + } + } + + private Optional findCurrentGoalRoomNode(final GoalRoom goalRoom) { + return goalRoom.findNodeByDate(LocalDate.now()); + } + + private List findCheckFeedsByGoalRoomRoadmapNode(final GoalRoom goalRoom, + final Optional currentGoalRoomRoadmapNode) { + if (goalRoom.isCompleted()) { + return checkFeedRepository.findByGoalRoomIdOrderByCreatedAtDesc(goalRoom.getId()); + } + if (goalRoom.isRunning() && currentGoalRoomRoadmapNode.isPresent()) { + return checkFeedRepository.findByGoalRoomRoadmapNodeIdOrderByCreatedAtDesc( + currentGoalRoomRoadmapNode.get().getId()); + } + return Collections.emptyList(); + } + + private List makeGoalRoomCheckFeedDtos(final List checkFeeds) { + return checkFeeds.stream() + .map(this::makeGoalRoomCheckFeedDto) + .toList(); + } + + private GoalRoomCheckFeedDto makeGoalRoomCheckFeedDto(final CheckFeed checkFeed) { + final GoalRoomMember goalRoomMember = findGoalRoomMemberById(checkFeed.getGoalRoomMemberId()); + final Member member = findMemberWithProfileAndImageById(goalRoomMember.getMemberId()); + + final URL memberImageUrl = fileService.generateUrl(member.getImage().getServerFilePath(), HttpMethod.GET); + + return new GoalRoomCheckFeedDto(new CheckFeedMemberDto(member.getId(), member.getNickname().getValue(), + memberImageUrl.toExternalForm()), makeCheckFeedDto(checkFeed)); + } + + private GoalRoomMember findGoalRoomMemberById(final Long goalRoomMemberId) { + return goalRoomMemberRepository.findById(goalRoomMemberId) + .orElseThrow(() -> new NotFoundException("존재하지 않는 골룸 멤버입니다. goalRoomMemberId = " + goalRoomMemberId)); + } + + private Member findMemberWithProfileAndImageById(final Long memberId) { + return memberRepository.findWithMemberProfileAndImageById(memberId) + .orElseThrow(() -> new NotFoundException("존재하지 않는 회원입니다. memberId = " + memberId)); + } + + private CheckFeedDto makeCheckFeedDto(final CheckFeed checkFeed) { + final URL checkFeedImageUrl = fileService.generateUrl(checkFeed.getServerFilePath(), HttpMethod.GET); + return new CheckFeedDto(checkFeed.getId(), checkFeedImageUrl.toExternalForm(), + checkFeed.getDescription(), checkFeed.getCreatedAt()); + } +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/CheckFeedDto.java b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/dto/CheckFeedDto.java similarity index 79% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/CheckFeedDto.java rename to backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/dto/CheckFeedDto.java index a1a3279eb..a334af4eb 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/CheckFeedDto.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/dto/CheckFeedDto.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.goalroom; +package co.kirikiri.checkfeed.service.dto; import java.time.LocalDateTime; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/dto/CheckFeedMemberDto.java b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/dto/CheckFeedMemberDto.java new file mode 100644 index 000000000..c1353c618 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/dto/CheckFeedMemberDto.java @@ -0,0 +1,9 @@ +package co.kirikiri.checkfeed.service.dto; + +public record CheckFeedMemberDto( + long id, + String name, + String imageUrl +) { + +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/dto/GoalRoomCheckFeedDto.java b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/dto/GoalRoomCheckFeedDto.java new file mode 100644 index 000000000..62cd956df --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/dto/GoalRoomCheckFeedDto.java @@ -0,0 +1,8 @@ +package co.kirikiri.checkfeed.service.dto; + +public record GoalRoomCheckFeedDto( + CheckFeedMemberDto memberDto, + CheckFeedDto checkFeedDto +) { + +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/request/CheckFeedRequest.java b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/dto/request/CheckFeedRequest.java similarity index 75% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/request/CheckFeedRequest.java rename to backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/dto/request/CheckFeedRequest.java index 439284a88..fb4f8bba4 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/request/CheckFeedRequest.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/dto/request/CheckFeedRequest.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.goalroom.request; +package co.kirikiri.checkfeed.service.dto.request; import org.springframework.web.multipart.MultipartFile; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/dto/response/CheckFeedMemberResponse.java b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/dto/response/CheckFeedMemberResponse.java new file mode 100644 index 000000000..27337783b --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/dto/response/CheckFeedMemberResponse.java @@ -0,0 +1,9 @@ +package co.kirikiri.checkfeed.service.dto.response; + +public record CheckFeedMemberResponse( + long id, + String name, + String imageUrl +) { + +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/CheckFeedResponse.java b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/dto/response/CheckFeedResponse.java similarity index 76% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/CheckFeedResponse.java rename to backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/dto/response/CheckFeedResponse.java index 0b2fa2869..a9a87aa9b 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/CheckFeedResponse.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/dto/response/CheckFeedResponse.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.goalroom.response; +package co.kirikiri.checkfeed.service.dto.response; import java.time.LocalDate; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/dto/response/GoalRoomCheckFeedResponse.java b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/dto/response/GoalRoomCheckFeedResponse.java new file mode 100644 index 000000000..9e74ccd98 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/dto/response/GoalRoomCheckFeedResponse.java @@ -0,0 +1,8 @@ +package co.kirikiri.checkfeed.service.dto.response; + +public record GoalRoomCheckFeedResponse( + CheckFeedMemberResponse member, + CheckFeedResponse checkFeed +) { + +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/mapper/CheckFeedMapper.java b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/mapper/CheckFeedMapper.java new file mode 100644 index 000000000..21cf46e62 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/checkfeed/service/mapper/CheckFeedMapper.java @@ -0,0 +1,35 @@ +package co.kirikiri.checkfeed.service.mapper; + +import co.kirikiri.checkfeed.service.dto.CheckFeedDto; +import co.kirikiri.checkfeed.service.dto.CheckFeedMemberDto; +import co.kirikiri.checkfeed.service.dto.GoalRoomCheckFeedDto; +import co.kirikiri.checkfeed.service.dto.response.CheckFeedMemberResponse; +import co.kirikiri.checkfeed.service.dto.response.CheckFeedResponse; +import co.kirikiri.checkfeed.service.dto.response.GoalRoomCheckFeedResponse; +import java.util.List; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class CheckFeedMapper { + + public static List convertToGoalRoomCheckFeedResponses( + final List checkFeeds) { + return checkFeeds.stream() + .map(CheckFeedMapper::convertToGoalRoomCheckFeedResponse) + .toList(); + } + + private static GoalRoomCheckFeedResponse convertToGoalRoomCheckFeedResponse( + final GoalRoomCheckFeedDto goalRoomCheckFeedDto) { + final CheckFeedMemberDto memberDto = goalRoomCheckFeedDto.memberDto(); + final CheckFeedMemberResponse memberResponse = new CheckFeedMemberResponse(memberDto.id(), memberDto.name(), + memberDto.imageUrl()); + + final CheckFeedDto checkFeedDto = goalRoomCheckFeedDto.checkFeedDto(); + final CheckFeedResponse checkFeedResponse = new CheckFeedResponse(checkFeedDto.id(), checkFeedDto.imageUrl(), + checkFeedDto.description(), checkFeedDto.createdAt().toLocalDate()); + + return new GoalRoomCheckFeedResponse(memberResponse, checkFeedResponse); + } +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/aop/ExceptionConvert.java b/backend/kirikiri/src/main/java/co/kirikiri/common/aop/ExceptionConvert.java similarity index 89% rename from backend/kirikiri/src/main/java/co/kirikiri/service/aop/ExceptionConvert.java rename to backend/kirikiri/src/main/java/co/kirikiri/common/aop/ExceptionConvert.java index 1a2b42941..9308051f8 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/aop/ExceptionConvert.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/aop/ExceptionConvert.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.aop; +package co.kirikiri.common.aop; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/aop/ExceptionConvertAop.java b/backend/kirikiri/src/main/java/co/kirikiri/common/aop/ExceptionConvertAop.java similarity index 59% rename from backend/kirikiri/src/main/java/co/kirikiri/service/aop/ExceptionConvertAop.java rename to backend/kirikiri/src/main/java/co/kirikiri/common/aop/ExceptionConvertAop.java index 4a9fb96ad..75a043acd 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/aop/ExceptionConvertAop.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/aop/ExceptionConvertAop.java @@ -1,9 +1,9 @@ -package co.kirikiri.service.aop; +package co.kirikiri.common.aop; -import co.kirikiri.domain.exception.DomainException; -import co.kirikiri.domain.exception.UnexpectedDomainException; -import co.kirikiri.service.exception.BadRequestException; -import co.kirikiri.service.exception.ServerException; +import co.kirikiri.common.exception.BadRequestException; +import co.kirikiri.common.exception.DomainException; +import co.kirikiri.common.exception.ServerException; +import co.kirikiri.common.exception.UnexpectedDomainException; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; @@ -12,7 +12,7 @@ @Component public class ExceptionConvertAop { - @AfterThrowing(pointcut = "within(@co.kirikiri.service.aop.ExceptionConvert *)", throwing = "exception") + @AfterThrowing(pointcut = "within(@co.kirikiri.common.aop.ExceptionConvert *)", throwing = "exception") public void convertException(final Throwable exception) { if (exception instanceof UnexpectedDomainException) { throw new ServerException(exception.getMessage()); diff --git a/backend/kirikiri/src/main/java/co/kirikiri/controller/GlobalExceptionHandler.java b/backend/kirikiri/src/main/java/co/kirikiri/common/controller/GlobalExceptionHandler.java similarity index 90% rename from backend/kirikiri/src/main/java/co/kirikiri/controller/GlobalExceptionHandler.java rename to backend/kirikiri/src/main/java/co/kirikiri/common/controller/GlobalExceptionHandler.java index 181ac9cb0..f24f97cbd 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/controller/GlobalExceptionHandler.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/controller/GlobalExceptionHandler.java @@ -1,12 +1,12 @@ -package co.kirikiri.controller; +package co.kirikiri.common.controller; -import co.kirikiri.service.dto.ErrorResponse; -import co.kirikiri.service.exception.AuthenticationException; -import co.kirikiri.service.exception.BadRequestException; -import co.kirikiri.service.exception.ConflictException; -import co.kirikiri.service.exception.ForbiddenException; -import co.kirikiri.service.exception.NotFoundException; -import co.kirikiri.service.exception.ServerException; +import co.kirikiri.common.exception.AuthenticationException; +import co.kirikiri.common.exception.BadRequestException; +import co.kirikiri.common.exception.ConflictException; +import co.kirikiri.common.exception.ForbiddenException; +import co.kirikiri.common.exception.NotFoundException; +import co.kirikiri.common.exception.ServerException; +import co.kirikiri.common.service.dto.ErrorResponse; import com.fasterxml.jackson.databind.exc.InvalidFormatException; import java.util.List; import org.slf4j.Logger; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/BaseCreatedTimeEntity.java b/backend/kirikiri/src/main/java/co/kirikiri/common/entity/BaseCreatedTimeEntity.java similarity index 95% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/BaseCreatedTimeEntity.java rename to backend/kirikiri/src/main/java/co/kirikiri/common/entity/BaseCreatedTimeEntity.java index 383bd9634..48bf35b69 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/BaseCreatedTimeEntity.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/entity/BaseCreatedTimeEntity.java @@ -1,4 +1,4 @@ -package co.kirikiri.domain; +package co.kirikiri.common.entity; import jakarta.persistence.Column; import jakarta.persistence.MappedSuperclass; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/BaseEntity.java b/backend/kirikiri/src/main/java/co/kirikiri/common/entity/BaseEntity.java similarity index 95% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/BaseEntity.java rename to backend/kirikiri/src/main/java/co/kirikiri/common/entity/BaseEntity.java index a66368c62..4e43ffc23 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/BaseEntity.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/entity/BaseEntity.java @@ -1,4 +1,4 @@ -package co.kirikiri.domain; +package co.kirikiri.common.entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/BaseUpdatedTimeEntity.java b/backend/kirikiri/src/main/java/co/kirikiri/common/entity/BaseUpdatedTimeEntity.java similarity index 96% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/BaseUpdatedTimeEntity.java rename to backend/kirikiri/src/main/java/co/kirikiri/common/entity/BaseUpdatedTimeEntity.java index 7434bf778..c81171865 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/BaseUpdatedTimeEntity.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/entity/BaseUpdatedTimeEntity.java @@ -1,4 +1,4 @@ -package co.kirikiri.domain; +package co.kirikiri.common.entity; import jakarta.persistence.Column; import jakarta.persistence.MappedSuperclass; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/exception/AuthenticationException.java b/backend/kirikiri/src/main/java/co/kirikiri/common/exception/AuthenticationException.java similarity index 80% rename from backend/kirikiri/src/main/java/co/kirikiri/service/exception/AuthenticationException.java rename to backend/kirikiri/src/main/java/co/kirikiri/common/exception/AuthenticationException.java index 6e08c9c38..b0dc6ae73 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/exception/AuthenticationException.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/exception/AuthenticationException.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.exception; +package co.kirikiri.common.exception; public class AuthenticationException extends BusinessException { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/exception/BadRequestException.java b/backend/kirikiri/src/main/java/co/kirikiri/common/exception/BadRequestException.java similarity index 79% rename from backend/kirikiri/src/main/java/co/kirikiri/service/exception/BadRequestException.java rename to backend/kirikiri/src/main/java/co/kirikiri/common/exception/BadRequestException.java index a6000ad1a..a17573429 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/exception/BadRequestException.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/exception/BadRequestException.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.exception; +package co.kirikiri.common.exception; public class BadRequestException extends BusinessException { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/exception/BusinessException.java b/backend/kirikiri/src/main/java/co/kirikiri/common/exception/BusinessException.java similarity index 78% rename from backend/kirikiri/src/main/java/co/kirikiri/service/exception/BusinessException.java rename to backend/kirikiri/src/main/java/co/kirikiri/common/exception/BusinessException.java index 404a22614..64ff299a8 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/exception/BusinessException.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/exception/BusinessException.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.exception; +package co.kirikiri.common.exception; public class BusinessException extends RuntimeException { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/exception/ConflictException.java b/backend/kirikiri/src/main/java/co/kirikiri/common/exception/ConflictException.java similarity index 78% rename from backend/kirikiri/src/main/java/co/kirikiri/service/exception/ConflictException.java rename to backend/kirikiri/src/main/java/co/kirikiri/common/exception/ConflictException.java index dc0103c4a..5d45089e1 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/exception/ConflictException.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/exception/ConflictException.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.exception; +package co.kirikiri.common.exception; public class ConflictException extends BusinessException { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/exception/DomainException.java b/backend/kirikiri/src/main/java/co/kirikiri/common/exception/DomainException.java similarity index 78% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/exception/DomainException.java rename to backend/kirikiri/src/main/java/co/kirikiri/common/exception/DomainException.java index bf1161db4..6d458a6c9 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/exception/DomainException.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/exception/DomainException.java @@ -1,4 +1,4 @@ -package co.kirikiri.domain.exception; +package co.kirikiri.common.exception; public class DomainException extends RuntimeException { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/exception/ForbiddenException.java b/backend/kirikiri/src/main/java/co/kirikiri/common/exception/ForbiddenException.java similarity index 79% rename from backend/kirikiri/src/main/java/co/kirikiri/service/exception/ForbiddenException.java rename to backend/kirikiri/src/main/java/co/kirikiri/common/exception/ForbiddenException.java index e945efb65..2671761f2 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/exception/ForbiddenException.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/exception/ForbiddenException.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.exception; +package co.kirikiri.common.exception; public class ForbiddenException extends RuntimeException { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/exception/ImageExtensionException.java b/backend/kirikiri/src/main/java/co/kirikiri/common/exception/ImageExtensionException.java similarity index 80% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/exception/ImageExtensionException.java rename to backend/kirikiri/src/main/java/co/kirikiri/common/exception/ImageExtensionException.java index 3a8e84f67..1643f0399 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/exception/ImageExtensionException.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/exception/ImageExtensionException.java @@ -1,4 +1,4 @@ -package co.kirikiri.domain.exception; +package co.kirikiri.common.exception; public class ImageExtensionException extends DomainException { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/exception/NotFoundException.java b/backend/kirikiri/src/main/java/co/kirikiri/common/exception/NotFoundException.java similarity index 78% rename from backend/kirikiri/src/main/java/co/kirikiri/service/exception/NotFoundException.java rename to backend/kirikiri/src/main/java/co/kirikiri/common/exception/NotFoundException.java index 135762e67..f6aa07098 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/exception/NotFoundException.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/exception/NotFoundException.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.exception; +package co.kirikiri.common.exception; public class NotFoundException extends BusinessException { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/exception/ServerException.java b/backend/kirikiri/src/main/java/co/kirikiri/common/exception/ServerException.java similarity index 78% rename from backend/kirikiri/src/main/java/co/kirikiri/service/exception/ServerException.java rename to backend/kirikiri/src/main/java/co/kirikiri/common/exception/ServerException.java index 105a85b63..1fa9dcd9e 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/exception/ServerException.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/exception/ServerException.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.exception; +package co.kirikiri.common.exception; public class ServerException extends RuntimeException { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/exception/UnexpectedDomainException.java b/backend/kirikiri/src/main/java/co/kirikiri/common/exception/UnexpectedDomainException.java similarity index 80% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/exception/UnexpectedDomainException.java rename to backend/kirikiri/src/main/java/co/kirikiri/common/exception/UnexpectedDomainException.java index 50735c79e..510f3c6bc 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/exception/UnexpectedDomainException.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/exception/UnexpectedDomainException.java @@ -1,4 +1,4 @@ -package co.kirikiri.domain.exception; +package co.kirikiri.common.exception; public class UnexpectedDomainException extends DomainException { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/common/interceptor/AuthInterceptor.java b/backend/kirikiri/src/main/java/co/kirikiri/common/interceptor/AuthInterceptor.java index d2298df5c..cca8b0608 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/common/interceptor/AuthInterceptor.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/interceptor/AuthInterceptor.java @@ -1,7 +1,7 @@ package co.kirikiri.common.interceptor; +import co.kirikiri.common.exception.AuthenticationException; import co.kirikiri.service.auth.AuthService; -import co.kirikiri.service.exception.AuthenticationException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/QuerydslRepositorySupporter.java b/backend/kirikiri/src/main/java/co/kirikiri/common/persistence/QuerydslRepositorySupporter.java similarity index 97% rename from backend/kirikiri/src/main/java/co/kirikiri/persistence/QuerydslRepositorySupporter.java rename to backend/kirikiri/src/main/java/co/kirikiri/common/persistence/QuerydslRepositorySupporter.java index 685533ef7..6300ecd13 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/QuerydslRepositorySupporter.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/persistence/QuerydslRepositorySupporter.java @@ -1,6 +1,6 @@ -package co.kirikiri.persistence; +package co.kirikiri.common.persistence; -import co.kirikiri.service.exception.ServerException; +import co.kirikiri.common.exception.ServerException; import com.querydsl.core.types.EntityPath; import com.querydsl.core.types.Expression; import com.querydsl.core.types.dsl.PathBuilder; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/common/resolver/MemberIdentifierArgumentResolver.java b/backend/kirikiri/src/main/java/co/kirikiri/common/resolver/MemberIdentifierArgumentResolver.java index caf9b0e30..462c6654f 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/common/resolver/MemberIdentifierArgumentResolver.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/resolver/MemberIdentifierArgumentResolver.java @@ -1,9 +1,9 @@ package co.kirikiri.common.resolver; +import co.kirikiri.common.exception.AuthenticationException; +import co.kirikiri.common.exception.ServerException; import co.kirikiri.common.interceptor.Authenticated; import co.kirikiri.service.auth.AuthService; -import co.kirikiri.service.exception.AuthenticationException; -import co.kirikiri.service.exception.ServerException; import lombok.RequiredArgsConstructor; import org.springframework.core.MethodParameter; import org.springframework.http.HttpHeaders; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/common/resolver/RoadmapSaveArgumentResolver.java b/backend/kirikiri/src/main/java/co/kirikiri/common/resolver/RoadmapSaveArgumentResolver.java index fb080e831..8c668086b 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/common/resolver/RoadmapSaveArgumentResolver.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/resolver/RoadmapSaveArgumentResolver.java @@ -1,8 +1,8 @@ package co.kirikiri.common.resolver; +import co.kirikiri.common.exception.BadRequestException; import co.kirikiri.service.dto.roadmap.request.RoadmapNodeSaveRequest; import co.kirikiri.service.dto.roadmap.request.RoadmapSaveRequest; -import co.kirikiri.service.exception.BadRequestException; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.http.HttpServletRequest; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/FilePathGenerator.java b/backend/kirikiri/src/main/java/co/kirikiri/common/service/FilePathGenerator.java similarity index 59% rename from backend/kirikiri/src/main/java/co/kirikiri/service/FilePathGenerator.java rename to backend/kirikiri/src/main/java/co/kirikiri/common/service/FilePathGenerator.java index 80bcb2120..3bec351fb 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/FilePathGenerator.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/service/FilePathGenerator.java @@ -1,4 +1,6 @@ -package co.kirikiri.service; +package co.kirikiri.common.service; + +import co.kirikiri.common.type.ImageDirType; public interface FilePathGenerator { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/FileService.java b/backend/kirikiri/src/main/java/co/kirikiri/common/service/FileService.java similarity index 72% rename from backend/kirikiri/src/main/java/co/kirikiri/service/FileService.java rename to backend/kirikiri/src/main/java/co/kirikiri/common/service/FileService.java index 74aa91ac8..c381550c8 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/FileService.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/service/FileService.java @@ -1,8 +1,8 @@ -package co.kirikiri.service; +package co.kirikiri.common.service; -import co.kirikiri.service.dto.FileInformation; -import org.springframework.http.HttpMethod; +import co.kirikiri.common.service.dto.FileInformation; import java.net.URL; +import org.springframework.http.HttpMethod; public interface FileService { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/ErrorResponse.java b/backend/kirikiri/src/main/java/co/kirikiri/common/service/dto/ErrorResponse.java similarity index 92% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/ErrorResponse.java rename to backend/kirikiri/src/main/java/co/kirikiri/common/service/dto/ErrorResponse.java index 789d0f211..42624d206 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/ErrorResponse.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/service/dto/ErrorResponse.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto; +package co.kirikiri.common.service.dto; import java.util.Objects; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/common/service/dto/FileInformation.java b/backend/kirikiri/src/main/java/co/kirikiri/common/service/dto/FileInformation.java new file mode 100644 index 000000000..cb31804d3 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/service/dto/FileInformation.java @@ -0,0 +1,23 @@ +package co.kirikiri.common.service.dto; + +import co.kirikiri.common.exception.ServerException; +import java.io.IOException; +import java.io.InputStream; +import org.springframework.web.multipart.MultipartFile; + +public record FileInformation( + String originalFileName, + long size, + String contentType, + InputStream inputStream +) { + + public static FileInformation from(final MultipartFile multipartFile) { + try { + return new FileInformation(multipartFile.getOriginalFilename(), multipartFile.getSize(), + multipartFile.getContentType(), multipartFile.getInputStream()); + } catch (final IOException exception) { + throw new ServerException(exception.getMessage()); + } + } +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/ImageContentType.java b/backend/kirikiri/src/main/java/co/kirikiri/common/type/ImageContentType.java similarity index 86% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/ImageContentType.java rename to backend/kirikiri/src/main/java/co/kirikiri/common/type/ImageContentType.java index 9d8a4df07..faf34f204 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/ImageContentType.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/type/ImageContentType.java @@ -1,6 +1,6 @@ -package co.kirikiri.domain; +package co.kirikiri.common.type; -import co.kirikiri.domain.exception.ImageExtensionException; +import co.kirikiri.common.exception.ImageExtensionException; import java.util.Arrays; public enum ImageContentType { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/ImageDirType.java b/backend/kirikiri/src/main/java/co/kirikiri/common/type/ImageDirType.java similarity index 90% rename from backend/kirikiri/src/main/java/co/kirikiri/service/ImageDirType.java rename to backend/kirikiri/src/main/java/co/kirikiri/common/type/ImageDirType.java index 87f99dfe2..c2f11c400 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/ImageDirType.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/common/type/ImageDirType.java @@ -1,4 +1,4 @@ -package co.kirikiri.service; +package co.kirikiri.common.type; public enum ImageDirType { CHECK_FEED("goalroom/checkfeed"), diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/member/EncryptedPassword.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/member/EncryptedPassword.java index 3dfb27793..b06f2b651 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/member/EncryptedPassword.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/member/EncryptedPassword.java @@ -1,6 +1,6 @@ package co.kirikiri.domain.member; -import co.kirikiri.domain.exception.UnexpectedDomainException; +import co.kirikiri.common.exception.UnexpectedDomainException; import co.kirikiri.domain.member.vo.Password; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/member/Member.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/member/Member.java index c5c1a8e7a..fec71cf79 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/member/Member.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/member/Member.java @@ -1,6 +1,6 @@ package co.kirikiri.domain.member; -import co.kirikiri.domain.BaseUpdatedTimeEntity; +import co.kirikiri.common.entity.BaseUpdatedTimeEntity; import co.kirikiri.domain.member.vo.Identifier; import co.kirikiri.domain.member.vo.Nickname; import co.kirikiri.domain.member.vo.Password; @@ -50,7 +50,8 @@ public Member(final Identifier identifier, final String oauthId, final Nickname this(null, identifier, oauthId, null, nickname, image, memberProfile); } - public Member(final Long id, final Identifier identifier, final String oauthId, final EncryptedPassword encryptedPassword, + public Member(final Long id, final Identifier identifier, final String oauthId, + final EncryptedPassword encryptedPassword, final Nickname nickname, final MemberImage image, final MemberProfile memberProfile) { this.id = id; this.identifier = identifier; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/member/MemberImage.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/member/MemberImage.java index 519ab7e5a..8e0032a54 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/member/MemberImage.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/member/MemberImage.java @@ -1,7 +1,7 @@ package co.kirikiri.domain.member; -import co.kirikiri.domain.BaseEntity; -import co.kirikiri.domain.ImageContentType; +import co.kirikiri.common.entity.BaseEntity; +import co.kirikiri.common.type.ImageContentType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/member/MemberProfile.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/member/MemberProfile.java index 0014aa38c..d8b6796ce 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/member/MemberProfile.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/member/MemberProfile.java @@ -1,6 +1,6 @@ package co.kirikiri.domain.member; -import co.kirikiri.domain.BaseUpdatedTimeEntity; +import co.kirikiri.common.entity.BaseUpdatedTimeEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/member/exception/MemberException.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/member/exception/MemberException.java index 44f6fa57b..2f2c42025 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/member/exception/MemberException.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/member/exception/MemberException.java @@ -1,6 +1,6 @@ package co.kirikiri.domain.member.exception; -import co.kirikiri.domain.exception.DomainException; +import co.kirikiri.common.exception.DomainException; public class MemberException extends DomainException { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/Roadmap.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/Roadmap.java index 6c509d470..ac45f02c4 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/Roadmap.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/Roadmap.java @@ -1,6 +1,6 @@ package co.kirikiri.domain.roadmap; -import co.kirikiri.domain.BaseCreatedTimeEntity; +import co.kirikiri.common.entity.BaseCreatedTimeEntity; import co.kirikiri.domain.member.Member; import co.kirikiri.domain.roadmap.exception.RoadmapException; import jakarta.persistence.Column; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapCategory.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapCategory.java index 521839855..a71fcfb19 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapCategory.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapCategory.java @@ -1,6 +1,6 @@ package co.kirikiri.domain.roadmap; -import co.kirikiri.domain.BaseEntity; +import co.kirikiri.common.entity.BaseEntity; import co.kirikiri.domain.roadmap.exception.RoadmapException; import jakarta.persistence.Column; import jakarta.persistence.Entity; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapContent.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapContent.java index e4d918267..e982cfdf9 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapContent.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapContent.java @@ -1,6 +1,6 @@ package co.kirikiri.domain.roadmap; -import co.kirikiri.domain.BaseUpdatedTimeEntity; +import co.kirikiri.common.entity.BaseUpdatedTimeEntity; import co.kirikiri.domain.roadmap.exception.RoadmapException; import jakarta.persistence.Column; import jakarta.persistence.Embedded; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapNode.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapNode.java index dcf5bfbdf..0e82f470d 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapNode.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapNode.java @@ -1,6 +1,6 @@ package co.kirikiri.domain.roadmap; -import co.kirikiri.domain.BaseEntity; +import co.kirikiri.common.entity.BaseEntity; import co.kirikiri.domain.roadmap.exception.RoadmapException; import jakarta.persistence.Column; import jakarta.persistence.Embedded; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapNodeImage.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapNodeImage.java index 47f3b1a1d..4713f04a2 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapNodeImage.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapNodeImage.java @@ -1,7 +1,7 @@ package co.kirikiri.domain.roadmap; -import co.kirikiri.domain.BaseEntity; -import co.kirikiri.domain.ImageContentType; +import co.kirikiri.common.entity.BaseEntity; +import co.kirikiri.common.type.ImageContentType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapReview.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapReview.java index 1b36d1f92..bd65ed753 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapReview.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapReview.java @@ -1,6 +1,6 @@ package co.kirikiri.domain.roadmap; -import co.kirikiri.domain.BaseUpdatedTimeEntity; +import co.kirikiri.common.entity.BaseUpdatedTimeEntity; import co.kirikiri.domain.member.Member; import co.kirikiri.domain.roadmap.exception.RoadmapException; import jakarta.persistence.Column; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapTag.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapTag.java index 2dcd55fdc..6ffb3283a 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapTag.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/RoadmapTag.java @@ -1,12 +1,12 @@ package co.kirikiri.domain.roadmap; -import co.kirikiri.domain.BaseEntity; +import co.kirikiri.common.entity.BaseEntity; import co.kirikiri.domain.roadmap.vo.RoadmapTagName; import jakarta.persistence.Embedded; import jakarta.persistence.Entity; +import java.util.Objects; import lombok.AccessLevel; import lombok.NoArgsConstructor; -import java.util.Objects; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/exception/RoadmapException.java b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/exception/RoadmapException.java index 86610f60b..d178b24d2 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/exception/RoadmapException.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/domain/roadmap/exception/RoadmapException.java @@ -1,6 +1,6 @@ package co.kirikiri.domain.roadmap.exception; -import co.kirikiri.domain.exception.DomainException; +import co.kirikiri.common.exception.DomainException; public class RoadmapException extends DomainException { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/controller/GoalRoomController.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/controller/GoalRoomController.java similarity index 59% rename from backend/kirikiri/src/main/java/co/kirikiri/controller/GoalRoomController.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/controller/GoalRoomController.java index 671c65dd8..b555ae1c5 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/controller/GoalRoomController.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/controller/GoalRoomController.java @@ -1,32 +1,25 @@ -package co.kirikiri.controller; +package co.kirikiri.goalroom.controller; import co.kirikiri.common.interceptor.Authenticated; import co.kirikiri.common.resolver.MemberIdentifier; -import co.kirikiri.service.dto.goalroom.GoalRoomMemberSortTypeDto; -import co.kirikiri.service.dto.goalroom.request.CheckFeedRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomCreateRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomStatusTypeRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomTodoRequest; -import co.kirikiri.service.dto.goalroom.response.GoalRoomCertifiedResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomCheckFeedResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomMemberResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomRoadmapNodeDetailResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomToDoCheckResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomTodoResponse; -import co.kirikiri.service.dto.member.response.MemberGoalRoomForListResponse; -import co.kirikiri.service.dto.member.response.MemberGoalRoomResponse; -import co.kirikiri.service.goalroom.GoalRoomCreateService; -import co.kirikiri.service.goalroom.GoalRoomReadService; +import co.kirikiri.goalroom.service.GoalRoomCreateService; +import co.kirikiri.goalroom.service.GoalRoomReadService; +import co.kirikiri.goalroom.service.dto.GoalRoomMemberSortTypeDto; +import co.kirikiri.goalroom.service.dto.request.GoalRoomCreateRequest; +import co.kirikiri.goalroom.service.dto.request.GoalRoomStatusTypeRequest; +import co.kirikiri.goalroom.service.dto.response.GoalRoomCertifiedResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomMemberResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomRoadmapNodeDetailResponse; +import co.kirikiri.goalroom.service.dto.response.MemberGoalRoomForListResponse; +import co.kirikiri.goalroom.service.dto.response.MemberGoalRoomResponse; import jakarta.validation.Valid; import java.net.URI; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -58,34 +51,6 @@ public ResponseEntity joinGoalRoom(@MemberIdentifier final String identifi return ResponseEntity.status(HttpStatus.OK).build(); } - @PostMapping("/{goalRoomId}/todos") - @Authenticated - public ResponseEntity addTodo(@RequestBody @Valid final GoalRoomTodoRequest goalRoomTodoRequest, - @PathVariable final Long goalRoomId, - @MemberIdentifier final String identifier) { - final Long id = goalRoomCreateService.addGoalRoomTodo(goalRoomId, identifier, goalRoomTodoRequest); - return ResponseEntity.created(URI.create("/api/goal-rooms/" + goalRoomId + "/todos/" + id)).build(); - } - - @PostMapping("/{goalRoomId}/todos/{todoId}") - @Authenticated - public ResponseEntity checkTodo(@PathVariable final Long goalRoomId, - @PathVariable final Long todoId, - @MemberIdentifier final String identifier) { - final GoalRoomToDoCheckResponse checkResponse = goalRoomCreateService.checkGoalRoomTodo(goalRoomId, todoId, - identifier); - return ResponseEntity.ok(checkResponse); - } - - @PostMapping(value = "/{goalRoomId}/checkFeeds", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}) - @Authenticated - public ResponseEntity createCheckFeed(@MemberIdentifier final String identifier, - @PathVariable("goalRoomId") final Long goalRoomId, - @ModelAttribute final CheckFeedRequest checkFeedRequest) { - final String imageUrl = goalRoomCreateService.createCheckFeed(identifier, goalRoomId, checkFeedRequest); - return ResponseEntity.created(URI.create(imageUrl)).build(); - } - @PostMapping("/{goalRoomId}/leave") @Authenticated public ResponseEntity leave(@MemberIdentifier final String identifier, @@ -150,16 +115,6 @@ public ResponseEntity> findMemberGoalRoomsBy return ResponseEntity.ok(memberGoalRoomForListResponses); } - @GetMapping("/{goalRoomId}/todos") - @Authenticated - public ResponseEntity> findAllTodos( - @PathVariable final Long goalRoomId, - @MemberIdentifier final String identifier) { - final List todoResponses = goalRoomReadService.findAllGoalRoomTodo(goalRoomId, - identifier); - return ResponseEntity.ok(todoResponses); - } - @GetMapping("/{goalRoomId}/nodes") @Authenticated public ResponseEntity> findAllNodes( @@ -170,14 +125,4 @@ public ResponseEntity> findAllNodes( goalRoomId, identifier); return ResponseEntity.ok(nodeResponses); } - - @GetMapping("/{goalRoomId}/checkFeeds") - @Authenticated - public ResponseEntity> findGoalRoomCheckFeeds( - @MemberIdentifier final String identifier, - @PathVariable("goalRoomId") final Long goalRoomId) { - final List response = goalRoomReadService.findGoalRoomCheckFeeds(identifier, - goalRoomId); - return ResponseEntity.ok(response); - } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/BaseGoalRoomMember.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/BaseGoalRoomMember.java similarity index 65% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/BaseGoalRoomMember.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/BaseGoalRoomMember.java index e034bc6d6..be129f359 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/BaseGoalRoomMember.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/BaseGoalRoomMember.java @@ -1,8 +1,6 @@ -package co.kirikiri.domain.goalroom; +package co.kirikiri.goalroom.domain; -import co.kirikiri.domain.BaseEntity; -import co.kirikiri.domain.member.Member; -import com.querydsl.core.annotations.QueryInit; +import co.kirikiri.common.entity.BaseEntity; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; import jakarta.persistence.FetchType; @@ -31,26 +29,22 @@ public abstract class BaseGoalRoomMember extends BaseEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "goal_room_id", nullable = false) - @QueryInit(value = {"roadmapContent.roadmap"}) protected GoalRoom goalRoom; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id", nullable = false) - @QueryInit(value = {"identifier"}) - protected Member member; + protected Long memberId; - public BaseGoalRoomMember(final GoalRoomRole role, final LocalDateTime joinedAt, - final GoalRoom goalRoom, final Member member) { - this(null, role, joinedAt, goalRoom, member); + protected BaseGoalRoomMember(final GoalRoomRole role, final LocalDateTime joinedAt, + final GoalRoom goalRoom, final Long memberId) { + this(null, role, joinedAt, goalRoom, memberId); } - public BaseGoalRoomMember(final Long id, final GoalRoomRole role, final LocalDateTime joinedAt, - final GoalRoom goalRoom, final Member member) { + protected BaseGoalRoomMember(final Long id, final GoalRoomRole role, final LocalDateTime joinedAt, + final GoalRoom goalRoom, final Long memberId) { this.id = id; this.role = role; this.joinedAt = joinedAt; this.goalRoom = goalRoom; - this.member = member; + this.memberId = memberId; } @PrePersist @@ -64,8 +58,8 @@ public boolean isLeader() { return role == GoalRoomRole.LEADER; } - public boolean isSameMember(final Member member) { - return this.member.equals(member); + public boolean isSameMember(final Long memberId) { + return this.memberId.equals(memberId); } public void becomeLeader() { @@ -84,12 +78,13 @@ public boolean equals(final Object o) { return false; } final BaseGoalRoomMember that = (BaseGoalRoomMember) o; - return Objects.equals(goalRoom, that.goalRoom) && Objects.equals(member, that.member); + return role == that.role && Objects.equals(joinedAt, that.joinedAt) && Objects.equals(goalRoom, + that.goalRoom) && Objects.equals(memberId, that.memberId); } @Override public int hashCode() { - return Objects.hash(super.hashCode(), goalRoom, member); + return Objects.hash(super.hashCode(), role, joinedAt, goalRoom, memberId); } public GoalRoomRole getRole() { @@ -104,7 +99,7 @@ public GoalRoom getGoalRoom() { return goalRoom; } - public Member getMember() { - return member; + public Long getMemberId() { + return memberId; } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoom.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoom.java similarity index 69% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoom.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoom.java index e10f05f82..9a3671f3c 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoom.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoom.java @@ -1,19 +1,14 @@ -package co.kirikiri.domain.goalroom; - -import co.kirikiri.domain.BaseUpdatedTimeEntity; -import co.kirikiri.domain.goalroom.exception.GoalRoomException; -import co.kirikiri.domain.goalroom.vo.GoalRoomName; -import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; -import co.kirikiri.domain.member.Member; -import co.kirikiri.domain.roadmap.RoadmapContent; +package co.kirikiri.goalroom.domain; + +import co.kirikiri.common.entity.BaseUpdatedTimeEntity; +import co.kirikiri.goalroom.domain.exception.GoalRoomException; +import co.kirikiri.goalroom.domain.vo.GoalRoomName; +import co.kirikiri.goalroom.domain.vo.LimitedMemberCount; import jakarta.persistence.Column; import jakarta.persistence.Embedded; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; -import jakarta.persistence.FetchType; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; import java.time.LocalDate; import java.time.temporal.ChronoUnit; import java.util.ArrayList; @@ -37,9 +32,7 @@ public class GoalRoom extends BaseUpdatedTimeEntity { @Enumerated(value = EnumType.STRING) private GoalRoomStatus status = GoalRoomStatus.RECRUITING; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "roadmap_content_id", nullable = false) - private RoadmapContent roadmapContent; + private Long roadmapContentId; @Column(nullable = false) private LocalDate startDate; @@ -53,34 +46,37 @@ public class GoalRoom extends BaseUpdatedTimeEntity { @Embedded private final GoalRoomMembers goalRoomMembers = new GoalRoomMembers(); - @Embedded - private final GoalRoomToDos goalRoomToDos = new GoalRoomToDos(); - @Embedded private final GoalRoomRoadmapNodes goalRoomRoadmapNodes = new GoalRoomRoadmapNodes(); public GoalRoom(final GoalRoomName name, final LimitedMemberCount limitedMemberCount, - final RoadmapContent roadmapContent, final Member member) { - this(null, name, limitedMemberCount, roadmapContent, member); + final Long roadmapContentId, final Long memberId) { + this(null, name, limitedMemberCount, roadmapContentId, memberId); } public GoalRoom(final Long id, final GoalRoomName name, final LimitedMemberCount limitedMemberCount, - final RoadmapContent roadmapContent, final Member member) { + final Long roadmapContentId, final Long memberId) { this.id = id; this.name = name; this.limitedMemberCount = limitedMemberCount; - this.roadmapContent = roadmapContent; - updateLeader(member); + this.roadmapContentId = roadmapContentId; + updateLeader(memberId); } - private void updateLeader(final Member member) { - final GoalRoomPendingMember leader = new GoalRoomPendingMember(GoalRoomRole.LEADER, member); + private void updateLeader(final Long memberId) { + final GoalRoomPendingMember leader = new GoalRoomPendingMember(GoalRoomRole.LEADER, memberId); leader.initGoalRoom(this); goalRoomPendingMembers.add(leader); } - public void join(final Member member) { - final GoalRoomPendingMember newMember = new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, member); + public void addAllGoalRoomRoadmapNodes(final GoalRoomRoadmapNodes goalRoomRoadmapNodes) { + this.goalRoomRoadmapNodes.addAll(goalRoomRoadmapNodes); + this.startDate = goalRoomRoadmapNodes.getGoalRoomStartDate(); + this.endDate = goalRoomRoadmapNodes.getGoalRoomEndDate(); + } + + public void join(final Long memberId) { + final GoalRoomPendingMember newMember = new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, memberId); newMember.initGoalRoom(this); validateJoinGoalRoom(newMember); goalRoomPendingMembers.add(newMember); @@ -134,43 +130,26 @@ public boolean isRunning() { return status == GoalRoomStatus.RUNNING; } - public void addAllGoalRoomRoadmapNodes(final GoalRoomRoadmapNodes goalRoomRoadmapNodes) { - checkTotalSize(goalRoomRoadmapNodes.size() + this.goalRoomRoadmapNodes.size()); - this.goalRoomRoadmapNodes.addAll(goalRoomRoadmapNodes); - this.startDate = goalRoomRoadmapNodes.getGoalRoomStartDate(); - this.endDate = goalRoomRoadmapNodes.getGoalRoomEndDate(); - } - - private void checkTotalSize(final int totalSize) { - if (totalSize > roadmapContent.nodesSize()) { - throw new GoalRoomException("로드맵의 노드 수보다 골룸의 노드 수가 큽니다."); - } + public boolean isCompleted() { + return this.status == GoalRoomStatus.COMPLETED; } - public void addGoalRoomTodo(final GoalRoomToDo goalRoomToDo) { - goalRoomToDos.add(goalRoomToDo); + public int goalRoomRoadmapNodeSize() { + return this.goalRoomRoadmapNodes.size(); } - public Member findGoalRoomLeader() { + public Long findGoalRoomLeaderId() { if (status == GoalRoomStatus.RECRUITING) { - return goalRoomPendingMembers.findGoalRoomLeader(); + return goalRoomPendingMembers.findGoalRoomLeaderId(); } - return goalRoomMembers.findGoalRoomLeader(); + return goalRoomMembers.findGoalRoomLeaderId(); } - public boolean isNotLeader(final Member member) { + public boolean isNotLeader(final Long memberId) { if (status == GoalRoomStatus.RECRUITING) { - return goalRoomPendingMembers.isNotLeader(member); + return goalRoomPendingMembers.isNotLeader(memberId); } - return goalRoomMembers.isNotLeader(member); - } - - public boolean isCompleted() { - return this.status == GoalRoomStatus.COMPLETED; - } - - public GoalRoomToDo findLastGoalRoomTodo() { - return goalRoomToDos.findLast(); + return goalRoomMembers.isNotLeader(memberId); } public Optional findNodeByDate(final LocalDate date) { @@ -184,26 +163,25 @@ public Integer getCurrentMemberCount() { return goalRoomMembers.size(); } - // FIXME 테스트용 메서드 public void addAllGoalRoomMembers(final List members) { this.goalRoomMembers.addAll(new ArrayList<>(members)); } - public boolean isGoalRoomMember(final Member member) { + public boolean isGoalRoomMember(final Long memberId) { if (status == GoalRoomStatus.RECRUITING) { - return goalRoomPendingMembers.isMember(member); + return goalRoomPendingMembers.isMember(memberId); } - return goalRoomMembers.isMember(member); + return goalRoomMembers.isMember(memberId); } - public void leave(final Member member) { + public void leave(final Long memberId) { if (status == GoalRoomStatus.RECRUITING) { - final GoalRoomPendingMember goalRoomPendingMember = findGoalRoomPendingMemberByMember(member); + final GoalRoomPendingMember goalRoomPendingMember = findGoalRoomPendingMemberByMember(memberId); changeRoleIfLeaderLeave(goalRoomPendingMembers, goalRoomPendingMember); goalRoomPendingMembers.remove(goalRoomPendingMember); return; } - final GoalRoomMember goalRoomMember = findGoalRoomMemberByMember(member); + final GoalRoomMember goalRoomMember = findGoalRoomMemberByMember(memberId); changeRoleIfLeaderLeave(goalRoomMembers, goalRoomMember); goalRoomMembers.remove(goalRoomMember); } @@ -212,9 +190,9 @@ public boolean cannotStart() { return startDate.isAfter(LocalDate.now()); } - private GoalRoomPendingMember findGoalRoomPendingMemberByMember(final Member member) { - return goalRoomPendingMembers.findByMember(member) - .orElseThrow(() -> new GoalRoomException("골룸에 참여한 사용자가 아닙니다. memberId = " + member.getId())); + private GoalRoomPendingMember findGoalRoomPendingMemberByMember(final Long memberId) { + return goalRoomPendingMembers.findByMemberId(memberId) + .orElseThrow(() -> new GoalRoomException("골룸에 참여한 사용자가 아닙니다. memberId = " + memberId)); } private void changeRoleIfLeaderLeave(final GoalRoomPendingMembers goalRoomPendingMembers, @@ -225,9 +203,9 @@ private void changeRoleIfLeaderLeave(final GoalRoomPendingMembers goalRoomPendin } } - private GoalRoomMember findGoalRoomMemberByMember(final Member member) { - return goalRoomMembers.findByMember(member) - .orElseThrow(() -> new GoalRoomException("골룸에 참여한 사용자가 아닙니다. memberId = " + member.getId())); + private GoalRoomMember findGoalRoomMemberByMember(final Long memberId) { + return goalRoomMembers.findByMemberId(memberId) + .orElseThrow(() -> new GoalRoomException("골룸에 참여한 사용자가 아닙니다. memberId = " + memberId)); } private void changeRoleIfLeaderLeave(final GoalRoomMembers goalRoomMembers, @@ -242,10 +220,6 @@ public boolean isEmptyGoalRoom() { return goalRoomPendingMembers.isEmpty() && goalRoomMembers.isEmpty(); } - public Optional findGoalRoomTodoByTodoId(final Long todoId) { - return goalRoomToDos.findById(todoId); - } - public void deleteAllPendingMembers() { goalRoomPendingMembers.deleteAll(); } @@ -275,18 +249,14 @@ public GoalRoomStatus getStatus() { return status; } - public RoadmapContent getRoadmapContent() { - return roadmapContent; + public Long getRoadmapContentId() { + return roadmapContentId; } public GoalRoomRoadmapNodes getGoalRoomRoadmapNodes() { return goalRoomRoadmapNodes; } - public GoalRoomToDos getGoalRoomToDos() { - return goalRoomToDos; - } - public GoalRoomPendingMembers getGoalRoomPendingMembers() { return goalRoomPendingMembers; } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomMember.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomMember.java similarity index 61% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomMember.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomMember.java index d99074fcd..58cd1ceb8 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomMember.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomMember.java @@ -1,11 +1,10 @@ -package co.kirikiri.domain.goalroom; +package co.kirikiri.goalroom.domain; -import co.kirikiri.domain.member.Member; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import java.time.LocalDateTime; import lombok.AccessLevel; import lombok.NoArgsConstructor; -import java.time.LocalDateTime; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -15,8 +14,13 @@ public class GoalRoomMember extends BaseGoalRoomMember { private Double accomplishmentRate = 0.0; public GoalRoomMember(final GoalRoomRole role, final LocalDateTime joinedAt, - final GoalRoom goalRoom, final Member member) { - super(role, joinedAt, goalRoom, member); + final GoalRoom goalRoom, final Long memberId) { + super(role, joinedAt, goalRoom, memberId); + } + + public GoalRoomMember(final Long id, final GoalRoomRole role, final LocalDateTime joinedAt, final GoalRoom goalRoom, + final Long memberId) { + super(id, role, joinedAt, goalRoom, memberId); } public void updateAccomplishmentRate(final Double rate) { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomMembers.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomMembers.java similarity index 76% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomMembers.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomMembers.java index f05d9d369..1c2862f13 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomMembers.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomMembers.java @@ -1,7 +1,6 @@ -package co.kirikiri.domain.goalroom; +package co.kirikiri.goalroom.domain; -import co.kirikiri.domain.exception.UnexpectedDomainException; -import co.kirikiri.domain.member.Member; +import co.kirikiri.common.exception.UnexpectedDomainException; import jakarta.persistence.CascadeType; import jakarta.persistence.Embeddable; import jakarta.persistence.FetchType; @@ -38,9 +37,9 @@ public void addAll(final List goalRoomMembers) { this.values.addAll(new ArrayList<>(goalRoomMembers)); } - public Optional findByMember(final Member member) { + public Optional findByMemberId(final Long memberId) { return values.stream() - .filter(value -> value.isSameMember(member)) + .filter(value -> value.isSameMember(memberId)) .findFirst(); } @@ -52,21 +51,21 @@ public Optional findNextLeader() { return Optional.of(values.get(1)); } - public boolean isMember(final Member member) { + public boolean isMember(final Long memberId) { return values.stream() - .anyMatch(value -> value.isSameMember(member)); + .anyMatch(value -> value.isSameMember(memberId)); } - public boolean isNotLeader(final Member member) { - final Member goalRoomLeader = findGoalRoomLeader(); - return !goalRoomLeader.equals(member); + public boolean isNotLeader(final Long memberId) { + final Long goalRoomLeaderId = findGoalRoomLeaderId(); + return !goalRoomLeaderId.equals(memberId); } - public Member findGoalRoomLeader() { + public Long findGoalRoomLeaderId() { return values.stream() .filter(GoalRoomMember::isLeader) .findFirst() - .map(GoalRoomMember::getMember) + .map(GoalRoomMember::getMemberId) .orElseThrow(() -> new UnexpectedDomainException("골룸의 리더가 없습니다.")); } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomPendingMember.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomPendingMember.java similarity index 52% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomPendingMember.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomPendingMember.java index ab671fb74..de7d682ca 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomPendingMember.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomPendingMember.java @@ -1,6 +1,5 @@ -package co.kirikiri.domain.goalroom; +package co.kirikiri.goalroom.domain; -import co.kirikiri.domain.member.Member; import jakarta.persistence.Entity; import java.time.LocalDateTime; import lombok.AccessLevel; @@ -10,22 +9,13 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class GoalRoomPendingMember extends BaseGoalRoomMember { - public GoalRoomPendingMember(final GoalRoomRole role, final Member member) { - super(role, null, null, member); - } - - public GoalRoomPendingMember(final GoalRoomRole role, final GoalRoom goalRoom, final Member member) { - super(role, null, goalRoom, member); - } - - public GoalRoomPendingMember(final GoalRoomRole role, final LocalDateTime joinedAt, - final GoalRoom goalRoom, final Member member) { - super(role, joinedAt, goalRoom, member); + public GoalRoomPendingMember(final GoalRoomRole role, final Long memberId) { + this(null, role, null, null, memberId); } public GoalRoomPendingMember(final Long id, final GoalRoomRole role, final LocalDateTime joinedAt, - final GoalRoom goalRoom, final Member member) { - super(id, role, joinedAt, goalRoom, member); + final GoalRoom goalRoom, final Long memberId) { + super(id, role, joinedAt, goalRoom, memberId); } public void initGoalRoom(final GoalRoom goalRoom) { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomPendingMembers.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomPendingMembers.java similarity index 77% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomPendingMembers.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomPendingMembers.java index 6cd84a26c..3f8924094 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomPendingMembers.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomPendingMembers.java @@ -1,7 +1,6 @@ -package co.kirikiri.domain.goalroom; +package co.kirikiri.goalroom.domain; -import co.kirikiri.domain.exception.UnexpectedDomainException; -import co.kirikiri.domain.member.Member; +import co.kirikiri.common.exception.UnexpectedDomainException; import jakarta.persistence.CascadeType; import jakarta.persistence.Embeddable; import jakarta.persistence.FetchType; @@ -36,34 +35,34 @@ public void add(final GoalRoomPendingMember goalRoomPendingMember) { public boolean containGoalRoomPendingMember(final GoalRoomPendingMember goalRoomPendingMember) { return values.stream() - .anyMatch(value -> value.isSameMember(goalRoomPendingMember.getMember())); + .anyMatch(value -> value.isSameMember(goalRoomPendingMember.getMemberId())); } - public boolean isMember(final Member member) { + public boolean isMember(final Long memberId) { return values.stream() - .anyMatch(value -> value.isSameMember(member)); + .anyMatch(value -> value.isSameMember(memberId)); } public int size() { return values.size(); } - public Member findGoalRoomLeader() { + public Long findGoalRoomLeaderId() { return values.stream() .filter(GoalRoomPendingMember::isLeader) .findFirst() - .map(GoalRoomPendingMember::getMember) + .map(GoalRoomPendingMember::getMemberId) .orElseThrow(() -> new UnexpectedDomainException("골룸의 리더가 없습니다.")); } - public boolean isNotLeader(final Member member) { - final Member goalRoomLeader = findGoalRoomLeader(); - return !goalRoomLeader.equals(member); + public boolean isNotLeader(final Long memberId) { + final Long goalRoomLeaderId = findGoalRoomLeaderId(); + return !goalRoomLeaderId.equals(memberId); } - public Optional findByMember(final Member member) { + public Optional findByMemberId(final Long memberId) { return values.stream() - .filter(value -> value.isSameMember(member)) + .filter(value -> value.isSameMember(memberId)) .findFirst(); } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNode.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomRoadmapNode.java similarity index 71% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNode.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomRoadmapNode.java index a8ec84112..9f0c426b7 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNode.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomRoadmapNode.java @@ -1,14 +1,10 @@ -package co.kirikiri.domain.goalroom; +package co.kirikiri.goalroom.domain; -import co.kirikiri.domain.BaseEntity; -import co.kirikiri.domain.goalroom.exception.GoalRoomException; -import co.kirikiri.domain.goalroom.vo.Period; -import co.kirikiri.domain.roadmap.RoadmapNode; +import co.kirikiri.common.entity.BaseEntity; +import co.kirikiri.goalroom.domain.exception.GoalRoomException; +import co.kirikiri.goalroom.domain.vo.Period; import jakarta.persistence.Embedded; import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; import java.time.LocalDate; import lombok.AccessLevel; import lombok.NoArgsConstructor; @@ -24,21 +20,19 @@ public class GoalRoomRoadmapNode extends BaseEntity { private Integer checkCount; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "roadmap_node_id", nullable = false) - private RoadmapNode roadmapNode; + private Long roadmapNodeId; - public GoalRoomRoadmapNode(final Period period, final Integer checkCount, final RoadmapNode roadmapNode) { - this(null, period, checkCount, roadmapNode); + public GoalRoomRoadmapNode(final Period period, final Integer checkCount, final Long roadmapNodeId) { + this(null, period, checkCount, roadmapNodeId); } public GoalRoomRoadmapNode(final Long id, final Period period, final Integer checkCount, - final RoadmapNode roadmapNode) { + final Long roadmapNodeId) { validate(period, checkCount); this.id = id; this.period = period; this.checkCount = checkCount; - this.roadmapNode = roadmapNode; + this.roadmapNodeId = roadmapNodeId; } private void validate(final Period period, final Integer checkCount) { @@ -74,8 +68,8 @@ public LocalDate getEndDate() { return period.getEndDate(); } - public RoadmapNode getRoadmapNode() { - return roadmapNode; + public Long getRoadmapNodeId() { + return roadmapNodeId; } public int getCheckCount() { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNodes.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomRoadmapNodes.java similarity index 97% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNodes.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomRoadmapNodes.java index 83401f80d..f7458d21d 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNodes.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomRoadmapNodes.java @@ -1,6 +1,6 @@ -package co.kirikiri.domain.goalroom; +package co.kirikiri.goalroom.domain; -import co.kirikiri.domain.goalroom.exception.GoalRoomException; +import co.kirikiri.goalroom.domain.exception.GoalRoomException; import jakarta.persistence.CascadeType; import jakarta.persistence.Embeddable; import jakarta.persistence.FetchType; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomRole.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomRole.java similarity index 57% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomRole.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomRole.java index 1fec95ac2..e7027da50 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomRole.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomRole.java @@ -1,4 +1,4 @@ -package co.kirikiri.domain.goalroom; +package co.kirikiri.goalroom.domain; public enum GoalRoomRole { LEADER, FOLLOWER diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomStatus.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomStatus.java similarity index 64% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomStatus.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomStatus.java index 91e0916ef..374b7ccc6 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomStatus.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/GoalRoomStatus.java @@ -1,4 +1,4 @@ -package co.kirikiri.domain.goalroom; +package co.kirikiri.goalroom.domain; public enum GoalRoomStatus { RECRUITING, RUNNING, COMPLETED diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/exception/GoalRoomException.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/exception/GoalRoomException.java similarity index 59% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/exception/GoalRoomException.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/exception/GoalRoomException.java index 514495361..e25c5dda5 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/exception/GoalRoomException.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/exception/GoalRoomException.java @@ -1,6 +1,6 @@ -package co.kirikiri.domain.goalroom.exception; +package co.kirikiri.goalroom.domain.exception; -import co.kirikiri.domain.exception.DomainException; +import co.kirikiri.common.exception.DomainException; public class GoalRoomException extends DomainException { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/GoalRoomName.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/vo/GoalRoomName.java similarity index 88% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/GoalRoomName.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/vo/GoalRoomName.java index 8893b12de..d9746488e 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/GoalRoomName.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/vo/GoalRoomName.java @@ -1,6 +1,6 @@ -package co.kirikiri.domain.goalroom.vo; +package co.kirikiri.goalroom.domain.vo; -import co.kirikiri.domain.goalroom.exception.GoalRoomException; +import co.kirikiri.goalroom.domain.exception.GoalRoomException; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import lombok.AccessLevel; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/LimitedMemberCount.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/vo/LimitedMemberCount.java similarity index 87% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/LimitedMemberCount.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/vo/LimitedMemberCount.java index 9160fb278..2f2ffe00b 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/LimitedMemberCount.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/vo/LimitedMemberCount.java @@ -1,6 +1,6 @@ -package co.kirikiri.domain.goalroom.vo; +package co.kirikiri.goalroom.domain.vo; -import co.kirikiri.domain.goalroom.exception.GoalRoomException; +import co.kirikiri.goalroom.domain.exception.GoalRoomException; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import lombok.AccessLevel; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/Period.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/vo/Period.java similarity index 94% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/Period.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/vo/Period.java index 881202f46..eabaf447f 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/Period.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/domain/vo/Period.java @@ -1,6 +1,6 @@ -package co.kirikiri.domain.goalroom.vo; +package co.kirikiri.goalroom.domain.vo; -import co.kirikiri.domain.goalroom.exception.GoalRoomException; +import co.kirikiri.goalroom.domain.exception.GoalRoomException; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import java.time.LocalDate; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberJdbcRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomMemberJdbcRepository.java similarity index 60% rename from backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberJdbcRepository.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomMemberJdbcRepository.java index 9a7b2e8b5..af3b6f3b6 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberJdbcRepository.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomMemberJdbcRepository.java @@ -1,6 +1,6 @@ -package co.kirikiri.persistence.goalroom; +package co.kirikiri.goalroom.persistence; -import co.kirikiri.domain.goalroom.GoalRoomMember; +import co.kirikiri.goalroom.domain.GoalRoomMember; import java.util.List; public interface GoalRoomMemberJdbcRepository { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberJdbcRepositoryImpl.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomMemberJdbcRepositoryImpl.java similarity index 87% rename from backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberJdbcRepositoryImpl.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomMemberJdbcRepositoryImpl.java index 28758b191..a54fafa34 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberJdbcRepositoryImpl.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomMemberJdbcRepositoryImpl.java @@ -1,6 +1,6 @@ -package co.kirikiri.persistence.goalroom; +package co.kirikiri.goalroom.persistence; -import co.kirikiri.domain.goalroom.GoalRoomMember; +import co.kirikiri.goalroom.domain.GoalRoomMember; import java.util.List; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; @@ -21,7 +21,7 @@ public void saveAllInBatch(final List goalRoomMembers) { + "VALUES (?, ?, ?, ?, ?)"; jdbcTemplate.batchUpdate(sql, goalRoomMembers, goalRoomMembers.size(), ((ps, goalRoomMember) -> { ps.setLong(1, goalRoomMember.getGoalRoom().getId()); - ps.setLong(2, goalRoomMember.getMember().getId()); + ps.setLong(2, goalRoomMember.getMemberId()); ps.setString(3, goalRoomMember.getRole().name()); ps.setObject(4, goalRoomMember.getJoinedAt()); ps.setDouble(5, goalRoomMember.getAccomplishmentRate()); diff --git a/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomMemberQueryRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomMemberQueryRepository.java new file mode 100644 index 000000000..42a931835 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomMemberQueryRepository.java @@ -0,0 +1,19 @@ +package co.kirikiri.goalroom.persistence; + +import co.kirikiri.goalroom.domain.GoalRoomMember; +import co.kirikiri.goalroom.domain.GoalRoomStatus; +import co.kirikiri.goalroom.persistence.dto.GoalRoomMemberSortType; +import java.util.List; +import java.util.Optional; + +public interface GoalRoomMemberQueryRepository { + + Optional findByRoadmapIdAndMemberIdentifierAndGoalRoomStatus(final Long roadmapId, + final Long memberId, + final GoalRoomStatus status); + + List findByGoalRoomIdOrderedBySortType(final Long goalRoomId, + final GoalRoomMemberSortType sortType); + + Optional findByGoalRoomIdAndMemberId(final Long goalRoomId, final Long memberId); +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberQueryRepositoryImpl.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomMemberQueryRepositoryImpl.java similarity index 58% rename from backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberQueryRepositoryImpl.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomMemberQueryRepositoryImpl.java index 5f83611bb..7f0ad12e8 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberQueryRepositoryImpl.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomMemberQueryRepositoryImpl.java @@ -1,18 +1,14 @@ -package co.kirikiri.persistence.goalroom; +package co.kirikiri.goalroom.persistence; -import static co.kirikiri.domain.goalroom.QGoalRoom.goalRoom; -import static co.kirikiri.domain.goalroom.QGoalRoomMember.goalRoomMember; -import static co.kirikiri.domain.member.QMember.member; -import static co.kirikiri.domain.member.QMemberImage.memberImage; -import static co.kirikiri.domain.roadmap.QRoadmapContent.roadmapContent; -import static co.kirikiri.persistence.goalroom.dto.GoalRoomMemberSortType.ACCOMPLISHMENT_RATE; -import static co.kirikiri.persistence.goalroom.dto.GoalRoomMemberSortType.JOINED_ASC; +import static co.kirikiri.goalroom.domain.QGoalRoom.goalRoom; +import static co.kirikiri.goalroom.domain.QGoalRoomMember.goalRoomMember; +import static co.kirikiri.goalroom.persistence.dto.GoalRoomMemberSortType.ACCOMPLISHMENT_RATE; +import static co.kirikiri.goalroom.persistence.dto.GoalRoomMemberSortType.JOINED_ASC; -import co.kirikiri.domain.goalroom.GoalRoomMember; -import co.kirikiri.domain.goalroom.GoalRoomStatus; -import co.kirikiri.domain.member.vo.Identifier; -import co.kirikiri.persistence.QuerydslRepositorySupporter; -import co.kirikiri.persistence.goalroom.dto.GoalRoomMemberSortType; +import co.kirikiri.common.persistence.QuerydslRepositorySupporter; +import co.kirikiri.goalroom.domain.GoalRoomMember; +import co.kirikiri.goalroom.domain.GoalRoomStatus; +import co.kirikiri.goalroom.persistence.dto.GoalRoomMemberSortType; import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.dsl.BooleanExpression; import java.util.List; @@ -27,18 +23,14 @@ public GoalRoomMemberQueryRepositoryImpl() { @Override public Optional findByRoadmapIdAndMemberIdentifierAndGoalRoomStatus(final Long roadmapId, - final Identifier identifier, + final Long memberId, final GoalRoomStatus status) { return Optional.ofNullable(selectFrom(goalRoomMember) .innerJoin(goalRoomMember.goalRoom, goalRoom) .fetchJoin() - .innerJoin(goalRoom.roadmapContent, roadmapContent) - .fetchJoin() - .innerJoin(goalRoomMember.member, member) .fetchJoin() .where( - goalRoom.roadmapContent.roadmap.id.eq(roadmapId), - member.identifier.eq(identifier), + memberIdCond(memberId), goalRoom.status.eq(status)) .fetchOne()); } @@ -47,15 +39,22 @@ public Optional findByRoadmapIdAndMemberIdentifierAndGoalRoomSta public List findByGoalRoomIdOrderedBySortType(final Long goalRoomId, final GoalRoomMemberSortType sortType) { return selectFrom(goalRoomMember) - .innerJoin(goalRoomMember.member, member) - .fetchJoin() - .innerJoin(member.image, memberImage) - .fetchJoin() .where(goalRoomMember.goalRoom.id.eq(goalRoomId)) .orderBy(sortCond(sortType)) .fetch(); } + @Override + public Optional findByGoalRoomIdAndMemberId(final Long goalRoomId, final Long memberId) { + return Optional.ofNullable(selectFrom(goalRoomMember) + .innerJoin(goalRoomMember.goalRoom, goalRoom) + .fetchJoin() + .where( + goalRoomIdCond(goalRoomId), + memberIdCond(memberId)) + .fetchFirst()); + } + private OrderSpecifier sortCond(final GoalRoomMemberSortType sortType) { if (sortType == null || sortType == ACCOMPLISHMENT_RATE) { return goalRoomMember.accomplishmentRate.desc(); @@ -66,22 +65,11 @@ private OrderSpecifier sortCond(final GoalRoomMemberSortType sortType) { return goalRoomMember.joinedAt.desc(); } - @Override - public Optional findGoalRoomMember(final Long goalRoomId, final Identifier memberIdentifier) { - return Optional.ofNullable(selectFrom(goalRoomMember) - .innerJoin(goalRoomMember.goalRoom, goalRoom) - .where( - goalRoomIdCond(goalRoomId), - memberIdentifierCond(memberIdentifier)) - .fetchJoin() - .fetchFirst()); - } - private BooleanExpression goalRoomIdCond(final Long goalRoomId) { return goalRoom.id.eq(goalRoomId); } - private BooleanExpression memberIdentifierCond(final Identifier memberIdentifier) { - return goalRoomMember.member.identifier.eq(memberIdentifier); + private BooleanExpression memberIdCond(final Long memberId) { + return goalRoomMember.memberId.eq(memberId); } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomMemberRepository.java similarity index 55% rename from backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberRepository.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomMemberRepository.java index aa1f912c8..88d8b6f59 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberRepository.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomMemberRepository.java @@ -1,8 +1,7 @@ -package co.kirikiri.persistence.goalroom; +package co.kirikiri.goalroom.persistence; -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomMember; -import co.kirikiri.domain.member.vo.Identifier; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomMember; import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; @@ -14,16 +13,14 @@ public interface GoalRoomMemberRepository extends JpaRepository findByGoalRoomAndMemberIdentifier( - @Param("goalRoom") final GoalRoom goalRoom, @Param("identifier") final Identifier identifier); + + "and gm.memberId =:memberId") + Optional findByGoalRoomAndMemberId( + @Param("goalRoom") final GoalRoom goalRoom, + @Param("memberId") final Long memberId); @Query("select gm from GoalRoomMember gm " + "join fetch gm.goalRoom g " - + "join fetch gm.member m " - + "where g=:goalRoom " - + "and gm.member = m") + + "where g=:goalRoom ") List findAllByGoalRoom(@Param("goalRoom") final GoalRoom goalRoom); } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomPendingMemberQueryRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomPendingMemberQueryRepository.java similarity index 63% rename from backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomPendingMemberQueryRepository.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomPendingMemberQueryRepository.java index ab5d88527..639e3aba2 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomPendingMemberQueryRepository.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomPendingMemberQueryRepository.java @@ -1,7 +1,7 @@ -package co.kirikiri.persistence.goalroom; +package co.kirikiri.goalroom.persistence; -import co.kirikiri.domain.goalroom.GoalRoomPendingMember; -import co.kirikiri.persistence.goalroom.dto.GoalRoomMemberSortType; +import co.kirikiri.goalroom.domain.GoalRoomPendingMember; +import co.kirikiri.goalroom.persistence.dto.GoalRoomMemberSortType; import java.util.List; public interface GoalRoomPendingMemberQueryRepository { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomPendingMemberQueryRepositoryImpl.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomPendingMemberQueryRepositoryImpl.java similarity index 61% rename from backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomPendingMemberQueryRepositoryImpl.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomPendingMemberQueryRepositoryImpl.java index 036c074d8..32d6d0064 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomPendingMemberQueryRepositoryImpl.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomPendingMemberQueryRepositoryImpl.java @@ -1,13 +1,11 @@ -package co.kirikiri.persistence.goalroom; +package co.kirikiri.goalroom.persistence; -import static co.kirikiri.domain.goalroom.QGoalRoomPendingMember.goalRoomPendingMember; -import static co.kirikiri.domain.member.QMember.member; -import static co.kirikiri.domain.member.QMemberImage.memberImage; -import static co.kirikiri.persistence.goalroom.dto.GoalRoomMemberSortType.JOINED_DESC; +import static co.kirikiri.goalroom.domain.QGoalRoomPendingMember.goalRoomPendingMember; +import static co.kirikiri.goalroom.persistence.dto.GoalRoomMemberSortType.JOINED_DESC; -import co.kirikiri.domain.goalroom.GoalRoomPendingMember; -import co.kirikiri.persistence.QuerydslRepositorySupporter; -import co.kirikiri.persistence.goalroom.dto.GoalRoomMemberSortType; +import co.kirikiri.common.persistence.QuerydslRepositorySupporter; +import co.kirikiri.goalroom.domain.GoalRoomPendingMember; +import co.kirikiri.goalroom.persistence.dto.GoalRoomMemberSortType; import com.querydsl.core.types.OrderSpecifier; import java.util.List; @@ -22,10 +20,6 @@ public GoalRoomPendingMemberQueryRepositoryImpl() { public List findByGoalRoomIdOrderedBySortType(final Long goalRoomId, final GoalRoomMemberSortType sortType) { return selectFrom(goalRoomPendingMember) - .innerJoin(goalRoomPendingMember.member, member) - .fetchJoin() - .innerJoin(member.image, memberImage) - .fetchJoin() .where(goalRoomPendingMember.goalRoom.id.eq(goalRoomId)) .orderBy(sortCond(sortType)) .fetch(); diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomPendingMemberRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomPendingMemberRepository.java similarity index 67% rename from backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomPendingMemberRepository.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomPendingMemberRepository.java index cdd2d45db..f197cd5b1 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomPendingMemberRepository.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomPendingMemberRepository.java @@ -1,8 +1,7 @@ -package co.kirikiri.persistence.goalroom; +package co.kirikiri.goalroom.persistence; -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomPendingMember; -import co.kirikiri.domain.member.vo.Identifier; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomPendingMember; import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; @@ -15,19 +14,16 @@ public interface GoalRoomPendingMemberRepository extends JpaRepository findByGoalRoomAndMemberIdentifier( - @Param("goalRoom") final GoalRoom goalRoom, @Param("identifier") final Identifier identifier); + + "and gp.memberId =:memberId") + Optional findByGoalRoomAndMemberId( + @Param("goalRoom") final GoalRoom goalRoom, @Param("memberId") final Long memberId); List findByGoalRoom(final GoalRoom goalRoom); @Query("select gp from GoalRoomPendingMember gp " + "join fetch gp.goalRoom g " - + "join fetch gp.member m " - + "where g=:goalRoom " - + "and gp.member = m") + + "where g=:goalRoom ") List findAllByGoalRoom(@Param("goalRoom") final GoalRoom goalRoom); @Modifying diff --git a/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomQueryRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomQueryRepository.java new file mode 100644 index 000000000..b78e09706 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomQueryRepository.java @@ -0,0 +1,26 @@ +package co.kirikiri.goalroom.persistence; + +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomStatus; +import co.kirikiri.goalroom.persistence.dto.RoadmapGoalRoomsOrderType; +import java.time.LocalDate; +import java.util.List; +import java.util.Optional; + +public interface GoalRoomQueryRepository { + + Optional findGoalRoomByIdWithPessimisticLock(Long goalRoomId); + + List findGoalRoomsByRoadmapContentIdAndCond(final Long roadmapContentId, + final RoadmapGoalRoomsOrderType filterType, + final Long lastId, + final int pageSize); + + List findByMemberId(final Long memberId); + + List findByMemberAndStatus(final Long memberId, final GoalRoomStatus goalRoomStatus); + + Optional findByIdWithNodes(final Long goalRoomId); + + List findAllRecruitingGoalRoomsByStartDateEarlierThan(final LocalDate startDate); +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomQueryRepositoryImpl.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomQueryRepositoryImpl.java similarity index 55% rename from backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomQueryRepositoryImpl.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomQueryRepositoryImpl.java index dad601666..aa4a25e4c 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomQueryRepositoryImpl.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomQueryRepositoryImpl.java @@ -1,18 +1,14 @@ -package co.kirikiri.persistence.goalroom; - -import static co.kirikiri.domain.goalroom.QGoalRoom.goalRoom; -import static co.kirikiri.domain.goalroom.QGoalRoomMember.goalRoomMember; -import static co.kirikiri.domain.goalroom.QGoalRoomPendingMember.goalRoomPendingMember; -import static co.kirikiri.domain.goalroom.QGoalRoomRoadmapNode.goalRoomRoadmapNode; -import static co.kirikiri.domain.goalroom.QGoalRoomToDo.goalRoomToDo; -import static co.kirikiri.domain.roadmap.QRoadmapContent.roadmapContent; - -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomStatus; -import co.kirikiri.domain.member.Member; -import co.kirikiri.domain.roadmap.Roadmap; -import co.kirikiri.persistence.QuerydslRepositorySupporter; -import co.kirikiri.persistence.goalroom.dto.RoadmapGoalRoomsOrderType; +package co.kirikiri.goalroom.persistence; + +import static co.kirikiri.goalroom.domain.QGoalRoom.goalRoom; +import static co.kirikiri.goalroom.domain.QGoalRoomMember.goalRoomMember; +import static co.kirikiri.goalroom.domain.QGoalRoomPendingMember.goalRoomPendingMember; +import static co.kirikiri.goalroom.domain.QGoalRoomRoadmapNode.goalRoomRoadmapNode; + +import co.kirikiri.common.persistence.QuerydslRepositorySupporter; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomStatus; +import co.kirikiri.goalroom.persistence.dto.RoadmapGoalRoomsOrderType; import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.dsl.BooleanExpression; import jakarta.persistence.LockModeType; @@ -39,68 +35,37 @@ public Optional findGoalRoomByIdWithPessimisticLock(final Long goalRoo } @Override - public Optional findByIdWithRoadmapContent(final Long goalRoomId) { - return Optional.ofNullable(selectFrom(goalRoom) - .innerJoin(goalRoom.roadmapContent, roadmapContent) - .fetchJoin() - .where(goalRoomIdCond(goalRoomId)) - .fetchFirst()); - } - - @Override - public Optional findByIdWithContentAndTodos(final Long goalRoomId) { - return Optional.ofNullable(selectFrom(goalRoom) - .innerJoin(goalRoom.roadmapContent, roadmapContent) - .fetchJoin() - .leftJoin(goalRoom.goalRoomToDos.values, goalRoomToDo) - .fetchJoin() - .where(goalRoomIdCond(goalRoomId)) - .fetchOne()); - } - - @Override - public List findGoalRoomsByRoadmapAndCond(final Roadmap roadmap, - final RoadmapGoalRoomsOrderType orderType, - final Long lastId, - final int pageSize) { + public List findGoalRoomsByRoadmapContentIdAndCond(final Long roadmapContentId, + final RoadmapGoalRoomsOrderType orderType, + final Long lastId, + final int pageSize) { return selectFrom(goalRoom) - .innerJoin(goalRoom.roadmapContent, roadmapContent) - .on(roadmapContent.roadmap.eq(roadmap)) .where( statusCond(orderType), lessThanLastId(lastId, orderType), - roadmapCond(roadmap)) + roadmapContentIdCond(roadmapContentId)) .limit(pageSize + LIMIT_OFFSET) .orderBy(sortCond(orderType)) .fetch(); } @Override - public Optional findByIdWithTodos(final Long goalRoomId) { - return Optional.ofNullable(selectFrom(goalRoom) - .leftJoin(goalRoom.goalRoomToDos.values, goalRoomToDo) - .fetchJoin() - .where(goalRoomIdCond(goalRoomId)) - .fetchFirst()); - } - - @Override - public List findByMember(final Member member) { + public List findByMemberId(final Long memberId) { return selectFrom(goalRoom) .leftJoin(goalRoom.goalRoomPendingMembers.values, goalRoomPendingMember) .leftJoin(goalRoom.goalRoomMembers.values, goalRoomMember) - .where(goalRoomPendingMember.member.eq(member) - .or(goalRoomMember.member.eq(member))) + .where(goalRoomPendingMember.memberId.eq(memberId) + .or(goalRoomMember.memberId.eq(memberId))) .fetch(); } @Override - public List findByMemberAndStatus(final Member member, final GoalRoomStatus goalRoomStatus) { + public List findByMemberAndStatus(final Long memberId, final GoalRoomStatus goalRoomStatus) { return selectFrom(goalRoom) .leftJoin(goalRoom.goalRoomPendingMembers.values, goalRoomPendingMember) .leftJoin(goalRoom.goalRoomMembers.values, goalRoomMember) - .where(goalRoomPendingMember.member.eq(member) - .or(goalRoomMember.member.eq(member))) + .where(goalRoomPendingMember.memberId.eq(memberId) + .or(goalRoomMember.memberId.eq(memberId))) .where(statusCond(goalRoomStatus)) .fetch(); } @@ -110,20 +75,10 @@ public Optional findByIdWithNodes(final Long goalRoomId) { return Optional.ofNullable(selectFrom(goalRoom) .innerJoin(goalRoom.goalRoomRoadmapNodes.values, goalRoomRoadmapNode) .fetchJoin() - .innerJoin(goalRoom.roadmapContent, roadmapContent) - .fetchJoin() .where(goalRoomIdCond(goalRoomId)) .fetchOne()); } - @Override - public List findByRoadmap(final Roadmap roadmap) { - return selectFrom(goalRoom) - .innerJoin(goalRoom.roadmapContent, roadmapContent) - .where(roadmapContent.roadmap.eq(roadmap)) - .fetch(); - } - @Override public List findAllRecruitingGoalRoomsByStartDateEarlierThan(final LocalDate date) { return selectFrom(goalRoom) @@ -173,8 +128,8 @@ private BooleanExpression lessThanLastId(final Long lastId, final RoadmapGoalRoo ); } - private BooleanExpression roadmapCond(final Roadmap roadmap) { - return goalRoom.roadmapContent.roadmap.eq(roadmap); + private BooleanExpression roadmapContentIdCond(final Long roadmapContentId) { + return goalRoom.roadmapContentId.eq(roadmapContentId); } private BooleanExpression equalOrEarlierStartDateThan(final LocalDate date) { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomRepository.java similarity index 67% rename from backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomRepository.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomRepository.java index 7f517ae99..2983599e1 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomRepository.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/GoalRoomRepository.java @@ -1,14 +1,17 @@ -package co.kirikiri.persistence.goalroom; +package co.kirikiri.goalroom.persistence; -import co.kirikiri.domain.goalroom.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoom; import java.time.LocalDate; import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; public interface GoalRoomRepository extends JpaRepository, GoalRoomQueryRepository { - + + @Override Optional findById(final Long goalRoomId); List findAllByEndDate(final LocalDate endDate); + + List findByRoadmapContentId(final Long roadmapContentId); } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/dto/GoalRoomFilterType.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/dto/GoalRoomFilterType.java similarity index 59% rename from backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/dto/GoalRoomFilterType.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/dto/GoalRoomFilterType.java index a102fa9eb..e4e413143 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/dto/GoalRoomFilterType.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/dto/GoalRoomFilterType.java @@ -1,4 +1,4 @@ -package co.kirikiri.persistence.goalroom.dto; +package co.kirikiri.goalroom.persistence.dto; public enum GoalRoomFilterType { LATEST, PARTICIPATION_RATE diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/dto/GoalRoomMemberSortType.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/dto/GoalRoomMemberSortType.java similarity index 87% rename from backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/dto/GoalRoomMemberSortType.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/dto/GoalRoomMemberSortType.java index 417a74f29..14f935c26 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/dto/GoalRoomMemberSortType.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/dto/GoalRoomMemberSortType.java @@ -1,4 +1,4 @@ -package co.kirikiri.persistence.goalroom.dto; +package co.kirikiri.goalroom.persistence.dto; public enum GoalRoomMemberSortType { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/dto/RoadmapGoalRoomsOrderType.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/dto/RoadmapGoalRoomsOrderType.java similarity index 61% rename from backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/dto/RoadmapGoalRoomsOrderType.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/dto/RoadmapGoalRoomsOrderType.java index 17a5256d3..746c9453f 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/dto/RoadmapGoalRoomsOrderType.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/persistence/dto/RoadmapGoalRoomsOrderType.java @@ -1,4 +1,4 @@ -package co.kirikiri.persistence.goalroom.dto; +package co.kirikiri.goalroom.persistence.dto; public enum RoadmapGoalRoomsOrderType { LATEST, CLOSE_TO_DEADLINE diff --git a/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/DashBoardCheckFeedService.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/DashBoardCheckFeedService.java new file mode 100644 index 000000000..43c492463 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/DashBoardCheckFeedService.java @@ -0,0 +1,13 @@ +package co.kirikiri.goalroom.service; + +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNode; +import co.kirikiri.goalroom.service.dto.response.DashBoardCheckFeedResponse; +import java.util.List; +import java.util.Optional; + +public interface DashBoardCheckFeedService { + + List findCheckFeedsByNodeAndGoalRoomStatus(final GoalRoom goalRoom, + final Optional currentGoalRoomRoadmapNode); +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/DashBoardToDoService.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/DashBoardToDoService.java new file mode 100644 index 000000000..7811f228d --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/DashBoardToDoService.java @@ -0,0 +1,10 @@ +package co.kirikiri.goalroom.service; + +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.service.dto.response.DashBoardToDoResponse; +import java.util.List; + +public interface DashBoardToDoService { + + List findMemberCheckedGoalRoomToDoIds(final GoalRoom goalRoom, final Long memberId); +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/GoalRoomCreateService.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/GoalRoomCreateService.java new file mode 100644 index 000000000..0817e3417 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/GoalRoomCreateService.java @@ -0,0 +1,153 @@ +package co.kirikiri.goalroom.service; + +import co.kirikiri.common.aop.ExceptionConvert; +import co.kirikiri.common.exception.BadRequestException; +import co.kirikiri.common.exception.NotFoundException; +import co.kirikiri.domain.member.Member; +import co.kirikiri.domain.member.vo.Identifier; +import co.kirikiri.domain.roadmap.Roadmap; +import co.kirikiri.domain.roadmap.RoadmapContent; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomMember; +import co.kirikiri.goalroom.domain.GoalRoomPendingMember; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNodes; +import co.kirikiri.goalroom.persistence.GoalRoomRepository; +import co.kirikiri.goalroom.service.dto.GoalRoomCreateDto; +import co.kirikiri.goalroom.service.dto.request.GoalRoomCreateRequest; +import co.kirikiri.goalroom.service.mapper.GoalRoomMapper; +import co.kirikiri.persistence.member.MemberRepository; +import co.kirikiri.persistence.roadmap.RoadmapContentRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +@RequiredArgsConstructor +@ExceptionConvert +public class GoalRoomCreateService { + + private final GoalRoomRepository goalRoomRepository; + private final RoadmapContentRepository roadmapContentRepository; + private final MemberRepository memberRepository; + + public Long create(final GoalRoomCreateRequest goalRoomCreateRequest, final String memberIdentifier) { + final GoalRoomCreateDto goalRoomCreateDto = GoalRoomMapper.convertToGoalRoomCreateDto(goalRoomCreateRequest); + final RoadmapContent roadmapContent = findRoadmapContentById(goalRoomCreateDto.roadmapContentId()); + validateDeletedRoadmap(roadmapContent); + validateNodeSizeEqual(roadmapContent.nodesSize(), goalRoomCreateDto.goalRoomRoadmapNodeDtosSize()); + final GoalRoomRoadmapNodes goalRoomRoadmapNodes = GoalRoomMapper.convertToGoalRoomRoadmapNodes( + goalRoomCreateDto.goalRoomRoadmapNodeDtos(), roadmapContent); + final Member leader = findMemberByIdentifier(memberIdentifier); + + final GoalRoom goalRoom = new GoalRoom(goalRoomCreateDto.goalRoomName(), goalRoomCreateDto.limitedMemberCount(), + roadmapContent.getId(), leader.getId()); + validateGoalRoomRoadmapNodeSize(goalRoom, goalRoomRoadmapNodes, roadmapContent); + goalRoom.addAllGoalRoomRoadmapNodes(goalRoomRoadmapNodes); + return goalRoomRepository.save(goalRoom).getId(); + } + + private void validateGoalRoomRoadmapNodeSize(final GoalRoom goalRoom, final GoalRoomRoadmapNodes goalRoomRoadmapNodes, + final RoadmapContent roadmapContent) { + final int totalSize = goalRoomRoadmapNodes.size() + goalRoom.goalRoomRoadmapNodeSize(); + if (totalSize > roadmapContent.nodesSize()) { + throw new BadRequestException("로드맵의 노드 수보다 골룸의 노드 수가 큽니다."); + } + } + + private RoadmapContent findRoadmapContentById(final Long roadmapContentId) { + return roadmapContentRepository.findByIdWithRoadmap(roadmapContentId) + .orElseThrow(() -> new NotFoundException("존재하지 않는 로드맵입니다.")); + } + + private void validateDeletedRoadmap(final RoadmapContent roadmapContent) { + final Roadmap roadmap = roadmapContent.getRoadmap(); + if (roadmap.isDeleted()) { + throw new BadRequestException("삭제된 로드맵에 대해 골룸을 생성할 수 없습니다."); + } + } + + private void validateNodeSizeEqual(final int roadmapNodesSize, final int goalRoomRoadmapNodeDtosSize) { + if (roadmapNodesSize != goalRoomRoadmapNodeDtosSize) { + throw new BadRequestException("모든 노드에 대해 기간이 설정돼야 합니다."); + } + } + + private Member findMemberByIdentifier(final String memberIdentifier) { + return memberRepository.findByIdentifier(new Identifier(memberIdentifier)) + .orElseThrow(() -> new NotFoundException("존재하지 않는 회원입니다.")); + } + + public void join(final String identifier, final Long goalRoomId) { + final Member member = findMemberByIdentifier(identifier); + final GoalRoom goalRoom = findGoalRoomByIdWithPessimisticLock(goalRoomId); + goalRoom.join(member.getId()); + } + + private GoalRoom findGoalRoomByIdWithPessimisticLock(final Long goalRoomId) { + return goalRoomRepository.findGoalRoomByIdWithPessimisticLock(goalRoomId) + .orElseThrow(() -> new NotFoundException("존재하지 않는 골룸입니다. goalRoomId = " + goalRoomId)); + } + + public void leave(final String identifier, final Long goalRoomId) { + final Member member = findMemberByIdentifier(identifier); + final GoalRoom goalRoom = findGoalRoomById(goalRoomId); + validateStatus(goalRoom); + goalRoom.leave(member.getId()); + if (goalRoom.isEmptyGoalRoom()) { + goalRoomRepository.delete(goalRoom); + } + } + + private GoalRoom findGoalRoomById(final Long goalRoomId) { + return goalRoomRepository.findById(goalRoomId) + .orElseThrow(() -> new NotFoundException("존재하지 않는 골룸입니다. goalRoomId = " + goalRoomId)); + } + + private void validateStatus(final GoalRoom goalRoom) { + if (goalRoom.isRunning()) { + throw new BadRequestException("진행중인 골룸에서는 나갈 수 없습니다."); + } + } + + public void startGoalRoom(final String memberIdentifier, final Long goalRoomId) { + final Member member = findMemberByIdentifier(memberIdentifier); + final GoalRoom goalRoom = findGoalRoomById(goalRoomId); + checkGoalRoomLeader(member.getId(), goalRoom); + validateGoalRoomStart(goalRoom); + final List goalRoomPendingMembers = goalRoom.getGoalRoomPendingMembers().getValues(); + saveGoalRoomMemberFromPendingMembers(goalRoomPendingMembers, goalRoom); + goalRoom.start(); + } + + private void checkGoalRoomLeader(final Long memberId, final GoalRoom goalRoom) { + if (goalRoom.isNotLeader(memberId)) { + throw new BadRequestException("골룸의 리더만 골룸을 시작할 수 있습니다."); + } + } + + private void validateGoalRoomStart(final GoalRoom goalRoom) { + if (goalRoom.cannotStart()) { + throw new BadRequestException("골룸의 시작 날짜가 되지 않았습니다."); + } + } + + private void saveGoalRoomMemberFromPendingMembers(final List goalRoomPendingMembers, + final GoalRoom goalRoom) { + final List goalRoomMembers = makeGoalRoomMembers(goalRoomPendingMembers); + goalRoom.addAllGoalRoomMembers(goalRoomMembers); + goalRoom.deleteAllPendingMembers(); + } + + private List makeGoalRoomMembers(final List goalRoomPendingMembers) { + return goalRoomPendingMembers.stream() + .map(this::makeGoalRoomMember) + .toList(); + } + + private GoalRoomMember makeGoalRoomMember(final GoalRoomPendingMember goalRoomPendingMember) { + return new GoalRoomMember(goalRoomPendingMember.getRole(), goalRoomPendingMember.getJoinedAt(), + goalRoomPendingMember.getGoalRoom(), goalRoomPendingMember.getMemberId()); + } +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/goalroom/GoalRoomReadService.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/GoalRoomReadService.java similarity index 55% rename from backend/kirikiri/src/main/java/co/kirikiri/service/goalroom/GoalRoomReadService.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/GoalRoomReadService.java index 09480bbef..40aa9ea7c 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/goalroom/GoalRoomReadService.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/GoalRoomReadService.java @@ -1,51 +1,46 @@ -package co.kirikiri.service.goalroom; - -import co.kirikiri.domain.goalroom.CheckFeed; -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomMember; -import co.kirikiri.domain.goalroom.GoalRoomPendingMember; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNode; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNodes; -import co.kirikiri.domain.goalroom.GoalRoomStatus; -import co.kirikiri.domain.goalroom.GoalRoomToDoCheck; -import co.kirikiri.domain.goalroom.GoalRoomToDos; +package co.kirikiri.goalroom.service; + +import co.kirikiri.common.aop.ExceptionConvert; +import co.kirikiri.common.exception.ForbiddenException; +import co.kirikiri.common.exception.NotFoundException; +import co.kirikiri.common.service.FileService; import co.kirikiri.domain.member.Member; import co.kirikiri.domain.member.vo.Identifier; +import co.kirikiri.domain.roadmap.RoadmapContent; import co.kirikiri.domain.roadmap.RoadmapNode; -import co.kirikiri.persistence.goalroom.CheckFeedRepository; -import co.kirikiri.persistence.goalroom.GoalRoomMemberRepository; -import co.kirikiri.persistence.goalroom.GoalRoomPendingMemberRepository; -import co.kirikiri.persistence.goalroom.GoalRoomRepository; -import co.kirikiri.persistence.goalroom.GoalRoomToDoCheckRepository; -import co.kirikiri.persistence.goalroom.dto.GoalRoomMemberSortType; +import co.kirikiri.domain.roadmap.RoadmapNodes; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomMember; +import co.kirikiri.goalroom.domain.GoalRoomPendingMember; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNode; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNodes; +import co.kirikiri.goalroom.domain.GoalRoomStatus; +import co.kirikiri.goalroom.persistence.GoalRoomMemberRepository; +import co.kirikiri.goalroom.persistence.GoalRoomPendingMemberRepository; +import co.kirikiri.goalroom.persistence.GoalRoomRepository; +import co.kirikiri.goalroom.persistence.dto.GoalRoomMemberSortType; +import co.kirikiri.goalroom.service.dto.GoalRoomMemberDto; +import co.kirikiri.goalroom.service.dto.GoalRoomMemberSortTypeDto; +import co.kirikiri.goalroom.service.dto.GoalRoomRoadmapNodeDetailDto; +import co.kirikiri.goalroom.service.dto.MemberDto; +import co.kirikiri.goalroom.service.dto.MemberGoalRoomForListDto; +import co.kirikiri.goalroom.service.dto.request.GoalRoomStatusTypeRequest; +import co.kirikiri.goalroom.service.dto.response.DashBoardCheckFeedResponse; +import co.kirikiri.goalroom.service.dto.response.DashBoardToDoResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomCertifiedResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomMemberResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomRoadmapNodeDetailResponse; +import co.kirikiri.goalroom.service.dto.response.MemberGoalRoomForListResponse; +import co.kirikiri.goalroom.service.dto.response.MemberGoalRoomResponse; +import co.kirikiri.goalroom.service.mapper.GoalRoomMapper; import co.kirikiri.persistence.member.MemberRepository; -import co.kirikiri.service.FileService; -import co.kirikiri.service.aop.ExceptionConvert; -import co.kirikiri.service.dto.goalroom.CheckFeedDto; -import co.kirikiri.service.dto.goalroom.GoalRoomCheckFeedDto; -import co.kirikiri.service.dto.goalroom.GoalRoomMemberDto; -import co.kirikiri.service.dto.goalroom.GoalRoomMemberSortTypeDto; -import co.kirikiri.service.dto.goalroom.GoalRoomRoadmapNodeDetailDto; -import co.kirikiri.service.dto.goalroom.MemberGoalRoomForListDto; -import co.kirikiri.service.dto.goalroom.request.GoalRoomStatusTypeRequest; -import co.kirikiri.service.dto.goalroom.response.GoalRoomCertifiedResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomCheckFeedResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomMemberResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomRoadmapNodeDetailResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomTodoResponse; -import co.kirikiri.service.dto.member.MemberDto; -import co.kirikiri.service.dto.member.response.MemberGoalRoomForListResponse; -import co.kirikiri.service.dto.member.response.MemberGoalRoomResponse; -import co.kirikiri.service.exception.ForbiddenException; -import co.kirikiri.service.exception.NotFoundException; -import co.kirikiri.service.mapper.GoalRoomMapper; +import co.kirikiri.persistence.roadmap.RoadmapContentRepository; +import co.kirikiri.persistence.roadmap.RoadmapNodeRepository; import java.net.URL; import java.time.LocalDate; -import java.util.Collections; import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Service; @@ -57,35 +52,49 @@ @ExceptionConvert public class GoalRoomReadService { - private final MemberRepository memberRepository; private final GoalRoomRepository goalRoomRepository; private final GoalRoomMemberRepository goalRoomMemberRepository; - private final GoalRoomToDoCheckRepository goalRoomToDoCheckRepository; private final GoalRoomPendingMemberRepository goalRoomPendingMemberRepository; - private final CheckFeedRepository checkFeedRepository; + private final DashBoardToDoService dashBoardToDoService; + private final DashBoardCheckFeedService dashBoardCheckFeedService; + private final RoadmapContentRepository roadmapContentRepository; + private final RoadmapNodeRepository roadmapNodeRepository; + private final MemberRepository memberRepository; private final FileService fileService; - public GoalRoomResponse findGoalRoom(final Long goalRoomId) { + public GoalRoomCertifiedResponse findGoalRoom(final String identifier, final Long goalRoomId) { final GoalRoom goalRoom = findGoalRoomWithRoadmapContentById(goalRoomId); - return GoalRoomMapper.convertGoalRoomResponse(goalRoom); + final RoadmapContent roadmapContent = findRoadmapContentById(goalRoom.getRoadmapContentId()); + final List roadmapNodes = roadmapNodeRepository.findAllByRoadmapContent(roadmapContent); + + final boolean isJoined = isMemberGoalRoomJoin(new Identifier(identifier), goalRoom); + return GoalRoomMapper.convertGoalRoomCertifiedResponse(goalRoom, new RoadmapNodes(roadmapNodes), isJoined); } private GoalRoom findGoalRoomWithRoadmapContentById(final Long goalRoomId) { - return goalRoomRepository.findByIdWithRoadmapContent(goalRoomId) + return goalRoomRepository.findById(goalRoomId) .orElseThrow(() -> new NotFoundException("골룸 정보가 존재하지 않습니다. goalRoomId = " + goalRoomId)); } - public GoalRoomCertifiedResponse findGoalRoom(final String identifier, final Long goalRoomId) { - final GoalRoom goalRoom = findGoalRoomWithRoadmapContentById(goalRoomId); - final boolean isJoined = isMemberGoalRoomJoin(new Identifier(identifier), goalRoom); - return GoalRoomMapper.convertGoalRoomCertifiedResponse(goalRoom, isJoined); + private RoadmapContent findRoadmapContentById(final Long roadmapContentId) { + return roadmapContentRepository.findById(roadmapContentId) + .orElseThrow(() -> new NotFoundException( + "존재하지 않는 로드맵 컨텐츠 아이디입니다. roadmapContentId = " + roadmapContentId)); } private boolean isMemberGoalRoomJoin(final Identifier identifier, final GoalRoom goalRoom) { + final Member member = findMemberByIdentifier(identifier); if (goalRoom.isRecruiting()) { - return goalRoomPendingMemberRepository.findByGoalRoomAndMemberIdentifier(goalRoom, identifier).isPresent(); + return goalRoomPendingMemberRepository.findByGoalRoomAndMemberId(goalRoom, member.getId()).isPresent(); } - return goalRoomMemberRepository.findByGoalRoomAndMemberIdentifier(goalRoom, identifier).isPresent(); + return goalRoomMemberRepository.findByGoalRoomAndMemberId(goalRoom, member.getId()).isPresent(); + } + + public GoalRoomResponse findGoalRoom(final Long goalRoomId) { + final GoalRoom goalRoom = findGoalRoomWithRoadmapContentById(goalRoomId); + final RoadmapContent roadmapContent = findRoadmapContentById(goalRoom.getRoadmapContentId()); + final List roadmapNodes = roadmapNodeRepository.findAllByRoadmapContent(roadmapContent); + return GoalRoomMapper.convertGoalRoomResponse(goalRoom, new RoadmapNodes(roadmapNodes)); } public List findGoalRoomMembers(final Long goalRoomId, @@ -119,12 +128,18 @@ private List makeGoalRoomMemberDtosWithAccomplishmentRateZero private GoalRoomMemberDto makeGoalRoomMemberDtoWithAccomplishmentRateZero( final GoalRoomPendingMember goalRoomPendingMember) { - final Member member = goalRoomPendingMember.getMember(); + final Long memberId = goalRoomPendingMember.getMemberId(); + final Member member = findMemberWithImageById(memberId); final URL memberImageUrl = fileService.generateUrl(member.getImage().getServerFilePath(), HttpMethod.GET); return new GoalRoomMemberDto(member.getId(), member.getNickname().getValue(), memberImageUrl.toExternalForm(), 0D); } + private Member findMemberWithImageById(final Long memberId) { + return memberRepository.findWithMemberImageById(memberId) + .orElseThrow(() -> new NotFoundException("존재하지 않는 골룸 멤버입니다. memberId = " + memberId)); + } + private List makeGoalRoomMemberDtos( final List goalRoomPendingMembers) { return goalRoomPendingMembers.stream() @@ -133,62 +148,31 @@ private List makeGoalRoomMemberDtos( } private GoalRoomMemberDto makeGoalRoomMemberDto(final GoalRoomMember goalRoomMember) { - final Member member = goalRoomMember.getMember(); + final Long memberId = goalRoomMember.getMemberId(); + final Member member = findMemberWithImageById(memberId); final URL memberImageUrl = fileService.generateUrl(member.getImage().getServerFilePath(), HttpMethod.GET); return new GoalRoomMemberDto(member.getId(), member.getNickname().getValue(), memberImageUrl.toExternalForm(), goalRoomMember.getAccomplishmentRate()); } - public List findAllGoalRoomTodo(final Long goalRoomId, final String identifier) { - final GoalRoomToDos goalRoomToDos = findGoalRoomTodosByGoalRoomId(goalRoomId); - validateGoalRoomMember(goalRoomId, identifier); - final List checkedTodos = findMemberCheckedGoalRoomToDoIds(goalRoomId, identifier); - return GoalRoomMapper.convertGoalRoomTodoResponses(goalRoomToDos, checkedTodos); - } - - private void validateGoalRoomMember(final Long goalRoomId, final String identifier) { - if (goalRoomMemberRepository.findGoalRoomMember(goalRoomId, new Identifier(identifier)).isEmpty()) { - throw new ForbiddenException( - "골룸에 참여하지 않은 사용자입니다. goalRoomId = " + goalRoomId + " memberIdentifier = " + identifier); - } - } - - private GoalRoomToDos findGoalRoomTodosByGoalRoomId(final Long goalRoomId) { - return goalRoomRepository.findByIdWithTodos(goalRoomId) - .orElseThrow(() -> new NotFoundException("존재하지 않는 골룸입니다. goalRoomId = " + goalRoomId)) - .getGoalRoomToDos(); - } - - private List findMemberCheckedGoalRoomToDoIds(final Long goalRoomId, final String identifier) { - return goalRoomToDoCheckRepository.findByGoalRoomIdAndMemberIdentifier(goalRoomId, new Identifier(identifier)); - } - public MemberGoalRoomResponse findMemberGoalRoom(final String identifier, final Long goalRoomId) { - final GoalRoom goalRoom = findMemberGoalRoomById(goalRoomId); + final GoalRoom goalRoom = findGoalRoomWithNodesById(goalRoomId); final Member member = findMemberByIdentifier(new Identifier(identifier)); - validateMemberInGoalRoom(goalRoom, member); + validateMemberInGoalRoom(goalRoom, member.getId()); + final RoadmapContent roadmapContent = findRoadmapContentById(goalRoom.getRoadmapContentId()); + final List roadmapNodes = roadmapNodeRepository.findAllByRoadmapContent(roadmapContent); final Optional currentGoalRoomRoadmapNode = findCurrentGoalRoomNode(goalRoom); - final List checkFeeds = findCheckFeedsByNodeAndGoalRoomStatus(goalRoom, currentGoalRoomRoadmapNode); - final List checkedTodos = findMemberCheckedGoalRoomToDoIds(goalRoomId, identifier); - final List checkFeedDtos = makeCheckFeedDtos(checkFeeds); - return GoalRoomMapper.convertToMemberGoalRoomResponse(goalRoom, checkFeedDtos, checkedTodos); + final List checkFeeds = dashBoardCheckFeedService.findCheckFeedsByNodeAndGoalRoomStatus( + goalRoom, currentGoalRoomRoadmapNode); + final List checkedTodos = dashBoardToDoService.findMemberCheckedGoalRoomToDoIds( + goalRoom, member.getId()); + return GoalRoomMapper.convertToMemberGoalRoomResponse(goalRoom, new RoadmapNodes(roadmapNodes), checkFeeds, + checkedTodos); } - private List makeCheckFeedDtos(final List checkFeeds) { - return checkFeeds.stream() - .map(this::makeCheckFeedDto) - .collect(Collectors.toList()); - } - - private CheckFeedDto makeCheckFeedDto(final CheckFeed checkFeed) { - final URL checkFeedImageUrl = fileService.generateUrl(checkFeed.getServerFilePath(), HttpMethod.GET); - return new CheckFeedDto(checkFeed.getId(), checkFeedImageUrl.toExternalForm(), - checkFeed.getDescription(), checkFeed.getCreatedAt()); - } - - private GoalRoom findMemberGoalRoomById(final Long goalRoomId) { - return goalRoomRepository.findByIdWithContentAndTodos(goalRoomId) + private GoalRoom findGoalRoomWithNodesById(final Long goalRoomId) { + return goalRoomRepository.findByIdWithNodes(goalRoomId) .orElseThrow(() -> new NotFoundException("골룸 정보가 존재하지 않습니다. goalRoomId = " + goalRoomId)); } @@ -197,8 +181,8 @@ private Member findMemberByIdentifier(final Identifier identifier) { .orElseThrow(() -> new NotFoundException("존재하지 않는 회원입니다.")); } - private void validateMemberInGoalRoom(final GoalRoom goalRoom, final Member member) { - if (!goalRoom.isGoalRoomMember(member)) { + private void validateMemberInGoalRoom(final GoalRoom goalRoom, final Long memberId) { + if (!goalRoom.isGoalRoomMember(memberId)) { throw new ForbiddenException("해당 골룸에 참여하지 않은 사용자입니다."); } } @@ -207,20 +191,9 @@ private Optional findCurrentGoalRoomNode(final GoalRoom goa return goalRoom.findNodeByDate(LocalDate.now()); } - private List findCheckFeedsByNodeAndGoalRoomStatus(final GoalRoom goalRoom, - final Optional currentGoalRoomRoadmapNode) { - if (goalRoom.isCompleted()) { - return checkFeedRepository.findByGoalRoom(goalRoom); - } - if (goalRoom.isRunning() && currentGoalRoomRoadmapNode.isPresent()) { - return checkFeedRepository.findByRunningGoalRoomRoadmapNode(currentGoalRoomRoadmapNode.get()); - } - return Collections.emptyList(); - } - public List findMemberGoalRooms(final String identifier) { final Member member = findMemberByIdentifier(new Identifier(identifier)); - final List memberGoalRooms = goalRoomRepository.findByMember(member); + final List memberGoalRooms = goalRoomRepository.findByMemberId(member.getId()); final List memberGoalRoomForListDtos = makeMemberGoalRoomForListDto( memberGoalRooms); return GoalRoomMapper.convertToMemberGoalRoomForListResponses(memberGoalRoomForListDtos); @@ -233,7 +206,8 @@ private List makeMemberGoalRoomForListDto(final List new NotFoundException("존재하지 않는 회원입니다. memberId = " + goalRoomLeaderId)); + } + public List findMemberGoalRoomsByStatusType(final String identifier, final GoalRoomStatusTypeRequest goalRoomStatusTypeRequest) { final Member member = findMemberByIdentifier(new Identifier(identifier)); final GoalRoomStatus goalRoomStatus = GoalRoomMapper.convertToGoalRoomStatus(goalRoomStatusTypeRequest); - final List memberGoalRooms = goalRoomRepository.findByMemberAndStatus(member, goalRoomStatus); + final List memberGoalRooms = goalRoomRepository.findByMemberAndStatus(member.getId(), goalRoomStatus); final List memberGoalRoomForListDtos = makeMemberGoalRoomForListDto( memberGoalRooms); return GoalRoomMapper.convertToMemberGoalRoomForListResponses(memberGoalRoomForListDtos); @@ -268,7 +247,15 @@ private GoalRoom findGoalRoomWithNodesByGoalRoomId(final Long goalRoomId) { .orElseThrow(() -> new NotFoundException("존재하지 않는 골룸입니다. goalRoomId = " + goalRoomId)); } - public List makeGoalRoomNodeDetailDtos( + private void validateGoalRoomMember(final Long goalRoomId, final String identifier) { + final Member member = findMemberByIdentifier(new Identifier(identifier)); + if (goalRoomMemberRepository.findByGoalRoomIdAndMemberId(goalRoomId, member.getId()).isEmpty()) { + throw new ForbiddenException( + "골룸에 참여하지 않은 사용자입니다. goalRoomId = " + goalRoomId + " memberIdentifier = " + identifier); + } + } + + private List makeGoalRoomNodeDetailDtos( final GoalRoomRoadmapNodes nodes) { return nodes.getValues().stream() .map(this::makeGoalRoomNodeDetailResponse) @@ -276,11 +263,17 @@ public List makeGoalRoomNodeDetailDtos( } private GoalRoomRoadmapNodeDetailDto makeGoalRoomNodeDetailResponse(final GoalRoomRoadmapNode node) { - final RoadmapNode roadmapNode = node.getRoadmapNode(); + final Long roadmapNodeId = node.getRoadmapNodeId(); + final RoadmapNode roadmapNode = findRoadmapNodeById(roadmapNodeId); return new GoalRoomRoadmapNodeDetailDto(node.getId(), roadmapNode.getTitle(), roadmapNode.getContent(), makeRoadmapNodeImageUrls(roadmapNode), node.getStartDate(), node.getEndDate(), node.getCheckCount()); } + private RoadmapNode findRoadmapNodeById(final Long roadmapNodeId) { + return roadmapNodeRepository.findById(roadmapNodeId) + .orElseThrow(() -> new NotFoundException("존재하지 않는 로드맵 노드입니다. roadmapNodeId = " + roadmapNodeId)); + } + private List makeRoadmapNodeImageUrls(final RoadmapNode roadmapNode) { return roadmapNode.getRoadmapNodeImages() .getValues() @@ -288,55 +281,4 @@ private List makeRoadmapNodeImageUrls(final RoadmapNode roadmapNode) { .map(it -> fileService.generateUrl(it.getServerFilePath(), HttpMethod.GET).toExternalForm()) .toList(); } - - public List findGoalRoomCheckFeeds(final String identifier, final Long goalRoomId) { - final GoalRoom goalRoom = findGoalRoomWithNodesById(goalRoomId); - validateJoinedMemberInRunningGoalRoom(goalRoom, identifier); - final Optional currentGoalRoomRoadmapNode = findCurrentGoalRoomNode(goalRoom); - final List checkFeeds = findCheckFeedsByNodeAndGoalRoomStatusWithMember(goalRoom, - currentGoalRoomRoadmapNode); - final List goalRoomCheckFeedDtos = makeGoalRoomCheckFeedDtos(checkFeeds); - return GoalRoomMapper.convertToGoalRoomCheckFeedResponses(goalRoomCheckFeedDtos); - } - - private GoalRoom findGoalRoomWithNodesById(final Long goalRoomId) { - return goalRoomRepository.findByIdWithNodes(goalRoomId) - .orElseThrow(() -> new NotFoundException("존재하지 않는 골룸입니다. goalRoomId = " + goalRoomId)); - } - - private void validateJoinedMemberInRunningGoalRoom(final GoalRoom goalRoom, final String identifier) { - if (goalRoomMemberRepository.findByGoalRoomAndMemberIdentifier(goalRoom, new Identifier(identifier)) - .isEmpty()) { - throw new ForbiddenException("골룸에 참여하지 않은 회원입니다."); - } - } - - private List findCheckFeedsByNodeAndGoalRoomStatusWithMember(final GoalRoom goalRoom, - final Optional currentGoalRoomRoadmapNode) { - if (goalRoom.isCompleted()) { - return checkFeedRepository.findByGoalRoomWithMemberAndMemberImage(goalRoom); - } - if (goalRoom.isRunning() && currentGoalRoomRoadmapNode.isPresent()) { - return checkFeedRepository.findByRunningGoalRoomRoadmapNodeWithMemberAndMemberImage( - currentGoalRoomRoadmapNode.get()); - } - return Collections.emptyList(); - } - - public List makeGoalRoomCheckFeedDtos( - final List checkFeeds) { - return checkFeeds.stream() - .map(this::makeGoalRoomCheckFeedDto) - .toList(); - } - - private GoalRoomCheckFeedDto makeGoalRoomCheckFeedDto(final CheckFeed checkFeed) { - final GoalRoomMember goalRoomMember = checkFeed.getGoalRoomMember(); - final Member member = goalRoomMember.getMember(); - - final URL memberImageUrl = fileService.generateUrl(member.getImage().getServerFilePath(), HttpMethod.GET); - - return new GoalRoomCheckFeedDto(new MemberDto(member.getId(), member.getNickname().getValue(), - memberImageUrl.toExternalForm()), makeCheckFeedDto(checkFeed)); - } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomCreateDto.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/GoalRoomCreateDto.java similarity index 69% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomCreateDto.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/GoalRoomCreateDto.java index 8d7482748..3f895bad3 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomCreateDto.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/GoalRoomCreateDto.java @@ -1,7 +1,7 @@ -package co.kirikiri.service.dto.goalroom; +package co.kirikiri.goalroom.service.dto; -import co.kirikiri.domain.goalroom.vo.GoalRoomName; -import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; +import co.kirikiri.goalroom.domain.vo.GoalRoomName; +import co.kirikiri.goalroom.domain.vo.LimitedMemberCount; import java.util.List; public record GoalRoomCreateDto( diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomFilterTypeDto.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/GoalRoomFilterTypeDto.java similarity index 84% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomFilterTypeDto.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/GoalRoomFilterTypeDto.java index 596ecde51..0936d1954 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomFilterTypeDto.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/GoalRoomFilterTypeDto.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.goalroom; +package co.kirikiri.goalroom.service.dto; public enum GoalRoomFilterTypeDto { @@ -10,4 +10,4 @@ public enum GoalRoomFilterTypeDto { GoalRoomFilterTypeDto(final String description) { this.description = description; } -} \ No newline at end of file +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomMemberDto.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/GoalRoomMemberDto.java similarity index 78% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomMemberDto.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/GoalRoomMemberDto.java index 01363bc1e..ad8211fd5 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomMemberDto.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/GoalRoomMemberDto.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.goalroom; +package co.kirikiri.goalroom.service.dto; public record GoalRoomMemberDto( Long memberId, diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomMemberSortTypeDto.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/GoalRoomMemberSortTypeDto.java similarity index 88% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomMemberSortTypeDto.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/GoalRoomMemberSortTypeDto.java index a7f816eea..2d77278ef 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomMemberSortTypeDto.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/GoalRoomMemberSortTypeDto.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.goalroom; +package co.kirikiri.goalroom.service.dto; public enum GoalRoomMemberSortTypeDto { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomRoadmapNodeDetailDto.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/GoalRoomRoadmapNodeDetailDto.java similarity index 87% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomRoadmapNodeDetailDto.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/GoalRoomRoadmapNodeDetailDto.java index d1808167f..d9dd9771d 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomRoadmapNodeDetailDto.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/GoalRoomRoadmapNodeDetailDto.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.goalroom; +package co.kirikiri.goalroom.service.dto; import java.time.LocalDate; import java.util.List; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomRoadmapNodeDto.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/GoalRoomRoadmapNodeDto.java similarity index 81% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomRoadmapNodeDto.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/GoalRoomRoadmapNodeDto.java index a456a23d4..b0c874e1c 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomRoadmapNodeDto.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/GoalRoomRoadmapNodeDto.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.goalroom; +package co.kirikiri.goalroom.service.dto; import java.time.LocalDate; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomStatusTypeDto.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/GoalRoomStatusTypeDto.java similarity index 86% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomStatusTypeDto.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/GoalRoomStatusTypeDto.java index 4f59aced8..af024d202 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomStatusTypeDto.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/GoalRoomStatusTypeDto.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.goalroom; +package co.kirikiri.goalroom.service.dto; public enum GoalRoomStatusTypeDto { RECRUITING("모집 중"), diff --git a/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/MemberDto.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/MemberDto.java new file mode 100644 index 000000000..4a709b505 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/MemberDto.java @@ -0,0 +1,9 @@ +package co.kirikiri.goalroom.service.dto; + +public record MemberDto( + long id, + String name, + String imageUrl +) { + +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/MemberGoalRoomForListDto.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/MemberGoalRoomForListDto.java similarity index 80% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/MemberGoalRoomForListDto.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/MemberGoalRoomForListDto.java index 6ee615c46..684a2abb8 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/MemberGoalRoomForListDto.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/MemberGoalRoomForListDto.java @@ -1,6 +1,5 @@ -package co.kirikiri.service.dto.goalroom; +package co.kirikiri.goalroom.service.dto; -import co.kirikiri.service.dto.member.MemberDto; import java.time.LocalDate; import java.time.LocalDateTime; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/RoadmapGoalRoomDto.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/RoadmapGoalRoomDto.java similarity index 72% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/RoadmapGoalRoomDto.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/RoadmapGoalRoomDto.java index 618204f0c..b73ad3f1a 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/RoadmapGoalRoomDto.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/RoadmapGoalRoomDto.java @@ -1,8 +1,6 @@ -package co.kirikiri.service.dto.goalroom; - -import co.kirikiri.domain.goalroom.GoalRoomStatus; -import co.kirikiri.service.dto.member.MemberDto; +package co.kirikiri.goalroom.service.dto; +import co.kirikiri.goalroom.domain.GoalRoomStatus; import java.time.LocalDate; import java.time.LocalDateTime; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/RoadmapGoalRoomScrollDto.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/RoadmapGoalRoomScrollDto.java similarity index 78% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/RoadmapGoalRoomScrollDto.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/RoadmapGoalRoomScrollDto.java index 59937fe0e..5975d255a 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/RoadmapGoalRoomScrollDto.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/RoadmapGoalRoomScrollDto.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.goalroom; +package co.kirikiri.goalroom.service.dto; import java.util.List; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/request/GoalRoomCreateRequest.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/request/GoalRoomCreateRequest.java similarity index 92% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/request/GoalRoomCreateRequest.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/request/GoalRoomCreateRequest.java index 546273c53..8bbe645e3 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/request/GoalRoomCreateRequest.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/request/GoalRoomCreateRequest.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.goalroom.request; +package co.kirikiri.goalroom.service.dto.request; import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/request/GoalRoomRoadmapNodeRequest.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/request/GoalRoomRoadmapNodeRequest.java similarity index 93% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/request/GoalRoomRoadmapNodeRequest.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/request/GoalRoomRoadmapNodeRequest.java index 91582039e..e14087735 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/request/GoalRoomRoadmapNodeRequest.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/request/GoalRoomRoadmapNodeRequest.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.goalroom.request; +package co.kirikiri.goalroom.service.dto.request; import com.fasterxml.jackson.annotation.JsonFormat; import jakarta.validation.constraints.NotNull; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/request/GoalRoomStatusTypeRequest.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/request/GoalRoomStatusTypeRequest.java similarity index 84% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/request/GoalRoomStatusTypeRequest.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/request/GoalRoomStatusTypeRequest.java index 53fd85154..f7c615841 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/request/GoalRoomStatusTypeRequest.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/request/GoalRoomStatusTypeRequest.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.goalroom.request; +package co.kirikiri.goalroom.service.dto.request; public enum GoalRoomStatusTypeRequest { RECRUITING("모집 중"), diff --git a/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/DashBoardCheckFeedResponse.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/DashBoardCheckFeedResponse.java new file mode 100644 index 000000000..52b25ce65 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/DashBoardCheckFeedResponse.java @@ -0,0 +1,12 @@ +package co.kirikiri.goalroom.service.dto.response; + +import java.time.LocalDate; + +public record DashBoardCheckFeedResponse( + Long id, + String imageUrl, + String description, + LocalDate createdAt +) { + +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/DashBoardToDoCheckResponse.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/DashBoardToDoCheckResponse.java new file mode 100644 index 000000000..84fcd0f9a --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/DashBoardToDoCheckResponse.java @@ -0,0 +1,7 @@ +package co.kirikiri.goalroom.service.dto.response; + +public record DashBoardToDoCheckResponse( + boolean isChecked +) { + +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/DashBoardToDoResponse.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/DashBoardToDoResponse.java new file mode 100644 index 000000000..d8b47403b --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/DashBoardToDoResponse.java @@ -0,0 +1,13 @@ +package co.kirikiri.goalroom.service.dto.response; + +import java.time.LocalDate; + +public record DashBoardToDoResponse( + Long id, + String content, + LocalDate startDate, + LocalDate endDate, + DashBoardToDoCheckResponse check +) { + +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomCertifiedResponse.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/GoalRoomCertifiedResponse.java similarity index 84% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomCertifiedResponse.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/GoalRoomCertifiedResponse.java index 253bb6b21..217b1d69b 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomCertifiedResponse.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/GoalRoomCertifiedResponse.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.goalroom.response; +package co.kirikiri.goalroom.service.dto.response; import java.util.List; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomMemberResponse.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/GoalRoomMemberResponse.java similarity index 75% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomMemberResponse.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/GoalRoomMemberResponse.java index 11ef4b04f..5cbe00a1d 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomMemberResponse.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/GoalRoomMemberResponse.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.goalroom.response; +package co.kirikiri.goalroom.service.dto.response; public record GoalRoomMemberResponse( Long memberId, diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomResponse.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/GoalRoomResponse.java similarity index 82% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomResponse.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/GoalRoomResponse.java index 15f9df8be..0ba8e1a34 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomResponse.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/GoalRoomResponse.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.goalroom.response; +package co.kirikiri.goalroom.service.dto.response; import java.util.List; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomRoadmapNodeDetailResponse.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/GoalRoomRoadmapNodeDetailResponse.java similarity index 85% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomRoadmapNodeDetailResponse.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/GoalRoomRoadmapNodeDetailResponse.java index 62a1422bc..e92257c99 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomRoadmapNodeDetailResponse.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/GoalRoomRoadmapNodeDetailResponse.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.goalroom.response; +package co.kirikiri.goalroom.service.dto.response; import java.time.LocalDate; import java.util.List; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomRoadmapNodeResponse.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/GoalRoomRoadmapNodeResponse.java similarity index 79% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomRoadmapNodeResponse.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/GoalRoomRoadmapNodeResponse.java index c89b8b1a5..eb419e69f 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomRoadmapNodeResponse.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/GoalRoomRoadmapNodeResponse.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.goalroom.response; +package co.kirikiri.goalroom.service.dto.response; import java.time.LocalDate; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomRoadmapNodesResponse.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/GoalRoomRoadmapNodesResponse.java similarity index 78% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomRoadmapNodesResponse.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/GoalRoomRoadmapNodesResponse.java index 000dad727..e26c083a5 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomRoadmapNodesResponse.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/GoalRoomRoadmapNodesResponse.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.goalroom.response; +package co.kirikiri.goalroom.service.dto.response; import java.util.List; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/member/response/MemberGoalRoomForListResponse.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/MemberGoalRoomForListResponse.java similarity index 88% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/member/response/MemberGoalRoomForListResponse.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/MemberGoalRoomForListResponse.java index dc30e5e21..b108b10b9 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/member/response/MemberGoalRoomForListResponse.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/MemberGoalRoomForListResponse.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.member.response; +package co.kirikiri.goalroom.service.dto.response; import java.time.LocalDate; import java.time.LocalDateTime; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/member/response/MemberGoalRoomResponse.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/MemberGoalRoomResponse.java similarity index 51% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/member/response/MemberGoalRoomResponse.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/MemberGoalRoomResponse.java index 1204d182c..6423e72f0 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/member/response/MemberGoalRoomResponse.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/MemberGoalRoomResponse.java @@ -1,8 +1,5 @@ -package co.kirikiri.service.dto.member.response; +package co.kirikiri.goalroom.service.dto.response; -import co.kirikiri.service.dto.goalroom.response.CheckFeedResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomRoadmapNodesResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomTodoResponse; import java.time.LocalDate; import java.util.List; @@ -16,8 +13,8 @@ public record MemberGoalRoomResponse( LocalDate endDate, Long roadmapContentId, GoalRoomRoadmapNodesResponse goalRoomRoadmapNodes, - List goalRoomTodos, - List checkFeeds + List goalRoomTodos, + List checkFeeds ) { } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/MemberResponse.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/MemberResponse.java new file mode 100644 index 000000000..a95dda910 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/MemberResponse.java @@ -0,0 +1,9 @@ +package co.kirikiri.goalroom.service.dto.response; + +public record MemberResponse( + long id, + String name, + String imageUrl +) { + +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/roadmap/response/RoadmapGoalRoomResponse.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/RoadmapGoalRoomResponse.java similarity index 70% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/roadmap/response/RoadmapGoalRoomResponse.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/RoadmapGoalRoomResponse.java index 2d63964e5..89ad78233 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/roadmap/response/RoadmapGoalRoomResponse.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/dto/response/RoadmapGoalRoomResponse.java @@ -1,7 +1,6 @@ -package co.kirikiri.service.dto.roadmap.response; +package co.kirikiri.goalroom.service.dto.response; -import co.kirikiri.domain.goalroom.GoalRoomStatus; -import co.kirikiri.service.dto.member.response.MemberResponse; +import co.kirikiri.goalroom.domain.GoalRoomStatus; import java.time.LocalDate; import java.time.LocalDateTime; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/mapper/GoalRoomMapper.java b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/mapper/GoalRoomMapper.java similarity index 56% rename from backend/kirikiri/src/main/java/co/kirikiri/service/mapper/GoalRoomMapper.java rename to backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/mapper/GoalRoomMapper.java index a7a7fdef6..6e56be2ac 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/mapper/GoalRoomMapper.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/goalroom/service/mapper/GoalRoomMapper.java @@ -1,53 +1,45 @@ -package co.kirikiri.service.mapper; - -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNode; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNodes; -import co.kirikiri.domain.goalroom.GoalRoomStatus; -import co.kirikiri.domain.goalroom.GoalRoomToDo; -import co.kirikiri.domain.goalroom.GoalRoomToDoCheck; -import co.kirikiri.domain.goalroom.GoalRoomToDos; -import co.kirikiri.domain.goalroom.vo.GoalRoomName; -import co.kirikiri.domain.goalroom.vo.GoalRoomTodoContent; -import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; -import co.kirikiri.domain.goalroom.vo.Period; -import co.kirikiri.persistence.goalroom.dto.GoalRoomMemberSortType; -import co.kirikiri.persistence.goalroom.dto.RoadmapGoalRoomsOrderType; -import co.kirikiri.service.dto.FileInformation; -import co.kirikiri.service.dto.goalroom.CheckFeedDto; -import co.kirikiri.service.dto.goalroom.GoalRoomCheckFeedDto; -import co.kirikiri.service.dto.goalroom.GoalRoomCreateDto; -import co.kirikiri.service.dto.goalroom.GoalRoomMemberDto; -import co.kirikiri.service.dto.goalroom.GoalRoomMemberSortTypeDto; -import co.kirikiri.service.dto.goalroom.GoalRoomRoadmapNodeDetailDto; -import co.kirikiri.service.dto.goalroom.GoalRoomRoadmapNodeDto; -import co.kirikiri.service.dto.goalroom.MemberGoalRoomForListDto; -import co.kirikiri.service.dto.goalroom.RoadmapGoalRoomDto; -import co.kirikiri.service.dto.goalroom.RoadmapGoalRoomScrollDto; -import co.kirikiri.service.dto.goalroom.request.GoalRoomCreateRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomRoadmapNodeRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomStatusTypeRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomTodoRequest; -import co.kirikiri.service.dto.goalroom.response.CheckFeedResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomCertifiedResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomCheckFeedResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomMemberResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomRoadmapNodeDetailResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomRoadmapNodeResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomRoadmapNodesResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomToDoCheckResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomTodoResponse; -import co.kirikiri.service.dto.member.MemberDto; -import co.kirikiri.service.dto.member.response.MemberGoalRoomForListResponse; -import co.kirikiri.service.dto.member.response.MemberGoalRoomResponse; -import co.kirikiri.service.dto.member.response.MemberResponse; +package co.kirikiri.goalroom.service.mapper; + +import co.kirikiri.common.exception.NotFoundException; +import co.kirikiri.domain.roadmap.RoadmapContent; +import co.kirikiri.domain.roadmap.RoadmapNode; +import co.kirikiri.domain.roadmap.RoadmapNodes; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNode; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNodes; +import co.kirikiri.goalroom.domain.GoalRoomStatus; +import co.kirikiri.goalroom.domain.vo.GoalRoomName; +import co.kirikiri.goalroom.domain.vo.LimitedMemberCount; +import co.kirikiri.goalroom.domain.vo.Period; +import co.kirikiri.goalroom.persistence.dto.GoalRoomMemberSortType; +import co.kirikiri.goalroom.persistence.dto.RoadmapGoalRoomsOrderType; +import co.kirikiri.goalroom.service.dto.GoalRoomCreateDto; +import co.kirikiri.goalroom.service.dto.GoalRoomMemberDto; +import co.kirikiri.goalroom.service.dto.GoalRoomMemberSortTypeDto; +import co.kirikiri.goalroom.service.dto.GoalRoomRoadmapNodeDetailDto; +import co.kirikiri.goalroom.service.dto.GoalRoomRoadmapNodeDto; +import co.kirikiri.goalroom.service.dto.MemberDto; +import co.kirikiri.goalroom.service.dto.MemberGoalRoomForListDto; +import co.kirikiri.goalroom.service.dto.RoadmapGoalRoomDto; +import co.kirikiri.goalroom.service.dto.RoadmapGoalRoomScrollDto; +import co.kirikiri.goalroom.service.dto.request.GoalRoomCreateRequest; +import co.kirikiri.goalroom.service.dto.request.GoalRoomRoadmapNodeRequest; +import co.kirikiri.goalroom.service.dto.request.GoalRoomStatusTypeRequest; +import co.kirikiri.goalroom.service.dto.response.DashBoardCheckFeedResponse; +import co.kirikiri.goalroom.service.dto.response.DashBoardToDoResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomCertifiedResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomMemberResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomRoadmapNodeDetailResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomRoadmapNodeResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomRoadmapNodesResponse; +import co.kirikiri.goalroom.service.dto.response.MemberGoalRoomForListResponse; +import co.kirikiri.goalroom.service.dto.response.MemberGoalRoomResponse; +import co.kirikiri.goalroom.service.dto.response.MemberResponse; +import co.kirikiri.goalroom.service.dto.response.RoadmapGoalRoomResponse; import co.kirikiri.service.dto.roadmap.RoadmapGoalRoomNumberDto; import co.kirikiri.service.dto.roadmap.RoadmapGoalRoomsOrderTypeDto; -import co.kirikiri.service.dto.roadmap.response.RoadmapGoalRoomResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapGoalRoomResponses; -import co.kirikiri.service.exception.ServerException; -import java.io.IOException; import java.time.LocalDate; import java.util.Collections; import java.util.List; @@ -55,12 +47,10 @@ import java.util.stream.Collectors; import lombok.AccessLevel; import lombok.NoArgsConstructor; -import org.springframework.web.multipart.MultipartFile; @NoArgsConstructor(access = AccessLevel.PRIVATE) public class GoalRoomMapper { - private static final int MAX_MEMBER_GOAL_ROOM_TODO_NUMBER = 3; private static final int MAX_MEMBER_GOAL_ROOM_CHECK_FEED_NUMBER = 4; public static GoalRoomCreateDto convertToGoalRoomCreateDto(final GoalRoomCreateRequest goalRoomCreateRequest) { @@ -75,9 +65,24 @@ public static GoalRoomCreateDto convertToGoalRoomCreateDto(final GoalRoomCreateR goalRoomRoadmapNodeDtos); } - public static GoalRoomToDo convertToGoalRoomTodo(final GoalRoomTodoRequest goalRoomTodoRequest) { - return new GoalRoomToDo(new GoalRoomTodoContent(goalRoomTodoRequest.content()), - new Period(goalRoomTodoRequest.startDate(), goalRoomTodoRequest.endDate())); + public static GoalRoomRoadmapNodes convertToGoalRoomRoadmapNodes( + final List goalRoomRoadmapNodeDtos, + final RoadmapContent roadmapContent) { + final List goalRoomRoadmapNodes = goalRoomRoadmapNodeDtos.stream() + .map(it -> makeGoalRoomRoadmapNode(roadmapContent, it)) + .toList(); + return new GoalRoomRoadmapNodes(goalRoomRoadmapNodes); + } + + private static GoalRoomRoadmapNode makeGoalRoomRoadmapNode(final RoadmapContent roadmapContent, + final GoalRoomRoadmapNodeDto it) { + return new GoalRoomRoadmapNode(new Period(it.startDate(), it.endDate()), it.checkCount(), + findRoadmapNode(roadmapContent, it.roadmapNodeId()).getId()); + } + + private static RoadmapNode findRoadmapNode(final RoadmapContent roadmapContent, final Long roadmapNodeId) { + return roadmapContent.findRoadmapNodeById(roadmapNodeId) + .orElseThrow(() -> new NotFoundException("로드맵에 존재하지 않는 노드입니다.")); } private static List makeGoalRoomRoadmapNodeDtos( @@ -89,22 +94,29 @@ private static List makeGoalRoomRoadmapNodeDtos( .toList(); } - public static GoalRoomResponse convertGoalRoomResponse(final GoalRoom goalRoom) { + public static GoalRoomResponse convertGoalRoomResponse(final GoalRoom goalRoom, final RoadmapNodes roadmapNodes) { final GoalRoomRoadmapNodes nodes = goalRoom.getGoalRoomRoadmapNodes(); - final List roadmapNodeResponses = convertGoalRoomNodeResponses(nodes); + final List roadmapNodeResponses = convertGoalRoomNodeResponses(nodes, + roadmapNodes); final int period = goalRoom.calculateTotalPeriod(); return new GoalRoomResponse(goalRoom.getName().getValue(), goalRoom.getCurrentMemberCount(), goalRoom.getLimitedMemberCount().getValue(), roadmapNodeResponses, period); } - public static List convertGoalRoomNodeResponses(final GoalRoomRoadmapNodes nodes) { - return nodes.getValues().stream() - .map(GoalRoomMapper::convertGoalRoomNodeResponse) + public static List convertGoalRoomNodeResponses( + final GoalRoomRoadmapNodes goalRoomRoadmapNodes, + final RoadmapNodes roadmapNodes) { + return goalRoomRoadmapNodes.getValues().stream() + .map(goalRoomRoadmapNode -> convertGoalRoomNodeResponse(goalRoomRoadmapNode, roadmapNodes)) .toList(); } - private static GoalRoomRoadmapNodeResponse convertGoalRoomNodeResponse(final GoalRoomRoadmapNode node) { - return new GoalRoomRoadmapNodeResponse(node.getId(), node.getRoadmapNode().getTitle(), node.getStartDate(), + private static GoalRoomRoadmapNodeResponse convertGoalRoomNodeResponse(final GoalRoomRoadmapNode node, + final RoadmapNodes roadmapNodes) { + final RoadmapNode roadmapNode = roadmapNodes.findById(node.getRoadmapNodeId()) + .orElseThrow(() -> new NotFoundException( + "존재하지 않는 로드맵 노드 아이디입니다. roadmapNodeId = " + node.getRoadmapNodeId())); + return new GoalRoomRoadmapNodeResponse(node.getId(), roadmapNode.getTitle(), node.getStartDate(), node.getEndDate(), node.getCheckCount()); } @@ -124,9 +136,11 @@ private static GoalRoomRoadmapNodeDetailResponse convertGoalRoomNodeDetailRespon } public static GoalRoomCertifiedResponse convertGoalRoomCertifiedResponse(final GoalRoom goalRoom, + final RoadmapNodes roadmapNodes, final boolean isJoined) { final GoalRoomRoadmapNodes nodes = goalRoom.getGoalRoomRoadmapNodes(); - final List roadmapNodeResponses = convertGoalRoomNodeResponses(nodes); + final List roadmapNodeResponses = convertGoalRoomNodeResponses(nodes, + roadmapNodes); final int period = goalRoom.calculateTotalPeriod(); return new GoalRoomCertifiedResponse(goalRoom.getName().getValue(), goalRoom.getCurrentMemberCount(), goalRoom.getLimitedMemberCount().getValue(), roadmapNodeResponses, period, isJoined); @@ -181,47 +195,22 @@ private static GoalRoomMemberResponse convertToGoalRoomMemberResponse(final Goal goalRoomMemberDto.imagePath(), goalRoomMemberDto.accomplishmentRate()); } - public static List convertGoalRoomTodoResponses(final GoalRoomToDos goalRoomToDos, - final List checkedTodos) { - return goalRoomToDos.getValues().stream() - .map(goalRoomToDo -> convertGoalRoomTodoResponse(checkedTodos, goalRoomToDo)) - .toList(); - } - - private static GoalRoomTodoResponse convertGoalRoomTodoResponse(final List checkedTodos, - final GoalRoomToDo goalRoomToDo) { - final GoalRoomToDoCheckResponse checkResponse = new GoalRoomToDoCheckResponse( - isCheckedTodo(goalRoomToDo.getId(), checkedTodos)); - return new GoalRoomTodoResponse(goalRoomToDo.getId(), - goalRoomToDo.getContent(), - goalRoomToDo.getStartDate(), goalRoomToDo.getEndDate(), - checkResponse); - } - - private static boolean isCheckedTodo(final Long targetTodoId, final List checkedTodos) { - final List checkTodoIds = checkedTodos.stream() - .map(goalRoomToDoCheck -> goalRoomToDoCheck.getGoalRoomToDo().getId()) - .toList(); - return checkTodoIds.contains(targetTodoId); - } - public static MemberGoalRoomResponse convertToMemberGoalRoomResponse(final GoalRoom goalRoom, - final List checkFeedDtos, - final List checkedTodos) { + final RoadmapNodes roadmapNodes, + final List allCheckFeedResponses, + final List todoResponses) { final GoalRoomRoadmapNodesResponse nodeResponses = convertToGoalRoomRoadmapNodesResponse( - goalRoom.getGoalRoomRoadmapNodes()); - final List todoResponses = convertGoalRoomTodoResponsesLimit(goalRoom.getGoalRoomToDos(), - checkedTodos); - final List checkFeedResponses = convertToCheckFeedResponses(checkFeedDtos); + goalRoom.getGoalRoomRoadmapNodes(), roadmapNodes); + final List checkFeedResponses = makeCheckFeedToLimit(allCheckFeedResponses); return new MemberGoalRoomResponse(goalRoom.getName().getValue(), goalRoom.getStatus().name(), - goalRoom.findGoalRoomLeader().getId(), goalRoom.getCurrentMemberCount(), + goalRoom.findGoalRoomLeaderId(), goalRoom.getCurrentMemberCount(), goalRoom.getLimitedMemberCount().getValue(), goalRoom.getStartDate(), goalRoom.getEndDate(), - goalRoom.getRoadmapContent().getId(), nodeResponses, todoResponses, checkFeedResponses); + goalRoom.getRoadmapContentId(), nodeResponses, todoResponses, checkFeedResponses); } private static GoalRoomRoadmapNodesResponse convertToGoalRoomRoadmapNodesResponse( - final GoalRoomRoadmapNodes nodes) { + final GoalRoomRoadmapNodes nodes, final RoadmapNodes roadmapNodes) { final GoalRoomRoadmapNode currentNode = nodes.getNodeByDate(LocalDate.now()) .orElse(nodes.getNodeByDate(nodes.getGoalRoomStartDate()).get()); @@ -229,28 +218,19 @@ private static GoalRoomRoadmapNodesResponse convertToGoalRoomRoadmapNodesRespons return new GoalRoomRoadmapNodesResponse( nodes.hasFrontNode(currentNode), nodes.hasBackNode(currentNode), - List.of(convertGoalRoomNodeResponse(currentNode)) + List.of(convertGoalRoomNodeResponse(currentNode, roadmapNodes)) ); } final GoalRoomRoadmapNode nextNode = nodes.nextNode(currentNode).get(); return new GoalRoomRoadmapNodesResponse(nodes.hasFrontNode(currentNode), nodes.hasBackNode(nextNode), - List.of(convertGoalRoomNodeResponse(currentNode), convertGoalRoomNodeResponse(nextNode))); + List.of(convertGoalRoomNodeResponse(currentNode, roadmapNodes), convertGoalRoomNodeResponse(nextNode, + roadmapNodes))); } - private static List convertGoalRoomTodoResponsesLimit(final GoalRoomToDos goalRoomToDos, - final List checkedTodos) { - return goalRoomToDos.getValues() - .stream() - .map(goalRoomToDo -> convertGoalRoomTodoResponse(checkedTodos, goalRoomToDo)) - .limit(MAX_MEMBER_GOAL_ROOM_TODO_NUMBER) - .toList(); - } - - private static List convertToCheckFeedResponses(final List checkFeedDtos) { + private static List makeCheckFeedToLimit( + final List checkFeedDtos) { return checkFeedDtos.stream() - .map(checkFeed -> new CheckFeedResponse(checkFeed.id(), checkFeed.imageUrl(), - checkFeed.description(), checkFeed.createdAt().toLocalDate())) .limit(MAX_MEMBER_GOAL_ROOM_CHECK_FEED_NUMBER) .toList(); } @@ -274,28 +254,7 @@ private static MemberGoalRoomForListResponse convertToMemberGoalRoomForListRespo memberGoalRoomForListDto.limitedMemberCount(), memberGoalRoomForListDto.createdAt(), memberGoalRoomForListDto.startDate(), memberGoalRoomForListDto.endDate(), - new MemberResponse(memberDto.id(), memberDto.name(), - memberDto.imageUrl())); - } - - public static List convertToGoalRoomCheckFeedResponses( - final List checkFeeds) { - return checkFeeds.stream() - .map(GoalRoomMapper::convertToGoalRoomCheckFeedResponse) - .toList(); - } - - private static GoalRoomCheckFeedResponse convertToGoalRoomCheckFeedResponse( - final GoalRoomCheckFeedDto goalRoomCheckFeedDto) { - final MemberDto memberDto = goalRoomCheckFeedDto.memberDto(); - final MemberResponse memberResponse = new MemberResponse(memberDto.id(), memberDto.name(), - memberDto.imageUrl()); - - final CheckFeedDto checkFeedDto = goalRoomCheckFeedDto.checkFeedDto(); - final CheckFeedResponse checkFeedResponse = new CheckFeedResponse(checkFeedDto.id(), checkFeedDto.imageUrl(), - checkFeedDto.description(), checkFeedDto.createdAt().toLocalDate()); - - return new GoalRoomCheckFeedResponse(memberResponse, checkFeedResponse); + new MemberResponse(memberDto.id(), memberDto.name(), memberDto.imageUrl())); } public static RoadmapGoalRoomNumberDto convertRoadmapGoalRoomDto(final List goalRooms) { @@ -307,13 +266,4 @@ public static RoadmapGoalRoomNumberDto convertRoadmapGoalRoomDto(final List makeGoalRoomMembers(final List makeGoalRoomPendingMemberIds(final List goalRoomPendingMembers) { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/infra/AmazonS3FileService.java b/backend/kirikiri/src/main/java/co/kirikiri/infra/AmazonS3FileService.java index 429359a26..1eb92cced 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/infra/AmazonS3FileService.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/infra/AmazonS3FileService.java @@ -1,8 +1,8 @@ package co.kirikiri.infra; -import co.kirikiri.service.FileService; -import co.kirikiri.service.dto.FileInformation; -import co.kirikiri.service.exception.ServerException; +import co.kirikiri.common.exception.ServerException; +import co.kirikiri.common.service.FileService; +import co.kirikiri.common.service.dto.FileInformation; import com.amazonaws.SdkClientException; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/infra/CloudFrontService.java b/backend/kirikiri/src/main/java/co/kirikiri/infra/CloudFrontService.java index 2c95c30ff..62db3821f 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/infra/CloudFrontService.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/infra/CloudFrontService.java @@ -1,6 +1,6 @@ package co.kirikiri.infra; -import co.kirikiri.service.exception.ServerException; +import co.kirikiri.common.exception.ServerException; import java.net.MalformedURLException; import java.net.URL; import lombok.RequiredArgsConstructor; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/dto/RoadmapSearchTagName.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/dto/RoadmapSearchTagName.java index c090385c1..3ed402e18 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/dto/RoadmapSearchTagName.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/persistence/dto/RoadmapSearchTagName.java @@ -1,6 +1,6 @@ package co.kirikiri.persistence.dto; -import co.kirikiri.service.exception.BadRequestException; +import co.kirikiri.common.exception.BadRequestException; public record RoadmapSearchTagName( String value diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/dto/RoadmapSearchTitle.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/dto/RoadmapSearchTitle.java index 8469ce5d7..743e78444 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/dto/RoadmapSearchTitle.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/persistence/dto/RoadmapSearchTitle.java @@ -1,6 +1,6 @@ package co.kirikiri.persistence.dto; -import co.kirikiri.service.exception.BadRequestException; +import co.kirikiri.common.exception.BadRequestException; public record RoadmapSearchTitle( String value diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/CheckFeedQueryRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/CheckFeedQueryRepository.java deleted file mode 100644 index 5cb828965..000000000 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/CheckFeedQueryRepository.java +++ /dev/null @@ -1,15 +0,0 @@ -package co.kirikiri.persistence.goalroom; - -import co.kirikiri.domain.goalroom.CheckFeed; -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNode; -import java.util.List; - -public interface CheckFeedQueryRepository { - - List findByRunningGoalRoomRoadmapNodeWithMemberAndMemberImage(final GoalRoomRoadmapNode goalRoomRoadmapNode); - - List findByRunningGoalRoomRoadmapNode(final GoalRoomRoadmapNode currentGoalRoomRoadmapNode); - - List findByGoalRoomWithMemberAndMemberImage(final GoalRoom goalRoom); -} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/CheckFeedQueryRepositoryImpl.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/CheckFeedQueryRepositoryImpl.java deleted file mode 100644 index be35407bd..000000000 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/CheckFeedQueryRepositoryImpl.java +++ /dev/null @@ -1,70 +0,0 @@ -package co.kirikiri.persistence.goalroom; - -import static co.kirikiri.domain.goalroom.QCheckFeed.checkFeed; -import static co.kirikiri.domain.goalroom.QGoalRoomMember.goalRoomMember; -import static co.kirikiri.domain.member.QMember.member; -import static co.kirikiri.domain.member.QMemberImage.memberImage; - -import co.kirikiri.domain.goalroom.CheckFeed; -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNode; -import co.kirikiri.persistence.QuerydslRepositorySupporter; -import com.querydsl.core.types.dsl.BooleanExpression; -import java.util.List; - -public class CheckFeedQueryRepositoryImpl extends QuerydslRepositorySupporter implements CheckFeedQueryRepository { - - public CheckFeedQueryRepositoryImpl() { - super(CheckFeed.class); - } - - @Override - public List findByRunningGoalRoomRoadmapNodeWithMemberAndMemberImage( - final GoalRoomRoadmapNode goalRoomRoadmapNode) { - return selectFrom(checkFeed) - .innerJoin(checkFeed.goalRoomMember, goalRoomMember) - .fetchJoin() - .innerJoin(goalRoomMember.member, member) - .fetchJoin() - .innerJoin(member.image, memberImage) - .fetchJoin() - .where(nodeCond(goalRoomRoadmapNode)) - .orderBy(checkFeed.createdAt.desc()) - .fetch(); - } - - @Override - public List findByRunningGoalRoomRoadmapNode( - final GoalRoomRoadmapNode currentGoalRoomRoadmapNode) { - return selectFrom(checkFeed) - .innerJoin(checkFeed.goalRoomMember, goalRoomMember) - .fetchJoin() - .innerJoin(goalRoomMember.member, member) - .fetchJoin() - .where(nodeCond(currentGoalRoomRoadmapNode)) - .orderBy(checkFeed.createdAt.desc()) - .fetch(); - } - - @Override - public List findByGoalRoomWithMemberAndMemberImage(final GoalRoom goalRoom) { - return selectFrom(checkFeed) - .innerJoin(checkFeed.goalRoomMember, goalRoomMember) - .fetchJoin() - .innerJoin(goalRoomMember.member, member) - .fetchJoin() - .innerJoin(member.image, memberImage) - .fetchJoin() - .where(goalRoomCond(goalRoom)) - .orderBy(checkFeed.createdAt.desc()) - .fetch(); - } - - private BooleanExpression nodeCond(final GoalRoomRoadmapNode node) { - return checkFeed.goalRoomRoadmapNode.eq(node); - } - - private BooleanExpression goalRoomCond(final GoalRoom goalRoom) { - return goalRoomMember.goalRoom.eq(goalRoom); - } -} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/CheckFeedRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/CheckFeedRepository.java deleted file mode 100644 index 25f009dcd..000000000 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/CheckFeedRepository.java +++ /dev/null @@ -1,42 +0,0 @@ -package co.kirikiri.persistence.goalroom; - -import co.kirikiri.domain.goalroom.CheckFeed; -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomMember; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNode; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import java.time.LocalDateTime; -import java.util.List; -import java.util.Optional; - -public interface CheckFeedRepository extends JpaRepository, CheckFeedQueryRepository { - - @Query("SELECT cf" - + " FROM CheckFeed cf" - + " WHERE cf.goalRoomMember = :goalRoomMember" - + " AND cf.createdAt >= :start" - + " AND cf.createdAt < :end") - Optional findByGoalRoomMemberAndDateTime(final GoalRoomMember goalRoomMember, final LocalDateTime start, - final LocalDateTime end); - - @Query("SELECT COUNT(cf)" - + " FROM CheckFeed cf" - + " WHERE cf.goalRoomMember = :goalRoomMember") - int countByGoalRoomMember(final GoalRoomMember goalRoomMember); - - @Query("SELECT COUNT(cf)" - + " FROM CheckFeed cf" - + " WHERE cf.goalRoomMember = :goalRoomMember" - + " AND cf.goalRoomRoadmapNode = :goalRoomRoadmapNode") - int countByGoalRoomMemberAndGoalRoomRoadmapNode(final GoalRoomMember goalRoomMember, - final GoalRoomRoadmapNode goalRoomRoadmapNode); - - @Query("SELECT cf" - + " FROM CheckFeed cf" - + " WHERE cf.goalRoomMember.goalRoom =:goalRoom" - + " ORDER BY cf.createdAt DESC") - List findByGoalRoom(final GoalRoom goalRoom); - - List findByGoalRoomRoadmapNode(final GoalRoomRoadmapNode goalRoomRoadmapNode); -} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberQueryRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberQueryRepository.java deleted file mode 100644 index 0087e6a93..000000000 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomMemberQueryRepository.java +++ /dev/null @@ -1,22 +0,0 @@ -package co.kirikiri.persistence.goalroom; - -import co.kirikiri.domain.goalroom.GoalRoomMember; -import co.kirikiri.domain.goalroom.GoalRoomStatus; -import co.kirikiri.domain.member.vo.Identifier; -import co.kirikiri.persistence.goalroom.dto.GoalRoomMemberSortType; -import org.springframework.data.repository.query.Param; -import java.util.List; -import java.util.Optional; - -public interface GoalRoomMemberQueryRepository { - - Optional findByRoadmapIdAndMemberIdentifierAndGoalRoomStatus( - @Param("roadmapId") final Long roadmapId, - @Param("identifier") final Identifier identifier, - @Param("status") final GoalRoomStatus status); - - List findByGoalRoomIdOrderedBySortType(final Long goalRoomId, - final GoalRoomMemberSortType sortType); - - Optional findGoalRoomMember(final Long goalRoomId, final Identifier memberIdentifier); -} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomQueryRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomQueryRepository.java deleted file mode 100644 index 5a18b19d9..000000000 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomQueryRepository.java +++ /dev/null @@ -1,36 +0,0 @@ -package co.kirikiri.persistence.goalroom; - -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomStatus; -import co.kirikiri.domain.member.Member; -import co.kirikiri.domain.roadmap.Roadmap; -import co.kirikiri.persistence.goalroom.dto.RoadmapGoalRoomsOrderType; -import java.time.LocalDate; -import java.util.List; -import java.util.Optional; - -public interface GoalRoomQueryRepository { - - Optional findGoalRoomByIdWithPessimisticLock(Long goalRoomId); - - Optional findByIdWithRoadmapContent(final Long goalRoomId); - - Optional findByIdWithContentAndTodos(final Long goalRoomId); - - List findGoalRoomsByRoadmapAndCond(final Roadmap roadmap, - final RoadmapGoalRoomsOrderType filterType, - final Long lastId, - final int pageSize); - - Optional findByIdWithTodos(final Long goalRoomId); - - List findByMember(final Member member); - - List findByMemberAndStatus(final Member member, final GoalRoomStatus goalRoomStatus); - - Optional findByIdWithNodes(final Long goalRoomId); - - List findByRoadmap(final Roadmap roadmap); - - List findAllRecruitingGoalRoomsByStartDateEarlierThan(final LocalDate startDate); -} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomToDoCheckRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomToDoCheckRepository.java deleted file mode 100644 index bc5609216..000000000 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/goalroom/GoalRoomToDoCheckRepository.java +++ /dev/null @@ -1,44 +0,0 @@ -package co.kirikiri.persistence.goalroom; - -import co.kirikiri.domain.goalroom.GoalRoomMember; -import co.kirikiri.domain.goalroom.GoalRoomToDo; -import co.kirikiri.domain.goalroom.GoalRoomToDoCheck; -import co.kirikiri.domain.member.vo.Identifier; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import java.util.List; -import java.util.Optional; - -public interface GoalRoomToDoCheckRepository extends JpaRepository { - - @Query("select gc from GoalRoomToDoCheck gc " - + "inner join fetch gc.goalRoomMember gcm " - + "inner join fetch gcm.member m " - + "inner join fetch gcm.goalRoom g " - + "where m.identifier = :identifier " - + "and gc.goalRoomToDo = :goalRoomTodo " - + "and g.id = :goalRoomId") - Optional findByGoalRoomIdAndTodoAndMemberIdentifier( - @Param("goalRoomId") final Long goalRoomId, - @Param("goalRoomTodo") final GoalRoomToDo goalRoomToDo, - @Param("identifier") final Identifier identifier); - - @Query("select gc from GoalRoomToDoCheck gc " - + "inner join fetch gc.goalRoomMember gcm " - + "inner join fetch gcm.member m " - + "inner join fetch gcm.goalRoom g " - + "where m.identifier = :identifier " - + "and g.id = :goalRoomId ") - List findByGoalRoomIdAndMemberIdentifier( - @Param("goalRoomId") final Long goalRoomId, - @Param("identifier") final Identifier identifier); - - @Modifying - @Query("delete from GoalRoomToDoCheck gc " - + "where gc.goalRoomMember = :goalRoomMember " - + "and gc.goalRoomToDo.id = :todoId") - void deleteByGoalRoomMemberAndToDoId(@Param("goalRoomMember") final GoalRoomMember goalRoomMember, - @Param("todoId") final Long todoId); -} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/member/MemberQueryRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/member/MemberQueryRepository.java index 8a11d80b8..42c4224c1 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/member/MemberQueryRepository.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/persistence/member/MemberQueryRepository.java @@ -8,4 +8,6 @@ public interface MemberQueryRepository { Optional findWithMemberProfileAndImageByIdentifier(final String identifier); Optional findWithMemberProfileAndImageById(final Long memberId); + + Optional findWithMemberImageById(final Long memberId); } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/member/MemberQueryRepositoryImpl.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/member/MemberQueryRepositoryImpl.java index 9d725af72..c00737d43 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/member/MemberQueryRepositoryImpl.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/persistence/member/MemberQueryRepositoryImpl.java @@ -4,8 +4,8 @@ import static co.kirikiri.domain.member.QMemberImage.memberImage; import static co.kirikiri.domain.member.QMemberProfile.memberProfile; +import co.kirikiri.common.persistence.QuerydslRepositorySupporter; import co.kirikiri.domain.member.Member; -import co.kirikiri.persistence.QuerydslRepositorySupporter; import java.util.Optional; public class MemberQueryRepositoryImpl extends QuerydslRepositorySupporter implements MemberQueryRepository { @@ -35,4 +35,13 @@ public Optional findWithMemberProfileAndImageById(final Long memberId) { .where(member.id.eq(memberId)) .fetchOne()); } + + @Override + public Optional findWithMemberImageById(final Long memberId) { + return Optional.ofNullable(selectFrom(member) + .innerJoin(member.image, memberImage) + .fetchJoin() + .where(member.id.eq(memberId)) + .fetchOne()); + } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/roadmap/RoadmapContentRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/roadmap/RoadmapContentRepository.java index 722761e75..3e75c3103 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/roadmap/RoadmapContentRepository.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/persistence/roadmap/RoadmapContentRepository.java @@ -2,10 +2,10 @@ import co.kirikiri.domain.roadmap.Roadmap; import co.kirikiri.domain.roadmap.RoadmapContent; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import java.util.Optional; public interface RoadmapContentRepository extends JpaRepository { @@ -15,4 +15,6 @@ public interface RoadmapContentRepository extends JpaRepository findByIdWithRoadmap(@Param("roadmapContentId") final Long roadmapContentId); + + Optional findByRoadmap(@Param("roadmap") final Roadmap roadmap); } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/roadmap/RoadmapQueryRepositoryImpl.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/roadmap/RoadmapQueryRepositoryImpl.java index 95680b8aa..c1b854df1 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/roadmap/RoadmapQueryRepositoryImpl.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/persistence/roadmap/RoadmapQueryRepositoryImpl.java @@ -1,20 +1,20 @@ package co.kirikiri.persistence.roadmap; -import static co.kirikiri.domain.goalroom.QGoalRoom.goalRoom; -import static co.kirikiri.domain.goalroom.QGoalRoomMember.goalRoomMember; import static co.kirikiri.domain.member.QMember.member; import static co.kirikiri.domain.roadmap.QRoadmap.roadmap; import static co.kirikiri.domain.roadmap.QRoadmapCategory.roadmapCategory; import static co.kirikiri.domain.roadmap.QRoadmapContent.roadmapContent; import static co.kirikiri.domain.roadmap.QRoadmapReview.roadmapReview; import static co.kirikiri.domain.roadmap.QRoadmapTag.roadmapTag; +import static co.kirikiri.goalroom.domain.QGoalRoom.goalRoom; +import static co.kirikiri.goalroom.domain.QGoalRoomMember.goalRoomMember; +import co.kirikiri.common.persistence.QuerydslRepositorySupporter; import co.kirikiri.domain.member.Member; import co.kirikiri.domain.member.vo.Identifier; import co.kirikiri.domain.roadmap.Roadmap; import co.kirikiri.domain.roadmap.RoadmapCategory; import co.kirikiri.domain.roadmap.RoadmapStatus; -import co.kirikiri.persistence.QuerydslRepositorySupporter; import co.kirikiri.persistence.dto.RoadmapOrderType; import co.kirikiri.persistence.dto.RoadmapSearchCreatorNickname; import co.kirikiri.persistence.dto.RoadmapSearchDto; @@ -171,18 +171,18 @@ private BooleanExpression tagCond(final RoadmapSearchTagName tagName) { } private OrderSpecifier sortCond(final RoadmapOrderType orderType) { - if (orderType == RoadmapOrderType.GOAL_ROOM_COUNT) { - return new OrderSpecifier<>( - Order.DESC, - goalRoomCountCond(goalRoom.roadmapContent.roadmap.eq(roadmap)) - ); - } - if (orderType == RoadmapOrderType.PARTICIPANT_COUNT) { - return new OrderSpecifier<>( - Order.DESC, - participantCountCond(goalRoomMember.goalRoom.roadmapContent.roadmap.eq(roadmap)) - ); - } +// if (orderType == RoadmapOrderType.GOAL_ROOM_COUNT) { +// return new OrderSpecifier<>( +// Order.DESC, +// goalRoomCountCond(goalRoom.roadmapContent.roadmap.eq(roadmap)) +// ); +// } +// if (orderType == RoadmapOrderType.PARTICIPANT_COUNT) { +// return new OrderSpecifier<>( +// Order.DESC, +// participantCountCond(goalRoomMember.goalRoom.roadmapContent.roadmap.eq(roadmap)) +// ); +// } if (orderType == RoadmapOrderType.REVIEW_RATE) { return new OrderSpecifier<>( Order.DESC, @@ -214,16 +214,16 @@ private BooleanExpression lessThanLastId(final Long lastId, final RoadmapOrderTy if (lastId == null) { return null; } - if (orderType == RoadmapOrderType.GOAL_ROOM_COUNT) { - final NumberPath goalRoomRoadmapId = goalRoom.roadmapContent.roadmap.id; - return goalRoomCountCond(goalRoomRoadmapId.eq(roadmap.id)) - .lt(goalRoomCountCond(goalRoomRoadmapId.eq(lastId))); - } - if (orderType == RoadmapOrderType.PARTICIPANT_COUNT) { - final NumberPath goalRoomMemberRoadmapId = goalRoomMember.goalRoom.roadmapContent.roadmap.id; - return participantCountCond(goalRoomMemberRoadmapId.eq(roadmap.id)) - .lt(participantCountCond(goalRoomMemberRoadmapId.eq(lastId))); - } +// if (orderType == RoadmapOrderType.GOAL_ROOM_COUNT) { +// final NumberPath goalRoomRoadmapId = goalRoom.roadmapContent.roadmap.id; +// return goalRoomCountCond(goalRoomRoadmapId.eq(roadmap.id)) +// .lt(goalRoomCountCond(goalRoomRoadmapId.eq(lastId))); +// } +// if (orderType == RoadmapOrderType.PARTICIPANT_COUNT) { +// final NumberPath goalRoomMemberRoadmapId = goalRoomMember.goalRoom.roadmapContent.roadmap.id; +// return participantCountCond(goalRoomMemberRoadmapId.eq(roadmap.id)) +// .lt(participantCountCond(goalRoomMemberRoadmapId.eq(lastId))); +// } if (orderType == RoadmapOrderType.REVIEW_RATE) { final NumberPath roadmapReviewRoadmapId = roadmapReview.roadmap.id; return reviewRateCond(roadmapReviewRoadmapId.eq(roadmap.id)) diff --git a/backend/kirikiri/src/main/java/co/kirikiri/persistence/roadmap/RoadmapReviewQueryRepositoryImpl.java b/backend/kirikiri/src/main/java/co/kirikiri/persistence/roadmap/RoadmapReviewQueryRepositoryImpl.java index a0dc47a56..894983742 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/persistence/roadmap/RoadmapReviewQueryRepositoryImpl.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/persistence/roadmap/RoadmapReviewQueryRepositoryImpl.java @@ -3,9 +3,9 @@ import static co.kirikiri.domain.member.QMember.member; import static co.kirikiri.domain.roadmap.QRoadmapReview.roadmapReview; +import co.kirikiri.common.persistence.QuerydslRepositorySupporter; import co.kirikiri.domain.roadmap.Roadmap; import co.kirikiri.domain.roadmap.RoadmapReview; -import co.kirikiri.persistence.QuerydslRepositorySupporter; import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.dsl.BooleanExpression; import java.time.LocalDateTime; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/UUIDFilePathGenerator.java b/backend/kirikiri/src/main/java/co/kirikiri/service/UUIDFilePathGenerator.java index 6d6450e2c..ebdf8ca81 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/UUIDFilePathGenerator.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/UUIDFilePathGenerator.java @@ -1,6 +1,8 @@ package co.kirikiri.service; -import co.kirikiri.service.exception.BadRequestException; +import co.kirikiri.common.exception.BadRequestException; +import co.kirikiri.common.service.FilePathGenerator; +import co.kirikiri.common.type.ImageDirType; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.UUID; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/auth/AuthService.java b/backend/kirikiri/src/main/java/co/kirikiri/service/auth/AuthService.java index f8cc195f0..9f72df0ea 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/auth/AuthService.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/auth/AuthService.java @@ -1,16 +1,16 @@ package co.kirikiri.service.auth; +import co.kirikiri.common.aop.ExceptionConvert; +import co.kirikiri.common.exception.AuthenticationException; import co.kirikiri.domain.member.Member; import co.kirikiri.domain.member.vo.Identifier; import co.kirikiri.domain.member.vo.Password; import co.kirikiri.persistence.auth.RefreshTokenRepository; import co.kirikiri.persistence.member.MemberRepository; -import co.kirikiri.service.aop.ExceptionConvert; import co.kirikiri.service.dto.auth.LoginDto; import co.kirikiri.service.dto.auth.request.LoginRequest; import co.kirikiri.service.dto.auth.request.ReissueTokenRequest; import co.kirikiri.service.dto.auth.response.AuthenticationResponse; -import co.kirikiri.service.exception.AuthenticationException; import co.kirikiri.service.mapper.AuthMapper; import java.util.Map; import lombok.RequiredArgsConstructor; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/auth/JwtTokenProvider.java b/backend/kirikiri/src/main/java/co/kirikiri/service/auth/JwtTokenProvider.java index 2b91cf904..dcfaeda37 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/auth/JwtTokenProvider.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/auth/JwtTokenProvider.java @@ -1,6 +1,6 @@ package co.kirikiri.service.auth; -import co.kirikiri.service.exception.AuthenticationException; +import co.kirikiri.common.exception.AuthenticationException; import io.jsonwebtoken.Claims; import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.Jws; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/FileInformation.java b/backend/kirikiri/src/main/java/co/kirikiri/service/dto/FileInformation.java deleted file mode 100644 index 0c1fc17b7..000000000 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/FileInformation.java +++ /dev/null @@ -1,12 +0,0 @@ -package co.kirikiri.service.dto; - -import java.io.InputStream; - -public record FileInformation( - String originalFileName, - long size, - String contentType, - InputStream inputStream -) { - -} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomCheckFeedDto.java b/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomCheckFeedDto.java deleted file mode 100644 index 06e0d4323..000000000 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/GoalRoomCheckFeedDto.java +++ /dev/null @@ -1,10 +0,0 @@ -package co.kirikiri.service.dto.goalroom; - -import co.kirikiri.service.dto.member.MemberDto; - -public record GoalRoomCheckFeedDto( - MemberDto memberDto, - CheckFeedDto checkFeedDto -) { - -} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomCheckFeedResponse.java b/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomCheckFeedResponse.java deleted file mode 100644 index 011b2d38d..000000000 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomCheckFeedResponse.java +++ /dev/null @@ -1,10 +0,0 @@ -package co.kirikiri.service.dto.goalroom.response; - -import co.kirikiri.service.dto.member.response.MemberResponse; - -public record GoalRoomCheckFeedResponse( - MemberResponse member, - CheckFeedResponse checkFeed -) { - -} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/member/request/GenderType.java b/backend/kirikiri/src/main/java/co/kirikiri/service/dto/member/request/GenderType.java index 164ebc537..0af6e6334 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/member/request/GenderType.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/dto/member/request/GenderType.java @@ -1,6 +1,6 @@ package co.kirikiri.service.dto.member.request; -import co.kirikiri.service.exception.BadRequestException; +import co.kirikiri.common.exception.BadRequestException; import java.util.Arrays; public enum GenderType { diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/roadmap/RoadmapNodeSaveDto.java b/backend/kirikiri/src/main/java/co/kirikiri/service/dto/roadmap/RoadmapNodeSaveDto.java index 474aab738..598b9e125 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/roadmap/RoadmapNodeSaveDto.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/dto/roadmap/RoadmapNodeSaveDto.java @@ -1,6 +1,6 @@ package co.kirikiri.service.dto.roadmap; -import co.kirikiri.service.dto.FileInformation; +import co.kirikiri.common.service.dto.FileInformation; import java.util.List; public record RoadmapNodeSaveDto( diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/roadmap/response/RoadmapGoalRoomResponses.java b/backend/kirikiri/src/main/java/co/kirikiri/service/dto/roadmap/response/RoadmapGoalRoomResponses.java index 1bb5df0dd..775066a6b 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/roadmap/response/RoadmapGoalRoomResponses.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/dto/roadmap/response/RoadmapGoalRoomResponses.java @@ -1,5 +1,6 @@ package co.kirikiri.service.dto.roadmap.response; +import co.kirikiri.goalroom.service.dto.response.RoadmapGoalRoomResponse; import java.util.List; public record RoadmapGoalRoomResponses( diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/goalroom/GoalRoomCreateService.java b/backend/kirikiri/src/main/java/co/kirikiri/service/goalroom/GoalRoomCreateService.java deleted file mode 100644 index 7e34b03ea..000000000 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/goalroom/GoalRoomCreateService.java +++ /dev/null @@ -1,325 +0,0 @@ -package co.kirikiri.service.goalroom; - -import co.kirikiri.domain.ImageContentType; -import co.kirikiri.domain.goalroom.CheckFeed; -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomMember; -import co.kirikiri.domain.goalroom.GoalRoomPendingMember; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNode; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNodes; -import co.kirikiri.domain.goalroom.GoalRoomToDo; -import co.kirikiri.domain.goalroom.GoalRoomToDoCheck; -import co.kirikiri.domain.goalroom.vo.Period; -import co.kirikiri.domain.member.Member; -import co.kirikiri.domain.member.vo.Identifier; -import co.kirikiri.domain.roadmap.Roadmap; -import co.kirikiri.domain.roadmap.RoadmapContent; -import co.kirikiri.domain.roadmap.RoadmapNode; -import co.kirikiri.persistence.goalroom.CheckFeedRepository; -import co.kirikiri.persistence.goalroom.GoalRoomMemberRepository; -import co.kirikiri.persistence.goalroom.GoalRoomRepository; -import co.kirikiri.persistence.goalroom.GoalRoomToDoCheckRepository; -import co.kirikiri.persistence.member.MemberRepository; -import co.kirikiri.persistence.roadmap.RoadmapContentRepository; -import co.kirikiri.service.FilePathGenerator; -import co.kirikiri.service.FileService; -import co.kirikiri.service.ImageDirType; -import co.kirikiri.service.aop.ExceptionConvert; -import co.kirikiri.service.dto.FileInformation; -import co.kirikiri.service.dto.goalroom.GoalRoomCreateDto; -import co.kirikiri.service.dto.goalroom.GoalRoomRoadmapNodeDto; -import co.kirikiri.service.dto.goalroom.request.CheckFeedRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomCreateRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomTodoRequest; -import co.kirikiri.service.dto.goalroom.response.GoalRoomToDoCheckResponse; -import co.kirikiri.service.exception.BadRequestException; -import co.kirikiri.service.exception.NotFoundException; -import co.kirikiri.service.mapper.GoalRoomMapper; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.List; -import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpMethod; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; - -@Service -@Transactional -@RequiredArgsConstructor -@ExceptionConvert -public class GoalRoomCreateService { - - private final FileService fileService; - private final FilePathGenerator filePathGenerator; - private final MemberRepository memberRepository; - private final GoalRoomRepository goalRoomRepository; - private final RoadmapContentRepository roadmapContentRepository; - private final GoalRoomMemberRepository goalRoomMemberRepository; - private final GoalRoomToDoCheckRepository goalRoomToDoCheckRepository; - private final CheckFeedRepository checkFeedRepository; - - public Long create(final GoalRoomCreateRequest goalRoomCreateRequest, final String memberIdentifier) { - final GoalRoomCreateDto goalRoomCreateDto = GoalRoomMapper.convertToGoalRoomCreateDto(goalRoomCreateRequest); - final RoadmapContent roadmapContent = findRoadmapContentById(goalRoomCreateDto.roadmapContentId()); - validateDeletedRoadmap(roadmapContent); - validateNodeSizeEqual(roadmapContent.nodesSize(), goalRoomCreateDto.goalRoomRoadmapNodeDtosSize()); - final GoalRoomRoadmapNodes goalRoomRoadmapNodes = makeGoalRoomRoadmapNodes( - goalRoomCreateDto.goalRoomRoadmapNodeDtos(), roadmapContent); - final Member leader = findMemberByIdentifier(memberIdentifier); - - final GoalRoom goalRoom = new GoalRoom(goalRoomCreateDto.goalRoomName(), goalRoomCreateDto.limitedMemberCount(), - roadmapContent, leader); - goalRoom.addAllGoalRoomRoadmapNodes(goalRoomRoadmapNodes); - return goalRoomRepository.save(goalRoom).getId(); - } - - private RoadmapContent findRoadmapContentById(final Long roadmapContentId) { - return roadmapContentRepository.findByIdWithRoadmap(roadmapContentId) - .orElseThrow(() -> new NotFoundException("존재하지 않는 로드맵입니다.")); - } - - private void validateDeletedRoadmap(final RoadmapContent roadmapContent) { - final Roadmap roadmap = roadmapContent.getRoadmap(); - if (roadmap.isDeleted()) { - throw new BadRequestException("삭제된 로드맵에 대해 골룸을 생성할 수 없습니다."); - } - } - - private void validateNodeSizeEqual(final int roadmapNodesSize, final int goalRoomRoadmapNodeDtosSize) { - if (roadmapNodesSize != goalRoomRoadmapNodeDtosSize) { - throw new BadRequestException("모든 노드에 대해 기간이 설정돼야 합니다."); - } - } - - private GoalRoomRoadmapNodes makeGoalRoomRoadmapNodes(final List goalRoomRoadmapNodeDtos, - final RoadmapContent roadmapContent) { - final List goalRoomRoadmapNodes = goalRoomRoadmapNodeDtos.stream() - .map(it -> makeGoalRoomRoadmapNode(roadmapContent, it)) - .toList(); - return new GoalRoomRoadmapNodes(goalRoomRoadmapNodes); - } - - private GoalRoomRoadmapNode makeGoalRoomRoadmapNode(final RoadmapContent roadmapContent, - final GoalRoomRoadmapNodeDto it) { - return new GoalRoomRoadmapNode(new Period(it.startDate(), it.endDate()), it.checkCount(), - findRoadmapNode(roadmapContent, it.roadmapNodeId())); - } - - private RoadmapNode findRoadmapNode(final RoadmapContent roadmapContent, final Long roadmapNodeId) { - return roadmapContent.findRoadmapNodeById(roadmapNodeId) - .orElseThrow(() -> new NotFoundException("로드맵에 존재하지 않는 노드입니다.")); - } - - private Member findMemberByIdentifier(final String memberIdentifier) { - return memberRepository.findByIdentifier(new Identifier(memberIdentifier)) - .orElseThrow(() -> new NotFoundException("존재하지 않는 회원입니다.")); - } - - public void join(final String identifier, final Long goalRoomId) { - final Member member = findMemberByIdentifier(identifier); - final GoalRoom goalRoom = findGoalRoomByIdWithPessimisticLock(goalRoomId); - goalRoom.join(member); - } - - private GoalRoom findGoalRoomByIdWithPessimisticLock(final Long goalRoomId) { - return goalRoomRepository.findGoalRoomByIdWithPessimisticLock(goalRoomId) - .orElseThrow(() -> new NotFoundException("존재하지 않는 골룸입니다. goalRoomId = " + goalRoomId)); - } - - public Long addGoalRoomTodo(final Long goalRoomId, final String identifier, - final GoalRoomTodoRequest goalRoomTodoRequest) { - final Member member = findMemberByIdentifier(identifier); - final GoalRoom goalRoom = findGoalRoomById(goalRoomId); - checkGoalRoomCompleted(goalRoom); - checkGoalRoomLeader(member, goalRoom, "골룸의 리더만 투두리스트를 추가할 수 있습니다."); - final GoalRoomToDo goalRoomToDo = GoalRoomMapper.convertToGoalRoomTodo(goalRoomTodoRequest); - goalRoom.addGoalRoomTodo(goalRoomToDo); - goalRoomRepository.save(goalRoom); - return goalRoom.findLastGoalRoomTodo().getId(); - } - - private GoalRoom findGoalRoomById(final Long goalRoomId) { - return goalRoomRepository.findById(goalRoomId) - .orElseThrow(() -> new NotFoundException("존재하지 않는 골룸입니다. goalRoomId = " + goalRoomId)); - } - - private void checkGoalRoomCompleted(final GoalRoom goalRoom) { - if (goalRoom.isCompleted()) { - throw new BadRequestException("이미 종료된 골룸입니다."); - } - } - - private void checkGoalRoomLeader(final Member member, final GoalRoom goalRoom, final String errorMessage) { - if (goalRoom.isNotLeader(member)) { - throw new BadRequestException(errorMessage); - } - } - - public GoalRoomToDoCheckResponse checkGoalRoomTodo(final Long goalRoomId, final Long todoId, - final String identifier) { - final Identifier memberIdentifier = new Identifier(identifier); - final GoalRoom goalRoom = findGoalRoomWithTodos(goalRoomId); - final GoalRoomToDo goalRoomToDo = findGoalRoomTodoById(todoId, goalRoom); - final GoalRoomMember goalRoomMember = findGoalRoomMember(memberIdentifier, goalRoom); - - final boolean isAlreadyChecked = goalRoomToDoCheckRepository.findByGoalRoomIdAndTodoAndMemberIdentifier( - goalRoomId, goalRoomToDo, memberIdentifier).isPresent(); - if (isAlreadyChecked) { - goalRoomToDoCheckRepository.deleteByGoalRoomMemberAndToDoId(goalRoomMember, todoId); - return new GoalRoomToDoCheckResponse(false); - } - final GoalRoomToDoCheck goalRoomToDoCheck = new GoalRoomToDoCheck(goalRoomMember, goalRoomToDo); - goalRoomToDoCheckRepository.save(goalRoomToDoCheck); - return new GoalRoomToDoCheckResponse(true); - } - - private GoalRoom findGoalRoomWithTodos(final Long goalRoomId) { - return goalRoomRepository.findByIdWithTodos(goalRoomId) - .orElseThrow(() -> new NotFoundException("골룸이 존재하지 않습니다. goalRoomId = " + goalRoomId)); - } - - private GoalRoomToDo findGoalRoomTodoById(final Long todoId, final GoalRoom goalRoom) { - return goalRoom.findGoalRoomTodoByTodoId(todoId) - .orElseThrow(() -> new NotFoundException("존재하지 않는 투두입니다. todoId = " + todoId)); - } - - private GoalRoomMember findGoalRoomMember(final Identifier memberIdentifier, final GoalRoom goalRoom) { - return goalRoomMemberRepository.findByGoalRoomAndMemberIdentifier(goalRoom, memberIdentifier) - .orElseThrow(() -> new NotFoundException( - "골룸에 사용자가 존재하지 않습니다. goalRoomId = " + goalRoom.getId() + " memberIdentifier = " - + memberIdentifier.getValue())); - } - - public String createCheckFeed(final String identifier, final Long goalRoomId, - final CheckFeedRequest checkFeedRequest) { - final MultipartFile checkFeedImage = checkFeedRequest.image(); - validateEmptyImage(checkFeedImage); - final FileInformation fileInformation = GoalRoomMapper.convertToFileInformation(checkFeedImage); - - final GoalRoom goalRoom = findGoalRoomById(goalRoomId); - final GoalRoomMember goalRoomMember = findGoalRoomMemberByGoalRoomAndIdentifier(goalRoom, identifier); - final GoalRoomRoadmapNode currentNode = getNodeByDate(goalRoom); - final int currentMemberCheckCount = checkFeedRepository.countByGoalRoomMemberAndGoalRoomRoadmapNode( - goalRoomMember, currentNode); - validateCheckCount(currentMemberCheckCount, goalRoomMember, currentNode); - updateAccomplishmentRate(goalRoom, goalRoomMember, currentMemberCheckCount); - - final String path = filePathGenerator.makeFilePath(ImageDirType.CHECK_FEED, - fileInformation.originalFileName()); - saveCheckFeed(checkFeedRequest, checkFeedImage, goalRoomMember, currentNode, path); - fileService.save(path, fileInformation); - return fileService.generateUrl(path, HttpMethod.GET).toExternalForm(); - } - - private void validateEmptyImage(final MultipartFile image) { - if (image.isEmpty()) { - throw new BadRequestException("인증 피드 등록 시 이미지가 반드시 포함되어야 합니다."); - } - - if (image.getOriginalFilename() == null) { - throw new BadRequestException("파일 이름은 반드시 포함되어야 합니다."); - } - } - - private GoalRoomMember findGoalRoomMemberByGoalRoomAndIdentifier(final GoalRoom goalRoom, final String identifier) { - return goalRoomMemberRepository.findByGoalRoomAndMemberIdentifier(goalRoom, new Identifier(identifier)) - .orElseThrow(() -> new NotFoundException("골룸에 해당 사용자가 존재하지 않습니다. 사용자 아이디 = " + identifier)); - } - - private GoalRoomRoadmapNode getNodeByDate(final GoalRoom goalRoom) { - return goalRoom.findNodeByDate(LocalDate.now()) - .orElseThrow(() -> new BadRequestException("인증 피드는 노드 기간 내에만 작성할 수 있습니다.")); - } - - private void validateCheckCount(final int memberCheckCount, final GoalRoomMember member, - final GoalRoomRoadmapNode goalRoomRoadmapNode) { - validateNodeCheckCount(memberCheckCount, goalRoomRoadmapNode); - validateTodayCheckCount(member); - } - - private void validateNodeCheckCount(final int memberCheckCount, - final GoalRoomRoadmapNode goalRoomRoadmapNode) { - if (memberCheckCount >= goalRoomRoadmapNode.getCheckCount()) { - throw new BadRequestException( - "이번 노드에는 최대 " + goalRoomRoadmapNode.getCheckCount() + "번만 인증 피드를 등록할 수 있습니다."); - } - } - - private void validateTodayCheckCount(final GoalRoomMember member) { - final LocalDate today = LocalDate.now(); - final LocalDateTime todayStart = today.atStartOfDay(); - final LocalDateTime todayEnd = today.plusDays(1).atStartOfDay(); - if (checkFeedRepository.findByGoalRoomMemberAndDateTime(member, todayStart, todayEnd).isPresent()) { - throw new BadRequestException("이미 오늘 인증 피드를 등록하였습니다."); - } - } - - private void updateAccomplishmentRate(final GoalRoom goalRoom, final GoalRoomMember goalRoomMember, - final int pastCheckCount) { - final int wholeCheckCount = goalRoom.getAllCheckCount(); - final int memberCheckCount = pastCheckCount + 1; - final Double accomplishmentRate = 100 * memberCheckCount / (double) wholeCheckCount; - goalRoomMember.updateAccomplishmentRate(accomplishmentRate); - } - - private void saveCheckFeed(final CheckFeedRequest checkFeedRequest, final MultipartFile checkFeedImage, - final GoalRoomMember goalRoomMember, final GoalRoomRoadmapNode currentNode, - final String path) { - checkFeedRepository.save( - new CheckFeed(path, ImageContentType.findImageContentType(checkFeedImage.getContentType()), - checkFeedImage.getOriginalFilename(), - checkFeedRequest.description(), currentNode, goalRoomMember)); - } - - public void startGoalRoom(final String memberIdentifier, final Long goalRoomId) { - final Member member = findMemberByIdentifier(memberIdentifier); - final GoalRoom goalRoom = findGoalRoomById(goalRoomId); - checkGoalRoomLeader(member, goalRoom, "골룸의 리더만 골룸을 시작할 수 있습니다."); - validateGoalRoomStart(goalRoom); - final List goalRoomPendingMembers = goalRoom.getGoalRoomPendingMembers().getValues(); - saveGoalRoomMemberFromPendingMembers(goalRoomPendingMembers, goalRoom); - goalRoom.start(); - } - - private void validateGoalRoomStart(final GoalRoom goalRoom) { - if (goalRoom.cannotStart()) { - throw new BadRequestException("골룸의 시작 날짜가 되지 않았습니다."); - } - } - - private void saveGoalRoomMemberFromPendingMembers(final List goalRoomPendingMembers, - final GoalRoom goalRoom) { - final List goalRoomMembers = makeGoalRoomMembers(goalRoomPendingMembers); - goalRoom.addAllGoalRoomMembers(goalRoomMembers); - goalRoom.deleteAllPendingMembers(); - } - - private List makeGoalRoomMembers(final List goalRoomPendingMembers) { - return goalRoomPendingMembers.stream() - .map(this::makeGoalRoomMember) - .toList(); - } - - private GoalRoomMember makeGoalRoomMember(final GoalRoomPendingMember goalRoomPendingMember) { - return new GoalRoomMember(goalRoomPendingMember.getRole(), - goalRoomPendingMember.getJoinedAt(), goalRoomPendingMember.getGoalRoom(), - goalRoomPendingMember.getMember()); - } - - public void leave(final String identifier, final Long goalRoomId) { - final Member member = findMemberByIdentifier(identifier); - final GoalRoom goalRoom = findGoalRoomById(goalRoomId); - validateStatus(goalRoom); - goalRoom.leave(member); - if (goalRoom.isEmptyGoalRoom()) { - goalRoomRepository.delete(goalRoom); - } - } - - private void validateStatus(final GoalRoom goalRoom) { - if (goalRoom.isRunning()) { - throw new BadRequestException("진행중인 골룸에서는 나갈 수 없습니다."); - } - } -} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/mapper/RoadmapMapper.java b/backend/kirikiri/src/main/java/co/kirikiri/service/mapper/RoadmapMapper.java index a5efc4376..d55511327 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/mapper/RoadmapMapper.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/mapper/RoadmapMapper.java @@ -1,10 +1,11 @@ package co.kirikiri.service.mapper; +import co.kirikiri.common.exception.ServerException; +import co.kirikiri.common.service.dto.FileInformation; import co.kirikiri.domain.member.Member; import co.kirikiri.domain.roadmap.Roadmap; import co.kirikiri.domain.roadmap.RoadmapCategory; import co.kirikiri.persistence.dto.RoadmapOrderType; -import co.kirikiri.service.dto.FileInformation; import co.kirikiri.service.dto.member.MemberDto; import co.kirikiri.service.dto.member.response.MemberResponse; import co.kirikiri.service.dto.roadmap.RoadmapCategoryDto; @@ -36,7 +37,6 @@ import co.kirikiri.service.dto.roadmap.response.RoadmapResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapReviewResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapTagResponse; -import co.kirikiri.service.exception.ServerException; import java.io.IOException; import java.util.Collections; import java.util.List; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/member/MemberService.java b/backend/kirikiri/src/main/java/co/kirikiri/service/member/MemberService.java index 2fec1552c..dc169c7f6 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/member/MemberService.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/member/MemberService.java @@ -1,6 +1,10 @@ package co.kirikiri.service.member; -import co.kirikiri.domain.ImageContentType; +import co.kirikiri.common.aop.ExceptionConvert; +import co.kirikiri.common.exception.ConflictException; +import co.kirikiri.common.exception.NotFoundException; +import co.kirikiri.common.service.FileService; +import co.kirikiri.common.type.ImageContentType; import co.kirikiri.domain.member.EncryptedPassword; import co.kirikiri.domain.member.Gender; import co.kirikiri.domain.member.Member; @@ -10,9 +14,7 @@ import co.kirikiri.domain.member.vo.Nickname; import co.kirikiri.persistence.auth.RefreshTokenRepository; import co.kirikiri.persistence.member.MemberRepository; -import co.kirikiri.service.FileService; import co.kirikiri.service.NumberGenerator; -import co.kirikiri.service.aop.ExceptionConvert; import co.kirikiri.service.auth.TokenProvider; import co.kirikiri.service.dto.auth.response.AuthenticationResponse; import co.kirikiri.service.dto.member.MemberInformationDto; @@ -22,8 +24,6 @@ import co.kirikiri.service.dto.member.request.MemberJoinRequest; import co.kirikiri.service.dto.member.response.MemberInformationForPublicResponse; import co.kirikiri.service.dto.member.response.MemberInformationResponse; -import co.kirikiri.service.exception.ConflictException; -import co.kirikiri.service.exception.NotFoundException; import co.kirikiri.service.mapper.AuthMapper; import co.kirikiri.service.mapper.MemberMapper; import java.net.URL; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapCreateEventListener.java b/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapCreateEventListener.java index 833c59de6..c70e02070 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapCreateEventListener.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapCreateEventListener.java @@ -1,21 +1,21 @@ package co.kirikiri.service.roadmap; -import co.kirikiri.domain.ImageContentType; +import co.kirikiri.common.aop.ExceptionConvert; +import co.kirikiri.common.exception.BadRequestException; +import co.kirikiri.common.exception.ServerException; +import co.kirikiri.common.service.FilePathGenerator; +import co.kirikiri.common.service.FileService; +import co.kirikiri.common.service.dto.FileInformation; +import co.kirikiri.common.type.ImageContentType; +import co.kirikiri.common.type.ImageDirType; import co.kirikiri.domain.roadmap.Roadmap; import co.kirikiri.domain.roadmap.RoadmapContent; import co.kirikiri.domain.roadmap.RoadmapNode; import co.kirikiri.domain.roadmap.RoadmapNodeImage; import co.kirikiri.domain.roadmap.RoadmapNodeImages; import co.kirikiri.persistence.roadmap.RoadmapContentRepository; -import co.kirikiri.service.FilePathGenerator; -import co.kirikiri.service.FileService; -import co.kirikiri.service.ImageDirType; -import co.kirikiri.service.aop.ExceptionConvert; -import co.kirikiri.service.dto.FileInformation; import co.kirikiri.service.dto.roadmap.RoadmapNodeSaveDto; import co.kirikiri.service.event.RoadmapCreateEvent; -import co.kirikiri.service.exception.BadRequestException; -import co.kirikiri.service.exception.ServerException; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.scheduling.annotation.Async; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapCreateService.java b/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapCreateService.java index 77bce647b..7f4785bb6 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapCreateService.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapCreateService.java @@ -1,8 +1,11 @@ package co.kirikiri.service.roadmap; -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomMember; -import co.kirikiri.domain.goalroom.GoalRoomStatus; +import co.kirikiri.common.aop.ExceptionConvert; +import co.kirikiri.common.exception.AuthenticationException; +import co.kirikiri.common.exception.BadRequestException; +import co.kirikiri.common.exception.ConflictException; +import co.kirikiri.common.exception.ForbiddenException; +import co.kirikiri.common.exception.NotFoundException; import co.kirikiri.domain.member.Member; import co.kirikiri.domain.member.vo.Identifier; import co.kirikiri.domain.roadmap.Roadmap; @@ -15,13 +18,16 @@ import co.kirikiri.domain.roadmap.RoadmapTag; import co.kirikiri.domain.roadmap.RoadmapTags; import co.kirikiri.domain.roadmap.vo.RoadmapTagName; -import co.kirikiri.persistence.goalroom.GoalRoomMemberRepository; -import co.kirikiri.persistence.goalroom.GoalRoomRepository; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomMember; +import co.kirikiri.goalroom.domain.GoalRoomStatus; +import co.kirikiri.goalroom.persistence.GoalRoomMemberRepository; +import co.kirikiri.goalroom.persistence.GoalRoomRepository; import co.kirikiri.persistence.member.MemberRepository; import co.kirikiri.persistence.roadmap.RoadmapCategoryRepository; +import co.kirikiri.persistence.roadmap.RoadmapContentRepository; import co.kirikiri.persistence.roadmap.RoadmapRepository; import co.kirikiri.persistence.roadmap.RoadmapReviewRepository; -import co.kirikiri.service.aop.ExceptionConvert; import co.kirikiri.service.dto.roadmap.RoadmapNodeSaveDto; import co.kirikiri.service.dto.roadmap.RoadmapReviewDto; import co.kirikiri.service.dto.roadmap.RoadmapSaveDto; @@ -30,11 +36,6 @@ import co.kirikiri.service.dto.roadmap.request.RoadmapReviewSaveRequest; import co.kirikiri.service.dto.roadmap.request.RoadmapSaveRequest; import co.kirikiri.service.event.RoadmapCreateEvent; -import co.kirikiri.service.exception.AuthenticationException; -import co.kirikiri.service.exception.BadRequestException; -import co.kirikiri.service.exception.ConflictException; -import co.kirikiri.service.exception.ForbiddenException; -import co.kirikiri.service.exception.NotFoundException; import co.kirikiri.service.mapper.RoadmapMapper; import java.util.List; import lombok.RequiredArgsConstructor; @@ -51,6 +52,7 @@ public class RoadmapCreateService { private final MemberRepository memberRepository; private final RoadmapRepository roadmapRepository; + private final RoadmapContentRepository roadmapContentRepository; private final RoadmapReviewRepository roadmapReviewRepository; private final GoalRoomRepository goalRoomRepository; private final GoalRoomMemberRepository goalRoomMemberRepository; @@ -122,8 +124,10 @@ private Roadmap makeRoadmap(final Member member, final RoadmapSaveDto roadmapSav public void createReview(final Long roadmapId, final String identifier, final RoadmapReviewSaveRequest request) { final Roadmap roadmap = findRoadmapById(roadmapId); - final GoalRoomMember goalRoomMember = findCompletedGoalRoomMember(roadmapId, identifier); - final Member member = goalRoomMember.getMember(); + final Member member = findMemberByIdentifier(identifier); + final GoalRoomMember goalRoomMember = findCompletedGoalRoomMember(roadmapId, member.getId()); +// final Long memberId = goalRoomMember.getMemberId(); +// final Member member = findMemberById(memberId); final RoadmapReviewDto roadmapReviewDto = RoadmapMapper.convertRoadmapReviewDto(request, member); validateReviewQualification(roadmap, member); validateReviewCount(roadmap, member); @@ -137,11 +141,16 @@ private Roadmap findRoadmapById(final Long id) { .orElseThrow(() -> new NotFoundException("존재하지 않는 로드맵입니다. roadmapId = " + id)); } - private GoalRoomMember findCompletedGoalRoomMember(final Long roadmapId, final String identifier) { - return goalRoomMemberRepository.findByRoadmapIdAndMemberIdentifierAndGoalRoomStatus(roadmapId, - new Identifier(identifier), GoalRoomStatus.COMPLETED) + private GoalRoomMember findCompletedGoalRoomMember(final Long roadmapId, final Long memberId) { + return goalRoomMemberRepository.findByRoadmapIdAndMemberIdentifierAndGoalRoomStatus(roadmapId, memberId, + GoalRoomStatus.COMPLETED) .orElseThrow(() -> new BadRequestException( - "로드맵에 대해서 완료된 골룸이 존재하지 않습니다. roadmapId = " + roadmapId + " memberIdentifier = " + identifier)); + "로드맵에 대해서 완료된 골룸이 존재하지 않습니다. roadmapId = " + roadmapId + " memberId = " + memberId)); + } + + private Member findMemberById(final Long memberId) { + return memberRepository.findById(memberId) + .orElseThrow(() -> new NotFoundException("존재하지 않는 회원입니다. memberId = " + memberId)); } private void validateReviewQualification(final Roadmap roadmap, final Member member) { @@ -162,7 +171,8 @@ private void validateReviewCount(final Roadmap roadmap, final Member member) { public void deleteRoadmap(final String identifier, final Long roadmapId) { final Roadmap roadmap = findRoadmapById(roadmapId); validateRoadmapCreator(roadmapId, identifier); - final List goalRooms = goalRoomRepository.findByRoadmap(roadmap); + final RoadmapContent roadmapContent = findRecentContent(roadmap); + final List goalRooms = goalRoomRepository.findByRoadmapContentId(roadmapContent.getId()); if (goalRooms.isEmpty()) { roadmapRepository.delete(roadmap); return; @@ -170,6 +180,11 @@ public void deleteRoadmap(final String identifier, final Long roadmapId) { roadmap.delete(); } + private RoadmapContent findRecentContent(final Roadmap roadmap) { + return roadmapContentRepository.findFirstByRoadmapOrderByCreatedAtDesc(roadmap) + .orElseThrow(() -> new NotFoundException("로드맵에 컨텐츠가 존재하지 않습니다.")); + } + private void validateRoadmapCreator(final Long roadmapId, final String identifier) { roadmapRepository.findByIdAndMemberIdentifier(roadmapId, identifier) .orElseThrow(() -> new ForbiddenException("해당 로드맵을 생성한 사용자가 아닙니다.")); diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapReadService.java b/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapReadService.java index 7afa4fce1..0f2f0a7da 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapReadService.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/roadmap/RoadmapReadService.java @@ -1,6 +1,8 @@ package co.kirikiri.service.roadmap; -import co.kirikiri.domain.goalroom.GoalRoom; +import co.kirikiri.common.aop.ExceptionConvert; +import co.kirikiri.common.exception.NotFoundException; +import co.kirikiri.common.service.FileService; import co.kirikiri.domain.member.Member; import co.kirikiri.domain.member.vo.Identifier; import co.kirikiri.domain.roadmap.Roadmap; @@ -10,20 +12,20 @@ import co.kirikiri.domain.roadmap.RoadmapNodes; import co.kirikiri.domain.roadmap.RoadmapReview; import co.kirikiri.domain.roadmap.RoadmapTags; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.persistence.GoalRoomRepository; +import co.kirikiri.goalroom.persistence.dto.RoadmapGoalRoomsOrderType; +import co.kirikiri.goalroom.service.dto.RoadmapGoalRoomDto; +import co.kirikiri.goalroom.service.dto.RoadmapGoalRoomScrollDto; +import co.kirikiri.goalroom.service.mapper.GoalRoomMapper; import co.kirikiri.persistence.dto.RoadmapOrderType; import co.kirikiri.persistence.dto.RoadmapSearchDto; -import co.kirikiri.persistence.goalroom.GoalRoomRepository; -import co.kirikiri.persistence.goalroom.dto.RoadmapGoalRoomsOrderType; import co.kirikiri.persistence.member.MemberRepository; import co.kirikiri.persistence.roadmap.RoadmapCategoryRepository; import co.kirikiri.persistence.roadmap.RoadmapContentRepository; import co.kirikiri.persistence.roadmap.RoadmapRepository; import co.kirikiri.persistence.roadmap.RoadmapReviewRepository; -import co.kirikiri.service.FileService; -import co.kirikiri.service.aop.ExceptionConvert; import co.kirikiri.service.dto.CustomScrollRequest; -import co.kirikiri.service.dto.goalroom.RoadmapGoalRoomDto; -import co.kirikiri.service.dto.goalroom.RoadmapGoalRoomScrollDto; import co.kirikiri.service.dto.member.MemberDto; import co.kirikiri.service.dto.roadmap.RoadmapCategoryDto; import co.kirikiri.service.dto.roadmap.RoadmapContentDto; @@ -43,8 +45,6 @@ import co.kirikiri.service.dto.roadmap.response.RoadmapGoalRoomResponses; import co.kirikiri.service.dto.roadmap.response.RoadmapResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapReviewResponse; -import co.kirikiri.service.exception.NotFoundException; -import co.kirikiri.service.mapper.GoalRoomMapper; import co.kirikiri.service.mapper.RoadmapMapper; import co.kirikiri.service.mapper.ScrollResponseMapper; import java.net.URL; @@ -73,7 +73,7 @@ public class RoadmapReadService { public RoadmapResponse findRoadmap(final Long id) { final Roadmap roadmap = findRoadmapById(id); final RoadmapContent recentRoadmapContent = findRecentContent(roadmap); - final List goalRooms = goalRoomRepository.findByRoadmap(roadmap); + final List goalRooms = goalRoomRepository.findByRoadmapContentId(recentRoadmapContent.getId()); final RoadmapGoalRoomNumberDto roadmapGoalRoomNumberDto = GoalRoomMapper.convertRoadmapGoalRoomDto(goalRooms); final RoadmapDto roadmapDto = makeRoadmapDto(roadmap, recentRoadmapContent); return RoadmapMapper.convertToRoadmapResponse(roadmapDto, roadmapGoalRoomNumberDto); @@ -227,15 +227,20 @@ public RoadmapGoalRoomResponses findRoadmapGoalRoomsByOrderType(final Long roadm final CustomScrollRequest scrollRequest) { final Roadmap roadmap = findRoadmapById(roadmapId); final RoadmapGoalRoomsOrderType orderType = GoalRoomMapper.convertToGoalRoomOrderType(orderTypeDto); - final List goalRooms = goalRoomRepository.findGoalRoomsByRoadmapAndCond( - roadmap, orderType, scrollRequest.lastId(), scrollRequest.size()); - final RoadmapGoalRoomScrollDto roadmapGoalRoomScrollDto = makeGoalRoomDtos(goalRooms, - scrollRequest.size()); + final RoadmapContent roadmapContent = findRecentContent(roadmap); + final List goalRooms = goalRoomRepository.findGoalRoomsByRoadmapContentIdAndCond( + roadmapContent.getId(), orderType, scrollRequest.lastId(), scrollRequest.size()); + final RoadmapGoalRoomScrollDto roadmapGoalRoomScrollDto = makeGoalRoomDtos(goalRooms, scrollRequest.size()); return GoalRoomMapper.convertToRoadmapGoalRoomResponses(roadmapGoalRoomScrollDto); } - public RoadmapGoalRoomScrollDto makeGoalRoomDtos(final List goalRooms, - final int requestSize) { +// private RoadmapContent findRoadmapContentByRoadmap(final Roadmap roadmap) { +// return roadmapContentRepository.findByRoadmap(roadmap) +// .orElseThrow(() -> new NotFoundException("존재하지 않는 로드맵 컨텐츠입니다.")); +// } + + private RoadmapGoalRoomScrollDto makeGoalRoomDtos(final List goalRooms, + final int requestSize) { final List roadmapGoalRoomDtos = goalRooms.stream() .map(this::makeGoalRoomDto) .toList(); @@ -245,11 +250,23 @@ public RoadmapGoalRoomScrollDto makeGoalRoomDtos(final List goalRooms, } private RoadmapGoalRoomDto makeGoalRoomDto(final GoalRoom goalRoom) { - final Member goalRoomLeader = goalRoom.findGoalRoomLeader(); + final Long goalRoomLeaderId = goalRoom.findGoalRoomLeaderId(); return new RoadmapGoalRoomDto(goalRoom.getId(), goalRoom.getName().getValue(), goalRoom.getStatus(), goalRoom.getCurrentMemberCount(), goalRoom.getLimitedMemberCount().getValue(), goalRoom.getCreatedAt(), goalRoom.getStartDate(), - goalRoom.getEndDate(), makeMemberDto(goalRoomLeader)); + goalRoom.getEndDate(), makeMemberDto(goalRoomLeaderId)); + } + + private co.kirikiri.goalroom.service.dto.MemberDto makeMemberDto(final Long creatorId) { + final Member creator = findMemberById(creatorId); + final URL url = fileService.generateUrl(creator.getImage().getServerFilePath(), HttpMethod.GET); + return new co.kirikiri.goalroom.service.dto.MemberDto(creator.getId(), creator.getNickname().getValue(), + url.toExternalForm()); + } + + private Member findMemberById(final Long creatorId) { + return memberRepository.findById(creatorId) + .orElseThrow(() -> new NotFoundException("존재하지 않는 회원입니다. memberId = " + creatorId)); } public List findRoadmapReviews(final Long roadmapId, diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/scheduler/RoadmapScheduler.java b/backend/kirikiri/src/main/java/co/kirikiri/service/scheduler/RoadmapScheduler.java index 92af456a9..eb640aa57 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/scheduler/RoadmapScheduler.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/service/scheduler/RoadmapScheduler.java @@ -1,11 +1,14 @@ package co.kirikiri.service.scheduler; -import co.kirikiri.domain.goalroom.GoalRoom; +import co.kirikiri.common.aop.ExceptionConvert; +import co.kirikiri.common.exception.NotFoundException; import co.kirikiri.domain.roadmap.Roadmap; +import co.kirikiri.domain.roadmap.RoadmapContent; import co.kirikiri.domain.roadmap.RoadmapStatus; -import co.kirikiri.persistence.goalroom.GoalRoomRepository; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.persistence.GoalRoomRepository; +import co.kirikiri.persistence.roadmap.RoadmapContentRepository; import co.kirikiri.persistence.roadmap.RoadmapRepository; -import co.kirikiri.service.aop.ExceptionConvert; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.scheduling.annotation.Scheduled; @@ -21,6 +24,7 @@ public class RoadmapScheduler { private static final int DELETE_AFTER_MONTH = 3; private final RoadmapRepository roadmapRepository; + private final RoadmapContentRepository roadmapContentRepository; private final GoalRoomRepository goalRoomRepository; @Scheduled(cron = "0 0 4 * * *") @@ -28,12 +32,18 @@ public void deleteRoadmaps() { final RoadmapStatus status = RoadmapStatus.DELETED; final List deletedStatusRoadmaps = roadmapRepository.findWithRoadmapContentByStatus(status); for (final Roadmap roadmap : deletedStatusRoadmaps) { - delete(roadmap); + final RoadmapContent roadmapContent = findRecentContent(roadmap); + delete(roadmap, roadmapContent); } } - private void delete(final Roadmap roadmap) { - final List goalRooms = goalRoomRepository.findByRoadmap(roadmap); + private RoadmapContent findRecentContent(final Roadmap roadmap) { + return roadmapContentRepository.findFirstByRoadmapOrderByCreatedAtDesc(roadmap) + .orElseThrow(() -> new NotFoundException("로드맵에 컨텐츠가 존재하지 않습니다.")); + } + + private void delete(final Roadmap roadmap, final RoadmapContent roadmapContent) { + final List goalRooms = goalRoomRepository.findByRoadmapContentId(roadmapContent.getId()); final boolean canDelete = canDeleteRoadmapBasedOnGoalRooms(goalRooms); if (canDelete) { deleteGoalRooms(goalRooms); diff --git a/backend/kirikiri/src/main/java/co/kirikiri/todo/controller/GoalRoomToDoController.java b/backend/kirikiri/src/main/java/co/kirikiri/todo/controller/GoalRoomToDoController.java new file mode 100644 index 000000000..6164b3b7d --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/todo/controller/GoalRoomToDoController.java @@ -0,0 +1,56 @@ +package co.kirikiri.todo.controller; + +import co.kirikiri.common.interceptor.Authenticated; +import co.kirikiri.common.resolver.MemberIdentifier; +import co.kirikiri.todo.service.GoalRoomToDoService; +import co.kirikiri.todo.service.dto.request.GoalRoomTodoRequest; +import co.kirikiri.todo.service.dto.response.GoalRoomToDoCheckResponse; +import co.kirikiri.todo.service.dto.response.GoalRoomTodoResponse; +import jakarta.validation.Valid; +import java.net.URI; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/goal-rooms/{goalRoomId}/todos") +@RequiredArgsConstructor +public class GoalRoomToDoController { + + private final GoalRoomToDoService goalRoomToDoService; + + @PostMapping + @Authenticated + public ResponseEntity addTodo(@RequestBody @Valid final GoalRoomTodoRequest goalRoomTodoRequest, + @PathVariable final Long goalRoomId, + @MemberIdentifier final String identifier) { + final Long id = goalRoomToDoService.addGoalRoomTodo(goalRoomId, identifier, goalRoomTodoRequest); + return ResponseEntity.created(URI.create("/api/goal-rooms/" + goalRoomId + "/todos/" + id)).build(); + } + + @PostMapping("/{todoId}") + @Authenticated + public ResponseEntity checkTodo(@PathVariable final Long goalRoomId, + @PathVariable final Long todoId, + @MemberIdentifier final String identifier) { + final GoalRoomToDoCheckResponse checkResponse = goalRoomToDoService.checkGoalRoomTodo(goalRoomId, todoId, + identifier); + return ResponseEntity.ok(checkResponse); + } + + @GetMapping + @Authenticated + public ResponseEntity> findAllTodos( + @PathVariable final Long goalRoomId, + @MemberIdentifier final String identifier) { + final List todoResponses = goalRoomToDoService.findAllGoalRoomTodo(goalRoomId, + identifier); + return ResponseEntity.ok(todoResponses); + } +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomToDo.java b/backend/kirikiri/src/main/java/co/kirikiri/todo/domain/GoalRoomToDo.java similarity index 56% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomToDo.java rename to backend/kirikiri/src/main/java/co/kirikiri/todo/domain/GoalRoomToDo.java index 3f84a708b..bd4df8f8d 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomToDo.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/todo/domain/GoalRoomToDo.java @@ -1,30 +1,34 @@ -package co.kirikiri.domain.goalroom; +package co.kirikiri.todo.domain; -import co.kirikiri.domain.BaseUpdatedTimeEntity; -import co.kirikiri.domain.goalroom.vo.GoalRoomTodoContent; -import co.kirikiri.domain.goalroom.vo.Period; +import co.kirikiri.common.entity.BaseUpdatedTimeEntity; +import co.kirikiri.todo.domain.vo.GoalRoomTodoContent; +import co.kirikiri.todo.domain.vo.ToDoPeriod; import jakarta.persistence.Embedded; import jakarta.persistence.Entity; +import java.time.LocalDate; import lombok.AccessLevel; import lombok.NoArgsConstructor; -import java.time.LocalDate; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) public class GoalRoomToDo extends BaseUpdatedTimeEntity { + private Long goalRoomId; + @Embedded private GoalRoomTodoContent content; @Embedded - private Period period; + private ToDoPeriod period; - public GoalRoomToDo(final GoalRoomTodoContent content, final Period period) { - this(null, content, period); + public GoalRoomToDo(final Long goalRoomId, final GoalRoomTodoContent content, final ToDoPeriod period) { + this(null, goalRoomId, content, period); } - public GoalRoomToDo(final Long id, final GoalRoomTodoContent content, final Period period) { + public GoalRoomToDo(final Long id, final Long goalRoomId, final GoalRoomTodoContent content, + final ToDoPeriod period) { this.id = id; + this.goalRoomId = goalRoomId; this.content = content; this.period = period; } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomToDoCheck.java b/backend/kirikiri/src/main/java/co/kirikiri/todo/domain/GoalRoomToDoCheck.java similarity index 61% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomToDoCheck.java rename to backend/kirikiri/src/main/java/co/kirikiri/todo/domain/GoalRoomToDoCheck.java index a52ee1812..1aa418fae 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomToDoCheck.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/todo/domain/GoalRoomToDoCheck.java @@ -1,6 +1,6 @@ -package co.kirikiri.domain.goalroom; +package co.kirikiri.todo.domain; -import co.kirikiri.domain.BaseEntity; +import co.kirikiri.common.entity.BaseEntity; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; @@ -12,16 +12,14 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class GoalRoomToDoCheck extends BaseEntity { - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "goal_room_member_id", nullable = false) - private GoalRoomMember goalRoomMember; + private Long goalRoomMemberId; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "goal_room_to_do_id", nullable = false) private GoalRoomToDo goalRoomToDo; - public GoalRoomToDoCheck(final GoalRoomMember goalRoomMember, final GoalRoomToDo goalRoomToDo) { - this.goalRoomMember = goalRoomMember; + public GoalRoomToDoCheck(final Long goalRoomMemberId, final GoalRoomToDo goalRoomToDo) { + this.goalRoomMemberId = goalRoomMemberId; this.goalRoomToDo = goalRoomToDo; } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomToDos.java b/backend/kirikiri/src/main/java/co/kirikiri/todo/domain/GoalRoomToDos.java similarity index 97% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomToDos.java rename to backend/kirikiri/src/main/java/co/kirikiri/todo/domain/GoalRoomToDos.java index 1a1106bba..d6498e679 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/GoalRoomToDos.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/todo/domain/GoalRoomToDos.java @@ -1,15 +1,15 @@ -package co.kirikiri.domain.goalroom; +package co.kirikiri.todo.domain; import jakarta.persistence.CascadeType; import jakarta.persistence.Embeddable; import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; import jakarta.persistence.OneToMany; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; import java.util.ArrayList; import java.util.List; import java.util.Optional; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; @Embeddable @NoArgsConstructor(access = AccessLevel.PROTECTED) diff --git a/backend/kirikiri/src/main/java/co/kirikiri/todo/domain/exception/GoalRoomToDoException.java b/backend/kirikiri/src/main/java/co/kirikiri/todo/domain/exception/GoalRoomToDoException.java new file mode 100644 index 000000000..68673c292 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/todo/domain/exception/GoalRoomToDoException.java @@ -0,0 +1,10 @@ +package co.kirikiri.todo.domain.exception; + +import co.kirikiri.common.exception.DomainException; + +public class GoalRoomToDoException extends DomainException { + + public GoalRoomToDoException(final String message) { + super(message); + } +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/GoalRoomTodoContent.java b/backend/kirikiri/src/main/java/co/kirikiri/todo/domain/vo/GoalRoomTodoContent.java similarity index 78% rename from backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/GoalRoomTodoContent.java rename to backend/kirikiri/src/main/java/co/kirikiri/todo/domain/vo/GoalRoomTodoContent.java index 4b5096307..862c6baa2 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/domain/goalroom/vo/GoalRoomTodoContent.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/todo/domain/vo/GoalRoomTodoContent.java @@ -1,6 +1,6 @@ -package co.kirikiri.domain.goalroom.vo; +package co.kirikiri.todo.domain.vo; -import co.kirikiri.domain.goalroom.exception.GoalRoomException; +import co.kirikiri.todo.domain.exception.GoalRoomToDoException; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import lombok.AccessLevel; @@ -23,7 +23,7 @@ public GoalRoomTodoContent(final String value) { private void validate(final String value) { if (value.length() < MIN_LENGTH || value.length() > MAX_LENGTH) { - throw new GoalRoomException("투두 컨텐츠의 길이가 적절하지 않습니다."); + throw new GoalRoomToDoException("투두 컨텐츠의 길이가 적절하지 않습니다."); } } diff --git a/backend/kirikiri/src/main/java/co/kirikiri/todo/domain/vo/ToDoPeriod.java b/backend/kirikiri/src/main/java/co/kirikiri/todo/domain/vo/ToDoPeriod.java new file mode 100644 index 000000000..ed8f5b8ba --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/todo/domain/vo/ToDoPeriod.java @@ -0,0 +1,50 @@ +package co.kirikiri.todo.domain.vo; + +import co.kirikiri.todo.domain.exception.GoalRoomToDoException; +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import java.time.LocalDate; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@Embeddable +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ToDoPeriod { + + @Column(nullable = false) + private LocalDate startDate; + + @Column(nullable = false) + private LocalDate endDate; + + public ToDoPeriod(final LocalDate startDate, final LocalDate endDate) { + validate(startDate, endDate); + this.startDate = startDate; + this.endDate = endDate; + } + + private void validate(final LocalDate startDate, final LocalDate endDate) { + validateStartDateAfterNow(startDate); + validateStartDateBeforeOrEqualEndDate(startDate, endDate); + } + + private void validateStartDateAfterNow(final LocalDate startDate) { + if (startDate.isBefore(LocalDate.now())) { + throw new GoalRoomToDoException("시작일은 오늘보다 전일 수 없습니다."); + } + } + + private void validateStartDateBeforeOrEqualEndDate(final LocalDate startDate, final LocalDate endDate) { + if (startDate.isAfter(endDate)) { + throw new GoalRoomToDoException("시작일은 종료일보다 후일 수 없습니다."); + } + } + + public LocalDate getStartDate() { + return startDate; + } + + public LocalDate getEndDate() { + return endDate; + } +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/todo/persistence/GoalRoomToDoCheckRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/todo/persistence/GoalRoomToDoCheckRepository.java new file mode 100644 index 000000000..b276e1d2a --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/todo/persistence/GoalRoomToDoCheckRepository.java @@ -0,0 +1,35 @@ +package co.kirikiri.todo.persistence; + +import co.kirikiri.todo.domain.GoalRoomToDo; +import co.kirikiri.todo.domain.GoalRoomToDoCheck; +import java.util.List; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +public interface GoalRoomToDoCheckRepository extends JpaRepository { + + @Query("select gc from GoalRoomToDoCheck gc " + + "where gc.goalRoomToDo = :goalRoomToDo " + + "and gc.goalRoomMemberId = :goalRoomMemberId ") + Optional findByGoalRoomTodoAndGoalRoomMemberId( + @Param("goalRoomToDo") final GoalRoomToDo goalRoomToDo, + @Param("goalRoomMemberId") final Long goalRoomMemberId); + + @Query("select gc from GoalRoomToDoCheck gc " + + "inner join fetch gc.goalRoomToDo gt " + + "where gc.goalRoomMemberId = :goalRoomMemberId " + + "and gt.goalRoomId = :goalRoomId ") + List findByGoalRoomIdAndGoalRoomMemberId( + @Param("goalRoomId") final Long goalRoomId, + @Param("goalRoomMemberId") final Long goalRoomMemberId); + + @Modifying + @Query("delete from GoalRoomToDoCheck gc " + + "where gc.goalRoomMemberId = :goalRoomMemberId " + + "and gc.goalRoomToDo.id = :todoId") + void deleteByGoalRoomMemberIdAndToDoId(@Param("goalRoomMemberId") final Long goalRoomMemberId, + @Param("todoId") final Long todoId); +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/todo/persistence/GoalRoomToDoRepository.java b/backend/kirikiri/src/main/java/co/kirikiri/todo/persistence/GoalRoomToDoRepository.java new file mode 100644 index 000000000..1e21859c1 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/todo/persistence/GoalRoomToDoRepository.java @@ -0,0 +1,10 @@ +package co.kirikiri.todo.persistence; + +import co.kirikiri.todo.domain.GoalRoomToDo; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface GoalRoomToDoRepository extends JpaRepository { + + List findGoalRoomToDosByGoalRoomId(final Long goalRoomId); +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/todo/service/DashBoardToDoServiceImpl.java b/backend/kirikiri/src/main/java/co/kirikiri/todo/service/DashBoardToDoServiceImpl.java new file mode 100644 index 000000000..b60b3bfc2 --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/todo/service/DashBoardToDoServiceImpl.java @@ -0,0 +1,52 @@ +package co.kirikiri.todo.service; + +import co.kirikiri.common.aop.ExceptionConvert; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomMember; +import co.kirikiri.goalroom.persistence.GoalRoomMemberRepository; +import co.kirikiri.goalroom.service.DashBoardToDoService; +import co.kirikiri.goalroom.service.dto.response.DashBoardToDoResponse; +import co.kirikiri.todo.domain.GoalRoomToDo; +import co.kirikiri.todo.domain.GoalRoomToDoCheck; +import co.kirikiri.todo.domain.GoalRoomToDos; +import co.kirikiri.todo.persistence.GoalRoomToDoCheckRepository; +import co.kirikiri.todo.persistence.GoalRoomToDoRepository; +import co.kirikiri.todo.service.mapper.GoalRoomToDoMapper; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +@RequiredArgsConstructor +@ExceptionConvert +public class DashBoardToDoServiceImpl implements DashBoardToDoService { + + private final GoalRoomToDoCheckRepository goalRoomToDoCheckRepository; + private final GoalRoomToDoRepository goalRoomToDoRepository; + private final GoalRoomMemberRepository goalRoomMemberRepository; + + @Override + @Transactional(readOnly = true) + public List findMemberCheckedGoalRoomToDoIds(final GoalRoom goalRoom, + final Long memberId) { + final Optional goalRoomMember = goalRoomMemberRepository.findByGoalRoomAndMemberId(goalRoom, + memberId); + if (goalRoomMember.isEmpty()) { + return Collections.emptyList(); + } + final List goalRoomToDoChecks = findByGoalRoomIdAndMemberIdentifier(goalRoom.getId(), + goalRoomMember.get().getId()); + final List goalRoomTodos = goalRoomToDoRepository.findGoalRoomToDosByGoalRoomId(goalRoom.getId()); + return GoalRoomToDoMapper.convertToDashBoardTodoResponsesLimit(new GoalRoomToDos(goalRoomTodos), + goalRoomToDoChecks); + } + + private List findByGoalRoomIdAndMemberIdentifier(final Long goalRoomId, + final Long goalRoomMemberId) { + return goalRoomToDoCheckRepository.findByGoalRoomIdAndGoalRoomMemberId(goalRoomId, goalRoomMemberId); + } +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/todo/service/GoalRoomToDoService.java b/backend/kirikiri/src/main/java/co/kirikiri/todo/service/GoalRoomToDoService.java new file mode 100644 index 000000000..1d1fbf64c --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/todo/service/GoalRoomToDoService.java @@ -0,0 +1,126 @@ +package co.kirikiri.todo.service; + +import co.kirikiri.common.aop.ExceptionConvert; +import co.kirikiri.common.exception.BadRequestException; +import co.kirikiri.common.exception.ForbiddenException; +import co.kirikiri.common.exception.NotFoundException; +import co.kirikiri.domain.member.Member; +import co.kirikiri.domain.member.vo.Identifier; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomMember; +import co.kirikiri.goalroom.persistence.GoalRoomMemberRepository; +import co.kirikiri.goalroom.persistence.GoalRoomRepository; +import co.kirikiri.persistence.member.MemberRepository; +import co.kirikiri.todo.domain.GoalRoomToDo; +import co.kirikiri.todo.domain.GoalRoomToDoCheck; +import co.kirikiri.todo.domain.GoalRoomToDos; +import co.kirikiri.todo.persistence.GoalRoomToDoCheckRepository; +import co.kirikiri.todo.persistence.GoalRoomToDoRepository; +import co.kirikiri.todo.service.dto.request.GoalRoomTodoRequest; +import co.kirikiri.todo.service.dto.response.GoalRoomToDoCheckResponse; +import co.kirikiri.todo.service.dto.response.GoalRoomTodoResponse; +import co.kirikiri.todo.service.mapper.GoalRoomToDoMapper; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +@RequiredArgsConstructor +@ExceptionConvert +public class GoalRoomToDoService { + + private final GoalRoomToDoRepository goalRoomToDoRepository; + private final GoalRoomToDoCheckRepository goalRoomToDoCheckRepository; + private final GoalRoomRepository goalRoomRepository; + private final GoalRoomMemberRepository goalRoomMemberRepository; + private final MemberRepository memberRepository; + + public Long addGoalRoomTodo(final Long goalRoomId, final String identifier, + final GoalRoomTodoRequest goalRoomTodoRequest) { + final Member member = findMemberByIdentifier(identifier); + final GoalRoom goalRoom = findGoalRoomById(goalRoomId); + checkGoalRoomCompleted(goalRoom); + checkGoalRoomLeader(member.getId(), goalRoom); + final GoalRoomToDo goalRoomToDo = GoalRoomToDoMapper.convertToGoalRoomTodo(goalRoomTodoRequest, goalRoomId); + return goalRoomToDoRepository.save(goalRoomToDo).getId(); + } + + private Member findMemberByIdentifier(final String memberIdentifier) { + return memberRepository.findByIdentifier(new Identifier(memberIdentifier)) + .orElseThrow(() -> new NotFoundException("존재하지 않는 회원입니다.")); + } + + private GoalRoom findGoalRoomById(final Long goalRoomId) { + return goalRoomRepository.findById(goalRoomId) + .orElseThrow(() -> new NotFoundException("존재하지 않는 골룸입니다. goalRoomId = " + goalRoomId)); + } + + private void checkGoalRoomCompleted(final GoalRoom goalRoom) { + if (goalRoom.isCompleted()) { + throw new BadRequestException("이미 종료된 골룸입니다."); + } + } + + private void checkGoalRoomLeader(final Long memberId, final GoalRoom goalRoom) { + if (goalRoom.isNotLeader(memberId)) { + throw new BadRequestException("골룸의 리더만 투두리스트를 추가할 수 있습니다."); + } + } + + public GoalRoomToDoCheckResponse checkGoalRoomTodo(final Long goalRoomId, final Long todoId, + final String identifier) { + final Identifier memberIdentifier = new Identifier(identifier); + final GoalRoom goalRoom = findGoalRoomById(goalRoomId); + final GoalRoomToDo goalRoomToDo = findGoalRoomTodoById(todoId); + final GoalRoomMember goalRoomMember = findGoalRoomMember(memberIdentifier, goalRoom); + + final boolean isAlreadyChecked = goalRoomToDoCheckRepository.findByGoalRoomTodoAndGoalRoomMemberId(goalRoomToDo, + goalRoomMember.getId()).isPresent(); + if (isAlreadyChecked) { + goalRoomToDoCheckRepository.deleteByGoalRoomMemberIdAndToDoId(goalRoomMember.getId(), todoId); + return new GoalRoomToDoCheckResponse(false); + } + final GoalRoomToDoCheck goalRoomToDoCheck = new GoalRoomToDoCheck(goalRoomMember.getId(), goalRoomToDo); + goalRoomToDoCheckRepository.save(goalRoomToDoCheck); + return new GoalRoomToDoCheckResponse(true); + } + + private GoalRoomToDo findGoalRoomTodoById(final Long todoId) { + return goalRoomToDoRepository.findById(todoId) + .orElseThrow(() -> new NotFoundException("존재하지 않는 투두입니다. todoId = " + todoId)); + } + + private GoalRoomMember findGoalRoomMember(final Identifier memberIdentifier, final GoalRoom goalRoom) { + final Member member = findMemberByIdentifier(memberIdentifier.getValue()); + return goalRoomMemberRepository.findByGoalRoomAndMemberId(goalRoom, member.getId()) + .orElseThrow(() -> new NotFoundException( + "골룸에 사용자가 존재하지 않습니다. goalRoomId = " + goalRoom.getId() + " memberIdentifier = " + + memberIdentifier.getValue())); + } + + @Transactional(readOnly = true) + public List findAllGoalRoomTodo(final Long goalRoomId, final String identifier) { + final GoalRoomToDos goalRoomToDos = findGoalRoomTodosByGoalRoomId(goalRoomId); + final GoalRoomMember goalRoomMember = findGoalRoomMember(goalRoomId, identifier); + final List checkedTodos = findMemberCheckedGoalRoomToDos(goalRoomId, goalRoomMember.getId()); + return GoalRoomToDoMapper.convertGoalRoomTodoResponses(goalRoomToDos, checkedTodos); + } + + private GoalRoomToDos findGoalRoomTodosByGoalRoomId(final Long goalRoomId) { + findGoalRoomById(goalRoomId); + return new GoalRoomToDos(goalRoomToDoRepository.findGoalRoomToDosByGoalRoomId(goalRoomId)); + } + + private GoalRoomMember findGoalRoomMember(final Long goalRoomId, final String identifier) { + final Member member = findMemberByIdentifier(identifier); + return goalRoomMemberRepository.findByGoalRoomIdAndMemberId(goalRoomId, member.getId()) + .orElseThrow(() -> new ForbiddenException( + "골룸에 참여하지 않은 사용자입니다. goalRoomId = " + goalRoomId + " memberIdentifier = " + identifier)); + } + + private List findMemberCheckedGoalRoomToDos(final Long goalRoomId, final Long goalRoomMemberId) { + return goalRoomToDoCheckRepository.findByGoalRoomIdAndGoalRoomMemberId(goalRoomId, goalRoomMemberId); + } +} diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/request/GoalRoomTodoRequest.java b/backend/kirikiri/src/main/java/co/kirikiri/todo/service/dto/request/GoalRoomTodoRequest.java similarity index 92% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/request/GoalRoomTodoRequest.java rename to backend/kirikiri/src/main/java/co/kirikiri/todo/service/dto/request/GoalRoomTodoRequest.java index 8f7da0ce8..b3fffa76b 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/request/GoalRoomTodoRequest.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/todo/service/dto/request/GoalRoomTodoRequest.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.goalroom.request; +package co.kirikiri.todo.service.dto.request; import com.fasterxml.jackson.annotation.JsonFormat; import jakarta.validation.constraints.NotBlank; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomToDoCheckResponse.java b/backend/kirikiri/src/main/java/co/kirikiri/todo/service/dto/response/GoalRoomToDoCheckResponse.java similarity index 59% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomToDoCheckResponse.java rename to backend/kirikiri/src/main/java/co/kirikiri/todo/service/dto/response/GoalRoomToDoCheckResponse.java index 5da8c9c95..d8cbe2534 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomToDoCheckResponse.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/todo/service/dto/response/GoalRoomToDoCheckResponse.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.goalroom.response; +package co.kirikiri.todo.service.dto.response; public record GoalRoomToDoCheckResponse( boolean isChecked diff --git a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomTodoResponse.java b/backend/kirikiri/src/main/java/co/kirikiri/todo/service/dto/response/GoalRoomTodoResponse.java similarity index 80% rename from backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomTodoResponse.java rename to backend/kirikiri/src/main/java/co/kirikiri/todo/service/dto/response/GoalRoomTodoResponse.java index be7247689..2242744a2 100644 --- a/backend/kirikiri/src/main/java/co/kirikiri/service/dto/goalroom/response/GoalRoomTodoResponse.java +++ b/backend/kirikiri/src/main/java/co/kirikiri/todo/service/dto/response/GoalRoomTodoResponse.java @@ -1,4 +1,4 @@ -package co.kirikiri.service.dto.goalroom.response; +package co.kirikiri.todo.service.dto.response; import java.time.LocalDate; diff --git a/backend/kirikiri/src/main/java/co/kirikiri/todo/service/mapper/GoalRoomToDoMapper.java b/backend/kirikiri/src/main/java/co/kirikiri/todo/service/mapper/GoalRoomToDoMapper.java new file mode 100644 index 000000000..32c47209e --- /dev/null +++ b/backend/kirikiri/src/main/java/co/kirikiri/todo/service/mapper/GoalRoomToDoMapper.java @@ -0,0 +1,67 @@ +package co.kirikiri.todo.service.mapper; + +import co.kirikiri.goalroom.service.dto.response.DashBoardToDoCheckResponse; +import co.kirikiri.goalroom.service.dto.response.DashBoardToDoResponse; +import co.kirikiri.todo.domain.GoalRoomToDo; +import co.kirikiri.todo.domain.GoalRoomToDoCheck; +import co.kirikiri.todo.domain.GoalRoomToDos; +import co.kirikiri.todo.domain.vo.GoalRoomTodoContent; +import co.kirikiri.todo.domain.vo.ToDoPeriod; +import co.kirikiri.todo.service.dto.request.GoalRoomTodoRequest; +import co.kirikiri.todo.service.dto.response.GoalRoomToDoCheckResponse; +import co.kirikiri.todo.service.dto.response.GoalRoomTodoResponse; +import java.util.List; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class GoalRoomToDoMapper { + + private static final int MAX_MEMBER_GOAL_ROOM_TODO_NUMBER = 3; + + public static GoalRoomToDo convertToGoalRoomTodo(final GoalRoomTodoRequest goalRoomTodoRequest, final Long goalRoomId) { + return new GoalRoomToDo(goalRoomId, new GoalRoomTodoContent(goalRoomTodoRequest.content()), + new ToDoPeriod(goalRoomTodoRequest.startDate(), goalRoomTodoRequest.endDate())); + } + + public static List convertGoalRoomTodoResponses(final GoalRoomToDos goalRoomToDos, + final List checkedTodos) { + return goalRoomToDos.getValues().stream() + .map(goalRoomToDo -> convertGoalRoomTodoResponse(checkedTodos, goalRoomToDo)) + .toList(); + } + + private static GoalRoomTodoResponse convertGoalRoomTodoResponse(final List checkedTodos, + final GoalRoomToDo goalRoomToDo) { + final GoalRoomToDoCheckResponse checkResponse = new GoalRoomToDoCheckResponse( + isCheckedTodo(goalRoomToDo.getId(), checkedTodos)); + return new GoalRoomTodoResponse(goalRoomToDo.getId(), goalRoomToDo.getContent(), goalRoomToDo.getStartDate(), + goalRoomToDo.getEndDate(), checkResponse); + } + + private static boolean isCheckedTodo(final Long targetTodoId, final List checkedTodos) { + final List checkTodoIds = checkedTodos.stream() + .map(goalRoomToDoCheck -> goalRoomToDoCheck.getGoalRoomToDo().getId()) + .toList(); + return checkTodoIds.contains(targetTodoId); + } + + public static List convertToDashBoardTodoResponsesLimit(final GoalRoomToDos goalRoomToDos, + final List checkedTodos) { + return goalRoomToDos.getValues() + .stream() + .map(goalRoomToDo -> convertToDashBoardTodoResponse(checkedTodos, goalRoomToDo)) + .limit(MAX_MEMBER_GOAL_ROOM_TODO_NUMBER) + .toList(); + } + + private static DashBoardToDoResponse convertToDashBoardTodoResponse(final List checkedTodos, + final GoalRoomToDo goalRoomToDo) { + final DashBoardToDoCheckResponse checkResponse = new DashBoardToDoCheckResponse( + isCheckedTodo(goalRoomToDo.getId(), checkedTodos)); + return new DashBoardToDoResponse(goalRoomToDo.getId(), + goalRoomToDo.getContent(), + goalRoomToDo.getStartDate(), goalRoomToDo.getEndDate(), + checkResponse); + } +} diff --git a/backend/kirikiri/src/main/resources/properties b/backend/kirikiri/src/main/resources/properties index 2fdc5b50c..ae1361d17 160000 --- a/backend/kirikiri/src/main/resources/properties +++ b/backend/kirikiri/src/main/resources/properties @@ -1 +1 @@ -Subproject commit 2fdc5b50cd9c5095f16c7b28ad1275c60289f930 +Subproject commit ae1361d17d2ab3ba82f0f519589b36181ad4dd6e diff --git a/backend/kirikiri/src/test/java/co/kirikiri/checkfeed/controller/GoalRoomCheckFeedApiTest.java b/backend/kirikiri/src/test/java/co/kirikiri/checkfeed/controller/GoalRoomCheckFeedApiTest.java new file mode 100644 index 000000000..d75d76fd7 --- /dev/null +++ b/backend/kirikiri/src/test/java/co/kirikiri/checkfeed/controller/GoalRoomCheckFeedApiTest.java @@ -0,0 +1,326 @@ +package co.kirikiri.checkfeed.controller; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.when; +import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; +import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.restdocs.request.RequestDocumentation.partWithName; +import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; +import static org.springframework.restdocs.request.RequestDocumentation.requestParts; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import co.kirikiri.checkfeed.service.GoalRoomCheckFeedService; +import co.kirikiri.checkfeed.service.dto.response.CheckFeedMemberResponse; +import co.kirikiri.checkfeed.service.dto.response.CheckFeedResponse; +import co.kirikiri.checkfeed.service.dto.response.GoalRoomCheckFeedResponse; +import co.kirikiri.common.exception.BadRequestException; +import co.kirikiri.common.exception.NotFoundException; +import co.kirikiri.common.helper.ControllerTestHelper; +import co.kirikiri.common.service.dto.ErrorResponse; +import com.fasterxml.jackson.core.type.TypeReference; +import java.time.LocalDate; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; +import org.springframework.test.web.servlet.MvcResult; + +@WebMvcTest(GoalRoomCheckFeedController.class) +class GoalRoomCheckFeedApiTest extends ControllerTestHelper { + + @MockBean + private GoalRoomCheckFeedService goalRoomCheckFeedService; + + @Test + void 인증_피드_등록_요청을_보낸다() throws Exception { + //given + final String imageName = "image"; + final String originalImageName = "originalImageName.jpeg"; + final String contentType = "image/jpeg"; + final String image = "테스트 이미지"; + final String description = "이미지 설명"; + final String filePath = "path/to/directories/" + contentType; + final MockMultipartFile imageFile = new MockMultipartFile(imageName, originalImageName, + contentType, image.getBytes()); + + given(goalRoomCheckFeedService.createCheckFeed(anyString(), anyLong(), any())) + .willReturn(filePath); + + //expect + mockMvc.perform( + RestDocumentationRequestBuilders + .multipart(API_PREFIX + "/goal-rooms/{goalRoomId}/checkFeeds", 1L) + .file(imageFile) + .file("text", description.getBytes()) + .header("Authorization", "Bearer accessToken") + .contextPath(API_PREFIX) + .contentType(MediaType.MULTIPART_FORM_DATA_VALUE)) + .andExpect(status().isCreated()) + .andExpect(header().string("Location", filePath)) + .andDo( + documentationResultHandler.document( + requestHeaders( + headerWithName("Authorization").description("액세스 토큰") + ), + pathParameters( + parameterWithName("goalRoomId").description("골룸 아이디") + ), + requestParts( + partWithName("image").description("업로드한 이미지"), + partWithName("text").description("인증 피드 본문") + ), + responseHeaders( + headerWithName("Location").description("저장된 이미지 경로") + ))); + } + + @Test + void 인증_피드_등록시_노드_기간에_해당하지_않으면_예외가_발생한다() throws Exception { + // given + final String imageName = "image"; + final String originalImageName = "originalImageName.jpeg"; + final String contentType = "image/jpeg"; + final String image = "테스트 이미지"; + final String description = "이미지 설명"; + final MockMultipartFile imageFile = new MockMultipartFile(imageName, originalImageName, + contentType, image.getBytes()); + + doThrow(new BadRequestException("인증 피드는 노드 기간 내에만 작성할 수 있습니다.")) + .when(goalRoomCheckFeedService) + .createCheckFeed(anyString(), anyLong(), any()); + + //when + mockMvc.perform( + RestDocumentationRequestBuilders + .multipart(API_PREFIX + "/goal-rooms/{goalRoomId}/checkFeeds", 1L) + .file(imageFile) + .param("description", description) + .header("Authorization", "Bearer accessToken") + .contextPath(API_PREFIX) + .contentType(MediaType.MULTIPART_FORM_DATA_VALUE)) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.message").value("인증 피드는 노드 기간 내에만 작성할 수 있습니다.")) + .andDo( + documentationResultHandler.document( + requestHeaders( + headerWithName("Authorization").description("액세스 토큰") + ), + pathParameters( + parameterWithName("goalRoomId").description("골룸 아이디") + ), + requestParts( + partWithName("image").description("업로드한 이미지") + ), + responseFields( + fieldWithPath("message").description("예외 메세지") + ))); + } + + @Test + void 인증_피드_등록_요청시_멤버가_존재하지_않을_경우_예외를_반환한다() throws Exception { + //given + final String imageName = "image"; + final String originalImageName = "originalImageName.jpeg"; + final String contentType = "image/jpeg"; + final String image = "테스트 이미지"; + final String description = "이미지 설명"; + final MockMultipartFile imageFile = new MockMultipartFile(imageName, originalImageName, + contentType, image.getBytes()); + + doThrow(new NotFoundException("존재하지 않는 회원입니다.")) + .when(goalRoomCheckFeedService) + .createCheckFeed(anyString(), anyLong(), any()); + + //when + mockMvc.perform( + RestDocumentationRequestBuilders + .multipart(API_PREFIX + "/goal-rooms/{goalRoomId}/checkFeeds", 1L) + .file(imageFile) + .file("text", description.getBytes()) + .header("Authorization", "Bearer accessToken") + .contextPath(API_PREFIX) + .contentType(MediaType.MULTIPART_FORM_DATA_VALUE)) + .andExpect(status().isNotFound()) + .andExpect(jsonPath("$.message").value("존재하지 않는 회원입니다.")) + .andDo( + documentationResultHandler.document( + requestHeaders( + headerWithName("Authorization").description("액세스 토큰") + ), + pathParameters( + parameterWithName("goalRoomId").description("골룸 아이디") + ), + requestParts( + partWithName("image").description("업로드한 이미지"), + partWithName("text").description("인증 피드 본문") + ), + responseFields( + fieldWithPath("message").description("예외 메세지") + ))); + } + + @Test + void 인증_피드_등록_요청시_로드맵이_존재하지_않을_경우_예외를_반환한다() throws Exception { + //given + final String imageName = "image"; + final String originalImageName = "originalImageName.jpeg"; + final String contentType = "image/jpeg"; + final String image = "테스트 이미지"; + final String description = "이미지 설명"; + final MockMultipartFile imageFile = new MockMultipartFile(imageName, originalImageName, + contentType, image.getBytes()); + + doThrow(new NotFoundException("골룸 정보가 존재하지 않습니다. goalRoomId = 1L")) + .when(goalRoomCheckFeedService) + .createCheckFeed(anyString(), anyLong(), any()); + + //when + mockMvc.perform( + RestDocumentationRequestBuilders + .multipart(API_PREFIX + "/goal-rooms/{goalRoomId}/checkFeeds", 1L) + .file(imageFile) + .file("text", description.getBytes()) + .header("Authorization", "Bearer accessToken") + .contextPath(API_PREFIX) + .contentType(MediaType.MULTIPART_FORM_DATA_VALUE)) + .andExpect(status().isNotFound()) + .andExpect(jsonPath("$.message").value("골룸 정보가 존재하지 않습니다. goalRoomId = 1L")) + .andDo( + documentationResultHandler.document( + requestHeaders( + headerWithName("Authorization").description("액세스 토큰") + ), + pathParameters( + parameterWithName("goalRoomId").description("골룸 아이디") + ), + requestParts( + partWithName("image").description("업로드한 이미지"), + partWithName("text").description("인증 피드 본문") + ), + responseFields( + fieldWithPath("message").description("예외 메세지") + ))); + } + + @Test + void 골룸의_인증피드를_전체_조회한다() throws Exception { + // given + final GoalRoomCheckFeedResponse goalRoomCheckFeedResponse1 = new GoalRoomCheckFeedResponse( + new CheckFeedMemberResponse(1L, "name1", "imageUrl"), + new CheckFeedResponse(1L, "imageUrl", "image description1", LocalDate.now())); + final GoalRoomCheckFeedResponse goalRoomCheckFeedResponse2 = new GoalRoomCheckFeedResponse( + new CheckFeedMemberResponse(2L, "name2", "imageUrl"), + new CheckFeedResponse(2L, "imageUrl", "image description2", LocalDate.now())); + + final List expected = List.of(goalRoomCheckFeedResponse2, + goalRoomCheckFeedResponse1); + + when(goalRoomCheckFeedService.findGoalRoomCheckFeeds(any(), any())) + .thenReturn(expected); + + // when + final String response = mockMvc.perform( + get(API_PREFIX + "/goal-rooms/{goalRoomId}/checkFeeds", 1L) + .header(AUTHORIZATION, String.format(BEARER_TOKEN_FORMAT, "test-token")) + .contextPath(API_PREFIX)) + .andExpect(status().isOk()) + .andDo( + documentationResultHandler.document( + requestHeaders( + headerWithName(AUTHORIZATION).description("액세스 토큰") + ), + pathParameters( + parameterWithName("goalRoomId").description("골룸 아이디") + ), + responseFields( + fieldWithPath("[0].member.id").description("사용자 ID"), + fieldWithPath("[0].member.name").description("사용자 닉네임"), + fieldWithPath("[0].member.imageUrl").description("사용자 이미지 Url"), + fieldWithPath("[0].checkFeed.id").description("인증 피드 ID"), + fieldWithPath("[0].checkFeed.imageUrl").description("인증 피드 이미지 Url"), + fieldWithPath("[0].checkFeed.description").description("인증 피드 설명"), + fieldWithPath("[0].checkFeed.createdAt").description("인증 피드 등록 날짜")))) + .andReturn().getResponse() + .getContentAsString(); + + // then + final List 골룸_인증피드_전체_조회_응답 = objectMapper.readValue(response, + new TypeReference<>() { + }); + assertThat(골룸_인증피드_전체_조회_응답) + .isEqualTo(expected); + } + + @Test + void 골룸_인증피드_전체_조회_시_존재하지_않는_골룸일_경우_예외가_발생한다() throws Exception { + //given + doThrow(new NotFoundException("존재하지 않는 골룸입니다. goalRoomId = 1")) + .when(goalRoomCheckFeedService) + .findGoalRoomCheckFeeds(any(), any()); + + //when + final MvcResult mvcResult = mockMvc.perform(get(API_PREFIX + "/goal-rooms/{goalRoomId}/checkFeeds", 1L) + .header(AUTHORIZATION, String.format(BEARER_TOKEN_FORMAT, "test-token")) + .contextPath(API_PREFIX)) + .andExpect(status().isNotFound()) + .andDo( + documentationResultHandler.document( + pathParameters( + parameterWithName("goalRoomId").description("골룸 아이디") + ), + responseFields( + fieldWithPath("message").description("예외 메세지") + ))) + .andReturn(); + + // then + final ErrorResponse responses = jsonToClass(mvcResult, new TypeReference<>() { + }); + + assertThat(responses).isEqualTo(new ErrorResponse("존재하지 않는 골룸입니다. goalRoomId = 1")); + } + + @Test + void 골룸_인증피드_전체_조회_시_골룸에_참여하지_않은_사용자일_경우_예외_발생() throws Exception { + //given + doThrow(new BadRequestException("골룸에 참여하지 않은 회원입니다.")) + .when(goalRoomCheckFeedService) + .findGoalRoomCheckFeeds(any(), any()); + + //when + final MvcResult mvcResult = mockMvc.perform(get(API_PREFIX + "/goal-rooms/{goalRoomId}/checkFeeds", 1L) + .header(AUTHORIZATION, String.format(BEARER_TOKEN_FORMAT, "test-token")) + .contextPath(API_PREFIX)) + .andExpect(status().isBadRequest()) + .andDo( + documentationResultHandler.document( + pathParameters( + parameterWithName("goalRoomId").description("골룸 아이디") + ), + responseFields( + fieldWithPath("message").description("예외 메세지") + ))) + .andReturn(); + + // then + final ErrorResponse responses = jsonToClass(mvcResult, new TypeReference<>() { + }); + + assertThat(responses).isEqualTo(new ErrorResponse("골룸에 참여하지 않은 회원입니다.")); + } +} diff --git a/backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/CheckFeedRepositoryTest.java b/backend/kirikiri/src/test/java/co/kirikiri/checkfeed/persistence/CheckFeedRepositoryTest.java similarity index 58% rename from backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/CheckFeedRepositoryTest.java rename to backend/kirikiri/src/test/java/co/kirikiri/checkfeed/persistence/CheckFeedRepositoryTest.java index f4eb535ee..2c765afc3 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/CheckFeedRepositoryTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/checkfeed/persistence/CheckFeedRepositoryTest.java @@ -1,18 +1,11 @@ -package co.kirikiri.persistence.goalroom; +package co.kirikiri.checkfeed.persistence; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; -import co.kirikiri.domain.ImageContentType; -import co.kirikiri.domain.goalroom.CheckFeed; -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomMember; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNode; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNodes; -import co.kirikiri.domain.goalroom.GoalRoomRole; -import co.kirikiri.domain.goalroom.vo.GoalRoomName; -import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; -import co.kirikiri.domain.goalroom.vo.Period; +import co.kirikiri.checkfeed.domain.CheckFeed; +import co.kirikiri.common.helper.RepositoryTest; +import co.kirikiri.common.type.ImageContentType; import co.kirikiri.domain.member.EncryptedPassword; import co.kirikiri.domain.member.Gender; import co.kirikiri.domain.member.Member; @@ -30,7 +23,16 @@ import co.kirikiri.domain.roadmap.RoadmapNodeImage; import co.kirikiri.domain.roadmap.RoadmapNodeImages; import co.kirikiri.domain.roadmap.RoadmapNodes; -import co.kirikiri.persistence.helper.RepositoryTest; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomMember; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNode; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNodes; +import co.kirikiri.goalroom.domain.GoalRoomRole; +import co.kirikiri.goalroom.domain.vo.GoalRoomName; +import co.kirikiri.goalroom.domain.vo.LimitedMemberCount; +import co.kirikiri.goalroom.domain.vo.Period; +import co.kirikiri.goalroom.persistence.GoalRoomMemberRepository; +import co.kirikiri.goalroom.persistence.GoalRoomRepository; import co.kirikiri.persistence.member.MemberRepository; import co.kirikiri.persistence.roadmap.RoadmapCategoryRepository; import co.kirikiri.persistence.roadmap.RoadmapRepository; @@ -83,19 +85,21 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository, final Member member = 사용자를_저장한다("participant", "참여자"); final GoalRoom goalRoom = 골룸을_저장한다(targetRoadmapContent, member); - final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator); + final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, + creator.getId()); final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, - member); - goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember)); + member.getId()); + final GoalRoomMember savedLeader = goalRoomMemberRepository.save(leader); + final GoalRoomMember savedJoinedMember = goalRoomMemberRepository.save(joinedMember); final GoalRoomRoadmapNode goalRoomRoadmapNode = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); - 인증_피드를_저장한다(goalRoomRoadmapNode, joinedMember); + 인증_피드를_저장한다(goalRoomRoadmapNode, savedJoinedMember); //when - final boolean isUpdateToday = checkFeedRepository.findByGoalRoomMemberAndDateTime(joinedMember, + final boolean isUpdateToday = checkFeedRepository.findByGoalRoomMemberIdAndDateTime(joinedMember.getId(), TODAY_START, TOMORROW_START).isPresent(); - final boolean isUpdateTomorrow = checkFeedRepository.findByGoalRoomMemberAndDateTime(joinedMember, + final boolean isUpdateTomorrow = checkFeedRepository.findByGoalRoomMemberIdAndDateTime(joinedMember.getId(), TOMORROW_START, DAY_AFTER_TOMORROW_START).isPresent(); //then @@ -117,59 +121,27 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository, final Member member = 사용자를_저장한다("participant", "참여자"); final GoalRoom goalRoom = 골룸을_저장한다(targetRoadmapContent, member); - final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator); + final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, + creator.getId()); final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, - member); - goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember)); + member.getId()); + final GoalRoomMember savedLeader = goalRoomMemberRepository.save(leader); + final GoalRoomMember savedJoinedMember = goalRoomMemberRepository.save(joinedMember); final GoalRoomRoadmapNode goalRoomRoadmapNode = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); - 인증_피드를_저장한다(goalRoomRoadmapNode, joinedMember); - 인증_피드를_저장한다(goalRoomRoadmapNode, joinedMember); - 인증_피드를_저장한다(goalRoomRoadmapNode, joinedMember); - 인증_피드를_저장한다(goalRoomRoadmapNode, joinedMember); + 인증_피드를_저장한다(goalRoomRoadmapNode, savedJoinedMember); + 인증_피드를_저장한다(goalRoomRoadmapNode, savedJoinedMember); + 인증_피드를_저장한다(goalRoomRoadmapNode, savedJoinedMember); + 인증_피드를_저장한다(goalRoomRoadmapNode, savedJoinedMember); //when - final int checkCount = checkFeedRepository.countByGoalRoomMemberAndGoalRoomRoadmapNode(joinedMember, - goalRoomRoadmapNode); + final int checkCount = checkFeedRepository.countByGoalRoomMemberIdAndGoalRoomRoadmapNodeId(joinedMember.getId(), + goalRoomRoadmapNode.getId()); //then assertThat(checkCount).isEqualTo(4); } - @Test - void 사용자가_골룸에서_등록한_인증_피드_횟수를_확인한다() { - //given - final Member creator = 사용자를_저장한다("cokiri", "코끼리"); - final RoadmapCategory category = 카테고리를_저장한다("여가"); - final Roadmap roadmap = 로드맵을_저장한다(creator, category); - - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final Member member = 사용자를_저장한다("participant", "참여자"); - final GoalRoom goalRoom = 골룸을_저장한다(targetRoadmapContent, member); - - final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator); - final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, - member); - goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember)); - - final GoalRoomRoadmapNode goalRoomRoadmapNode1 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); - final GoalRoomRoadmapNode goalRoomRoadmapNode2 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(1); - - 인증_피드를_저장한다(goalRoomRoadmapNode1, joinedMember); - 인증_피드를_저장한다(goalRoomRoadmapNode1, joinedMember); - 인증_피드를_저장한다(goalRoomRoadmapNode1, joinedMember); - 인증_피드를_저장한다(goalRoomRoadmapNode2, joinedMember); - 인증_피드를_저장한다(goalRoomRoadmapNode2, joinedMember); - 인증_피드를_저장한다(goalRoomRoadmapNode2, joinedMember); - - //when - final int checkCount = checkFeedRepository.countByGoalRoomMember(joinedMember); - - //then - assertThat(checkCount).isEqualTo(6); - } - @Test void 특정_골룸에서_등록된_모든_인증_피드들을_조회한다() { //given @@ -183,28 +155,31 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository, final GoalRoom goalRoom1 = 골룸을_저장한다(targetRoadmapContent, creator); final GoalRoom goalRoom2 = 골룸을_저장한다(targetRoadmapContent, creator); - final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom1, creator); + final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom1, + creator.getId()); final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom1, - member); + member.getId()); final GoalRoomMember otherLeader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom2, - creator); - goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember)); + creator.getId()); + final GoalRoomMember savedLeader = goalRoomMemberRepository.save(leader); + final GoalRoomMember savedJoinedMember = goalRoomMemberRepository.save(joinedMember); + final GoalRoomMember savedOtherLeader = goalRoomMemberRepository.save(otherLeader); final GoalRoomRoadmapNode goalRoomRoadmapNode1 = goalRoom1.getGoalRoomRoadmapNodes().getValues().get(0); final GoalRoomRoadmapNode goalRoomRoadmapNode2 = goalRoom1.getGoalRoomRoadmapNodes().getValues().get(1); final GoalRoomRoadmapNode otherGoalRoomRoadmapNode = goalRoom2.getGoalRoomRoadmapNodes().getValues().get(0); - final CheckFeed checkFeed1 = 인증_피드를_저장한다(goalRoomRoadmapNode1, joinedMember); - final CheckFeed checkFeed2 = 인증_피드를_저장한다(goalRoomRoadmapNode1, joinedMember); - final CheckFeed checkFeed3 = 인증_피드를_저장한다(goalRoomRoadmapNode1, joinedMember); - final CheckFeed checkFeed4 = 인증_피드를_저장한다(goalRoomRoadmapNode2, joinedMember); - final CheckFeed checkFeed5 = 인증_피드를_저장한다(goalRoomRoadmapNode2, joinedMember); - final CheckFeed checkFeed6 = 인증_피드를_저장한다(goalRoomRoadmapNode2, joinedMember); - 인증_피드를_저장한다(otherGoalRoomRoadmapNode, otherLeader); - 인증_피드를_저장한다(otherGoalRoomRoadmapNode, otherLeader); + final CheckFeed checkFeed1 = 인증_피드를_저장한다(goalRoomRoadmapNode1, savedJoinedMember); + final CheckFeed checkFeed2 = 인증_피드를_저장한다(goalRoomRoadmapNode1, savedJoinedMember); + final CheckFeed checkFeed3 = 인증_피드를_저장한다(goalRoomRoadmapNode1, savedJoinedMember); + final CheckFeed checkFeed4 = 인증_피드를_저장한다(goalRoomRoadmapNode2, savedJoinedMember); + final CheckFeed checkFeed5 = 인증_피드를_저장한다(goalRoomRoadmapNode2, savedJoinedMember); + final CheckFeed checkFeed6 = 인증_피드를_저장한다(goalRoomRoadmapNode2, savedJoinedMember); + 인증_피드를_저장한다(otherGoalRoomRoadmapNode, savedOtherLeader); + 인증_피드를_저장한다(otherGoalRoomRoadmapNode, savedOtherLeader); //when - final List checkFeeds = checkFeedRepository.findByGoalRoom(goalRoom1); + final List checkFeeds = checkFeedRepository.findByGoalRoomIdOrderByCreatedAtDesc(goalRoom1.getId()); assertThat(checkFeeds) .hasSize(6) @@ -212,7 +187,7 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository, } @Test - void 골룸이_진행중일_때_특정_노드_동안_등록된_인증_피드들을_조회한다() { + void 골룸이_완료됐을_때는_특정한_노드_동안이_아닌_모든_기간_동안_등록된_인증_피드들을_조회한다() { //given final Member creator = 사용자를_저장한다("cokiri", "코끼리"); final RoadmapCategory category = 카테고리를_저장한다("여가"); @@ -223,39 +198,33 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository, final Member member = 사용자를_저장한다("participant", "참여자"); final GoalRoom goalRoom = 골룸을_저장한다(targetRoadmapContent, member); - final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator); + final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, + creator.getId()); final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, - member); - goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember)); + member.getId()); + final GoalRoomMember savedLeader = goalRoomMemberRepository.save(leader); + final GoalRoomMember savedJoinedMember = goalRoomMemberRepository.save(joinedMember); final GoalRoomRoadmapNode goalRoomRoadmapNode1 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); final GoalRoomRoadmapNode goalRoomRoadmapNode2 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(1); - final CheckFeed checkFeed1 = 인증_피드를_저장한다(goalRoomRoadmapNode1, joinedMember); - final CheckFeed checkFeed2 = 인증_피드를_저장한다(goalRoomRoadmapNode1, joinedMember); - final CheckFeed checkFeed3 = 인증_피드를_저장한다(goalRoomRoadmapNode1, joinedMember); - final CheckFeed checkFeed4 = 인증_피드를_저장한다(goalRoomRoadmapNode2, joinedMember); - final CheckFeed checkFeed5 = 인증_피드를_저장한다(goalRoomRoadmapNode2, joinedMember); - final CheckFeed checkFeed6 = 인증_피드를_저장한다(goalRoomRoadmapNode2, joinedMember); + final CheckFeed checkFeed1 = 인증_피드를_저장한다(goalRoomRoadmapNode1, savedJoinedMember); + final CheckFeed checkFeed2 = 인증_피드를_저장한다(goalRoomRoadmapNode1, savedJoinedMember); + final CheckFeed checkFeed3 = 인증_피드를_저장한다(goalRoomRoadmapNode1, savedJoinedMember); + final CheckFeed checkFeed4 = 인증_피드를_저장한다(goalRoomRoadmapNode2, savedJoinedMember); + final CheckFeed checkFeed5 = 인증_피드를_저장한다(goalRoomRoadmapNode2, savedJoinedMember); + final CheckFeed checkFeed6 = 인증_피드를_저장한다(goalRoomRoadmapNode2, savedJoinedMember); //when - final List checkFeeds1 = checkFeedRepository - .findByRunningGoalRoomRoadmapNode(goalRoomRoadmapNode1); - final List checkFeeds2 = checkFeedRepository - .findByRunningGoalRoomRoadmapNode(goalRoomRoadmapNode2); + final List checkFeeds = checkFeedRepository.findByGoalRoomIdOrderByCreatedAtDesc(goalRoom.getId()); - assertAll( - () -> assertThat(checkFeeds1) - .hasSize(3) - .isEqualTo(List.of(checkFeed3, checkFeed2, checkFeed1)), - () -> assertThat(checkFeeds2) - .hasSize(3) - .isEqualTo(List.of(checkFeed6, checkFeed5, checkFeed4)) - ); + //then + assertThat(checkFeeds) + .isEqualTo(List.of(checkFeed6, checkFeed5, checkFeed4, checkFeed3, checkFeed2, checkFeed1)); } @Test - void 진행중인_골룸에서_특정_노드_기간이_아니면_빈_인증_피드들_반환한다() { + void 골룸이_진행중일_때_특정_노드_동안_등록된_인증_피드들을_조회한다() { //given final Member creator = 사용자를_저장한다("cokiri", "코끼리"); final RoadmapCategory category = 카테고리를_저장한다("여가"); @@ -266,30 +235,41 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository, final Member member = 사용자를_저장한다("participant", "참여자"); final GoalRoom goalRoom = 골룸을_저장한다(targetRoadmapContent, member); - final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator); + final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, + creator.getId()); final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, - member); - goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember)); + member.getId()); + final GoalRoomMember savedLeader = goalRoomMemberRepository.save(leader); + final GoalRoomMember savedJoinedMember = goalRoomMemberRepository.save(joinedMember); final GoalRoomRoadmapNode goalRoomRoadmapNode1 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); final GoalRoomRoadmapNode goalRoomRoadmapNode2 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(1); - 인증_피드를_저장한다(goalRoomRoadmapNode1, joinedMember); - 인증_피드를_저장한다(goalRoomRoadmapNode1, joinedMember); - 인증_피드를_저장한다(goalRoomRoadmapNode1, joinedMember); - 인증_피드를_저장한다(goalRoomRoadmapNode2, joinedMember); - 인증_피드를_저장한다(goalRoomRoadmapNode2, joinedMember); - 인증_피드를_저장한다(goalRoomRoadmapNode2, joinedMember); + final CheckFeed checkFeed1 = 인증_피드를_저장한다(goalRoomRoadmapNode1, savedJoinedMember); + final CheckFeed checkFeed2 = 인증_피드를_저장한다(goalRoomRoadmapNode1, savedJoinedMember); + final CheckFeed checkFeed3 = 인증_피드를_저장한다(goalRoomRoadmapNode1, savedJoinedMember); + final CheckFeed checkFeed4 = 인증_피드를_저장한다(goalRoomRoadmapNode2, savedJoinedMember); + final CheckFeed checkFeed5 = 인증_피드를_저장한다(goalRoomRoadmapNode2, savedJoinedMember); + final CheckFeed checkFeed6 = 인증_피드를_저장한다(goalRoomRoadmapNode2, savedJoinedMember); //when final List checkFeeds1 = checkFeedRepository - .findByGoalRoomRoadmapNode(null); + .findByGoalRoomRoadmapNodeIdOrderByCreatedAtDesc(goalRoomRoadmapNode1.getId()); + final List checkFeeds2 = checkFeedRepository + .findByGoalRoomRoadmapNodeIdOrderByCreatedAtDesc(goalRoomRoadmapNode2.getId()); - assertThat(checkFeeds1).isEmpty(); + assertAll( + () -> assertThat(checkFeeds1) + .hasSize(3) + .isEqualTo(List.of(checkFeed3, checkFeed2, checkFeed1)), + () -> assertThat(checkFeeds2) + .hasSize(3) + .isEqualTo(List.of(checkFeed6, checkFeed5, checkFeed4)) + ); } @Test - void 골룸이_완료됐을_때는_특정한_노드_동안이_아닌_모든_기간_동안_등록된_인증_피드들을_조회한다() { + void 진행중인_골룸에서_특정_노드_기간이_아니면_빈_인증_피드들_반환한다() { //given final Member creator = 사용자를_저장한다("cokiri", "코끼리"); final RoadmapCategory category = 카테고리를_저장한다("여가"); @@ -300,140 +280,40 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository, final Member member = 사용자를_저장한다("participant", "참여자"); final GoalRoom goalRoom = 골룸을_저장한다(targetRoadmapContent, member); - final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator); + final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, + creator.getId()); final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, - member); - goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember)); + member.getId()); + final GoalRoomMember savedLeader = goalRoomMemberRepository.save(leader); + final GoalRoomMember savedJoinedMember = goalRoomMemberRepository.save(joinedMember); final GoalRoomRoadmapNode goalRoomRoadmapNode1 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); final GoalRoomRoadmapNode goalRoomRoadmapNode2 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(1); - final CheckFeed checkFeed1 = 인증_피드를_저장한다(goalRoomRoadmapNode1, joinedMember); - final CheckFeed checkFeed2 = 인증_피드를_저장한다(goalRoomRoadmapNode1, joinedMember); - final CheckFeed checkFeed3 = 인증_피드를_저장한다(goalRoomRoadmapNode1, joinedMember); - final CheckFeed checkFeed4 = 인증_피드를_저장한다(goalRoomRoadmapNode2, joinedMember); - final CheckFeed checkFeed5 = 인증_피드를_저장한다(goalRoomRoadmapNode2, joinedMember); - final CheckFeed checkFeed6 = 인증_피드를_저장한다(goalRoomRoadmapNode2, joinedMember); + 인증_피드를_저장한다(goalRoomRoadmapNode1, savedJoinedMember); + 인증_피드를_저장한다(goalRoomRoadmapNode1, savedJoinedMember); + 인증_피드를_저장한다(goalRoomRoadmapNode1, savedJoinedMember); + 인증_피드를_저장한다(goalRoomRoadmapNode2, savedJoinedMember); + 인증_피드를_저장한다(goalRoomRoadmapNode2, savedJoinedMember); + 인증_피드를_저장한다(goalRoomRoadmapNode2, savedJoinedMember); //when - final List checkFeeds = checkFeedRepository.findByGoalRoom(goalRoom); + final List checkFeeds1 = checkFeedRepository + .findByGoalRoomRoadmapNodeIdOrderByCreatedAtDesc(null); - //then - assertThat(checkFeeds) - .isEqualTo(List.of(checkFeed6, checkFeed5, checkFeed4, checkFeed3, checkFeed2, checkFeed1)); + assertThat(checkFeeds1).isEmpty(); } @Test void 골룸_노드값으로_null이_들어오면_빈_리스트를_반환한다() { //given //when - final List checkFeeds = checkFeedRepository.findByGoalRoomRoadmapNode(null); + final List checkFeeds = checkFeedRepository.findByGoalRoomRoadmapNodeIdOrderByCreatedAtDesc(null); //then assertThat(checkFeeds).isEmpty(); } - - @Test - void 골룸_진행_중에_특정_노드_동안_등록된_인증_피드들을_등록한_사용자의_정보와_함께_조회한다() { - //given - final Member creator = 사용자를_저장한다("cokiri", "코끼리"); - final RoadmapCategory category = 카테고리를_저장한다("여가"); - final Roadmap roadmap = 로드맵을_저장한다(creator, category); - - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final Member member = 사용자를_저장한다("participant", "참여자"); - final GoalRoom goalRoom = 골룸을_저장한다(targetRoadmapContent, member); - - final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator); - final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, - member); - goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember)); - - final GoalRoomRoadmapNode goalRoomRoadmapNode1 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); - final GoalRoomRoadmapNode goalRoomRoadmapNode2 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(1); - - 인증_피드를_저장한다(goalRoomRoadmapNode1, joinedMember); - 인증_피드를_저장한다(goalRoomRoadmapNode1, joinedMember); - 인증_피드를_저장한다(goalRoomRoadmapNode1, joinedMember); - 인증_피드를_저장한다(goalRoomRoadmapNode2, leader); - 인증_피드를_저장한다(goalRoomRoadmapNode2, leader); - 인증_피드를_저장한다(goalRoomRoadmapNode2, leader); - - //when - final List checkFeeds1 = checkFeedRepository.findByRunningGoalRoomRoadmapNodeWithMemberAndMemberImage( - goalRoomRoadmapNode1); - final List checkFeeds2 = checkFeedRepository.findByRunningGoalRoomRoadmapNodeWithMemberAndMemberImage( - goalRoomRoadmapNode2); - - //then - final CheckFeed expected1 = new CheckFeed("src/test/resources/testImage", ImageContentType.JPEG, - "originalFileName", "인증 피드 본문", goalRoomRoadmapNode1, joinedMember); - final CheckFeed expected2 = new CheckFeed("src/test/resources/testImage", ImageContentType.JPEG, - "originalFileName", "인증 피드 본문", goalRoomRoadmapNode2, leader); - - assertAll( - () -> assertThat(checkFeeds1).hasSize(3) - .usingRecursiveComparison() - .ignoringFields("id", "createdAt") - .isEqualTo(List.of(expected1, expected1, expected1)), - () -> assertThat(checkFeeds1.get(0).getGoalRoomMember().getMember().getNickname().getValue()) - .isEqualTo("참여자"), - () -> assertThat(checkFeeds1.get(0).getGoalRoomMember().getMember().getImage().getServerFilePath()) - .isEqualTo("serverFilePath"), - () -> assertThat(checkFeeds2).hasSize(3) - .usingRecursiveComparison() - .ignoringFields("id", "createdAt") - .isEqualTo(List.of(expected2, expected2, expected2)), - () -> assertThat(checkFeeds2.get(0).getGoalRoomMember().getMember().getNickname().getValue()) - .isEqualTo("코끼리"), - () -> assertThat(checkFeeds2.get(0).getGoalRoomMember().getMember().getImage().getServerFilePath()) - .isEqualTo("serverFilePath") - ); - } - - @Test - void 골룸_완료_시_모든_기간_동안_등록된_인증_피드들을_등록한_사용자의_정보와_함께_조회한다() { - //given - final Member creator = 사용자를_저장한다("cokiri", "코끼리"); - final RoadmapCategory category = 카테고리를_저장한다("여가"); - final Roadmap roadmap = 로드맵을_저장한다(creator, category); - - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final Member member = 사용자를_저장한다("participant", "참여자"); - final GoalRoom goalRoom = 골룸을_저장한다(targetRoadmapContent, member); - - final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator); - final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, - member); - goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember)); - - final GoalRoomRoadmapNode goalRoomRoadmapNode1 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); - final GoalRoomRoadmapNode goalRoomRoadmapNode2 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(1); - - 인증_피드를_저장한다(goalRoomRoadmapNode1, joinedMember); - 인증_피드를_저장한다(goalRoomRoadmapNode1, joinedMember); - 인증_피드를_저장한다(goalRoomRoadmapNode1, joinedMember); - 인증_피드를_저장한다(goalRoomRoadmapNode2, leader); - 인증_피드를_저장한다(goalRoomRoadmapNode2, leader); - 인증_피드를_저장한다(goalRoomRoadmapNode2, leader); - - //when - final List checkFeeds = checkFeedRepository.findByGoalRoomWithMemberAndMemberImage(goalRoom); - - //then - final CheckFeed expected1 = new CheckFeed("src/test/resources/testImage", ImageContentType.JPEG, - "originalFileName", "인증 피드 본문", goalRoomRoadmapNode1, joinedMember); - final CheckFeed expected2 = new CheckFeed("src/test/resources/testImage", ImageContentType.JPEG, - "originalFileName", "인증 피드 본문", goalRoomRoadmapNode2, leader); - - assertThat(checkFeeds).hasSize(6) - .usingRecursiveComparison() - .ignoringFields("id", "createdAt") - .isEqualTo(List.of(expected2, expected2, expected2, expected1, expected1, expected1)); - } - + private Member 사용자를_저장한다(final String identifier, final String nickname) { final MemberImage memberImage = new MemberImage("originalFileName", "serverFilePath", ImageContentType.PNG); final MemberProfile memberProfile = new MemberProfile(Gender.MALE, "kirikiri1@email.com"); @@ -477,18 +357,18 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository, private GoalRoom 골룸을_저장한다(final RoadmapContent roadmapContent, final Member member) { final GoalRoom goalRoom = new GoalRoom(new GoalRoomName("골룸"), new LimitedMemberCount(10), - roadmapContent, member); + roadmapContent.getId(), member.getId()); final List roadmapNodes = roadmapContent.getNodes().getValues(); final RoadmapNode firstRoadmapNode = roadmapNodes.get(0); final GoalRoomRoadmapNode firstGoalRoomRoadmapNode = new GoalRoomRoadmapNode( new Period(TODAY, TEN_DAY_LATER), - 10, firstRoadmapNode); + 10, firstRoadmapNode.getId()); final RoadmapNode secondRoadmapNode = roadmapNodes.get(1); final GoalRoomRoadmapNode secondGoalRoomRoadmapNode = new GoalRoomRoadmapNode( new Period(TWENTY_DAY_LAYER, THIRTY_DAY_LATER), - 10, secondRoadmapNode); + 10, secondRoadmapNode.getId()); final GoalRoomRoadmapNodes goalRoomRoadmapNodes = new GoalRoomRoadmapNodes( List.of(firstGoalRoomRoadmapNode, secondGoalRoomRoadmapNode)); @@ -499,6 +379,6 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository, private CheckFeed 인증_피드를_저장한다(final GoalRoomRoadmapNode goalRoomRoadmapNode, final GoalRoomMember joinedMember) { return checkFeedRepository.save( new CheckFeed("src/test/resources/testImage", ImageContentType.JPEG, - "originalFileName", "인증 피드 본문", goalRoomRoadmapNode, joinedMember)); + "originalFileName", "인증 피드 본문", goalRoomRoadmapNode.getId(), joinedMember.getId())); } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/checkfeed/service/GoalRoomCheckFeedServiceTest.java b/backend/kirikiri/src/test/java/co/kirikiri/checkfeed/service/GoalRoomCheckFeedServiceTest.java new file mode 100644 index 000000000..d109d6fad --- /dev/null +++ b/backend/kirikiri/src/test/java/co/kirikiri/checkfeed/service/GoalRoomCheckFeedServiceTest.java @@ -0,0 +1,655 @@ +package co.kirikiri.checkfeed.service; + +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.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.when; + +import co.kirikiri.checkfeed.domain.CheckFeed; +import co.kirikiri.checkfeed.persistence.CheckFeedRepository; +import co.kirikiri.checkfeed.service.dto.request.CheckFeedRequest; +import co.kirikiri.checkfeed.service.dto.response.CheckFeedMemberResponse; +import co.kirikiri.checkfeed.service.dto.response.CheckFeedResponse; +import co.kirikiri.checkfeed.service.dto.response.GoalRoomCheckFeedResponse; +import co.kirikiri.common.exception.BadRequestException; +import co.kirikiri.common.exception.ForbiddenException; +import co.kirikiri.common.exception.ImageExtensionException; +import co.kirikiri.common.exception.NotFoundException; +import co.kirikiri.common.service.FilePathGenerator; +import co.kirikiri.common.service.FileService; +import co.kirikiri.common.type.ImageContentType; +import co.kirikiri.domain.member.EncryptedPassword; +import co.kirikiri.domain.member.Gender; +import co.kirikiri.domain.member.Member; +import co.kirikiri.domain.member.MemberImage; +import co.kirikiri.domain.member.MemberProfile; +import co.kirikiri.domain.member.vo.Identifier; +import co.kirikiri.domain.member.vo.Nickname; +import co.kirikiri.domain.member.vo.Password; +import co.kirikiri.domain.roadmap.Roadmap; +import co.kirikiri.domain.roadmap.RoadmapCategory; +import co.kirikiri.domain.roadmap.RoadmapContent; +import co.kirikiri.domain.roadmap.RoadmapContents; +import co.kirikiri.domain.roadmap.RoadmapDifficulty; +import co.kirikiri.domain.roadmap.RoadmapNode; +import co.kirikiri.domain.roadmap.RoadmapNodeImage; +import co.kirikiri.domain.roadmap.RoadmapNodeImages; +import co.kirikiri.domain.roadmap.RoadmapNodes; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomMember; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNode; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNodes; +import co.kirikiri.goalroom.domain.GoalRoomRole; +import co.kirikiri.goalroom.domain.vo.GoalRoomName; +import co.kirikiri.goalroom.domain.vo.LimitedMemberCount; +import co.kirikiri.goalroom.domain.vo.Period; +import co.kirikiri.goalroom.persistence.GoalRoomMemberRepository; +import co.kirikiri.goalroom.persistence.GoalRoomRepository; +import co.kirikiri.persistence.member.MemberRepository; +import java.net.MalformedURLException; +import java.net.URL; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.mock.web.MockMultipartFile; + +@ExtendWith(MockitoExtension.class) +class GoalRoomCheckFeedServiceTest { + + private static final LocalDate TODAY = LocalDate.now(); + private static final LocalDate TEN_DAY_LATER = TODAY.plusDays(10); + private static final LocalDate TWENTY_DAY_LATER = TODAY.plusDays(20); + private static final LocalDate THIRTY_DAY_LATER = TODAY.plusDays(30); + + @Mock + private GoalRoomRepository goalRoomRepository; + + @Mock + private GoalRoomMemberRepository goalRoomMemberRepository; + + @Mock + private CheckFeedRepository checkFeedRepository; + + @Mock + private MemberRepository memberRepository; + + @Mock + private FileService fileService; + + @Mock + private FilePathGenerator filePathGenerator; + + @InjectMocks + private GoalRoomCheckFeedService goalRoomCheckFeedService; + + @Test + void 인증_피드_등록을_요청한다() { + // given + final CheckFeedRequest request = 인증_피드_요청_DTO를_생성한다("image/jpeg"); + + final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 20); + final GoalRoomMember goalRoomLeader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, + creator.getId()); + goalRoomMemberRepository.save(goalRoomLeader); + final GoalRoomRoadmapNode goalRoomRoadmapNode = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); + final CheckFeed checkFeed = 인증_피드를_생성한다(goalRoomRoadmapNode, goalRoomLeader); + + when(goalRoomRepository.findByIdWithNodes(anyLong())) + .thenReturn(Optional.of(goalRoom)); + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(creator)); + when(goalRoomMemberRepository.findByGoalRoomAndMemberId(any(), any())) + .thenReturn(Optional.of(goalRoomLeader)); + when(checkFeedRepository.countByGoalRoomMemberIdAndGoalRoomRoadmapNodeId(any(), any())) + .thenReturn(0); + when(checkFeedRepository.findByGoalRoomMemberIdAndDateTime(any(), any(), any())) + .thenReturn(Optional.empty()); + when(checkFeedRepository.save(any())) + .thenReturn(checkFeed); + when(filePathGenerator.makeFilePath(any(), any())) + .thenReturn("originalFileName.jpeg"); + when(fileService.generateUrl(anyString(), any())) + .thenReturn(makeUrl("originalFileName.jpeg")); + + // when + final String response = goalRoomCheckFeedService.createCheckFeed("cokirikiri", 1L, request); + + // then + assertAll( + () -> assertThat(goalRoomLeader.getAccomplishmentRate()).isEqualTo(100 / (double) 10), + () -> assertThat(response).contains("originalFileName") + ); + } + + @Test + void 인증_피드_등록시_노드_기간에_해당하지_않으면_예외가_발생한다() { + // given + final CheckFeedRequest request = 인증_피드_요청_DTO를_생성한다("image/jpeg"); + + final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + final GoalRoom goalRoom = 시작_날짜가_미래인_골룸을_생성한다(1L, creator, targetRoadmapContent, 20); + final GoalRoomMember goalRoomLeader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, + creator.getId()); + goalRoomMemberRepository.save(goalRoomLeader); + + when(goalRoomRepository.findByIdWithNodes(anyLong())) + .thenReturn(Optional.of(goalRoom)); + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(creator)); + when(goalRoomMemberRepository.findByGoalRoomAndMemberId(any(), any())) + .thenReturn(Optional.of(goalRoomLeader)); + + // expected + assertThatThrownBy( + () -> goalRoomCheckFeedService.createCheckFeed("cokirikiri", 1L, request)) + .isInstanceOf(BadRequestException.class) + .hasMessage("인증 피드는 노드 기간 내에만 작성할 수 있습니다."); + } + + @Test + void 하루에_두_번_이상_인증_피드_등록_요청_시_예외를_반환한다() { + // given + final CheckFeedRequest request = 인증_피드_요청_DTO를_생성한다("image/jpeg"); + + final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 20); + final GoalRoomMember goalRoomLeader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, + creator.getId()); + goalRoomMemberRepository.save(goalRoomLeader); + final GoalRoomRoadmapNode goalRoomRoadmapNode = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); + final CheckFeed checkFeed = 인증_피드를_생성한다(goalRoomRoadmapNode, goalRoomLeader); + + when(goalRoomRepository.findByIdWithNodes(any())) + .thenReturn(Optional.of(goalRoom)); + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(creator)); + when(goalRoomMemberRepository.findByGoalRoomAndMemberId(any(), any())) + .thenReturn(Optional.of(goalRoomLeader)); + when(checkFeedRepository.findByGoalRoomMemberIdAndDateTime(any(), any(), any())) + .thenReturn(Optional.of(checkFeed)); + + //expect + assertThatThrownBy( + () -> goalRoomCheckFeedService.createCheckFeed("cokirikiri", 1L, request)) + .isInstanceOf(BadRequestException.class) + .hasMessage("이미 오늘 인증 피드를 등록하였습니다."); + } + + @Test + void 골룸_노드에서_허가된_인증_횟수보다_많은_인증_피드_등록_요청_시_예외를_반환한다() { + // given + final CheckFeedRequest request = 인증_피드_요청_DTO를_생성한다("image/jpeg"); + + final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 20); + final GoalRoomMember goalRoomLeader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, + creator.getId()); + goalRoomMemberRepository.save(goalRoomLeader); + final GoalRoomRoadmapNode goalRoomRoadmapNode = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); + + when(goalRoomRepository.findByIdWithNodes(any())) + .thenReturn(Optional.of(goalRoom)); + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(creator)); + when(goalRoomMemberRepository.findByGoalRoomAndMemberId(any(), any())) + .thenReturn(Optional.of(goalRoomLeader)); + when(checkFeedRepository.countByGoalRoomMemberIdAndGoalRoomRoadmapNodeId(any(), any())) + .thenReturn(goalRoomRoadmapNode.getCheckCount()); + + //expect + assertThatThrownBy( + () -> goalRoomCheckFeedService.createCheckFeed("cokirikiri", 1L, request)) + .isInstanceOf(BadRequestException.class) + .hasMessage("이번 노드에는 최대 " + goalRoomRoadmapNode.getCheckCount() + "번만 인증 피드를 등록할 수 있습니다."); + } + + @Test + void 인증_피드_등록_요청_시_허용되지_않는_확장자_형식이라면_예외를_반환한다() { + // given + final CheckFeedRequest request = 인증_피드_요청_DTO를_생성한다("image/gif"); + + final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 20); + final GoalRoomMember goalRoomLeader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, + creator.getId()); + goalRoomMemberRepository.save(goalRoomLeader); + final GoalRoomRoadmapNode goalRoomRoadmapNode = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); + + when(goalRoomRepository.findByIdWithNodes(any())) + .thenReturn(Optional.of(goalRoom)); + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(creator)); + when(goalRoomMemberRepository.findByGoalRoomAndMemberId(any(), any())) + .thenReturn(Optional.of(goalRoomLeader)); + + // when + assertThatThrownBy( + () -> goalRoomCheckFeedService.createCheckFeed("cokirikiri", 1L, request)) + .isInstanceOf(ImageExtensionException.class) + .hasMessage("허용되지 않는 확장자입니다."); + } + + @Test + void 인증_피드_등록_요청_시_존재하지_않는_골룸이라면_예외를_반환한다() { + // given + final CheckFeedRequest request = 인증_피드_요청_DTO를_생성한다("image/jpeg"); + + final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 20); + final GoalRoomMember goalRoomLeader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, + creator.getId()); + goalRoomMemberRepository.save(goalRoomLeader); + + when(goalRoomRepository.findByIdWithNodes(any())) + .thenReturn(Optional.empty()); + + //expect + assertThatThrownBy( + () -> goalRoomCheckFeedService.createCheckFeed("cokirikiri", 1L, request)) + .isInstanceOf(NotFoundException.class) + .hasMessage("존재하지 않는 골룸입니다. goalRoomId = 1"); + } + + @Test + void 인증_피드_등록_요청_시_사용자가_참여하지_않은_골룸이라면_예외를_반환한다() { + // given + final CheckFeedRequest request = 인증_피드_요청_DTO를_생성한다("image/jpeg"); + + final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 20); + + final GoalRoomMember goalRoomLeader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, + creator.getId()); + goalRoomMemberRepository.save(goalRoomLeader); + + when(goalRoomRepository.findByIdWithNodes(any())) + .thenReturn(Optional.of(goalRoom)); + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(creator)); + when(goalRoomMemberRepository.findByGoalRoomAndMemberId(any(), any())) + .thenReturn(Optional.empty()); + + //expect + assertThatThrownBy( + () -> goalRoomCheckFeedService.createCheckFeed("identifier", 1L, request)) + .isInstanceOf(NotFoundException.class) + .hasMessage("골룸에 해당 사용자가 존재하지 않습니다. 사용자 아이디 = " + "identifier"); + } + + @Test + void 진행중인_골룸의_인증피드를_전체_조회한다() throws MalformedURLException { + // given + final Member creator = 사용자를_생성한다(1L, "cokirikiri1", "password1!", "코끼리1", "kirikiri1@email"); + final Member follower = 사용자를_생성한다(2L, "cokirikiri2", "password2!", "코끼리2", "kirikiri2@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 20); + goalRoom.start(); + + final GoalRoomMember goalRoomMember1 = new GoalRoomMember(1L, GoalRoomRole.LEADER, LocalDateTime.now(), + goalRoom, creator.getId()); + final GoalRoomMember goalRoomMember2 = new GoalRoomMember(2L, GoalRoomRole.FOLLOWER, LocalDateTime.now(), + goalRoom, follower.getId()); + final GoalRoomRoadmapNode goalRoomRoadmapNode = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); + + final CheckFeed checkFeed1 = 인증피드를_생성한다("serverFilePath1", "description1", goalRoomRoadmapNode, + goalRoomMember1); + final CheckFeed checkFeed2 = 인증피드를_생성한다("serverFilePath2", "description2", goalRoomRoadmapNode, + goalRoomMember1); + final CheckFeed checkFeed3 = 인증피드를_생성한다("serverFilePath3", "description3", goalRoomRoadmapNode, + goalRoomMember2); + + when(goalRoomRepository.findByIdWithNodes(anyLong())) + .thenReturn(Optional.of(goalRoom)); + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(creator)); + when(goalRoomMemberRepository.findByGoalRoomAndMemberId(any(), any())) + .thenReturn(Optional.of(goalRoomMember1)); + when(goalRoomMemberRepository.findById(1L)) + .thenReturn(Optional.of(goalRoomMember1)); + when(goalRoomMemberRepository.findById(2L)) + .thenReturn(Optional.of(goalRoomMember2)); + when(memberRepository.findWithMemberProfileAndImageById(goalRoomMember1.getMemberId())) + .thenReturn(Optional.of(creator)); + when(memberRepository.findWithMemberProfileAndImageById(goalRoomMember2.getMemberId())) + .thenReturn(Optional.of(follower)); + when(checkFeedRepository.findByGoalRoomRoadmapNodeIdOrderByCreatedAtDesc(any())) + .thenReturn(List.of(checkFeed3, checkFeed2, checkFeed1)); + when(fileService.generateUrl(anyString(), any())) + .thenReturn(new URL("http://example.com/serverFilePath")); + + // when + final List responses = goalRoomCheckFeedService.findGoalRoomCheckFeeds("cokirikiri", + 1L); + + // then + final GoalRoomCheckFeedResponse goalRoomCheckFeedResponse1 = new GoalRoomCheckFeedResponse( + new CheckFeedMemberResponse(1L, "코끼리1", "http://example.com/serverFilePath"), + new CheckFeedResponse(1L, "http://example.com/serverFilePath", "description1", LocalDate.now())); + final GoalRoomCheckFeedResponse goalRoomCheckFeedResponse2 = new GoalRoomCheckFeedResponse( + new CheckFeedMemberResponse(1L, "코끼리1", "http://example.com/serverFilePath"), + new CheckFeedResponse(2L, "http://example.com/serverFilePath", "description2", LocalDate.now())); + final GoalRoomCheckFeedResponse goalRoomCheckFeedResponse3 = new GoalRoomCheckFeedResponse( + new CheckFeedMemberResponse(2L, "코끼리2", "http://example.com/serverFilePath"), + new CheckFeedResponse(3L, "http://example.com/serverFilePath", "description3", LocalDate.now())); + final List expected = List.of(goalRoomCheckFeedResponse3, + goalRoomCheckFeedResponse2, goalRoomCheckFeedResponse1); + + assertThat(responses).usingRecursiveComparison() + .ignoringFields("checkFeed.id", "checkFeed.createdAt") + .isEqualTo(expected); + } + + @Test + void 모집중인_골룸의_인증피드를_조회시_빈_값을_반환한다() { + // given + final Member creator = 사용자를_생성한다(1L, "cokirikiri1", "password1!", "코끼리1", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 20); + final GoalRoomMember goalRoomMember = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, + creator.getId()); + + when(goalRoomRepository.findByIdWithNodes(anyLong())) + .thenReturn(Optional.of(goalRoom)); + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(creator)); + when(goalRoomMemberRepository.findByGoalRoomAndMemberId(any(), any())) + .thenReturn(Optional.of(goalRoomMember)); + + // when + final List responses = goalRoomCheckFeedService.findGoalRoomCheckFeeds("cokirikiri", + 1L); + + // then + final List expected = Collections.emptyList(); + + assertThat(responses).isEqualTo(expected); + } + + @Test + void 종료된_골룸의_인증피드를_전체_조회시_모든_기간의_인증피드를_대상으로_반환한다() throws MalformedURLException { + // given + final Member creator = 사용자를_생성한다(1L, "cokirikiri1", "password1!", "코끼리1", "kirikiri1@email"); + final Member follower = 사용자를_생성한다(2L, "cokirikiri2", "password2!", "코끼리2", "kirikiri2@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 20); + goalRoom.complete(); + + final GoalRoomMember goalRoomMember1 = new GoalRoomMember(1L, GoalRoomRole.LEADER, LocalDateTime.now(), + goalRoom, + creator.getId()); + final GoalRoomMember goalRoomMember2 = new GoalRoomMember(2L, GoalRoomRole.FOLLOWER, LocalDateTime.now(), + goalRoom, + follower.getId()); + final GoalRoomRoadmapNode goalRoomRoadmapNode = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); + + final CheckFeed checkFeed1 = 인증피드를_생성한다("serverFilePath1", "description1", goalRoomRoadmapNode, + goalRoomMember1); + final CheckFeed checkFeed2 = 인증피드를_생성한다("serverFilePath2", "description2", goalRoomRoadmapNode, + goalRoomMember1); + final CheckFeed checkFeed3 = 인증피드를_생성한다("serverFilePath3", "description3", goalRoomRoadmapNode, + goalRoomMember2); + + when(goalRoomRepository.findByIdWithNodes(anyLong())) + .thenReturn(Optional.of(goalRoom)); + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(creator)); + when(goalRoomMemberRepository.findByGoalRoomAndMemberId(any(), any())) + .thenReturn(Optional.of(goalRoomMember1)); + when(goalRoomMemberRepository.findById(1L)) + .thenReturn(Optional.of(goalRoomMember1)); + when(goalRoomMemberRepository.findById(2L)) + .thenReturn(Optional.of(goalRoomMember2)); + when(memberRepository.findWithMemberProfileAndImageById(goalRoomMember1.getMemberId())) + .thenReturn(Optional.of(creator)); + when(memberRepository.findWithMemberProfileAndImageById(goalRoomMember2.getMemberId())) + .thenReturn(Optional.of(follower)); + given(checkFeedRepository.findByGoalRoomIdOrderByCreatedAtDesc(any())) + .willReturn(List.of(checkFeed3, checkFeed2, checkFeed1)); + given(fileService.generateUrl(anyString(), any())) + .willReturn(new URL("http://example.com/serverFilePath")); + + // when + final List responses = goalRoomCheckFeedService.findGoalRoomCheckFeeds("cokirikiri", + 1L); + + // then + final GoalRoomCheckFeedResponse goalRoomCheckFeedResponse1 = new GoalRoomCheckFeedResponse( + new CheckFeedMemberResponse(1L, "코끼리1", "http://example.com/serverFilePath"), + new CheckFeedResponse(1L, "http://example.com/serverFilePath", "description1", LocalDate.now())); + final GoalRoomCheckFeedResponse goalRoomCheckFeedResponse2 = new GoalRoomCheckFeedResponse( + new CheckFeedMemberResponse(1L, "코끼리1", "http://example.com/serverFilePath"), + new CheckFeedResponse(2L, "http://example.com/serverFilePath", "description2", LocalDate.now())); + final GoalRoomCheckFeedResponse goalRoomCheckFeedResponse3 = new GoalRoomCheckFeedResponse( + new CheckFeedMemberResponse(2L, "코끼리2", "http://example.com/serverFilePath"), + new CheckFeedResponse(3L, "http://example.com/serverFilePath", "description3", LocalDate.now())); + final List expected = List.of(goalRoomCheckFeedResponse3, + goalRoomCheckFeedResponse2, goalRoomCheckFeedResponse1); + + assertThat(responses).usingRecursiveComparison() + .ignoringFields("checkFeed.id", "checkFeed.createdAt") + .isEqualTo(expected); + } + + @Test + void 골룸의_인증피드를_전체_조회시_현재_진행중인_노드가_없으면_빈_리스트를_반환한다() { + // given + final Member creator = 사용자를_생성한다(1L, "cokirikiri1", "password1!", "코끼리1", "kirikiri1@email"); + final Member follower = 사용자를_생성한다(2L, "cokirikiri2", "password2!", "코끼리2", "kirikiri2@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + + final GoalRoom goalRoom = 진행중인_노드가_없는_골룸을_생성한다(creator, roadmap.getContents().getValues().get(0)); + final GoalRoomMember goalRoomMember1 = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, + creator.getId()); + final GoalRoomMember goalRoomMember2 = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, + follower.getId()); + final GoalRoomRoadmapNode goalRoomRoadmapNode = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); + + 인증피드를_생성한다("serverFilePath1", "description1", goalRoomRoadmapNode, goalRoomMember1); + 인증피드를_생성한다("serverFilePath2", "description2", goalRoomRoadmapNode, goalRoomMember1); + 인증피드를_생성한다("serverFilePath3", "description3", goalRoomRoadmapNode, goalRoomMember2); + + when(goalRoomRepository.findByIdWithNodes(anyLong())) + .thenReturn(Optional.of(goalRoom)); + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(creator)); + when(goalRoomMemberRepository.findByGoalRoomAndMemberId(any(), any())) + .thenReturn(Optional.of(goalRoomMember1)); + + // when + final List responses = goalRoomCheckFeedService.findGoalRoomCheckFeeds("cokirikiri", + 1L); + + // then + assertThat(responses).isEmpty(); + } + + @Test + void 골룸의_인증피드를_전체_조회할_때_존재하지_않는_골룸이면_예외가_발생한다() { + // given + when(goalRoomRepository.findByIdWithNodes(anyLong())) + .thenThrow(new NotFoundException("존재하지 않는 골룸입니다. goalRoomId = 1")); + + // when + // then + assertThatThrownBy(() -> goalRoomCheckFeedService.findGoalRoomCheckFeeds("cokirikiri", 1L)) + .isInstanceOf(NotFoundException.class); + } + + @Test + void 골룸의_인증피드를_전체_조회할_때_골룸에_참여하지_않은_회원이면_예외가_발생한다() { + // given + final Member creator = 사용자를_생성한다(1L, "cokirikiri1", "password1!", "코끼리1", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 20); + + when(goalRoomRepository.findByIdWithNodes(anyLong())) + .thenReturn(Optional.of(goalRoom)); + when(goalRoomRepository.findByIdWithNodes(anyLong())) + .thenThrow(new ForbiddenException("골룸에 참여하지 않은 회원입니다.")); + + // when + // then + assertThatThrownBy(() -> goalRoomCheckFeedService.findGoalRoomCheckFeeds("cokirikiri", 1L)) + .isInstanceOf(ForbiddenException.class); + } + + private Member 사용자를_생성한다(final Long memberId, final String identifier, final String password, final String nickname, + final String email) { + final MemberProfile memberProfile = new MemberProfile(Gender.MALE, email); + final MemberImage memberImage = new MemberImage("orifinalFileName", "serveFilePath", ImageContentType.PNG); + return new Member(memberId, new Identifier(identifier), null, new EncryptedPassword(new Password(password)), + new Nickname(nickname), memberImage, memberProfile); + } + + private Roadmap 로드맵을_생성한다(final Member creator) { + final RoadmapCategory category = new RoadmapCategory("게임"); + final List roadmapNodes = 로드맵_노드들을_생성한다(); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); + final Roadmap roadmap = new Roadmap("로드맵 제목", "로드맵 소개글", 10, RoadmapDifficulty.NORMAL, creator, category); + roadmap.addContent(roadmapContent); + return roadmap; + } + + private List 로드맵_노드들을_생성한다() { + final RoadmapNode roadmapNode1 = new RoadmapNode("로드맵 1주차", "로드맵 1주차 내용"); + roadmapNode1.addImages(new RoadmapNodeImages(노드_이미지들을_생성한다())); + final RoadmapNode roadmapNode2 = new RoadmapNode("로드맵 2주차", "로드맵 2주차 내용"); + return List.of(roadmapNode1, roadmapNode2); + } + + private RoadmapContent 로드맵_본문을_생성한다(final List roadmapNodes) { + final RoadmapContent roadmapContent = new RoadmapContent("로드맵 본문"); + roadmapContent.addNodes(new RoadmapNodes(roadmapNodes)); + return roadmapContent; + } + + private List 노드_이미지들을_생성한다() { + return List.of( + new RoadmapNodeImage("node-image1.png", "node-image1-save-path", ImageContentType.PNG), + new RoadmapNodeImage("node-image2.png", "node-image2-save-path", ImageContentType.PNG) + ); + } + + private GoalRoom 골룸을_생성한다(final Long goalRoomId, final Member creator, final RoadmapContent roadmapContent, + final Integer limitedMemberCount) { + final GoalRoom goalRoom = new GoalRoom(goalRoomId, new GoalRoomName("골룸 이름"), + new LimitedMemberCount(limitedMemberCount), roadmapContent.getId(), creator.getId()); + goalRoom.addAllGoalRoomRoadmapNodes(골룸_로드맵_노드들을_생성한다(roadmapContent.getNodes())); + return goalRoom; + } + + private GoalRoom 시작_날짜가_미래인_골룸을_생성한다(final Long goalRoomId, final Member creator, + final RoadmapContent roadmapContent, final Integer limitedMemberCount) { + final GoalRoom goalRoom = new GoalRoom(goalRoomId, new GoalRoomName("골룸 이름"), + new LimitedMemberCount(limitedMemberCount), roadmapContent.getId(), creator.getId()); + final GoalRoomRoadmapNode goalRoomRoadmapNode = new GoalRoomRoadmapNode( + new Period(TEN_DAY_LATER, TWENTY_DAY_LATER), 5, roadmapContent.getNodes().getValues().get(0).getId()); + goalRoom.addAllGoalRoomRoadmapNodes( + new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode))); + return goalRoom; + } + + private GoalRoom 진행중인_노드가_없는_골룸을_생성한다(final Member member, final RoadmapContent roadmapContent) { + final GoalRoom goalRoom = new GoalRoom(new GoalRoomName("골룸"), new LimitedMemberCount(10), + roadmapContent.getId(), member.getId()); + final List roadmapNodes = roadmapContent.getNodes().getValues(); + + final RoadmapNode firstRoadmapNode = roadmapNodes.get(0); + final GoalRoomRoadmapNode firstGoalRoomRoadmapNode = new GoalRoomRoadmapNode( + 1L, new Period(TEN_DAY_LATER, TWENTY_DAY_LATER), 10, firstRoadmapNode.getId()); + + final RoadmapNode secondRoadmapNode = roadmapNodes.get(1); + final GoalRoomRoadmapNode secondGoalRoomRoadmapNode = new GoalRoomRoadmapNode( + 2L, new Period(THIRTY_DAY_LATER, THIRTY_DAY_LATER.plusDays(10)), 2, secondRoadmapNode.getId()); + + final GoalRoomRoadmapNodes goalRoomRoadmapNodes = new GoalRoomRoadmapNodes( + List.of(firstGoalRoomRoadmapNode, secondGoalRoomRoadmapNode)); + goalRoom.addAllGoalRoomRoadmapNodes(goalRoomRoadmapNodes); + return goalRoom; + } + + private GoalRoomRoadmapNodes 골룸_로드맵_노드들을_생성한다(final RoadmapNodes roadmapNodes) { + return new GoalRoomRoadmapNodes(List.of( + new GoalRoomRoadmapNode(new Period(TODAY, TEN_DAY_LATER), 5, roadmapNodes.getValues().get(0).getId()), + new GoalRoomRoadmapNode(new Period(TEN_DAY_LATER.plusDays(1), TWENTY_DAY_LATER), 5, + roadmapNodes.getValues().get(1).getId())) + ); + } + + private CheckFeedRequest 인증_피드_요청_DTO를_생성한다(final String contentType) { + return new CheckFeedRequest( + new MockMultipartFile("image", "originalFileName.jpeg", contentType, + "test image".getBytes()), "인증 피드 설명"); + } + + private CheckFeed 인증_피드를_생성한다(final GoalRoomRoadmapNode goalRoomRoadmapNode, final GoalRoomMember joinedMember) { + return new CheckFeed("src/test/resources/testImage/originalFileName.jpeg", ImageContentType.JPEG, + "originalFileName.jpeg", "인증 피드 설명", goalRoomRoadmapNode.getId(), joinedMember.getId()); + } + + private CheckFeed 인증피드를_생성한다(final String serverFilePath, final String description, + final GoalRoomRoadmapNode goalRoomRoadmapNode, final GoalRoomMember goalRoomMember) { + return new CheckFeed(serverFilePath, ImageContentType.PNG, "fileName", description, goalRoomRoadmapNode.getId(), + goalRoomMember.getId(), LocalDateTime.now()); + } + + private URL makeUrl(final String path) { + try { + return new URL("http://example.com/" + path); + } catch (final MalformedURLException e) { + throw new RuntimeException(e); + } + } +} diff --git a/backend/kirikiri/src/test/java/co/kirikiri/controller/helper/ControllerTestHelper.java b/backend/kirikiri/src/test/java/co/kirikiri/common/helper/ControllerTestHelper.java similarity index 85% rename from backend/kirikiri/src/test/java/co/kirikiri/controller/helper/ControllerTestHelper.java rename to backend/kirikiri/src/test/java/co/kirikiri/common/helper/ControllerTestHelper.java index 7fcf69214..c5d6046fd 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/controller/helper/ControllerTestHelper.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/common/helper/ControllerTestHelper.java @@ -1,14 +1,15 @@ -package co.kirikiri.controller.helper; +package co.kirikiri.common.helper; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; +import co.kirikiri.common.helper.FieldDescriptionHelper.FieldDescription; import co.kirikiri.common.interceptor.AuthInterceptor; import co.kirikiri.common.resolver.MemberIdentifierArgumentResolver; +import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.restdocs.payload.FieldDescriptor; -import java.util.List; public class ControllerTestHelper extends RestDocsHelper { @@ -31,8 +32,7 @@ void setUp() { .thenReturn(true); } - protected List makeFieldDescriptor( - final List descriptions) { + protected List makeFieldDescriptor(final List descriptions) { return descriptions.stream() .map(FieldDescriptionHelper::getDescriptor) .toList(); diff --git a/backend/kirikiri/src/test/java/co/kirikiri/controller/helper/FieldDescriptionHelper.java b/backend/kirikiri/src/test/java/co/kirikiri/common/helper/FieldDescriptionHelper.java similarity index 93% rename from backend/kirikiri/src/test/java/co/kirikiri/controller/helper/FieldDescriptionHelper.java rename to backend/kirikiri/src/test/java/co/kirikiri/common/helper/FieldDescriptionHelper.java index e7cdaeb4f..6f5ba543f 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/controller/helper/FieldDescriptionHelper.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/common/helper/FieldDescriptionHelper.java @@ -1,6 +1,6 @@ -package co.kirikiri.controller.helper; +package co.kirikiri.common.helper; -import static co.kirikiri.controller.helper.RestDocsHelper.RESTRICT; +import static co.kirikiri.common.helper.RestDocsHelper.RESTRICT; import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; import org.springframework.restdocs.payload.FieldDescriptor; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/persistence/helper/RepositoryTest.java b/backend/kirikiri/src/test/java/co/kirikiri/common/helper/RepositoryTest.java similarity index 93% rename from backend/kirikiri/src/test/java/co/kirikiri/persistence/helper/RepositoryTest.java rename to backend/kirikiri/src/test/java/co/kirikiri/common/helper/RepositoryTest.java index 5bfa474ac..aec6345c0 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/persistence/helper/RepositoryTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/common/helper/RepositoryTest.java @@ -1,4 +1,4 @@ -package co.kirikiri.persistence.helper; +package co.kirikiri.common.helper; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/controller/helper/RestDocsHelper.java b/backend/kirikiri/src/test/java/co/kirikiri/common/helper/RestDocsHelper.java similarity index 98% rename from backend/kirikiri/src/test/java/co/kirikiri/controller/helper/RestDocsHelper.java rename to backend/kirikiri/src/test/java/co/kirikiri/common/helper/RestDocsHelper.java index f977002c7..647456cd7 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/controller/helper/RestDocsHelper.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/common/helper/RestDocsHelper.java @@ -1,10 +1,11 @@ -package co.kirikiri.controller.helper; +package co.kirikiri.common.helper; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.UnsupportedEncodingException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -21,7 +22,6 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.filter.CharacterEncodingFilter; -import java.io.UnsupportedEncodingException; @ActiveProfiles("test") @Import(TestObjectMapperConfig.class) diff --git a/backend/kirikiri/src/test/java/co/kirikiri/controller/helper/TestObjectMapperConfig.java b/backend/kirikiri/src/test/java/co/kirikiri/common/helper/TestObjectMapperConfig.java similarity index 91% rename from backend/kirikiri/src/test/java/co/kirikiri/controller/helper/TestObjectMapperConfig.java rename to backend/kirikiri/src/test/java/co/kirikiri/common/helper/TestObjectMapperConfig.java index 1d0fb9f35..681c83655 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/controller/helper/TestObjectMapperConfig.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/common/helper/TestObjectMapperConfig.java @@ -1,4 +1,4 @@ -package co.kirikiri.controller.helper; +package co.kirikiri.common.helper; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/common/interceptor/AuthInterceptorTest.java b/backend/kirikiri/src/test/java/co/kirikiri/common/interceptor/AuthInterceptorTest.java index 606505846..19ac403e2 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/common/interceptor/AuthInterceptorTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/common/interceptor/AuthInterceptorTest.java @@ -6,8 +6,8 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; +import co.kirikiri.common.exception.AuthenticationException; import co.kirikiri.service.auth.AuthService; -import co.kirikiri.service.exception.AuthenticationException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/common/resolver/MemberIdentifierArgumentResolverTest.java b/backend/kirikiri/src/test/java/co/kirikiri/common/resolver/MemberIdentifierArgumentResolverTest.java index c9843407f..5063ba103 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/common/resolver/MemberIdentifierArgumentResolverTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/common/resolver/MemberIdentifierArgumentResolverTest.java @@ -5,10 +5,10 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; +import co.kirikiri.common.exception.AuthenticationException; +import co.kirikiri.common.exception.ServerException; import co.kirikiri.common.interceptor.Authenticated; import co.kirikiri.service.auth.AuthService; -import co.kirikiri.service.exception.AuthenticationException; -import co.kirikiri.service.exception.ServerException; import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/common/resolver/RoadmapSaveArgumentResolverTest.java b/backend/kirikiri/src/test/java/co/kirikiri/common/resolver/RoadmapSaveArgumentResolverTest.java index 80973fc0f..5ee14a499 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/common/resolver/RoadmapSaveArgumentResolverTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/common/resolver/RoadmapSaveArgumentResolverTest.java @@ -4,9 +4,9 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.when; +import co.kirikiri.common.exception.BadRequestException; import co.kirikiri.service.dto.member.request.MemberJoinRequest; import co.kirikiri.service.dto.roadmap.request.RoadmapSaveRequest; -import co.kirikiri.service.exception.BadRequestException; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import javax.xml.validation.Validator; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/controller/AuthCreateApiTest.java b/backend/kirikiri/src/test/java/co/kirikiri/controller/AuthCreateApiTest.java index 8b1741f4c..dad0e21f3 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/controller/AuthCreateApiTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/controller/AuthCreateApiTest.java @@ -12,16 +12,16 @@ import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import co.kirikiri.controller.helper.ControllerTestHelper; -import co.kirikiri.controller.helper.FieldDescriptionHelper.FieldDescription; +import co.kirikiri.common.exception.AuthenticationException; +import co.kirikiri.common.helper.ControllerTestHelper; +import co.kirikiri.common.service.dto.ErrorResponse; +import co.kirikiri.common.helper.FieldDescriptionHelper.FieldDescription; import co.kirikiri.service.auth.AuthService; import co.kirikiri.service.auth.NaverOauthService; -import co.kirikiri.service.dto.ErrorResponse; import co.kirikiri.service.dto.auth.OauthRedirectResponse; import co.kirikiri.service.dto.auth.request.LoginRequest; import co.kirikiri.service.dto.auth.request.ReissueTokenRequest; import co.kirikiri.service.dto.auth.response.AuthenticationResponse; -import co.kirikiri.service.exception.AuthenticationException; import com.fasterxml.jackson.core.type.TypeReference; import java.util.List; import org.junit.jupiter.api.Test; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/controller/MemberCreateApiTest.java b/backend/kirikiri/src/test/java/co/kirikiri/controller/MemberCreateApiTest.java index 0764ac644..89320fed1 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/controller/MemberCreateApiTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/controller/MemberCreateApiTest.java @@ -11,13 +11,13 @@ import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import co.kirikiri.controller.helper.ControllerTestHelper; -import co.kirikiri.controller.helper.FieldDescriptionHelper.FieldDescription; -import co.kirikiri.service.dto.ErrorResponse; +import co.kirikiri.common.exception.BadRequestException; +import co.kirikiri.common.exception.ConflictException; +import co.kirikiri.common.helper.ControllerTestHelper; +import co.kirikiri.common.service.dto.ErrorResponse; +import co.kirikiri.common.helper.FieldDescriptionHelper.FieldDescription; import co.kirikiri.service.dto.member.request.GenderType; import co.kirikiri.service.dto.member.request.MemberJoinRequest; -import co.kirikiri.service.exception.BadRequestException; -import co.kirikiri.service.exception.ConflictException; import co.kirikiri.service.member.MemberService; import com.fasterxml.jackson.core.type.TypeReference; import java.util.List; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/controller/MemberReadApiTest.java b/backend/kirikiri/src/test/java/co/kirikiri/controller/MemberReadApiTest.java index cfb492596..6ecb6a607 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/controller/MemberReadApiTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/controller/MemberReadApiTest.java @@ -12,12 +12,12 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import co.kirikiri.controller.helper.ControllerTestHelper; +import co.kirikiri.common.exception.NotFoundException; +import co.kirikiri.common.helper.ControllerTestHelper; +import co.kirikiri.common.service.dto.ErrorResponse; import co.kirikiri.domain.member.Gender; -import co.kirikiri.service.dto.ErrorResponse; import co.kirikiri.service.dto.member.response.MemberInformationForPublicResponse; import co.kirikiri.service.dto.member.response.MemberInformationResponse; -import co.kirikiri.service.exception.NotFoundException; import co.kirikiri.service.member.MemberService; import com.fasterxml.jackson.core.type.TypeReference; import org.junit.jupiter.api.Test; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/controller/RoadmapCreateApiTest.java b/backend/kirikiri/src/test/java/co/kirikiri/controller/RoadmapCreateApiTest.java index 04f4a8d19..6a34ccb28 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/controller/RoadmapCreateApiTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/controller/RoadmapCreateApiTest.java @@ -24,19 +24,19 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import co.kirikiri.controller.helper.ControllerTestHelper; -import co.kirikiri.service.dto.ErrorResponse; +import co.kirikiri.common.exception.AuthenticationException; +import co.kirikiri.common.exception.BadRequestException; +import co.kirikiri.common.exception.ConflictException; +import co.kirikiri.common.exception.ForbiddenException; +import co.kirikiri.common.exception.NotFoundException; +import co.kirikiri.common.helper.ControllerTestHelper; +import co.kirikiri.common.service.dto.ErrorResponse; import co.kirikiri.service.dto.roadmap.request.RoadmapCategorySaveRequest; import co.kirikiri.service.dto.roadmap.request.RoadmapDifficultyType; import co.kirikiri.service.dto.roadmap.request.RoadmapNodeSaveRequest; import co.kirikiri.service.dto.roadmap.request.RoadmapReviewSaveRequest; import co.kirikiri.service.dto.roadmap.request.RoadmapSaveRequest; import co.kirikiri.service.dto.roadmap.request.RoadmapTagSaveRequest; -import co.kirikiri.service.exception.AuthenticationException; -import co.kirikiri.service.exception.BadRequestException; -import co.kirikiri.service.exception.ConflictException; -import co.kirikiri.service.exception.ForbiddenException; -import co.kirikiri.service.exception.NotFoundException; import co.kirikiri.service.roadmap.RoadmapCreateService; import co.kirikiri.service.roadmap.RoadmapReadService; import com.fasterxml.jackson.core.type.TypeReference; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/controller/RoadmapReadApiTest.java b/backend/kirikiri/src/test/java/co/kirikiri/controller/RoadmapReadApiTest.java index ceda742a1..ceaca5704 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/controller/RoadmapReadApiTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/controller/RoadmapReadApiTest.java @@ -16,11 +16,13 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import co.kirikiri.controller.helper.ControllerTestHelper; -import co.kirikiri.domain.goalroom.GoalRoomStatus; +import co.kirikiri.common.exception.NotFoundException; +import co.kirikiri.common.helper.ControllerTestHelper; +import co.kirikiri.common.service.dto.ErrorResponse; import co.kirikiri.domain.roadmap.RoadmapDifficulty; +import co.kirikiri.goalroom.domain.GoalRoomStatus; +import co.kirikiri.goalroom.service.dto.response.RoadmapGoalRoomResponse; import co.kirikiri.service.dto.CustomScrollRequest; -import co.kirikiri.service.dto.ErrorResponse; import co.kirikiri.service.dto.member.response.MemberResponse; import co.kirikiri.service.dto.roadmap.request.RoadmapOrderTypeRequest; import co.kirikiri.service.dto.roadmap.response.MemberRoadmapResponse; @@ -29,13 +31,11 @@ import co.kirikiri.service.dto.roadmap.response.RoadmapContentResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapForListResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapForListResponses; -import co.kirikiri.service.dto.roadmap.response.RoadmapGoalRoomResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapGoalRoomResponses; import co.kirikiri.service.dto.roadmap.response.RoadmapNodeResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapReviewResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapTagResponse; -import co.kirikiri.service.exception.NotFoundException; import co.kirikiri.service.roadmap.RoadmapCreateService; import co.kirikiri.service.roadmap.RoadmapReadService; import com.fasterxml.jackson.core.type.TypeReference; @@ -692,12 +692,12 @@ class RoadmapReadApiTest extends ControllerTestHelper { GoalRoomStatus.RECRUITING, 3, 6, LocalDateTime.of(2023, 7, 20, 13, 0, 0), LocalDate.now(), LocalDate.now().plusDays(100), - new MemberResponse(1L, "황시진", "default-member-image")); + new co.kirikiri.goalroom.service.dto.response.MemberResponse(1L, "황시진", "default-member-image")); final RoadmapGoalRoomResponse roadmapGoalRoomResponse2 = new RoadmapGoalRoomResponse(2L, "골룸 이름2", GoalRoomStatus.RECRUITING, 4, 10, LocalDateTime.of(2023, 7, 10, 13, 0, 0), LocalDate.now(), LocalDate.now().plusDays(100), - new MemberResponse(2L, "시진이", "default-member-image")); + new co.kirikiri.goalroom.service.dto.response.MemberResponse(2L, "시진이", "default-member-image")); final List responses = List.of(roadmapGoalRoomResponse1, roadmapGoalRoomResponse2); return new RoadmapGoalRoomResponses(responses, false); diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomPendingMemberTest.java b/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomPendingMemberTest.java deleted file mode 100644 index 78a675c65..000000000 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomPendingMemberTest.java +++ /dev/null @@ -1,105 +0,0 @@ -package co.kirikiri.domain.goalroom; - -import static org.assertj.core.api.Assertions.assertThat; - -import co.kirikiri.domain.goalroom.vo.GoalRoomName; -import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; -import co.kirikiri.domain.member.EncryptedPassword; -import co.kirikiri.domain.member.Gender; -import co.kirikiri.domain.member.Member; -import co.kirikiri.domain.member.MemberProfile; -import co.kirikiri.domain.member.vo.Identifier; -import co.kirikiri.domain.member.vo.Nickname; -import co.kirikiri.domain.member.vo.Password; -import co.kirikiri.domain.roadmap.RoadmapContent; -import org.junit.jupiter.api.Test; -import java.time.LocalDateTime; - -class GoalRoomPendingMemberTest { - - @Test - void 골룸의_리더이면_True를_반환한다() { - // given - final Member member = new Member(new Identifier("identifier"), new EncryptedPassword(new Password("password1")), - new Nickname("nickname"), null, - new MemberProfile(Gender.FEMALE, "kirikiri1@email.com")); - final GoalRoom goalRoom = new GoalRoom(new GoalRoomName("goalroom"), new LimitedMemberCount(10), - new RoadmapContent("content"), member); - - // when - final GoalRoomPendingMember goalRoomPendingMember = new GoalRoomPendingMember(GoalRoomRole.LEADER, goalRoom, - member); - - // then - assertThat(goalRoomPendingMember.isLeader()).isTrue(); - } - - @Test - void 골룸의_리더가_아니면_false를_반환한다() { - // given - final Member member = new Member(new Identifier("identifier"), new EncryptedPassword(new Password("password1")), - new Nickname("nickname"), null, - new MemberProfile(Gender.FEMALE, "kirikiri1@email.com")); - final GoalRoom goalRoom = new GoalRoom(new GoalRoomName("goalroom"), new LimitedMemberCount(10), - new RoadmapContent("content"), member); - - // when - final GoalRoomPendingMember goalRoomPendingMember = new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, goalRoom, - member); - - // then - assertThat(goalRoomPendingMember.isLeader()).isFalse(); - } - - @Test - void 입력받은_멤버가_자신과_같은_멤버이면_true를_반환한다() { - // given - final Member member = new Member(new Identifier("identifier"), - new EncryptedPassword(new Password("password1!")), - new Nickname("name"), null, null); - final GoalRoomPendingMember goalRoomPendingMember = new GoalRoomPendingMember(GoalRoomRole.LEADER, - LocalDateTime.now(), null, - member); - - // when - final boolean result = goalRoomPendingMember.isSameMember(member); - - // then - assertThat(result).isTrue(); - } - - @Test - void 입력받은_멤버가_자신과_다른_멤버이면_false를_반환한다() { - // given - final Member member1 = new Member(1L, new Identifier("identifier1"), - null, new EncryptedPassword(new Password("password1!")), - new Nickname("name1"), null, null); - final Member member2 = new Member(2L, new Identifier("identifier2"), - null, new EncryptedPassword(new Password("password2!")), - new Nickname("name2"), null, null); - - final GoalRoomPendingMember goalRoomPendingMember = new GoalRoomPendingMember(GoalRoomRole.LEADER, - LocalDateTime.now(), null, - member1); - - // when - final boolean result = goalRoomPendingMember.isSameMember(member2); - - // then - assertThat(result).isFalse(); - } - - @Test - void 팔로워가_리더로_변경된다() { - // given - final GoalRoomPendingMember goalRoomPendingMember = new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, - LocalDateTime.now(), null, - null); - - // when - goalRoomPendingMember.becomeLeader(); - - // then - assertThat(goalRoomPendingMember.isLeader()).isTrue(); - } -} diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapNodeImagesTest.java b/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapNodeImagesTest.java index d5aab01ae..12b46e1ee 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapNodeImagesTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/domain/roadmap/RoadmapNodeImagesTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import co.kirikiri.domain.ImageContentType; +import co.kirikiri.common.type.ImageContentType; import co.kirikiri.domain.roadmap.exception.RoadmapException; import java.util.List; import org.junit.jupiter.api.Test; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/controller/GoalRoomCreateApiTest.java b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/controller/GoalRoomCreateApiTest.java similarity index 54% rename from backend/kirikiri/src/test/java/co/kirikiri/controller/GoalRoomCreateApiTest.java rename to backend/kirikiri/src/test/java/co/kirikiri/goalroom/controller/GoalRoomCreateApiTest.java index 01b22f4ee..3e18c2aa0 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/controller/GoalRoomCreateApiTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/controller/GoalRoomCreateApiTest.java @@ -1,4 +1,4 @@ -package co.kirikiri.controller; +package co.kirikiri.goalroom.controller; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -7,7 +7,6 @@ import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.when; import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; @@ -16,25 +15,20 @@ import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; -import static org.springframework.restdocs.request.RequestDocumentation.partWithName; import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; -import static org.springframework.restdocs.request.RequestDocumentation.requestParts; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import co.kirikiri.controller.helper.ControllerTestHelper; -import co.kirikiri.controller.helper.FieldDescriptionHelper.FieldDescription; -import co.kirikiri.service.dto.ErrorResponse; -import co.kirikiri.service.dto.goalroom.request.GoalRoomCreateRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomRoadmapNodeRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomTodoRequest; -import co.kirikiri.service.dto.goalroom.response.GoalRoomToDoCheckResponse; -import co.kirikiri.service.exception.BadRequestException; -import co.kirikiri.service.exception.NotFoundException; -import co.kirikiri.service.goalroom.GoalRoomCreateService; -import co.kirikiri.service.goalroom.GoalRoomReadService; +import co.kirikiri.common.exception.BadRequestException; +import co.kirikiri.common.exception.NotFoundException; +import co.kirikiri.common.helper.ControllerTestHelper; +import co.kirikiri.common.helper.FieldDescriptionHelper.FieldDescription; +import co.kirikiri.common.service.dto.ErrorResponse; +import co.kirikiri.goalroom.service.GoalRoomCreateService; +import co.kirikiri.goalroom.service.GoalRoomReadService; +import co.kirikiri.goalroom.service.dto.request.GoalRoomCreateRequest; +import co.kirikiri.goalroom.service.dto.request.GoalRoomRoadmapNodeRequest; import com.fasterxml.jackson.core.type.TypeReference; import java.time.LocalDate; import java.util.ArrayList; @@ -44,8 +38,6 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; -import org.springframework.mock.web.MockMultipartFile; -import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.ResultMatcher; @@ -395,511 +387,7 @@ class GoalRoomCreateApiTest extends ControllerTestHelper { pathParameters(parameterWithName("goalRoomId").description("골룸 아이디")), responseFields(fieldWithPath("message").description("예외 메세지")))); } - - @Test - void 정상적으로_골룸에_투두리스트를_추가한다() throws Exception { - //given - final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest("content", TODAY, TEN_DAY_LATER); - final String jsonRequest = objectMapper.writeValueAsString(goalRoomTodoRequest); - given(goalRoomCreateService.addGoalRoomTodo(anyLong(), anyString(), any())) - .willReturn(1L); - - //when - final MvcResult mvcResult = mockMvc.perform(post(API_PREFIX + "/goal-rooms/{goalRoomId}/todos", 1L) - .content(jsonRequest) - .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") - .contentType(MediaType.APPLICATION_JSON) - .contextPath(API_PREFIX)) - .andExpect(status().isCreated()) - .andDo(print()) - .andDo(documentationResultHandler.document( - requestFields(makeFieldDescriptor(makeAddTodoSuccessRequestFieldDescription())), - requestHeaders(headerWithName(HttpHeaders.AUTHORIZATION).description("액세스 토큰")), - responseHeaders(headerWithName(HttpHeaders.LOCATION).description("골룸 투두 단일 조회 api 경로")), - pathParameters(parameterWithName("goalRoomId").description("골룸 아이디")))) - .andReturn(); - - //then - assertThat(mvcResult.getResponse().getHeader(HttpHeaders.LOCATION)).isEqualTo( - API_PREFIX + "/goal-rooms/1/todos/1"); - } - - @Test - void 골룸_투두_추가시_존재하지_않는_회원일_경우() throws Exception { - //given - final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest("content", TODAY, TEN_DAY_LATER); - final String jsonRequest = objectMapper.writeValueAsString(goalRoomTodoRequest); - doThrow(new NotFoundException("존재하지 않는 회원입니다.")) - .when(goalRoomCreateService) - .addGoalRoomTodo(anyLong(), anyString(), any()); - - //when - final MvcResult mvcResult = mockMvc.perform(post(API_PREFIX + "/goal-rooms/{goalRoomId}/todos", 1) - .content(jsonRequest) - .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") - .contentType(MediaType.APPLICATION_JSON) - .contextPath(API_PREFIX)) - .andExpect(status().isNotFound()) - .andDo(print()) - .andDo(documentationResultHandler.document( - requestFields(makeFieldDescriptor(makeAddTodoSuccessRequestFieldDescription())), - requestHeaders(headerWithName(AUTHORIZATION).description("액세스 토큰")), - pathParameters(parameterWithName("goalRoomId").description("골룸 아이디")), - responseFields(fieldWithPath("message").description("예외 메세지")))) - .andReturn(); - - //then - final ErrorResponse response = jsonToClass(mvcResult, new TypeReference<>() { - }); - assertThat(response).isEqualTo(new ErrorResponse("존재하지 않는 회원입니다.")); - } - - @Test - void 골룸_투두_추가시_존재하지_않는_골룸일_경우() throws Exception { - //given - final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest("content", TODAY, TEN_DAY_LATER); - final String jsonRequest = objectMapper.writeValueAsString(goalRoomTodoRequest); - doThrow(new NotFoundException("존재하지 않는 골룸입니다. goalRoomId = 1")) - .when(goalRoomCreateService) - .addGoalRoomTodo(anyLong(), anyString(), any()); - - //when - final MvcResult mvcResult = mockMvc.perform(post(API_PREFIX + "/goal-rooms/{goalRoomId}/todos", 1) - .content(jsonRequest) - .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") - .contentType(MediaType.APPLICATION_JSON) - .contextPath(API_PREFIX)) - .andExpect(status().isNotFound()) - .andDo(print()) - .andDo(documentationResultHandler.document( - requestFields(makeFieldDescriptor(makeAddTodoSuccessRequestFieldDescription())), - requestHeaders(headerWithName(AUTHORIZATION).description("액세스 토큰")), - pathParameters(parameterWithName("goalRoomId").description("골룸 아이디")), - responseFields(fieldWithPath("message").description("예외 메세지")))) - .andReturn(); - - //then - final ErrorResponse response = jsonToClass(mvcResult, new TypeReference<>() { - }); - assertThat(response).isEqualTo(new ErrorResponse("존재하지 않는 골룸입니다. goalRoomId = 1")); - } - - @Test - void 골룸_투두_추가시_이미_종료된_골룸일_경우() throws Exception { - //given - final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest("content", TODAY, TEN_DAY_LATER); - final String jsonRequest = objectMapper.writeValueAsString(goalRoomTodoRequest); - doThrow(new BadRequestException("이미 종료된 골룸입니다.")) - .when(goalRoomCreateService) - .addGoalRoomTodo(anyLong(), anyString(), any()); - - //when - final MvcResult mvcResult = mockMvc.perform(post(API_PREFIX + "/goal-rooms/{goalRoomId}/todos", 1L) - .content(jsonRequest) - .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") - .contentType(MediaType.APPLICATION_JSON) - .contextPath(API_PREFIX)) - .andExpect(status().isBadRequest()) - .andDo(print()) - .andDo(documentationResultHandler.document( - requestFields(makeFieldDescriptor(makeAddTodoSuccessRequestFieldDescription())), - requestHeaders(headerWithName(AUTHORIZATION).description("액세스 토큰")), - pathParameters(parameterWithName("goalRoomId").description("골룸 아이디")), - responseFields(fieldWithPath("message").description("예외 메세지")))) - .andReturn(); - - //then - final ErrorResponse response = jsonToClass(mvcResult, new TypeReference<>() { - }); - assertThat(response).isEqualTo(new ErrorResponse("이미 종료된 골룸입니다.")); - } - - @Test - void 골룸_투두_추가시_리더가_아닌_경우() throws Exception { - //given - final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest("content", TODAY, TEN_DAY_LATER); - final String jsonRequest = objectMapper.writeValueAsString(goalRoomTodoRequest); - doThrow(new BadRequestException("골룸의 리더만 투두리스트를 추가할 수 있습니다.")) - .when(goalRoomCreateService) - .addGoalRoomTodo(anyLong(), anyString(), any()); - - //when - final MvcResult mvcResult = mockMvc.perform(post(API_PREFIX + "/goal-rooms/{goalRoomId}/todos", 1L) - .content(jsonRequest) - .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") - .contentType(MediaType.APPLICATION_JSON) - .contextPath(API_PREFIX)) - .andExpect(status().isBadRequest()) - .andDo(print()) - .andDo(documentationResultHandler.document( - requestFields(makeFieldDescriptor(makeAddTodoSuccessRequestFieldDescription())), - requestHeaders(headerWithName(AUTHORIZATION).description("액세스 토큰")), - pathParameters(parameterWithName("goalRoomId").description("골룸 아이디")), - responseFields(fieldWithPath("message").description("예외 메세지")))) - .andReturn(); - - //then - final ErrorResponse response = jsonToClass(mvcResult, new TypeReference<>() { - }); - assertThat(response).isEqualTo(new ErrorResponse("골룸의 리더만 투두리스트를 추가할 수 있습니다.")); - } - - @Test - void 골룸_투두_추가시_컨텐츠가_250글자가_넘을_경우() throws Exception { - //given - final String content = "a".repeat(251); - final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest(content, TODAY, TEN_DAY_LATER); - final String jsonRequest = objectMapper.writeValueAsString(goalRoomTodoRequest); - doThrow(new BadRequestException("투두 컨텐츠의 길이가 적절하지 않습니다.")) - .when(goalRoomCreateService) - .addGoalRoomTodo(anyLong(), anyString(), any()); - - //when - final MvcResult mvcResult = mockMvc.perform(post(API_PREFIX + "/goal-rooms/{goalRoomId}/todos", 1L) - .content(jsonRequest) - .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") - .contentType(MediaType.APPLICATION_JSON) - .contextPath(API_PREFIX)) - .andExpect(status().isBadRequest()) - .andDo(print()) - .andDo(documentationResultHandler.document( - requestFields(makeFieldDescriptor(makeAddTodoSuccessRequestFieldDescription())), - requestHeaders(headerWithName(AUTHORIZATION).description("액세스 토큰")), - pathParameters(parameterWithName("goalRoomId").description("골룸 아이디")), - responseFields(fieldWithPath("message").description("예외 메세지")))) - .andReturn(); - - //then - final ErrorResponse response = jsonToClass(mvcResult, new TypeReference<>() { - }); - assertThat(response).isEqualTo(new ErrorResponse("투두 컨텐츠의 길이가 적절하지 않습니다.")); - } - - @Test - void 골룸_투두리스트에_대해_체크한다() throws Exception { - // given - final GoalRoomToDoCheckResponse expected = new GoalRoomToDoCheckResponse(true); - when(goalRoomCreateService.checkGoalRoomTodo(anyLong(), anyLong(), anyString())) - .thenReturn(expected); - - // when - final MvcResult mvcResult = mockMvc.perform(post(API_PREFIX + "/goal-rooms/{goalRoomId}/todos/{todoId}", 1L, 1L) - .header(AUTHORIZATION, String.format(BEARER_TOKEN_FORMAT, "test-token")) - .contextPath(API_PREFIX)) - .andExpect(status().isOk()) - .andDo( - documentationResultHandler.document( - requestHeaders( - headerWithName(AUTHORIZATION).description("액세스 토큰")), - pathParameters( - parameterWithName("goalRoomId").description("골룸 아이디"), - parameterWithName("todoId").description("골룸 투두 아이디")), - responseFields( - fieldWithPath("isChecked").description( - "투두 체크 현황 (true: 체크됨, false: 체크되지 않음)")))) - .andReturn(); - - // then - final GoalRoomToDoCheckResponse response = jsonToClass(mvcResult, new TypeReference<>() { - }); - - assertThat(response) - .isEqualTo(expected); - } - - @Test - void 골룸_투두리스트_체크시_체크_이력이_있으면_제거한다() throws Exception { - // given - final GoalRoomToDoCheckResponse expected = new GoalRoomToDoCheckResponse(false); - when(goalRoomCreateService.checkGoalRoomTodo(anyLong(), anyLong(), anyString())) - .thenReturn(expected); - - // when - final MvcResult mvcResult = mockMvc.perform(post(API_PREFIX + "/goal-rooms/{goalRoomId}/todos/{todoId}", 1L, 1L) - .header(AUTHORIZATION, String.format(BEARER_TOKEN_FORMAT, "test-token")) - .contextPath(API_PREFIX)) - .andExpect(status().isOk()) - .andDo( - documentationResultHandler.document( - requestHeaders( - headerWithName(AUTHORIZATION).description("액세스 토큰")), - pathParameters( - parameterWithName("goalRoomId").description("골룸 아이디"), - parameterWithName("todoId").description("골룸 투두 아이디")), - responseFields( - fieldWithPath("isChecked").description( - "투두 체크 현황 (true: 체크됨, false: 체크되지 않음)")))) - .andReturn(); - - // then - final GoalRoomToDoCheckResponse response = jsonToClass(mvcResult, new TypeReference<>() { - }); - - assertThat(response) - .isEqualTo(expected); - } - - @Test - void 골룸_투두리스트_체크시_골룸이_존재하지_않으면_예외가_발생한다() throws Exception { - //given - doThrow(new NotFoundException("골룸이 존재하지 않습니다. goalRoomId = 1")) - .when(goalRoomCreateService) - .checkGoalRoomTodo(anyLong(), anyLong(), anyString()); - - //when - final MvcResult mvcResult = mockMvc.perform(post(API_PREFIX + "/goal-rooms/{goalRoomId}/todos/{todoId}", 1L, 1L) - .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") - .contentType(MediaType.APPLICATION_JSON) - .contextPath(API_PREFIX)) - .andExpect(status().isNotFound()) - .andDo(print()) - .andDo(documentationResultHandler.document( - requestHeaders(headerWithName(AUTHORIZATION).description("액세스 토큰")), - pathParameters( - parameterWithName("goalRoomId").description("골룸 아이디"), - parameterWithName("todoId").description("골룸 투두 아이디")), - responseFields(fieldWithPath("message").description("예외 메세지")))) - .andReturn(); - - //then - final ErrorResponse response = jsonToClass(mvcResult, new TypeReference<>() { - }); - assertThat(response).isEqualTo(new ErrorResponse("골룸이 존재하지 않습니다. goalRoomId = 1")); - } - - @Test - void 골룸_투두리스트_체크시_해당_투두가_존재하지_않으면_예외가_발생한다() throws Exception { - //given - doThrow(new NotFoundException("존재하지 않는 투두입니다. todoId = 1")) - .when(goalRoomCreateService) - .checkGoalRoomTodo(anyLong(), anyLong(), anyString()); - - //when - final MvcResult mvcResult = mockMvc.perform(post(API_PREFIX + "/goal-rooms/{goalRoomId}/todos/{todoId}", 1L, 1L) - .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") - .contentType(MediaType.APPLICATION_JSON) - .contextPath(API_PREFIX)) - .andExpect(status().isNotFound()) - .andDo(print()) - .andDo(documentationResultHandler.document( - requestHeaders( - headerWithName(AUTHORIZATION).description("액세스 토큰")), - pathParameters( - parameterWithName("goalRoomId").description("골룸 아이디"), - parameterWithName("todoId").description("골룸 투두 아이디")), - responseFields( - fieldWithPath("message").description("예외 메세지")))) - .andReturn(); - - //then - final ErrorResponse response = jsonToClass(mvcResult, new TypeReference<>() { - }); - assertThat(response) - .isEqualTo(new ErrorResponse("존재하지 않는 투두입니다. todoId = 1")); - } - - @Test - void 골룸_투두리스트_체크시_사용자가_없으면_예외가_발생한다() throws Exception { - //given - doThrow(new NotFoundException("골룸에 사용자가 존재하지 않습니다. goalRoomId = 1 memberIdentifier = cokirikiri")) - .when(goalRoomCreateService) - .checkGoalRoomTodo(anyLong(), anyLong(), anyString()); - - //when - final MvcResult mvcResult = mockMvc.perform(post(API_PREFIX + "/goal-rooms/{goalRoomId}/todos/{todoId}", 1L, 1L) - .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") - .contentType(MediaType.APPLICATION_JSON) - .contextPath(API_PREFIX)) - .andExpect(status().isNotFound()) - .andDo(print()) - .andDo(documentationResultHandler.document( - requestHeaders( - headerWithName(AUTHORIZATION).description("액세스 토큰")), - pathParameters( - parameterWithName("goalRoomId").description("골룸 아이디"), - parameterWithName("todoId").description("골룸 투두 아이디")), - responseFields( - fieldWithPath("message").description("예외 메세지")))) - .andReturn(); - - //then - final ErrorResponse response = jsonToClass(mvcResult, new TypeReference<>() { - }); - assertThat(response) - .isEqualTo(new ErrorResponse("골룸에 사용자가 존재하지 않습니다. goalRoomId = 1 memberIdentifier = cokirikiri")); - } - - @Test - void 인증_피드_등록_요청을_보낸다() throws Exception { - //given - final String imageName = "image"; - final String originalImageName = "originalImageName.jpeg"; - final String contentType = "image/jpeg"; - final String image = "테스트 이미지"; - final String description = "이미지 설명"; - final String filePath = "path/to/directories/" + contentType; - final MockMultipartFile imageFile = new MockMultipartFile(imageName, originalImageName, - contentType, image.getBytes()); - - given(goalRoomCreateService.createCheckFeed(anyString(), anyLong(), any())) - .willReturn(filePath); - - //expect - mockMvc.perform( - RestDocumentationRequestBuilders - .multipart(API_PREFIX + "/goal-rooms/{goalRoomId}/checkFeeds", 1L) - .file(imageFile) - .file("text", description.getBytes()) - .header("Authorization", "Bearer accessToken") - .contextPath(API_PREFIX) - .contentType(MediaType.MULTIPART_FORM_DATA_VALUE)) - .andExpect(status().isCreated()) - .andExpect(header().string("Location", filePath)) - .andDo( - documentationResultHandler.document( - requestHeaders( - headerWithName("Authorization").description("액세스 토큰") - ), - pathParameters( - parameterWithName("goalRoomId").description("골룸 아이디") - ), - requestParts( - partWithName("image").description("업로드한 이미지"), - partWithName("text").description("인증 피드 본문") - ), - responseHeaders( - headerWithName("Location").description("저장된 이미지 경로") - ))); - } - - @Test - void 인증_피드_등록시_노드_기간에_해당하지_않으면_예외가_발생한다() throws Exception { - // given - final String imageName = "image"; - final String originalImageName = "originalImageName.jpeg"; - final String contentType = "image/jpeg"; - final String image = "테스트 이미지"; - final String description = "이미지 설명"; - final MockMultipartFile imageFile = new MockMultipartFile(imageName, originalImageName, - contentType, image.getBytes()); - - doThrow(new BadRequestException("인증 피드는 노드 기간 내에만 작성할 수 있습니다.")) - .when(goalRoomCreateService) - .createCheckFeed(anyString(), anyLong(), any()); - - //when - mockMvc.perform( - RestDocumentationRequestBuilders - .multipart(API_PREFIX + "/goal-rooms/{goalRoomId}/checkFeeds", 1L) - .file(imageFile) - .param("description", description) - .header("Authorization", "Bearer accessToken") - .contextPath(API_PREFIX) - .contentType(MediaType.MULTIPART_FORM_DATA_VALUE)) - .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.message").value("인증 피드는 노드 기간 내에만 작성할 수 있습니다.")) - .andDo( - documentationResultHandler.document( - requestHeaders( - headerWithName("Authorization").description("액세스 토큰") - ), - pathParameters( - parameterWithName("goalRoomId").description("골룸 아이디") - ), - requestParts( - partWithName("image").description("업로드한 이미지") - ), - responseFields( - fieldWithPath("message").description("예외 메세지") - ))); - } - - @Test - void 인증_피드_등록_요청시_멤버가_존재하지_않을_경우_예외를_반환한다() throws Exception { - //given - final String imageName = "image"; - final String originalImageName = "originalImageName.jpeg"; - final String contentType = "image/jpeg"; - final String image = "테스트 이미지"; - final String description = "이미지 설명"; - final MockMultipartFile imageFile = new MockMultipartFile(imageName, originalImageName, - contentType, image.getBytes()); - - doThrow(new NotFoundException("존재하지 않는 회원입니다.")) - .when(goalRoomCreateService) - .createCheckFeed(anyString(), anyLong(), any()); - - //when - mockMvc.perform( - RestDocumentationRequestBuilders - .multipart(API_PREFIX + "/goal-rooms/{goalRoomId}/checkFeeds", 1L) - .file(imageFile) - .file("text", description.getBytes()) - .header("Authorization", "Bearer accessToken") - .contextPath(API_PREFIX) - .contentType(MediaType.MULTIPART_FORM_DATA_VALUE)) - .andExpect(status().isNotFound()) - .andExpect(jsonPath("$.message").value("존재하지 않는 회원입니다.")) - .andDo( - documentationResultHandler.document( - requestHeaders( - headerWithName("Authorization").description("액세스 토큰") - ), - pathParameters( - parameterWithName("goalRoomId").description("골룸 아이디") - ), - requestParts( - partWithName("image").description("업로드한 이미지"), - partWithName("text").description("인증 피드 본문") - ), - responseFields( - fieldWithPath("message").description("예외 메세지") - ))); - } - - @Test - void 인증_피드_등록_요청시_로드맵이_존재하지_않을_경우_예외를_반환한다() throws Exception { - //given - final String imageName = "image"; - final String originalImageName = "originalImageName.jpeg"; - final String contentType = "image/jpeg"; - final String image = "테스트 이미지"; - final String description = "이미지 설명"; - final MockMultipartFile imageFile = new MockMultipartFile(imageName, originalImageName, - contentType, image.getBytes()); - - doThrow(new NotFoundException("골룸 정보가 존재하지 않습니다. goalRoomId = 1L")) - .when(goalRoomCreateService) - .createCheckFeed(anyString(), anyLong(), any()); - - //when - mockMvc.perform( - RestDocumentationRequestBuilders - .multipart(API_PREFIX + "/goal-rooms/{goalRoomId}/checkFeeds", 1L) - .file(imageFile) - .file("text", description.getBytes()) - .header("Authorization", "Bearer accessToken") - .contextPath(API_PREFIX) - .contentType(MediaType.MULTIPART_FORM_DATA_VALUE)) - .andExpect(status().isNotFound()) - .andExpect(jsonPath("$.message").value("골룸 정보가 존재하지 않습니다. goalRoomId = 1L")) - .andDo( - documentationResultHandler.document( - requestHeaders( - headerWithName("Authorization").description("액세스 토큰") - ), - pathParameters( - parameterWithName("goalRoomId").description("골룸 아이디") - ), - requestParts( - partWithName("image").description("업로드한 이미지"), - partWithName("text").description("인증 피드 본문") - ), - responseFields( - fieldWithPath("message").description("예외 메세지") - ))); - } - + @Test void 정상적으로_골룸을_나간다() throws Exception { // given @@ -1212,12 +700,4 @@ private List makeCreateGoalRoomSuccessRequestFieldDescription( new FieldDescription("goalRoomRoadmapNodeRequests[].endDate", "골룸 노드의 종료일", "- yyyyMMdd 형식") ); } - - private List makeAddTodoSuccessRequestFieldDescription() { - return List.of( - new FieldDescription("content", "골룸 투두 컨텐츠", "- 길이 : 1 ~ 250"), - new FieldDescription("startDate", "골룸 투두 시작일", "- yyyyMMdd 형식"), - new FieldDescription("endDate", "골룸 투두 종료일", "- yyyyMMdd 형식") - ); - } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/controller/GoalRoomReadApiTest.java b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/controller/GoalRoomReadApiTest.java similarity index 72% rename from backend/kirikiri/src/test/java/co/kirikiri/controller/GoalRoomReadApiTest.java rename to backend/kirikiri/src/test/java/co/kirikiri/goalroom/controller/GoalRoomReadApiTest.java index 1ad346fbb..4571b9f0d 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/controller/GoalRoomReadApiTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/controller/GoalRoomReadApiTest.java @@ -1,6 +1,6 @@ -package co.kirikiri.controller; +package co.kirikiri.goalroom.controller; -import static co.kirikiri.service.dto.goalroom.GoalRoomMemberSortTypeDto.ACCOMPLISHMENT_RATE; +import static co.kirikiri.goalroom.service.dto.GoalRoomMemberSortTypeDto.ACCOMPLISHMENT_RATE; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; @@ -18,28 +18,26 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import co.kirikiri.controller.helper.ControllerTestHelper; -import co.kirikiri.domain.goalroom.GoalRoomStatus; -import co.kirikiri.service.dto.ErrorResponse; -import co.kirikiri.service.dto.goalroom.request.GoalRoomStatusTypeRequest; -import co.kirikiri.service.dto.goalroom.response.CheckFeedResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomCertifiedResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomCheckFeedResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomMemberResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomRoadmapNodeDetailResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomRoadmapNodeResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomRoadmapNodesResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomToDoCheckResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomTodoResponse; -import co.kirikiri.service.dto.member.response.MemberGoalRoomForListResponse; -import co.kirikiri.service.dto.member.response.MemberGoalRoomResponse; -import co.kirikiri.service.dto.member.response.MemberResponse; -import co.kirikiri.service.exception.BadRequestException; -import co.kirikiri.service.exception.ForbiddenException; -import co.kirikiri.service.exception.NotFoundException; -import co.kirikiri.service.goalroom.GoalRoomCreateService; -import co.kirikiri.service.goalroom.GoalRoomReadService; +import co.kirikiri.common.exception.ForbiddenException; +import co.kirikiri.common.exception.NotFoundException; +import co.kirikiri.common.helper.ControllerTestHelper; +import co.kirikiri.common.service.dto.ErrorResponse; +import co.kirikiri.goalroom.domain.GoalRoomStatus; +import co.kirikiri.goalroom.service.GoalRoomCreateService; +import co.kirikiri.goalroom.service.GoalRoomReadService; +import co.kirikiri.goalroom.service.dto.request.GoalRoomStatusTypeRequest; +import co.kirikiri.goalroom.service.dto.response.DashBoardCheckFeedResponse; +import co.kirikiri.goalroom.service.dto.response.DashBoardToDoCheckResponse; +import co.kirikiri.goalroom.service.dto.response.DashBoardToDoResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomCertifiedResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomMemberResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomRoadmapNodeDetailResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomRoadmapNodeResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomRoadmapNodesResponse; +import co.kirikiri.goalroom.service.dto.response.MemberGoalRoomForListResponse; +import co.kirikiri.goalroom.service.dto.response.MemberGoalRoomResponse; +import co.kirikiri.goalroom.service.dto.response.MemberResponse; import com.fasterxml.jackson.core.type.TypeReference; import java.time.LocalDate; import java.time.LocalDateTime; @@ -430,108 +428,6 @@ class GoalRoomReadApiTest extends ControllerTestHelper { assertThat(responses).isEqualTo(new ErrorResponse("존재하지 않는 골룸입니다. goalRoomId = 1")); } - @Test - void 골룸의_투두리스트를_조회한다() throws Exception { - // given - final LocalDate today = LocalDate.now(); - final List goalRoomTodoResponses = List.of( - new GoalRoomTodoResponse(1L, "투두 1", today, today.plusDays(10), new GoalRoomToDoCheckResponse(true)), - new GoalRoomTodoResponse(2L, "투두 2", today.plusDays(20), today.plusDays(30), - new GoalRoomToDoCheckResponse(false))); - - when(goalRoomReadService.findAllGoalRoomTodo(any(), any())) - .thenReturn(goalRoomTodoResponses); - - // when - final MvcResult mvcResult = mockMvc.perform(get(API_PREFIX + "/goal-rooms/{goalRoomId}/todos", 1L) - .header(AUTHORIZATION, String.format(BEARER_TOKEN_FORMAT, "test-token")) - .contextPath(API_PREFIX)) - .andExpect(status().isOk()) - .andDo( - documentationResultHandler.document( - requestHeaders( - headerWithName(AUTHORIZATION).description("액세스 토큰") - ), - pathParameters( - parameterWithName("goalRoomId").description("골룸 아이디") - ), - responseFields( - fieldWithPath("[0].id").description("투두 아이디"), - fieldWithPath("[0].content").description("투두 내용"), - fieldWithPath("[0].startDate").description("투두 시작 날짜"), - fieldWithPath("[0].endDate").description("투두 종료 날짜"), - fieldWithPath("[0].check.isChecked").description("투두 체크 여부") - ))) - .andReturn(); - - // then - final List response = jsonToClass(mvcResult, new TypeReference<>() { - }); - - assertThat(response) - .isEqualTo(goalRoomTodoResponses); - } - - @Test - void 골룸_투두리스트_조회시_존재하지_않은_골룸일_경우() throws Exception { - // given - doThrow(new NotFoundException("존재하지 않는 골룸입니다. goalRoomId = 1")) - .when(goalRoomReadService) - .findAllGoalRoomTodo(any(), any()); - - // when - final MvcResult mvcResult = mockMvc.perform(get(API_PREFIX + "/goal-rooms/{goalRoomId}/todos", 1L) - .header(AUTHORIZATION, String.format(BEARER_TOKEN_FORMAT, "test-token")) - .contextPath(API_PREFIX)) - .andExpect(status().isNotFound()) - .andDo( - documentationResultHandler.document( - pathParameters( - parameterWithName("goalRoomId").description("골룸 아이디") - ), - responseFields( - fieldWithPath("message").description("예외 메세지") - ))) - .andReturn(); - - // then - final ErrorResponse responses = jsonToClass(mvcResult, new TypeReference<>() { - }); - - assertThat(responses) - .isEqualTo(new ErrorResponse("존재하지 않는 골룸입니다. goalRoomId = 1")); - } - - @Test - void 골룸_투두리스트_조회시_참여하지_않은_사용자일_경우() throws Exception { - // given - doThrow(new ForbiddenException("골룸에 참여하지 않은 사용자입니다. goalRoomId = 1 memberIdentifier = identifier")) - .when(goalRoomReadService) - .findAllGoalRoomTodo(any(), any()); - - // when - final MvcResult mvcResult = mockMvc.perform(get(API_PREFIX + "/goal-rooms/{goalRoomId}/todos", 1L) - .header(AUTHORIZATION, String.format(BEARER_TOKEN_FORMAT, "test-token")) - .contextPath(API_PREFIX)) - .andExpect(status().isForbidden()) - .andDo( - documentationResultHandler.document( - pathParameters( - parameterWithName("goalRoomId").description("골룸 아이디") - ), - responseFields( - fieldWithPath("message").description("예외 메세지") - ))) - .andReturn(); - - // then - final ErrorResponse responses = jsonToClass(mvcResult, new TypeReference<>() { - }); - - assertThat(responses) - .isEqualTo(new ErrorResponse("골룸에 참여하지 않은 사용자입니다. goalRoomId = 1 memberIdentifier = identifier")); - } - @Test void 골룸의_노드를_조회한다() throws Exception { // given @@ -637,113 +533,6 @@ class GoalRoomReadApiTest extends ControllerTestHelper { .isEqualTo(new ErrorResponse("골룸에 참여하지 않은 사용자입니다. goalRoomId = 1 memberIdentifier = identifier")); } - @Test - void 골룸의_인증피드를_전체_조회한다() throws Exception { - // given - final GoalRoomCheckFeedResponse goalRoomCheckFeedResponse1 = new GoalRoomCheckFeedResponse( - new MemberResponse(1L, "name1", "imageUrl"), - new CheckFeedResponse(1L, "imageUrl", "image description1", LocalDate.now())); - final GoalRoomCheckFeedResponse goalRoomCheckFeedResponse2 = new GoalRoomCheckFeedResponse( - new MemberResponse(2L, "name2", "imageUrl"), - new CheckFeedResponse(2L, "imageUrl", "image description2", LocalDate.now())); - - final List expected = List.of(goalRoomCheckFeedResponse2, - goalRoomCheckFeedResponse1); - - when(goalRoomReadService.findGoalRoomCheckFeeds(any(), any())) - .thenReturn(expected); - - // when - final String response = mockMvc.perform( - get(API_PREFIX + "/goal-rooms/{goalRoomId}/checkFeeds", 1L) - .header(AUTHORIZATION, String.format(BEARER_TOKEN_FORMAT, "test-token")) - .contextPath(API_PREFIX)) - .andExpect(status().isOk()) - .andDo( - documentationResultHandler.document( - requestHeaders( - headerWithName(AUTHORIZATION).description("액세스 토큰") - ), - pathParameters( - parameterWithName("goalRoomId").description("골룸 아이디") - ), - responseFields( - fieldWithPath("[0].member.id").description("사용자 ID"), - fieldWithPath("[0].member.name").description("사용자 닉네임"), - fieldWithPath("[0].member.imageUrl").description("사용자 이미지 Url"), - fieldWithPath("[0].checkFeed.id").description("인증 피드 ID"), - fieldWithPath("[0].checkFeed.imageUrl").description("인증 피드 이미지 Url"), - fieldWithPath("[0].checkFeed.description").description("인증 피드 설명"), - fieldWithPath("[0].checkFeed.createdAt").description("인증 피드 등록 날짜")))) - .andReturn().getResponse() - .getContentAsString(); - - // then - final List 골룸_인증피드_전체_조회_응답 = objectMapper.readValue(response, - new TypeReference<>() { - }); - assertThat(골룸_인증피드_전체_조회_응답) - .isEqualTo(expected); - } - - @Test - void 골룸_인증피드_전체_조회_시_존재하지_않는_골룸일_경우_예외가_발생한다() throws Exception { - //given - doThrow(new NotFoundException("존재하지 않는 골룸입니다. goalRoomId = 1")) - .when(goalRoomReadService) - .findGoalRoomCheckFeeds(any(), any()); - - //when - final MvcResult mvcResult = mockMvc.perform(get(API_PREFIX + "/goal-rooms/{goalRoomId}/checkFeeds", 1L) - .header(AUTHORIZATION, String.format(BEARER_TOKEN_FORMAT, "test-token")) - .contextPath(API_PREFIX)) - .andExpect(status().isNotFound()) - .andDo( - documentationResultHandler.document( - pathParameters( - parameterWithName("goalRoomId").description("골룸 아이디") - ), - responseFields( - fieldWithPath("message").description("예외 메세지") - ))) - .andReturn(); - - // then - final ErrorResponse responses = jsonToClass(mvcResult, new TypeReference<>() { - }); - - assertThat(responses).isEqualTo(new ErrorResponse("존재하지 않는 골룸입니다. goalRoomId = 1")); - } - - @Test - void 골룸_인증피드_전체_조회_시_골룸에_참여하지_않은_사용자일_경우_예외_발생() throws Exception { - //given - doThrow(new BadRequestException("골룸에 참여하지 않은 회원입니다.")) - .when(goalRoomReadService) - .findGoalRoomCheckFeeds(any(), any()); - - //when - final MvcResult mvcResult = mockMvc.perform(get(API_PREFIX + "/goal-rooms/{goalRoomId}/checkFeeds", 1L) - .header(AUTHORIZATION, String.format(BEARER_TOKEN_FORMAT, "test-token")) - .contextPath(API_PREFIX)) - .andExpect(status().isBadRequest()) - .andDo( - documentationResultHandler.document( - pathParameters( - parameterWithName("goalRoomId").description("골룸 아이디") - ), - responseFields( - fieldWithPath("message").description("예외 메세지") - ))) - .andReturn(); - - // then - final ErrorResponse responses = jsonToClass(mvcResult, new TypeReference<>() { - }); - - assertThat(responses).isEqualTo(new ErrorResponse("골룸에 참여하지 않은 회원입니다.")); - } - private GoalRoomResponse 골룸_조회_응답을_생성한다() { final List goalRoomNodeResponses = List.of( new GoalRoomRoadmapNodeResponse(1L, "로드맵 1주차", LocalDate.of(2023, 7, 19), @@ -771,13 +560,13 @@ class GoalRoomReadApiTest extends ControllerTestHelper { LocalDate.of(2023, 1, 31), 15), new GoalRoomRoadmapNodeResponse(2L, "두번째 골룸 노드 제목", LocalDate.of(2023, 2, 1), LocalDate.of(2023, 2, 28), 14))), - List.of(new GoalRoomTodoResponse(1L, "첫 번째 할일", + List.of(new DashBoardToDoResponse(1L, "첫 번째 할일", LocalDate.of(2023, 1, 15), LocalDate.of(2023, 1, 31), - new GoalRoomToDoCheckResponse(false))), - List.of(new CheckFeedResponse(1L, "imageUrl1", "인증 피드 설명 1", LocalDate.now()), - new CheckFeedResponse(2L, "imageUrl2", "인증 피드 설명 2", LocalDate.now()), - new CheckFeedResponse(3L, "imageUrl3", "인증 피드 설명 3", LocalDate.now()), - new CheckFeedResponse(4L, "imageUrl4", "인증 피드 설명 4", LocalDate.now()))); + new DashBoardToDoCheckResponse(false))), + List.of(new DashBoardCheckFeedResponse(1L, "imageUrl1", "인증 피드 설명 1", LocalDate.now()), + new DashBoardCheckFeedResponse(2L, "imageUrl2", "인증 피드 설명 2", LocalDate.now()), + new DashBoardCheckFeedResponse(3L, "imageUrl3", "인증 피드 설명 3", LocalDate.now()), + new DashBoardCheckFeedResponse(4L, "imageUrl4", "인증 피드 설명 4", LocalDate.now()))); } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomMemberTest.java b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/GoalRoomMemberTest.java similarity index 60% rename from backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomMemberTest.java rename to backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/GoalRoomMemberTest.java index ba9af7109..76decf520 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomMemberTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/GoalRoomMemberTest.java @@ -1,14 +1,9 @@ -package co.kirikiri.domain.goalroom; +package co.kirikiri.goalroom.domain; import static org.assertj.core.api.Assertions.assertThat; -import co.kirikiri.domain.member.EncryptedPassword; -import co.kirikiri.domain.member.Member; -import co.kirikiri.domain.member.vo.Identifier; -import co.kirikiri.domain.member.vo.Nickname; -import co.kirikiri.domain.member.vo.Password; -import org.junit.jupiter.api.Test; import java.time.LocalDateTime; +import org.junit.jupiter.api.Test; class GoalRoomMemberTest { @@ -40,14 +35,10 @@ class GoalRoomMemberTest { @Test void 입력받은_멤버가_자신과_같은_멤버이면_true를_반환한다() { // given - final Member member = new Member(new Identifier("identifier"), - new EncryptedPassword(new Password("password1!")), - new Nickname("name"), null, null); - final GoalRoomMember goalRoomMember = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), null, - member); + final GoalRoomMember goalRoomMember = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), null, 1L); // when - final boolean result = goalRoomMember.isSameMember(member); + final boolean result = goalRoomMember.isSameMember(1L); // then assertThat(result).isTrue(); @@ -56,18 +47,10 @@ class GoalRoomMemberTest { @Test void 입력받은_멤버가_자신과_다른_멤버이면_false를_반환한다() { // given - final Member member1 = new Member(1L, new Identifier("identifier1"), - null, new EncryptedPassword(new Password("password1!")), - new Nickname("name1"), null, null); - final Member member2 = new Member(2L, new Identifier("identifier2"), - null, new EncryptedPassword(new Password("password2!")), - new Nickname("name2"), null, null); - - final GoalRoomMember goalRoomMember = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), null, - member1); + final GoalRoomMember goalRoomMember = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), null, 1L); // when - final boolean result = goalRoomMember.isSameMember(member2); + final boolean result = goalRoomMember.isSameMember(2L); // then assertThat(result).isFalse(); diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomMembersTest.java b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/GoalRoomMembersTest.java similarity index 62% rename from backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomMembersTest.java rename to backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/GoalRoomMembersTest.java index eb9dbc68f..1e9b0d230 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomMembersTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/GoalRoomMembersTest.java @@ -1,37 +1,23 @@ -package co.kirikiri.domain.goalroom; +package co.kirikiri.goalroom.domain; import static org.assertj.core.api.Assertions.assertThat; -import co.kirikiri.domain.member.EncryptedPassword; -import co.kirikiri.domain.member.Member; -import co.kirikiri.domain.member.vo.Identifier; -import co.kirikiri.domain.member.vo.Nickname; -import co.kirikiri.domain.member.vo.Password; -import org.junit.jupiter.api.Test; import java.time.LocalDateTime; import java.util.List; +import org.junit.jupiter.api.Test; class GoalRoomMembersTest { - private static final Member MEMBER1 = new Member(1L, new Identifier("identifier1"), - null, new EncryptedPassword(new Password("password1!")), - new Nickname("name1"), null, null); - private static final Member MEMBER2 = new Member(2L, new Identifier("identifier2"), - null, new EncryptedPassword(new Password("password2!")), - new Nickname("name2"), null, null); - @Test void 입력받은_사용자를_골룸_사용자_중에서_찾는다() { // given - final GoalRoomMember goalRoomMember1 = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), null, - MEMBER1); - final GoalRoomMember goalRoomMember2 = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), null, - MEMBER2); + final GoalRoomMember goalRoomMember1 = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), null, 1L); + final GoalRoomMember goalRoomMember2 = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), null, 2L); final GoalRoomMembers goalRoomMembers = new GoalRoomMembers(List.of(goalRoomMember1, goalRoomMember2)); // when - final GoalRoomMember findGoalRoomMember = goalRoomMembers.findByMember(MEMBER1).get(); + final GoalRoomMember findGoalRoomMember = goalRoomMembers.findByMemberId(1L).get(); // then assertThat(findGoalRoomMember).isEqualTo(goalRoomMember1); @@ -40,10 +26,8 @@ null, new EncryptedPassword(new Password("password2!")), @Test void 다음_리더가_될_사용자를_찾는다() { // given - final GoalRoomMember goalRoomMember1 = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), null, - MEMBER1); - final GoalRoomMember goalRoomMember2 = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), null, - MEMBER2); + final GoalRoomMember goalRoomMember1 = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), null, 1L); + final GoalRoomMember goalRoomMember2 = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), null, 2L); final GoalRoomMembers goalRoomMembers = new GoalRoomMembers(List.of(goalRoomMember1, goalRoomMember2)); @@ -57,10 +41,8 @@ null, new EncryptedPassword(new Password("password2!")), @Test void 골룸_사용자의_수를_구한다() { // given - final GoalRoomMember goalRoomMember1 = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), null, - MEMBER1); - final GoalRoomMember goalRoomMember2 = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), null, - MEMBER2); + final GoalRoomMember goalRoomMember1 = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), null, 1L); + final GoalRoomMember goalRoomMember2 = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), null, 2L); final GoalRoomMembers goalRoomMembers = new GoalRoomMembers(List.of(goalRoomMember1, goalRoomMember2)); @@ -74,10 +56,8 @@ null, new EncryptedPassword(new Password("password2!")), @Test void 골룸_사용자에서_입렵받은_사용자를_제거한다() { // given - final GoalRoomMember goalRoomMember1 = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), null, - MEMBER1); - final GoalRoomMember goalRoomMember2 = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), null, - MEMBER2); + final GoalRoomMember goalRoomMember1 = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), null, 1L); + final GoalRoomMember goalRoomMember2 = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), null, 2L); final GoalRoomMembers goalRoomMembers = new GoalRoomMembers(List.of(goalRoomMember1, goalRoomMember2)); diff --git a/backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/GoalRoomPendingMemberTest.java b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/GoalRoomPendingMemberTest.java new file mode 100644 index 000000000..9bba5a68e --- /dev/null +++ b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/GoalRoomPendingMemberTest.java @@ -0,0 +1,76 @@ +package co.kirikiri.goalroom.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import co.kirikiri.goalroom.domain.vo.GoalRoomName; +import co.kirikiri.goalroom.domain.vo.LimitedMemberCount; +import java.time.LocalDateTime; +import org.junit.jupiter.api.Test; + +class GoalRoomPendingMemberTest { + + @Test + void 골룸의_리더이면_True를_반환한다() { + // given + final GoalRoom goalRoom = new GoalRoom(1L, new GoalRoomName("goalroom"), new LimitedMemberCount(10), 1L, 1L); + + // when + final GoalRoomPendingMember goalRoomPendingMember = new GoalRoomPendingMember(1L, GoalRoomRole.LEADER, null, + goalRoom, 1L); + + // then + assertThat(goalRoomPendingMember.isLeader()).isTrue(); + } + + @Test + void 골룸의_리더가_아니면_false를_반환한다() { + // given + final GoalRoom goalRoom = new GoalRoom(new GoalRoomName("goalroom"), new LimitedMemberCount(10), 1L, 1L); + + // when + final GoalRoomPendingMember goalRoomPendingMember = new GoalRoomPendingMember(2L, GoalRoomRole.FOLLOWER, null, + goalRoom, 2L); + + // then + assertThat(goalRoomPendingMember.isLeader()).isFalse(); + } + + @Test + void 입력받은_멤버가_자신과_같은_멤버이면_true를_반환한다() { + // given + final GoalRoomPendingMember goalRoomPendingMember = new GoalRoomPendingMember(1L, GoalRoomRole.LEADER, + LocalDateTime.now(), null, 1L); + + // when + final boolean result = goalRoomPendingMember.isSameMember(1L); + + // then + assertThat(result).isTrue(); + } + + @Test + void 입력받은_멤버가_자신과_다른_멤버이면_false를_반환한다() { + // given + final GoalRoomPendingMember goalRoomPendingMember = new GoalRoomPendingMember(1L, GoalRoomRole.LEADER, + LocalDateTime.now(), null, 1L); + + // when + final boolean result = goalRoomPendingMember.isSameMember(2L); + + // then + assertThat(result).isFalse(); + } + + @Test + void 팔로워가_리더로_변경된다() { + // given + final GoalRoomPendingMember goalRoomPendingMember = new GoalRoomPendingMember(1L, GoalRoomRole.FOLLOWER, + LocalDateTime.now(), null, null); + + // when + goalRoomPendingMember.becomeLeader(); + + // then + assertThat(goalRoomPendingMember.isLeader()).isTrue(); + } +} diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomPendingMembersTest.java b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/GoalRoomPendingMembersTest.java similarity index 56% rename from backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomPendingMembersTest.java rename to backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/GoalRoomPendingMembersTest.java index bcb18de45..7b02b5774 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomPendingMembersTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/GoalRoomPendingMembersTest.java @@ -1,76 +1,61 @@ -package co.kirikiri.domain.goalroom; +package co.kirikiri.goalroom.domain; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import co.kirikiri.domain.exception.UnexpectedDomainException; -import co.kirikiri.domain.goalroom.vo.GoalRoomName; -import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; -import co.kirikiri.domain.member.EncryptedPassword; -import co.kirikiri.domain.member.Member; -import co.kirikiri.domain.member.vo.Identifier; -import co.kirikiri.domain.member.vo.Nickname; -import co.kirikiri.domain.member.vo.Password; -import co.kirikiri.domain.roadmap.RoadmapContent; +import co.kirikiri.common.exception.UnexpectedDomainException; +import co.kirikiri.goalroom.domain.vo.GoalRoomName; +import co.kirikiri.goalroom.domain.vo.LimitedMemberCount; import java.time.LocalDateTime; import java.util.List; import org.junit.jupiter.api.Test; class GoalRoomPendingMembersTest { - private static final Member MEMBER1 = new Member(1L, new Identifier("identifier1"), - null, new EncryptedPassword(new Password("password1!")), - new Nickname("name1"), null, null); - private static final Member MEMBER2 = new Member(2L, new Identifier("identifier2"), - null, new EncryptedPassword(new Password("password2!")), - new Nickname("name2"), null, null); - @Test void 골룸의_리더를_찾는다() { // given - final GoalRoom goalRoom = new GoalRoom(new GoalRoomName("goalroom"), new LimitedMemberCount(10), - new RoadmapContent("content"), MEMBER1); + final GoalRoom goalRoom = new GoalRoom(new GoalRoomName("goalroom"), new LimitedMemberCount(10), 1L, 1L); // when final GoalRoomPendingMembers goalRoomPendingMembers = new GoalRoomPendingMembers(List.of( - new GoalRoomPendingMember(GoalRoomRole.LEADER, goalRoom, MEMBER2), - new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, goalRoom, MEMBER1) + new GoalRoomPendingMember(1L, GoalRoomRole.LEADER, null, goalRoom, 1L), + new GoalRoomPendingMember(2L, GoalRoomRole.FOLLOWER, null, goalRoom, 2L) )); // then - assertThat(goalRoomPendingMembers.findGoalRoomLeader()).isEqualTo(MEMBER2); + assertThat(goalRoomPendingMembers.findGoalRoomLeaderId()).isEqualTo(1L); } @Test void 골룸의_리더가_없으면_예외가_발생한다() { // given - final GoalRoom goalRoom = new GoalRoom(new GoalRoomName("goalroom"), new LimitedMemberCount(10), - new RoadmapContent("content"), MEMBER1); + final GoalRoom goalRoom = new GoalRoom(new GoalRoomName("goalroom"), new LimitedMemberCount(10), 1L, 1L); // when final GoalRoomPendingMembers goalRoomPendingMembers = new GoalRoomPendingMembers(List.of( - new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, goalRoom, MEMBER1), - new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, goalRoom, MEMBER2) + new GoalRoomPendingMember(1L, GoalRoomRole.FOLLOWER, null, goalRoom, 1L), + new GoalRoomPendingMember(2L, GoalRoomRole.FOLLOWER, null, goalRoom, 2L) )); // then - assertThatThrownBy(() -> assertThat(goalRoomPendingMembers.findGoalRoomLeader())) + assertThatThrownBy(() -> goalRoomPendingMembers.findGoalRoomLeaderId()) .isInstanceOf(UnexpectedDomainException.class); } @Test void 입력받은_사용자를_골룸_사용자_중에서_찾는다() { // given - final GoalRoomPendingMember goalRoomPendingMember1 = new GoalRoomPendingMember(GoalRoomRole.LEADER, - LocalDateTime.now(), null, MEMBER1); - final GoalRoomPendingMember goalRoomPendingMember2 = new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, - LocalDateTime.now(), null, MEMBER2); + final GoalRoomPendingMember goalRoomPendingMember1 = new GoalRoomPendingMember(1L, GoalRoomRole.LEADER, null, + null, 1L); + final GoalRoomPendingMember goalRoomPendingMember2 = new GoalRoomPendingMember(2L, GoalRoomRole.FOLLOWER, null, + null, 2L); final GoalRoomPendingMembers goalRoomPendingMembers = new GoalRoomPendingMembers( List.of(goalRoomPendingMember1, goalRoomPendingMember2)); // when - final GoalRoomPendingMember findGoalRoomPendingMember = goalRoomPendingMembers.findByMember(MEMBER1).get(); + final GoalRoomPendingMember findGoalRoomPendingMember = goalRoomPendingMembers.findByMemberId(1L).get(); // then assertThat(findGoalRoomPendingMember).isEqualTo(goalRoomPendingMember1); @@ -79,12 +64,10 @@ null, new EncryptedPassword(new Password("password2!")), @Test void 다음_리더가_될_사용자를_찾는다() { // given - final GoalRoomPendingMember goalRoomPendingMember1 = new GoalRoomPendingMember(GoalRoomRole.LEADER, - LocalDateTime.now(), null, - MEMBER1); - final GoalRoomPendingMember goalRoomPendingMember2 = new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, - LocalDateTime.now(), null, - MEMBER2); + final GoalRoomPendingMember goalRoomPendingMember1 = new GoalRoomPendingMember(1L, GoalRoomRole.LEADER, + LocalDateTime.now(), null, 1L); + final GoalRoomPendingMember goalRoomPendingMember2 = new GoalRoomPendingMember(1L, GoalRoomRole.FOLLOWER, + LocalDateTime.now(), null, 2L); final GoalRoomPendingMembers goalRoomPendingMembers = new GoalRoomPendingMembers( List.of(goalRoomPendingMember1, goalRoomPendingMember2)); @@ -99,12 +82,10 @@ null, new EncryptedPassword(new Password("password2!")), @Test void 골룸_사용자의_수를_구한다() { // given - final GoalRoomPendingMember goalRoomPendingMember1 = new GoalRoomPendingMember(GoalRoomRole.LEADER, - LocalDateTime.now(), null, - MEMBER1); - final GoalRoomPendingMember goalRoomPendingMember2 = new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, - LocalDateTime.now(), null, - MEMBER2); + final GoalRoomPendingMember goalRoomPendingMember1 = new GoalRoomPendingMember(1L, GoalRoomRole.LEADER, + LocalDateTime.now(), null, 1L); + final GoalRoomPendingMember goalRoomPendingMember2 = new GoalRoomPendingMember(1L, GoalRoomRole.FOLLOWER, + LocalDateTime.now(), null, 2L); final GoalRoomPendingMembers goalRoomPendingMembers = new GoalRoomPendingMembers( List.of(goalRoomPendingMember1, goalRoomPendingMember2)); @@ -119,12 +100,10 @@ null, new EncryptedPassword(new Password("password2!")), @Test void 골룸_사용자에서_입렵받은_사용자를_제거한다() { // given - final GoalRoomPendingMember goalRoomPendingMember1 = new GoalRoomPendingMember(GoalRoomRole.LEADER, - LocalDateTime.now(), null, - MEMBER1); - final GoalRoomPendingMember goalRoomPendingMember2 = new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, - LocalDateTime.now(), null, - MEMBER2); + final GoalRoomPendingMember goalRoomPendingMember1 = new GoalRoomPendingMember(1L, GoalRoomRole.LEADER, + LocalDateTime.now(), null, 1L); + final GoalRoomPendingMember goalRoomPendingMember2 = new GoalRoomPendingMember(1L, GoalRoomRole.FOLLOWER, + LocalDateTime.now(), null, 2L); final GoalRoomPendingMembers goalRoomPendingMembers = new GoalRoomPendingMembers( List.of(goalRoomPendingMember1, goalRoomPendingMember2)); diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNodeTest.java b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/GoalRoomRoadmapNodeTest.java similarity index 82% rename from backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNodeTest.java rename to backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/GoalRoomRoadmapNodeTest.java index 51a8d6208..dc1d09722 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNodeTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/GoalRoomRoadmapNodeTest.java @@ -1,12 +1,11 @@ -package co.kirikiri.domain.goalroom; +package co.kirikiri.goalroom.domain; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import co.kirikiri.domain.goalroom.exception.GoalRoomException; -import co.kirikiri.domain.goalroom.vo.Period; -import co.kirikiri.domain.roadmap.RoadmapNode; +import co.kirikiri.goalroom.domain.exception.GoalRoomException; +import co.kirikiri.goalroom.domain.vo.Period; import java.time.LocalDate; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -22,8 +21,7 @@ class GoalRoomRoadmapNodeTest { //when //then - assertDoesNotThrow(() -> new GoalRoomRoadmapNode(new Period(startDate, endDate), daysToAdd + 1, - new RoadmapNode("title", "content"))); + assertDoesNotThrow(() -> new GoalRoomRoadmapNode(new Period(startDate, endDate), daysToAdd + 1, 1L)); } @ParameterizedTest @@ -35,8 +33,7 @@ class GoalRoomRoadmapNodeTest { //when //then - assertThatThrownBy(() -> new GoalRoomRoadmapNode(new Period(startDate, endDate), checkCount, - new RoadmapNode("title", "content"))) + assertThatThrownBy(() -> new GoalRoomRoadmapNode(new Period(startDate, endDate), checkCount, 1L)) .isInstanceOf(GoalRoomException.class); } @@ -49,8 +46,7 @@ class GoalRoomRoadmapNodeTest { //when //then - assertThatThrownBy(() -> new GoalRoomRoadmapNode(new Period(startDate, endDate), checkCount, - new RoadmapNode("title", "content"))) + assertThatThrownBy(() -> new GoalRoomRoadmapNode(new Period(startDate, endDate), checkCount, 1L)) .isInstanceOf(GoalRoomException.class); } @@ -64,8 +60,7 @@ class GoalRoomRoadmapNodeTest { //when //then - assertThatThrownBy(() -> new GoalRoomRoadmapNode(new Period(startDate, endDate), checkCount, - new RoadmapNode("title", "content"))) + assertThatThrownBy(() -> new GoalRoomRoadmapNode(new Period(startDate, endDate), checkCount, 1L)) .isInstanceOf(GoalRoomException.class); } @@ -79,8 +74,7 @@ class GoalRoomRoadmapNodeTest { //when //then - assertThatThrownBy(() -> new GoalRoomRoadmapNode(new Period(startDate, endDate), checkCount, - new RoadmapNode("title", "content"))) + assertThatThrownBy(() -> new GoalRoomRoadmapNode(new Period(startDate, endDate), checkCount, 1L)) .isInstanceOf(GoalRoomException.class); } @@ -90,7 +84,7 @@ class GoalRoomRoadmapNodeTest { final GoalRoomRoadmapNode goalRoomRoadmapNode = new GoalRoomRoadmapNode( new Period(LocalDate.of(2300, 7, 1), LocalDate.of(2300, 7, 15)), - 7, new RoadmapNode("제목", "내용")); + 7, 1L); assertThat(goalRoomRoadmapNode.isDayOfNode(date)).isTrue(); } @@ -101,7 +95,7 @@ class GoalRoomRoadmapNodeTest { final GoalRoomRoadmapNode goalRoomRoadmapNode = new GoalRoomRoadmapNode( new Period(LocalDate.of(2300, 7, 1), LocalDate.of(2300, 7, 15)), - 7, new RoadmapNode("제목", "내용")); + 7, 1L); assertThat(goalRoomRoadmapNode.isDayOfNode(date)).isFalse(); } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNodesTest.java b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/GoalRoomRoadmapNodesTest.java similarity index 90% rename from backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNodesTest.java rename to backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/GoalRoomRoadmapNodesTest.java index 3743814ba..ee32e0ccc 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomRoadmapNodesTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/GoalRoomRoadmapNodesTest.java @@ -1,13 +1,12 @@ -package co.kirikiri.domain.goalroom; +package co.kirikiri.goalroom.domain; 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.assertDoesNotThrow; -import co.kirikiri.domain.goalroom.exception.GoalRoomException; -import co.kirikiri.domain.goalroom.vo.Period; -import co.kirikiri.domain.roadmap.RoadmapNode; +import co.kirikiri.goalroom.domain.exception.GoalRoomException; +import co.kirikiri.goalroom.domain.vo.Period; import java.time.LocalDate; import java.util.ArrayList; import java.util.Collections; @@ -117,21 +116,21 @@ class GoalRoomRoadmapNodesTest { assertAll( () -> assertThat(goalRoomRoadmapNodes.getNodeByDate(TODAY).get()) .isEqualTo(new GoalRoomRoadmapNode(new Period(TODAY, TEN_DAY_LATER), - 10, new RoadmapNode("로드맵 제목 1", "로드맵 내용 1"))), + 10, 1L)), () -> assertThat(goalRoomRoadmapNodes.getNodeByDate(TEN_DAY_LATER).get()) .isEqualTo(new GoalRoomRoadmapNode(new Period(TWENTY_DAY_LAYER, THIRTY_DAY_LATER), - 10, new RoadmapNode("로드맵 제목 2", "로드맵 내용 2"))) + 10, 2L)) ); } private GoalRoomRoadmapNodes 골룸_노드를_생성한다() { final GoalRoomRoadmapNode firstGoalRoomRoadmapNode = new GoalRoomRoadmapNode( new Period(TODAY, TEN_DAY_LATER), - 10, new RoadmapNode("로드맵 제목 1", "로드맵 내용 1")); + 10, 1L); final GoalRoomRoadmapNode secondGoalRoomRoadmapNode = new GoalRoomRoadmapNode( new Period(TWENTY_DAY_LAYER, THIRTY_DAY_LATER), - 10, new RoadmapNode("로드맵 제목 2", "로드맵 내용 2")); + 10, 2L); return new GoalRoomRoadmapNodes( List.of(firstGoalRoomRoadmapNode, secondGoalRoomRoadmapNode)); diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomTest.java b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/GoalRoomTest.java similarity index 63% rename from backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomTest.java rename to backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/GoalRoomTest.java index 8459bd4d1..950e461a5 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/GoalRoomTest.java @@ -1,13 +1,9 @@ -package co.kirikiri.domain.goalroom; +package co.kirikiri.goalroom.domain; 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 co.kirikiri.domain.goalroom.exception.GoalRoomException; -import co.kirikiri.domain.goalroom.vo.GoalRoomName; -import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; -import co.kirikiri.domain.goalroom.vo.Period; import co.kirikiri.domain.member.EncryptedPassword; import co.kirikiri.domain.member.Gender; import co.kirikiri.domain.member.Member; @@ -23,10 +19,13 @@ import co.kirikiri.domain.roadmap.RoadmapNode; import co.kirikiri.domain.roadmap.RoadmapNodeImages; import co.kirikiri.domain.roadmap.RoadmapNodes; +import co.kirikiri.goalroom.domain.exception.GoalRoomException; +import co.kirikiri.goalroom.domain.vo.GoalRoomName; +import co.kirikiri.goalroom.domain.vo.LimitedMemberCount; +import co.kirikiri.goalroom.domain.vo.Period; import java.time.LocalDate; import java.util.Collections; import java.util.List; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; class GoalRoomTest { @@ -37,67 +36,14 @@ class GoalRoomTest { private static final LocalDate TWENTY_DAY_LAYER = TODAY.plusDays(20); private static final LocalDate THIRTY_DAY_LATER = TODAY.plusDays(30); - private static Member member; - - @BeforeAll - static void setUp() { - final Identifier identifier = new Identifier("identifier1"); - final Password password = new Password("password1!"); - final EncryptedPassword encryptedPassword = new EncryptedPassword(password); - final Nickname nickname = new Nickname("nickname"); - final MemberProfile memberProfile = new MemberProfile(Gender.MALE, "kirikiri1@email.com"); - member = new Member(1L, identifier, null, encryptedPassword, nickname, null, memberProfile); - } - - @Test - void 골룸의_총_기간을_계산한다() { - // given - final Member creator = 크리에이터를_생성한다(); - final Roadmap roadmap = 로드맵을_생성한다(creator); - - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom = 골룸을_생성한다(targetRoadmapContent, creator); - - // when - final int totalPeriod = goalRoom.calculateTotalPeriod(); - - // then - assertThat(totalPeriod) - .isSameAs(31); - } - - @Test - void 골룸에_대기중인_인원수를_계산한다() { - // given - final GoalRoom goalRoom = new GoalRoom(new GoalRoomName("goalroom"), new LimitedMemberCount(10), - new RoadmapContent("content"), member); - final Member member1 = new Member(2L, new Identifier("identifier2"), - null, new EncryptedPassword(new Password("password1")), new Nickname("닉네임2"), - null, - new MemberProfile(Gender.FEMALE, "kirikiri1@email.com")); - final Member member2 = new Member(3L, new Identifier("identifier3"), - null, new EncryptedPassword(new Password("password1")), new Nickname("닉네임3"), - null, - new MemberProfile(Gender.FEMALE, "kirikiri1@email.com")); - - // when - goalRoom.join(member1); - goalRoom.join(member2); - - // then - assertThat(goalRoom.getCurrentMemberCount()).isEqualTo(3); - } - @Test void 골룸에_사용자를_추가한다() { //given - final GoalRoom goalRoom = new GoalRoom(GOAL_ROOM_NAME, new LimitedMemberCount(10), - new RoadmapContent("로드맵 내용"), member); - final Member follower = 사용자를_생성한다(2L, "identifier12", "시진이"); + final GoalRoom goalRoom = new GoalRoom(GOAL_ROOM_NAME, new LimitedMemberCount(10), 1L, 1L); //when - goalRoom.join(follower); + final Long followerId = 2L; + goalRoom.join(followerId); //then final Integer currentMemberCount = goalRoom.getCurrentMemberCount(); @@ -108,12 +54,11 @@ null, new EncryptedPassword(new Password("password1")), new Nickname("닉네임3 @Test void 모집중이_아닌_골룸에_사용자를_추가하면_예외가_발생한다() { //given - final GoalRoom goalRoom = new GoalRoom(GOAL_ROOM_NAME, new LimitedMemberCount(10), new RoadmapContent("로드맵 내용"), - 사용자를_생성한다(2L, "identifier1", "시진이")); + final GoalRoom goalRoom = new GoalRoom(GOAL_ROOM_NAME, new LimitedMemberCount(10), 1L, 1L); goalRoom.start(); //when, then - assertThatThrownBy(() -> goalRoom.join(member)) + assertThatThrownBy(() -> goalRoom.join(2L)) .isInstanceOf(GoalRoomException.class) .hasMessage("모집 중이지 않은 골룸에는 참여할 수 없습니다."); } @@ -121,11 +66,10 @@ null, new EncryptedPassword(new Password("password1")), new Nickname("닉네임3 @Test void 제한_인원이_가득_찬_골룸에_사용자를_추가하면_예외가_발생한다() { //given - final GoalRoom goalRoom = new GoalRoom(GOAL_ROOM_NAME, new LimitedMemberCount(1), new RoadmapContent("로드맵 내용"), - 사용자를_생성한다(2L, "identifier1", "시진이")); + final GoalRoom goalRoom = new GoalRoom(GOAL_ROOM_NAME, new LimitedMemberCount(1), 1L, 1L); //when,then - assertThatThrownBy(() -> goalRoom.join(member)) + assertThatThrownBy(() -> goalRoom.join(2L)) .isInstanceOf(GoalRoomException.class) .hasMessage("제한 인원이 꽉 찬 골룸에는 참여할 수 없습니다."); } @@ -133,18 +77,17 @@ null, new EncryptedPassword(new Password("password1")), new Nickname("닉네임3 @Test void 이미_참여_중인_사용자를_골룸에_추가하면_예외가_발생한다() { //given - final GoalRoom goalRoom = new GoalRoom(GOAL_ROOM_NAME, new LimitedMemberCount(2), - new RoadmapContent("로드맵 내용"), member); + final GoalRoom goalRoom = new GoalRoom(GOAL_ROOM_NAME, new LimitedMemberCount(2), 1L, 1L); //when,then - assertThatThrownBy(() -> goalRoom.join(member)) + assertThatThrownBy(() -> goalRoom.join(1L)) .isInstanceOf(GoalRoomException.class) .hasMessage("이미 참여한 골룸에는 참여할 수 없습니다."); } @Test - void 골룸의_총_인증_횟수를_구한다() { - //given + void 골룸의_총_기간을_계산한다() { + // given final Member creator = 크리에이터를_생성한다(); final Roadmap roadmap = 로드맵을_생성한다(creator); @@ -152,12 +95,28 @@ null, new EncryptedPassword(new Password("password1")), new Nickname("닉네임3 final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); final GoalRoom goalRoom = 골룸을_생성한다(targetRoadmapContent, creator); - //expect - assertThat(goalRoom.getAllCheckCount()).isEqualTo(20); + // when + final int totalPeriod = goalRoom.calculateTotalPeriod(); + + // then + assertThat(totalPeriod).isEqualTo(31); } @Test - void 골룸이_시작하기_전에_참여_멤버를_확인한다() { + void 골룸에_대기중인_인원수를_계산한다() { + // given + final GoalRoom goalRoom = new GoalRoom(new GoalRoomName("goalroom"), new LimitedMemberCount(10), 1L, 1L); + + // when + goalRoom.join(2L); + goalRoom.join(3L); + + // then + assertThat(goalRoom.getCurrentMemberCount()).isEqualTo(3); + } + + @Test + void 골룸의_총_인증_횟수를_구한다() { //given final Member creator = 크리에이터를_생성한다(); final Roadmap roadmap = 로드맵을_생성한다(creator); @@ -166,18 +125,12 @@ null, new EncryptedPassword(new Password("password1")), new Nickname("닉네임3 final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); final GoalRoom goalRoom = 골룸을_생성한다(targetRoadmapContent, creator); - final Member 참여자 = 사용자를_생성한다(2L, "identifier1", "팔로워"); - goalRoom.join(참여자); - //expect - assertAll( - () -> assertThat(goalRoom.isGoalRoomMember(참여자)).isTrue(), - () -> assertThat(goalRoom.getCurrentMemberCount()).isEqualTo(2) - ); + assertThat(goalRoom.getAllCheckCount()).isEqualTo(20); } @Test - void 골룸이_시작한_후에_참여_멤버를_확인한다() { + void 골룸이_시작하기_전에_참여_멤버를_확인한다() { //given final Member creator = 크리에이터를_생성한다(); final Roadmap roadmap = 로드맵을_생성한다(creator); @@ -186,25 +139,22 @@ null, new EncryptedPassword(new Password("password1")), new Nickname("닉네임3 final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); final GoalRoom goalRoom = 골룸을_생성한다(targetRoadmapContent, creator); - final Member 참여자 = 사용자를_생성한다(2L, "identifier1", "팔로워"); -// goalRoom.join(참여자); - goalRoom.start(); + goalRoom.join(2L); //expect assertAll( - () -> assertThat(goalRoom.isGoalRoomMember(참여자)).isFalse(), - () -> assertThat(goalRoom.getCurrentMemberCount()).isEqualTo(0) + () -> assertThat(goalRoom.isGoalRoomMember(2L)).isTrue(), + () -> assertThat(goalRoom.getCurrentMemberCount()).isEqualTo(2) ); } @Test void 골룸을_나간다() { //given - final GoalRoom goalRoom = new GoalRoom(GOAL_ROOM_NAME, new LimitedMemberCount(2), - new RoadmapContent("로드맵 내용"), member); + final GoalRoom goalRoom = new GoalRoom(GOAL_ROOM_NAME, new LimitedMemberCount(2), 1L, 1L); // when - goalRoom.leave(member); + goalRoom.leave(1L); // then assertThat(goalRoom.isEmptyGoalRoom()).isTrue(); @@ -213,16 +163,13 @@ null, new EncryptedPassword(new Password("password1")), new Nickname("닉네임3 @Test void 골룸에_참여하지_않은_멤버가_나가면_예외가_발생한다() { //given - final GoalRoom goalRoom = new GoalRoom(GOAL_ROOM_NAME, new LimitedMemberCount(2), - new RoadmapContent("로드맵 내용"), member); - - final Member notJoinMember = new Member(new Identifier("identifier2"), - new EncryptedPassword(new Password("password2!")), - new Nickname("name2"), null, null); + final GoalRoom goalRoom = new GoalRoom(GOAL_ROOM_NAME, new LimitedMemberCount(2), 1L, 1L); // when + final Long notJoinMemberId = 2L; + // then - assertThatThrownBy(() -> goalRoom.leave(notJoinMember)) + assertThatThrownBy(() -> goalRoom.leave(notJoinMemberId)) .isInstanceOf(GoalRoomException.class); } @@ -245,15 +192,15 @@ null, new EncryptedPassword(new Password("password1")), new Nickname("닉네임3 private Member 크리에이터를_생성한다() { final MemberProfile memberProfile = new MemberProfile(Gender.MALE, "kirikiri1@email.com"); - return new Member(new Identifier("cokirikiri"), + return new Member(1L, new Identifier("cokirikiri"), null, new EncryptedPassword(new Password("password1!")), new Nickname("코끼리"), null, memberProfile); } - private Member 사용자를_생성한다(final Long id, final String identifier, final String nickname) { - final MemberProfile memberProfile = new MemberProfile(Gender.MALE, "kirikiri1@email.com"); - return new Member(id, new Identifier(identifier), null, new EncryptedPassword(new Password("password1!")), - new Nickname(nickname), null, memberProfile); - } +// private Member 사용자를_생성한다(final Long id, final String identifier, final String nickname) { +// final MemberProfile memberProfile = new MemberProfile(Gender.MALE, "kirikiri1@email.com"); +// return new Member(id, new Identifier(identifier), null, new EncryptedPassword(new Password("password1!")), +// new Nickname(nickname), null, memberProfile); +// } private Roadmap 로드맵을_생성한다(final Member creator) { final RoadmapCategory category = new RoadmapCategory("게임"); @@ -265,30 +212,30 @@ null, new EncryptedPassword(new Password("password1")), new Nickname("닉네임3 } private List 로드맵_노드들을_생성한다() { - final RoadmapNode roadmapNode1 = new RoadmapNode("로드맵 1주차", "로드맵 1주차 내용"); + final RoadmapNode roadmapNode1 = new RoadmapNode(1L, "로드맵 1주차", "로드맵 1주차 내용"); roadmapNode1.addImages(new RoadmapNodeImages(Collections.emptyList())); - final RoadmapNode roadmapNode2 = new RoadmapNode("로드맵 2주차", "로드맵 2주차 내용"); + final RoadmapNode roadmapNode2 = new RoadmapNode(2L, "로드맵 2주차", "로드맵 2주차 내용"); return List.of(roadmapNode1, roadmapNode2); } private RoadmapContent 로드맵_본문을_생성한다(final List roadmapNodes) { - final RoadmapContent roadmapContent = new RoadmapContent("로드맵 본문"); + final RoadmapContent roadmapContent = new RoadmapContent(1L, "로드맵 본문"); roadmapContent.addNodes(new RoadmapNodes(roadmapNodes)); return roadmapContent; } private GoalRoom 골룸을_생성한다(final RoadmapContent roadmapContent, final Member creator) { final GoalRoom goalRoom = new GoalRoom(new GoalRoomName("골룸"), - new LimitedMemberCount(10), roadmapContent, creator); + new LimitedMemberCount(10), roadmapContent.getId(), creator.getId()); final List roadmapNodes = roadmapContent.getNodes().getValues(); final RoadmapNode firstRoadmapNode = roadmapNodes.get(0); final GoalRoomRoadmapNode firstGoalRoomRoadmapNode = new GoalRoomRoadmapNode( - new Period(TODAY, TEN_DAY_LATER), 10, firstRoadmapNode); + new Period(TODAY, TEN_DAY_LATER), 10, firstRoadmapNode.getId()); final RoadmapNode secondRoadmapNode = roadmapNodes.get(1); final GoalRoomRoadmapNode secondGoalRoomRoadmapNode = new GoalRoomRoadmapNode( - new Period(TWENTY_DAY_LAYER, THIRTY_DAY_LATER), 10, secondRoadmapNode); + new Period(TWENTY_DAY_LAYER, THIRTY_DAY_LATER), 10, secondRoadmapNode.getId()); final GoalRoomRoadmapNodes goalRoomRoadmapNodes = new GoalRoomRoadmapNodes( List.of(firstGoalRoomRoadmapNode, secondGoalRoomRoadmapNode)); diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/vo/GoalRoomNameTest.java b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/vo/GoalRoomNameTest.java similarity index 90% rename from backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/vo/GoalRoomNameTest.java rename to backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/vo/GoalRoomNameTest.java index b1eafe64e..1d8fb04d8 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/vo/GoalRoomNameTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/vo/GoalRoomNameTest.java @@ -1,9 +1,9 @@ -package co.kirikiri.domain.goalroom.vo; +package co.kirikiri.goalroom.domain.vo; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import co.kirikiri.domain.goalroom.exception.GoalRoomException; +import co.kirikiri.goalroom.domain.exception.GoalRoomException; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/vo/LimitedMemberCountTest.java b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/vo/LimitedMemberCountTest.java similarity index 89% rename from backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/vo/LimitedMemberCountTest.java rename to backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/vo/LimitedMemberCountTest.java index 66445598a..c87735cc8 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/vo/LimitedMemberCountTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/domain/vo/LimitedMemberCountTest.java @@ -1,9 +1,9 @@ -package co.kirikiri.domain.goalroom.vo; +package co.kirikiri.goalroom.domain.vo; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import co.kirikiri.domain.goalroom.exception.GoalRoomException; +import co.kirikiri.goalroom.domain.exception.GoalRoomException; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/GoalRoomMemberRepositoryTest.java b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/persistence/GoalRoomMemberRepositoryTest.java similarity index 92% rename from backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/GoalRoomMemberRepositoryTest.java rename to backend/kirikiri/src/test/java/co/kirikiri/goalroom/persistence/GoalRoomMemberRepositoryTest.java index 5fed7fa95..0c40e2bfb 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/GoalRoomMemberRepositoryTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/persistence/GoalRoomMemberRepositoryTest.java @@ -1,16 +1,9 @@ -package co.kirikiri.persistence.goalroom; +package co.kirikiri.goalroom.persistence; import static org.assertj.core.api.Assertions.assertThat; -import co.kirikiri.domain.ImageContentType; -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomMember; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNode; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNodes; -import co.kirikiri.domain.goalroom.GoalRoomRole; -import co.kirikiri.domain.goalroom.vo.GoalRoomName; -import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; -import co.kirikiri.domain.goalroom.vo.Period; +import co.kirikiri.common.helper.RepositoryTest; +import co.kirikiri.common.type.ImageContentType; import co.kirikiri.domain.member.EncryptedPassword; import co.kirikiri.domain.member.Gender; import co.kirikiri.domain.member.Member; @@ -28,8 +21,15 @@ import co.kirikiri.domain.roadmap.RoadmapNodeImage; import co.kirikiri.domain.roadmap.RoadmapNodeImages; import co.kirikiri.domain.roadmap.RoadmapNodes; -import co.kirikiri.persistence.goalroom.dto.GoalRoomMemberSortType; -import co.kirikiri.persistence.helper.RepositoryTest; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomMember; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNode; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNodes; +import co.kirikiri.goalroom.domain.GoalRoomRole; +import co.kirikiri.goalroom.domain.vo.GoalRoomName; +import co.kirikiri.goalroom.domain.vo.LimitedMemberCount; +import co.kirikiri.goalroom.domain.vo.Period; +import co.kirikiri.goalroom.persistence.dto.GoalRoomMemberSortType; import co.kirikiri.persistence.member.MemberRepository; import co.kirikiri.persistence.roadmap.RoadmapCategoryRepository; import co.kirikiri.persistence.roadmap.RoadmapRepository; @@ -80,12 +80,12 @@ public GoalRoomMemberRepositoryTest(final MemberRepository memberRepository, final GoalRoom savedGoalRoom = goalRoomRepository.save(goalRoom); final GoalRoomMember goalRoomMember = new GoalRoomMember(GoalRoomRole.LEADER, - LocalDateTime.of(2023, 7, 19, 12, 0, 0), savedGoalRoom, creator); + LocalDateTime.of(2023, 7, 19, 12, 0, 0), savedGoalRoom, creator.getId()); final GoalRoomMember expected = goalRoomMemberRepository.save(goalRoomMember); // when - final Optional findGoalRoomMember = goalRoomMemberRepository.findByGoalRoomAndMemberIdentifier( - savedGoalRoom, new Identifier("cokirikiri")); + final Optional findGoalRoomMember = goalRoomMemberRepository.findByGoalRoomAndMemberId( + savedGoalRoom, creator.getId()); // then assertThat(findGoalRoomMember.get()) @@ -108,8 +108,8 @@ public GoalRoomMemberRepositoryTest(final MemberRepository memberRepository, final GoalRoom savedGoalRoom = goalRoomRepository.save(goalRoom); // when - final Optional findGoalRoomMember = goalRoomMemberRepository.findByGoalRoomAndMemberIdentifier( - savedGoalRoom, new Identifier("cokirikiri2")); + final Optional findGoalRoomMember = goalRoomMemberRepository.findByGoalRoomAndMemberId( + savedGoalRoom, 2L); // then assertThat(findGoalRoomMember) @@ -134,11 +134,11 @@ public GoalRoomMemberRepositoryTest(final MemberRepository memberRepository, final Member member3 = 사용자를_생성한다("identifier3", "password4!", "name3", "kirikiri1@email.com"); final GoalRoomMember goalRoomMember1 = new GoalRoomMember(GoalRoomRole.LEADER, - LocalDateTime.of(2023, 7, 19, 12, 0, 0), savedGoalRoom, member1); + LocalDateTime.of(2023, 7, 19, 12, 0, 0), savedGoalRoom, member1.getId()); final GoalRoomMember goalRoomMember2 = new GoalRoomMember(GoalRoomRole.FOLLOWER, - LocalDateTime.of(2023, 7, 20, 12, 0, 0), savedGoalRoom, member2); + LocalDateTime.of(2023, 7, 20, 12, 0, 0), savedGoalRoom, member2.getId()); final GoalRoomMember goalRoomMember3 = new GoalRoomMember(GoalRoomRole.FOLLOWER, - LocalDateTime.of(2023, 7, 21, 12, 0, 0), savedGoalRoom, member3); + LocalDateTime.of(2023, 7, 21, 12, 0, 0), savedGoalRoom, member3.getId()); final List expected = goalRoomMemberRepository.saveAll( List.of(goalRoomMember1, goalRoomMember2, goalRoomMember3)); @@ -169,11 +169,11 @@ public GoalRoomMemberRepositoryTest(final MemberRepository memberRepository, final Member member3 = 사용자를_생성한다("identifier3", "password4!", "name3", "kirikiri1@email.com"); final GoalRoomMember goalRoomMember1 = new GoalRoomMember(GoalRoomRole.LEADER, - LocalDateTime.of(2023, 7, 19, 12, 0, 0), savedGoalRoom, member1); + LocalDateTime.of(2023, 7, 19, 12, 0, 0), savedGoalRoom, member1.getId()); final GoalRoomMember goalRoomMember2 = new GoalRoomMember(GoalRoomRole.FOLLOWER, - LocalDateTime.of(2023, 7, 20, 12, 0, 0), savedGoalRoom, member2); + LocalDateTime.of(2023, 7, 20, 12, 0, 0), savedGoalRoom, member2.getId()); final GoalRoomMember goalRoomMember3 = new GoalRoomMember(GoalRoomRole.FOLLOWER, - LocalDateTime.of(2023, 7, 21, 12, 0, 0), savedGoalRoom, member3); + LocalDateTime.of(2023, 7, 21, 12, 0, 0), savedGoalRoom, member3.getId()); final List expected = goalRoomMemberRepository.saveAll( List.of(goalRoomMember1, goalRoomMember2, goalRoomMember3)); @@ -204,11 +204,11 @@ public GoalRoomMemberRepositoryTest(final MemberRepository memberRepository, final Member member3 = 사용자를_생성한다("identifier3", "password4!", "name3", "kirikiri1@email.com"); final GoalRoomMember goalRoomMember1 = new GoalRoomMember(GoalRoomRole.LEADER, - LocalDateTime.of(2023, 7, 19, 12, 0, 0), savedGoalRoom, member1); + LocalDateTime.of(2023, 7, 19, 12, 0, 0), savedGoalRoom, member1.getId()); final GoalRoomMember goalRoomMember2 = new GoalRoomMember(GoalRoomRole.FOLLOWER, - LocalDateTime.of(2023, 7, 20, 12, 0, 0), savedGoalRoom, member2); + LocalDateTime.of(2023, 7, 20, 12, 0, 0), savedGoalRoom, member2.getId()); final GoalRoomMember goalRoomMember3 = new GoalRoomMember(GoalRoomRole.FOLLOWER, - LocalDateTime.of(2023, 7, 21, 12, 0, 0), savedGoalRoom, member3); + LocalDateTime.of(2023, 7, 21, 12, 0, 0), savedGoalRoom, member3.getId()); final GoalRoomMember savedGoalRoomMember1 = goalRoomMemberRepository.save(goalRoomMember1); final GoalRoomMember savedGoalRoomMember2 = goalRoomMemberRepository.save(goalRoomMember2); final GoalRoomMember savedGoalRoomMember3 = goalRoomMemberRepository.save(goalRoomMember3); @@ -240,13 +240,13 @@ public GoalRoomMemberRepositoryTest(final MemberRepository memberRepository, final Member member3 = 사용자를_생성한다("identifier3", "password4!", "name3", "kirikiri1@email.com"); final GoalRoomMember goalRoomMember1 = new GoalRoomMember(GoalRoomRole.LEADER, - LocalDateTime.of(2023, 7, 19, 12, 0, 0), savedGoalRoom, member1); + LocalDateTime.of(2023, 7, 19, 12, 0, 0), savedGoalRoom, member1.getId()); goalRoomMember1.updateAccomplishmentRate(30.0); final GoalRoomMember goalRoomMember2 = new GoalRoomMember(GoalRoomRole.FOLLOWER, - LocalDateTime.of(2023, 7, 20, 12, 0, 0), savedGoalRoom, member2); + LocalDateTime.of(2023, 7, 20, 12, 0, 0), savedGoalRoom, member2.getId()); goalRoomMember2.updateAccomplishmentRate(70.0); final GoalRoomMember goalRoomMember3 = new GoalRoomMember(GoalRoomRole.FOLLOWER, - LocalDateTime.of(2023, 7, 21, 12, 0, 0), savedGoalRoom, member3); + LocalDateTime.of(2023, 7, 21, 12, 0, 0), savedGoalRoom, member3.getId()); goalRoomMember3.updateAccomplishmentRate(10.0); final List expected = goalRoomMemberRepository.saveAll( List.of(goalRoomMember2, goalRoomMember1, goalRoomMember3)); @@ -278,13 +278,13 @@ public GoalRoomMemberRepositoryTest(final MemberRepository memberRepository, goalRoomRepository.save(goalRoom); final GoalRoomMember goalRoomMember = new GoalRoomMember( - GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator + GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator.getId() ); goalRoomMemberRepository.save(goalRoomMember); // when - final GoalRoomMember findGoalRoomMember = goalRoomMemberRepository.findGoalRoomMember(goalRoom.getId(), - creator.getIdentifier()).get(); + final GoalRoomMember findGoalRoomMember = goalRoomMemberRepository.findByGoalRoomIdAndMemberId(goalRoom.getId(), + creator.getId()).get(); // then Assertions.assertThat(findGoalRoomMember) @@ -345,17 +345,17 @@ public GoalRoomMemberRepositoryTest(final MemberRepository memberRepository, private GoalRoom 골룸을_생성한다(final RoadmapContent roadmapContent, final Member member) { final GoalRoom goalRoom = new GoalRoom(new GoalRoomName("골룸"), new LimitedMemberCount(10), - roadmapContent, member); + roadmapContent.getId(), member.getId()); final List roadmapNodes = roadmapContent.getNodes().getValues(); final RoadmapNode firstRoadmapNode = roadmapNodes.get(0); final GoalRoomRoadmapNode firstGoalRoomRoadmapNode = new GoalRoomRoadmapNode( - new Period(TODAY, TEN_DAY_LATER), 10, firstRoadmapNode); + new Period(TODAY, TEN_DAY_LATER), 10, firstRoadmapNode.getId()); final RoadmapNode secondRoadmapNode = roadmapNodes.get(1); final GoalRoomRoadmapNode secondGoalRoomRoadmapNode = new GoalRoomRoadmapNode( new Period(TWENTY_DAY_LAYER, THIRTY_DAY_LATER), - 10, secondRoadmapNode); + 10, secondRoadmapNode.getId()); final GoalRoomRoadmapNodes goalRoomRoadmapNodes = new GoalRoomRoadmapNodes( List.of(firstGoalRoomRoadmapNode, secondGoalRoomRoadmapNode)); diff --git a/backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/GoalRoomPendingMemberRepositoryTest.java b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/persistence/GoalRoomPendingMemberRepositoryTest.java similarity index 85% rename from backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/GoalRoomPendingMemberRepositoryTest.java rename to backend/kirikiri/src/test/java/co/kirikiri/goalroom/persistence/GoalRoomPendingMemberRepositoryTest.java index 2febbb556..9ec7bbe63 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/GoalRoomPendingMemberRepositoryTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/persistence/GoalRoomPendingMemberRepositoryTest.java @@ -1,16 +1,9 @@ -package co.kirikiri.persistence.goalroom; +package co.kirikiri.goalroom.persistence; import static org.assertj.core.api.Assertions.assertThat; -import co.kirikiri.domain.ImageContentType; -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomPendingMember; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNode; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNodes; -import co.kirikiri.domain.goalroom.GoalRoomRole; -import co.kirikiri.domain.goalroom.vo.GoalRoomName; -import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; -import co.kirikiri.domain.goalroom.vo.Period; +import co.kirikiri.common.helper.RepositoryTest; +import co.kirikiri.common.type.ImageContentType; import co.kirikiri.domain.member.EncryptedPassword; import co.kirikiri.domain.member.Gender; import co.kirikiri.domain.member.Member; @@ -28,17 +21,24 @@ import co.kirikiri.domain.roadmap.RoadmapNodeImage; import co.kirikiri.domain.roadmap.RoadmapNodeImages; import co.kirikiri.domain.roadmap.RoadmapNodes; -import co.kirikiri.persistence.goalroom.dto.GoalRoomMemberSortType; -import co.kirikiri.persistence.helper.RepositoryTest; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomPendingMember; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNode; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNodes; +import co.kirikiri.goalroom.domain.GoalRoomRole; +import co.kirikiri.goalroom.domain.vo.GoalRoomName; +import co.kirikiri.goalroom.domain.vo.LimitedMemberCount; +import co.kirikiri.goalroom.domain.vo.Period; +import co.kirikiri.goalroom.persistence.dto.GoalRoomMemberSortType; import co.kirikiri.persistence.member.MemberRepository; import co.kirikiri.persistence.roadmap.RoadmapCategoryRepository; import co.kirikiri.persistence.roadmap.RoadmapRepository; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; @RepositoryTest class GoalRoomPendingMemberRepositoryTest { @@ -79,12 +79,12 @@ public GoalRoomPendingMemberRepositoryTest(final MemberRepository memberReposito final GoalRoom goalRoom = 골룸을_생성한다(targetRoadmapContent, creator); final GoalRoom savedGoalRoom = goalRoomRepository.save(goalRoom); - final GoalRoomPendingMember expected = new GoalRoomPendingMember(GoalRoomRole.LEADER, - LocalDateTime.of(2023, 7, 19, 12, 0, 0), savedGoalRoom, creator); + final GoalRoomPendingMember expected = new GoalRoomPendingMember(1L, GoalRoomRole.LEADER, + LocalDateTime.of(2023, 7, 19, 12, 0, 0), savedGoalRoom, creator.getId()); // when - final Optional findGoalRoomPendingMember = goalRoomPendingMemberRepository.findByGoalRoomAndMemberIdentifier( - savedGoalRoom, new Identifier("cokirikiri")); + final Optional findGoalRoomPendingMember = goalRoomPendingMemberRepository.findByGoalRoomAndMemberId( + savedGoalRoom, creator.getId()); // then assertThat(findGoalRoomPendingMember.get()) @@ -107,8 +107,8 @@ public GoalRoomPendingMemberRepositoryTest(final MemberRepository memberReposito final GoalRoom savedGoalRoom = goalRoomRepository.save(goalRoom); // when - final Optional findGoalRoomPendingMember = goalRoomPendingMemberRepository.findByGoalRoomAndMemberIdentifier( - savedGoalRoom, new Identifier("cokirikiri2")); + final Optional findGoalRoomPendingMember = goalRoomPendingMemberRepository.findByGoalRoomAndMemberId( + savedGoalRoom, 2L); // then assertThat(findGoalRoomPendingMember) @@ -132,14 +132,14 @@ public GoalRoomPendingMemberRepositoryTest(final MemberRepository memberReposito final Member member2 = 사용자를_생성한다("identifier2", "password3!", "name2", "kirikiri1@email.com"); final Member member3 = 사용자를_생성한다("identifier3", "password4!", "name3", "kirikiri1@email.com"); - final GoalRoomPendingMember goalRoomPendingMember = new GoalRoomPendingMember(GoalRoomRole.LEADER, - LocalDateTime.now(), savedGoalRoom, creator); - final GoalRoomPendingMember goalRoomPendingMember1 = new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, - LocalDateTime.now(), savedGoalRoom, member1); - final GoalRoomPendingMember goalRoomPendingMember2 = new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, - LocalDateTime.now(), savedGoalRoom, member2); - final GoalRoomPendingMember goalRoomPendingMember3 = new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, - LocalDateTime.now(), savedGoalRoom, member3); + final GoalRoomPendingMember goalRoomPendingMember = new GoalRoomPendingMember(null, GoalRoomRole.LEADER, + LocalDateTime.now(), savedGoalRoom, creator.getId()); + final GoalRoomPendingMember goalRoomPendingMember1 = new GoalRoomPendingMember(null, GoalRoomRole.FOLLOWER, + LocalDateTime.now(), savedGoalRoom, member1.getId()); + final GoalRoomPendingMember goalRoomPendingMember2 = new GoalRoomPendingMember(null, GoalRoomRole.FOLLOWER, + LocalDateTime.now(), savedGoalRoom, member2.getId()); + final GoalRoomPendingMember goalRoomPendingMember3 = new GoalRoomPendingMember(null, GoalRoomRole.FOLLOWER, + LocalDateTime.now(), savedGoalRoom, member3.getId()); goalRoomPendingMemberRepository.saveAll( List.of(goalRoomPendingMember1, goalRoomPendingMember2, goalRoomPendingMember3)); @@ -171,19 +171,19 @@ public GoalRoomPendingMemberRepositoryTest(final MemberRepository memberReposito final Member follower = 사용자를_생성한다("identifier2", "password!2", "name", "kirikiri1@email.com"); //when - savedGoalRoom.join(follower); + savedGoalRoom.join(follower.getId()); //then final List goalRoomPendingMembers = goalRoomPendingMemberRepository.findByGoalRoom( goalRoom); - final List members = goalRoomPendingMembers.stream() - .map(GoalRoomPendingMember::getMember) + final List memberIds = goalRoomPendingMembers.stream() + .map(GoalRoomPendingMember::getMemberId) .toList(); Assertions.assertAll( () -> assertThat(goalRoomPendingMembers).hasSize(2), - () -> assertThat(members).contains(follower) + () -> assertThat(memberIds).contains(follower.getId()) ); } @@ -205,12 +205,12 @@ public GoalRoomPendingMemberRepositoryTest(final MemberRepository memberReposito final Member member3 = 사용자를_생성한다("identifier3", "password4!", "name3", "kirikiri1@email.com"); final GoalRoomPendingMember goalRoomPendingMember0 = goalRoom.getGoalRoomPendingMembers().getValues().get(0); - final GoalRoomPendingMember goalRoomPendingMember1 = new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, - LocalDateTime.now(), savedGoalRoom, member1); - final GoalRoomPendingMember goalRoomPendingMember2 = new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, - LocalDateTime.now(), savedGoalRoom, member2); - final GoalRoomPendingMember goalRoomPendingMember3 = new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, - LocalDateTime.now(), savedGoalRoom, member3); + final GoalRoomPendingMember goalRoomPendingMember1 = new GoalRoomPendingMember(null, GoalRoomRole.FOLLOWER, + LocalDateTime.now(), savedGoalRoom, member1.getId()); + final GoalRoomPendingMember goalRoomPendingMember2 = new GoalRoomPendingMember(null, GoalRoomRole.FOLLOWER, + LocalDateTime.now(), savedGoalRoom, member2.getId()); + final GoalRoomPendingMember goalRoomPendingMember3 = new GoalRoomPendingMember(null, GoalRoomRole.FOLLOWER, + LocalDateTime.now(), savedGoalRoom, member3.getId()); goalRoomPendingMemberRepository.saveAll( List.of(goalRoomPendingMember1, goalRoomPendingMember2, goalRoomPendingMember3)); final List expected = List.of(goalRoomPendingMember0, goalRoomPendingMember1, @@ -222,6 +222,8 @@ public GoalRoomPendingMemberRepositoryTest(final MemberRepository memberReposito // then assertThat(goalRoomPendingMembers) + .usingRecursiveComparison() + .ignoringFields("id") .isEqualTo(expected); } @@ -243,12 +245,12 @@ public GoalRoomPendingMemberRepositoryTest(final MemberRepository memberReposito final Member member3 = 사용자를_생성한다("identifier3", "password4!", "name3", "kirikiri1@email.com"); final GoalRoomPendingMember goalRoomPendingMember0 = goalRoom.getGoalRoomPendingMembers().getValues().get(0); - final GoalRoomPendingMember goalRoomPendingMember1 = new GoalRoomPendingMember(GoalRoomRole.LEADER, - LocalDateTime.now(), savedGoalRoom, member1); - final GoalRoomPendingMember goalRoomPendingMember2 = new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, - LocalDateTime.now(), savedGoalRoom, member2); - final GoalRoomPendingMember goalRoomPendingMember3 = new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, - LocalDateTime.now(), savedGoalRoom, member3); + final GoalRoomPendingMember goalRoomPendingMember1 = new GoalRoomPendingMember(null, GoalRoomRole.LEADER, + LocalDateTime.now(), savedGoalRoom, member1.getId()); + final GoalRoomPendingMember goalRoomPendingMember2 = new GoalRoomPendingMember(null, GoalRoomRole.FOLLOWER, + LocalDateTime.now(), savedGoalRoom, member2.getId()); + final GoalRoomPendingMember goalRoomPendingMember3 = new GoalRoomPendingMember(null, GoalRoomRole.FOLLOWER, + LocalDateTime.now(), savedGoalRoom, member3.getId()); final GoalRoomPendingMember savedGoalRoomPendingMember1 = goalRoomPendingMemberRepository.save( goalRoomPendingMember1); final GoalRoomPendingMember savedGoalRoomPendingMember2 = goalRoomPendingMemberRepository.save( @@ -285,12 +287,12 @@ public GoalRoomPendingMemberRepositoryTest(final MemberRepository memberReposito final Member member3 = 사용자를_생성한다("identifier3", "password4!", "name3", "kirikiri1@email.com"); final GoalRoomPendingMember goalRoomPendingMember0 = goalRoom.getGoalRoomPendingMembers().getValues().get(0); - final GoalRoomPendingMember goalRoomPendingMember1 = new GoalRoomPendingMember(GoalRoomRole.LEADER, - LocalDateTime.now(), savedGoalRoom, member1); - final GoalRoomPendingMember goalRoomPendingMember2 = new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, - LocalDateTime.now(), savedGoalRoom, member2); - final GoalRoomPendingMember goalRoomPendingMember3 = new GoalRoomPendingMember(GoalRoomRole.FOLLOWER, - LocalDateTime.now(), savedGoalRoom, member3); + final GoalRoomPendingMember goalRoomPendingMember1 = new GoalRoomPendingMember(null, GoalRoomRole.LEADER, + LocalDateTime.now(), savedGoalRoom, member1.getId()); + final GoalRoomPendingMember goalRoomPendingMember2 = new GoalRoomPendingMember(null, GoalRoomRole.FOLLOWER, + LocalDateTime.now(), savedGoalRoom, member2.getId()); + final GoalRoomPendingMember goalRoomPendingMember3 = new GoalRoomPendingMember(null, GoalRoomRole.FOLLOWER, + LocalDateTime.now(), savedGoalRoom, member3.getId()); goalRoomPendingMemberRepository.saveAll( List.of(goalRoomPendingMember1, goalRoomPendingMember2, goalRoomPendingMember3)); final List expected = List.of(goalRoomPendingMember0, goalRoomPendingMember1, @@ -304,8 +306,12 @@ public GoalRoomPendingMemberRepositoryTest(final MemberRepository memberReposito // then assertThat(goalRoomPendingMembers1) + .usingRecursiveComparison() + .ignoringFields("id") .isEqualTo(expected); assertThat(goalRoomPendingMembers2) + .usingRecursiveComparison() + .ignoringFields("id") .isEqualTo(expected); } @@ -361,18 +367,18 @@ public GoalRoomPendingMemberRepositoryTest(final MemberRepository memberReposito private GoalRoom 골룸을_생성한다(final RoadmapContent roadmapContent, final Member member) { final GoalRoom goalRoom = new GoalRoom(new GoalRoomName("골룸"), new LimitedMemberCount(10), - roadmapContent, member); + roadmapContent.getId(), member.getId()); final List roadmapNodes = roadmapContent.getNodes().getValues(); final RoadmapNode firstRoadmapNode = roadmapNodes.get(0); final GoalRoomRoadmapNode firstGoalRoomRoadmapNode = new GoalRoomRoadmapNode( new Period(TODAY, TEN_DAY_LATER), - 10, firstRoadmapNode); + 10, firstRoadmapNode.getId()); final RoadmapNode secondRoadmapNode = roadmapNodes.get(1); final GoalRoomRoadmapNode secondGoalRoomRoadmapNode = new GoalRoomRoadmapNode( new Period(TWENTY_DAY_LAYER, THIRTY_DAY_LATER), - 10, secondRoadmapNode); + 10, secondRoadmapNode.getId()); final GoalRoomRoadmapNodes goalRoomRoadmapNodes = new GoalRoomRoadmapNodes( List.of(firstGoalRoomRoadmapNode, secondGoalRoomRoadmapNode)); diff --git a/backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/GoalRoomRepositoryTest.java b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/persistence/GoalRoomRepositoryTest.java similarity index 75% rename from backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/GoalRoomRepositoryTest.java rename to backend/kirikiri/src/test/java/co/kirikiri/goalroom/persistence/GoalRoomRepositoryTest.java index 38f6fb513..f9afd87ac 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/GoalRoomRepositoryTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/persistence/GoalRoomRepositoryTest.java @@ -1,17 +1,9 @@ -package co.kirikiri.persistence.goalroom; +package co.kirikiri.goalroom.persistence; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNode; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNodes; -import co.kirikiri.domain.goalroom.GoalRoomStatus; -import co.kirikiri.domain.goalroom.GoalRoomToDo; -import co.kirikiri.domain.goalroom.vo.GoalRoomName; -import co.kirikiri.domain.goalroom.vo.GoalRoomTodoContent; -import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; -import co.kirikiri.domain.goalroom.vo.Period; +import co.kirikiri.common.helper.RepositoryTest; import co.kirikiri.domain.member.EncryptedPassword; import co.kirikiri.domain.member.Gender; import co.kirikiri.domain.member.Member; @@ -25,14 +17,20 @@ import co.kirikiri.domain.roadmap.RoadmapDifficulty; import co.kirikiri.domain.roadmap.RoadmapNode; import co.kirikiri.domain.roadmap.RoadmapNodes; -import co.kirikiri.persistence.goalroom.dto.RoadmapGoalRoomsOrderType; -import co.kirikiri.persistence.helper.RepositoryTest; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNode; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNodes; +import co.kirikiri.goalroom.domain.GoalRoomStatus; +import co.kirikiri.goalroom.domain.vo.GoalRoomName; +import co.kirikiri.goalroom.domain.vo.LimitedMemberCount; +import co.kirikiri.goalroom.domain.vo.Period; +import co.kirikiri.goalroom.persistence.dto.RoadmapGoalRoomsOrderType; import co.kirikiri.persistence.member.MemberRepository; import co.kirikiri.persistence.roadmap.RoadmapCategoryRepository; import co.kirikiri.persistence.roadmap.RoadmapRepository; -import org.junit.jupiter.api.Test; import java.time.LocalDate; import java.util.List; +import org.junit.jupiter.api.Test; @RepositoryTest class GoalRoomRepositoryTest { @@ -57,35 +55,35 @@ public GoalRoomRepositoryTest(final MemberRepository memberRepository, this.roadmapCategoryRepository = roadmapCategoryRepository; } - @Test - void 골룸_아이디로_골룸_정보를_조회한다() { - //given - final Member creator = 사용자를_생성한다("name1", "kirikiri@email.com", "identifier1", "password!1"); - final RoadmapCategory category = 카테고리를_저장한다("여가"); - final RoadmapNode roadmapNode1 = 로드맵_노드를_생성한다("로드맵 1주차", "로드맵 1주차 내용"); - final RoadmapNode roadmapNode2 = 로드맵_노드를_생성한다("로드맵 2주차", "로드맵 2주차 내용"); - final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(List.of(roadmapNode1, roadmapNode2)); - 로드맵을_생성한다(creator, category, roadmapContent); - - final GoalRoomRoadmapNode goalRoomRoadmapNode1 = 골룸_로드맵_노드를_생성한다(TODAY, TODAY.plusDays(10), - roadmapNode1); - final GoalRoomRoadmapNode goalRoomRoadmapNode2 = 골룸_로드맵_노드를_생성한다(TODAY.plusDays(11), TODAY.plusDays(20), - roadmapNode2); - final Member goalRoomPendingMember1 = 사용자를_생성한다("name2", "kirikiri@email.com", "identifier2", "password!2"); - final GoalRoom goalRoom = 골룸을_생성한다("goalroom1", 6, roadmapContent, - new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode1, goalRoomRoadmapNode2)), goalRoomPendingMember1); - goalRoomRepository.save(goalRoom); - - // when - final GoalRoom findGoalRoom = goalRoomRepository.findByIdWithRoadmapContent(goalRoom.getId()) - .get(); - - // then - assertThat(findGoalRoom) - .usingRecursiveComparison() - .ignoringFields("id", "createdAt", "updatedAt") - .isEqualTo(goalRoom); - } +// @Test +// void 골룸_아이디로_골룸_정보를_조회한다() { +// //given +// final Member creator = 사용자를_생성한다("name1", "kirikiri@email.com", "identifier1", "password!1"); +// final RoadmapCategory category = 카테고리를_저장한다("여가"); +// final RoadmapNode roadmapNode1 = 로드맵_노드를_생성한다("로드맵 1주차", "로드맵 1주차 내용"); +// final RoadmapNode roadmapNode2 = 로드맵_노드를_생성한다("로드맵 2주차", "로드맵 2주차 내용"); +// final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(List.of(roadmapNode1, roadmapNode2)); +// 로드맵을_생성한다(creator, category, roadmapContent); +// +// final GoalRoomRoadmapNode goalRoomRoadmapNode1 = 골룸_로드맵_노드를_생성한다(TODAY, TODAY.plusDays(10), +// roadmapNode1); +// final GoalRoomRoadmapNode goalRoomRoadmapNode2 = 골룸_로드맵_노드를_생성한다(TODAY.plusDays(11), TODAY.plusDays(20), +// roadmapNode2); +// final Member goalRoomPendingMember1 = 사용자를_생성한다("name2", "kirikiri@email.com", "identifier2", "password!2"); +// final GoalRoom goalRoom = 골룸을_생성한다("goalroom1", 6, roadmapContent, +// new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode1, goalRoomRoadmapNode2)), goalRoomPendingMember1); +// goalRoomRepository.save(goalRoom); +// +// // when +// final GoalRoom findGoalRoom = goalRoomRepository.findByIdWithRoadmapContent(goalRoom.getId()) +// .get(); +// +// // then +// assertThat(findGoalRoom) +// .usingRecursiveComparison() +// .ignoringFields("id", "createdAt", "updatedAt") +// .isEqualTo(goalRoom); +// } @Test void 골룸을_최신순으로_조회한다() { @@ -116,9 +114,11 @@ public GoalRoomRepositoryTest(final MemberRepository memberRepository, goalRoomRepository.save(goalRoom2); // when - final List goalRooms1 = goalRoomRepository.findGoalRoomsByRoadmapAndCond(roadmap, + final List goalRooms1 = goalRoomRepository.findGoalRoomsByRoadmapContentIdAndCond( + roadmapContent.getId(), RoadmapGoalRoomsOrderType.LATEST, null, 1); - final List goalRooms2 = goalRoomRepository.findGoalRoomsByRoadmapAndCond(roadmap, + final List goalRooms2 = goalRoomRepository.findGoalRoomsByRoadmapContentIdAndCond( + roadmapContent.getId(), RoadmapGoalRoomsOrderType.LATEST, goalRoom2.getId(), 10); assertThat(goalRooms1) @@ -155,9 +155,11 @@ public GoalRoomRepositoryTest(final MemberRepository memberRepository, goalRoomRepository.save(goalRoom2); // when - final List goalRooms1 = goalRoomRepository.findGoalRoomsByRoadmapAndCond(roadmap, + final List goalRooms1 = goalRoomRepository.findGoalRoomsByRoadmapContentIdAndCond( + roadmapContent.getId(), RoadmapGoalRoomsOrderType.CLOSE_TO_DEADLINE, null, 1); - final List goalRooms2 = goalRoomRepository.findGoalRoomsByRoadmapAndCond(roadmap, + final List goalRooms2 = goalRoomRepository.findGoalRoomsByRoadmapContentIdAndCond( + roadmapContent.getId(), RoadmapGoalRoomsOrderType.CLOSE_TO_DEADLINE, goalRoom1.getId(), 10); // then @@ -165,125 +167,88 @@ public GoalRoomRepositoryTest(final MemberRepository memberRepository, assertThat(goalRooms2).isEqualTo(List.of(goalRoom2)); } - @Test - void 골룸의_노드의_시작날짜가_오늘인_골룸을_조회한다() { - // given - final Member creator = 크리에이터를_저장한다(); - final RoadmapCategory category = 카테고리를_저장한다("게임"); - final RoadmapNode roadmapNode1 = 로드맵_노드를_생성한다("로드맵 1주차", "로드맵 1주차 내용"); - final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(List.of(roadmapNode1)); - 로드맵을_생성한다(creator, category, roadmapContent); - - final GoalRoomRoadmapNode goalRoomRoadmapNode1 = 골룸_로드맵_노드를_생성한다(TODAY, TODAY.plusDays(10), - roadmapNode1); - final GoalRoomRoadmapNode goalRoomRoadmapNode2 = 골룸_로드맵_노드를_생성한다(TODAY, TODAY.plusDays(10), - roadmapNode1); - final GoalRoomRoadmapNode goalRoomRoadmapNode3 = 골룸_로드맵_노드를_생성한다(TODAY.plusDays(10), TODAY.plusDays(20), - roadmapNode1); - - final GoalRoom goalRoom1 = 골룸을_생성한다("goalroom1", 20, roadmapContent, - new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode1)), creator); - final GoalRoom goalRoom2 = 골룸을_생성한다("goalroom2", 20, roadmapContent, - new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode2)), creator); - final GoalRoom goalRoom3 = 골룸을_생성한다("goalroom3", 20, roadmapContent, - new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode3)), creator); - - final GoalRoom savedGoalRoom1 = goalRoomRepository.save(goalRoom1); - final GoalRoom savedGoalRoom2 = goalRoomRepository.save(goalRoom2); - goalRoomRepository.save(goalRoom3); - - // when - final List findGoalRooms = goalRoomRepository.findAllRecruitingGoalRoomsByStartDateEarlierThan(LocalDate.now()); - - // then - assertThat(findGoalRooms) - .usingRecursiveComparison() - .ignoringFields("id") - .isEqualTo(List.of(savedGoalRoom1, savedGoalRoom2)); - } - - @Test - void 투두리스트와_함께_골룸을_조회한다() { - final Member creator = 사용자를_생성한다("name1", "kirikiri@email.com", "identifier1", "password!1"); - final RoadmapCategory category = 카테고리를_저장한다("여가"); - final RoadmapNode roadmapNode1 = 로드맵_노드를_생성한다("로드맵 1주차", "로드맵 1주차 내용"); - final RoadmapNode roadmapNode2 = 로드맵_노드를_생성한다("로드맵 2주차", "로드맵 2주차 내용"); - final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(List.of(roadmapNode1, roadmapNode2)); - 로드맵을_생성한다(creator, category, roadmapContent); - - final GoalRoomRoadmapNode goalRoomRoadmapNode1 = 골룸_로드맵_노드를_생성한다(TODAY, TODAY.plusDays(10), - roadmapNode1); - final GoalRoomRoadmapNode goalRoomRoadmapNode2 = 골룸_로드맵_노드를_생성한다(TODAY.plusDays(11), TODAY.plusDays(20), - roadmapNode2); - final Member goalRoomPendingMember = 사용자를_생성한다("name2", "kirikiri@email.com", "identifier2", "password!2"); - final GoalRoom goalRoom = 골룸을_생성한다("goalroom1", 6, roadmapContent, - new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode1, goalRoomRoadmapNode2)), goalRoomPendingMember); - - final LocalDate today = LocalDate.now(); - final LocalDate threeDaysAfter = today.plusDays(3); - goalRoom.addGoalRoomTodo(new GoalRoomToDo( - new GoalRoomTodoContent("투두1"), new Period(today, threeDaysAfter) - )); - goalRoom.addGoalRoomTodo(new GoalRoomToDo( - new GoalRoomTodoContent("투두2"), new Period(today, threeDaysAfter) - )); - goalRoomRepository.save(goalRoom); - - // when - final GoalRoom findGoalRoom = goalRoomRepository.findByIdWithTodos(goalRoom.getId()).get(); - - // then - assertThat(findGoalRoom) - .usingRecursiveComparison() - .ignoringFields("id", "createdAt", "updatedAt") - .isEqualTo(goalRoom); - } - - @Test - void 골룸_아이디로_골룸과_로드맵컨텐츠_골룸노드_투두_정보를_조회한다() { - final Member creator = 크리에이터를_저장한다(); - final RoadmapCategory category = 카테고리를_저장한다("게임"); - final RoadmapNode roadmapNode = 로드맵_노드를_생성한다("로드맵 1주차", "로드맵 1주차 내용"); - final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(List.of(roadmapNode)); - 로드맵을_생성한다(creator, category, roadmapContent); - - final GoalRoomRoadmapNode goalRoomRoadmapNode1 = 골룸_로드맵_노드를_생성한다(TODAY, TODAY.plusDays(10), - roadmapNode); - final GoalRoomRoadmapNode goalRoomRoadmapNode2 = 골룸_로드맵_노드를_생성한다(TODAY, TODAY.plusDays(10), - roadmapNode); - - final GoalRoom goalRoom1 = 골룸을_생성한다("goalroom1", 20, roadmapContent, - new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode1)), creator); - final GoalRoomToDo goalRoomToDo1 = new GoalRoomToDo(new GoalRoomTodoContent("할 일 목록"), - new Period(TODAY, TEN_DAY_LATER)); - goalRoom1.addGoalRoomTodo(goalRoomToDo1); - final GoalRoom savedGoalRoom1 = goalRoomRepository.save(goalRoom1); - - final GoalRoom goalRoom2 = 골룸을_생성한다("goalroom2", 20, roadmapContent, - new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode2)), creator); - final GoalRoomToDo goalRoomToDo2 = new GoalRoomToDo(new GoalRoomTodoContent("우리만의 투두"), - new Period(TEN_DAY_LATER, TWENTY_DAY_LAYER)); - goalRoom2.addGoalRoomTodo(goalRoomToDo2); - final GoalRoom savedGoalRoom2 = goalRoomRepository.save(goalRoom2); - - // when - final GoalRoom findGoalRoom1 = goalRoomRepository.findByIdWithContentAndTodos(goalRoom1.getId()) - .get(); - final GoalRoom findGoalRoom2 = goalRoomRepository.findByIdWithContentAndTodos(goalRoom2.getId()) - .get(); - - //then - assertAll( - () -> assertThat(findGoalRoom1) - .usingRecursiveComparison() - .ignoringFields("id") - .isEqualTo(savedGoalRoom1), - () -> assertThat(findGoalRoom2) - .usingRecursiveComparison() - .ignoringFields("id") - .isEqualTo(savedGoalRoom2) - ); - } +// @Test +// void 투두리스트와_함께_골룸을_조회한다() { +// final Member creator = 사용자를_생성한다("name1", "kirikiri@email.com", "identifier1", "password!1"); +// final RoadmapCategory category = 카테고리를_저장한다("여가"); +// final RoadmapNode roadmapNode1 = 로드맵_노드를_생성한다("로드맵 1주차", "로드맵 1주차 내용"); +// final RoadmapNode roadmapNode2 = 로드맵_노드를_생성한다("로드맵 2주차", "로드맵 2주차 내용"); +// final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(List.of(roadmapNode1, roadmapNode2)); +// 로드맵을_생성한다(creator, category, roadmapContent); +// +// final GoalRoomRoadmapNode goalRoomRoadmapNode1 = 골룸_로드맵_노드를_생성한다(TODAY, TODAY.plusDays(10), +// roadmapNode1); +// final GoalRoomRoadmapNode goalRoomRoadmapNode2 = 골룸_로드맵_노드를_생성한다(TODAY.plusDays(11), TODAY.plusDays(20), +// roadmapNode2); +// final Member goalRoomPendingMember = 사용자를_생성한다("name2", "kirikiri@email.com", "identifier2", "password!2"); +// final GoalRoom goalRoom = 골룸을_생성한다("goalroom1", 6, roadmapContent, +// new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode1, goalRoomRoadmapNode2)), goalRoomPendingMember); +// +// final LocalDate today = LocalDate.now(); +// final LocalDate threeDaysAfter = today.plusDays(3); +// goalRoom.addGoalRoomTodo(new GoalRoomToDo( +// new GoalRoomTodoContent("투두1"), new Period(today, threeDaysAfter) +// )); +// goalRoom.addGoalRoomTodo(new GoalRoomToDo( +// new GoalRoomTodoContent("투두2"), new Period(today, threeDaysAfter) +// )); +// goalRoomRepository.save(goalRoom); +// +// // when +// final GoalRoom findGoalRoom = goalRoomRepository.findByIdWithTodos(goalRoom.getId()).get(); +// +// // then +// assertThat(findGoalRoom) +// .usingRecursiveComparison() +// .ignoringFields("id", "createdAt", "updatedAt") +// .isEqualTo(goalRoom); +// } + +// @Test +// void 골룸_아이디로_골룸과_로드맵컨텐츠_골룸노드_투두_정보를_조회한다() { +// final Member creator = 크리에이터를_저장한다(); +// final RoadmapCategory category = 카테고리를_저장한다("게임"); +// final RoadmapNode roadmapNode = 로드맵_노드를_생성한다("로드맵 1주차", "로드맵 1주차 내용"); +// final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(List.of(roadmapNode)); +// 로드맵을_생성한다(creator, category, roadmapContent); +// +// final GoalRoomRoadmapNode goalRoomRoadmapNode1 = 골룸_로드맵_노드를_생성한다(TODAY, TODAY.plusDays(10), +// roadmapNode); +// final GoalRoomRoadmapNode goalRoomRoadmapNode2 = 골룸_로드맵_노드를_생성한다(TODAY, TODAY.plusDays(10), +// roadmapNode); +// +// final GoalRoom goalRoom1 = 골룸을_생성한다("goalroom1", 20, roadmapContent, +// new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode1)), creator); +// final GoalRoomToDo goalRoomToDo1 = new GoalRoomToDo(new GoalRoomTodoContent("할 일 목록"), +// new Period(TODAY, TEN_DAY_LATER)); +// goalRoom1.addGoalRoomTodo(goalRoomToDo1); +// final GoalRoom savedGoalRoom1 = goalRoomRepository.save(goalRoom1); +// +// final GoalRoom goalRoom2 = 골룸을_생성한다("goalroom2", 20, roadmapContent, +// new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode2)), creator); +// final GoalRoomToDo goalRoomToDo2 = new GoalRoomToDo(new GoalRoomTodoContent("우리만의 투두"), +// new Period(TEN_DAY_LATER, TWENTY_DAY_LAYER)); +// goalRoom2.addGoalRoomTodo(goalRoomToDo2); +// final GoalRoom savedGoalRoom2 = goalRoomRepository.save(goalRoom2); +// +// // when +// final GoalRoom findGoalRoom1 = goalRoomRepository.findByIdWithContentAndTodos(goalRoom1.getId()) +// .get(); +// final GoalRoom findGoalRoom2 = goalRoomRepository.findByIdWithContentAndTodos(goalRoom2.getId()) +// .get(); +// +// //then +// assertAll( +// () -> assertThat(findGoalRoom1) +// .usingRecursiveComparison() +// .ignoringFields("id") +// .isEqualTo(savedGoalRoom1), +// () -> assertThat(findGoalRoom2) +// .usingRecursiveComparison() +// .ignoringFields("id") +// .isEqualTo(savedGoalRoom2) +// ); +// } @Test void 사용자가_참가한_모든_골룸들을_조회한다() { @@ -313,9 +278,10 @@ public GoalRoomRepositoryTest(final MemberRepository memberRepository, new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode3)), creator); final Member member = 사용자를_생성한다("팔로워", "010-111-1111", "identifier2", "password2@"); - goalRoom1.join(member); - goalRoom2.join(member); - goalRoom3.join(member); + final Long memberId = member.getId(); + goalRoom1.join(memberId); + goalRoom2.join(memberId); + goalRoom3.join(memberId); goalRoom2.start(); goalRoom3.complete(); @@ -325,8 +291,8 @@ public GoalRoomRepositoryTest(final MemberRepository memberRepository, goalRoomRepository.save(goalRoom4); //when - final List creatorMemberGoalRooms = goalRoomRepository.findByMember(creator); - final List followerMemberGoalRooms = goalRoomRepository.findByMember(member); + final List creatorMemberGoalRooms = goalRoomRepository.findByMemberId(creator.getId()); + final List followerMemberGoalRooms = goalRoomRepository.findByMemberId(member.getId()); //then assertAll( @@ -367,10 +333,11 @@ public GoalRoomRepositoryTest(final MemberRepository memberRepository, new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode3)), creator); final Member member = 사용자를_생성한다("팔로워", "010-111-1111", "identifier2", "password2@"); - goalRoom1.join(member); - goalRoom2.join(member); - goalRoom3.join(member); - goalRoom4.join(member); + final Long memberId = member.getId(); + goalRoom1.join(memberId); + goalRoom2.join(memberId); + goalRoom3.join(memberId); + goalRoom4.join(memberId); goalRoom2.start(); goalRoom3.complete(); @@ -380,11 +347,11 @@ public GoalRoomRepositoryTest(final MemberRepository memberRepository, goalRoomRepository.save(goalRoom4); //when - final List memberRecruitingGoalRooms = goalRoomRepository.findByMemberAndStatus(member, + final List memberRecruitingGoalRooms = goalRoomRepository.findByMemberAndStatus(memberId, GoalRoomStatus.RECRUITING); - final List memberRunningGoalRooms = goalRoomRepository.findByMemberAndStatus(member, + final List memberRunningGoalRooms = goalRoomRepository.findByMemberAndStatus(memberId, GoalRoomStatus.RUNNING); - final List memberCompletedGoalRooms = goalRoomRepository.findByMemberAndStatus(member, + final List memberCompletedGoalRooms = goalRoomRepository.findByMemberAndStatus(memberId, GoalRoomStatus.COMPLETED); //then @@ -454,7 +421,7 @@ public GoalRoomRepositoryTest(final MemberRepository memberRepository, goalRoomRepository.save(goalRoom3); // when - final List goalRooms = goalRoomRepository.findByRoadmap(roadmap); + final List goalRooms = goalRoomRepository.findByRoadmapContentId(roadmapContent.getId()); // then assertThat(goalRooms) @@ -497,12 +464,50 @@ public GoalRoomRepositoryTest(final MemberRepository memberRepository, goalRoomRepository.saveAll(List.of(goalRoom1, goalRoom2, goalRoom3)); // when - final List goalRooms = goalRoomRepository.findByRoadmap(roadmap1); + final List goalRooms = goalRoomRepository.findByRoadmapContentId(roadmapContent1.getId()); // then assertThat(goalRooms).isEqualTo(List.of(goalRoom1, goalRoom2)); } + @Test + void 골룸의_노드의_시작날짜가_오늘인_골룸을_조회한다() { + // given + final Member creator = 크리에이터를_저장한다(); + final RoadmapCategory category = 카테고리를_저장한다("게임"); + final RoadmapNode roadmapNode1 = 로드맵_노드를_생성한다("로드맵 1주차", "로드맵 1주차 내용"); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(List.of(roadmapNode1)); + 로드맵을_생성한다(creator, category, roadmapContent); + + final GoalRoomRoadmapNode goalRoomRoadmapNode1 = 골룸_로드맵_노드를_생성한다(TODAY, TODAY.plusDays(10), + roadmapNode1); + final GoalRoomRoadmapNode goalRoomRoadmapNode2 = 골룸_로드맵_노드를_생성한다(TODAY, TODAY.plusDays(10), + roadmapNode1); + final GoalRoomRoadmapNode goalRoomRoadmapNode3 = 골룸_로드맵_노드를_생성한다(TODAY.plusDays(10), TODAY.plusDays(20), + roadmapNode1); + + final GoalRoom goalRoom1 = 골룸을_생성한다("goalroom1", 20, roadmapContent, + new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode1)), creator); + final GoalRoom goalRoom2 = 골룸을_생성한다("goalroom2", 20, roadmapContent, + new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode2)), creator); + final GoalRoom goalRoom3 = 골룸을_생성한다("goalroom3", 20, roadmapContent, + new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode3)), creator); + + final GoalRoom savedGoalRoom1 = goalRoomRepository.save(goalRoom1); + final GoalRoom savedGoalRoom2 = goalRoomRepository.save(goalRoom2); + goalRoomRepository.save(goalRoom3); + + // when + final List findGoalRooms = goalRoomRepository.findAllRecruitingGoalRoomsByStartDateEarlierThan( + LocalDate.now()); + + // then + assertThat(findGoalRooms) + .usingRecursiveComparison() + .ignoringFields("id") + .isEqualTo(List.of(savedGoalRoom1, savedGoalRoom2)); + } + @Test void 시작날짜가_오늘보다_작거나_같은_모집중인_골룸들을_조회한다() { //given @@ -526,7 +531,8 @@ public GoalRoomRepositoryTest(final MemberRepository memberRepository, goalRoomRepository.saveAll(List.of(todayStartGoalRoom1, futureStartGoalRoom, todayStartGoalRoom2)); // when - final List goalRooms = goalRoomRepository.findAllRecruitingGoalRoomsByStartDateEarlierThan(LocalDate.now()); + final List goalRooms = goalRoomRepository.findAllRecruitingGoalRoomsByStartDateEarlierThan( + LocalDate.now()); // then assertThat(goalRooms).isEqualTo(List.of(todayStartGoalRoom1, todayStartGoalRoom2)); @@ -572,13 +578,13 @@ public GoalRoomRepositoryTest(final MemberRepository memberRepository, private GoalRoomRoadmapNode 골룸_로드맵_노드를_생성한다(final LocalDate startDate, final LocalDate endDate, final RoadmapNode roadmapNode) { - return new GoalRoomRoadmapNode(new Period(startDate, endDate), 1, roadmapNode); + return new GoalRoomRoadmapNode(new Period(startDate, endDate), 1, roadmapNode.getId()); } private GoalRoom 골룸을_생성한다(final String name, final Integer limitedMemberCount, final RoadmapContent roadmapContent, final GoalRoomRoadmapNodes goalRoomRoadmapNodes, final Member member) { final GoalRoom goalRoom = new GoalRoom(new GoalRoomName(name), new LimitedMemberCount(limitedMemberCount), - roadmapContent, member); + roadmapContent.getId(), member.getId()); goalRoom.addAllGoalRoomRoadmapNodes(goalRoomRoadmapNodes); return goalRoom; } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/goalroom/service/GoalRoomCreateServiceTest.java b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/service/GoalRoomCreateServiceTest.java new file mode 100644 index 000000000..05f4be8e7 --- /dev/null +++ b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/service/GoalRoomCreateServiceTest.java @@ -0,0 +1,555 @@ +package co.kirikiri.goalroom.service; + +import static co.kirikiri.goalroom.domain.GoalRoomStatus.RUNNING; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import co.kirikiri.checkfeed.persistence.CheckFeedRepository; +import co.kirikiri.common.exception.BadRequestException; +import co.kirikiri.common.exception.NotFoundException; +import co.kirikiri.common.service.FilePathGenerator; +import co.kirikiri.common.service.FileService; +import co.kirikiri.common.type.ImageContentType; +import co.kirikiri.domain.member.EncryptedPassword; +import co.kirikiri.domain.member.Gender; +import co.kirikiri.domain.member.Member; +import co.kirikiri.domain.member.MemberProfile; +import co.kirikiri.domain.member.vo.Identifier; +import co.kirikiri.domain.member.vo.Nickname; +import co.kirikiri.domain.member.vo.Password; +import co.kirikiri.domain.roadmap.Roadmap; +import co.kirikiri.domain.roadmap.RoadmapCategory; +import co.kirikiri.domain.roadmap.RoadmapContent; +import co.kirikiri.domain.roadmap.RoadmapContents; +import co.kirikiri.domain.roadmap.RoadmapDifficulty; +import co.kirikiri.domain.roadmap.RoadmapNode; +import co.kirikiri.domain.roadmap.RoadmapNodeImage; +import co.kirikiri.domain.roadmap.RoadmapNodeImages; +import co.kirikiri.domain.roadmap.RoadmapNodes; +import co.kirikiri.domain.roadmap.RoadmapStatus; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNode; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNodes; +import co.kirikiri.goalroom.domain.exception.GoalRoomException; +import co.kirikiri.goalroom.domain.vo.GoalRoomName; +import co.kirikiri.goalroom.domain.vo.LimitedMemberCount; +import co.kirikiri.goalroom.domain.vo.Period; +import co.kirikiri.goalroom.persistence.GoalRoomMemberRepository; +import co.kirikiri.goalroom.persistence.GoalRoomRepository; +import co.kirikiri.goalroom.service.dto.request.GoalRoomCreateRequest; +import co.kirikiri.goalroom.service.dto.request.GoalRoomRoadmapNodeRequest; +import co.kirikiri.persistence.member.MemberRepository; +import co.kirikiri.persistence.roadmap.RoadmapContentRepository; +import co.kirikiri.todo.persistence.GoalRoomToDoCheckRepository; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class GoalRoomCreateServiceTest { + + private static final LocalDate TODAY = LocalDate.now(); + private static final LocalDate TEN_DAY_LATER = TODAY.plusDays(10); + private static final LocalDate TWENTY_DAY_LATER = TODAY.plusDays(20); + + private static final RoadmapNode ROADMAP_NODE = new RoadmapNode(1L, "title", "content"); + private static final RoadmapContent ROADMAP_CONTENT = new RoadmapContent(1L, "content"); + private static final RoadmapContent DELETED_ROADMAP_CONTENT = new RoadmapContent(2L, "content2"); + private static final RoadmapNodes ROADMAP_CONTENTS = new RoadmapNodes(new ArrayList<>(List.of(ROADMAP_NODE))); + + private static final Member MEMBER = new Member(1L, new Identifier("identifier2"), null, + new EncryptedPassword(new Password("password!2")), + new Nickname("name2"), null, + new MemberProfile(Gender.FEMALE, "kirikiri@email.com")); + + private static final Roadmap ROADMAP = new Roadmap("roadmap", "introduction", 30, RoadmapDifficulty.DIFFICULT, + MEMBER, new RoadmapCategory("IT")); + + private static final Roadmap DELETED_ROADMAP = new Roadmap("roadmap", "introduction", 30, + RoadmapDifficulty.DIFFICULT, RoadmapStatus.DELETED, MEMBER, new RoadmapCategory("IT")); + + private static Member member; + + @Mock + private GoalRoomRepository goalRoomRepository; + + @Mock + private GoalRoomMemberRepository goalRoomMemberRepository; + + @Mock + private RoadmapContentRepository roadmapContentRepository; + + @Mock + private MemberRepository memberRepository; + + @Mock + private GoalRoomToDoCheckRepository goalRoomToDoCheckRepository; + + @Mock + private CheckFeedRepository checkFeedRepository; + + @Mock + private FileService fileService; + + @Mock + private FilePathGenerator filePathGenerator; + + @InjectMocks + private GoalRoomCreateService goalRoomCreateService; + + @BeforeAll + static void setUp() { + ROADMAP_CONTENT.addNodes(ROADMAP_CONTENTS); + ROADMAP.addContent(ROADMAP_CONTENT); + DELETED_ROADMAP.addContent(DELETED_ROADMAP_CONTENT); + final Identifier identifier = new Identifier("identifier1"); + final Password password = new Password("password1!"); + final EncryptedPassword encryptedPassword = new EncryptedPassword(password); + final Nickname nickname = new Nickname("nickname"); + final String email = "kirikiri@email.com"; + final MemberProfile memberProfile = new MemberProfile(Gender.MALE, email); + member = new Member(identifier, encryptedPassword, nickname, null, memberProfile); + } + + @Test + void 정상적으로_골룸을_생성한다() { + //given + final GoalRoomCreateRequest request = new GoalRoomCreateRequest(1L, "name", + 20, new ArrayList<>(List.of(new GoalRoomRoadmapNodeRequest(1L, 10, TODAY, TEN_DAY_LATER)))); + + given(roadmapContentRepository.findByIdWithRoadmap(anyLong())) + .willReturn(Optional.of(ROADMAP_CONTENT)); + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.of(member)); + given(goalRoomRepository.save(any())) + .willReturn(new GoalRoom(1L, null, null, null, null)); + + //when + assertDoesNotThrow(() -> goalRoomCreateService.create(request, member.getIdentifier().getValue())); + } + + @Test + void 골룸_생성_시_삭제된_로드맵이면_예외를_던진다() { + //given + final GoalRoomCreateRequest request = new GoalRoomCreateRequest(1L, "name", + 20, new ArrayList<>(List.of(new GoalRoomRoadmapNodeRequest(1L, 10, TODAY, TEN_DAY_LATER)))); + + given(roadmapContentRepository.findByIdWithRoadmap(anyLong())) + .willReturn(Optional.of(DELETED_ROADMAP_CONTENT)); + + //when + //then + assertThatThrownBy(() -> goalRoomCreateService.create(request, member.getIdentifier().getValue())) + .isInstanceOf(BadRequestException.class); + } + + @Test + void 골룸_생성_시_존재하지_않은_로드맵_컨텐츠가_들어올때_예외를_던진다() { + //given + final GoalRoomCreateRequest request = new GoalRoomCreateRequest(1L, "name", + 20, new ArrayList<>(List.of(new GoalRoomRoadmapNodeRequest(1L, 10, TODAY, TEN_DAY_LATER)))); + + given(roadmapContentRepository.findByIdWithRoadmap(anyLong())) + .willReturn(Optional.empty()); + + //when + //then + assertThatThrownBy(() -> goalRoomCreateService.create(request, member.getIdentifier().getValue())) + .isInstanceOf(NotFoundException.class); + } + + @Test + void 골룸_생성_시_로드맵_컨텐츠의_노드사이즈와_요청의_노드사이즈가_다를때_예외를_던진다() { + //given + final List wrongSizeGoalRoomRoadmapNodeRequest = new ArrayList<>(List.of( + new GoalRoomRoadmapNodeRequest(1L, 10, TODAY, TEN_DAY_LATER), + new GoalRoomRoadmapNodeRequest(2L, 10, TODAY, TEN_DAY_LATER))); + final GoalRoomCreateRequest request = new GoalRoomCreateRequest(1L, "name", + 20, wrongSizeGoalRoomRoadmapNodeRequest); + + given(roadmapContentRepository.findByIdWithRoadmap(anyLong())) + .willReturn(Optional.of(ROADMAP_CONTENT)); + + //when + //then + assertThatThrownBy(() -> goalRoomCreateService.create(request, member.getIdentifier().getValue())) + .isInstanceOf(BadRequestException.class); + } + + @Test + void 골룸_생성_시_로드맵에_존재하지_않는_노드가_요청으로_들어올때_예외를_던진다() { + //given + final long wrongRoadmapNodId = 2L; + final GoalRoomCreateRequest request = new GoalRoomCreateRequest(1L, "name", + 20, + new ArrayList<>(List.of(new GoalRoomRoadmapNodeRequest(wrongRoadmapNodId, 10, TODAY, TEN_DAY_LATER)))); + + given(roadmapContentRepository.findByIdWithRoadmap(anyLong())) + .willReturn(Optional.of(ROADMAP_CONTENT)); + + //when + //then + assertThatThrownBy(() -> goalRoomCreateService.create(request, member.getIdentifier().getValue())) + .isInstanceOf(NotFoundException.class); + } + + @Test + void 골룸_생성_시_존재하지_않은_회원의_Identifier가_들어올때_예외를_던진다() { + //given + final GoalRoomCreateRequest request = new GoalRoomCreateRequest(1L, "name", + 20, new ArrayList<>(List.of(new GoalRoomRoadmapNodeRequest(1L, 10, TODAY, TEN_DAY_LATER)))); + + given(roadmapContentRepository.findByIdWithRoadmap(anyLong())) + .willReturn(Optional.of(ROADMAP_CONTENT)); + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.empty()); + + //when + //then + assertThatThrownBy(() -> goalRoomCreateService.create(request, member.getIdentifier().getValue())) + .isInstanceOf(NotFoundException.class); + } + + @Test + void 골룸에_참가한다() { + //given + final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "시진이", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + final int limitedMemberCount = 20; + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, limitedMemberCount); + final Member follower = 사용자를_생성한다(2L, "identifier2", "password1!", "팔로워", "kirikiri1@email"); + + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(follower)); + when(goalRoomRepository.findGoalRoomByIdWithPessimisticLock(anyLong())) + .thenReturn(Optional.of(goalRoom)); + + //when + goalRoomCreateService.join("identifier2", 1L); + + //then + assertThat(goalRoom.getCurrentMemberCount()) + .isEqualTo(2); + } + + @Test + void 골룸_참가_요청시_유효한_사용자_아이디가_아니면_예외가_발생한다() { + //given + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.empty()); + + //when, then + assertThatThrownBy(() -> goalRoomCreateService.join("identifier2", 1L)) + .isInstanceOf(NotFoundException.class) + .hasMessage("존재하지 않는 회원입니다."); + } + + @Test + void 골룸_참가_요청시_유효한_골룸_아이디가_아니면_예외가_발생한다() { + //given + final Member follower = 사용자를_생성한다(1L, "identifier1", "password1!", "팔로워", "kirikiri1@email"); + + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(follower)); + when(goalRoomRepository.findGoalRoomByIdWithPessimisticLock(anyLong())) + .thenReturn(Optional.empty()); + + //when, then + assertThatThrownBy(() -> goalRoomCreateService.join("identifier1", 1L)) + .isInstanceOf(NotFoundException.class) + .hasMessage("존재하지 않는 골룸입니다. goalRoomId = 1"); + } + + @Test + void 골룸_참가_요청시_제한_인원이_가득_찼을_경우_예외가_발생한다() { + //given + final Member creator = 사용자를_생성한다(1L, "identifier1", "password1!", "시진이", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + final int limitedMemberCount = 1; + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, limitedMemberCount); + final Member follower = 사용자를_생성한다(1L, "identifier2", "password1!", "팔로워", "kirikiri1@email"); + + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(follower)); + when(goalRoomRepository.findGoalRoomByIdWithPessimisticLock(anyLong())) + .thenReturn(Optional.of(goalRoom)); + + //when, then + assertThatThrownBy(() -> goalRoomCreateService.join("identifier2", 1L)) + .isInstanceOf(GoalRoomException.class) + .hasMessage("제한 인원이 꽉 찬 골룸에는 참여할 수 없습니다."); + } + + @Test + void 골룸_참가_요청시_모집_중이_아닌_경우_예외가_발생한다() { + //given + final List roadmapNodes = 로드맵_노드들을_생성한다(); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); + final Member creator = 사용자를_생성한다(1L, "identifier1", "password1!", "시진이", "kirikiri1@email"); + final int limitedMemberCount = 20; + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, roadmapContent, limitedMemberCount); + final Member follower = 사용자를_생성한다(2L, "identifier2", "password2!", "팔로워", "kirikiri1@email"); + goalRoom.start(); + + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(follower)); + when(goalRoomRepository.findGoalRoomByIdWithPessimisticLock(anyLong())) + .thenReturn(Optional.of(goalRoom)); + + //when, then + assertThatThrownBy(() -> goalRoomCreateService.join("identifier2", 1L)) + .isInstanceOf(GoalRoomException.class) + .hasMessage("모집 중이지 않은 골룸에는 참여할 수 없습니다."); + } + + @Test + void 골룸을_시작한다() { + // given + final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 10); + + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(creator)); + when(goalRoomRepository.findById(any())) + .thenReturn(Optional.of(goalRoom)); + + // when + goalRoomCreateService.startGoalRoom("cokirikiri", 1L); + + // then + assertThat(goalRoom.getStatus()).isEqualTo(RUNNING); + } + + @Test + void 골룸_시작시_존재하지_않는_사용자면_예외가_발생한다() { + // given + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.empty()); + + // expected + assertThatThrownBy(() -> goalRoomCreateService.startGoalRoom("identifier", 1L)) + .isInstanceOf(NotFoundException.class); + } + + @Test + void 골룸_시작시_존재하지_않는_골룸이면_예외가_발생한다() { + // given + final Member member = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); + + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(member)); + when(goalRoomRepository.findById(any())) + .thenReturn(Optional.empty()); + + // expected + assertThatThrownBy(() -> goalRoomCreateService.startGoalRoom("identifier", 1L)) + .isInstanceOf(NotFoundException.class); + } + + @Test + void 골룸을_시작하는_사용자가_골룸의_리더가_아니면_예외가_발생한다() { + // given + final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); + final Member follower = 사용자를_생성한다(2L, "kirikirico", "password2!", "끼리코", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 10); + + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(follower)); + when(goalRoomRepository.findById(any())) + .thenReturn(Optional.of(goalRoom)); + + // expected + assertThatThrownBy(() -> goalRoomCreateService.startGoalRoom("identifier", 1L)) + .isInstanceOf(BadRequestException.class); + } + + @Test + void 골룸_시작시_시작날짜가_아직_지나지_않았으면_예외가_발생한다() { + // given + final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + final GoalRoom goalRoom = 시작_날짜가_미래인_골룸을_생성한다(1L, creator, targetRoadmapContent, 10); + + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(creator)); + when(goalRoomRepository.findById(any())) + .thenReturn(Optional.of(goalRoom)); + + // expected + assertThatThrownBy(() -> goalRoomCreateService.startGoalRoom("cokirikiri", 1L)) + .isInstanceOf(BadRequestException.class); + } + + @Test + void 골룸을_나간다() { + // given + final GoalRoom goalRoom = new GoalRoom(1L, new GoalRoomName("골룸"), new LimitedMemberCount(3), 1L, + MEMBER.getId()); + + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.of(MEMBER)); + given(goalRoomRepository.findById(anyLong())) + .willReturn(Optional.of(goalRoom)); + + // when + // then + assertDoesNotThrow(() -> goalRoomCreateService.leave("identifier2", 1L)); + + } + + @Test + void 골룸을_나갈때_존재하지_않는_회원일_경우_예외가_발생한다() { + // given + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.empty()); + + // when + // then + assertThatThrownBy(() -> goalRoomCreateService.leave("identifier2", 1L)) + .isInstanceOf(NotFoundException.class); + } + + @Test + void 골룸을_나갈때_존재하지_않는_골룸일_경우_예외가_발생한다() { + // given + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.of(member)); + given(goalRoomRepository.findById(anyLong())) + .willReturn(Optional.empty()); + + // when + // then + assertThatThrownBy(() -> goalRoomCreateService.leave("identifier2", 1L)) + .isInstanceOf(NotFoundException.class); + } + + @Test + void 골룸을_나갈때_골룸이_진행중이면_예외가_발생한다() { + // given + final GoalRoom goalRoom = new GoalRoom(1L, new GoalRoomName("골룸"), new LimitedMemberCount(3), 1L, + MEMBER.getId()); + + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.of(member)); + given(goalRoomRepository.findById(anyLong())) + .willReturn(Optional.of(goalRoom)); + + // when + goalRoom.start(); + + // then + assertThatThrownBy(() -> goalRoomCreateService.leave("identifier2", 1L)) + .isInstanceOf(BadRequestException.class); + } + + @Test + void 골룸을_나갈때_골룸에_남아있는_사용자가_없으면_골룸이_삭제된다() { + // given + final GoalRoom goalRoom = new GoalRoom(1L, new GoalRoomName("골룸"), new LimitedMemberCount(3), 1L, + MEMBER.getId()); + + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.of(MEMBER)); + given(goalRoomRepository.findById(anyLong())) + .willReturn(Optional.of(goalRoom)); + + // when + goalRoomCreateService.leave("identifier2", 1L); + + // then + verify(goalRoomRepository, times(1)).delete(goalRoom); + } + + private Member 사용자를_생성한다(final Long memberId, final String identifier, final String password, final String nickname, + final String email) { + final MemberProfile memberProfile = new MemberProfile(Gender.MALE, email); + + return new Member(memberId, new Identifier(identifier), null, new EncryptedPassword(new Password(password)), + new Nickname(nickname), null, memberProfile); + } + + private Roadmap 로드맵을_생성한다(final Member creator) { + final RoadmapCategory category = new RoadmapCategory("게임"); + final List roadmapNodes = 로드맵_노드들을_생성한다(); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); + final Roadmap roadmap = new Roadmap("로드맵 제목", "로드맵 소개글", 10, RoadmapDifficulty.NORMAL, creator, category); + roadmap.addContent(roadmapContent); + return roadmap; + } + + private List 로드맵_노드들을_생성한다() { + final RoadmapNode roadmapNode1 = new RoadmapNode("로드맵 1주차", "로드맵 1주차 내용"); + roadmapNode1.addImages(new RoadmapNodeImages(노드_이미지들을_생성한다())); + final RoadmapNode roadmapNode2 = new RoadmapNode("로드맵 2주차", "로드맵 2주차 내용"); + return List.of(roadmapNode1, roadmapNode2); + } + + private RoadmapContent 로드맵_본문을_생성한다(final List roadmapNodes) { + final RoadmapContent roadmapContent = new RoadmapContent("로드맵 본문"); + roadmapContent.addNodes(new RoadmapNodes(roadmapNodes)); + return roadmapContent; + } + + private List 노드_이미지들을_생성한다() { + return List.of( + new RoadmapNodeImage("node-image1.png", "node-image1-save-path", ImageContentType.PNG), + new RoadmapNodeImage("node-image2.png", "node-image2-save-path", ImageContentType.PNG) + ); + } + + private GoalRoom 골룸을_생성한다(final Long goalRoomId, final Member creator, final RoadmapContent roadmapContent, + final Integer limitedMemberCount) { + final GoalRoom goalRoom = new GoalRoom(goalRoomId, new GoalRoomName("골룸 이름"), + new LimitedMemberCount(limitedMemberCount), roadmapContent.getId(), creator.getId()); + goalRoom.addAllGoalRoomRoadmapNodes(골룸_로드맵_노드들을_생성한다(roadmapContent.getNodes())); + return goalRoom; + } + + private GoalRoom 시작_날짜가_미래인_골룸을_생성한다(final Long goalRoomId, final Member creator, + final RoadmapContent roadmapContent, final Integer limitedMemberCount) { + final GoalRoom goalRoom = new GoalRoom(goalRoomId, new GoalRoomName("골룸 이름"), + new LimitedMemberCount(limitedMemberCount), roadmapContent.getId(), creator.getId()); + final GoalRoomRoadmapNode goalRoomRoadmapNode = new GoalRoomRoadmapNode( + new Period(TEN_DAY_LATER, TWENTY_DAY_LATER), 5, roadmapContent.getNodes().getValues().get(0).getId()); + goalRoom.addAllGoalRoomRoadmapNodes( + new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode))); + return goalRoom; + } + + private GoalRoomRoadmapNodes 골룸_로드맵_노드들을_생성한다(final RoadmapNodes roadmapNodes) { + return new GoalRoomRoadmapNodes(List.of( + new GoalRoomRoadmapNode(new Period(TODAY, TEN_DAY_LATER), 5, roadmapNodes.getValues().get(0).getId()), + new GoalRoomRoadmapNode(new Period(TEN_DAY_LATER.plusDays(1), TWENTY_DAY_LATER), 5, + roadmapNodes.getValues().get(1).getId())) + ); + } +} diff --git a/backend/kirikiri/src/test/java/co/kirikiri/service/GoalRoomReadServiceTest.java b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/service/GoalRoomReadServiceTest.java similarity index 55% rename from backend/kirikiri/src/test/java/co/kirikiri/service/GoalRoomReadServiceTest.java rename to backend/kirikiri/src/test/java/co/kirikiri/goalroom/service/GoalRoomReadServiceTest.java index cf1452150..2294fe573 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/service/GoalRoomReadServiceTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/service/GoalRoomReadServiceTest.java @@ -1,4 +1,4 @@ -package co.kirikiri.service; +package co.kirikiri.goalroom.service; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -8,22 +8,11 @@ import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import co.kirikiri.domain.ImageContentType; -import co.kirikiri.domain.goalroom.CheckFeed; -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomMember; -import co.kirikiri.domain.goalroom.GoalRoomPendingMember; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNode; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNodes; -import co.kirikiri.domain.goalroom.GoalRoomRole; -import co.kirikiri.domain.goalroom.GoalRoomToDo; -import co.kirikiri.domain.goalroom.GoalRoomToDoCheck; -import co.kirikiri.domain.goalroom.vo.GoalRoomName; -import co.kirikiri.domain.goalroom.vo.GoalRoomTodoContent; -import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; -import co.kirikiri.domain.goalroom.vo.Period; + +import co.kirikiri.common.exception.ForbiddenException; +import co.kirikiri.common.exception.NotFoundException; +import co.kirikiri.common.service.FileService; +import co.kirikiri.common.type.ImageContentType; import co.kirikiri.domain.member.EncryptedPassword; import co.kirikiri.domain.member.Gender; import co.kirikiri.domain.member.Member; @@ -35,36 +24,38 @@ import co.kirikiri.domain.roadmap.Roadmap; import co.kirikiri.domain.roadmap.RoadmapCategory; import co.kirikiri.domain.roadmap.RoadmapContent; -import co.kirikiri.domain.roadmap.RoadmapContents; import co.kirikiri.domain.roadmap.RoadmapDifficulty; import co.kirikiri.domain.roadmap.RoadmapNode; import co.kirikiri.domain.roadmap.RoadmapNodeImage; import co.kirikiri.domain.roadmap.RoadmapNodeImages; import co.kirikiri.domain.roadmap.RoadmapNodes; -import co.kirikiri.persistence.goalroom.CheckFeedRepository; -import co.kirikiri.persistence.goalroom.GoalRoomMemberRepository; -import co.kirikiri.persistence.goalroom.GoalRoomPendingMemberRepository; -import co.kirikiri.persistence.goalroom.GoalRoomRepository; -import co.kirikiri.persistence.goalroom.GoalRoomToDoCheckRepository; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomMember; +import co.kirikiri.goalroom.domain.GoalRoomPendingMember; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNode; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNodes; +import co.kirikiri.goalroom.domain.GoalRoomRole; +import co.kirikiri.goalroom.domain.vo.GoalRoomName; +import co.kirikiri.goalroom.domain.vo.LimitedMemberCount; +import co.kirikiri.goalroom.domain.vo.Period; +import co.kirikiri.goalroom.persistence.GoalRoomMemberRepository; +import co.kirikiri.goalroom.persistence.GoalRoomPendingMemberRepository; +import co.kirikiri.goalroom.persistence.GoalRoomRepository; +import co.kirikiri.goalroom.service.dto.GoalRoomMemberSortTypeDto; +import co.kirikiri.goalroom.service.dto.request.GoalRoomStatusTypeRequest; +import co.kirikiri.goalroom.service.dto.response.DashBoardCheckFeedResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomCertifiedResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomMemberResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomRoadmapNodeDetailResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomRoadmapNodeResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomRoadmapNodesResponse; +import co.kirikiri.goalroom.service.dto.response.MemberGoalRoomForListResponse; +import co.kirikiri.goalroom.service.dto.response.MemberGoalRoomResponse; +import co.kirikiri.goalroom.service.dto.response.MemberResponse; import co.kirikiri.persistence.member.MemberRepository; -import co.kirikiri.service.dto.goalroom.GoalRoomMemberSortTypeDto; -import co.kirikiri.service.dto.goalroom.request.GoalRoomStatusTypeRequest; -import co.kirikiri.service.dto.goalroom.response.CheckFeedResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomCertifiedResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomCheckFeedResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomMemberResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomRoadmapNodeDetailResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomRoadmapNodeResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomRoadmapNodesResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomToDoCheckResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomTodoResponse; -import co.kirikiri.service.dto.member.response.MemberGoalRoomForListResponse; -import co.kirikiri.service.dto.member.response.MemberGoalRoomResponse; -import co.kirikiri.service.dto.member.response.MemberResponse; -import co.kirikiri.service.exception.ForbiddenException; -import co.kirikiri.service.exception.NotFoundException; -import co.kirikiri.service.goalroom.GoalRoomReadService; +import co.kirikiri.persistence.roadmap.RoadmapContentRepository; +import co.kirikiri.persistence.roadmap.RoadmapNodeRepository; import java.net.MalformedURLException; import java.net.URL; import java.time.LocalDate; @@ -99,14 +90,20 @@ class GoalRoomReadServiceTest { private GoalRoomPendingMemberRepository goalRoomPendingMemberRepository; @Mock - private GoalRoomToDoCheckRepository goalRoomToDoCheckRepository; + private RoadmapNodeRepository roadmapNodeRepository; @Mock - private CheckFeedRepository checkFeedRepository; + private RoadmapContentRepository roadmapContentRepository; @Mock private FileService fileService; + @Mock + private DashBoardCheckFeedService dashBoardCheckFeedService; + + @Mock + private DashBoardToDoService dashBoardToDoService; + @InjectMocks private GoalRoomReadService goalRoomReadService; @@ -114,14 +111,18 @@ class GoalRoomReadServiceTest { void 골룸_아이디로_골룸_정보를_조회한다() { // given final Member creator = 크리에이터를_생성한다(); - final Roadmap roadmap = 로드맵을_생성한다(creator); + final List roadmapNodes = 로드맵_노드들을_생성한다(); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); + final Roadmap roadmap = 로드맵을_생성한다(creator, roadmapContent); - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom = 골룸을_생성한다(creator, targetRoadmapContent); + final GoalRoom goalRoom = 골룸을_생성한다(creator, roadmapContent); - when(goalRoomRepository.findByIdWithRoadmapContent(any())) - .thenReturn(Optional.of(goalRoom)); + given(goalRoomRepository.findById(any())) + .willReturn(Optional.of(goalRoom)); + given(roadmapContentRepository.findById(anyLong())) + .willReturn(Optional.of(roadmapContent)); + given(roadmapNodeRepository.findAllByRoadmapContent(any())) + .willReturn(roadmapNodes); // when final GoalRoomResponse goalRoomResponse = goalRoomReadService.findGoalRoom(goalRoom.getId()); @@ -135,8 +136,8 @@ class GoalRoomReadServiceTest { @Test void 골룸_조회시_골룸_아이디가_유효하지_않으면_예외가_발생한다() { // given - when(goalRoomRepository.findByIdWithRoadmapContent(any())) - .thenReturn(Optional.empty()); + given(goalRoomRepository.findById(any())) + .willReturn(Optional.empty()); // expected assertThatThrownBy(() -> goalRoomReadService.findGoalRoom(1L)) @@ -144,22 +145,28 @@ class GoalRoomReadServiceTest { } @Test - void 모집중인_골룸에_대해서_골룸_아이디와_사용자_아이디로_골룸_대기_목록_조회시_참여하는_사용자면_참여여부가_true로_반환된다() { + void 모집중인_골룸에_대해서_골룸_아이디와_사용자_아이디로_골룸_조회시_참여하는_사용자면_참여여부가_true로_반환된다() { // given final Member creator = 크리에이터를_생성한다(); - final Roadmap roadmap = 로드맵을_생성한다(creator); + final List roadmapNodes = 로드맵_노드들을_생성한다(); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); + final Roadmap roadmap = 로드맵을_생성한다(creator, roadmapContent); - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom = 골룸을_생성한다(creator, targetRoadmapContent); + final GoalRoom goalRoom = 골룸을_생성한다(creator, roadmapContent); - final GoalRoomPendingMember goalRoomPendingMember = new GoalRoomPendingMember(GoalRoomRole.LEADER, - LocalDateTime.of(2023, 7, 19, 12, 0, 0), goalRoom, creator); + final GoalRoomPendingMember goalRoomPendingMember = new GoalRoomPendingMember(1L, GoalRoomRole.LEADER, + LocalDateTime.of(2023, 7, 19, 12, 0, 0), goalRoom, creator.getId()); - when(goalRoomRepository.findByIdWithRoadmapContent(any())) - .thenReturn(Optional.of(goalRoom)); - when(goalRoomPendingMemberRepository.findByGoalRoomAndMemberIdentifier(any(), any())) - .thenReturn(Optional.of(goalRoomPendingMember)); + given(goalRoomRepository.findById(any())) + .willReturn(Optional.of(goalRoom)); + given(goalRoomPendingMemberRepository.findByGoalRoomAndMemberId(any(), any())) + .willReturn(Optional.of(goalRoomPendingMember)); + given(roadmapContentRepository.findById(anyLong())) + .willReturn(Optional.of(roadmapContent)); + given(roadmapNodeRepository.findAllByRoadmapContent(any())) + .willReturn(roadmapNodes); + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.of(creator)); // when final GoalRoomCertifiedResponse goalRoomResponse = goalRoomReadService.findGoalRoom( @@ -172,19 +179,25 @@ class GoalRoomReadServiceTest { } @Test - void 모집중인_골룸에_대해서_골룸_아이디와_사용자_아이디로_골룸_대기_목록_조회시_참여하지_않는_사용자면_참여여부가_false로_반환된다() { + void 모집중인_골룸에_대해서_골룸_아이디와_사용자_아이디로_골룸_조회시_참여하지_않는_사용자면_참여여부가_false로_반환된다() { // given final Member creator = 크리에이터를_생성한다(); - final Roadmap roadmap = 로드맵을_생성한다(creator); + final List roadmapNodes = 로드맵_노드들을_생성한다(); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); + final Roadmap roadmap = 로드맵을_생성한다(creator, roadmapContent); - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom = 골룸을_생성한다(creator, targetRoadmapContent); + final GoalRoom goalRoom = 골룸을_생성한다(creator, roadmapContent); - when(goalRoomRepository.findByIdWithRoadmapContent(any())) - .thenReturn(Optional.of(goalRoom)); - when(goalRoomPendingMemberRepository.findByGoalRoomAndMemberIdentifier(any(), any())) - .thenReturn(Optional.empty()); + given(goalRoomRepository.findById(any())) + .willReturn(Optional.of(goalRoom)); + given(goalRoomPendingMemberRepository.findByGoalRoomAndMemberId(any(), any())) + .willReturn(Optional.empty()); + given(roadmapContentRepository.findById(anyLong())) + .willReturn(Optional.of(roadmapContent)); + given(roadmapNodeRepository.findAllByRoadmapContent(any())) + .willReturn(roadmapNodes); + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.of(creator)); // when final GoalRoomCertifiedResponse goalRoomResponse = goalRoomReadService.findGoalRoom( @@ -197,23 +210,29 @@ class GoalRoomReadServiceTest { } @Test - void 모집중이지_않은_골룸에_대해서_골룸_아이디와_사용자_아이디로_골룸_사용자_목록_조회시_참여하는_사용자면_참여여부가_true로_반환된다() { + void 모집중이지_않은_골룸에_대해서_골룸_아이디와_사용자_아이디로_골룸_조회시_참여하는_사용자면_참여여부가_true로_반환된다() { // given final Member creator = 크리에이터를_생성한다(); - final Roadmap roadmap = 로드맵을_생성한다(creator); + final List roadmapNodes = 로드맵_노드들을_생성한다(); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); + final Roadmap roadmap = 로드맵을_생성한다(creator, roadmapContent); - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom = 골룸을_생성한다(creator, targetRoadmapContent); + final GoalRoom goalRoom = 골룸을_생성한다(creator, roadmapContent); goalRoom.start(); final GoalRoomMember goalRoomMember = new GoalRoomMember(GoalRoomRole.LEADER, - LocalDateTime.of(2023, 7, 19, 12, 0, 0), goalRoom, creator); + LocalDateTime.of(2023, 7, 19, 12, 0, 0), goalRoom, creator.getId()); - when(goalRoomRepository.findByIdWithRoadmapContent(any())) - .thenReturn(Optional.of(goalRoom)); - when(goalRoomMemberRepository.findByGoalRoomAndMemberIdentifier(any(), any())) - .thenReturn(Optional.of(goalRoomMember)); + given(goalRoomRepository.findById(any())) + .willReturn(Optional.of(goalRoom)); + given(goalRoomMemberRepository.findByGoalRoomAndMemberId(any(), any())) + .willReturn(Optional.of(goalRoomMember)); + given(roadmapContentRepository.findById(anyLong())) + .willReturn(Optional.of(roadmapContent)); + given(roadmapNodeRepository.findAllByRoadmapContent(any())) + .willReturn(roadmapNodes); + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.of(creator)); // when final GoalRoomCertifiedResponse goalRoomResponse = goalRoomReadService.findGoalRoom( @@ -226,20 +245,26 @@ class GoalRoomReadServiceTest { } @Test - void 모집중이지_않은_골룸에_대해서_골룸_아이디와_사용자_아이디로_골룸_사용자_목록_조회시_참여하지_않는_사용자면_참여여부가_false로_반환된다() { + void 모집중이지_않은_골룸에_대해서_골룸_아이디와_사용자_아이디로_골룸_조회시_참여하지_않는_사용자면_참여여부가_false로_반환된다() { // given final Member creator = 크리에이터를_생성한다(); - final Roadmap roadmap = 로드맵을_생성한다(creator); + final List roadmapNodes = 로드맵_노드들을_생성한다(); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); + final Roadmap roadmap = 로드맵을_생성한다(creator, roadmapContent); - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom = 골룸을_생성한다(creator, targetRoadmapContent); + final GoalRoom goalRoom = 골룸을_생성한다(creator, roadmapContent); goalRoom.start(); - when(goalRoomRepository.findByIdWithRoadmapContent(any())) - .thenReturn(Optional.of(goalRoom)); - when(goalRoomMemberRepository.findByGoalRoomAndMemberIdentifier(any(), any())) - .thenReturn(Optional.empty()); + given(goalRoomRepository.findById(any())) + .willReturn(Optional.of(goalRoom)); + given(goalRoomMemberRepository.findByGoalRoomAndMemberId(any(), any())) + .willReturn(Optional.empty()); + given(roadmapContentRepository.findById(anyLong())) + .willReturn(Optional.of(roadmapContent)); + given(roadmapNodeRepository.findAllByRoadmapContent(any())) + .willReturn(roadmapNodes); + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.of(creator)); // when final GoalRoomCertifiedResponse goalRoomResponse = goalRoomReadService.findGoalRoom( @@ -254,8 +279,8 @@ class GoalRoomReadServiceTest { @Test void 골룸_아이디와_사용자_아이디로_골룸_대기_목록_조회시_골룸_아이디가_유효하지_않으면_예외가_발생한다() { // given - when(goalRoomRepository.findByIdWithRoadmapContent(any())) - .thenReturn(Optional.empty()); + given(goalRoomRepository.findById(any())) + .willReturn(Optional.empty()); // expected assertThatThrownBy(() -> goalRoomReadService.findGoalRoom("cokirikiri", 1L)) @@ -268,20 +293,26 @@ class GoalRoomReadServiceTest { final Member creator = 사용자를_생성한다(1L); final Member follower = 사용자를_생성한다(2L); - final Roadmap roadmap = 로드맵을_생성한다(creator); + final List roadmapNodes = 로드맵_노드들을_생성한다(); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); + final Roadmap roadmap = 로드맵을_생성한다(creator, roadmapContent); - final GoalRoom goalRoom = 골룸을_생성한다(creator, roadmap.getContents().getValues().get(0)); + final GoalRoom goalRoom = 골룸을_생성한다(creator, roadmapContent); goalRoom.start(); final GoalRoomMember goalRoomMemberCreator = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), - goalRoom, creator); + goalRoom, creator.getId()); final GoalRoomMember goalRoomMemberFollower = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), - goalRoom, follower); + goalRoom, follower.getId()); given(goalRoomRepository.findById(anyLong())) .willReturn(Optional.of(goalRoom)); given(goalRoomMemberRepository.findByGoalRoomIdOrderedBySortType(anyLong(), any())) .willReturn(List.of(goalRoomMemberCreator, goalRoomMemberFollower)); + given(memberRepository.findWithMemberImageById(1L)) + .willReturn(Optional.of(creator)); + given(memberRepository.findWithMemberImageById(2L)) + .willReturn(Optional.of(follower)); given(fileService.generateUrl(anyString(), any())) .willReturn(new URL("http://example.com/serverFilePath")); @@ -305,20 +336,26 @@ class GoalRoomReadServiceTest { final Member creator = 사용자를_생성한다(1L); final Member follower = 사용자를_생성한다(2L); - final Roadmap roadmap = 로드맵을_생성한다(creator); + final List roadmapNodes = 로드맵_노드들을_생성한다(); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); + final Roadmap roadmap = 로드맵을_생성한다(creator, roadmapContent); final GoalRoom goalRoom = 골룸을_생성한다(creator, roadmap.getContents().getValues().get(0)); goalRoom.complete(); final GoalRoomMember goalRoomMemberCreator = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), - goalRoom, creator); + goalRoom, creator.getId()); final GoalRoomMember goalRoomMemberFollower = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), - goalRoom, follower); + goalRoom, follower.getId()); given(goalRoomRepository.findById(anyLong())) .willReturn(Optional.of(goalRoom)); given(goalRoomMemberRepository.findByGoalRoomIdOrderedBySortType(anyLong(), any())) .willReturn(List.of(goalRoomMemberCreator, goalRoomMemberFollower)); + given(memberRepository.findWithMemberImageById(1L)) + .willReturn(Optional.of(creator)); + given(memberRepository.findWithMemberImageById(2L)) + .willReturn(Optional.of(follower)); given(fileService.generateUrl(anyString(), any())) .willReturn(new URL("http://example.com/serverFilePath")); @@ -342,19 +379,25 @@ class GoalRoomReadServiceTest { final Member creator = 사용자를_생성한다(1L); final Member follower = 사용자를_생성한다(2L); - final Roadmap roadmap = 로드맵을_생성한다(creator); + final List roadmapNodes = 로드맵_노드들을_생성한다(); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); + final Roadmap roadmap = 로드맵을_생성한다(creator, roadmapContent); final GoalRoom goalRoom = 골룸을_생성한다(creator, roadmap.getContents().getValues().get(0)); - final GoalRoomPendingMember goalRoomMemberCreator = new GoalRoomPendingMember(GoalRoomRole.LEADER, - LocalDateTime.now(), goalRoom, creator); - final GoalRoomPendingMember goalRoomMemberFollower = new GoalRoomPendingMember(GoalRoomRole.LEADER, - LocalDateTime.now(), goalRoom, follower); + final GoalRoomPendingMember goalRoomMemberCreator = new GoalRoomPendingMember(1L, GoalRoomRole.LEADER, + LocalDateTime.now(), goalRoom, creator.getId()); + final GoalRoomPendingMember goalRoomMemberFollower = new GoalRoomPendingMember(2L, GoalRoomRole.LEADER, + LocalDateTime.now(), goalRoom, follower.getId()); given(goalRoomRepository.findById(anyLong())) .willReturn(Optional.of(goalRoom)); given(goalRoomPendingMemberRepository.findByGoalRoomIdOrderedBySortType(anyLong(), any())) .willReturn(List.of(goalRoomMemberCreator, goalRoomMemberFollower)); + given(memberRepository.findWithMemberImageById(1L)) + .willReturn(Optional.of(creator)); + given(memberRepository.findWithMemberImageById(2L)) + .willReturn(Optional.of(follower)); given(fileService.generateUrl(anyString(), any())) .willReturn(new URL("http://example.com/serverFilePath")); @@ -367,6 +410,7 @@ class GoalRoomReadServiceTest { "http://example.com/serverFilePath", 0.0); final GoalRoomMemberResponse expectedGoalRoomMemberResponse2 = new GoalRoomMemberResponse(2L, "name1", "http://example.com/serverFilePath", 0.0); + assertThat(result) .isEqualTo(List.of(expectedGoalRoomMemberResponse1, expectedGoalRoomMemberResponse2)); verify(goalRoomMemberRepository, never()).findByGoalRoomIdOrderedBySortType(anyLong(), any()); @@ -385,114 +429,46 @@ class GoalRoomReadServiceTest { .isInstanceOf(NotFoundException.class); } - @Test - void 골룸의_전체_투두리스트를_조회한다() { - // given - final Member creator = 사용자를_생성한다(1L); - final Roadmap roadmap = 로드맵을_생성한다(creator); - final GoalRoom goalRoom = 골룸을_생성한다(creator, roadmap.getContents().getValues().get(0)); - - final GoalRoomToDo firstGoalRoomTodo = new GoalRoomToDo(1L, new GoalRoomTodoContent("투두 1"), - new Period(TODAY, TEN_DAY_LATER)); - final GoalRoomToDo secondGoalRoomTodo = new GoalRoomToDo(2L, new GoalRoomTodoContent("투두 2"), - new Period(TWENTY_DAY_LAYER, THIRTY_DAY_LATER)); - goalRoom.addGoalRoomTodo(firstGoalRoomTodo); - goalRoom.addGoalRoomTodo(secondGoalRoomTodo); - - final GoalRoomMember goalRoomMember = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, - creator); - when(goalRoomMemberRepository.findGoalRoomMember(anyLong(), any())) - .thenReturn(Optional.of(goalRoomMember)); - when(goalRoomRepository.findByIdWithTodos(1L)) - .thenReturn(Optional.of(goalRoom)); - when(goalRoomToDoCheckRepository.findByGoalRoomIdAndMemberIdentifier(anyLong(), any())) - .thenReturn(List.of( - new GoalRoomToDoCheck(goalRoomMember, firstGoalRoomTodo) - )); - - // when - final List responses = goalRoomReadService.findAllGoalRoomTodo(1L, "identifier"); - final List expected = List.of( - new GoalRoomTodoResponse(1L, "투두 1", TODAY, TEN_DAY_LATER, new GoalRoomToDoCheckResponse(true)), - new GoalRoomTodoResponse(2L, "투두 2", TWENTY_DAY_LAYER, THIRTY_DAY_LATER, - new GoalRoomToDoCheckResponse(false))); - - // then - assertThat(responses) - .isEqualTo(expected); - } - - @Test - void 골룸의_투두리스트_조회시_존재하지_않는_골룸이면_예외가_발생한다() { - // given - when(goalRoomRepository.findByIdWithTodos(1L)) - .thenReturn(Optional.empty()); - - // expected - assertThatThrownBy(() -> goalRoomReadService.findAllGoalRoomTodo(1L, "identifier")) - .isInstanceOf(NotFoundException.class); - } - - @Test - void 골룸의_투두리스트_조회시_골룸에_참여하지_않은_사용자면_예외가_발생한다() { - // given - final Member creator = 사용자를_생성한다(1L); - final Roadmap roadmap = 로드맵을_생성한다(creator); - final GoalRoom goalRoom = 골룸을_생성한다(creator, roadmap.getContents().getValues().get(0)); - - final GoalRoomToDo firstGoalRoomTodo = new GoalRoomToDo(1L, new GoalRoomTodoContent("투두 1"), - new Period(TODAY, TEN_DAY_LATER)); - final GoalRoomToDo secondGoalRoomTodo = new GoalRoomToDo(2L, new GoalRoomTodoContent("투두 2"), - new Period(TWENTY_DAY_LAYER, THIRTY_DAY_LATER)); - goalRoom.addGoalRoomTodo(firstGoalRoomTodo); - goalRoom.addGoalRoomTodo(secondGoalRoomTodo); - - when(goalRoomRepository.findByIdWithTodos(1L)) - .thenReturn(Optional.of(goalRoom)); - when(goalRoomMemberRepository.findGoalRoomMember(anyLong(), any())) - .thenReturn(Optional.empty()); - - // expected - assertThatThrownBy(() -> goalRoomReadService.findAllGoalRoomTodo(1L, "identifier")) - .isInstanceOf(ForbiddenException.class); - } - @Test void 진행중인_사용자_단일_골룸을_조회한다() throws MalformedURLException { // given - final RoadmapNode roadmapNode1 = new RoadmapNode("로드맵 1주차", "로드맵 1주차 내용"); - final RoadmapNode roadmapNode2 = new RoadmapNode("로드맵 2주차", "로드맵 2주차 내용"); - final RoadmapNode roadmapNode3 = new RoadmapNode("로드맵 3주차", "로드맵 3주차 내용"); - final RoadmapNode roadmapNode4 = new RoadmapNode("로드맵 4주차", "로드맵 4주차 내용"); + final RoadmapNode roadmapNode1 = new RoadmapNode(1L, "로드맵 1주차", "로드맵 1주차 내용"); + final RoadmapNode roadmapNode2 = new RoadmapNode(2L, "로드맵 2주차", "로드맵 2주차 내용"); + final RoadmapNode roadmapNode3 = new RoadmapNode(3L, "로드맵 3주차", "로드맵 3주차 내용"); + final RoadmapNode roadmapNode4 = new RoadmapNode(4L, "로드맵 4주차", "로드맵 4주차 내용"); final RoadmapNodes roadmapNodes = new RoadmapNodes( List.of(roadmapNode1, roadmapNode2, roadmapNode3, roadmapNode4)); final RoadmapContent roadmapContent = new RoadmapContent("로드맵 본문"); roadmapContent.addNodes(roadmapNodes); final GoalRoomRoadmapNode goalRoomRoadmapNode1 = new GoalRoomRoadmapNode( - new Period(TODAY, TODAY.plusDays(10)), 5, roadmapNode1); + new Period(TODAY, TODAY.plusDays(10)), 5, roadmapNode1.getId()); final GoalRoomRoadmapNode goalRoomRoadmapNode2 = new GoalRoomRoadmapNode( - new Period(TODAY.plusDays(11), TODAY.plusDays(20)), 5, roadmapNode2); + new Period(TODAY.plusDays(11), TODAY.plusDays(20)), 5, roadmapNode2.getId()); final Member member = 사용자를_생성한다(1L); final GoalRoom goalRoom = new GoalRoom(1L, new GoalRoomName("goalroom"), new LimitedMemberCount(10), - roadmapContent, member); + roadmapContent.getId(), member.getId()); goalRoom.start(); goalRoom.addAllGoalRoomRoadmapNodes( new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode1, goalRoomRoadmapNode2))); goalRoom.addAllGoalRoomMembers( - List.of(new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, member))); + List.of(new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, member.getId()))); - final List checkFeeds = 인증_피드_목록을_생성한다(goalRoomRoadmapNode1, member, goalRoom); - given(goalRoomRepository.findByIdWithContentAndTodos(anyLong())) + final List dashBoardCheckFeedResponses = 대시보드_인증_피드_목록_응답을_생성한다(); + given(goalRoomRepository.findByIdWithNodes(anyLong())) .willReturn(Optional.of(goalRoom)); given(memberRepository.findByIdentifier(any())) .willReturn(Optional.of(member)); - given(checkFeedRepository.findByRunningGoalRoomRoadmapNode(any())) - .willReturn(checkFeeds); - given(fileService.generateUrl(anyString(), any())) - .willReturn(new URL("http://example.com/serverFilePath")); + given(roadmapContentRepository.findById(any())) + .willReturn(Optional.of(roadmapContent)); + given(roadmapNodeRepository.findAllByRoadmapContent(any())) + .willReturn(List.of(roadmapNode1, roadmapNode2, roadmapNode3, roadmapNode4)); + given(dashBoardCheckFeedService.findCheckFeedsByNodeAndGoalRoomStatus(any(), any())) + .willReturn(dashBoardCheckFeedResponses); + given(dashBoardToDoService.findMemberCheckedGoalRoomToDoIds(any(), any())) + .willReturn(Collections.emptyList()); final MemberGoalRoomResponse expected = new MemberGoalRoomResponse(goalRoom.getName().getValue(), goalRoom.getStatus().name(), member.getId(), goalRoom.getCurrentMemberCount(), @@ -507,10 +483,14 @@ class GoalRoomReadServiceTest { goalRoomRoadmapNode2.getEndDate(), goalRoomRoadmapNode2.getCheckCount()) )), Collections.emptyList(), List.of( - new CheckFeedResponse(1L, "http://example.com/serverFilePath", "인증 피드 설명", LocalDate.now()), - new CheckFeedResponse(2L, "http://example.com/serverFilePath", "인증 피드 설명", LocalDate.now()), - new CheckFeedResponse(3L, "http://example.com/serverFilePath", "인증 피드 설명", LocalDate.now()), - new CheckFeedResponse(4L, "http://example.com/serverFilePath", "인증 피드 설명", LocalDate.now()) + new DashBoardCheckFeedResponse(1L, "http://example.com/serverFilePath", "인증 피드 설명", + LocalDate.now()), + new DashBoardCheckFeedResponse(2L, "http://example.com/serverFilePath", "인증 피드 설명", + LocalDate.now()), + new DashBoardCheckFeedResponse(3L, "http://example.com/serverFilePath", "인증 피드 설명", + LocalDate.now()), + new DashBoardCheckFeedResponse(4L, "http://example.com/serverFilePath", "인증 피드 설명", + LocalDate.now()) )); //when @@ -526,35 +506,43 @@ class GoalRoomReadServiceTest { @Test void 모집중인_사용자_단일_골룸_조회시_인증피드가_빈_응답을_반환한다() { // given - final RoadmapNode roadmapNode1 = new RoadmapNode("로드맵 1주차", "로드맵 1주차 내용"); - final RoadmapNode roadmapNode2 = new RoadmapNode("로드맵 2주차", "로드맵 2주차 내용"); - final RoadmapNode roadmapNode3 = new RoadmapNode("로드맵 3주차", "로드맵 3주차 내용"); - final RoadmapNode roadmapNode4 = new RoadmapNode("로드맵 4주차", "로드맵 4주차 내용"); + final RoadmapNode roadmapNode1 = new RoadmapNode(1L, "로드맵 1주차", "로드맵 1주차 내용"); + final RoadmapNode roadmapNode2 = new RoadmapNode(2L, "로드맵 2주차", "로드맵 2주차 내용"); + final RoadmapNode roadmapNode3 = new RoadmapNode(3L, "로드맵 3주차", "로드맵 3주차 내용"); + final RoadmapNode roadmapNode4 = new RoadmapNode(4L, "로드맵 4주차", "로드맵 4주차 내용"); final RoadmapNodes roadmapNodes = new RoadmapNodes( List.of(roadmapNode1, roadmapNode2, roadmapNode3, roadmapNode4)); final RoadmapContent roadmapContent = new RoadmapContent("로드맵 본문"); roadmapContent.addNodes(roadmapNodes); final GoalRoomRoadmapNode goalRoomRoadmapNode1 = new GoalRoomRoadmapNode( - new Period(TODAY, TODAY.plusDays(10)), 5, roadmapNode1); + new Period(TODAY, TODAY.plusDays(10)), 5, roadmapNode1.getId()); final GoalRoomRoadmapNode goalRoomRoadmapNode2 = new GoalRoomRoadmapNode( - new Period(TODAY.plusDays(11), TODAY.plusDays(20)), 5, roadmapNode2); + new Period(TODAY.plusDays(11), TODAY.plusDays(20)), 5, roadmapNode2.getId()); final GoalRoomRoadmapNode goalRoomRoadmapNode3 = new GoalRoomRoadmapNode( - new Period(TODAY.plusDays(21), TODAY.plusDays(30)), 5, roadmapNode1); + new Period(TODAY.plusDays(21), TODAY.plusDays(30)), 5, roadmapNode1.getId()); final GoalRoomRoadmapNode goalRoomRoadmapNode4 = new GoalRoomRoadmapNode( - new Period(TODAY.plusDays(31), TODAY.plusDays(40)), 5, roadmapNode2); + new Period(TODAY.plusDays(31), TODAY.plusDays(40)), 5, roadmapNode2.getId()); final Member member = 사용자를_생성한다(1L); final GoalRoom goalRoom = new GoalRoom(1L, new GoalRoomName("goalroom"), new LimitedMemberCount(10), - roadmapContent, member); + roadmapContent.getId(), member.getId()); goalRoom.addAllGoalRoomRoadmapNodes( new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode1, goalRoomRoadmapNode2, goalRoomRoadmapNode3, goalRoomRoadmapNode4))); - given(goalRoomRepository.findByIdWithContentAndTodos(anyLong())) + given(goalRoomRepository.findByIdWithNodes(anyLong())) .willReturn(Optional.of(goalRoom)); given(memberRepository.findByIdentifier(any())) .willReturn(Optional.of(member)); + given(roadmapContentRepository.findById(any())) + .willReturn(Optional.of(roadmapContent)); + given(roadmapNodeRepository.findAllByRoadmapContent(any())) + .willReturn(List.of(roadmapNode1, roadmapNode2, roadmapNode3, roadmapNode4)); + given(dashBoardCheckFeedService.findCheckFeedsByNodeAndGoalRoomStatus(any(), any())) + .willReturn(Collections.emptyList()); + given(dashBoardToDoService.findMemberCheckedGoalRoomToDoIds(any(), any())) + .willReturn(Collections.emptyList()); final MemberGoalRoomResponse expected = new MemberGoalRoomResponse(goalRoom.getName().getValue(), goalRoom.getStatus().name(), member.getId(), goalRoom.getCurrentMemberCount(), @@ -579,43 +567,47 @@ class GoalRoomReadServiceTest { @Test void 종료된_사용자_단일_골룸을_조회시_전체_인증피드를_대상으로_반환한다() throws MalformedURLException { // given - final RoadmapNode roadmapNode1 = new RoadmapNode("로드맵 1주차", "로드맵 1주차 내용"); - final RoadmapNode roadmapNode2 = new RoadmapNode("로드맵 2주차", "로드맵 2주차 내용"); - final RoadmapNode roadmapNode3 = new RoadmapNode("로드맵 3주차", "로드맵 3주차 내용"); - final RoadmapNode roadmapNode4 = new RoadmapNode("로드맵 4주차", "로드맵 4주차 내용"); + final RoadmapNode roadmapNode1 = new RoadmapNode(1L, "로드맵 1주차", "로드맵 1주차 내용"); + final RoadmapNode roadmapNode2 = new RoadmapNode(2L, "로드맵 2주차", "로드맵 2주차 내용"); + final RoadmapNode roadmapNode3 = new RoadmapNode(3L, "로드맵 3주차", "로드맵 3주차 내용"); + final RoadmapNode roadmapNode4 = new RoadmapNode(4L, "로드맵 4주차", "로드맵 4주차 내용"); final RoadmapNodes roadmapNodes = new RoadmapNodes( List.of(roadmapNode1, roadmapNode2, roadmapNode3, roadmapNode4)); final RoadmapContent roadmapContent = new RoadmapContent("로드맵 본문"); roadmapContent.addNodes(roadmapNodes); final GoalRoomRoadmapNode goalRoomRoadmapNode1 = new GoalRoomRoadmapNode( - new Period(TODAY, TODAY.plusDays(10)), 5, roadmapNode1); + new Period(TODAY, TODAY.plusDays(10)), 5, roadmapNode1.getId()); final GoalRoomRoadmapNode goalRoomRoadmapNode2 = new GoalRoomRoadmapNode( - new Period(TODAY.plusDays(11), TODAY.plusDays(20)), 5, roadmapNode2); + new Period(TODAY.plusDays(11), TODAY.plusDays(20)), 5, roadmapNode2.getId()); final GoalRoomRoadmapNode goalRoomRoadmapNode3 = new GoalRoomRoadmapNode( - new Period(TODAY.plusDays(21), TODAY.plusDays(30)), 5, roadmapNode1); + new Period(TODAY.plusDays(21), TODAY.plusDays(30)), 5, roadmapNode1.getId()); final GoalRoomRoadmapNode goalRoomRoadmapNode4 = new GoalRoomRoadmapNode( - new Period(TODAY.plusDays(31), TODAY.plusDays(40)), 5, roadmapNode2); + new Period(TODAY.plusDays(31), TODAY.plusDays(40)), 5, roadmapNode2.getId()); final Member member = 사용자를_생성한다(1L); final GoalRoom goalRoom = new GoalRoom(1L, new GoalRoomName("goalroom"), new LimitedMemberCount(10), - roadmapContent, member); + roadmapContent.getId(), member.getId()); goalRoom.start(); goalRoom.complete(); goalRoom.addAllGoalRoomRoadmapNodes( new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode1, goalRoomRoadmapNode2))); goalRoom.addAllGoalRoomMembers( - List.of(new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, member))); + List.of(new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, member.getId()))); - final List checkFeeds = 인증_피드_목록을_생성한다(goalRoomRoadmapNode1, member, goalRoom); - given(goalRoomRepository.findByIdWithContentAndTodos(anyLong())) + final List dashBoardCheckFeedResponses = 대시보드_인증_피드_목록_응답을_생성한다(); + given(goalRoomRepository.findByIdWithNodes(anyLong())) .willReturn(Optional.of(goalRoom)); given(memberRepository.findByIdentifier(any())) .willReturn(Optional.of(member)); - given(checkFeedRepository.findByGoalRoom(any())) - .willReturn(checkFeeds); - given(fileService.generateUrl(anyString(), any())) - .willReturn(new URL("http://example.com/serverFilePath")); + given(roadmapContentRepository.findById(any())) + .willReturn(Optional.of(roadmapContent)); + given(roadmapNodeRepository.findAllByRoadmapContent(any())) + .willReturn(List.of(roadmapNode1, roadmapNode2, roadmapNode3, roadmapNode4)); + given(dashBoardCheckFeedService.findCheckFeedsByNodeAndGoalRoomStatus(any(), any())) + .willReturn(dashBoardCheckFeedResponses); + given(dashBoardToDoService.findMemberCheckedGoalRoomToDoIds(any(), any())) + .willReturn(Collections.emptyList()); final MemberGoalRoomResponse expected = new MemberGoalRoomResponse(goalRoom.getName().getValue(), goalRoom.getStatus().name(), member.getId(), goalRoom.getCurrentMemberCount(), @@ -630,10 +622,14 @@ class GoalRoomReadServiceTest { goalRoomRoadmapNode2.getEndDate(), goalRoomRoadmapNode2.getCheckCount()) )), Collections.emptyList(), List.of( - new CheckFeedResponse(1L, "http://example.com/serverFilePath", "인증 피드 설명", LocalDate.now()), - new CheckFeedResponse(2L, "http://example.com/serverFilePath", "인증 피드 설명", LocalDate.now()), - new CheckFeedResponse(3L, "http://example.com/serverFilePath", "인증 피드 설명", LocalDate.now()), - new CheckFeedResponse(4L, "http://example.com/serverFilePath", "인증 피드 설명", LocalDate.now()) + new DashBoardCheckFeedResponse(1L, "http://example.com/serverFilePath", "인증 피드 설명", + LocalDate.now()), + new DashBoardCheckFeedResponse(2L, "http://example.com/serverFilePath", "인증 피드 설명", + LocalDate.now()), + new DashBoardCheckFeedResponse(3L, "http://example.com/serverFilePath", "인증 피드 설명", + LocalDate.now()), + new DashBoardCheckFeedResponse(4L, "http://example.com/serverFilePath", "인증 피드 설명", + LocalDate.now()) )); //when @@ -649,8 +645,8 @@ class GoalRoomReadServiceTest { @Test void 사용자_단일_목록_조회_시_유효하지_않은_골룸_아이디일_경우_예외를_반환한다() { //given - when(goalRoomRepository.findByIdWithContentAndTodos(anyLong())) - .thenThrow(new NotFoundException("골룸 정보가 존재하지 않습니다. goalRoomId = 1")); + given(goalRoomRepository.findByIdWithNodes(anyLong())) + .willThrow(new NotFoundException("골룸 정보가 존재하지 않습니다. goalRoomId = 1")); //when, then assertThatThrownBy(() -> goalRoomReadService.findMemberGoalRoom("identifier1", 1L)) @@ -663,16 +659,16 @@ class GoalRoomReadServiceTest { void 사용자_단일_목록_조회_시_유효하지_않은_아이디일_경우_예외를_반환한다() { // given final Member creator = 크리에이터를_생성한다(); - final Roadmap roadmap = 로드맵을_생성한다(creator); + final List roadmapNodes = 로드맵_노드들을_생성한다(); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); + final Roadmap roadmap = 로드맵을_생성한다(creator, roadmapContent); - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom = 골룸을_생성한다(creator, targetRoadmapContent); + final GoalRoom goalRoom = 골룸을_생성한다(creator, roadmapContent); - when(goalRoomRepository.findByIdWithContentAndTodos(anyLong())) - .thenReturn(Optional.of(goalRoom)); - when(memberRepository.findByIdentifier(any())) - .thenThrow(new NotFoundException("존재하지 않는 회원입니다.")); + given(goalRoomRepository.findByIdWithNodes(anyLong())) + .willReturn(Optional.of(goalRoom)); + given(memberRepository.findByIdentifier(any())) + .willThrow(new NotFoundException("존재하지 않는 회원입니다.")); // when, then assertThatThrownBy(() -> goalRoomReadService.findMemberGoalRoom("identifier2", 1L)) @@ -685,16 +681,16 @@ class GoalRoomReadServiceTest { // given final Member creator = 크리에이터를_생성한다(); final Member member = 사용자를_생성한다(2L); - final Roadmap roadmap = 로드맵을_생성한다(creator); + final List roadmapNodes = 로드맵_노드들을_생성한다(); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); + final Roadmap roadmap = 로드맵을_생성한다(creator, roadmapContent); - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom = 골룸을_생성한다(creator, targetRoadmapContent); + final GoalRoom goalRoom = 골룸을_생성한다(creator, roadmapContent); - when(goalRoomRepository.findByIdWithContentAndTodos(anyLong())) - .thenReturn(Optional.of(goalRoom)); - when(memberRepository.findByIdentifier(any())) - .thenReturn(Optional.of(member)); + given(goalRoomRepository.findByIdWithNodes(anyLong())) + .willReturn(Optional.of(goalRoom)); + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.of(member)); // when, then assertThatThrownBy(() -> goalRoomReadService.findMemberGoalRoom("identifier2", 1L)) @@ -706,23 +702,25 @@ class GoalRoomReadServiceTest { void 사용자_골룸_목록을_조회한다() throws MalformedURLException { // given final Member creator = 크리에이터를_생성한다(); - final Roadmap roadmap = 로드맵을_생성한다(creator); + final List roadmapNodes = 로드맵_노드들을_생성한다(); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); + final Roadmap roadmap = 로드맵을_생성한다(creator, roadmapContent); - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom1 = 골룸을_생성한다(creator, targetRoadmapContent); - 골룸을_생성한다(creator, targetRoadmapContent); - final GoalRoom goalRoom3 = 골룸을_생성한다(creator, targetRoadmapContent); - 골룸을_생성한다(creator, targetRoadmapContent); + final GoalRoom goalRoom1 = 골룸을_생성한다(creator, roadmapContent); + 골룸을_생성한다(creator, roadmapContent); + final GoalRoom goalRoom3 = 골룸을_생성한다(creator, roadmapContent); + 골룸을_생성한다(creator, roadmapContent); final Member member = 사용자를_생성한다(2L); - goalRoom1.join(member); - goalRoom3.join(member); + goalRoom1.join(member.getId()); + goalRoom3.join(member.getId()); - when(memberRepository.findByIdentifier(any())) - .thenReturn(Optional.of(member)); - when(goalRoomRepository.findByMember(any())) - .thenReturn(List.of(goalRoom1, goalRoom3)); + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.of(member)); + given(goalRoomRepository.findByMemberId(any())) + .willReturn(List.of(goalRoom1, goalRoom3)); + given(memberRepository.findWithMemberProfileAndImageById(1L)) + .willReturn(Optional.of(creator)); given(fileService.generateUrl(anyString(), any())) .willReturn(new URL("http://example.com/serverFilePath")); @@ -751,10 +749,10 @@ THIRTY_DAY_LATER, new MemberResponse(creator.getId(), creator.getNickname().getV // given final Member creator = 크리에이터를_생성한다(); - when(memberRepository.findByIdentifier(any())) - .thenReturn(Optional.of(creator)); - when(goalRoomRepository.findByMember(any())) - .thenReturn(Collections.emptyList()); + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.of(creator)); + given(goalRoomRepository.findByMemberId(any())) + .willReturn(Collections.emptyList()); // when final List response = goalRoomReadService.findMemberGoalRooms("identifier1"); @@ -766,28 +764,31 @@ THIRTY_DAY_LATER, new MemberResponse(creator.getId(), creator.getNickname().getV @Test void 사용자_골룸_목록_중_모집_중인_상태만_조회한다() throws MalformedURLException { final Member creator = 크리에이터를_생성한다(); - final Roadmap roadmap = 로드맵을_생성한다(creator); + final List roadmapNodes = 로드맵_노드들을_생성한다(); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); + final Roadmap roadmap = 로드맵을_생성한다(creator, roadmapContent); - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom1 = 골룸을_생성한다(creator, targetRoadmapContent); - final GoalRoom goalRoom2 = 골룸을_생성한다(creator, targetRoadmapContent); - final GoalRoom goalRoom3 = 골룸을_생성한다(creator, targetRoadmapContent); - final GoalRoom goalRoom4 = 골룸을_생성한다(creator, targetRoadmapContent); + final GoalRoom goalRoom1 = 골룸을_생성한다(creator, roadmapContent); + final GoalRoom goalRoom2 = 골룸을_생성한다(creator, roadmapContent); + final GoalRoom goalRoom3 = 골룸을_생성한다(creator, roadmapContent); + final GoalRoom goalRoom4 = 골룸을_생성한다(creator, roadmapContent); final Member member = 사용자를_생성한다(2L); - goalRoom1.join(member); - goalRoom2.join(member); - goalRoom3.join(member); - goalRoom4.join(member); + final Long memberId = member.getId(); + goalRoom1.join(memberId); + goalRoom2.join(memberId); + goalRoom3.join(memberId); + goalRoom4.join(memberId); goalRoom3.start(); goalRoom4.complete(); - when(memberRepository.findByIdentifier(any())) - .thenReturn(Optional.of(member)); - when(goalRoomRepository.findByMemberAndStatus(any(), any())) - .thenReturn(List.of(goalRoom1, goalRoom2)); + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.of(member)); + given(goalRoomRepository.findByMemberAndStatus(any(), any())) + .willReturn(List.of(goalRoom1, goalRoom2)); + given(memberRepository.findWithMemberProfileAndImageById(1L)) + .willReturn(Optional.of(creator)); given(fileService.generateUrl(anyString(), any())) .willReturn(new URL("http://example.com/serverFilePath")); @@ -816,35 +817,38 @@ THIRTY_DAY_LATER, new MemberResponse(creator.getId(), creator.getNickname().getV @Test void 사용자_골룸_목록_중_진행_중인_상태만_조회한다() throws MalformedURLException { final Member creator = 크리에이터를_생성한다(); - final Roadmap roadmap = 로드맵을_생성한다(creator); + final List roadmapNodes = 로드맵_노드들을_생성한다(); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); + final Roadmap roadmap = 로드맵을_생성한다(creator, roadmapContent); - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom1 = 골룸을_생성한다(creator, targetRoadmapContent); - final GoalRoom goalRoom2 = 골룸을_생성한다(creator, targetRoadmapContent); - final GoalRoom goalRoom3 = 골룸을_생성한다(creator, targetRoadmapContent); - final GoalRoom goalRoom4 = 골룸을_생성한다(creator, targetRoadmapContent); + final GoalRoom goalRoom1 = 골룸을_생성한다(creator, roadmapContent); + final GoalRoom goalRoom2 = 골룸을_생성한다(creator, roadmapContent); + final GoalRoom goalRoom3 = 골룸을_생성한다(creator, roadmapContent); + final GoalRoom goalRoom4 = 골룸을_생성한다(creator, roadmapContent); final Member member = 사용자를_생성한다(2L); - goalRoom1.join(member); - goalRoom2.join(member); - goalRoom3.join(member); - goalRoom4.join(member); + final Long memberId = member.getId(); + goalRoom1.join(memberId); + goalRoom2.join(memberId); + goalRoom3.join(memberId); + goalRoom4.join(memberId); goalRoom3.start(); goalRoom4.start(); goalRoom3.addAllGoalRoomMembers(List.of( - new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom3, creator), - new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom3, member))); + new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom3, creator.getId()), + new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom3, member.getId()))); goalRoom4.addAllGoalRoomMembers(List.of( - new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom3, creator), - new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom3, member))); + new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom3, creator.getId()), + new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom3, member.getId()))); - when(memberRepository.findByIdentifier(any())) - .thenReturn(Optional.of(member)); - when(goalRoomRepository.findByMemberAndStatus(any(), any())) - .thenReturn(List.of(goalRoom3, goalRoom4)); + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.of(member)); + given(goalRoomRepository.findByMemberAndStatus(any(), any())) + .willReturn(List.of(goalRoom3, goalRoom4)); + given(memberRepository.findWithMemberProfileAndImageById(1L)) + .willReturn(Optional.of(creator)); given(fileService.generateUrl(anyString(), any())) .willReturn(new URL("http://example.com/serverFilePath")); @@ -873,35 +877,38 @@ THIRTY_DAY_LATER, new MemberResponse(creator.getId(), creator.getNickname().getV @Test void 사용자_골룸_목록_중_종료된_상태만_조회한다() throws MalformedURLException { final Member creator = 크리에이터를_생성한다(); - final Roadmap roadmap = 로드맵을_생성한다(creator); + final List roadmapNodes = 로드맵_노드들을_생성한다(); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); + final Roadmap roadmap = 로드맵을_생성한다(creator, roadmapContent); - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom1 = 골룸을_생성한다(creator, targetRoadmapContent); - final GoalRoom goalRoom2 = 골룸을_생성한다(creator, targetRoadmapContent); - final GoalRoom goalRoom3 = 골룸을_생성한다(creator, targetRoadmapContent); - final GoalRoom goalRoom4 = 골룸을_생성한다(creator, targetRoadmapContent); + final GoalRoom goalRoom1 = 골룸을_생성한다(creator, roadmapContent); + final GoalRoom goalRoom2 = 골룸을_생성한다(creator, roadmapContent); + final GoalRoom goalRoom3 = 골룸을_생성한다(creator, roadmapContent); + final GoalRoom goalRoom4 = 골룸을_생성한다(creator, roadmapContent); final Member member = 사용자를_생성한다(2L); - goalRoom1.join(member); - goalRoom2.join(member); - goalRoom3.join(member); - goalRoom4.join(member); + final Long memberId = member.getId(); + goalRoom1.join(memberId); + goalRoom2.join(memberId); + goalRoom3.join(memberId); + goalRoom4.join(memberId); goalRoom3.complete(); goalRoom4.complete(); goalRoom3.addAllGoalRoomMembers(List.of( - new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom3, creator), - new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom3, member))); + new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom3, creator.getId()), + new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom3, member.getId()))); goalRoom4.addAllGoalRoomMembers(List.of( - new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom3, creator), - new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom3, member))); + new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom3, creator.getId()), + new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom3, member.getId()))); - when(memberRepository.findByIdentifier(any())) - .thenReturn(Optional.of(member)); - when(goalRoomRepository.findByMemberAndStatus(any(), any())) - .thenReturn(List.of(goalRoom3, goalRoom4)); + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.of(member)); + given(goalRoomRepository.findByMemberAndStatus(any(), any())) + .willReturn(List.of(goalRoom3, goalRoom4)); + given(memberRepository.findWithMemberProfileAndImageById(1L)) + .willReturn(Optional.of(creator)); given(fileService.generateUrl(anyString(), any())) .willReturn(new URL("http://example.com/serverFilePath")); @@ -931,15 +938,23 @@ THIRTY_DAY_LATER, new MemberResponse(creator.getId(), creator.getNickname().getV void 골룸의_전체_노드를_조회한다() throws MalformedURLException { // given final Member creator = 사용자를_생성한다(1L); - final Roadmap roadmap = 로드맵을_생성한다(creator); - final GoalRoom goalRoom = 골룸을_생성한다(creator, roadmap.getContents().getValues().get(0)); + final List roadmapNodes = 로드맵_노드들을_생성한다(); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); + final Roadmap roadmap = 로드맵을_생성한다(creator, roadmapContent); + final GoalRoom goalRoom = 골룸을_생성한다(creator, roadmap.getContents().getValues().get(0)); final GoalRoomMember goalRoomMember = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, - creator); - when(goalRoomMemberRepository.findGoalRoomMember(anyLong(), any())) - .thenReturn(Optional.of(goalRoomMember)); - when(goalRoomRepository.findByIdWithNodes(1L)) - .thenReturn(Optional.of(goalRoom)); + creator.getId()); + given(goalRoomRepository.findByIdWithNodes(1L)) + .willReturn(Optional.of(goalRoom)); + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.of(creator)); + given(goalRoomMemberRepository.findByGoalRoomIdAndMemberId(anyLong(), any())) + .willReturn(Optional.of(goalRoomMember)); + given(roadmapNodeRepository.findById(1L)) + .willReturn(Optional.of(roadmapNodes.get(0))); + given(roadmapNodeRepository.findById(2L)) + .willReturn(Optional.of(roadmapNodes.get(1))); given(fileService.generateUrl(anyString(), any())) .willReturn(new URL("http://example.com/serverFilePath")); @@ -963,13 +978,18 @@ THIRTY_DAY_LATER, new MemberResponse(creator.getId(), creator.getNickname().getV void 골룸의_노드_조회시_골룸에_참여하지_않은_사용자면_예외가_발생한다() { // given final Member creator = 사용자를_생성한다(1L); - final Roadmap roadmap = 로드맵을_생성한다(creator); + final List roadmapNodes = 로드맵_노드들을_생성한다(); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); + final Roadmap roadmap = 로드맵을_생성한다(creator, roadmapContent); + final GoalRoom goalRoom = 골룸을_생성한다(creator, roadmap.getContents().getValues().get(0)); - when(goalRoomRepository.findByIdWithNodes(1L)) - .thenReturn(Optional.of(goalRoom)); - when(goalRoomMemberRepository.findGoalRoomMember(anyLong(), any())) - .thenReturn(Optional.empty()); + given(goalRoomRepository.findByIdWithNodes(1L)) + .willReturn(Optional.of(goalRoom)); + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.of(creator)); + given(goalRoomMemberRepository.findByGoalRoomIdAndMemberId(anyLong(), any())) + .willReturn(Optional.empty()); // expected assertThatThrownBy(() -> goalRoomReadService.findAllGoalRoomNodes(1L, "identifier")) @@ -979,209 +999,14 @@ THIRTY_DAY_LATER, new MemberResponse(creator.getId(), creator.getNickname().getV @Test void 골룸의_노드_조회시_존재하지_않는_골룸이면_예외가_발생한다() { // given - when(goalRoomRepository.findByIdWithNodes(1L)) - .thenReturn(Optional.empty()); + given(goalRoomRepository.findByIdWithNodes(1L)) + .willReturn(Optional.empty()); // expected assertThatThrownBy(() -> goalRoomReadService.findAllGoalRoomNodes(1L, "identifier")) .isInstanceOf(NotFoundException.class); } - @Test - void 진행중인_골룸의_인증피드를_전체_조회한다() throws MalformedURLException { - // given - final Member creator = 사용자를_생성한다(1L); - final Member follower = 사용자를_생성한다(2L); - - final Roadmap roadmap = 로드맵을_생성한다(creator); - - final GoalRoom goalRoom = 골룸을_생성한다(creator, roadmap.getContents().getValues().get(0)); - goalRoom.start(); - - final GoalRoomMember goalRoomMember1 = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, - creator); - final GoalRoomMember goalRoomMember2 = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, - follower); - final GoalRoomRoadmapNode goalRoomRoadmapNode = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); - - final CheckFeed checkFeed1 = 인증피드를_생성한다("serverFilePath1", "description1", goalRoomRoadmapNode, - goalRoomMember1); - final CheckFeed checkFeed2 = 인증피드를_생성한다("serverFilePath2", "description2", goalRoomRoadmapNode, - goalRoomMember1); - final CheckFeed checkFeed3 = 인증피드를_생성한다("serverFilePath3", "description3", goalRoomRoadmapNode, - goalRoomMember2); - - given(goalRoomRepository.findByIdWithNodes(anyLong())) - .willReturn(Optional.of(goalRoom)); - given(goalRoomMemberRepository.findByGoalRoomAndMemberIdentifier(any(), any())) - .willReturn(Optional.of(goalRoomMember1)); - given(checkFeedRepository.findByRunningGoalRoomRoadmapNodeWithMemberAndMemberImage(any())) - .willReturn(List.of(checkFeed3, checkFeed2, checkFeed1)); - given(fileService.generateUrl(anyString(), any())) - .willReturn(new URL("http://example.com/serverFilePath")); - - // when - final List responses = goalRoomReadService.findGoalRoomCheckFeeds("cokirikiri", 1L); - - // then - final GoalRoomCheckFeedResponse goalRoomCheckFeedResponse1 = new GoalRoomCheckFeedResponse( - new MemberResponse(1L, "name1", "http://example.com/serverFilePath"), - new CheckFeedResponse(1L, "http://example.com/serverFilePath", "description1", LocalDate.now())); - final GoalRoomCheckFeedResponse goalRoomCheckFeedResponse2 = new GoalRoomCheckFeedResponse( - new MemberResponse(1L, "name1", "http://example.com/serverFilePath"), - new CheckFeedResponse(2L, "http://example.com/serverFilePath", "description2", LocalDate.now())); - final GoalRoomCheckFeedResponse goalRoomCheckFeedResponse3 = new GoalRoomCheckFeedResponse( - new MemberResponse(2L, "name1", "http://example.com/serverFilePath"), - new CheckFeedResponse(3L, "http://example.com/serverFilePath", "description3", LocalDate.now())); - final List expected = List.of(goalRoomCheckFeedResponse3, - goalRoomCheckFeedResponse2, goalRoomCheckFeedResponse1); - - assertThat(responses).usingRecursiveComparison() - .ignoringFields("checkFeed.id", "checkFeed.createdAt") - .isEqualTo(expected); - } - - @Test - void 모집중인_골룸의_인증피드를_조회시_빈_값을_반환한다() { - // given - final Member creator = 사용자를_생성한다(1L); - - final Roadmap roadmap = 로드맵을_생성한다(creator); - - final GoalRoom goalRoom = 골룸을_생성한다(creator, roadmap.getContents().getValues().get(0)); - final GoalRoomMember goalRoomMember = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, - creator); - - given(goalRoomRepository.findByIdWithNodes(anyLong())) - .willReturn(Optional.of(goalRoom)); - given(goalRoomMemberRepository.findByGoalRoomAndMemberIdentifier(any(), any())) - .willReturn(Optional.of(goalRoomMember)); - - // when - final List responses = goalRoomReadService.findGoalRoomCheckFeeds("cokirikiri", 1L); - - // then - final List expected = Collections.emptyList(); - - assertThat(responses).isEqualTo(expected); - } - - @Test - void 종료된_골룸의_인증피드를_전체_조회시_모든_기간의_인증피드를_대상으로_반환한다() throws MalformedURLException { - // given - final Member creator = 사용자를_생성한다(1L); - final Member follower = 사용자를_생성한다(2L); - - final Roadmap roadmap = 로드맵을_생성한다(creator); - - final GoalRoom goalRoom = 골룸을_생성한다(creator, roadmap.getContents().getValues().get(0)); - goalRoom.complete(); - final GoalRoomMember goalRoomMember1 = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, - creator); - final GoalRoomMember goalRoomMember2 = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, - follower); - final GoalRoomRoadmapNode goalRoomRoadmapNode = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); - - final CheckFeed checkFeed1 = 인증피드를_생성한다("serverFilePath1", "description1", goalRoomRoadmapNode, - goalRoomMember1); - final CheckFeed checkFeed2 = 인증피드를_생성한다("serverFilePath2", "description2", goalRoomRoadmapNode, - goalRoomMember1); - final CheckFeed checkFeed3 = 인증피드를_생성한다("serverFilePath3", "description3", goalRoomRoadmapNode, - goalRoomMember2); - - given(goalRoomRepository.findByIdWithNodes(anyLong())) - .willReturn(Optional.of(goalRoom)); - given(goalRoomMemberRepository.findByGoalRoomAndMemberIdentifier(any(), any())) - .willReturn(Optional.of(goalRoomMember1)); - given(checkFeedRepository.findByGoalRoomWithMemberAndMemberImage(any())) - .willReturn(List.of(checkFeed3, checkFeed2, checkFeed1)); - given(fileService.generateUrl(anyString(), any())) - .willReturn(new URL("http://example.com/serverFilePath")); - - // when - final List responses = goalRoomReadService.findGoalRoomCheckFeeds("cokirikiri", 1L); - - // then - final GoalRoomCheckFeedResponse goalRoomCheckFeedResponse1 = new GoalRoomCheckFeedResponse( - new MemberResponse(1L, "name1", "http://example.com/serverFilePath"), - new CheckFeedResponse(1L, "http://example.com/serverFilePath", "description1", LocalDate.now())); - final GoalRoomCheckFeedResponse goalRoomCheckFeedResponse2 = new GoalRoomCheckFeedResponse( - new MemberResponse(1L, "name1", "http://example.com/serverFilePath"), - new CheckFeedResponse(2L, "http://example.com/serverFilePath", "description2", LocalDate.now())); - final GoalRoomCheckFeedResponse goalRoomCheckFeedResponse3 = new GoalRoomCheckFeedResponse( - new MemberResponse(2L, "name1", "http://example.com/serverFilePath"), - new CheckFeedResponse(3L, "http://example.com/serverFilePath", "description3", LocalDate.now())); - final List expected = List.of(goalRoomCheckFeedResponse3, - goalRoomCheckFeedResponse2, goalRoomCheckFeedResponse1); - - assertThat(responses).usingRecursiveComparison() - .ignoringFields("checkFeed.id", "checkFeed.createdAt") - .isEqualTo(expected); - } - - @Test - void 골룸의_인증피드를_전체_조회시_현재_진행중인_노드가_없으면_빈_리스트를_반환한다() { - // given - final Member creator = 사용자를_생성한다(1L); - final Member follower = 사용자를_생성한다(2L); - - final Roadmap roadmap = 로드맵을_생성한다(creator); - - final GoalRoom goalRoom = 진행중인_노드가_없는_골룸을_생성한다(creator, roadmap.getContents().getValues().get(0)); - final GoalRoomMember goalRoomMember1 = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, - creator); - final GoalRoomMember goalRoomMember2 = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, - follower); - final GoalRoomRoadmapNode goalRoomRoadmapNode = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); - - 인증피드를_생성한다("serverFilePath1", "description1", goalRoomRoadmapNode, goalRoomMember1); - 인증피드를_생성한다("serverFilePath2", "description2", goalRoomRoadmapNode, goalRoomMember1); - 인증피드를_생성한다("serverFilePath3", "description3", goalRoomRoadmapNode, goalRoomMember2); - - given(goalRoomRepository.findByIdWithNodes(anyLong())) - .willReturn(Optional.of(goalRoom)); - given(goalRoomMemberRepository.findByGoalRoomAndMemberIdentifier(any(), any())) - .willReturn(Optional.of(goalRoomMember1)); - - // when - final List responses = goalRoomReadService.findGoalRoomCheckFeeds("cokirikiri", 1L); - - // then - assertThat(responses).isEmpty(); - } - - @Test - void 골룸의_인증피드를_전체_조회할_때_존재하지_않는_골룸이면_예외가_발생한다() { - // given - given(goalRoomRepository.findByIdWithNodes(anyLong())) - .willThrow(new NotFoundException("존재하지 않는 골룸입니다. goalRoomId = 1")); - - // when - // then - assertThatThrownBy(() -> goalRoomReadService.findGoalRoomCheckFeeds("cokirikiri", 1L)) - .isInstanceOf(NotFoundException.class); - } - - @Test - void 골룸의_인증피드를_전체_조회할_때_골룸에_참여하지_않은_회원이면_예외가_발생한다() { - // given - final Member creator = 사용자를_생성한다(1L); - - final Roadmap roadmap = 로드맵을_생성한다(creator); - - final GoalRoom goalRoom = 골룸을_생성한다(creator, roadmap.getContents().getValues().get(0)); - - given(goalRoomRepository.findByIdWithNodes(anyLong())) - .willReturn(Optional.of(goalRoom)); - given(goalRoomRepository.findByIdWithNodes(anyLong())) - .willThrow(new ForbiddenException("골룸에 참여하지 않은 회원입니다.")); - - // when - // then - assertThatThrownBy(() -> goalRoomReadService.findGoalRoomCheckFeeds("cokirikiri", 1L)) - .isInstanceOf(ForbiddenException.class); - } - private Member 크리에이터를_생성한다() { final MemberImage memberImage = new MemberImage("originalFileName", "default-member-image", ImageContentType.JPG); @@ -1197,24 +1022,22 @@ null, new EncryptedPassword(new Password("password1")), new Nickname("name1"), new MemberProfile(Gender.FEMALE, "kirikiri@email.com")); } - private Roadmap 로드맵을_생성한다(final Member creator) { + private Roadmap 로드맵을_생성한다(final Member creator, final RoadmapContent roadmapContent) { final RoadmapCategory category = new RoadmapCategory("게임"); - final List roadmapNodes = 로드맵_노드들을_생성한다(); - final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); final Roadmap roadmap = new Roadmap("로드맵 제목", "로드맵 소개글", 10, RoadmapDifficulty.NORMAL, creator, category); roadmap.addContent(roadmapContent); return roadmap; } private List 로드맵_노드들을_생성한다() { - final RoadmapNode roadmapNode1 = new RoadmapNode("로드맵 1주차", "로드맵 1주차 내용"); + final RoadmapNode roadmapNode1 = new RoadmapNode(1L, "로드맵 1주차", "로드맵 1주차 내용"); roadmapNode1.addImages(new RoadmapNodeImages(노드_이미지들을_생성한다())); - final RoadmapNode roadmapNode2 = new RoadmapNode("로드맵 2주차", "로드맵 2주차 내용"); + final RoadmapNode roadmapNode2 = new RoadmapNode(2L, "로드맵 2주차", "로드맵 2주차 내용"); return List.of(roadmapNode1, roadmapNode2); } private RoadmapContent 로드맵_본문을_생성한다(final List roadmapNodes) { - final RoadmapContent roadmapContent = new RoadmapContent("로드맵 본문"); + final RoadmapContent roadmapContent = new RoadmapContent(1L, "로드맵 본문"); roadmapContent.addNodes(new RoadmapNodes(roadmapNodes)); return roadmapContent; } @@ -1228,35 +1051,16 @@ null, new EncryptedPassword(new Password("password1")), new Nickname("name1"), private GoalRoom 골룸을_생성한다(final Member member, final RoadmapContent roadmapContent) { final GoalRoom goalRoom = new GoalRoom(new GoalRoomName("골룸"), new LimitedMemberCount(10), - roadmapContent, member); - final List roadmapNodes = roadmapContent.getNodes().getValues(); - - final RoadmapNode firstRoadmapNode = roadmapNodes.get(0); - final GoalRoomRoadmapNode firstGoalRoomRoadmapNode = new GoalRoomRoadmapNode( - 1L, new Period(TODAY, TEN_DAY_LATER), 10, firstRoadmapNode); - - final RoadmapNode secondRoadmapNode = roadmapNodes.get(1); - final GoalRoomRoadmapNode secondGoalRoomRoadmapNode = new GoalRoomRoadmapNode( - 2L, new Period(TWENTY_DAY_LAYER, THIRTY_DAY_LATER), 2, secondRoadmapNode); - - final GoalRoomRoadmapNodes goalRoomRoadmapNodes = new GoalRoomRoadmapNodes( - List.of(firstGoalRoomRoadmapNode, secondGoalRoomRoadmapNode)); - goalRoom.addAllGoalRoomRoadmapNodes(goalRoomRoadmapNodes); - return goalRoom; - } - - private GoalRoom 진행중인_노드가_없는_골룸을_생성한다(final Member member, final RoadmapContent roadmapContent) { - final GoalRoom goalRoom = new GoalRoom(new GoalRoomName("골룸"), new LimitedMemberCount(10), - roadmapContent, member); + roadmapContent.getId(), member.getId()); final List roadmapNodes = roadmapContent.getNodes().getValues(); final RoadmapNode firstRoadmapNode = roadmapNodes.get(0); final GoalRoomRoadmapNode firstGoalRoomRoadmapNode = new GoalRoomRoadmapNode( - 1L, new Period(TEN_DAY_LATER, TWENTY_DAY_LAYER), 10, firstRoadmapNode); + 1L, new Period(TODAY, TEN_DAY_LATER), 10, firstRoadmapNode.getId()); final RoadmapNode secondRoadmapNode = roadmapNodes.get(1); final GoalRoomRoadmapNode secondGoalRoomRoadmapNode = new GoalRoomRoadmapNode( - 2L, new Period(THIRTY_DAY_LATER, THIRTY_DAY_LATER.plusDays(10)), 2, secondRoadmapNode); + 2L, new Period(TWENTY_DAY_LAYER, THIRTY_DAY_LATER), 2, secondRoadmapNode.getId()); final GoalRoomRoadmapNodes goalRoomRoadmapNodes = new GoalRoomRoadmapNodes( List.of(firstGoalRoomRoadmapNode, secondGoalRoomRoadmapNode)); @@ -1279,30 +1083,16 @@ null, new EncryptedPassword(new Password("password1")), new Nickname("name1"), return new GoalRoomCertifiedResponse("골룸", currentMemberCount, 10, goalRoomNodeResponses, 31, isJoined); } - private CheckFeed 인증피드를_생성한다(final String serverFilePath, final String description, - final GoalRoomRoadmapNode goalRoomRoadmapNode, final GoalRoomMember goalRoomMember) { - return new CheckFeed(serverFilePath, ImageContentType.PNG, "fileName", description, goalRoomRoadmapNode, - goalRoomMember, LocalDateTime.now()); - } - - private List 인증_피드_목록을_생성한다(final GoalRoomRoadmapNode node, final Member member, - final GoalRoom goalRoom) { + private List 대시보드_인증_피드_목록_응답을_생성한다() { return List.of( - new CheckFeed("filePath1", ImageContentType.JPEG, "originalFileName1", "인증 피드 설명", node, - new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, member), - LocalDateTime.now()), - new CheckFeed("filePath2", ImageContentType.JPEG, "originalFileName2", "인증 피드 설명", node, - new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, member), - LocalDateTime.now()), - new CheckFeed("filePath3", ImageContentType.JPEG, "originalFileName3", "인증 피드 설명", node, - new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, member), - LocalDateTime.now()), - new CheckFeed("filePath4", ImageContentType.JPEG, "originalFileName4", "인증 피드 설명", node, - new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, member), - LocalDateTime.now()), - new CheckFeed("filePath5", ImageContentType.JPEG, "originalFileName5", "인증 피드 설명", node, - new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, member), - LocalDateTime.now()) + new DashBoardCheckFeedResponse(1L, "http://example.com/serverFilePath", "인증 피드 설명", + LocalDate.now()), + new DashBoardCheckFeedResponse(2L, "http://example.com/serverFilePath", "인증 피드 설명", + LocalDate.now()), + new DashBoardCheckFeedResponse(3L, "http://example.com/serverFilePath", "인증 피드 설명", + LocalDate.now()), + new DashBoardCheckFeedResponse(4L, "http://example.com/serverFilePath", "인증 피드 설명", + LocalDate.now()) ); } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/service/GoalRoomSchedulerTest.java b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/service/GoalRoomSchedulerTest.java similarity index 85% rename from backend/kirikiri/src/test/java/co/kirikiri/service/GoalRoomSchedulerTest.java rename to backend/kirikiri/src/test/java/co/kirikiri/goalroom/service/GoalRoomSchedulerTest.java index f4118210d..47554069f 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/service/GoalRoomSchedulerTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/goalroom/service/GoalRoomSchedulerTest.java @@ -1,7 +1,7 @@ -package co.kirikiri.service; +package co.kirikiri.goalroom.service; -import static co.kirikiri.domain.goalroom.GoalRoomStatus.RECRUITING; -import static co.kirikiri.domain.goalroom.GoalRoomStatus.RUNNING; +import static co.kirikiri.goalroom.domain.GoalRoomStatus.RECRUITING; +import static co.kirikiri.goalroom.domain.GoalRoomStatus.RUNNING; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; import static org.mockito.ArgumentMatchers.anyList; @@ -9,15 +9,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import co.kirikiri.domain.ImageContentType; -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomPendingMember; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNode; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNodes; -import co.kirikiri.domain.goalroom.GoalRoomRole; -import co.kirikiri.domain.goalroom.vo.GoalRoomName; -import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; -import co.kirikiri.domain.goalroom.vo.Period; +import co.kirikiri.common.type.ImageContentType; import co.kirikiri.domain.member.EncryptedPassword; import co.kirikiri.domain.member.Gender; import co.kirikiri.domain.member.Member; @@ -34,10 +26,18 @@ import co.kirikiri.domain.roadmap.RoadmapNodeImage; import co.kirikiri.domain.roadmap.RoadmapNodeImages; import co.kirikiri.domain.roadmap.RoadmapNodes; -import co.kirikiri.persistence.goalroom.GoalRoomMemberRepository; -import co.kirikiri.persistence.goalroom.GoalRoomPendingMemberRepository; -import co.kirikiri.persistence.goalroom.GoalRoomRepository; -import co.kirikiri.service.scheduler.GoalRoomScheduler; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomPendingMember; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNode; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNodes; +import co.kirikiri.goalroom.domain.GoalRoomRole; +import co.kirikiri.goalroom.domain.vo.GoalRoomName; +import co.kirikiri.goalroom.domain.vo.LimitedMemberCount; +import co.kirikiri.goalroom.domain.vo.Period; +import co.kirikiri.goalroom.persistence.GoalRoomMemberRepository; +import co.kirikiri.goalroom.persistence.GoalRoomPendingMemberRepository; +import co.kirikiri.goalroom.persistence.GoalRoomRepository; +import co.kirikiri.goalroom.service.scheduler.GoalRoomScheduler; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.Collections; @@ -60,7 +60,7 @@ class GoalRoomSchedulerTest { @Mock private GoalRoomPendingMemberRepository goalRoomPendingMemberRepository; - + @Mock private GoalRoomMemberRepository goalRoomMemberRepository; @@ -86,9 +86,9 @@ class GoalRoomSchedulerTest { 골룸_대기자를_생성한다(goalRoom1, follower1, GoalRoomRole.FOLLOWER); 골룸_대기자를_생성한다(goalRoom1, follower2, GoalRoomRole.FOLLOWER); - goalRoom1.join(follower1); - goalRoom1.join(follower2); - goalRoom2.join(follower3); + goalRoom1.join(follower1.getId()); + goalRoom1.join(follower2.getId()); + goalRoom2.join(follower3.getId()); when(goalRoomRepository.findAllRecruitingGoalRoomsByStartDateEarlierThan(LocalDate.now())) .thenReturn(List.of(goalRoom1)); @@ -118,9 +118,9 @@ class GoalRoomSchedulerTest { final Member follower2 = 사용자를_생성한다(3L, "identifier2", "password3!", "name2", "kirikiri@email.com"); final Member follower3 = 사용자를_생성한다(4L, "identifier3", "password4!", "name3", "kirikiri@email.com"); - goalRoom1.join(follower1); - goalRoom1.join(follower2); - goalRoom2.join(follower3); + goalRoom1.join(follower1.getId()); + goalRoom1.join(follower2.getId()); + goalRoom2.join(follower3.getId()); when(goalRoomRepository.findAllRecruitingGoalRoomsByStartDateEarlierThan(LocalDate.now())) .thenReturn(Collections.emptyList()); @@ -177,21 +177,21 @@ class GoalRoomSchedulerTest { private GoalRoom 골룸을_생성한다(final Long goalRoomId, final Member creator, final RoadmapContent roadmapContent, final Integer limitedMemberCount) { final GoalRoom goalRoom = new GoalRoom(goalRoomId, new GoalRoomName("골룸 이름"), - new LimitedMemberCount(limitedMemberCount), roadmapContent, creator); + new LimitedMemberCount(limitedMemberCount), roadmapContent.getId(), creator.getId()); goalRoom.addAllGoalRoomRoadmapNodes(골룸_로드맵_노드들을_생성한다(roadmapContent.getNodes())); return goalRoom; } private GoalRoomRoadmapNodes 골룸_로드맵_노드들을_생성한다(final RoadmapNodes roadmapNodes) { return new GoalRoomRoadmapNodes(List.of( - new GoalRoomRoadmapNode(new Period(TODAY, TEN_DAY_LATER), 5, roadmapNodes.getValues().get(0)), + new GoalRoomRoadmapNode(new Period(TODAY, TEN_DAY_LATER), 5, roadmapNodes.getValues().get(0).getId()), new GoalRoomRoadmapNode(new Period(TEN_DAY_LATER.plusDays(1), TWENTY_DAY_LATER), 5, - roadmapNodes.getValues().get(1))) + roadmapNodes.getValues().get(1).getId())) ); } private GoalRoomPendingMember 골룸_대기자를_생성한다(final GoalRoom goalRoom, final Member follower, final GoalRoomRole role) { - return new GoalRoomPendingMember(role, LocalDateTime.of(2023, 7, 19, 12, 0, 0), goalRoom, follower); + return new GoalRoomPendingMember(1L, role, LocalDateTime.of(2023, 7, 19, 12, 0, 0), goalRoom, follower.getId()); } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/infra/AmazonS3FileServiceTest.java b/backend/kirikiri/src/test/java/co/kirikiri/infra/AmazonS3FileServiceTest.java index 602e83e4d..abe6232c4 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/infra/AmazonS3FileServiceTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/infra/AmazonS3FileServiceTest.java @@ -7,8 +7,8 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; -import co.kirikiri.service.dto.FileInformation; -import co.kirikiri.service.exception.ServerException; +import co.kirikiri.common.exception.ServerException; +import co.kirikiri.common.service.dto.FileInformation; import com.amazonaws.AmazonServiceException; import com.amazonaws.Protocol; import com.amazonaws.SdkClientException; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/infra/CloudFrontServiceTest.java b/backend/kirikiri/src/test/java/co/kirikiri/infra/CloudFrontServiceTest.java index 1b56ff0d4..ae8f9aeb6 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/infra/CloudFrontServiceTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/infra/CloudFrontServiceTest.java @@ -4,7 +4,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.when; -import co.kirikiri.service.exception.ServerException; +import co.kirikiri.common.exception.ServerException; import java.net.MalformedURLException; import java.net.URL; import org.junit.jupiter.api.Test; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/AuthenticationIntegrationTest.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/AuthenticationIntegrationTest.java index efc6e01a2..d68f092de 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/integration/AuthenticationIntegrationTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/AuthenticationIntegrationTest.java @@ -6,8 +6,8 @@ import static co.kirikiri.integration.fixture.MemberAPIFixture.DEFAULT_PASSWORD; import static org.assertj.core.api.Assertions.assertThat; +import co.kirikiri.common.service.dto.ErrorResponse; import co.kirikiri.integration.helper.InitIntegrationTest; -import co.kirikiri.service.dto.ErrorResponse; import co.kirikiri.service.dto.auth.request.LoginRequest; import co.kirikiri.service.dto.auth.request.ReissueTokenRequest; import co.kirikiri.service.dto.auth.response.AuthenticationResponse; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomCheckFeedIntegrationTest.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomCheckFeedIntegrationTest.java new file mode 100644 index 000000000..90af24ad4 --- /dev/null +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomCheckFeedIntegrationTest.java @@ -0,0 +1,270 @@ +package co.kirikiri.integration; + +import static co.kirikiri.integration.fixture.AuthenticationAPIFixture.로그인; +import static co.kirikiri.integration.fixture.CommonFixture.BEARER_TOKEN_FORMAT; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸_참가_요청; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸을_생성하고_아이디를_반환한다; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸을_시작한다; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸의_사용자_정보를_정렬_기준없이_조회; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.기본_골룸_생성; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.십일_후; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.오늘; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.인증_피드_등록; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.인증_피드_전체_조회_요청; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.정상적인_골룸_노드_인증_횟수; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.정상적인_골룸_이름; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.정상적인_골룸_제한_인원; +import static co.kirikiri.integration.fixture.MemberAPIFixture.DEFAULT_EMAIL; +import static co.kirikiri.integration.fixture.MemberAPIFixture.회원가입; +import static co.kirikiri.integration.fixture.RoadmapAPIFixture.로드맵_생성; +import static co.kirikiri.integration.fixture.RoadmapAPIFixture.로드맵을_아이디로_조회하고_응답객체를_반환한다; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import co.kirikiri.checkfeed.service.dto.request.CheckFeedRequest; +import co.kirikiri.checkfeed.service.dto.response.GoalRoomCheckFeedResponse; +import co.kirikiri.common.service.dto.ErrorResponse; +import co.kirikiri.goalroom.service.dto.request.GoalRoomCreateRequest; +import co.kirikiri.goalroom.service.dto.request.GoalRoomRoadmapNodeRequest; +import co.kirikiri.goalroom.service.dto.response.GoalRoomMemberResponse; +import co.kirikiri.integration.helper.InitIntegrationTest; +import co.kirikiri.service.dto.auth.request.LoginRequest; +import co.kirikiri.service.dto.member.request.GenderType; +import co.kirikiri.service.dto.member.request.MemberJoinRequest; +import co.kirikiri.service.dto.roadmap.response.RoadmapResponse; +import com.fasterxml.jackson.core.type.TypeReference; +import io.restassured.common.mapper.TypeRef; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; +import java.io.IOException; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; +import org.springframework.mock.web.MockMultipartFile; + +class GoalRoomCheckFeedIntegrationTest extends InitIntegrationTest { + + @Test + void 인증_피드_등록을_요청한다() throws IOException { + //given + final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); + final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); + + final List 골룸_노드_별_기간_요청 = List.of( + new GoalRoomRoadmapNodeRequest(로드맵_응답.content().nodes().get(0).id(), 정상적인_골룸_노드_인증_횟수, 오늘, 십일_후)); + final GoalRoomCreateRequest 골룸_생성_요청 = new GoalRoomCreateRequest(기본_로드맵_아이디, 정상적인_골룸_이름, 정상적인_골룸_제한_인원, + 골룸_노드_별_기간_요청); + final Long 골룸_아이디 = 골룸을_생성하고_아이디를_반환한다(골룸_생성_요청, 기본_로그인_토큰); + 골룸을_시작한다(기본_로그인_토큰, 골룸_아이디); + + final MockMultipartFile 가짜_이미지_객체 = new MockMultipartFile("image", "originalFileName.jpeg", + "image/jpeg", "tempImage".getBytes()); + final CheckFeedRequest 인증_피드_등록_요청 = new CheckFeedRequest(가짜_이미지_객체, "image description"); + + //when + final ExtractableResponse 인증_피드_등록_응답 = 인증_피드_등록(골룸_아이디, 가짜_이미지_객체, 인증_피드_등록_요청, 기본_로그인_토큰); + + //then + assertThat(인증_피드_등록_응답.statusCode()).isEqualTo(HttpStatus.CREATED.value()); + } + + @Test + void 인증용_사진이_없는_경우_인증_피드_등록이_실패한다() throws IOException { + final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); + final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); + + final List 골룸_노드_별_기간_요청 = List.of( + new GoalRoomRoadmapNodeRequest(로드맵_응답.content().nodes().get(0).id(), 정상적인_골룸_노드_인증_횟수, 오늘, 십일_후)); + final GoalRoomCreateRequest 골룸_생성_요청 = new GoalRoomCreateRequest(기본_로드맵_아이디, 정상적인_골룸_이름, 정상적인_골룸_제한_인원, + 골룸_노드_별_기간_요청); + final Long 골룸_아이디 = 골룸을_생성하고_아이디를_반환한다(골룸_생성_요청, 기본_로그인_토큰); + 골룸을_시작한다(기본_로그인_토큰, 골룸_아이디); + + final MockMultipartFile 빈_이미지_객체 = new MockMultipartFile("image", "originalFileName.jpeg", + "image/jpeg", "".getBytes()); + final CheckFeedRequest 인증_피드_등록_요청 = new CheckFeedRequest(빈_이미지_객체, "image description"); + + //when + final ExtractableResponse 인증_피드_등록_응답 = 인증_피드_등록(골룸_아이디, 빈_이미지_객체, + 인증_피드_등록_요청, 기본_로그인_토큰); + final ErrorResponse 예외_메세지 = 인증_피드_등록_응답.as(ErrorResponse.class); + + //then + assertAll( + () -> assertThat(인증_피드_등록_응답.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST.value()), + () -> assertThat(예외_메세지.message()).isEqualTo("인증 피드 등록 시 이미지가 반드시 포함되어야 합니다.") + ); + } + + @Test + void 인증용_사진의_확장자가_허용되지_않는_경우_인증_피드_등록이_실패한다() throws IOException { + final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); + final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); + + final List 골룸_노드_별_기간_요청 = List.of( + new GoalRoomRoadmapNodeRequest(로드맵_응답.content().nodes().get(0).id(), 정상적인_골룸_노드_인증_횟수, 오늘, 십일_후)); + final GoalRoomCreateRequest 골룸_생성_요청 = new GoalRoomCreateRequest(기본_로드맵_아이디, 정상적인_골룸_이름, 정상적인_골룸_제한_인원, + 골룸_노드_별_기간_요청); + final Long 골룸_아이디 = 골룸을_생성하고_아이디를_반환한다(골룸_생성_요청, 기본_로그인_토큰); + 골룸을_시작한다(기본_로그인_토큰, 골룸_아이디); + + final MockMultipartFile 가짜_이미지_객체 = new MockMultipartFile("image", "originalFileName.gif", + "image/gif", "tempImage".getBytes()); + final CheckFeedRequest 인증_피드_등록_요청 = new CheckFeedRequest(가짜_이미지_객체, "image description"); + + //when + final ExtractableResponse 인증_피드_등록_응답 = 인증_피드_등록(골룸_아이디, 가짜_이미지_객체, + 인증_피드_등록_요청, 기본_로그인_토큰); + + final ErrorResponse 예외_메세지 = 인증_피드_등록_응답.as(ErrorResponse.class); + + //then + assertAll( + () -> assertThat(인증_피드_등록_응답.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST.value()), + () -> assertThat(예외_메세지.message()).isEqualTo("허용되지 않는 확장자입니다.") + ); + } + + @Test + void 하루에_두_번_이상_인증_피드_등록을_요청하는_경우_실패한다() throws IOException { + final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); + final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); + + final List 골룸_노드_별_기간_요청 = List.of( + new GoalRoomRoadmapNodeRequest(로드맵_응답.content().nodes().get(0).id(), 정상적인_골룸_노드_인증_횟수, 오늘, 십일_후)); + final GoalRoomCreateRequest 골룸_생성_요청 = new GoalRoomCreateRequest(기본_로드맵_아이디, 정상적인_골룸_이름, 정상적인_골룸_제한_인원, + 골룸_노드_별_기간_요청); + final Long 골룸_아이디 = 골룸을_생성하고_아이디를_반환한다(골룸_생성_요청, 기본_로그인_토큰); + 골룸을_시작한다(기본_로그인_토큰, 골룸_아이디); + + final MockMultipartFile 가짜_이미지_객체 = new MockMultipartFile("image", "originalFileName.jpeg", + "image/webp", "tempImage".getBytes()); + final CheckFeedRequest 인증_피드_등록_요청 = new CheckFeedRequest(가짜_이미지_객체, "image description"); + 인증_피드_등록(골룸_아이디, 가짜_이미지_객체, 인증_피드_등록_요청, 기본_로그인_토큰); + + //when + final ExtractableResponse 인증_피드_등록_응답 = 인증_피드_등록(골룸_아이디, 가짜_이미지_객체, 인증_피드_등록_요청, 기본_로그인_토큰); + final ErrorResponse 예외_메세지 = 인증_피드_등록_응답.as(ErrorResponse.class); + + //then + final List 골룸_사용자_응답 = 골룸의_사용자_정보를_정렬_기준없이_조회(골룸_아이디, 기본_로그인_토큰).as(new TypeRef<>() { + }); + + assertAll( + () -> assertThat(인증_피드_등록_응답.statusCode()) + .isEqualTo(HttpStatus.BAD_REQUEST.value()), + () -> assertThat(예외_메세지.message()).isEqualTo("이미 오늘 인증 피드를 등록하였습니다."), + () -> assertThat(골룸_사용자_응답.get(0).accomplishmentRate()) + .isEqualTo(100 / (double) 정상적인_골룸_노드_인증_횟수) + ); + } + + @Test + void 진행_중인_노드의_허용된_인증_횟수_이상_요청할_경우_실패한다() throws IOException { + final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); + final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); + + final List 골룸_노드_별_기간_요청 = List.of( + new GoalRoomRoadmapNodeRequest(로드맵_응답.content().nodes().get(0).id(), 1, 오늘, 십일_후)); + final GoalRoomCreateRequest 골룸_생성_요청 = new GoalRoomCreateRequest(기본_로드맵_아이디, 정상적인_골룸_이름, 정상적인_골룸_제한_인원, + 골룸_노드_별_기간_요청); + final Long 골룸_아이디 = 골룸을_생성하고_아이디를_반환한다(골룸_생성_요청, 기본_로그인_토큰); + 골룸을_시작한다(기본_로그인_토큰, 골룸_아이디); + + final MockMultipartFile 가짜_이미지_객체 = new MockMultipartFile("image", "originalFileName.jpeg", + "image/webp", "tempImage".getBytes()); + final CheckFeedRequest 인증_피드_등록_요청 = new CheckFeedRequest(가짜_이미지_객체, "image description"); + 인증_피드_등록(골룸_아이디, 가짜_이미지_객체, 인증_피드_등록_요청, 기본_로그인_토큰); + + //when + final ExtractableResponse 인증_피드_등록_응답 = 인증_피드_등록(골룸_아이디, 가짜_이미지_객체, 인증_피드_등록_요청, 기본_로그인_토큰); + + final ErrorResponse 예외_메세지 = 인증_피드_등록_응답.as(ErrorResponse.class); + + //then + assertAll( + () -> assertThat(인증_피드_등록_응답.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST.value()), + () -> assertThat(예외_메세지.message()).isEqualTo("이번 노드에는 최대 " + 1 + "번만 인증 피드를 등록할 수 있습니다.") + ); + } + + @Test + void 골룸의_인증피드를_전체_조회한다() throws IOException { + // given + final MemberJoinRequest 팔로워_회원_가입_요청 = new MemberJoinRequest("identifier2", "paswword2@", + "follower", GenderType.FEMALE, DEFAULT_EMAIL); + final LoginRequest 팔로워_로그인_요청 = new LoginRequest(팔로워_회원_가입_요청.identifier(), 팔로워_회원_가입_요청.password()); + 회원가입(팔로워_회원_가입_요청); + final String 팔로워_액세스_토큰 = String.format(BEARER_TOKEN_FORMAT, 로그인(팔로워_로그인_요청).accessToken()); + + final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); + final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); + + final Long 기본_골룸_아이디 = 기본_골룸_생성(기본_로그인_토큰, 로드맵_응답); + + 골룸_참가_요청(기본_골룸_아이디, 팔로워_액세스_토큰); + 골룸을_시작한다(기본_로그인_토큰, 기본_골룸_아이디); + + final MockMultipartFile 가짜_이미지_객체 = new MockMultipartFile("image", "originalFileName.jpeg", + "image/jpeg", "tempImage".getBytes()); + final CheckFeedRequest 인증_피드_등록_요청1 = new CheckFeedRequest(가짜_이미지_객체, "image description1"); + final CheckFeedRequest 인증_피드_등록_요청2 = new CheckFeedRequest(가짜_이미지_객체, "image description2"); + + 인증_피드_등록(기본_골룸_아이디, 가짜_이미지_객체, 인증_피드_등록_요청1, 기본_로그인_토큰); + 인증_피드_등록(기본_골룸_아이디, 가짜_이미지_객체, 인증_피드_등록_요청2, 팔로워_액세스_토큰); + + //when + final List 인증_피드_전체_조회_요청에_대한_응답 = 인증_피드_전체_조회_요청(팔로워_액세스_토큰, 기본_골룸_아이디) + .as(new TypeRef<>() { + }); + + // then + assertThat(인증_피드_전체_조회_요청에_대한_응답.get(0).checkFeed().description()).isEqualTo(인증_피드_등록_요청2.description()); + assertThat(인증_피드_전체_조회_요청에_대한_응답.get(1).checkFeed().description()).isEqualTo(인증_피드_등록_요청1.description()); + } + + @Test + void 골룸의_인증피드를_전체_조회시_존재하지_않는_골룸인_경우_예외가_발생한다() throws IOException { + // given + //when + final Long 존재하지_않는_골룸_아이디 = 1L; + final ExtractableResponse 인증_피드_전체_조회_요청에_대한_응답 = 인증_피드_전체_조회_요청(기본_로그인_토큰, 존재하지_않는_골룸_아이디); + + // then + final ErrorResponse 인증_피드_전체_조회_응답_바디 = jsonToClass(인증_피드_전체_조회_요청에_대한_응답.asString(), new TypeReference<>() { + }); + assertThat(인증_피드_전체_조회_요청에_대한_응답.statusCode()).isEqualTo(HttpStatus.NOT_FOUND.value()); + assertThat(인증_피드_전체_조회_응답_바디).isEqualTo(new ErrorResponse("존재하지 않는 골룸입니다. goalRoomId = 1")); + } + + @Test + void 골룸의_인증피드를_전체_조회시_골룸에_참여하지_않은_사용자면_예외가_발생한다() throws IOException { + // given + final MemberJoinRequest 다른_회원_회원_가입_요청 = new MemberJoinRequest("identifier2", "paswword2@", + "follower", GenderType.FEMALE, DEFAULT_EMAIL); + final LoginRequest 다른_회원_로그인_요청 = new LoginRequest(다른_회원_회원_가입_요청.identifier(), 다른_회원_회원_가입_요청.password()); + 회원가입(다른_회원_회원_가입_요청); + final String 다른_회원_액세스_토큰 = String.format(BEARER_TOKEN_FORMAT, 로그인(다른_회원_로그인_요청).accessToken()); + + final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); + final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); + + final Long 기본_골룸_아이디 = 기본_골룸_생성(기본_로그인_토큰, 로드맵_응답); + 골룸을_시작한다(기본_로그인_토큰, 기본_골룸_아이디); + + final MockMultipartFile 가짜_이미지_객체 = new MockMultipartFile("image", "originalFileName.jpeg", + "image/jpeg", "tempImage".getBytes()); + final CheckFeedRequest 인증_피드_등록_요청1 = new CheckFeedRequest(가짜_이미지_객체, "image description1"); + + 인증_피드_등록(기본_골룸_아이디, 가짜_이미지_객체, 인증_피드_등록_요청1, 기본_로그인_토큰); + + //when + final ExtractableResponse 인증_피드_전체_조회_요청에_대한_응답 = 인증_피드_전체_조회_요청(다른_회원_액세스_토큰, 기본_골룸_아이디); + + // then + final ErrorResponse 인증_피드_전체_조회_응답_바디 = jsonToClass(인증_피드_전체_조회_요청에_대한_응답.asString(), new TypeReference<>() { + }); + assertThat(인증_피드_전체_조회_요청에_대한_응답.statusCode()).isEqualTo(HttpStatus.FORBIDDEN.value()); + assertThat(인증_피드_전체_조회_응답_바디).isEqualTo(new ErrorResponse("골룸에 참여하지 않은 회원입니다.")); + } +} diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomCreateIntegrationTest.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomCreateIntegrationTest.java index b1f922460..13a41c437 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomCreateIntegrationTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomCreateIntegrationTest.java @@ -6,9 +6,6 @@ import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸_목록_조회_요청; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸_생성; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸_참가_요청; -import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸_투두리스트_추가; -import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸_투두리스트_추가후_아이디를_반환한다; -import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸_투두리스트를_체크한다; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸을_생성하고_아이디를_반환한다; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸을_시작한다; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸의_사용자_정보를_정렬_기준없이_조회; @@ -16,12 +13,9 @@ import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.십일_후; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.오늘; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.이십일_후; -import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.인증_피드_등록; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.정상적인_골룸_노드_인증_횟수; -import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.정상적인_골룸_생성; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.정상적인_골룸_이름; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.정상적인_골룸_제한_인원; -import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.정상적인_골룸_투두_컨텐츠; import static co.kirikiri.integration.fixture.MemberAPIFixture.DEFAULT_EMAIL; import static co.kirikiri.integration.fixture.MemberAPIFixture.요청을_받는_사용자_자신의_정보_조회_요청; import static co.kirikiri.integration.fixture.MemberAPIFixture.회원가입; @@ -30,19 +24,16 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; +import co.kirikiri.common.service.dto.ErrorResponse; +import co.kirikiri.goalroom.service.dto.GoalRoomFilterTypeDto; +import co.kirikiri.goalroom.service.dto.request.GoalRoomCreateRequest; +import co.kirikiri.goalroom.service.dto.request.GoalRoomRoadmapNodeRequest; +import co.kirikiri.goalroom.service.dto.response.GoalRoomMemberResponse; +import co.kirikiri.goalroom.service.dto.response.MemberGoalRoomResponse; import co.kirikiri.integration.helper.InitIntegrationTest; -import co.kirikiri.service.dto.ErrorResponse; import co.kirikiri.service.dto.auth.request.LoginRequest; -import co.kirikiri.service.dto.goalroom.GoalRoomFilterTypeDto; -import co.kirikiri.service.dto.goalroom.request.CheckFeedRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomCreateRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomRoadmapNodeRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomTodoRequest; -import co.kirikiri.service.dto.goalroom.response.GoalRoomMemberResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomToDoCheckResponse; import co.kirikiri.service.dto.member.request.GenderType; import co.kirikiri.service.dto.member.request.MemberJoinRequest; -import co.kirikiri.service.dto.member.response.MemberGoalRoomResponse; import co.kirikiri.service.dto.member.response.MemberInformationResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapGoalRoomResponses; import co.kirikiri.service.dto.roadmap.response.RoadmapResponse; @@ -55,9 +46,7 @@ import java.util.Collections; import java.util.List; import org.junit.jupiter.api.Test; -import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; -import org.springframework.mock.web.MockMultipartFile; class GoalRoomCreateIntegrationTest extends InitIntegrationTest { @@ -289,151 +278,7 @@ class GoalRoomCreateIntegrationTest extends InitIntegrationTest { () -> assertThat(예외_메시지).contains("제한 인원이 꽉 찬 골룸에는 참여할 수 없습니다.") ); } - - @Test - void 인증_피드_등록을_요청한다() throws IOException { - //given - final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); - final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); - - final List 골룸_노드_별_기간_요청 = List.of( - new GoalRoomRoadmapNodeRequest(로드맵_응답.content().nodes().get(0).id(), 정상적인_골룸_노드_인증_횟수, 오늘, 십일_후)); - final GoalRoomCreateRequest 골룸_생성_요청 = new GoalRoomCreateRequest(기본_로드맵_아이디, 정상적인_골룸_이름, 정상적인_골룸_제한_인원, - 골룸_노드_별_기간_요청); - final Long 골룸_아이디 = 골룸을_생성하고_아이디를_반환한다(골룸_생성_요청, 기본_로그인_토큰); - 골룸을_시작한다(기본_로그인_토큰, 골룸_아이디); - - final MockMultipartFile 가짜_이미지_객체 = new MockMultipartFile("image", "originalFileName.jpeg", - "image/jpeg", "tempImage".getBytes()); - final CheckFeedRequest 인증_피드_등록_요청 = new CheckFeedRequest(가짜_이미지_객체, "image description"); - - //when - final ExtractableResponse 인증_피드_등록_응답 = 인증_피드_등록(골룸_아이디, 가짜_이미지_객체, 인증_피드_등록_요청, 기본_로그인_토큰); - - //then - assertThat(인증_피드_등록_응답.statusCode()).isEqualTo(HttpStatus.CREATED.value()); - } - - @Test - void 인증용_사진이_없는_경우_인증_피드_등록이_실패한다() throws IOException { - final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); - final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); - - final List 골룸_노드_별_기간_요청 = List.of( - new GoalRoomRoadmapNodeRequest(로드맵_응답.content().nodes().get(0).id(), 정상적인_골룸_노드_인증_횟수, 오늘, 십일_후)); - final GoalRoomCreateRequest 골룸_생성_요청 = new GoalRoomCreateRequest(기본_로드맵_아이디, 정상적인_골룸_이름, 정상적인_골룸_제한_인원, - 골룸_노드_별_기간_요청); - final Long 골룸_아이디 = 골룸을_생성하고_아이디를_반환한다(골룸_생성_요청, 기본_로그인_토큰); - 골룸을_시작한다(기본_로그인_토큰, 골룸_아이디); - - final MockMultipartFile 빈_이미지_객체 = new MockMultipartFile("image", "originalFileName.jpeg", - "image/jpeg", "".getBytes()); - final CheckFeedRequest 인증_피드_등록_요청 = new CheckFeedRequest(빈_이미지_객체, "image description"); - - //when - final ExtractableResponse 인증_피드_등록_응답 = 인증_피드_등록(골룸_아이디, 빈_이미지_객체, - 인증_피드_등록_요청, 기본_로그인_토큰); - final ErrorResponse 예외_메세지 = 인증_피드_등록_응답.as(ErrorResponse.class); - - //then - assertAll( - () -> assertThat(인증_피드_등록_응답.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST.value()), - () -> assertThat(예외_메세지.message()).isEqualTo("인증 피드 등록 시 이미지가 반드시 포함되어야 합니다.") - ); - } - - @Test - void 인증용_사진의_확장자가_허용되지_않는_경우_인증_피드_등록이_실패한다() throws IOException { - final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); - final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); - - final List 골룸_노드_별_기간_요청 = List.of( - new GoalRoomRoadmapNodeRequest(로드맵_응답.content().nodes().get(0).id(), 정상적인_골룸_노드_인증_횟수, 오늘, 십일_후)); - final GoalRoomCreateRequest 골룸_생성_요청 = new GoalRoomCreateRequest(기본_로드맵_아이디, 정상적인_골룸_이름, 정상적인_골룸_제한_인원, - 골룸_노드_별_기간_요청); - final Long 골룸_아이디 = 골룸을_생성하고_아이디를_반환한다(골룸_생성_요청, 기본_로그인_토큰); - 골룸을_시작한다(기본_로그인_토큰, 골룸_아이디); - - final MockMultipartFile 가짜_이미지_객체 = new MockMultipartFile("image", "originalFileName.gif", - "image/gif", "tempImage".getBytes()); - final CheckFeedRequest 인증_피드_등록_요청 = new CheckFeedRequest(가짜_이미지_객체, "image description"); - - //when - final ExtractableResponse 인증_피드_등록_응답 = 인증_피드_등록(골룸_아이디, 가짜_이미지_객체, - 인증_피드_등록_요청, 기본_로그인_토큰); - - final ErrorResponse 예외_메세지 = 인증_피드_등록_응답.as(ErrorResponse.class); - - //then - assertAll( - () -> assertThat(인증_피드_등록_응답.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST.value()), - () -> assertThat(예외_메세지.message()).isEqualTo("허용되지 않는 확장자입니다.") - ); - } - - @Test - void 하루에_두_번_이상_인증_피드_등록을_요청하는_경우_실패한다() throws IOException { - final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); - final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); - - final List 골룸_노드_별_기간_요청 = List.of( - new GoalRoomRoadmapNodeRequest(로드맵_응답.content().nodes().get(0).id(), 정상적인_골룸_노드_인증_횟수, 오늘, 십일_후)); - final GoalRoomCreateRequest 골룸_생성_요청 = new GoalRoomCreateRequest(기본_로드맵_아이디, 정상적인_골룸_이름, 정상적인_골룸_제한_인원, - 골룸_노드_별_기간_요청); - final Long 골룸_아이디 = 골룸을_생성하고_아이디를_반환한다(골룸_생성_요청, 기본_로그인_토큰); - 골룸을_시작한다(기본_로그인_토큰, 골룸_아이디); - - final MockMultipartFile 가짜_이미지_객체 = new MockMultipartFile("image", "originalFileName.jpeg", - "image/webp", "tempImage".getBytes()); - final CheckFeedRequest 인증_피드_등록_요청 = new CheckFeedRequest(가짜_이미지_객체, "image description"); - 인증_피드_등록(골룸_아이디, 가짜_이미지_객체, 인증_피드_등록_요청, 기본_로그인_토큰); - - //when - final ExtractableResponse 인증_피드_등록_응답 = 인증_피드_등록(골룸_아이디, 가짜_이미지_객체, 인증_피드_등록_요청, 기본_로그인_토큰); - final ErrorResponse 예외_메세지 = 인증_피드_등록_응답.as(ErrorResponse.class); - - //then - final List 골룸_사용자_응답 = 골룸의_사용자_정보를_정렬_기준없이_조회(골룸_아이디, 기본_로그인_토큰).as(new TypeRef<>() { - }); - - assertAll( - () -> assertThat(인증_피드_등록_응답.statusCode()) - .isEqualTo(HttpStatus.BAD_REQUEST.value()), - () -> assertThat(예외_메세지.message()).isEqualTo("이미 오늘 인증 피드를 등록하였습니다."), - () -> assertThat(골룸_사용자_응답.get(0).accomplishmentRate()) - .isEqualTo(100 / (double) 정상적인_골룸_노드_인증_횟수) - ); - } - - @Test - void 진행_중인_노드의_허용된_인증_횟수_이상_요청할_경우_실패한다() throws IOException { - final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); - final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); - - final List 골룸_노드_별_기간_요청 = List.of( - new GoalRoomRoadmapNodeRequest(로드맵_응답.content().nodes().get(0).id(), 1, 오늘, 십일_후)); - final GoalRoomCreateRequest 골룸_생성_요청 = new GoalRoomCreateRequest(기본_로드맵_아이디, 정상적인_골룸_이름, 정상적인_골룸_제한_인원, - 골룸_노드_별_기간_요청); - final Long 골룸_아이디 = 골룸을_생성하고_아이디를_반환한다(골룸_생성_요청, 기본_로그인_토큰); - 골룸을_시작한다(기본_로그인_토큰, 골룸_아이디); - - final MockMultipartFile 가짜_이미지_객체 = new MockMultipartFile("image", "originalFileName.jpeg", - "image/webp", "tempImage".getBytes()); - final CheckFeedRequest 인증_피드_등록_요청 = new CheckFeedRequest(가짜_이미지_객체, "image description"); - 인증_피드_등록(골룸_아이디, 가짜_이미지_객체, 인증_피드_등록_요청, 기본_로그인_토큰); - - //when - final ExtractableResponse 인증_피드_등록_응답 = 인증_피드_등록(골룸_아이디, 가짜_이미지_객체, 인증_피드_등록_요청, 기본_로그인_토큰); - - final ErrorResponse 예외_메세지 = 인증_피드_등록_응답.as(ErrorResponse.class); - - //then - assertAll( - () -> assertThat(인증_피드_등록_응답.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST.value()), - () -> assertThat(예외_메세지.message()).isEqualTo("이번 노드에는 최대 " + 1 + "번만 인증 피드를 등록할 수 있습니다.") - ); - } - + @Test void 이미_참여한_골룸에_참가_요청을_보내면_예외가_발생한다() throws IOException { //given @@ -459,158 +304,6 @@ class GoalRoomCreateIntegrationTest extends InitIntegrationTest { ); } - @Test - void 정상적으로_골룸에_투두리스트를_추가한다() throws IOException { - // given - final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); - final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); - final Long 골룸_아이디 = 정상적인_골룸_생성(기본_로그인_토큰, 기본_로드맵_아이디, 로드맵_응답.content().nodes().get(0).id()); - - final GoalRoomTodoRequest 골룸_투두리스트_추가_요청 = new GoalRoomTodoRequest(정상적인_골룸_투두_컨텐츠, 오늘, 십일_후); - - // when - final ExtractableResponse 골룸_투두리스트_추가 = 골룸_투두리스트_추가(기본_로그인_토큰, 골룸_아이디, 골룸_투두리스트_추가_요청); - - // then - assertThat(골룸_투두리스트_추가.statusCode()).isEqualTo(HttpStatus.CREATED.value()); - final String header = 골룸_투두리스트_추가.response() - .header(HttpHeaders.LOCATION); - assertThat(header).contains("/api/goal-rooms/1/todos/" + header.substring(24)); - } - - @Test - void 골룸에_팔로워가_투두_리스트를_추가할때_예외를_던진다() throws IOException { - // given - final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); - final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); - - final MemberJoinRequest 팔로워_회원가입_요청 = new MemberJoinRequest("identifier2", "password12!@#$%", "follower", - GenderType.MALE, DEFAULT_EMAIL); - 회원가입(팔로워_회원가입_요청); - final String 팔로워_로그인_토큰 = String.format(BEARER_TOKEN_FORMAT, - 로그인(new LoginRequest(팔로워_회원가입_요청.identifier(), 팔로워_회원가입_요청.password())).accessToken()); - - final Long 골룸_아이디 = 정상적인_골룸_생성(기본_로그인_토큰, 로드맵_응답.roadmapId(), 로드맵_응답.content().nodes().get(0).id()); - - final GoalRoomTodoRequest 골룸_투두리스트_추가_요청 = new GoalRoomTodoRequest(정상적인_골룸_투두_컨텐츠, 오늘, 십일_후); - - // when - final ExtractableResponse 골룸_투두리스트_추가 = 골룸_투두리스트_추가(팔로워_로그인_토큰, 골룸_아이디, 골룸_투두리스트_추가_요청); - - // then - final ErrorResponse 골룸_투두리스트_추가_바디 = 골룸_투두리스트_추가.as(new TypeRef<>() { - }); - - assertThat(골룸_투두리스트_추가.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST.value()); - assertThat(골룸_투두리스트_추가_바디).isEqualTo(new ErrorResponse("골룸의 리더만 투두리스트를 추가할 수 있습니다.")); - } - - @Test - void 종료된_골룸에_투두_리스트를_추가할때_예외를_던진다() throws IOException { - //given - final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); - final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); - - final Long 골룸_아이디 = 정상적인_골룸_생성(기본_로그인_토큰, 기본_로드맵_아이디, 로드맵_응답.content().nodes().get(0).id()); - testTransactionService.골룸을_완료시킨다(골룸_아이디); - - final GoalRoomTodoRequest 골룸_투두_리스트_추가_요청 = new GoalRoomTodoRequest(정상적인_골룸_투두_컨텐츠, 오늘, 십일_후); - - //when - final ExtractableResponse 골룸_추가_응답 = 골룸_투두리스트_추가(기본_로그인_토큰, 골룸_아이디, 골룸_투두_리스트_추가_요청); - - //then - final ErrorResponse 골룸_추가_응답_바디 = 골룸_추가_응답.as(new TypeRef<>() { - }); - - assertThat(골룸_추가_응답.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST.value()); - assertThat(골룸_추가_응답_바디).isEqualTo(new ErrorResponse("이미 종료된 골룸입니다.")); - } - - @Test - void 골룸_투두_리스트를_체크한다() throws IOException { - // given - final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); - final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); - - final Long 골룸_아이디 = 정상적인_골룸_생성(기본_로그인_토큰, 기본_로드맵_아이디, 로드맵_응답.content().nodes().get(0).id()); - 골룸을_시작한다(기본_로그인_토큰, 골룸_아이디); - final Long 투두_아이디 = 골룸_투두리스트_추가후_아이디를_반환한다(기본_로그인_토큰, 골룸_아이디); - - // when - final GoalRoomToDoCheckResponse 골룸_투두리스트_체크_응답값 = 골룸_투두리스트를_체크한다(기본_로그인_토큰, 골룸_아이디, 투두_아이디) - .as(new TypeRef<>() { - }); - - // then - final GoalRoomToDoCheckResponse 예상하는_골룸_투두리스트_체크_응답값 = new GoalRoomToDoCheckResponse(true); - assertThat(골룸_투두리스트_체크_응답값) - .isEqualTo(예상하는_골룸_투두리스트_체크_응답값); - } - - @Test - void 골룸_투두리스트_체크를_해제한다() throws IOException { - // given - final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); - final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); - - final Long 골룸_아이디 = 정상적인_골룸_생성(기본_로그인_토큰, 기본_로드맵_아이디, 로드맵_응답.content().nodes().get(0).id()); - 골룸을_시작한다(기본_로그인_토큰, 골룸_아이디); - final Long 투두_아이디 = 골룸_투두리스트_추가후_아이디를_반환한다(기본_로그인_토큰, 골룸_아이디); - - 골룸_투두리스트를_체크한다(기본_로그인_토큰, 골룸_아이디, 투두_아이디); - - // when - final GoalRoomToDoCheckResponse 두번째_골룸_투두리스트_체크_응답값 = 골룸_투두리스트를_체크한다(기본_로그인_토큰, 골룸_아이디, 투두_아이디) - .as(new TypeRef<>() { - }); - - // then - final GoalRoomToDoCheckResponse 예상하는_골룸_투두리스트_체크_응답값 = new GoalRoomToDoCheckResponse(false); - assertThat(두번째_골룸_투두리스트_체크_응답값) - .isEqualTo(예상하는_골룸_투두리스트_체크_응답값); - } - - @Test - void 골룸_투두리스트_체크시_골룸이_존재하지_않으면_예외가_발생한다() { - // given - // when - final ErrorResponse 에러_응답 = 골룸_투두리스트를_체크한다(기본_로그인_토큰, 1L, 1L) - .as(new TypeRef<>() { - }); - - // then - assertThat(에러_응답) - .isEqualTo(new ErrorResponse("골룸이 존재하지 않습니다. goalRoomId = 1")); - } - - @Test - void 골룸_투두리스트_체크시_사용자가_없으면_예외가_발생한다() throws IOException { - // given - final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); - final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); - - final Long 골룸_아이디 = 정상적인_골룸_생성(기본_로그인_토큰, 기본_로드맵_아이디, 로드맵_응답.content().nodes().get(0).id()); - 골룸을_시작한다(기본_로그인_토큰, 골룸_아이디); - final Long 투두_아이디 = 골룸_투두리스트_추가후_아이디를_반환한다(기본_로그인_토큰, 골룸_아이디); - - final MemberJoinRequest 팔로워_회원_가입_요청 = new MemberJoinRequest("identifier2", "paswword2@", - "follower", GenderType.FEMALE, DEFAULT_EMAIL); - final LoginRequest 팔로워_로그인_요청 = new LoginRequest(팔로워_회원_가입_요청.identifier(), 팔로워_회원_가입_요청.password()); - 회원가입(팔로워_회원_가입_요청); - final String 팔로워_액세스_토큰 = String.format(BEARER_TOKEN_FORMAT, 로그인(팔로워_로그인_요청).accessToken()); - - // when - final ErrorResponse 에러_응답 = 골룸_투두리스트를_체크한다(팔로워_액세스_토큰, 골룸_아이디, 투두_아이디) - .as(new TypeRef<>() { - }); - - // then - assertThat(에러_응답) - .isEqualTo(new ErrorResponse("골룸에 사용자가 존재하지 않습니다. goalRoomId = " + 골룸_아이디 + - " memberIdentifier = " + 팔로워_회원_가입_요청.identifier())); - } - @Test void 정상적으로_모집중인_골룸을_나간다() throws IOException { //given diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomReadIntegrationTest.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomReadIntegrationTest.java index bed2603b5..6b3e97fd9 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomReadIntegrationTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomReadIntegrationTest.java @@ -2,12 +2,12 @@ import static co.kirikiri.integration.fixture.AuthenticationAPIFixture.로그인; import static co.kirikiri.integration.fixture.CommonFixture.BEARER_TOKEN_FORMAT; +import static co.kirikiri.integration.fixture.CommonFixture.LOCATION; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸_노드_조회; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸_생성; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸_아이디로_골룸을_조회; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸_아이디와_토큰으로_골룸_정보를_조회; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸_참가_요청; -import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸_투두리스트_조회; -import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸_투두리스트_추가; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸을_생성하고_아이디를_반환한다; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸을_시작한다; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸의_사용자_정보를_전체_조회; @@ -17,12 +17,10 @@ import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.사용자가_참여한_골룸_중_골룸_진행_상태에_따라_목록을_조회; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.사용자의_모든_골룸_조회; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.사용자의_특정_골룸_정보를_조회한다; -import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.삼십일_후; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.십일_후; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.오늘; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.이십일_후; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.인증_피드_등록; -import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.인증_피드_전체_조회_요청; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.정상적인_골룸_노드_인증_횟수; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.정상적인_골룸_이름; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.정상적인_골룸_제한_인원; @@ -32,42 +30,35 @@ import static co.kirikiri.integration.fixture.RoadmapAPIFixture.로드맵을_아이디로_조회하고_응답객체를_반환한다; import static org.assertj.core.api.Assertions.assertThat; +import co.kirikiri.checkfeed.service.dto.request.CheckFeedRequest; +import co.kirikiri.common.service.dto.ErrorResponse; +import co.kirikiri.goalroom.persistence.dto.RoadmapGoalRoomsOrderType; +import co.kirikiri.goalroom.service.dto.GoalRoomMemberSortTypeDto; +import co.kirikiri.goalroom.service.dto.request.GoalRoomCreateRequest; +import co.kirikiri.goalroom.service.dto.request.GoalRoomRoadmapNodeRequest; +import co.kirikiri.goalroom.service.dto.response.DashBoardCheckFeedResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomCertifiedResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomMemberResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomRoadmapNodeDetailResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomRoadmapNodeResponse; +import co.kirikiri.goalroom.service.dto.response.GoalRoomRoadmapNodesResponse; +import co.kirikiri.goalroom.service.dto.response.MemberGoalRoomForListResponse; +import co.kirikiri.goalroom.service.dto.response.MemberGoalRoomResponse; import co.kirikiri.integration.helper.InitIntegrationTest; -import co.kirikiri.persistence.goalroom.dto.RoadmapGoalRoomsOrderType; -import co.kirikiri.service.dto.ErrorResponse; import co.kirikiri.service.dto.auth.request.LoginRequest; -import co.kirikiri.service.dto.goalroom.GoalRoomMemberSortTypeDto; -import co.kirikiri.service.dto.goalroom.request.CheckFeedRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomCreateRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomRoadmapNodeRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomTodoRequest; -import co.kirikiri.service.dto.goalroom.response.CheckFeedResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomCertifiedResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomCheckFeedResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomMemberResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomRoadmapNodeDetailResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomRoadmapNodeResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomRoadmapNodesResponse; -import co.kirikiri.service.dto.goalroom.response.GoalRoomTodoResponse; import co.kirikiri.service.dto.member.request.GenderType; import co.kirikiri.service.dto.member.request.MemberJoinRequest; -import co.kirikiri.service.dto.member.response.MemberGoalRoomForListResponse; -import co.kirikiri.service.dto.member.response.MemberGoalRoomResponse; import co.kirikiri.service.dto.roadmap.request.RoadmapDifficultyType; import co.kirikiri.service.dto.roadmap.request.RoadmapNodeSaveRequest; import co.kirikiri.service.dto.roadmap.request.RoadmapSaveRequest; import co.kirikiri.service.dto.roadmap.response.RoadmapGoalRoomResponses; import co.kirikiri.service.dto.roadmap.response.RoadmapResponse; -import com.fasterxml.jackson.core.type.TypeReference; import io.restassured.common.mapper.TypeRef; -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; import java.io.IOException; import java.time.LocalDate; import java.util.List; import org.junit.jupiter.api.Test; -import org.springframework.http.HttpStatus; import org.springframework.mock.web.MockMultipartFile; class GoalRoomReadIntegrationTest extends InitIntegrationTest { @@ -106,72 +97,6 @@ class GoalRoomReadIntegrationTest extends InitIntegrationTest { assertThat(골룸_응답값.name()).isEqualTo(정상적인_골룸_이름); } - @Test - void 골룸_투두리스트를_조회한다() throws IOException { - // given - final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); - final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); - - final Long 기본_골룸_아이디 = 기본_골룸_생성(기본_로그인_토큰, 로드맵_응답); - - final GoalRoomTodoRequest 골룸_투두_생성_요청 = new GoalRoomTodoRequest("content", 이십일_후, 삼십일_후); - 골룸_투두리스트_추가(기본_로그인_토큰, 기본_골룸_아이디, 골룸_투두_생성_요청); - - 골룸을_시작한다(기본_로그인_토큰, 기본_골룸_아이디); - - // when - final List 골룸_투두리스트_응답값 = 골룸_투두리스트_조회(기본_골룸_아이디, 기본_로그인_토큰) - .as(new TypeRef<>() { - }); - - // then - assertThat(골룸_투두리스트_응답값.get(0).startDate()) - .isEqualTo(이십일_후); - } - - @Test - void 골룸_투두리스트_조회시_존재하지_않은_골룸일_경우() { - // given - // when - final ErrorResponse 예외_응답 = 골룸_투두리스트_조회(1L, 기본_로그인_토큰) - .as(new TypeRef<>() { - }); - - // then - assertThat(예외_응답) - .isEqualTo(new ErrorResponse("존재하지 않는 골룸입니다. goalRoomId = 1")); - } - - @Test - void 골룸_투두리스트_조회시_참여하지_않은_사용자일_경우() throws IOException { - // given - final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); - final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); - - final Long 기본_골룸_아이디 = 기본_골룸_생성(기본_로그인_토큰, 로드맵_응답); - - final GoalRoomTodoRequest 골룸_투두_생성_요청 = new GoalRoomTodoRequest("content", 이십일_후, 삼십일_후); - 골룸_투두리스트_추가(기본_로그인_토큰, 기본_골룸_아이디, 골룸_투두_생성_요청); - - final MemberJoinRequest 다른_사용자_회원_가입_요청 = new MemberJoinRequest("identifier2", "paswword2@", - "follower", GenderType.FEMALE, DEFAULT_EMAIL); - final LoginRequest 다른_사용자_로그인_요청 = new LoginRequest(다른_사용자_회원_가입_요청.identifier(), 다른_사용자_회원_가입_요청.password()); - 회원가입(다른_사용자_회원_가입_요청); - final String 다른_사용자_액세스_토큰 = String.format(BEARER_TOKEN_FORMAT, 로그인(다른_사용자_로그인_요청).accessToken()); - - 골룸을_시작한다(기본_로그인_토큰, 기본_골룸_아이디); - - // when - final ErrorResponse 예외_응답 = 골룸_투두리스트_조회(기본_골룸_아이디, 다른_사용자_액세스_토큰) - .as(new TypeRef<>() { - }); - - // then - assertThat(예외_응답) - .isEqualTo(new ErrorResponse("골룸에 참여하지 않은 사용자입니다. goalRoomId = " + 기본_골룸_아이디 + - " memberIdentifier = identifier2")); - } - @Test void 진행중인_사용자_단일_골룸을_조회한다() throws IOException { // given @@ -205,8 +130,9 @@ class GoalRoomReadIntegrationTest extends InitIntegrationTest { List.of(new GoalRoomRoadmapNodeResponse(로드맵_응답.content().nodes().get(0).id(), "roadmap 1st week", 오늘, 십일_후, 정상적인_골룸_노드_인증_횟수))), List.of(), - List.of(new CheckFeedResponse(2L, "default-image-path", "image description", LocalDate.now()), - new CheckFeedResponse(1L, "default-image-path", "image description", LocalDate.now()))); + List.of(new DashBoardCheckFeedResponse(2L, "default-image-path", "image description", LocalDate.now()), + new DashBoardCheckFeedResponse(1L, "default-image-path", "image description", + LocalDate.now()))); assertThat(요청_응답값) .usingRecursiveComparison() @@ -229,6 +155,32 @@ class GoalRoomReadIntegrationTest extends InitIntegrationTest { assertThat(요청_응답값.checkFeeds()).isEmpty(); } + @Test + void 진행_중인_사용자_단일_골룸을_조회할_때_진행_중인_노드_기간이_아니면_빈_인증피드를_반환한다() throws IOException { + // given + final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); + final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); + + final Long 기본_골룸_아이디 = 십일_후에_시작하는_골룸_생성(기본_로그인_토큰, 로드맵_응답); + + final MemberJoinRequest 팔로워_회원_가입_요청 = new MemberJoinRequest("identifier2", "paswword2@", + "follower", GenderType.FEMALE, DEFAULT_EMAIL); + final LoginRequest 팔로워_로그인_요청 = new LoginRequest(팔로워_회원_가입_요청.identifier(), 팔로워_회원_가입_요청.password()); + 회원가입(팔로워_회원_가입_요청); + final String 팔로워_액세스_토큰 = 로그인(팔로워_로그인_요청).accessToken(); + + 골룸_참가_요청(기본_골룸_아이디, 팔로워_액세스_토큰); + + testTransactionService.골룸의_시작날짜를_변경한다(기본_골룸_아이디, 오늘); + 골룸을_시작한다(기본_로그인_토큰, 기본_골룸_아이디); + + // when + final MemberGoalRoomResponse 요청_응답값 = 사용자의_특정_골룸_정보를_조회한다(기본_로그인_토큰, 기본_골룸_아이디); + + // then + assertThat(요청_응답값.checkFeeds()).isEmpty(); + } + @Test void 사용자의_모든_골룸_목록을_조회한다() throws IOException { // given @@ -378,86 +330,6 @@ class GoalRoomReadIntegrationTest extends InitIntegrationTest { .isEqualTo(new ErrorResponse("골룸에 참여하지 않은 사용자입니다. goalRoomId = 1 memberIdentifier = identifier2")); } - @Test - void 골룸의_인증피드를_전체_조회한다() throws IOException { - // given - final MemberJoinRequest 팔로워_회원_가입_요청 = new MemberJoinRequest("identifier2", "paswword2@", - "follower", GenderType.FEMALE, DEFAULT_EMAIL); - final LoginRequest 팔로워_로그인_요청 = new LoginRequest(팔로워_회원_가입_요청.identifier(), 팔로워_회원_가입_요청.password()); - 회원가입(팔로워_회원_가입_요청); - final String 팔로워_액세스_토큰 = String.format(BEARER_TOKEN_FORMAT, 로그인(팔로워_로그인_요청).accessToken()); - - final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); - final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); - - final Long 기본_골룸_아이디 = 기본_골룸_생성(기본_로그인_토큰, 로드맵_응답); - - 골룸_참가_요청(기본_골룸_아이디, 팔로워_액세스_토큰); - 골룸을_시작한다(기본_로그인_토큰, 기본_골룸_아이디); - - final MockMultipartFile 가짜_이미지_객체 = new MockMultipartFile("image", "originalFileName.jpeg", - "image/jpeg", "tempImage".getBytes()); - final CheckFeedRequest 인증_피드_등록_요청1 = new CheckFeedRequest(가짜_이미지_객체, "image description1"); - final CheckFeedRequest 인증_피드_등록_요청2 = new CheckFeedRequest(가짜_이미지_객체, "image description2"); - - 인증_피드_등록(기본_골룸_아이디, 가짜_이미지_객체, 인증_피드_등록_요청1, 기본_로그인_토큰); - 인증_피드_등록(기본_골룸_아이디, 가짜_이미지_객체, 인증_피드_등록_요청2, 팔로워_액세스_토큰); - - //when - final List 인증_피드_전체_조회_요청에_대한_응답 = 인증_피드_전체_조회_요청(팔로워_액세스_토큰, 기본_골룸_아이디) - .as(new TypeRef<>() { - }); - - // then - assertThat(인증_피드_전체_조회_요청에_대한_응답.get(0).checkFeed().description()).isEqualTo(인증_피드_등록_요청2.description()); - assertThat(인증_피드_전체_조회_요청에_대한_응답.get(1).checkFeed().description()).isEqualTo(인증_피드_등록_요청1.description()); - } - - @Test - void 골룸의_인증피드를_전체_조회시_존재하지_않는_골룸인_경우_예외가_발생한다() throws IOException { - // given - //when - final Long 존재하지_않는_골룸_아이디 = 1L; - final ExtractableResponse 인증_피드_전체_조회_요청에_대한_응답 = 인증_피드_전체_조회_요청(기본_로그인_토큰, 존재하지_않는_골룸_아이디); - - // then - final ErrorResponse 인증_피드_전체_조회_응답_바디 = jsonToClass(인증_피드_전체_조회_요청에_대한_응답.asString(), new TypeReference<>() { - }); - assertThat(인증_피드_전체_조회_요청에_대한_응답.statusCode()).isEqualTo(HttpStatus.NOT_FOUND.value()); - assertThat(인증_피드_전체_조회_응답_바디).isEqualTo(new ErrorResponse("존재하지 않는 골룸입니다. goalRoomId = 1")); - } - - @Test - void 골룸의_인증피드를_전체_조회시_골룸에_참여하지_않은_사용자면_예외가_발생한다() throws IOException { - // given - final MemberJoinRequest 다른_회원_회원_가입_요청 = new MemberJoinRequest("identifier2", "paswword2@", - "follower", GenderType.FEMALE, DEFAULT_EMAIL); - final LoginRequest 다른_회원_로그인_요청 = new LoginRequest(다른_회원_회원_가입_요청.identifier(), 다른_회원_회원_가입_요청.password()); - 회원가입(다른_회원_회원_가입_요청); - final String 다른_회원_액세스_토큰 = String.format(BEARER_TOKEN_FORMAT, 로그인(다른_회원_로그인_요청).accessToken()); - - final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); - final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); - - final Long 기본_골룸_아이디 = 기본_골룸_생성(기본_로그인_토큰, 로드맵_응답); - 골룸을_시작한다(기본_로그인_토큰, 기본_골룸_아이디); - - final MockMultipartFile 가짜_이미지_객체 = new MockMultipartFile("image", "originalFileName.jpeg", - "image/jpeg", "tempImage".getBytes()); - final CheckFeedRequest 인증_피드_등록_요청1 = new CheckFeedRequest(가짜_이미지_객체, "image description1"); - - 인증_피드_등록(기본_골룸_아이디, 가짜_이미지_객체, 인증_피드_등록_요청1, 기본_로그인_토큰); - - //when - final ExtractableResponse 인증_피드_전체_조회_요청에_대한_응답 = 인증_피드_전체_조회_요청(다른_회원_액세스_토큰, 기본_골룸_아이디); - - // then - final ErrorResponse 인증_피드_전체_조회_응답_바디 = jsonToClass(인증_피드_전체_조회_요청에_대한_응답.asString(), new TypeReference<>() { - }); - assertThat(인증_피드_전체_조회_요청에_대한_응답.statusCode()).isEqualTo(HttpStatus.FORBIDDEN.value()); - assertThat(인증_피드_전체_조회_응답_바디).isEqualTo(new ErrorResponse("골룸에 참여하지 않은 회원입니다.")); - } - @Test void 골룸의_사용자_정보를_달성률순으로_전체_조회한다() throws IOException { // given @@ -641,4 +513,13 @@ class GoalRoomReadIntegrationTest extends InitIntegrationTest { assertThat(로드맵_아이디로_골룸_목록_조회_응답1.responses().get(0).goalRoomId()).isEqualTo(기본_골룸_아이디); assertThat(로드맵_아이디로_골룸_목록_조회_응답1.responses().get(1).goalRoomId()).isEqualTo(두번째_골룸_아이디); } + + private Long 십일_후에_시작하는_골룸_생성(final String 액세스_토큰, final RoadmapResponse 로드맵_응답) { + final List 골룸_노드_별_기간_요청 = List.of( + new GoalRoomRoadmapNodeRequest(로드맵_응답.content().nodes().get(0).id(), 정상적인_골룸_노드_인증_횟수, 십일_후, 이십일_후)); + final GoalRoomCreateRequest 골룸_생성_요청 = new GoalRoomCreateRequest(로드맵_응답.content().id(), 정상적인_골룸_이름, + 정상적인_골룸_제한_인원, 골룸_노드_별_기간_요청); + final String Location_헤더 = 골룸_생성(골룸_생성_요청, 액세스_토큰).response().header(LOCATION); + return Long.parseLong(Location_헤더.substring(16)); + } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomSchedulerIntegrationTest.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomSchedulerIntegrationTest.java index f4f5e9399..c25478f5b 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomSchedulerIntegrationTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomSchedulerIntegrationTest.java @@ -2,18 +2,11 @@ import static co.kirikiri.integration.fixture.AuthenticationAPIFixture.로그인; import static co.kirikiri.integration.fixture.CommonFixture.BEARER_TOKEN_FORMAT; -import static co.kirikiri.integration.fixture.CommonFixture.LOCATION; -import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸_생성; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸_참가_요청; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸을_시작한다; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.기본_골룸_생성; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.사용자의_특정_골룸_정보를_조회한다; -import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.십일_후; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.오늘; -import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.이십일_후; -import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.정상적인_골룸_노드_인증_횟수; -import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.정상적인_골룸_이름; -import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.정상적인_골룸_제한_인원; import static co.kirikiri.integration.fixture.MemberAPIFixture.DEFAULT_EMAIL; import static co.kirikiri.integration.fixture.MemberAPIFixture.회원가입; import static co.kirikiri.integration.fixture.RoadmapAPIFixture.로드맵_생성; @@ -21,21 +14,18 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomStatus; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomStatus; +import co.kirikiri.goalroom.persistence.GoalRoomMemberRepository; +import co.kirikiri.goalroom.persistence.GoalRoomPendingMemberRepository; +import co.kirikiri.goalroom.service.dto.response.MemberGoalRoomResponse; +import co.kirikiri.goalroom.service.scheduler.GoalRoomScheduler; import co.kirikiri.integration.helper.InitIntegrationTest; -import co.kirikiri.persistence.goalroom.GoalRoomMemberRepository; -import co.kirikiri.persistence.goalroom.GoalRoomPendingMemberRepository; import co.kirikiri.service.dto.auth.request.LoginRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomCreateRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomRoadmapNodeRequest; import co.kirikiri.service.dto.member.request.GenderType; import co.kirikiri.service.dto.member.request.MemberJoinRequest; -import co.kirikiri.service.dto.member.response.MemberGoalRoomResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapResponse; -import co.kirikiri.service.scheduler.GoalRoomScheduler; import java.io.IOException; -import java.util.List; import org.junit.jupiter.api.Test; class GoalRoomSchedulerIntegrationTest extends InitIntegrationTest { @@ -185,62 +175,4 @@ public GoalRoomSchedulerIntegrationTest(final GoalRoomScheduler goalRoomSchedule // then assertThat(요청_응답값.status()).isEqualTo(GoalRoomStatus.RUNNING.name()); } - - @Test - void 진행_중인_사용자_단일_골룸을_조회할_때_진행_중인_노드_기간이_아니면_빈_인증피드를_반환한다() throws IOException { - // given - final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); - final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); - - final Long 기본_골룸_아이디 = 십일_후에_시작하는_골룸_생성(기본_로그인_토큰, 로드맵_응답); - - final MemberJoinRequest 팔로워_회원_가입_요청 = new MemberJoinRequest("identifier2", "paswword2@", - "follower", GenderType.FEMALE, DEFAULT_EMAIL); - final LoginRequest 팔로워_로그인_요청 = new LoginRequest(팔로워_회원_가입_요청.identifier(), 팔로워_회원_가입_요청.password()); - 회원가입(팔로워_회원_가입_요청); - final String 팔로워_액세스_토큰 = 로그인(팔로워_로그인_요청).accessToken(); - - 골룸_참가_요청(기본_골룸_아이디, 팔로워_액세스_토큰); - - testTransactionService.골룸의_시작날짜를_변경한다(기본_골룸_아이디, 오늘); - 골룸을_시작한다(기본_로그인_토큰, 기본_골룸_아이디); - - // when - final MemberGoalRoomResponse 요청_응답값 = 사용자의_특정_골룸_정보를_조회한다(기본_로그인_토큰, 기본_골룸_아이디); - - // then - assertThat(요청_응답값.checkFeeds()).isEmpty(); - } - - @Test - void 모집_중인_사용자_단일_골룸_조회_시_인증_피드가_빈_응답을_반환한다() throws IOException { - // given - final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); - final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); - - final Long 기본_골룸_아이디 = 기본_골룸_생성(기본_로그인_토큰, 로드맵_응답); - - final MemberJoinRequest 팔로워_회원_가입_요청 = new MemberJoinRequest("identifier2", "paswword2@", - "follower", GenderType.FEMALE, DEFAULT_EMAIL); - final LoginRequest 팔로워_로그인_요청 = new LoginRequest(팔로워_회원_가입_요청.identifier(), 팔로워_회원_가입_요청.password()); - 회원가입(팔로워_회원_가입_요청); - final String 팔로워_액세스_토큰 = 로그인(팔로워_로그인_요청).accessToken(); - - 골룸_참가_요청(기본_골룸_아이디, 팔로워_액세스_토큰); - - //when - final MemberGoalRoomResponse 요청_응답값 = 사용자의_특정_골룸_정보를_조회한다(기본_로그인_토큰, 기본_골룸_아이디); - - //then - assertThat(요청_응답값.checkFeeds()).isEmpty(); - } - - private Long 십일_후에_시작하는_골룸_생성(final String 액세스_토큰, final RoadmapResponse 로드맵_응답) { - final List 골룸_노드_별_기간_요청 = List.of( - new GoalRoomRoadmapNodeRequest(로드맵_응답.content().nodes().get(0).id(), 정상적인_골룸_노드_인증_횟수, 십일_후, 이십일_후)); - final GoalRoomCreateRequest 골룸_생성_요청 = new GoalRoomCreateRequest(로드맵_응답.content().id(), 정상적인_골룸_이름, - 정상적인_골룸_제한_인원, 골룸_노드_별_기간_요청); - final String Location_헤더 = 골룸_생성(골룸_생성_요청, 액세스_토큰).response().header(LOCATION); - return Long.parseLong(Location_헤더.substring(16)); - } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomToDoIntegrationTest.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomToDoIntegrationTest.java new file mode 100644 index 000000000..f32c2320a --- /dev/null +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/GoalRoomToDoIntegrationTest.java @@ -0,0 +1,260 @@ +package co.kirikiri.integration; + +import static co.kirikiri.integration.fixture.AuthenticationAPIFixture.로그인; +import static co.kirikiri.integration.fixture.CommonFixture.BEARER_TOKEN_FORMAT; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸_투두리스트_조회; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸_투두리스트_추가; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸_투두리스트_추가후_아이디를_반환한다; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸_투두리스트를_체크한다; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.골룸을_시작한다; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.기본_골룸_생성; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.삼십일_후; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.십일_후; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.오늘; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.이십일_후; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.정상적인_골룸_생성; +import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.정상적인_골룸_투두_컨텐츠; +import static co.kirikiri.integration.fixture.MemberAPIFixture.DEFAULT_EMAIL; +import static co.kirikiri.integration.fixture.MemberAPIFixture.회원가입; +import static co.kirikiri.integration.fixture.RoadmapAPIFixture.로드맵_생성; +import static co.kirikiri.integration.fixture.RoadmapAPIFixture.로드맵을_아이디로_조회하고_응답객체를_반환한다; +import static org.assertj.core.api.Assertions.assertThat; + +import co.kirikiri.common.service.dto.ErrorResponse; +import co.kirikiri.integration.helper.InitIntegrationTest; +import co.kirikiri.service.dto.auth.request.LoginRequest; +import co.kirikiri.service.dto.member.request.GenderType; +import co.kirikiri.service.dto.member.request.MemberJoinRequest; +import co.kirikiri.service.dto.roadmap.response.RoadmapResponse; +import co.kirikiri.todo.service.dto.request.GoalRoomTodoRequest; +import co.kirikiri.todo.service.dto.response.GoalRoomToDoCheckResponse; +import co.kirikiri.todo.service.dto.response.GoalRoomTodoResponse; +import io.restassured.common.mapper.TypeRef; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; +import java.io.IOException; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; + +class GoalRoomToDoIntegrationTest extends InitIntegrationTest { + + @Test + void 정상적으로_골룸에_투두리스트를_추가한다() throws IOException { + // given + final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); + final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); + final Long 골룸_아이디 = 정상적인_골룸_생성(기본_로그인_토큰, 기본_로드맵_아이디, 로드맵_응답.content().nodes().get(0).id()); + + final GoalRoomTodoRequest 골룸_투두리스트_추가_요청 = new GoalRoomTodoRequest(정상적인_골룸_투두_컨텐츠, 오늘, 십일_후); + + // when + final ExtractableResponse 골룸_투두리스트_추가 = 골룸_투두리스트_추가(기본_로그인_토큰, 골룸_아이디, 골룸_투두리스트_추가_요청); + + // then + assertThat(골룸_투두리스트_추가.statusCode()).isEqualTo(HttpStatus.CREATED.value()); + final String header = 골룸_투두리스트_추가.response() + .header(HttpHeaders.LOCATION); + assertThat(header).contains("/api/goal-rooms/1/todos/" + header.substring(24)); + } + + @Test + void 골룸에_팔로워가_투두_리스트를_추가할때_예외를_던진다() throws IOException { + // given + final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); + final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); + + final MemberJoinRequest 팔로워_회원가입_요청 = new MemberJoinRequest("identifier2", "password12!@#$%", "follower", + GenderType.MALE, DEFAULT_EMAIL); + 회원가입(팔로워_회원가입_요청); + final String 팔로워_로그인_토큰 = String.format(BEARER_TOKEN_FORMAT, + 로그인(new LoginRequest(팔로워_회원가입_요청.identifier(), 팔로워_회원가입_요청.password())).accessToken()); + + final Long 골룸_아이디 = 정상적인_골룸_생성(기본_로그인_토큰, 로드맵_응답.roadmapId(), 로드맵_응답.content().nodes().get(0).id()); + + final GoalRoomTodoRequest 골룸_투두리스트_추가_요청 = new GoalRoomTodoRequest(정상적인_골룸_투두_컨텐츠, 오늘, 십일_후); + + // when + final ExtractableResponse 골룸_투두리스트_추가 = 골룸_투두리스트_추가(팔로워_로그인_토큰, 골룸_아이디, 골룸_투두리스트_추가_요청); + + // then + final ErrorResponse 골룸_투두리스트_추가_바디 = 골룸_투두리스트_추가.as(new TypeRef<>() { + }); + + assertThat(골룸_투두리스트_추가.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST.value()); + assertThat(골룸_투두리스트_추가_바디).isEqualTo(new ErrorResponse("골룸의 리더만 투두리스트를 추가할 수 있습니다.")); + } + + @Test + void 종료된_골룸에_투두_리스트를_추가할때_예외를_던진다() throws IOException { + //given + final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); + final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); + + final Long 골룸_아이디 = 정상적인_골룸_생성(기본_로그인_토큰, 기본_로드맵_아이디, 로드맵_응답.content().nodes().get(0).id()); + testTransactionService.골룸을_완료시킨다(골룸_아이디); + + final GoalRoomTodoRequest 골룸_투두_리스트_추가_요청 = new GoalRoomTodoRequest(정상적인_골룸_투두_컨텐츠, 오늘, 십일_후); + + //when + final ExtractableResponse 골룸_추가_응답 = 골룸_투두리스트_추가(기본_로그인_토큰, 골룸_아이디, 골룸_투두_리스트_추가_요청); + + //then + final ErrorResponse 골룸_추가_응답_바디 = 골룸_추가_응답.as(new TypeRef<>() { + }); + + assertThat(골룸_추가_응답.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST.value()); + assertThat(골룸_추가_응답_바디).isEqualTo(new ErrorResponse("이미 종료된 골룸입니다.")); + } + + @Test + void 골룸_투두_리스트를_체크한다() throws IOException { + // given + final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); + final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); + + final Long 골룸_아이디 = 정상적인_골룸_생성(기본_로그인_토큰, 기본_로드맵_아이디, 로드맵_응답.content().nodes().get(0).id()); + 골룸을_시작한다(기본_로그인_토큰, 골룸_아이디); + final Long 투두_아이디 = 골룸_투두리스트_추가후_아이디를_반환한다(기본_로그인_토큰, 골룸_아이디); + + // when + final GoalRoomToDoCheckResponse 골룸_투두리스트_체크_응답값 = 골룸_투두리스트를_체크한다(기본_로그인_토큰, 골룸_아이디, 투두_아이디) + .as(new TypeRef<>() { + }); + + // then + final GoalRoomToDoCheckResponse 예상하는_골룸_투두리스트_체크_응답값 = new GoalRoomToDoCheckResponse(true); + assertThat(골룸_투두리스트_체크_응답값) + .isEqualTo(예상하는_골룸_투두리스트_체크_응답값); + } + + @Test + void 골룸_투두리스트_체크를_해제한다() throws IOException { + // given + final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); + final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); + + final Long 골룸_아이디 = 정상적인_골룸_생성(기본_로그인_토큰, 기본_로드맵_아이디, 로드맵_응답.content().nodes().get(0).id()); + 골룸을_시작한다(기본_로그인_토큰, 골룸_아이디); + final Long 투두_아이디 = 골룸_투두리스트_추가후_아이디를_반환한다(기본_로그인_토큰, 골룸_아이디); + + 골룸_투두리스트를_체크한다(기본_로그인_토큰, 골룸_아이디, 투두_아이디); + + // when + final GoalRoomToDoCheckResponse 두번째_골룸_투두리스트_체크_응답값 = 골룸_투두리스트를_체크한다(기본_로그인_토큰, 골룸_아이디, 투두_아이디) + .as(new TypeRef<>() { + }); + + // then + final GoalRoomToDoCheckResponse 예상하는_골룸_투두리스트_체크_응답값 = new GoalRoomToDoCheckResponse(false); + assertThat(두번째_골룸_투두리스트_체크_응답값) + .isEqualTo(예상하는_골룸_투두리스트_체크_응답값); + } + + @Test + void 골룸_투두리스트_체크시_골룸이_존재하지_않으면_예외가_발생한다() { + // given + // when + final ErrorResponse 에러_응답 = 골룸_투두리스트를_체크한다(기본_로그인_토큰, 1L, 1L) + .as(new TypeRef<>() { + }); + + // then + assertThat(에러_응답) + .isEqualTo(new ErrorResponse("존재하지 않는 골룸입니다. goalRoomId = 1")); + } + + @Test + void 골룸_투두리스트_체크시_사용자가_없으면_예외가_발생한다() throws IOException { + // given + final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); + final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); + + final Long 골룸_아이디 = 정상적인_골룸_생성(기본_로그인_토큰, 기본_로드맵_아이디, 로드맵_응답.content().nodes().get(0).id()); + 골룸을_시작한다(기본_로그인_토큰, 골룸_아이디); + final Long 투두_아이디 = 골룸_투두리스트_추가후_아이디를_반환한다(기본_로그인_토큰, 골룸_아이디); + + final MemberJoinRequest 팔로워_회원_가입_요청 = new MemberJoinRequest("identifier2", "paswword2@", + "follower", GenderType.FEMALE, DEFAULT_EMAIL); + final LoginRequest 팔로워_로그인_요청 = new LoginRequest(팔로워_회원_가입_요청.identifier(), 팔로워_회원_가입_요청.password()); + 회원가입(팔로워_회원_가입_요청); + final String 팔로워_액세스_토큰 = String.format(BEARER_TOKEN_FORMAT, 로그인(팔로워_로그인_요청).accessToken()); + + // when + final ErrorResponse 에러_응답 = 골룸_투두리스트를_체크한다(팔로워_액세스_토큰, 골룸_아이디, 투두_아이디) + .as(new TypeRef<>() { + }); + + // then + assertThat(에러_응답) + .isEqualTo(new ErrorResponse("골룸에 사용자가 존재하지 않습니다. goalRoomId = " + 골룸_아이디 + + " memberIdentifier = " + 팔로워_회원_가입_요청.identifier())); + } + + @Test + void 골룸_투두리스트를_조회한다() throws IOException { + // given + final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); + final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); + + final Long 기본_골룸_아이디 = 기본_골룸_생성(기본_로그인_토큰, 로드맵_응답); + + final GoalRoomTodoRequest 골룸_투두_생성_요청 = new GoalRoomTodoRequest("content", 이십일_후, 삼십일_후); + + 골룸을_시작한다(기본_로그인_토큰, 기본_골룸_아이디); + 골룸_투두리스트_추가(기본_로그인_토큰, 기본_골룸_아이디, 골룸_투두_생성_요청); + + // when + final List 골룸_투두리스트_응답값 = 골룸_투두리스트_조회(기본_골룸_아이디, 기본_로그인_토큰) + .as(new TypeRef<>() { + }); + + // then + assertThat(골룸_투두리스트_응답값.get(0).startDate()) + .isEqualTo(이십일_후); + } + + @Test + void 골룸_투두리스트_조회시_존재하지_않은_골룸일_경우() { + // given + // when + final ErrorResponse 예외_응답 = 골룸_투두리스트_조회(1L, 기본_로그인_토큰) + .as(new TypeRef<>() { + }); + + // then + assertThat(예외_응답) + .isEqualTo(new ErrorResponse("존재하지 않는 골룸입니다. goalRoomId = 1")); + } + + @Test + void 골룸_투두리스트_조회시_참여하지_않은_사용자일_경우() throws IOException { + // given + final Long 기본_로드맵_아이디 = 로드맵_생성(기본_로드맵_생성_요청, 기본_로그인_토큰); + final RoadmapResponse 로드맵_응답 = 로드맵을_아이디로_조회하고_응답객체를_반환한다(기본_로드맵_아이디); + + final Long 기본_골룸_아이디 = 기본_골룸_생성(기본_로그인_토큰, 로드맵_응답); + + final GoalRoomTodoRequest 골룸_투두_생성_요청 = new GoalRoomTodoRequest("content", 이십일_후, 삼십일_후); + 골룸_투두리스트_추가(기본_로그인_토큰, 기본_골룸_아이디, 골룸_투두_생성_요청); + + final MemberJoinRequest 다른_사용자_회원_가입_요청 = new MemberJoinRequest("identifier2", "paswword2@", + "follower", GenderType.FEMALE, DEFAULT_EMAIL); + final LoginRequest 다른_사용자_로그인_요청 = new LoginRequest(다른_사용자_회원_가입_요청.identifier(), 다른_사용자_회원_가입_요청.password()); + 회원가입(다른_사용자_회원_가입_요청); + final String 다른_사용자_액세스_토큰 = String.format(BEARER_TOKEN_FORMAT, 로그인(다른_사용자_로그인_요청).accessToken()); + + 골룸을_시작한다(기본_로그인_토큰, 기본_골룸_아이디); + + // when + final ErrorResponse 예외_응답 = 골룸_투두리스트_조회(기본_골룸_아이디, 다른_사용자_액세스_토큰) + .as(new TypeRef<>() { + }); + + // then + assertThat(예외_응답) + .isEqualTo(new ErrorResponse("골룸에 참여하지 않은 사용자입니다. goalRoomId = " + 기본_골룸_아이디 + + " memberIdentifier = identifier2")); + } +} diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/MemberCreateIntegrationTest.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/MemberCreateIntegrationTest.java index 9d58ca281..d31b9c998 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/integration/MemberCreateIntegrationTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/MemberCreateIntegrationTest.java @@ -4,8 +4,8 @@ import static co.kirikiri.integration.fixture.MemberAPIFixture.요청을_받는_회원가입; import static org.assertj.core.api.Assertions.assertThat; +import co.kirikiri.common.service.dto.ErrorResponse; import co.kirikiri.integration.helper.InitIntegrationTest; -import co.kirikiri.service.dto.ErrorResponse; import co.kirikiri.service.dto.member.request.GenderType; import co.kirikiri.service.dto.member.request.MemberJoinRequest; import io.restassured.common.mapper.TypeRef; @@ -21,7 +21,8 @@ class MemberCreateIntegrationTest extends InitIntegrationTest { @Test void 정상적으로_회원가입을_성공한다() { //given - final MemberJoinRequest 회원가입_요청 = new MemberJoinRequest("ab12", "password12!@#$%", "hello", GenderType.MALE, DEFAULT_EMAIL); + final MemberJoinRequest 회원가입_요청 = new MemberJoinRequest("ab12", "password12!@#$%", "hello", GenderType.MALE, + DEFAULT_EMAIL); //when final ExtractableResponse 회원가입_응답 = 요청을_받는_회원가입(회원가입_요청); @@ -34,7 +35,8 @@ class MemberCreateIntegrationTest extends InitIntegrationTest { @ValueSource(strings = {"abc", "abcdefghijklmnopqrstuabcdefghijklmnopqrst"}) void 아이디_길이가_틀린_경우_회원가입에_실패한다(final String 회원_아이디) { //given - final MemberJoinRequest 회원가입_요청 = new MemberJoinRequest(회원_아이디, "password12!", "nickname", GenderType.MALE, DEFAULT_EMAIL); + final MemberJoinRequest 회원가입_요청 = new MemberJoinRequest(회원_아이디, "password12!", "nickname", GenderType.MALE, + DEFAULT_EMAIL); //when final ExtractableResponse 회원가입_응답 = 요청을_받는_회원가입(회원가입_요청); @@ -50,7 +52,8 @@ class MemberCreateIntegrationTest extends InitIntegrationTest { @ValueSource(strings = {"Abcd", "abcdefghijklmnopqrsT", "가나다라"}) void 아이디에_허용되지_않은_문자가_들어온_경우_회원가입에_실패한다(final String 회원_아이디) { //given - final MemberJoinRequest 회원가입_요청 = new MemberJoinRequest(회원_아이디, "password12!", "nickname", GenderType.MALE, DEFAULT_EMAIL); + final MemberJoinRequest 회원가입_요청 = new MemberJoinRequest(회원_아이디, "password12!", "nickname", GenderType.MALE, + DEFAULT_EMAIL); //when final ExtractableResponse 회원가입_응답 = 요청을_받는_회원가입(회원가입_요청); @@ -64,7 +67,8 @@ class MemberCreateIntegrationTest extends InitIntegrationTest { @Test void 아이디가_중복된_경우_회원가입에_실패한다() { //given - final MemberJoinRequest 회원가입_요청 = new MemberJoinRequest("ab12", "password12!", "hello", GenderType.MALE, DEFAULT_EMAIL); + final MemberJoinRequest 회원가입_요청 = new MemberJoinRequest("ab12", "password12!", "hello", GenderType.MALE, + DEFAULT_EMAIL); 요청을_받는_회원가입(회원가입_요청); //when @@ -80,7 +84,8 @@ class MemberCreateIntegrationTest extends InitIntegrationTest { @ValueSource(strings = {"abcde1!", "abcdefghijklmn12"}) void 비밀번호_길이가_틀린_경우_회원가입에_실패한다(final String password) { //given - final MemberJoinRequest 회원가입_요청 = new MemberJoinRequest("ab12", password, "nickname", GenderType.MALE, DEFAULT_EMAIL); + final MemberJoinRequest 회원가입_요청 = new MemberJoinRequest("ab12", password, "nickname", GenderType.MALE, + DEFAULT_EMAIL); //when final ExtractableResponse 회원가입_응답 = 요청을_받는_회원가입(회원가입_요청); @@ -95,7 +100,8 @@ class MemberCreateIntegrationTest extends InitIntegrationTest { @ValueSource(strings = {"abcdef1/", "abcdefghij1₩", "abcdefgH1!"}) void 비밀번호에_허용되지_않은_문자가_들어온_경우_회원가입에_실패한다(final String password) { //given - final MemberJoinRequest 회원가입_요청 = new MemberJoinRequest("ab12", password, "nickname", GenderType.MALE, DEFAULT_EMAIL); + final MemberJoinRequest 회원가입_요청 = new MemberJoinRequest("ab12", password, "nickname", GenderType.MALE, + DEFAULT_EMAIL); //when final ExtractableResponse 회원가입_응답 = 요청을_받는_회원가입(회원가입_요청); @@ -110,7 +116,8 @@ class MemberCreateIntegrationTest extends InitIntegrationTest { @ValueSource(strings = {"abcdefgh", "abcdefghijkl"}) void 비밀번호에_영소문자만_들어온_경우_회원가입에_실패한다(final String password) { //given - final MemberJoinRequest 회원가입_요청 = new MemberJoinRequest("ab12", password, "nickname", GenderType.MALE, DEFAULT_EMAIL); + final MemberJoinRequest 회원가입_요청 = new MemberJoinRequest("ab12", password, "nickname", GenderType.MALE, + DEFAULT_EMAIL); //when final ExtractableResponse 회원가입_응답 = 요청을_받는_회원가입(회원가입_요청); @@ -141,7 +148,8 @@ class MemberCreateIntegrationTest extends InitIntegrationTest { @ValueSource(strings = {"a", "123456789012345678901"}) void 닉네임_길이가_틀린_경우_회원가입에_실패한다(final String nickname) { //given - final MemberJoinRequest 회원가입_요청 = new MemberJoinRequest("ab12", "password12!@#$%", nickname, GenderType.MALE, DEFAULT_EMAIL); + final MemberJoinRequest 회원가입_요청 = new MemberJoinRequest("ab12", "password12!@#$%", nickname, GenderType.MALE, + DEFAULT_EMAIL); //when final ExtractableResponse 회원가입_응답 = 요청을_받는_회원가입(회원가입_요청); diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/MemberReadIntegrationTest.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/MemberReadIntegrationTest.java index d86c9a31e..2883d10b6 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/integration/MemberReadIntegrationTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/MemberReadIntegrationTest.java @@ -9,9 +9,9 @@ import static co.kirikiri.integration.fixture.MemberAPIFixture.회원가입; import static org.assertj.core.api.Assertions.assertThat; +import co.kirikiri.common.service.dto.ErrorResponse; import co.kirikiri.domain.member.Gender; import co.kirikiri.integration.helper.InitIntegrationTest; -import co.kirikiri.service.dto.ErrorResponse; import co.kirikiri.service.dto.member.request.MemberJoinRequest; import co.kirikiri.service.dto.member.response.MemberInformationForPublicResponse; import co.kirikiri.service.dto.member.response.MemberInformationResponse; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapCreateIntegrationTest.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapCreateIntegrationTest.java index 32e6b9023..169295c1f 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapCreateIntegrationTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapCreateIntegrationTest.java @@ -12,8 +12,8 @@ import static co.kirikiri.integration.fixture.RoadmapAPIFixture.요청을_받는_이미지가_포함된_로드맵_생성; import static org.assertj.core.api.Assertions.assertThat; +import co.kirikiri.common.service.dto.ErrorResponse; import co.kirikiri.integration.helper.InitIntegrationTest; -import co.kirikiri.service.dto.ErrorResponse; import co.kirikiri.service.dto.auth.request.LoginRequest; import co.kirikiri.service.dto.member.request.GenderType; import co.kirikiri.service.dto.member.request.MemberJoinRequest; @@ -25,13 +25,13 @@ import io.restassured.common.mapper.TypeRef; import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; +import java.io.IOException; +import java.util.Collections; +import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.springframework.http.HttpStatus; -import java.io.IOException; -import java.util.Collections; -import java.util.List; class RoadmapCreateIntegrationTest extends InitIntegrationTest { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapReadIntegrationTest.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapReadIntegrationTest.java index e51683df5..6c437131d 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapReadIntegrationTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapReadIntegrationTest.java @@ -13,10 +13,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; +import co.kirikiri.common.service.dto.ErrorResponse; import co.kirikiri.domain.roadmap.RoadmapCategory; import co.kirikiri.integration.helper.InitIntegrationTest; import co.kirikiri.persistence.dto.RoadmapOrderType; -import co.kirikiri.service.dto.ErrorResponse; import co.kirikiri.service.dto.roadmap.request.RoadmapDifficultyType; import co.kirikiri.service.dto.roadmap.request.RoadmapNodeSaveRequest; import co.kirikiri.service.dto.roadmap.request.RoadmapSaveRequest; @@ -29,10 +29,10 @@ import io.restassured.common.mapper.TypeRef; import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; -import org.junit.jupiter.api.Test; -import org.springframework.http.HttpStatus; import java.io.IOException; import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; class RoadmapReadIntegrationTest extends InitIntegrationTest { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapReadOrderIntegrationTest.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapReadOrderIntegrationTest.java index ddd207f71..3f3c3155b 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapReadOrderIntegrationTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapReadOrderIntegrationTest.java @@ -18,12 +18,12 @@ import static co.kirikiri.integration.fixture.RoadmapAPIFixture.카테고리_생성; import static org.assertj.core.api.Assertions.assertThat; -import co.kirikiri.domain.goalroom.GoalRoom; import co.kirikiri.domain.roadmap.RoadmapCategory; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.service.dto.request.GoalRoomCreateRequest; +import co.kirikiri.goalroom.service.dto.request.GoalRoomRoadmapNodeRequest; import co.kirikiri.integration.helper.InitIntegrationTest; import co.kirikiri.persistence.dto.RoadmapOrderType; -import co.kirikiri.service.dto.goalroom.request.GoalRoomCreateRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomRoadmapNodeRequest; import co.kirikiri.service.dto.member.response.MemberInformationResponse; import co.kirikiri.service.dto.roadmap.request.RoadmapDifficultyType; import co.kirikiri.service.dto.roadmap.request.RoadmapNodeSaveRequest; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapReviewCreateIntegrationTest.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapReviewCreateIntegrationTest.java index 3f5784e8a..4408d3d13 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapReviewCreateIntegrationTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapReviewCreateIntegrationTest.java @@ -8,7 +8,6 @@ import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.정상적인_골룸_노드_인증_횟수; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.정상적인_골룸_이름; import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.정상적인_골룸_제한_인원; -import static co.kirikiri.integration.fixture.GoalRoomAPIFixture.정상적인_골룸_투두_컨텐츠; import static co.kirikiri.integration.fixture.MemberAPIFixture.DEFAULT_EMAIL; import static co.kirikiri.integration.fixture.MemberAPIFixture.요청을_받는_사용자_자신의_정보_조회_요청; import static co.kirikiri.integration.fixture.MemberAPIFixture.회원가입; @@ -17,12 +16,12 @@ import static co.kirikiri.integration.fixture.RoadmapAPIFixture.리뷰를_생성한다; import static org.assertj.core.api.Assertions.assertThat; -import co.kirikiri.domain.goalroom.GoalRoom; +import co.kirikiri.common.service.dto.ErrorResponse; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.service.dto.request.GoalRoomCreateRequest; +import co.kirikiri.goalroom.service.dto.request.GoalRoomRoadmapNodeRequest; import co.kirikiri.integration.helper.InitIntegrationTest; -import co.kirikiri.service.dto.ErrorResponse; import co.kirikiri.service.dto.auth.request.LoginRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomCreateRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomRoadmapNodeRequest; import co.kirikiri.service.dto.member.request.GenderType; import co.kirikiri.service.dto.member.request.MemberJoinRequest; import co.kirikiri.service.dto.member.response.MemberInformationResponse; @@ -31,10 +30,10 @@ import io.restassured.common.mapper.TypeRef; import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; -import org.junit.jupiter.api.Test; -import org.springframework.http.HttpStatus; import java.io.IOException; import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; class RoadmapReviewCreateIntegrationTest extends InitIntegrationTest { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapReviewReadIntegrationTest.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapReviewReadIntegrationTest.java index ba7dd7fea..11a57222e 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapReviewReadIntegrationTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapReviewReadIntegrationTest.java @@ -12,10 +12,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; -import co.kirikiri.domain.goalroom.GoalRoom; +import co.kirikiri.common.service.dto.ErrorResponse; +import co.kirikiri.goalroom.domain.GoalRoom; import co.kirikiri.integration.helper.InitIntegrationTest; import co.kirikiri.service.dto.CustomScrollRequest; -import co.kirikiri.service.dto.ErrorResponse; import co.kirikiri.service.dto.auth.request.LoginRequest; import co.kirikiri.service.dto.member.request.GenderType; import co.kirikiri.service.dto.member.request.MemberJoinRequest; @@ -29,11 +29,11 @@ import io.restassured.common.mapper.TypeRef; import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; -import org.junit.jupiter.api.Test; -import org.springframework.http.HttpStatus; import java.io.IOException; import java.time.LocalDateTime; import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; class RoadmapReviewReadIntegrationTest extends InitIntegrationTest { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapSchedulerIntegrationTest.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapSchedulerIntegrationTest.java index a5a3e83f4..cacf1efd7 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapSchedulerIntegrationTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/RoadmapSchedulerIntegrationTest.java @@ -11,17 +11,17 @@ import static co.kirikiri.integration.fixture.RoadmapAPIFixture.로드맵을_아이디로_조회하고_응답객체를_반환한다; import static org.assertj.core.api.Assertions.assertThat; -import co.kirikiri.domain.goalroom.GoalRoomStatus; +import co.kirikiri.goalroom.domain.GoalRoomStatus; +import co.kirikiri.goalroom.service.dto.request.GoalRoomCreateRequest; +import co.kirikiri.goalroom.service.dto.request.GoalRoomRoadmapNodeRequest; import co.kirikiri.integration.helper.InitIntegrationTest; import co.kirikiri.persistence.roadmap.RoadmapRepository; -import co.kirikiri.service.scheduler.RoadmapScheduler; -import co.kirikiri.service.dto.goalroom.request.GoalRoomCreateRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomRoadmapNodeRequest; import co.kirikiri.service.dto.roadmap.response.RoadmapResponse; -import org.junit.jupiter.api.Test; +import co.kirikiri.service.scheduler.RoadmapScheduler; import java.io.IOException; import java.time.LocalDate; import java.util.List; +import org.junit.jupiter.api.Test; class RoadmapSchedulerIntegrationTest extends InitIntegrationTest { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/fixture/GoalRoomAPIFixture.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/fixture/GoalRoomAPIFixture.java index 500761b69..b7f8b5cd7 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/integration/fixture/GoalRoomAPIFixture.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/fixture/GoalRoomAPIFixture.java @@ -5,24 +5,24 @@ import static co.kirikiri.integration.fixture.CommonFixture.LOCATION; import static io.restassured.RestAssured.given; -import co.kirikiri.service.dto.goalroom.request.CheckFeedRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomCreateRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomRoadmapNodeRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomTodoRequest; -import co.kirikiri.service.dto.member.response.MemberGoalRoomResponse; +import co.kirikiri.checkfeed.service.dto.request.CheckFeedRequest; +import co.kirikiri.goalroom.service.dto.request.GoalRoomCreateRequest; +import co.kirikiri.goalroom.service.dto.request.GoalRoomRoadmapNodeRequest; +import co.kirikiri.goalroom.service.dto.response.MemberGoalRoomResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapResponse; +import co.kirikiri.todo.service.dto.request.GoalRoomTodoRequest; import io.restassured.common.mapper.TypeRef; import io.restassured.http.Header; import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.mock.web.MockMultipartFile; import java.io.IOException; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; import java.util.List; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.mock.web.MockMultipartFile; public class GoalRoomAPIFixture { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestConfig.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestConfig.java index 8f62a2887..2122c142e 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestConfig.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestConfig.java @@ -1,9 +1,9 @@ package co.kirikiri.integration.helper; +import co.kirikiri.common.service.FileService; +import co.kirikiri.goalroom.persistence.GoalRoomMemberRepository; +import co.kirikiri.goalroom.persistence.GoalRoomRepository; import co.kirikiri.persistence.auth.RefreshTokenRepository; -import co.kirikiri.persistence.goalroom.GoalRoomMemberRepository; -import co.kirikiri.persistence.goalroom.GoalRoomRepository; -import co.kirikiri.service.FileService; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestFileService.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestFileService.java index 5803f3af2..122ced8fa 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestFileService.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestFileService.java @@ -1,10 +1,10 @@ package co.kirikiri.integration.helper; -import co.kirikiri.service.FileService; -import co.kirikiri.service.dto.FileInformation; -import org.springframework.http.HttpMethod; +import co.kirikiri.common.service.FileService; +import co.kirikiri.common.service.dto.FileInformation; import java.net.MalformedURLException; import java.net.URL; +import org.springframework.http.HttpMethod; public class TestFileService implements FileService { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestTransactionService.java b/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestTransactionService.java index accf118e2..df0fa35d4 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestTransactionService.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/integration/helper/TestTransactionService.java @@ -9,10 +9,6 @@ import static co.kirikiri.integration.fixture.MemberAPIFixture.DEFAULT_PASSWORD; import static co.kirikiri.integration.helper.InitIntegrationTest.기본_로그인_토큰; -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomMember; -import co.kirikiri.domain.goalroom.GoalRoomRole; -import co.kirikiri.domain.goalroom.GoalRoomStatus; import co.kirikiri.domain.member.EncryptedPassword; import co.kirikiri.domain.member.Gender; import co.kirikiri.domain.member.Member; @@ -20,10 +16,14 @@ import co.kirikiri.domain.member.vo.Identifier; import co.kirikiri.domain.member.vo.Nickname; import co.kirikiri.domain.member.vo.Password; -import co.kirikiri.persistence.goalroom.GoalRoomMemberRepository; -import co.kirikiri.persistence.goalroom.GoalRoomRepository; -import co.kirikiri.service.dto.goalroom.request.GoalRoomCreateRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomRoadmapNodeRequest; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomMember; +import co.kirikiri.goalroom.domain.GoalRoomRole; +import co.kirikiri.goalroom.domain.GoalRoomStatus; +import co.kirikiri.goalroom.persistence.GoalRoomMemberRepository; +import co.kirikiri.goalroom.persistence.GoalRoomRepository; +import co.kirikiri.goalroom.service.dto.request.GoalRoomCreateRequest; +import co.kirikiri.goalroom.service.dto.request.GoalRoomRoadmapNodeRequest; import co.kirikiri.service.dto.member.response.MemberInformationResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapResponse; import jakarta.persistence.EntityManager; @@ -68,14 +68,14 @@ public TestTransactionService(final GoalRoomRepository goalRoomRepository, final MemberInformationResponse... 팔로워들_정보) { final Member 리더 = 사용자_정보에서_사용자를_생성한다(리더_정보); final GoalRoomMember 골룸_멤버_리더 = new GoalRoomMember(GoalRoomRole.LEADER, - LocalDateTime.of(2023, 7, 1, 12, 0), 골룸, 리더); + LocalDateTime.of(2023, 7, 1, 12, 0), 골룸, 리더.getId()); final List 골룸_멤버_리스트 = new ArrayList<>(); 골룸_멤버_리스트.add(골룸_멤버_리더); for (final MemberInformationResponse 팔로워_정보 : 팔로워들_정보) { final Member 팔로워 = 사용자_정보에서_사용자를_생성한다(팔로워_정보); final GoalRoomMember 골룸_멤버_팔로워 = new GoalRoomMember(GoalRoomRole.FOLLOWER, - LocalDateTime.of(2023, 7, 5, 18, 0), 골룸, 팔로워); + LocalDateTime.of(2023, 7, 5, 18, 0), 골룸, 팔로워.getId()); 골룸_멤버_리스트.add(골룸_멤버_팔로워); } 골룸_멤버를_저장한다(골룸_멤버_리스트); diff --git a/backend/kirikiri/src/test/java/co/kirikiri/persistence/dto/RoadmapSearchTagNameTest.java b/backend/kirikiri/src/test/java/co/kirikiri/persistence/dto/RoadmapSearchTagNameTest.java index 23459fce2..795be340d 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/persistence/dto/RoadmapSearchTagNameTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/persistence/dto/RoadmapSearchTagNameTest.java @@ -4,7 +4,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import co.kirikiri.service.exception.BadRequestException; +import co.kirikiri.common.exception.BadRequestException; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.ValueSource; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/persistence/dto/RoadmapSearchTitleTest.java b/backend/kirikiri/src/test/java/co/kirikiri/persistence/dto/RoadmapSearchTitleTest.java index add4ecca9..10e762ae4 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/persistence/dto/RoadmapSearchTitleTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/persistence/dto/RoadmapSearchTitleTest.java @@ -4,7 +4,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import co.kirikiri.service.exception.BadRequestException; +import co.kirikiri.common.exception.BadRequestException; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.ValueSource; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/persistence/member/MemberRepositoryTest.java b/backend/kirikiri/src/test/java/co/kirikiri/persistence/member/MemberRepositoryTest.java index 99052941c..67d6da865 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/persistence/member/MemberRepositoryTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/persistence/member/MemberRepositoryTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; -import co.kirikiri.domain.ImageContentType; +import co.kirikiri.common.type.ImageContentType; import co.kirikiri.domain.member.EncryptedPassword; import co.kirikiri.domain.member.Gender; import co.kirikiri.domain.member.Member; @@ -12,10 +12,10 @@ import co.kirikiri.domain.member.vo.Identifier; import co.kirikiri.domain.member.vo.Nickname; import co.kirikiri.domain.member.vo.Password; -import co.kirikiri.persistence.helper.RepositoryTest; +import co.kirikiri.common.helper.RepositoryTest; +import java.util.Optional; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import java.util.Optional; @RepositoryTest class MemberRepositoryTest { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/persistence/roadmap/RoadmapContentRepositoryTest.java b/backend/kirikiri/src/test/java/co/kirikiri/persistence/roadmap/RoadmapContentRepositoryTest.java index 9f6ce6a34..96bcbbf74 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/persistence/roadmap/RoadmapContentRepositoryTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/persistence/roadmap/RoadmapContentRepositoryTest.java @@ -14,7 +14,7 @@ import co.kirikiri.domain.roadmap.RoadmapCategory; import co.kirikiri.domain.roadmap.RoadmapContent; import co.kirikiri.domain.roadmap.RoadmapDifficulty; -import co.kirikiri.persistence.helper.RepositoryTest; +import co.kirikiri.common.helper.RepositoryTest; import co.kirikiri.persistence.member.MemberRepository; import org.junit.jupiter.api.Test; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/persistence/roadmap/RoadmapRepositoryTest.java b/backend/kirikiri/src/test/java/co/kirikiri/persistence/roadmap/RoadmapRepositoryTest.java index 83ab3ff56..66470d730 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/persistence/roadmap/RoadmapRepositoryTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/persistence/roadmap/RoadmapRepositoryTest.java @@ -3,15 +3,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; -import co.kirikiri.domain.ImageContentType; -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomMember; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNode; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNodes; -import co.kirikiri.domain.goalroom.GoalRoomRole; -import co.kirikiri.domain.goalroom.vo.GoalRoomName; -import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; -import co.kirikiri.domain.goalroom.vo.Period; +import co.kirikiri.common.helper.RepositoryTest; +import co.kirikiri.common.type.ImageContentType; import co.kirikiri.domain.member.EncryptedPassword; import co.kirikiri.domain.member.Gender; import co.kirikiri.domain.member.Member; @@ -31,11 +24,18 @@ import co.kirikiri.domain.roadmap.RoadmapTag; import co.kirikiri.domain.roadmap.RoadmapTags; import co.kirikiri.domain.roadmap.vo.RoadmapTagName; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomMember; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNode; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNodes; +import co.kirikiri.goalroom.domain.GoalRoomRole; +import co.kirikiri.goalroom.domain.vo.GoalRoomName; +import co.kirikiri.goalroom.domain.vo.LimitedMemberCount; +import co.kirikiri.goalroom.domain.vo.Period; +import co.kirikiri.goalroom.persistence.GoalRoomMemberRepository; +import co.kirikiri.goalroom.persistence.GoalRoomRepository; import co.kirikiri.persistence.dto.RoadmapOrderType; import co.kirikiri.persistence.dto.RoadmapSearchDto; -import co.kirikiri.persistence.goalroom.GoalRoomMemberRepository; -import co.kirikiri.persistence.goalroom.GoalRoomRepository; -import co.kirikiri.persistence.helper.RepositoryTest; import co.kirikiri.persistence.member.MemberRepository; import java.time.LocalDate; import java.time.LocalDateTime; @@ -248,13 +248,14 @@ public RoadmapRepositoryTest(final MemberRepository memberRepository, // gameRoadmap1 : 참가인원 0명 // gameRoadmap2 : 참가인원 1명 final List gameRoadmap2GoalRoomMembers = List.of( - new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), gameRoadmap2GoalRoom, creator)); + new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), gameRoadmap2GoalRoom, creator.getId())); goalRoomMemberRepository.saveAllInBatch(gameRoadmap2GoalRoomMembers); // travelRoadmap : 참가인원 2명 final List travelRoadmapGoalRoomMembers = List.of( - new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), travelRoadmapGoalRoom, creator), - new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), travelRoadmapGoalRoom, follower)); + new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), travelRoadmapGoalRoom, creator.getId()), + new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), travelRoadmapGoalRoom, + follower.getId())); goalRoomMemberRepository.saveAllInBatch(travelRoadmapGoalRoomMembers); final RoadmapCategory category = null; @@ -616,14 +617,14 @@ public RoadmapRepositoryTest(final MemberRepository memberRepository, final GoalRoomRoadmapNodes goalRoomRoadmapNodes = new GoalRoomRoadmapNodes( List.of(goalRoomRoadmapNode1, goalRoomRoadmapNode2)); - final GoalRoom goalRoom = new GoalRoom(new GoalRoomName("골룸"), new LimitedMemberCount(5), roadmapContent, - member); + final GoalRoom goalRoom = new GoalRoom(new GoalRoomName("골룸"), new LimitedMemberCount(5), + roadmapContent.getId(), member.getId()); goalRoom.addAllGoalRoomRoadmapNodes(goalRoomRoadmapNodes); return goalRoomRepository.save(goalRoom); } private GoalRoomRoadmapNode 골룸_로드맵_노드를_생성한다(final LocalDate startDate, final LocalDate endDate, final RoadmapNode roadmapNode) { - return new GoalRoomRoadmapNode(new Period(startDate, endDate), 1, roadmapNode); + return new GoalRoomRoadmapNode(new Period(startDate, endDate), 1, roadmapNode.getId()); } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/persistence/roadmap/RoadmapReviewRepositoryTest.java b/backend/kirikiri/src/test/java/co/kirikiri/persistence/roadmap/RoadmapReviewRepositoryTest.java index 099dd5fc9..184fe21f1 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/persistence/roadmap/RoadmapReviewRepositoryTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/persistence/roadmap/RoadmapReviewRepositoryTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; -import co.kirikiri.domain.ImageContentType; +import co.kirikiri.common.type.ImageContentType; import co.kirikiri.domain.member.EncryptedPassword; import co.kirikiri.domain.member.Gender; import co.kirikiri.domain.member.Member; @@ -19,11 +19,11 @@ import co.kirikiri.domain.roadmap.RoadmapNode; import co.kirikiri.domain.roadmap.RoadmapNodes; import co.kirikiri.domain.roadmap.RoadmapReview; -import co.kirikiri.persistence.helper.RepositoryTest; +import co.kirikiri.common.helper.RepositoryTest; import co.kirikiri.persistence.member.MemberRepository; -import org.junit.jupiter.api.Test; import java.util.List; import java.util.Optional; +import org.junit.jupiter.api.Test; @RepositoryTest class RoadmapReviewRepositoryTest { diff --git a/backend/kirikiri/src/test/java/co/kirikiri/service/AuthServiceTest.java b/backend/kirikiri/src/test/java/co/kirikiri/service/AuthServiceTest.java index ddf3ec88a..8851cbf56 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/service/AuthServiceTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/service/AuthServiceTest.java @@ -5,6 +5,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; +import co.kirikiri.common.exception.AuthenticationException; import co.kirikiri.domain.member.EncryptedPassword; import co.kirikiri.domain.member.Gender; import co.kirikiri.domain.member.Member; @@ -19,7 +20,6 @@ import co.kirikiri.service.dto.auth.request.LoginRequest; import co.kirikiri.service.dto.auth.request.ReissueTokenRequest; import co.kirikiri.service.dto.auth.response.AuthenticationResponse; -import co.kirikiri.service.exception.AuthenticationException; import java.util.Optional; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/service/GoalRoomCreateServiceTest.java b/backend/kirikiri/src/test/java/co/kirikiri/service/GoalRoomCreateServiceTest.java deleted file mode 100644 index b409f8ddb..000000000 --- a/backend/kirikiri/src/test/java/co/kirikiri/service/GoalRoomCreateServiceTest.java +++ /dev/null @@ -1,1072 +0,0 @@ -package co.kirikiri.service; - -import static co.kirikiri.domain.goalroom.GoalRoomStatus.RUNNING; -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.assertDoesNotThrow; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import co.kirikiri.domain.ImageContentType; -import co.kirikiri.domain.exception.ImageExtensionException; -import co.kirikiri.domain.goalroom.CheckFeed; -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomMember; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNode; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNodes; -import co.kirikiri.domain.goalroom.GoalRoomRole; -import co.kirikiri.domain.goalroom.GoalRoomToDo; -import co.kirikiri.domain.goalroom.GoalRoomToDoCheck; -import co.kirikiri.domain.goalroom.exception.GoalRoomException; -import co.kirikiri.domain.goalroom.vo.GoalRoomName; -import co.kirikiri.domain.goalroom.vo.GoalRoomTodoContent; -import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; -import co.kirikiri.domain.goalroom.vo.Period; -import co.kirikiri.domain.member.EncryptedPassword; -import co.kirikiri.domain.member.Gender; -import co.kirikiri.domain.member.Member; -import co.kirikiri.domain.member.MemberProfile; -import co.kirikiri.domain.member.vo.Identifier; -import co.kirikiri.domain.member.vo.Nickname; -import co.kirikiri.domain.member.vo.Password; -import co.kirikiri.domain.roadmap.Roadmap; -import co.kirikiri.domain.roadmap.RoadmapCategory; -import co.kirikiri.domain.roadmap.RoadmapContent; -import co.kirikiri.domain.roadmap.RoadmapContents; -import co.kirikiri.domain.roadmap.RoadmapDifficulty; -import co.kirikiri.domain.roadmap.RoadmapNode; -import co.kirikiri.domain.roadmap.RoadmapNodeImage; -import co.kirikiri.domain.roadmap.RoadmapNodeImages; -import co.kirikiri.domain.roadmap.RoadmapNodes; -import co.kirikiri.domain.roadmap.RoadmapStatus; -import co.kirikiri.persistence.goalroom.CheckFeedRepository; -import co.kirikiri.persistence.goalroom.GoalRoomMemberRepository; -import co.kirikiri.persistence.goalroom.GoalRoomRepository; -import co.kirikiri.persistence.goalroom.GoalRoomToDoCheckRepository; -import co.kirikiri.persistence.member.MemberRepository; -import co.kirikiri.persistence.roadmap.RoadmapContentRepository; -import co.kirikiri.service.dto.goalroom.request.CheckFeedRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomCreateRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomRoadmapNodeRequest; -import co.kirikiri.service.dto.goalroom.request.GoalRoomTodoRequest; -import co.kirikiri.service.dto.goalroom.response.GoalRoomToDoCheckResponse; -import co.kirikiri.service.exception.BadRequestException; -import co.kirikiri.service.exception.NotFoundException; -import co.kirikiri.service.goalroom.GoalRoomCreateService; -import java.net.MalformedURLException; -import java.net.URL; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.mock.web.MockMultipartFile; - -@ExtendWith(MockitoExtension.class) -class GoalRoomCreateServiceTest { - - private static final LocalDate TODAY = LocalDate.now(); - private static final LocalDate TEN_DAY_LATER = TODAY.plusDays(10); - private static final LocalDate TWENTY_DAY_LATER = TODAY.plusDays(20); - - private static final RoadmapNode ROADMAP_NODE = new RoadmapNode(1L, "title", "content"); - private static final RoadmapContent ROADMAP_CONTENT = new RoadmapContent(1L, "content"); - private static final RoadmapContent DELETED_ROADMAP_CONTENT = new RoadmapContent(2L, "content2"); - private static final RoadmapNodes ROADMAP_CONTENTS = new RoadmapNodes(new ArrayList<>(List.of(ROADMAP_NODE))); - - private static final Member MEMBER = new Member(new Identifier("identifier2"), - new EncryptedPassword(new Password("password!2")), - new Nickname("name2"), null, - new MemberProfile(Gender.FEMALE, "kirikiri@email.com")); - - private static final Roadmap ROADMAP = new Roadmap("roadmap", "introduction", 30, RoadmapDifficulty.DIFFICULT, - MEMBER, new RoadmapCategory("IT")); - - private static final Roadmap DELETED_ROADMAP = new Roadmap("roadmap", "introduction", 30, - RoadmapDifficulty.DIFFICULT, RoadmapStatus.DELETED, MEMBER, new RoadmapCategory("IT")); - - private static Member member; - - @Mock - private GoalRoomRepository goalRoomRepository; - - @Mock - private GoalRoomMemberRepository goalRoomMemberRepository; - - @Mock - private RoadmapContentRepository roadmapContentRepository; - - @Mock - private MemberRepository memberRepository; - - @Mock - private GoalRoomToDoCheckRepository goalRoomToDoCheckRepository; - - @Mock - private CheckFeedRepository checkFeedRepository; - - @Mock - private FileService fileService; - - @Mock - private FilePathGenerator filePathGenerator; - - @InjectMocks - private GoalRoomCreateService goalRoomCreateService; - - @BeforeAll - static void setUp() { - ROADMAP_CONTENT.addNodes(ROADMAP_CONTENTS); - ROADMAP.addContent(ROADMAP_CONTENT); - DELETED_ROADMAP.addContent(DELETED_ROADMAP_CONTENT); - final Identifier identifier = new Identifier("identifier1"); - final Password password = new Password("password1!"); - final EncryptedPassword encryptedPassword = new EncryptedPassword(password); - final Nickname nickname = new Nickname("nickname"); - final String email = "kirikiri@email.com"; - final MemberProfile memberProfile = new MemberProfile(Gender.MALE, email); - member = new Member(identifier, encryptedPassword, nickname, null, memberProfile); - } - - @Test - void 정상적으로_골룸을_생성한다() { - //given - final GoalRoomCreateRequest request = new GoalRoomCreateRequest(1L, "name", - 20, new ArrayList<>(List.of(new GoalRoomRoadmapNodeRequest(1L, 10, TODAY, TEN_DAY_LATER)))); - - given(roadmapContentRepository.findByIdWithRoadmap(anyLong())) - .willReturn(Optional.of(ROADMAP_CONTENT)); - given(memberRepository.findByIdentifier(any())) - .willReturn(Optional.of(member)); - given(goalRoomRepository.save(any())) - .willReturn(new GoalRoom(1L, null, null, null, null)); - - //when - assertDoesNotThrow(() -> goalRoomCreateService.create(request, member.getIdentifier().getValue())); - } - - @Test - void 골룸_생성_시_삭제된_로드맵이면_예외를_던진다() { - //given - final GoalRoomCreateRequest request = new GoalRoomCreateRequest(1L, "name", - 20, new ArrayList<>(List.of(new GoalRoomRoadmapNodeRequest(1L, 10, TODAY, TEN_DAY_LATER)))); - - given(roadmapContentRepository.findByIdWithRoadmap(anyLong())) - .willReturn(Optional.of(DELETED_ROADMAP_CONTENT)); - - //when - //then - assertThatThrownBy(() -> goalRoomCreateService.create(request, member.getIdentifier().getValue())) - .isInstanceOf(BadRequestException.class); - } - - @Test - void 골룸_생성_시_존재하지_않은_로드맵_컨텐츠가_들어올때_예외를_던진다() { - //given - final GoalRoomCreateRequest request = new GoalRoomCreateRequest(1L, "name", - 20, new ArrayList<>(List.of(new GoalRoomRoadmapNodeRequest(1L, 10, TODAY, TEN_DAY_LATER)))); - - given(roadmapContentRepository.findByIdWithRoadmap(anyLong())) - .willReturn(Optional.empty()); - - //when - //then - assertThatThrownBy(() -> goalRoomCreateService.create(request, member.getIdentifier().getValue())) - .isInstanceOf(NotFoundException.class); - } - - @Test - void 골룸_생성_시_로드맵_컨텐츠의_노드사이즈와_요청의_노드사이즈가_다를때_예외를_던진다() { - //given - final List wrongSizeGoalRoomRoadmapNodeRequest = new ArrayList<>(List.of( - new GoalRoomRoadmapNodeRequest(1L, 10, TODAY, TEN_DAY_LATER), - new GoalRoomRoadmapNodeRequest(2L, 10, TODAY, TEN_DAY_LATER))); - final GoalRoomCreateRequest request = new GoalRoomCreateRequest(1L, "name", - 20, wrongSizeGoalRoomRoadmapNodeRequest); - - given(roadmapContentRepository.findByIdWithRoadmap(anyLong())) - .willReturn(Optional.of(ROADMAP_CONTENT)); - - //when - //then - assertThatThrownBy(() -> goalRoomCreateService.create(request, member.getIdentifier().getValue())) - .isInstanceOf(BadRequestException.class); - } - - @Test - void 골룸_생성_시_로드맵에_존재하지_않는_노드가_요청으로_들어올때_예외를_던진다() { - //given - final long wrongRoadmapNodId = 2L; - final GoalRoomCreateRequest request = new GoalRoomCreateRequest(1L, "name", - 20, - new ArrayList<>(List.of(new GoalRoomRoadmapNodeRequest(wrongRoadmapNodId, 10, TODAY, TEN_DAY_LATER)))); - - given(roadmapContentRepository.findByIdWithRoadmap(anyLong())) - .willReturn(Optional.of(ROADMAP_CONTENT)); - - //when - //then - assertThatThrownBy(() -> goalRoomCreateService.create(request, member.getIdentifier().getValue())) - .isInstanceOf(NotFoundException.class); - } - - @Test - void 골룸_생성_시_존재하지_않은_회원의_Identifier가_들어올때_예외를_던진다() { - //given - final GoalRoomCreateRequest request = new GoalRoomCreateRequest(1L, "name", - 20, new ArrayList<>(List.of(new GoalRoomRoadmapNodeRequest(1L, 10, TODAY, TEN_DAY_LATER)))); - - given(roadmapContentRepository.findByIdWithRoadmap(anyLong())) - .willReturn(Optional.of(ROADMAP_CONTENT)); - given(memberRepository.findByIdentifier(any())) - .willReturn(Optional.empty()); - - //when - //then - assertThatThrownBy(() -> goalRoomCreateService.create(request, member.getIdentifier().getValue())) - .isInstanceOf(NotFoundException.class); - } - - @Test - void 골룸에_참가한다() { - //given - final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "시진이", "kirikiri1@email"); - final Roadmap roadmap = 로드맵을_생성한다(creator); - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final int limitedMemberCount = 20; - final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, limitedMemberCount); - final Member follower = 사용자를_생성한다(2L, "identifier2", "password1!", "팔로워", "kirikiri1@email"); - - when(memberRepository.findByIdentifier(any())) - .thenReturn(Optional.of(follower)); - when(goalRoomRepository.findGoalRoomByIdWithPessimisticLock(anyLong())) - .thenReturn(Optional.of(goalRoom)); - - //when - goalRoomCreateService.join("identifier2", 1L); - - //then - assertThat(goalRoom.getCurrentMemberCount()) - .isEqualTo(2); - } - - @Test - void 골룸_참가_요청시_유효한_사용자_아이디가_아니면_예외가_발생한다() { - //given - when(memberRepository.findByIdentifier(any())) - .thenReturn(Optional.empty()); - - //when, then - assertThatThrownBy(() -> goalRoomCreateService.join("identifier2", 1L)) - .isInstanceOf(NotFoundException.class) - .hasMessage("존재하지 않는 회원입니다."); - } - - @Test - void 골룸_참가_요청시_유효한_골룸_아이디가_아니면_예외가_발생한다() { - //given - final Member follower = 사용자를_생성한다(1L, "identifier1", "password1!", "팔로워", "kirikiri1@email"); - - when(memberRepository.findByIdentifier(any())) - .thenReturn(Optional.of(follower)); - when(goalRoomRepository.findGoalRoomByIdWithPessimisticLock(anyLong())) - .thenReturn(Optional.empty()); - - //when, then - assertThatThrownBy(() -> goalRoomCreateService.join("identifier1", 1L)) - .isInstanceOf(NotFoundException.class) - .hasMessage("존재하지 않는 골룸입니다. goalRoomId = 1"); - } - - @Test - void 골룸_참가_요청시_제한_인원이_가득_찼을_경우_예외가_발생한다() { - //given - final Member creator = 사용자를_생성한다(1L, "identifier1", "password1!", "시진이", "kirikiri1@email"); - final Roadmap roadmap = 로드맵을_생성한다(creator); - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final int limitedMemberCount = 1; - final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, limitedMemberCount); - final Member follower = 사용자를_생성한다(1L, "identifier2", "password1!", "팔로워", "kirikiri1@email"); - - when(memberRepository.findByIdentifier(any())) - .thenReturn(Optional.of(follower)); - when(goalRoomRepository.findGoalRoomByIdWithPessimisticLock(anyLong())) - .thenReturn(Optional.of(goalRoom)); - - //when, then - assertThatThrownBy(() -> goalRoomCreateService.join("identifier2", 1L)) - .isInstanceOf(GoalRoomException.class) - .hasMessage("제한 인원이 꽉 찬 골룸에는 참여할 수 없습니다."); - } - - @Test - void 골룸_참가_요청시_모집_중이_아닌_경우_예외가_발생한다() { - //given - final List roadmapNodes = 로드맵_노드들을_생성한다(); - final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); - final Member creator = 사용자를_생성한다(1L, "identifier1", "password1!", "시진이", "kirikiri1@email"); - final int limitedMemberCount = 20; - final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, roadmapContent, limitedMemberCount); - final Member follower = 사용자를_생성한다(2L, "identifier2", "password2!", "팔로워", "kirikiri1@email"); - goalRoom.start(); - - when(memberRepository.findByIdentifier(any())) - .thenReturn(Optional.of(follower)); - when(goalRoomRepository.findGoalRoomByIdWithPessimisticLock(anyLong())) - .thenReturn(Optional.of(goalRoom)); - - //when, then - assertThatThrownBy(() -> goalRoomCreateService.join("identifier2", 1L)) - .isInstanceOf(GoalRoomException.class) - .hasMessage("모집 중이지 않은 골룸에는 참여할 수 없습니다."); - } - - @Test - void 정상적으로_골룸에_투두리스트를_추가한다() { - //given - final Member creator = 사용자를_생성한다(1L, "identifier1", "password1!", "시진이", "kirikiri1@email"); - final Roadmap roadmap = 로드맵을_생성한다(creator); - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final int limitedMemberCount = 20; - final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, limitedMemberCount); - - goalRoom.addGoalRoomTodo( - new GoalRoomToDo(new GoalRoomTodoContent("goalRoomTodoContent"), new Period(TODAY, TEN_DAY_LATER))); - - given(memberRepository.findByIdentifier(any())) - .willReturn(Optional.of(creator)); - given(goalRoomRepository.findById(anyLong())) - .willReturn(Optional.of(goalRoom)); - - final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest("goalRoomContent", TODAY, - TEN_DAY_LATER); - - //when - //then - assertDoesNotThrow(() -> goalRoomCreateService.addGoalRoomTodo(1L, "identifier1", goalRoomTodoRequest)); - } - - @Test - void 골룸에_투두리스트_추가시_회원을_찾지_못할_경우_예외를_던진다() { - //given - given(memberRepository.findByIdentifier(any())) - .willReturn(Optional.empty()); - - final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest("goalRoomContent", TODAY, - TEN_DAY_LATER); - - //when - //then - assertThatThrownBy(() -> goalRoomCreateService.addGoalRoomTodo(1L, "identifier1", goalRoomTodoRequest)) - .isInstanceOf(NotFoundException.class); - } - - @Test - void 골룸에_투두리스트_추가시_골룸을_찾지_못할_경우_예외를_던진다() { - //given - final Member creator = 사용자를_생성한다(1L, "identifier1", "password1!", "시진이", "kirikiri1@email"); - final Roadmap roadmap = 로드맵을_생성한다(creator); - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final int limitedMemberCount = 20; - final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, limitedMemberCount); - - goalRoom.addGoalRoomTodo( - new GoalRoomToDo(new GoalRoomTodoContent("goalRoomTodoContent"), new Period(TODAY, TEN_DAY_LATER))); - - given(memberRepository.findByIdentifier(any())) - .willReturn(Optional.of(creator)); - given(goalRoomRepository.findById(anyLong())) - .willReturn(Optional.empty()); - - final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest("goalRoomContent", TODAY, - TEN_DAY_LATER); - - //when - //then - assertThatThrownBy(() -> goalRoomCreateService.addGoalRoomTodo(1L, "identifier1", goalRoomTodoRequest)) - .isInstanceOf(NotFoundException.class); - } - - @Test - void 골룸에_투두리스트_추가시_종료된_골룸일_경우_예외를_던진다() { - //given - final Member creator = 사용자를_생성한다(1L, "identifier1", "password1!", "시진이", "kirikiri1@email"); - final Roadmap roadmap = 로드맵을_생성한다(creator); - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final int limitedMemberCount = 20; - final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, limitedMemberCount); - - goalRoom.addGoalRoomTodo( - new GoalRoomToDo(new GoalRoomTodoContent("goalRoomTodoContent"), new Period(TODAY, TEN_DAY_LATER))); - goalRoom.complete(); - - given(memberRepository.findByIdentifier(any())) - .willReturn(Optional.of(creator)); - given(goalRoomRepository.findById(anyLong())) - .willReturn(Optional.of(goalRoom)); - - final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest("goalRoomContent", TODAY, - TEN_DAY_LATER); - - //when - //then - assertThatThrownBy(() -> goalRoomCreateService.addGoalRoomTodo(1L, "identifier1", goalRoomTodoRequest)) - .isInstanceOf(BadRequestException.class); - } - - @Test - void 골룸에_투두리스트_추가시_리더가_아닐_경우_예외를_던진다() { - //given - final Member creator = 사용자를_생성한다(1L, "identifier1", "password1!", "시진이", "kirikiri1@email"); - final Roadmap roadmap = 로드맵을_생성한다(creator); - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final int limitedMemberCount = 20; - final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, limitedMemberCount); - - goalRoom.addGoalRoomTodo( - new GoalRoomToDo(new GoalRoomTodoContent("goalRoomTodoContent"), new Period(TODAY, TEN_DAY_LATER))); - - given(memberRepository.findByIdentifier(any())) - .willReturn(Optional.of(member)); - given(goalRoomRepository.findById(anyLong())) - .willReturn(Optional.of(goalRoom)); - - final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest("goalRoomContent", TODAY, - TEN_DAY_LATER); - - //when - //then - assertThatThrownBy(() -> goalRoomCreateService.addGoalRoomTodo(1L, "identifier2", goalRoomTodoRequest)) - .isInstanceOf(BadRequestException.class); - } - - @Test - void 골룸에_투두리스트_추가시_골룸_컨텐츠가_250글자가_넘을때_예외를_던진다() { - //given - final Member creator = 사용자를_생성한다(1L, "identifier1", "password1!", "시진이", "kirikiri1@email"); - final Roadmap roadmap = 로드맵을_생성한다(creator); - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final int limitedMemberCount = 20; - final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, limitedMemberCount); - - goalRoom.addGoalRoomTodo( - new GoalRoomToDo(new GoalRoomTodoContent("goalRoomTodoContent"), new Period(TODAY, TEN_DAY_LATER))); - - given(memberRepository.findByIdentifier(any())) - .willReturn(Optional.of(creator)); - given(goalRoomRepository.findById(anyLong())) - .willReturn(Optional.of(goalRoom)); - - final String goalRoomTodoContent = "a".repeat(251); - final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest(goalRoomTodoContent, TODAY, - TEN_DAY_LATER); - - //when - //then - assertThatThrownBy(() -> goalRoomCreateService.addGoalRoomTodo(1L, "identifier1", goalRoomTodoRequest)) - .isInstanceOf(GoalRoomException.class); - } - - @Test - void 골룸을_시작한다() { - // given - final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); - final Roadmap roadmap = 로드맵을_생성한다(creator); - - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 10); - - when(memberRepository.findByIdentifier(any())) - .thenReturn(Optional.of(creator)); - when(goalRoomRepository.findById(any())) - .thenReturn(Optional.of(goalRoom)); - - // when - goalRoomCreateService.startGoalRoom("cokirikiri", 1L); - - // then - assertThat(goalRoom.getStatus()).isEqualTo(RUNNING); - } - - @Test - void 골룸_시작시_존재하지_않는_사용자면_예외가_발생한다() { - // given - when(memberRepository.findByIdentifier(any())) - .thenReturn(Optional.empty()); - - // expected - assertThatThrownBy(() -> goalRoomCreateService.startGoalRoom("identifier", 1L)) - .isInstanceOf(NotFoundException.class); - } - - @Test - void 골룸_시작시_존재하지_않는_골룸이면_예외가_발생한다() { - // given - final Member member = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); - - when(memberRepository.findByIdentifier(any())) - .thenReturn(Optional.of(member)); - when(goalRoomRepository.findById(any())) - .thenReturn(Optional.empty()); - - // expected - assertThatThrownBy(() -> goalRoomCreateService.startGoalRoom("identifier", 1L)) - .isInstanceOf(NotFoundException.class); - } - - @Test - void 골룸을_시작하는_사용자가_골룸의_리더가_아니면_예외가_발생한다() { - // given - final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); - final Member follower = 사용자를_생성한다(2L, "kirikirico", "password2!", "끼리코", "kirikiri1@email"); - final Roadmap roadmap = 로드맵을_생성한다(creator); - - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 10); - - when(memberRepository.findByIdentifier(any())) - .thenReturn(Optional.of(follower)); - when(goalRoomRepository.findById(any())) - .thenReturn(Optional.of(goalRoom)); - - // expected - assertThatThrownBy(() -> goalRoomCreateService.startGoalRoom("identifier", 1L)) - .isInstanceOf(BadRequestException.class); - } - - @Test - void 골룸_시작시_시작날짜가_아직_지나지_않았으면_예외가_발생한다() { - // given - final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); - final Roadmap roadmap = 로드맵을_생성한다(creator); - - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom = 시작_날짜가_미래인_골룸을_생성한다(1L, creator, targetRoadmapContent, 10); - - when(memberRepository.findByIdentifier(any())) - .thenReturn(Optional.of(creator)); - when(goalRoomRepository.findById(any())) - .thenReturn(Optional.of(goalRoom)); - - // expected - assertThatThrownBy(() -> goalRoomCreateService.startGoalRoom("cokirikiri", 1L)) - .isInstanceOf(BadRequestException.class); - } - - @Test - void 인증_피드_등록을_요청한다() { - // given - final CheckFeedRequest request = 인증_피드_요청_DTO를_생성한다("image/jpeg"); - - final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); - final Roadmap roadmap = 로드맵을_생성한다(creator); - - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 20); - final GoalRoomMember goalRoomLeader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, - creator); - goalRoomMemberRepository.save(goalRoomLeader); - final GoalRoomRoadmapNode goalRoomRoadmapNode = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); - final CheckFeed checkFeed = 인증_피드를_생성한다(goalRoomRoadmapNode, goalRoomLeader); - - when(goalRoomRepository.findById(anyLong())) - .thenReturn(Optional.of(goalRoom)); - when(goalRoomMemberRepository.findByGoalRoomAndMemberIdentifier(any(), any())) - .thenReturn(Optional.of(goalRoomLeader)); - when(checkFeedRepository.findByGoalRoomMemberAndDateTime(any(), any(), any())) - .thenReturn(Optional.empty()); - when(checkFeedRepository.countByGoalRoomMemberAndGoalRoomRoadmapNode(any(), any())) - .thenReturn(0); - when(checkFeedRepository.save(any())) - .thenReturn(checkFeed); - when(filePathGenerator.makeFilePath(any(), any())) - .thenReturn("originalFileName.jpeg"); - when(fileService.generateUrl(anyString(), any())) - .thenReturn(makeUrl("originalFileName.jpeg")); - - // when - final String response = goalRoomCreateService.createCheckFeed("identifier", 1L, request); - - // then - assertAll( - () -> assertThat(goalRoomLeader.getAccomplishmentRate()).isEqualTo(100 / (double) 10), - () -> assertThat(response).contains("originalFileName") - ); - } - - @Test - void 인증_피드_등록시_노드_기간에_해당하지_않으면_예외가_발생한다() { - // given - final CheckFeedRequest request = 인증_피드_요청_DTO를_생성한다("image/jpeg"); - - final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); - final Roadmap roadmap = 로드맵을_생성한다(creator); - - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom = 시작_날짜가_미래인_골룸을_생성한다(1L, creator, targetRoadmapContent, 20); - final GoalRoomMember goalRoomLeader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, - creator); - goalRoomMemberRepository.save(goalRoomLeader); - - when(goalRoomRepository.findById(anyLong())) - .thenReturn(Optional.of(goalRoom)); - when(goalRoomMemberRepository.findByGoalRoomAndMemberIdentifier(any(), any())) - .thenReturn(Optional.of(goalRoomLeader)); - - // expected - assertThatThrownBy( - () -> goalRoomCreateService.createCheckFeed("identifier", 1L, request)) - .isInstanceOf(BadRequestException.class) - .hasMessage("인증 피드는 노드 기간 내에만 작성할 수 있습니다."); - } - - @Test - void 하루에_두_번_이상_인증_피드_등록_요청_시_예외를_반환한다() { - // given - final CheckFeedRequest request = 인증_피드_요청_DTO를_생성한다("image/jpeg"); - - final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); - final Roadmap roadmap = 로드맵을_생성한다(creator); - - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 20); - final GoalRoomMember goalRoomLeader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, - creator); - goalRoomMemberRepository.save(goalRoomLeader); - final GoalRoomRoadmapNode goalRoomRoadmapNode = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); - final CheckFeed checkFeed = 인증_피드를_생성한다(goalRoomRoadmapNode, goalRoomLeader); - - when(goalRoomRepository.findById(any())) - .thenReturn(Optional.of(goalRoom)); - when(goalRoomMemberRepository.findByGoalRoomAndMemberIdentifier(any(), any())) - .thenReturn(Optional.of(goalRoomLeader)); - when(checkFeedRepository.findByGoalRoomMemberAndDateTime(any(), any(), any())) - .thenReturn(Optional.of(checkFeed)); - - //expect - assertThatThrownBy( - () -> goalRoomCreateService.createCheckFeed("identifier", 1L, request)) - .isInstanceOf(BadRequestException.class) - .hasMessage("이미 오늘 인증 피드를 등록하였습니다."); - } - - @Test - void 골룸_노드에서_허가된_인증_횟수보다_많은_인증_피드_등록_요청_시_예외를_반환한다() { - // given - final CheckFeedRequest request = 인증_피드_요청_DTO를_생성한다("image/jpeg"); - - final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); - final Roadmap roadmap = 로드맵을_생성한다(creator); - - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 20); - final GoalRoomMember goalRoomLeader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, - creator); - goalRoomMemberRepository.save(goalRoomLeader); - final GoalRoomRoadmapNode goalRoomRoadmapNode = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); - - when(goalRoomRepository.findById(any())) - .thenReturn(Optional.of(goalRoom)); - when(goalRoomMemberRepository.findByGoalRoomAndMemberIdentifier(any(), any())) - .thenReturn(Optional.of(goalRoomLeader)); - when(checkFeedRepository.countByGoalRoomMemberAndGoalRoomRoadmapNode(any(), any())) - .thenReturn(goalRoomRoadmapNode.getCheckCount()); - - //expect - assertThatThrownBy( - () -> goalRoomCreateService.createCheckFeed("identifier", 1L, request)) - .isInstanceOf(BadRequestException.class) - .hasMessage("이번 노드에는 최대 " + goalRoomRoadmapNode.getCheckCount() + "번만 인증 피드를 등록할 수 있습니다."); - } - - @Test - void 인증_피드_등록_요청_시_허용되지_않는_확장자_형식이라면_예외를_반환한다() { - // given - final CheckFeedRequest request = 인증_피드_요청_DTO를_생성한다("image/gif"); - - final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); - final Roadmap roadmap = 로드맵을_생성한다(creator); - - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 20); - final GoalRoomMember goalRoomLeader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, - creator); - goalRoomMemberRepository.save(goalRoomLeader); - final GoalRoomRoadmapNode goalRoomRoadmapNode = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0); - - when(goalRoomRepository.findById(any())) - .thenReturn(Optional.of(goalRoom)); - when(goalRoomMemberRepository.findByGoalRoomAndMemberIdentifier(any(), any())) - .thenReturn(Optional.of(goalRoomLeader)); - - // when - assertThatThrownBy( - () -> goalRoomCreateService.createCheckFeed("identifier", 1L, request)) - .isInstanceOf(ImageExtensionException.class) - .hasMessage("허용되지 않는 확장자입니다."); - } - - @Test - void 인증_피드_등록_요청_시_존재하지_않는_골룸이라면_예외를_반환한다() { - // given - final CheckFeedRequest request = 인증_피드_요청_DTO를_생성한다("image/jpeg"); - - final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); - final Roadmap roadmap = 로드맵을_생성한다(creator); - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 20); - final GoalRoomMember goalRoomLeader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, - creator); - goalRoomMemberRepository.save(goalRoomLeader); - - when(goalRoomRepository.findById(any())) - .thenReturn(Optional.empty()); - - //expect - assertThatThrownBy( - () -> goalRoomCreateService.createCheckFeed("identifier", 1L, request)) - .isInstanceOf(NotFoundException.class) - .hasMessage("존재하지 않는 골룸입니다. goalRoomId = 1"); - } - - @Test - void 인증_피드_등록_요청_시_사용자가_참여하지_않은_골룸이라면_예외를_반환한다() { - // given - final CheckFeedRequest request = 인증_피드_요청_DTO를_생성한다("image/jpeg"); - - final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); - final Roadmap roadmap = 로드맵을_생성한다(creator); - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 20); - - final GoalRoomMember goalRoomLeader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, - creator); - goalRoomMemberRepository.save(goalRoomLeader); - - when(goalRoomRepository.findById(any())) - .thenReturn(Optional.of(goalRoom)); - when(goalRoomMemberRepository.findByGoalRoomAndMemberIdentifier(any(), any())) - .thenReturn(Optional.empty()); - - //expect - assertThatThrownBy( - () -> goalRoomCreateService.createCheckFeed("identifier", 1L, request)) - .isInstanceOf(NotFoundException.class) - .hasMessage("골룸에 해당 사용자가 존재하지 않습니다. 사용자 아이디 = " + "identifier"); - } - - @Test - void 투두리스트를_체크한다() { - // given - final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); - final Roadmap roadmap = 로드맵을_생성한다(creator); - - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 10); - goalRoom.addGoalRoomTodo(new GoalRoomToDo( - 1L, new GoalRoomTodoContent("투두 1"), new Period(TODAY, TODAY.plusDays(3)) - )); - final GoalRoomMember goalRoomMember = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, - creator); - - when(goalRoomRepository.findByIdWithTodos(anyLong())) - .thenReturn(Optional.of(goalRoom)); - - when(goalRoomMemberRepository.findByGoalRoomAndMemberIdentifier(any(), any())) - .thenReturn(Optional.of(goalRoomMember)); - - when(goalRoomToDoCheckRepository.findByGoalRoomIdAndTodoAndMemberIdentifier(any(), any(), any())) - .thenReturn(Optional.empty()); - - // when - final GoalRoomToDoCheckResponse checkResponse = goalRoomCreateService.checkGoalRoomTodo(1L, 1L, "cokirikiri"); - - // then - assertThat(checkResponse) - .isEqualTo(new GoalRoomToDoCheckResponse(true)); - } - - @Test - void 투두리스트_체크시_체크_이력이_있으면_제거한다() { - // given - final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); - final Roadmap roadmap = 로드맵을_생성한다(creator); - - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 10); - final GoalRoomToDo goalRoomToDo = new GoalRoomToDo( - 1L, new GoalRoomTodoContent("투두 1"), new Period(TODAY, TODAY.plusDays(3))); - goalRoom.addGoalRoomTodo(goalRoomToDo); - - final GoalRoomMember goalRoomMember = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, - creator); - final GoalRoomToDoCheck goalRoomToDoCheck = new GoalRoomToDoCheck(goalRoomMember, goalRoomToDo); - - when(goalRoomRepository.findByIdWithTodos(anyLong())) - .thenReturn(Optional.of(goalRoom)); - - when(goalRoomMemberRepository.findByGoalRoomAndMemberIdentifier(any(), any())) - .thenReturn(Optional.of(goalRoomMember)); - - when(goalRoomToDoCheckRepository.findByGoalRoomIdAndTodoAndMemberIdentifier(any(), any(), any())) - .thenReturn(Optional.of(goalRoomToDoCheck)); - - // when - final GoalRoomToDoCheckResponse checkResponse = goalRoomCreateService.checkGoalRoomTodo(1L, 1L, "cokirikiri"); - - // then - assertThat(checkResponse) - .isEqualTo(new GoalRoomToDoCheckResponse(false)); - } - - @Test - void 투두리스트_체크시_골룸이_존재하지_않으면_예외가_발생한다() { - // given - when(goalRoomRepository.findByIdWithTodos(anyLong())) - .thenReturn(Optional.empty()); - - // expected - assertThatThrownBy(() -> goalRoomCreateService.checkGoalRoomTodo(1L, 1L, "cokirikiri")) - .isInstanceOf(NotFoundException.class) - .hasMessage("골룸이 존재하지 않습니다. goalRoomId = 1"); - } - - @Test - void 투두리스트_체크시_해당_투두가_존재하지_않으면_예외가_발생한다() { - // given - final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); - final Roadmap roadmap = 로드맵을_생성한다(creator); - - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 10); - goalRoom.addGoalRoomTodo(new GoalRoomToDo( - 1L, new GoalRoomTodoContent("투두 1"), new Period(TODAY, TODAY.plusDays(3)))); - - when(goalRoomRepository.findByIdWithTodos(anyLong())) - .thenReturn(Optional.of(goalRoom)); - - // expected - assertThatThrownBy(() -> goalRoomCreateService.checkGoalRoomTodo(1L, 2L, "cokirikiri")) - .isInstanceOf(NotFoundException.class) - .hasMessage("존재하지 않는 투두입니다. todoId = 2"); - } - - @Test - void 투두리스트_체크시_골룸에_사용자가_없으면_예외가_발생한다() { - // given - final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); - final Roadmap roadmap = 로드맵을_생성한다(creator); - - final RoadmapContents roadmapContents = roadmap.getContents(); - final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); - final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 10); - goalRoom.addGoalRoomTodo(new GoalRoomToDo( - 1L, new GoalRoomTodoContent("투두 1"), new Period(TODAY, TODAY.plusDays(3)))); - - when(goalRoomRepository.findByIdWithTodos(anyLong())) - .thenReturn(Optional.of(goalRoom)); - - when(goalRoomMemberRepository.findByGoalRoomAndMemberIdentifier(any(), any())) - .thenReturn(Optional.empty()); - - // expected - assertThatThrownBy(() -> goalRoomCreateService.checkGoalRoomTodo(1L, 1L, "cokirikiri")) - .isInstanceOf(NotFoundException.class) - .hasMessage("골룸에 사용자가 존재하지 않습니다. goalRoomId = 1 memberIdentifier = cokirikiri"); - } - - @Test - void 골룸을_나간다() { - // given - final GoalRoom goalRoom = new GoalRoom(1L, new GoalRoomName("골룸"), new LimitedMemberCount(3), - new RoadmapContent("content"), MEMBER); - - given(memberRepository.findByIdentifier(any())) - .willReturn(Optional.of(MEMBER)); - given(goalRoomRepository.findById(anyLong())) - .willReturn(Optional.of(goalRoom)); - - // when - // then - assertDoesNotThrow(() -> goalRoomCreateService.leave("identifier2", 1L)); - - } - - @Test - void 골룸을_나갈때_존재하지_않는_회원일_경우_예외가_발생한다() { - // given - given(memberRepository.findByIdentifier(any())) - .willReturn(Optional.empty()); - - // when - // then - assertThatThrownBy(() -> goalRoomCreateService.leave("identifier2", 1L)) - .isInstanceOf(NotFoundException.class); - } - - @Test - void 골룸을_나갈때_존재하지_않는_골룸일_경우_예외가_발생한다() { - // given - given(memberRepository.findByIdentifier(any())) - .willReturn(Optional.of(member)); - given(goalRoomRepository.findById(anyLong())) - .willReturn(Optional.empty()); - - // when - // then - assertThatThrownBy(() -> goalRoomCreateService.leave("identifier2", 1L)) - .isInstanceOf(NotFoundException.class); - } - - @Test - void 골룸을_나갈때_골룸이_진행중이면_예외가_발생한다() { - // given - final GoalRoom goalRoom = new GoalRoom(1L, new GoalRoomName("골룸"), new LimitedMemberCount(3), - new RoadmapContent("content"), MEMBER); - - given(memberRepository.findByIdentifier(any())) - .willReturn(Optional.of(member)); - given(goalRoomRepository.findById(anyLong())) - .willReturn(Optional.of(goalRoom)); - - // when - goalRoom.start(); - - // then - assertThatThrownBy(() -> goalRoomCreateService.leave("identifier2", 1L)) - .isInstanceOf(BadRequestException.class); - } - - @Test - void 골룸을_나갈때_골룸에_남아있는_사용자가_없으면_골룸이_삭제된다() { - // given - final GoalRoom goalRoom = new GoalRoom(1L, new GoalRoomName("골룸"), new LimitedMemberCount(3), - new RoadmapContent("content"), MEMBER); - - given(memberRepository.findByIdentifier(any())) - .willReturn(Optional.of(member)); - given(goalRoomRepository.findById(anyLong())) - .willReturn(Optional.of(goalRoom)); - - // when - goalRoomCreateService.leave("identifier2", 1L); - - // then - verify(goalRoomRepository, times(1)).delete(goalRoom); - } - - private Member 사용자를_생성한다(final Long memberId, final String identifier, final String password, final String nickname, - final String email) { - final MemberProfile memberProfile = new MemberProfile(Gender.MALE, email); - - return new Member(memberId, new Identifier(identifier), null, new EncryptedPassword(new Password(password)), - new Nickname(nickname), null, memberProfile); - } - - private Roadmap 로드맵을_생성한다(final Member creator) { - final RoadmapCategory category = new RoadmapCategory("게임"); - final List roadmapNodes = 로드맵_노드들을_생성한다(); - final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); - final Roadmap roadmap = new Roadmap("로드맵 제목", "로드맵 소개글", 10, RoadmapDifficulty.NORMAL, creator, category); - roadmap.addContent(roadmapContent); - return roadmap; - } - - private List 로드맵_노드들을_생성한다() { - final RoadmapNode roadmapNode1 = new RoadmapNode("로드맵 1주차", "로드맵 1주차 내용"); - roadmapNode1.addImages(new RoadmapNodeImages(노드_이미지들을_생성한다())); - final RoadmapNode roadmapNode2 = new RoadmapNode("로드맵 2주차", "로드맵 2주차 내용"); - return List.of(roadmapNode1, roadmapNode2); - } - - private RoadmapContent 로드맵_본문을_생성한다(final List roadmapNodes) { - final RoadmapContent roadmapContent = new RoadmapContent("로드맵 본문"); - roadmapContent.addNodes(new RoadmapNodes(roadmapNodes)); - return roadmapContent; - } - - private List 노드_이미지들을_생성한다() { - return List.of( - new RoadmapNodeImage("node-image1.png", "node-image1-save-path", ImageContentType.PNG), - new RoadmapNodeImage("node-image2.png", "node-image2-save-path", ImageContentType.PNG) - ); - } - - private GoalRoom 골룸을_생성한다(final Long goalRoomId, final Member creator, final RoadmapContent roadmapContent, - final Integer limitedMemberCount) { - final GoalRoom goalRoom = new GoalRoom(goalRoomId, new GoalRoomName("골룸 이름"), - new LimitedMemberCount(limitedMemberCount), roadmapContent, creator); - goalRoom.addAllGoalRoomRoadmapNodes(골룸_로드맵_노드들을_생성한다(roadmapContent.getNodes())); - return goalRoom; - } - - private GoalRoom 시작_날짜가_미래인_골룸을_생성한다(final Long goalRoomId, final Member creator, - final RoadmapContent roadmapContent, final Integer limitedMemberCount) { - final GoalRoom goalRoom = new GoalRoom(goalRoomId, new GoalRoomName("골룸 이름"), - new LimitedMemberCount(limitedMemberCount), roadmapContent, creator); - final GoalRoomRoadmapNode goalRoomRoadmapNode = new GoalRoomRoadmapNode( - new Period(TEN_DAY_LATER, TWENTY_DAY_LATER), 5, roadmapContent.getNodes().getValues().get(0)); - goalRoom.addAllGoalRoomRoadmapNodes( - new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode))); - return goalRoom; - } - - private GoalRoomRoadmapNodes 골룸_로드맵_노드들을_생성한다(final RoadmapNodes roadmapNodes) { - return new GoalRoomRoadmapNodes(List.of( - new GoalRoomRoadmapNode(new Period(TODAY, TEN_DAY_LATER), 5, roadmapNodes.getValues().get(0)), - new GoalRoomRoadmapNode(new Period(TEN_DAY_LATER.plusDays(1), TWENTY_DAY_LATER), 5, - roadmapNodes.getValues().get(1))) - ); - } - - private CheckFeedRequest 인증_피드_요청_DTO를_생성한다(final String contentType) { - return new CheckFeedRequest( - new MockMultipartFile("image", "originalFileName.jpeg", contentType, - "test image".getBytes()), "인증 피드 설명"); - } - - private CheckFeed 인증_피드를_생성한다(final GoalRoomRoadmapNode goalRoomRoadmapNode, final GoalRoomMember joinedMember) { - return new CheckFeed("src/test/resources/testImage/originalFileName.jpeg", ImageContentType.JPEG, - "originalFileName.jpeg", "인증 피드 설명", goalRoomRoadmapNode, joinedMember); - } - - private URL makeUrl(final String path) { - try { - return new URL("http://example.com/" + path); - } catch (final MalformedURLException e) { - throw new RuntimeException(e); - } - } -} diff --git a/backend/kirikiri/src/test/java/co/kirikiri/service/JwtTokenProviderTest.java b/backend/kirikiri/src/test/java/co/kirikiri/service/JwtTokenProviderTest.java index ec35509ae..b91457c58 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/service/JwtTokenProviderTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/service/JwtTokenProviderTest.java @@ -4,9 +4,9 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import co.kirikiri.common.exception.AuthenticationException; import co.kirikiri.service.auth.JwtTokenProvider; import co.kirikiri.service.auth.TokenProvider; -import co.kirikiri.service.exception.AuthenticationException; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.security.Keys; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/service/MemberServiceTest.java b/backend/kirikiri/src/test/java/co/kirikiri/service/MemberServiceTest.java index 30d66dc46..c7c488d20 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/service/MemberServiceTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/service/MemberServiceTest.java @@ -6,7 +6,10 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; -import co.kirikiri.domain.ImageContentType; +import co.kirikiri.common.exception.ConflictException; +import co.kirikiri.common.exception.NotFoundException; +import co.kirikiri.common.service.FileService; +import co.kirikiri.common.type.ImageContentType; import co.kirikiri.domain.member.EncryptedPassword; import co.kirikiri.domain.member.Gender; import co.kirikiri.domain.member.Member; @@ -24,8 +27,6 @@ import co.kirikiri.service.dto.member.request.MemberJoinRequest; import co.kirikiri.service.dto.member.response.MemberInformationForPublicResponse; import co.kirikiri.service.dto.member.response.MemberInformationResponse; -import co.kirikiri.service.exception.ConflictException; -import co.kirikiri.service.exception.NotFoundException; import co.kirikiri.service.member.MemberService; import java.net.MalformedURLException; import java.net.URL; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapCreateEventListenerTest.java b/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapCreateEventListenerTest.java index e2ce4b915..91825d1b7 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapCreateEventListenerTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapCreateEventListenerTest.java @@ -4,6 +4,11 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import co.kirikiri.common.exception.BadRequestException; +import co.kirikiri.common.exception.ServerException; +import co.kirikiri.common.service.FilePathGenerator; +import co.kirikiri.common.service.FileService; +import co.kirikiri.common.service.dto.FileInformation; import co.kirikiri.domain.member.EncryptedPassword; import co.kirikiri.domain.member.Gender; import co.kirikiri.domain.member.Member; @@ -18,14 +23,11 @@ import co.kirikiri.domain.roadmap.RoadmapNode; import co.kirikiri.domain.roadmap.RoadmapNodes; import co.kirikiri.persistence.roadmap.RoadmapContentRepository; -import co.kirikiri.service.dto.FileInformation; import co.kirikiri.service.dto.roadmap.RoadmapNodeSaveDto; import co.kirikiri.service.dto.roadmap.RoadmapSaveDto; import co.kirikiri.service.dto.roadmap.RoadmapTagSaveDto; import co.kirikiri.service.dto.roadmap.request.RoadmapDifficultyType; import co.kirikiri.service.event.RoadmapCreateEvent; -import co.kirikiri.service.exception.BadRequestException; -import co.kirikiri.service.exception.ServerException; import co.kirikiri.service.roadmap.RoadmapCreateEventListener; import java.io.IOException; import java.util.List; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapCreateServiceTest.java b/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapCreateServiceTest.java index f0c78c42e..5b983851a 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapCreateServiceTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapCreateServiceTest.java @@ -12,11 +12,11 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomMember; -import co.kirikiri.domain.goalroom.GoalRoomRole; -import co.kirikiri.domain.goalroom.vo.GoalRoomName; -import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; +import co.kirikiri.common.exception.AuthenticationException; +import co.kirikiri.common.exception.BadRequestException; +import co.kirikiri.common.exception.ConflictException; +import co.kirikiri.common.exception.ForbiddenException; +import co.kirikiri.common.exception.NotFoundException; import co.kirikiri.domain.member.EncryptedPassword; import co.kirikiri.domain.member.Gender; import co.kirikiri.domain.member.Member; @@ -30,8 +30,13 @@ import co.kirikiri.domain.roadmap.RoadmapContents; import co.kirikiri.domain.roadmap.RoadmapDifficulty; import co.kirikiri.domain.roadmap.RoadmapReview; -import co.kirikiri.persistence.goalroom.GoalRoomMemberRepository; -import co.kirikiri.persistence.goalroom.GoalRoomRepository; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomMember; +import co.kirikiri.goalroom.domain.GoalRoomRole; +import co.kirikiri.goalroom.domain.vo.GoalRoomName; +import co.kirikiri.goalroom.domain.vo.LimitedMemberCount; +import co.kirikiri.goalroom.persistence.GoalRoomMemberRepository; +import co.kirikiri.goalroom.persistence.GoalRoomRepository; import co.kirikiri.persistence.member.MemberRepository; import co.kirikiri.persistence.roadmap.RoadmapCategoryRepository; import co.kirikiri.persistence.roadmap.RoadmapRepository; @@ -42,11 +47,6 @@ import co.kirikiri.service.dto.roadmap.request.RoadmapReviewSaveRequest; import co.kirikiri.service.dto.roadmap.request.RoadmapSaveRequest; import co.kirikiri.service.dto.roadmap.request.RoadmapTagSaveRequest; -import co.kirikiri.service.exception.AuthenticationException; -import co.kirikiri.service.exception.BadRequestException; -import co.kirikiri.service.exception.ConflictException; -import co.kirikiri.service.exception.ForbiddenException; -import co.kirikiri.service.exception.NotFoundException; import co.kirikiri.service.roadmap.RoadmapCreateService; import java.time.LocalDateTime; import java.util.Collections; @@ -172,7 +172,7 @@ null, new EncryptedPassword(new Password("password1!")), new Nickname("닉네임 .thenReturn(Optional.of(roadmap)); when(goalRoomMemberRepository.findByRoadmapIdAndMemberIdentifierAndGoalRoomStatus(anyLong(), any(), any())) .thenReturn(Optional.of( - new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, follower))); + new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, follower.getId()))); when(roadmapReviewRepository.findByRoadmapAndMember(any(), any())) .thenReturn(Optional.empty()); @@ -235,7 +235,7 @@ null, new EncryptedPassword(new Password("password1!")), new Nickname("닉네임 .thenReturn(Optional.of(roadmap)); when(goalRoomMemberRepository.findByRoadmapIdAndMemberIdentifierAndGoalRoomStatus(anyLong(), any(), any())) .thenReturn(Optional.of( - new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, follower))); + new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom, follower.getId()))); when(roadmapReviewRepository.findByRoadmapAndMember(any(), any())) .thenReturn(Optional.of(new RoadmapReview("로드맵 짱!", 5.0, MEMBER))); @@ -256,7 +256,7 @@ null, new EncryptedPassword(new Password("password1!")), new Nickname("닉네임 .thenReturn(Optional.of(roadmap)); when(roadmapRepository.findByIdAndMemberIdentifier(anyLong(), anyString())) .thenReturn(Optional.of(roadmap)); - when(goalRoomRepository.findByRoadmap(any())) + when(goalRoomRepository.findByRoadmapContentId(any())) .thenReturn(Collections.emptyList()); // when @@ -283,7 +283,7 @@ null, new EncryptedPassword(new Password("password1!")), new Nickname("닉네임 .thenReturn(Optional.of(roadmap)); when(roadmapRepository.findByIdAndMemberIdentifier(anyLong(), anyString())) .thenReturn(Optional.of(roadmap)); - when(goalRoomRepository.findByRoadmap(any())) + when(goalRoomRepository.findByRoadmapContentId(any())) .thenReturn(List.of(goalRoom)); // when @@ -363,6 +363,6 @@ null, new EncryptedPassword(new Password("password1!")), new Nickname("닉네임 } private GoalRoom 골룸을_생성한다(final Member member, final RoadmapContent roadmapContent) { - return new GoalRoom(new GoalRoomName("골룸"), new LimitedMemberCount(10), roadmapContent, member); + return new GoalRoom(new GoalRoomName("골룸"), new LimitedMemberCount(10), roadmapContent.getId(), member.getId()); } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapReadServiceTest.java b/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapReadServiceTest.java index d6222964e..fdc79fa04 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapReadServiceTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapReadServiceTest.java @@ -9,14 +9,9 @@ import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.when; -import co.kirikiri.domain.ImageContentType; -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNode; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNodes; -import co.kirikiri.domain.goalroom.GoalRoomStatus; -import co.kirikiri.domain.goalroom.vo.GoalRoomName; -import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; -import co.kirikiri.domain.goalroom.vo.Period; +import co.kirikiri.common.exception.NotFoundException; +import co.kirikiri.common.service.FileService; +import co.kirikiri.common.type.ImageContentType; import co.kirikiri.domain.member.EncryptedPassword; import co.kirikiri.domain.member.Gender; import co.kirikiri.domain.member.Member; @@ -35,8 +30,16 @@ import co.kirikiri.domain.roadmap.RoadmapTag; import co.kirikiri.domain.roadmap.RoadmapTags; import co.kirikiri.domain.roadmap.vo.RoadmapTagName; -import co.kirikiri.persistence.goalroom.GoalRoomRepository; -import co.kirikiri.persistence.goalroom.dto.RoadmapGoalRoomsOrderType; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNode; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNodes; +import co.kirikiri.goalroom.domain.GoalRoomStatus; +import co.kirikiri.goalroom.domain.vo.GoalRoomName; +import co.kirikiri.goalroom.domain.vo.LimitedMemberCount; +import co.kirikiri.goalroom.domain.vo.Period; +import co.kirikiri.goalroom.persistence.GoalRoomRepository; +import co.kirikiri.goalroom.persistence.dto.RoadmapGoalRoomsOrderType; +import co.kirikiri.goalroom.service.dto.response.RoadmapGoalRoomResponse; import co.kirikiri.persistence.member.MemberRepository; import co.kirikiri.persistence.roadmap.RoadmapCategoryRepository; import co.kirikiri.persistence.roadmap.RoadmapContentRepository; @@ -53,13 +56,11 @@ import co.kirikiri.service.dto.roadmap.response.RoadmapContentResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapForListResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapForListResponses; -import co.kirikiri.service.dto.roadmap.response.RoadmapGoalRoomResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapGoalRoomResponses; import co.kirikiri.service.dto.roadmap.response.RoadmapNodeResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapReviewResponse; import co.kirikiri.service.dto.roadmap.response.RoadmapTagResponse; -import co.kirikiri.service.exception.NotFoundException; import co.kirikiri.service.roadmap.RoadmapReadService; import java.net.MalformedURLException; import java.net.URL; @@ -125,7 +126,7 @@ null, new EncryptedPassword(new Password("password1!")), new Nickname("닉네임 .thenReturn(Optional.of(roadmap)); when(roadmapContentRepository.findFirstByRoadmapOrderByCreatedAtDesc(any())) .thenReturn(Optional.of(roadmap.getContents().getValues().get(0))); - when(goalRoomRepository.findByRoadmap(any())) + when(goalRoomRepository.findByRoadmapContentId(any())) .thenReturn(goalRooms); when(fileService.generateUrl(anyString(), any())) .thenReturn(new URL("http://example.com/serverFilePath")); @@ -470,32 +471,38 @@ roadmapId, new RoadmapCategoryResponse(1L, "운동"), "로드맵 제목", "로 new RoadmapCategory("it")); final GoalRoomRoadmapNode goalRoomRoadmapNode1 = new GoalRoomRoadmapNode(new Period(TODAY, TODAY.plusDays(10)), - 1, roadmapNode1); + 1, roadmapNode1.getId()); final GoalRoomRoadmapNode goalRoomRoadmapNode2 = new GoalRoomRoadmapNode( - new Period(TODAY.plusDays(11), TODAY.plusDays(20)), 1, roadmapNode2); + new Period(TODAY.plusDays(11), TODAY.plusDays(20)), 1, roadmapNode2.getId()); final GoalRoomRoadmapNode goalRoomRoadmapNode3 = new GoalRoomRoadmapNode(new Period(TODAY, TODAY.plusDays(10)), - 1, roadmapNode1); + 1, roadmapNode1.getId()); final GoalRoomRoadmapNode goalRoomRoadmapNode4 = new GoalRoomRoadmapNode( - new Period(TODAY.plusDays(11), TODAY.plusDays(20)), 1, roadmapNode2); + new Period(TODAY.plusDays(11), TODAY.plusDays(20)), 1, roadmapNode2.getId()); final Member member2 = 사용자를_생성한다(2L, "identifier2", "name2"); final GoalRoom goalRoom1 = new GoalRoom(1L, new GoalRoomName("goalroom1"), new LimitedMemberCount(10), - roadmapContent, member2); + roadmapContent.getId(), member2.getId()); goalRoom1.addAllGoalRoomRoadmapNodes( new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode1, goalRoomRoadmapNode2))); final Member member3 = 사용자를_생성한다(3L, "identifier2", "name3"); final GoalRoom goalRoom2 = new GoalRoom(2L, new GoalRoomName("goalroom2"), new LimitedMemberCount(10), - roadmapContent, member3); + roadmapContent.getId(), member3.getId()); goalRoom2.addAllGoalRoomRoadmapNodes( new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode3, goalRoomRoadmapNode4))); final List goalRooms = List.of(goalRoom2, goalRoom1); given(roadmapRepository.findRoadmapById(anyLong())) .willReturn(Optional.of(roadmap)); - given(goalRoomRepository.findGoalRoomsByRoadmapAndCond(roadmap, + given(roadmapContentRepository.findFirstByRoadmapOrderByCreatedAtDesc(any())) + .willReturn(Optional.of(roadmapContent)); + given(goalRoomRepository.findGoalRoomsByRoadmapContentIdAndCond(roadmapContent.getId(), RoadmapGoalRoomsOrderType.LATEST, null, 10)) .willReturn(goalRooms); + given(memberRepository.findById(2L)) + .willReturn(Optional.of(member2)); + given(memberRepository.findById(3L)) + .willReturn(Optional.of(member3)); given(fileService.generateUrl(anyString(), any())) .willReturn(new URL("http://example.com/serverFilePath")); @@ -508,12 +515,14 @@ roadmapId, new RoadmapCategoryResponse(1L, "운동"), "로드맵 제목", "로 new RoadmapGoalRoomResponse(2L, "goalroom2", GoalRoomStatus.RECRUITING, 1, 10, LocalDateTime.now(), TODAY, TODAY.plusDays(20), - new MemberResponse(member3.getId(), member3.getNickname().getValue(), + new co.kirikiri.goalroom.service.dto.response.MemberResponse(member3.getId(), + member3.getNickname().getValue(), "http://example.com/serverFilePath")), new RoadmapGoalRoomResponse(1L, "goalroom1", GoalRoomStatus.RECRUITING, 1, 10, LocalDateTime.now(), TODAY, TODAY.plusDays(20), - new MemberResponse(member2.getId(), member2.getNickname().getValue(), + new co.kirikiri.goalroom.service.dto.response.MemberResponse(member2.getId(), + member2.getNickname().getValue(), "http://example.com/serverFilePath"))), false); assertThat(result) @@ -655,17 +664,17 @@ null, new EncryptedPassword(new Password("password1!")), private List 상태별_골룸_목록을_생성한다() { final RoadmapContent roadmapContent = new RoadmapContent("로드맵 내용"); final GoalRoom recruitedGoalRoom1 = new GoalRoom(new GoalRoomName("모집 중 골룸 1"), - new LimitedMemberCount(20), roadmapContent, member); + new LimitedMemberCount(20), roadmapContent.getId(), member.getId()); final GoalRoom recruitedGoalRoom2 = new GoalRoom(new GoalRoomName("모집 중 골룸 2"), - new LimitedMemberCount(20), roadmapContent, member); + new LimitedMemberCount(20), roadmapContent.getId(), member.getId()); final GoalRoom runningGoalRoom1 = new GoalRoom(new GoalRoomName("진행 중 골룸 1"), - new LimitedMemberCount(20), roadmapContent, member); + new LimitedMemberCount(20), roadmapContent.getId(), member.getId()); final GoalRoom runningGoalRoom2 = new GoalRoom(new GoalRoomName("진행 중 골룸 2"), - new LimitedMemberCount(20), roadmapContent, member); + new LimitedMemberCount(20), roadmapContent.getId(), member.getId()); final GoalRoom completedGoalRoom1 = new GoalRoom(new GoalRoomName("완료된 골룸 1"), - new LimitedMemberCount(20), roadmapContent, member); + new LimitedMemberCount(20), roadmapContent.getId(), member.getId()); final GoalRoom completedGoalRoom2 = new GoalRoom(new GoalRoomName("완료된 골룸 2"), - new LimitedMemberCount(20), roadmapContent, member); + new LimitedMemberCount(20), roadmapContent.getId(), member.getId()); runningGoalRoom1.start(); runningGoalRoom2.start(); diff --git a/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapSchedulerTest.java b/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapSchedulerTest.java index eaea4f202..86d0c3379 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapSchedulerTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/service/RoadmapSchedulerTest.java @@ -6,12 +6,6 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNode; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNodes; -import co.kirikiri.domain.goalroom.vo.GoalRoomName; -import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; -import co.kirikiri.domain.goalroom.vo.Period; import co.kirikiri.domain.member.EncryptedPassword; import co.kirikiri.domain.member.Gender; import co.kirikiri.domain.member.Member; @@ -25,17 +19,23 @@ import co.kirikiri.domain.roadmap.RoadmapDifficulty; import co.kirikiri.domain.roadmap.RoadmapNode; import co.kirikiri.domain.roadmap.RoadmapNodes; -import co.kirikiri.persistence.goalroom.GoalRoomRepository; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNode; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNodes; +import co.kirikiri.goalroom.domain.vo.GoalRoomName; +import co.kirikiri.goalroom.domain.vo.LimitedMemberCount; +import co.kirikiri.goalroom.domain.vo.Period; +import co.kirikiri.goalroom.persistence.GoalRoomRepository; import co.kirikiri.persistence.roadmap.RoadmapRepository; import co.kirikiri.service.scheduler.RoadmapScheduler; +import java.time.LocalDate; +import java.util.Collections; +import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import java.time.LocalDate; -import java.util.Collections; -import java.util.List; @ExtendWith(MockitoExtension.class) class RoadmapSchedulerTest { @@ -73,18 +73,18 @@ class RoadmapSchedulerTest { roadmap1.addContent(roadmapContent1_2); final GoalRoom goalRoom1_1 = new GoalRoom(new GoalRoomName("골룸2"), new LimitedMemberCount(10), - roadmapContent1_1, member2); + roadmapContent1_1.getId(), member2.getId()); final GoalRoom goalRoom1_2 = new GoalRoom(new GoalRoomName("골룸2-1"), new LimitedMemberCount(10), - roadmapContent1_2, member2); + roadmapContent1_2.getId(), member2.getId()); final GoalRoomRoadmapNodes goalRoomRoadmapNodes1 = new GoalRoomRoadmapNodes(List.of( - new GoalRoomRoadmapNode(new Period(TODAY, TEN_DAY_LATER), 5, roadmapNode1))); + new GoalRoomRoadmapNode(new Period(TODAY, TEN_DAY_LATER), 5, roadmapNode1.getId()))); goalRoom1_1.addAllGoalRoomRoadmapNodes(goalRoomRoadmapNodes1); goalRoom1_2.addAllGoalRoomRoadmapNodes(goalRoomRoadmapNodes1); given(roadmapRepository.findWithRoadmapContentByStatus(any())) .willReturn(List.of(roadmap1)); - given(goalRoomRepository.findByRoadmap(roadmap1)) + given(goalRoomRepository.findByRoadmapContentId(roadmapContent1_2.getId())) .willReturn(List.of(goalRoom1_1, goalRoom1_2)); // when @@ -115,15 +115,15 @@ class RoadmapSchedulerTest { final Roadmap roadmap1 = new Roadmap("로드맵1", "로드맵 설명1", 30, RoadmapDifficulty.DIFFICULT, member1, category); roadmap1.addContent(roadmapContent1); - final GoalRoom goalRoom1 = new GoalRoom(new GoalRoomName("골룸1"), new LimitedMemberCount(10), roadmapContent1, - member2); + final GoalRoom goalRoom1 = new GoalRoom(new GoalRoomName("골룸1"), new LimitedMemberCount(10), + roadmapContent1.getId(), member2.getId()); final GoalRoomRoadmapNodes goalRoomRoadmapNodes1 = new GoalRoomRoadmapNodes(List.of( - new GoalRoomRoadmapNode(new Period(TODAY, TEN_DAY_LATER), 5, roadmapNode1))); + new GoalRoomRoadmapNode(new Period(TODAY, TEN_DAY_LATER), 5, roadmapNode1.getId()))); goalRoom1.addAllGoalRoomRoadmapNodes(goalRoomRoadmapNodes1); given(roadmapRepository.findWithRoadmapContentByStatus(any())) .willReturn(List.of(roadmap1)); - given(goalRoomRepository.findByRoadmap(roadmap1)) + given(goalRoomRepository.findByRoadmapContentId(roadmapContent1.getId())) .willReturn(List.of(goalRoom1)); // when @@ -153,11 +153,11 @@ class RoadmapSchedulerTest { roadmapContent1.addNodes(new RoadmapNodes(List.of(roadmapNode))); roadmap1.addContent(roadmapContent1); - final GoalRoom goalRoom1 = new GoalRoom(new GoalRoomName("골룸1"), new LimitedMemberCount(10), roadmapContent1, - member2); + final GoalRoom goalRoom1 = new GoalRoom(new GoalRoomName("골룸1"), new LimitedMemberCount(10), + roadmapContent1.getId(), member2.getId()); final GoalRoomRoadmapNodes goalRoomRoadmapNodes = new GoalRoomRoadmapNodes(List.of( - new GoalRoomRoadmapNode(new Period(TODAY, TEN_DAY_LATER), 5, roadmapNode))); + new GoalRoomRoadmapNode(new Period(TODAY, TEN_DAY_LATER), 5, roadmapNode.getId()))); goalRoom1.addAllGoalRoomRoadmapNodes(goalRoomRoadmapNodes); goalRoom1.complete(); @@ -167,7 +167,7 @@ class RoadmapSchedulerTest { // when // then assertDoesNotThrow(() -> roadmapScheduler.deleteRoadmaps()); - verify(goalRoomRepository, never()).findByRoadmap(any()); + verify(goalRoomRepository, never()).findByRoadmapContentId(any()); verify(roadmapRepository, never()).deleteAll(any()); } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/service/UUIDFilePathGeneratorTest.java b/backend/kirikiri/src/test/java/co/kirikiri/service/UUIDFilePathGeneratorTest.java index 7e9dc620d..44e2319f6 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/service/UUIDFilePathGeneratorTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/service/UUIDFilePathGeneratorTest.java @@ -3,7 +3,9 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertTrue; -import co.kirikiri.service.exception.BadRequestException; +import co.kirikiri.common.exception.BadRequestException; +import co.kirikiri.common.service.FilePathGenerator; +import co.kirikiri.common.type.ImageDirType; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; diff --git a/backend/kirikiri/src/test/java/co/kirikiri/todo/controller/GoalRoomToDoApiTest.java b/backend/kirikiri/src/test/java/co/kirikiri/todo/controller/GoalRoomToDoApiTest.java new file mode 100644 index 000000000..d0e9e34aa --- /dev/null +++ b/backend/kirikiri/src/test/java/co/kirikiri/todo/controller/GoalRoomToDoApiTest.java @@ -0,0 +1,494 @@ +package co.kirikiri.todo.controller; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.when; +import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; +import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import co.kirikiri.common.exception.BadRequestException; +import co.kirikiri.common.exception.ForbiddenException; +import co.kirikiri.common.exception.NotFoundException; +import co.kirikiri.common.helper.ControllerTestHelper; +import co.kirikiri.common.helper.FieldDescriptionHelper.FieldDescription; +import co.kirikiri.common.service.dto.ErrorResponse; +import co.kirikiri.todo.service.GoalRoomToDoService; +import co.kirikiri.todo.service.dto.request.GoalRoomTodoRequest; +import co.kirikiri.todo.service.dto.response.GoalRoomToDoCheckResponse; +import co.kirikiri.todo.service.dto.response.GoalRoomTodoResponse; +import com.fasterxml.jackson.core.type.TypeReference; +import java.time.LocalDate; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MvcResult; + +@WebMvcTest(GoalRoomToDoController.class) +class GoalRoomToDoApiTest extends ControllerTestHelper { + + private static final LocalDate TODAY = LocalDate.now(); + private static final LocalDate TEN_DAY_LATER = TODAY.plusDays(10); + + @MockBean + private GoalRoomToDoService goalRoomToDoService; + + @Test + void 정상적으로_골룸에_투두리스트를_추가한다() throws Exception { + //given + final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest("content", TODAY, TEN_DAY_LATER); + final String jsonRequest = objectMapper.writeValueAsString(goalRoomTodoRequest); + given(goalRoomToDoService.addGoalRoomTodo(anyLong(), anyString(), any())) + .willReturn(1L); + + //when + final MvcResult mvcResult = mockMvc.perform(post(API_PREFIX + "/goal-rooms/{goalRoomId}/todos", 1L) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") + .contentType(MediaType.APPLICATION_JSON) + .contextPath(API_PREFIX)) + .andExpect(status().isCreated()) + .andDo(print()) + .andDo(documentationResultHandler.document( + requestFields(makeFieldDescriptor(makeAddTodoSuccessRequestFieldDescription())), + requestHeaders(headerWithName(HttpHeaders.AUTHORIZATION).description("액세스 토큰")), + responseHeaders(headerWithName(HttpHeaders.LOCATION).description("골룸 투두 단일 조회 api 경로")), + pathParameters(parameterWithName("goalRoomId").description("골룸 아이디")))) + .andReturn(); + + //then + assertThat(mvcResult.getResponse().getHeader(HttpHeaders.LOCATION)).isEqualTo( + API_PREFIX + "/goal-rooms/1/todos/1"); + } + + @Test + void 골룸_투두_추가시_존재하지_않는_회원일_경우() throws Exception { + //given + final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest("content", TODAY, TEN_DAY_LATER); + final String jsonRequest = objectMapper.writeValueAsString(goalRoomTodoRequest); + doThrow(new NotFoundException("존재하지 않는 회원입니다.")) + .when(goalRoomToDoService) + .addGoalRoomTodo(anyLong(), anyString(), any()); + + //when + final MvcResult mvcResult = mockMvc.perform(post(API_PREFIX + "/goal-rooms/{goalRoomId}/todos", 1) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") + .contentType(MediaType.APPLICATION_JSON) + .contextPath(API_PREFIX)) + .andExpect(status().isNotFound()) + .andDo(print()) + .andDo(documentationResultHandler.document( + requestFields(makeFieldDescriptor(makeAddTodoSuccessRequestFieldDescription())), + requestHeaders(headerWithName(AUTHORIZATION).description("액세스 토큰")), + pathParameters(parameterWithName("goalRoomId").description("골룸 아이디")), + responseFields(fieldWithPath("message").description("예외 메세지")))) + .andReturn(); + + //then + final ErrorResponse response = jsonToClass(mvcResult, new TypeReference<>() { + }); + assertThat(response).isEqualTo(new ErrorResponse("존재하지 않는 회원입니다.")); + } + + @Test + void 골룸_투두_추가시_존재하지_않는_골룸일_경우() throws Exception { + //given + final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest("content", TODAY, TEN_DAY_LATER); + final String jsonRequest = objectMapper.writeValueAsString(goalRoomTodoRequest); + doThrow(new NotFoundException("존재하지 않는 골룸입니다. goalRoomId = 1")) + .when(goalRoomToDoService) + .addGoalRoomTodo(anyLong(), anyString(), any()); + + //when + final MvcResult mvcResult = mockMvc.perform(post(API_PREFIX + "/goal-rooms/{goalRoomId}/todos", 1) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") + .contentType(MediaType.APPLICATION_JSON) + .contextPath(API_PREFIX)) + .andExpect(status().isNotFound()) + .andDo(print()) + .andDo(documentationResultHandler.document( + requestFields(makeFieldDescriptor(makeAddTodoSuccessRequestFieldDescription())), + requestHeaders(headerWithName(AUTHORIZATION).description("액세스 토큰")), + pathParameters(parameterWithName("goalRoomId").description("골룸 아이디")), + responseFields(fieldWithPath("message").description("예외 메세지")))) + .andReturn(); + + //then + final ErrorResponse response = jsonToClass(mvcResult, new TypeReference<>() { + }); + assertThat(response).isEqualTo(new ErrorResponse("존재하지 않는 골룸입니다. goalRoomId = 1")); + } + + @Test + void 골룸_투두_추가시_이미_종료된_골룸일_경우() throws Exception { + //given + final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest("content", TODAY, TEN_DAY_LATER); + final String jsonRequest = objectMapper.writeValueAsString(goalRoomTodoRequest); + doThrow(new BadRequestException("이미 종료된 골룸입니다.")) + .when(goalRoomToDoService) + .addGoalRoomTodo(anyLong(), anyString(), any()); + + //when + final MvcResult mvcResult = mockMvc.perform(post(API_PREFIX + "/goal-rooms/{goalRoomId}/todos", 1L) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") + .contentType(MediaType.APPLICATION_JSON) + .contextPath(API_PREFIX)) + .andExpect(status().isBadRequest()) + .andDo(print()) + .andDo(documentationResultHandler.document( + requestFields(makeFieldDescriptor(makeAddTodoSuccessRequestFieldDescription())), + requestHeaders(headerWithName(AUTHORIZATION).description("액세스 토큰")), + pathParameters(parameterWithName("goalRoomId").description("골룸 아이디")), + responseFields(fieldWithPath("message").description("예외 메세지")))) + .andReturn(); + + //then + final ErrorResponse response = jsonToClass(mvcResult, new TypeReference<>() { + }); + assertThat(response).isEqualTo(new ErrorResponse("이미 종료된 골룸입니다.")); + } + + @Test + void 골룸_투두_추가시_리더가_아닌_경우() throws Exception { + //given + final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest("content", TODAY, TEN_DAY_LATER); + final String jsonRequest = objectMapper.writeValueAsString(goalRoomTodoRequest); + doThrow(new BadRequestException("골룸의 리더만 투두리스트를 추가할 수 있습니다.")) + .when(goalRoomToDoService) + .addGoalRoomTodo(anyLong(), anyString(), any()); + + //when + final MvcResult mvcResult = mockMvc.perform(post(API_PREFIX + "/goal-rooms/{goalRoomId}/todos", 1L) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") + .contentType(MediaType.APPLICATION_JSON) + .contextPath(API_PREFIX)) + .andExpect(status().isBadRequest()) + .andDo(print()) + .andDo(documentationResultHandler.document( + requestFields(makeFieldDescriptor(makeAddTodoSuccessRequestFieldDescription())), + requestHeaders(headerWithName(AUTHORIZATION).description("액세스 토큰")), + pathParameters(parameterWithName("goalRoomId").description("골룸 아이디")), + responseFields(fieldWithPath("message").description("예외 메세지")))) + .andReturn(); + + //then + final ErrorResponse response = jsonToClass(mvcResult, new TypeReference<>() { + }); + assertThat(response).isEqualTo(new ErrorResponse("골룸의 리더만 투두리스트를 추가할 수 있습니다.")); + } + + @Test + void 골룸_투두_추가시_컨텐츠가_250글자가_넘을_경우() throws Exception { + //given + final String content = "a".repeat(251); + final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest(content, TODAY, TEN_DAY_LATER); + final String jsonRequest = objectMapper.writeValueAsString(goalRoomTodoRequest); + doThrow(new BadRequestException("투두 컨텐츠의 길이가 적절하지 않습니다.")) + .when(goalRoomToDoService) + .addGoalRoomTodo(anyLong(), anyString(), any()); + + //when + final MvcResult mvcResult = mockMvc.perform(post(API_PREFIX + "/goal-rooms/{goalRoomId}/todos", 1L) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") + .contentType(MediaType.APPLICATION_JSON) + .contextPath(API_PREFIX)) + .andExpect(status().isBadRequest()) + .andDo(print()) + .andDo(documentationResultHandler.document( + requestFields(makeFieldDescriptor(makeAddTodoSuccessRequestFieldDescription())), + requestHeaders(headerWithName(AUTHORIZATION).description("액세스 토큰")), + pathParameters(parameterWithName("goalRoomId").description("골룸 아이디")), + responseFields(fieldWithPath("message").description("예외 메세지")))) + .andReturn(); + + //then + final ErrorResponse response = jsonToClass(mvcResult, new TypeReference<>() { + }); + assertThat(response).isEqualTo(new ErrorResponse("투두 컨텐츠의 길이가 적절하지 않습니다.")); + } + + @Test + void 골룸_투두리스트에_대해_체크한다() throws Exception { + // given + final GoalRoomToDoCheckResponse expected = new GoalRoomToDoCheckResponse(true); + when(goalRoomToDoService.checkGoalRoomTodo(anyLong(), anyLong(), anyString())) + .thenReturn(expected); + + // when + final MvcResult mvcResult = mockMvc.perform(post(API_PREFIX + "/goal-rooms/{goalRoomId}/todos/{todoId}", 1L, 1L) + .header(AUTHORIZATION, String.format(BEARER_TOKEN_FORMAT, "test-token")) + .contextPath(API_PREFIX)) + .andExpect(status().isOk()) + .andDo( + documentationResultHandler.document( + requestHeaders( + headerWithName(AUTHORIZATION).description("액세스 토큰")), + pathParameters( + parameterWithName("goalRoomId").description("골룸 아이디"), + parameterWithName("todoId").description("골룸 투두 아이디")), + responseFields( + fieldWithPath("isChecked").description( + "투두 체크 현황 (true: 체크됨, false: 체크되지 않음)")))) + .andReturn(); + + // then + final GoalRoomToDoCheckResponse response = jsonToClass(mvcResult, new TypeReference<>() { + }); + + assertThat(response) + .isEqualTo(expected); + } + + @Test + void 골룸_투두리스트_체크시_체크_이력이_있으면_제거한다() throws Exception { + // given + final GoalRoomToDoCheckResponse expected = new GoalRoomToDoCheckResponse(false); + when(goalRoomToDoService.checkGoalRoomTodo(anyLong(), anyLong(), anyString())) + .thenReturn(expected); + + // when + final MvcResult mvcResult = mockMvc.perform(post(API_PREFIX + "/goal-rooms/{goalRoomId}/todos/{todoId}", 1L, 1L) + .header(AUTHORIZATION, String.format(BEARER_TOKEN_FORMAT, "test-token")) + .contextPath(API_PREFIX)) + .andExpect(status().isOk()) + .andDo( + documentationResultHandler.document( + requestHeaders( + headerWithName(AUTHORIZATION).description("액세스 토큰")), + pathParameters( + parameterWithName("goalRoomId").description("골룸 아이디"), + parameterWithName("todoId").description("골룸 투두 아이디")), + responseFields( + fieldWithPath("isChecked").description( + "투두 체크 현황 (true: 체크됨, false: 체크되지 않음)")))) + .andReturn(); + + // then + final GoalRoomToDoCheckResponse response = jsonToClass(mvcResult, new TypeReference<>() { + }); + + assertThat(response) + .isEqualTo(expected); + } + + @Test + void 골룸_투두리스트_체크시_골룸이_존재하지_않으면_예외가_발생한다() throws Exception { + //given + doThrow(new NotFoundException("골룸이 존재하지 않습니다. goalRoomId = 1")) + .when(goalRoomToDoService) + .checkGoalRoomTodo(anyLong(), anyLong(), anyString()); + + //when + final MvcResult mvcResult = mockMvc.perform(post(API_PREFIX + "/goal-rooms/{goalRoomId}/todos/{todoId}", 1L, 1L) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") + .contentType(MediaType.APPLICATION_JSON) + .contextPath(API_PREFIX)) + .andExpect(status().isNotFound()) + .andDo(print()) + .andDo(documentationResultHandler.document( + requestHeaders(headerWithName(AUTHORIZATION).description("액세스 토큰")), + pathParameters( + parameterWithName("goalRoomId").description("골룸 아이디"), + parameterWithName("todoId").description("골룸 투두 아이디")), + responseFields(fieldWithPath("message").description("예외 메세지")))) + .andReturn(); + + //then + final ErrorResponse response = jsonToClass(mvcResult, new TypeReference<>() { + }); + assertThat(response).isEqualTo(new ErrorResponse("골룸이 존재하지 않습니다. goalRoomId = 1")); + } + + @Test + void 골룸_투두리스트_체크시_해당_투두가_존재하지_않으면_예외가_발생한다() throws Exception { + //given + doThrow(new NotFoundException("존재하지 않는 투두입니다. todoId = 1")) + .when(goalRoomToDoService) + .checkGoalRoomTodo(anyLong(), anyLong(), anyString()); + + //when + final MvcResult mvcResult = mockMvc.perform(post(API_PREFIX + "/goal-rooms/{goalRoomId}/todos/{todoId}", 1L, 1L) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") + .contentType(MediaType.APPLICATION_JSON) + .contextPath(API_PREFIX)) + .andExpect(status().isNotFound()) + .andDo(print()) + .andDo(documentationResultHandler.document( + requestHeaders( + headerWithName(AUTHORIZATION).description("액세스 토큰")), + pathParameters( + parameterWithName("goalRoomId").description("골룸 아이디"), + parameterWithName("todoId").description("골룸 투두 아이디")), + responseFields( + fieldWithPath("message").description("예외 메세지")))) + .andReturn(); + + //then + final ErrorResponse response = jsonToClass(mvcResult, new TypeReference<>() { + }); + assertThat(response) + .isEqualTo(new ErrorResponse("존재하지 않는 투두입니다. todoId = 1")); + } + + @Test + void 골룸_투두리스트_체크시_사용자가_없으면_예외가_발생한다() throws Exception { + //given + doThrow(new NotFoundException("골룸에 사용자가 존재하지 않습니다. goalRoomId = 1 memberIdentifier = cokirikiri")) + .when(goalRoomToDoService) + .checkGoalRoomTodo(anyLong(), anyLong(), anyString()); + + //when + final MvcResult mvcResult = mockMvc.perform(post(API_PREFIX + "/goal-rooms/{goalRoomId}/todos/{todoId}", 1L, 1L) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") + .contentType(MediaType.APPLICATION_JSON) + .contextPath(API_PREFIX)) + .andExpect(status().isNotFound()) + .andDo(print()) + .andDo(documentationResultHandler.document( + requestHeaders( + headerWithName(AUTHORIZATION).description("액세스 토큰")), + pathParameters( + parameterWithName("goalRoomId").description("골룸 아이디"), + parameterWithName("todoId").description("골룸 투두 아이디")), + responseFields( + fieldWithPath("message").description("예외 메세지")))) + .andReturn(); + + //then + final ErrorResponse response = jsonToClass(mvcResult, new TypeReference<>() { + }); + assertThat(response) + .isEqualTo(new ErrorResponse("골룸에 사용자가 존재하지 않습니다. goalRoomId = 1 memberIdentifier = cokirikiri")); + } + + @Test + void 골룸의_투두리스트를_조회한다() throws Exception { + // given + final LocalDate today = LocalDate.now(); + final List goalRoomTodoResponses = List.of( + new GoalRoomTodoResponse(1L, "투두 1", today, today.plusDays(10), new GoalRoomToDoCheckResponse(true)), + new GoalRoomTodoResponse(2L, "투두 2", today.plusDays(20), today.plusDays(30), + new GoalRoomToDoCheckResponse(false))); + + when(goalRoomToDoService.findAllGoalRoomTodo(any(), any())) + .thenReturn(goalRoomTodoResponses); + + // when + final MvcResult mvcResult = mockMvc.perform(get(API_PREFIX + "/goal-rooms/{goalRoomId}/todos", 1L) + .header(AUTHORIZATION, String.format(BEARER_TOKEN_FORMAT, "test-token")) + .contextPath(API_PREFIX)) + .andExpect(status().isOk()) + .andDo( + documentationResultHandler.document( + requestHeaders( + headerWithName(AUTHORIZATION).description("액세스 토큰") + ), + pathParameters( + parameterWithName("goalRoomId").description("골룸 아이디") + ), + responseFields( + fieldWithPath("[0].id").description("투두 아이디"), + fieldWithPath("[0].content").description("투두 내용"), + fieldWithPath("[0].startDate").description("투두 시작 날짜"), + fieldWithPath("[0].endDate").description("투두 종료 날짜"), + fieldWithPath("[0].check.isChecked").description("투두 체크 여부") + ))) + .andReturn(); + + // then + final List response = jsonToClass(mvcResult, new TypeReference<>() { + }); + + assertThat(response) + .isEqualTo(goalRoomTodoResponses); + } + + @Test + void 골룸_투두리스트_조회시_존재하지_않은_골룸일_경우() throws Exception { + // given + doThrow(new NotFoundException("존재하지 않는 골룸입니다. goalRoomId = 1")) + .when(goalRoomToDoService) + .findAllGoalRoomTodo(any(), any()); + + // when + final MvcResult mvcResult = mockMvc.perform(get(API_PREFIX + "/goal-rooms/{goalRoomId}/todos", 1L) + .header(AUTHORIZATION, String.format(BEARER_TOKEN_FORMAT, "test-token")) + .contextPath(API_PREFIX)) + .andExpect(status().isNotFound()) + .andDo( + documentationResultHandler.document( + pathParameters( + parameterWithName("goalRoomId").description("골룸 아이디") + ), + responseFields( + fieldWithPath("message").description("예외 메세지") + ))) + .andReturn(); + + // then + final ErrorResponse responses = jsonToClass(mvcResult, new TypeReference<>() { + }); + + assertThat(responses) + .isEqualTo(new ErrorResponse("존재하지 않는 골룸입니다. goalRoomId = 1")); + } + + @Test + void 골룸_투두리스트_조회시_참여하지_않은_사용자일_경우() throws Exception { + // given + doThrow(new ForbiddenException("골룸에 참여하지 않은 사용자입니다. goalRoomId = 1 memberIdentifier = identifier")) + .when(goalRoomToDoService) + .findAllGoalRoomTodo(any(), any()); + + // when + final MvcResult mvcResult = mockMvc.perform(get(API_PREFIX + "/goal-rooms/{goalRoomId}/todos", 1L) + .header(AUTHORIZATION, String.format(BEARER_TOKEN_FORMAT, "test-token")) + .contextPath(API_PREFIX)) + .andExpect(status().isForbidden()) + .andDo( + documentationResultHandler.document( + pathParameters( + parameterWithName("goalRoomId").description("골룸 아이디") + ), + responseFields( + fieldWithPath("message").description("예외 메세지") + ))) + .andReturn(); + + // then + final ErrorResponse responses = jsonToClass(mvcResult, new TypeReference<>() { + }); + + assertThat(responses) + .isEqualTo(new ErrorResponse("골룸에 참여하지 않은 사용자입니다. goalRoomId = 1 memberIdentifier = identifier")); + } + + private List makeAddTodoSuccessRequestFieldDescription() { + return List.of( + new FieldDescription("content", "골룸 투두 컨텐츠", "- 길이 : 1 ~ 250"), + new FieldDescription("startDate", "골룸 투두 시작일", "- yyyyMMdd 형식"), + new FieldDescription("endDate", "골룸 투두 종료일", "- yyyyMMdd 형식") + ); + } +} diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomToDoTest.java b/backend/kirikiri/src/test/java/co/kirikiri/todo/domain/GoalRoomToDoTest.java similarity index 64% rename from backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomToDoTest.java rename to backend/kirikiri/src/test/java/co/kirikiri/todo/domain/GoalRoomToDoTest.java index 16b3a5dce..f23f6991a 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomToDoTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/todo/domain/GoalRoomToDoTest.java @@ -1,11 +1,11 @@ -package co.kirikiri.domain.goalroom; +package co.kirikiri.todo.domain; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import co.kirikiri.domain.goalroom.exception.GoalRoomException; -import co.kirikiri.domain.goalroom.vo.GoalRoomTodoContent; -import co.kirikiri.domain.goalroom.vo.Period; +import co.kirikiri.todo.domain.exception.GoalRoomToDoException; +import co.kirikiri.todo.domain.vo.GoalRoomTodoContent; +import co.kirikiri.todo.domain.vo.ToDoPeriod; import java.time.LocalDate; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -21,7 +21,8 @@ class GoalRoomToDoTest { //when //then - assertDoesNotThrow(() -> new GoalRoomToDo(new GoalRoomTodoContent("content"), new Period(startDate, endDate))); + assertDoesNotThrow( + () -> new GoalRoomToDo(null, new GoalRoomTodoContent("content"), new ToDoPeriod(startDate, endDate))); } @ParameterizedTest @@ -33,8 +34,9 @@ class GoalRoomToDoTest { //when //then - assertThatThrownBy(() -> new GoalRoomToDo(new GoalRoomTodoContent("content"), new Period(startDate, endDate))) - .isInstanceOf(GoalRoomException.class); + assertThatThrownBy( + () -> new GoalRoomToDo(null, new GoalRoomTodoContent("content"), new ToDoPeriod(startDate, endDate))) + .isInstanceOf(GoalRoomToDoException.class); } @ParameterizedTest @@ -46,7 +48,8 @@ class GoalRoomToDoTest { //when //then - assertThatThrownBy(() -> new GoalRoomToDo(new GoalRoomTodoContent("content"), new Period(startDate, endDate))) - .isInstanceOf(GoalRoomException.class); + assertThatThrownBy( + () -> new GoalRoomToDo(null, new GoalRoomTodoContent("content"), new ToDoPeriod(startDate, endDate))) + .isInstanceOf(GoalRoomToDoException.class); } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomToDosTest.java b/backend/kirikiri/src/test/java/co/kirikiri/todo/domain/GoalRoomToDosTest.java similarity index 51% rename from backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomToDosTest.java rename to backend/kirikiri/src/test/java/co/kirikiri/todo/domain/GoalRoomToDosTest.java index 3de322e61..5bdaebb80 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/GoalRoomToDosTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/todo/domain/GoalRoomToDosTest.java @@ -1,22 +1,22 @@ -package co.kirikiri.domain.goalroom; +package co.kirikiri.todo.domain; import static org.assertj.core.api.Assertions.assertThat; -import co.kirikiri.domain.goalroom.vo.GoalRoomTodoContent; -import co.kirikiri.domain.goalroom.vo.Period; -import org.junit.jupiter.api.Test; +import co.kirikiri.todo.domain.vo.GoalRoomTodoContent; +import co.kirikiri.todo.domain.vo.ToDoPeriod; import java.time.LocalDate; import java.util.List; +import org.junit.jupiter.api.Test; class GoalRoomToDosTest { @Test void 아이디로_투두를_조회한다() { // given - final GoalRoomToDo firstTodo = new GoalRoomToDo(1L, new GoalRoomTodoContent("투두1"), - new Period(LocalDate.now(), LocalDate.now().plusDays(3))); - final GoalRoomToDo secondTodo = new GoalRoomToDo(2L, new GoalRoomTodoContent("투두2"), - new Period(LocalDate.now(), LocalDate.now().plusDays(5))); + final GoalRoomToDo firstTodo = new GoalRoomToDo(1L, null, new GoalRoomTodoContent("투두1"), + new ToDoPeriod(LocalDate.now(), LocalDate.now().plusDays(3))); + final GoalRoomToDo secondTodo = new GoalRoomToDo(2L, null, new GoalRoomTodoContent("투두2"), + new ToDoPeriod(LocalDate.now(), LocalDate.now().plusDays(5))); final GoalRoomToDos goalRoomToDos = new GoalRoomToDos(List.of( firstTodo, secondTodo @@ -33,10 +33,10 @@ class GoalRoomToDosTest { @Test void 아이디로_투두_조회시_없으면_빈값을_반환한다() { // given - final GoalRoomToDo firstTodo = new GoalRoomToDo(1L, new GoalRoomTodoContent("투두1"), - new Period(LocalDate.now(), LocalDate.now().plusDays(3))); - final GoalRoomToDo secondTodo = new GoalRoomToDo(2L, new GoalRoomTodoContent("투두2"), - new Period(LocalDate.now(), LocalDate.now().plusDays(5))); + final GoalRoomToDo firstTodo = new GoalRoomToDo(1L, null, new GoalRoomTodoContent("투두1"), + new ToDoPeriod(LocalDate.now(), LocalDate.now().plusDays(3))); + final GoalRoomToDo secondTodo = new GoalRoomToDo(2L, null, new GoalRoomTodoContent("투두2"), + new ToDoPeriod(LocalDate.now(), LocalDate.now().plusDays(5))); final GoalRoomToDos goalRoomToDos = new GoalRoomToDos(List.of( firstTodo, secondTodo diff --git a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/vo/GoalRoomTodoContentTest.java b/backend/kirikiri/src/test/java/co/kirikiri/todo/domain/vo/GoalRoomTodoContentTest.java similarity index 85% rename from backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/vo/GoalRoomTodoContentTest.java rename to backend/kirikiri/src/test/java/co/kirikiri/todo/domain/vo/GoalRoomTodoContentTest.java index ef200e17c..5e104da82 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/domain/goalroom/vo/GoalRoomTodoContentTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/todo/domain/vo/GoalRoomTodoContentTest.java @@ -1,9 +1,9 @@ -package co.kirikiri.domain.goalroom.vo; +package co.kirikiri.todo.domain.vo; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import co.kirikiri.domain.goalroom.exception.GoalRoomException; +import co.kirikiri.todo.domain.exception.GoalRoomToDoException; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -29,6 +29,6 @@ class GoalRoomTodoContentTest { //when //then assertThatThrownBy(() -> new GoalRoomTodoContent(value)) - .isInstanceOf(GoalRoomException.class); + .isInstanceOf(GoalRoomToDoException.class); } } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/GoalRoomToDoCheckRepositoryTest.java b/backend/kirikiri/src/test/java/co/kirikiri/todo/persistence/GoalRoomToDoCheckRepositoryTest.java similarity index 58% rename from backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/GoalRoomToDoCheckRepositoryTest.java rename to backend/kirikiri/src/test/java/co/kirikiri/todo/persistence/GoalRoomToDoCheckRepositoryTest.java index 2d7ebd328..a83df761c 100644 --- a/backend/kirikiri/src/test/java/co/kirikiri/persistence/goalroom/GoalRoomToDoCheckRepositoryTest.java +++ b/backend/kirikiri/src/test/java/co/kirikiri/todo/persistence/GoalRoomToDoCheckRepositoryTest.java @@ -1,18 +1,8 @@ -package co.kirikiri.persistence.goalroom; +package co.kirikiri.todo.persistence; import static org.assertj.core.api.Assertions.assertThat; -import co.kirikiri.domain.goalroom.GoalRoom; -import co.kirikiri.domain.goalroom.GoalRoomMember; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNode; -import co.kirikiri.domain.goalroom.GoalRoomRoadmapNodes; -import co.kirikiri.domain.goalroom.GoalRoomRole; -import co.kirikiri.domain.goalroom.GoalRoomToDo; -import co.kirikiri.domain.goalroom.GoalRoomToDoCheck; -import co.kirikiri.domain.goalroom.vo.GoalRoomName; -import co.kirikiri.domain.goalroom.vo.GoalRoomTodoContent; -import co.kirikiri.domain.goalroom.vo.LimitedMemberCount; -import co.kirikiri.domain.goalroom.vo.Period; +import co.kirikiri.common.helper.RepositoryTest; import co.kirikiri.domain.member.EncryptedPassword; import co.kirikiri.domain.member.Gender; import co.kirikiri.domain.member.Member; @@ -26,10 +16,23 @@ import co.kirikiri.domain.roadmap.RoadmapDifficulty; import co.kirikiri.domain.roadmap.RoadmapNode; import co.kirikiri.domain.roadmap.RoadmapNodes; -import co.kirikiri.persistence.helper.RepositoryTest; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomMember; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNode; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNodes; +import co.kirikiri.goalroom.domain.GoalRoomRole; +import co.kirikiri.goalroom.domain.vo.GoalRoomName; +import co.kirikiri.goalroom.domain.vo.LimitedMemberCount; +import co.kirikiri.goalroom.domain.vo.Period; +import co.kirikiri.goalroom.persistence.GoalRoomMemberRepository; +import co.kirikiri.goalroom.persistence.GoalRoomRepository; import co.kirikiri.persistence.member.MemberRepository; import co.kirikiri.persistence.roadmap.RoadmapCategoryRepository; import co.kirikiri.persistence.roadmap.RoadmapRepository; +import co.kirikiri.todo.domain.GoalRoomToDo; +import co.kirikiri.todo.domain.GoalRoomToDoCheck; +import co.kirikiri.todo.domain.vo.GoalRoomTodoContent; +import co.kirikiri.todo.domain.vo.ToDoPeriod; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; @@ -45,6 +48,7 @@ class GoalRoomToDoCheckRepositoryTest { private final GoalRoomRepository goalRoomRepository; private final GoalRoomMemberRepository goalRoomMemberRepository; private final RoadmapCategoryRepository roadmapCategoryRepository; + private final GoalRoomToDoRepository goalRoomToDoRepository; private final GoalRoomToDoCheckRepository goalRoomToDoCheckRepository; public GoalRoomToDoCheckRepositoryTest(final MemberRepository memberRepository, @@ -52,12 +56,14 @@ public GoalRoomToDoCheckRepositoryTest(final MemberRepository memberRepository, final GoalRoomRepository goalRoomRepository, final GoalRoomMemberRepository goalRoomMemberRepository, final RoadmapCategoryRepository roadmapCategoryRepository, + final GoalRoomToDoRepository goalRoomToDoRepository, final GoalRoomToDoCheckRepository goalRoomToDoCheckRepository) { this.memberRepository = memberRepository; this.roadmapRepository = roadmapRepository; this.goalRoomRepository = goalRoomRepository; this.goalRoomMemberRepository = goalRoomMemberRepository; this.roadmapCategoryRepository = roadmapCategoryRepository; + this.goalRoomToDoRepository = goalRoomToDoRepository; this.goalRoomToDoCheckRepository = goalRoomToDoCheckRepository; } @@ -78,28 +84,30 @@ public GoalRoomToDoCheckRepositoryTest(final MemberRepository memberRepository, final Member goalRoomPendingMember = 사용자를_생성한다("name2", "01011112222", "identifier2", "password!2"); final GoalRoom goalRoom = 골룸을_생성한다("goalroom1", 6, roadmapContent, new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode1, goalRoomRoadmapNode2)), goalRoomPendingMember); + final GoalRoom savedGoalRoom = goalRoomRepository.save(goalRoom); final LocalDate today = LocalDate.now(); final LocalDate threeDaysAfter = today.plusDays(3); - final GoalRoomToDo firstGoalRoomTodo = new GoalRoomToDo( - new GoalRoomTodoContent("투두1"), new Period(today, threeDaysAfter)); - final GoalRoomToDo secondGoalRoomTodo = new GoalRoomToDo( - new GoalRoomTodoContent("투두2"), new Period(today, threeDaysAfter)); - goalRoom.addGoalRoomTodo(firstGoalRoomTodo); - goalRoom.addGoalRoomTodo(secondGoalRoomTodo); - goalRoomRepository.save(goalRoom); + final GoalRoomToDo firstGoalRoomTodo = new GoalRoomToDo(null, savedGoalRoom.getId(), + new GoalRoomTodoContent("투두1"), new ToDoPeriod(today, threeDaysAfter)); + final GoalRoomToDo secondGoalRoomTodo = new GoalRoomToDo(null, savedGoalRoom.getId(), + new GoalRoomTodoContent("투두2"), new ToDoPeriod(today, threeDaysAfter)); + final GoalRoomToDo savedFirstGoalRoomToDo = goalRoomToDoRepository.save(firstGoalRoomTodo); + final GoalRoomToDo savedSecondGoalRoomToDo = goalRoomToDoRepository.save(secondGoalRoomTodo); final GoalRoomMember goalRoomMember = new GoalRoomMember( - GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator); - goalRoomMemberRepository.save(goalRoomMember); + GoalRoomRole.LEADER, LocalDateTime.now(), savedGoalRoom, creator.getId()); + final GoalRoomMember savedGoalRoomMember = goalRoomMemberRepository.save(goalRoomMember); - final GoalRoomToDoCheck firstGoalRoomToDoCheck = new GoalRoomToDoCheck(goalRoomMember, firstGoalRoomTodo); - final GoalRoomToDoCheck secondGoalRoomToDoCheck = new GoalRoomToDoCheck(goalRoomMember, secondGoalRoomTodo); + final GoalRoomToDoCheck firstGoalRoomToDoCheck = new GoalRoomToDoCheck(savedGoalRoomMember.getId(), + savedFirstGoalRoomToDo); + final GoalRoomToDoCheck secondGoalRoomToDoCheck = new GoalRoomToDoCheck(savedGoalRoomMember.getId(), + savedSecondGoalRoomToDo); goalRoomToDoCheckRepository.saveAll(List.of(firstGoalRoomToDoCheck, secondGoalRoomToDoCheck)); // when - final GoalRoomToDoCheck findGoalRoomTodoCheck = goalRoomToDoCheckRepository.findByGoalRoomIdAndTodoAndMemberIdentifier( - goalRoom.getId(), firstGoalRoomTodo, new Identifier("identifier1")).get(); + final GoalRoomToDoCheck findGoalRoomTodoCheck = goalRoomToDoCheckRepository.findByGoalRoomTodoAndGoalRoomMemberId( + savedFirstGoalRoomToDo, savedGoalRoomMember.getId()).get(); // then assertThat(findGoalRoomTodoCheck) @@ -124,28 +132,30 @@ public GoalRoomToDoCheckRepositoryTest(final MemberRepository memberRepository, final Member goalRoomPendingMember = 사용자를_생성한다("name2", "01011112222", "identifier2", "password!2"); final GoalRoom goalRoom = 골룸을_생성한다("goalroom1", 6, roadmapContent, new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode1, goalRoomRoadmapNode2)), goalRoomPendingMember); + final GoalRoom savedGoalRoom = goalRoomRepository.save(goalRoom); final LocalDate today = LocalDate.now(); final LocalDate threeDaysAfter = today.plusDays(3); - final GoalRoomToDo firstGoalRoomTodo = new GoalRoomToDo( - new GoalRoomTodoContent("투두1"), new Period(today, threeDaysAfter)); - final GoalRoomToDo secondGoalRoomTodo = new GoalRoomToDo( - new GoalRoomTodoContent("투두2"), new Period(today, threeDaysAfter)); - goalRoom.addGoalRoomTodo(firstGoalRoomTodo); - goalRoom.addGoalRoomTodo(secondGoalRoomTodo); - goalRoomRepository.save(goalRoom); + final GoalRoomToDo firstGoalRoomTodo = new GoalRoomToDo(null, savedGoalRoom.getId(), + new GoalRoomTodoContent("투두1"), new ToDoPeriod(today, threeDaysAfter)); + final GoalRoomToDo secondGoalRoomTodo = new GoalRoomToDo(null, savedGoalRoom.getId(), + new GoalRoomTodoContent("투두2"), new ToDoPeriod(today, threeDaysAfter)); + final GoalRoomToDo savedFirstGoalRoomToDo = goalRoomToDoRepository.save(firstGoalRoomTodo); + final GoalRoomToDo savedSecondGoalRoomToDo = goalRoomToDoRepository.save(secondGoalRoomTodo); final GoalRoomMember goalRoomMember = new GoalRoomMember( - GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator); - goalRoomMemberRepository.save(goalRoomMember); + GoalRoomRole.LEADER, LocalDateTime.now(), savedGoalRoom, creator.getId()); + final GoalRoomMember savedGoalRoomMember = goalRoomMemberRepository.save(goalRoomMember); - final GoalRoomToDoCheck firstGoalRoomToDoCheck = new GoalRoomToDoCheck(goalRoomMember, firstGoalRoomTodo); - final GoalRoomToDoCheck secondGoalRoomToDoCheck = new GoalRoomToDoCheck(goalRoomMember, secondGoalRoomTodo); + final GoalRoomToDoCheck firstGoalRoomToDoCheck = new GoalRoomToDoCheck(savedGoalRoomMember.getId(), + savedFirstGoalRoomToDo); + final GoalRoomToDoCheck secondGoalRoomToDoCheck = new GoalRoomToDoCheck(savedGoalRoomMember.getId(), + savedSecondGoalRoomToDo); goalRoomToDoCheckRepository.saveAll(List.of(firstGoalRoomToDoCheck, secondGoalRoomToDoCheck)); // when - final List findGoalRoomTodoCheck = goalRoomToDoCheckRepository.findByGoalRoomIdAndMemberIdentifier( - goalRoom.getId(), new Identifier("identifier1")); + final List findGoalRoomTodoCheck = goalRoomToDoCheckRepository.findByGoalRoomIdAndGoalRoomMemberId( + savedGoalRoom.getId(), savedGoalRoomMember.getId()); // then assertThat(findGoalRoomTodoCheck) @@ -153,6 +163,57 @@ public GoalRoomToDoCheckRepositoryTest(final MemberRepository memberRepository, .isEqualTo(List.of(firstGoalRoomToDoCheck, secondGoalRoomToDoCheck)); } + @Test + void 골룸_멤버와_투두_아이디로_골룸_투두_체크를_삭제한다() { + // given + final Member creator = 사용자를_생성한다("name1", "01011111111", "identifier1", "password!1"); + final RoadmapCategory category = 카테고리를_저장한다("여가"); + final RoadmapNode roadmapNode1 = 로드맵_노드를_생성한다("로드맵 1주차", "로드맵 1주차 내용"); + final RoadmapNode roadmapNode2 = 로드맵_노드를_생성한다("로드맵 2주차", "로드맵 2주차 내용"); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(List.of(roadmapNode1, roadmapNode2)); + 로드맵을_생성한다(creator, category, roadmapContent); + + final GoalRoomRoadmapNode goalRoomRoadmapNode1 = 골룸_로드맵_노드를_생성한다(TODAY, TODAY.plusDays(10), + roadmapNode1); + final GoalRoomRoadmapNode goalRoomRoadmapNode2 = 골룸_로드맵_노드를_생성한다(TODAY.plusDays(11), TODAY.plusDays(20), + roadmapNode2); + final Member goalRoomPendingMember = 사용자를_생성한다("name2", "01011112222", "identifier2", "password!2"); + final GoalRoom goalRoom = 골룸을_생성한다("goalroom1", 6, roadmapContent, + new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode1, goalRoomRoadmapNode2)), goalRoomPendingMember); + final GoalRoom savedGoalRoom = goalRoomRepository.save(goalRoom); + + final LocalDate today = LocalDate.now(); + final LocalDate threeDaysAfter = today.plusDays(3); + final GoalRoomToDo firstGoalRoomTodo = new GoalRoomToDo(null, savedGoalRoom.getId(), + new GoalRoomTodoContent("투두1"), new ToDoPeriod(today, threeDaysAfter)); + final GoalRoomToDo secondGoalRoomTodo = new GoalRoomToDo(null, savedGoalRoom.getId(), + new GoalRoomTodoContent("투두2"), new ToDoPeriod(today, threeDaysAfter)); + final GoalRoomToDo savedFirstGoalRoomToDo = goalRoomToDoRepository.save(firstGoalRoomTodo); + final GoalRoomToDo savedSecondGoalRoomToDo = goalRoomToDoRepository.save(secondGoalRoomTodo); + + final GoalRoomMember goalRoomMember = new GoalRoomMember( + GoalRoomRole.LEADER, LocalDateTime.now(), savedGoalRoom, creator.getId()); + final GoalRoomMember savedGoalRoomMember = goalRoomMemberRepository.save(goalRoomMember); + + final GoalRoomToDoCheck firstGoalRoomToDoCheck = new GoalRoomToDoCheck(savedGoalRoomMember.getId(), + savedFirstGoalRoomToDo); + final GoalRoomToDoCheck secondGoalRoomToDoCheck = new GoalRoomToDoCheck(savedGoalRoomMember.getId(), + savedSecondGoalRoomToDo); + goalRoomToDoCheckRepository.saveAll(List.of(firstGoalRoomToDoCheck, secondGoalRoomToDoCheck)); + + // when + goalRoomToDoCheckRepository.deleteByGoalRoomMemberIdAndToDoId(savedGoalRoomMember.getId(), + savedFirstGoalRoomToDo.getId()); + + // then + final List findGoalRoomToDoChecks = goalRoomToDoCheckRepository.findByGoalRoomIdAndGoalRoomMemberId( + savedGoalRoom.getId(), savedGoalRoomMember.getId()); + assertThat(findGoalRoomToDoChecks) + .usingRecursiveComparison() + .ignoringFields("id") + .isEqualTo(List.of(secondGoalRoomToDoCheck)); + } + private RoadmapCategory 카테고리를_저장한다(final String name) { final RoadmapCategory roadmapCategory = new RoadmapCategory(name); return roadmapCategoryRepository.save(roadmapCategory); @@ -186,13 +247,13 @@ public GoalRoomToDoCheckRepositoryTest(final MemberRepository memberRepository, private GoalRoomRoadmapNode 골룸_로드맵_노드를_생성한다(final LocalDate startDate, final LocalDate endDate, final RoadmapNode roadmapNode) { - return new GoalRoomRoadmapNode(new Period(startDate, endDate), 1, roadmapNode); + return new GoalRoomRoadmapNode(new Period(startDate, endDate), 1, roadmapNode.getId()); } private GoalRoom 골룸을_생성한다(final String name, final Integer limitedMemberCount, final RoadmapContent roadmapContent, final GoalRoomRoadmapNodes goalRoomRoadmapNodes, final Member member) { final GoalRoom goalRoom = new GoalRoom(new GoalRoomName(name), new LimitedMemberCount(limitedMemberCount), - roadmapContent, member); + roadmapContent.getId(), member.getId()); goalRoom.addAllGoalRoomRoadmapNodes(goalRoomRoadmapNodes); return goalRoom; } diff --git a/backend/kirikiri/src/test/java/co/kirikiri/todo/persistence/GoalRoomToDoRepositoryTest.java b/backend/kirikiri/src/test/java/co/kirikiri/todo/persistence/GoalRoomToDoRepositoryTest.java new file mode 100644 index 000000000..1cf172a49 --- /dev/null +++ b/backend/kirikiri/src/test/java/co/kirikiri/todo/persistence/GoalRoomToDoRepositoryTest.java @@ -0,0 +1,151 @@ +package co.kirikiri.todo.persistence; + +import static org.assertj.core.api.Assertions.assertThat; + +import co.kirikiri.common.helper.RepositoryTest; +import co.kirikiri.domain.member.EncryptedPassword; +import co.kirikiri.domain.member.Gender; +import co.kirikiri.domain.member.Member; +import co.kirikiri.domain.member.MemberProfile; +import co.kirikiri.domain.member.vo.Identifier; +import co.kirikiri.domain.member.vo.Nickname; +import co.kirikiri.domain.member.vo.Password; +import co.kirikiri.domain.roadmap.Roadmap; +import co.kirikiri.domain.roadmap.RoadmapCategory; +import co.kirikiri.domain.roadmap.RoadmapContent; +import co.kirikiri.domain.roadmap.RoadmapDifficulty; +import co.kirikiri.domain.roadmap.RoadmapNode; +import co.kirikiri.domain.roadmap.RoadmapNodes; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomMember; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNode; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNodes; +import co.kirikiri.goalroom.domain.GoalRoomRole; +import co.kirikiri.goalroom.domain.vo.GoalRoomName; +import co.kirikiri.goalroom.domain.vo.LimitedMemberCount; +import co.kirikiri.goalroom.domain.vo.Period; +import co.kirikiri.goalroom.persistence.GoalRoomMemberRepository; +import co.kirikiri.goalroom.persistence.GoalRoomRepository; +import co.kirikiri.persistence.member.MemberRepository; +import co.kirikiri.persistence.roadmap.RoadmapCategoryRepository; +import co.kirikiri.persistence.roadmap.RoadmapRepository; +import co.kirikiri.todo.domain.GoalRoomToDo; +import co.kirikiri.todo.domain.vo.GoalRoomTodoContent; +import co.kirikiri.todo.domain.vo.ToDoPeriod; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; +import org.junit.jupiter.api.Test; + +@RepositoryTest +class GoalRoomToDoRepositoryTest { + + private static final LocalDate TODAY = LocalDate.now(); + + private final MemberRepository memberRepository; + private final RoadmapRepository roadmapRepository; + private final GoalRoomRepository goalRoomRepository; + private final GoalRoomMemberRepository goalRoomMemberRepository; + private final RoadmapCategoryRepository roadmapCategoryRepository; + private final GoalRoomToDoRepository goalRoomToDoRepository; + + public GoalRoomToDoRepositoryTest(final MemberRepository memberRepository, + final RoadmapRepository roadmapRepository, + final GoalRoomRepository goalRoomRepository, + final GoalRoomMemberRepository goalRoomMemberRepository, + final RoadmapCategoryRepository roadmapCategoryRepository, + final GoalRoomToDoRepository goalRoomToDoRepository) { + this.memberRepository = memberRepository; + this.roadmapRepository = roadmapRepository; + this.goalRoomRepository = goalRoomRepository; + this.goalRoomMemberRepository = goalRoomMemberRepository; + this.roadmapCategoryRepository = roadmapCategoryRepository; + this.goalRoomToDoRepository = goalRoomToDoRepository; + } + + @Test + void 골룸_아이디와_사용자_아이디로_골룸_투두_체크_현황을_반환한다() { + // given + final Member creator = 사용자를_생성한다("name1", "01011111111", "identifier1", "password!1"); + final RoadmapCategory category = 카테고리를_저장한다("여가"); + final RoadmapNode roadmapNode1 = 로드맵_노드를_생성한다("로드맵 1주차", "로드맵 1주차 내용"); + final RoadmapNode roadmapNode2 = 로드맵_노드를_생성한다("로드맵 2주차", "로드맵 2주차 내용"); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(List.of(roadmapNode1, roadmapNode2)); + 로드맵을_생성한다(creator, category, roadmapContent); + + final GoalRoomRoadmapNode goalRoomRoadmapNode1 = 골룸_로드맵_노드를_생성한다(TODAY, TODAY.plusDays(10), + roadmapNode1); + final GoalRoomRoadmapNode goalRoomRoadmapNode2 = 골룸_로드맵_노드를_생성한다(TODAY.plusDays(11), TODAY.plusDays(20), + roadmapNode2); + final Member goalRoomPendingMember = 사용자를_생성한다("name2", "01011112222", "identifier2", "password!2"); + final GoalRoom goalRoom = 골룸을_생성한다("goalroom1", 6, roadmapContent, + new GoalRoomRoadmapNodes(List.of(goalRoomRoadmapNode1, goalRoomRoadmapNode2)), goalRoomPendingMember); + final GoalRoom savedGoalRoom = goalRoomRepository.save(goalRoom); + + final LocalDate today = LocalDate.now(); + final LocalDate threeDaysAfter = today.plusDays(3); + final GoalRoomToDo firstGoalRoomTodo = new GoalRoomToDo(null, savedGoalRoom.getId(), + new GoalRoomTodoContent("투두1"), new ToDoPeriod(today, threeDaysAfter)); + final GoalRoomToDo secondGoalRoomTodo = new GoalRoomToDo(null, savedGoalRoom.getId(), + new GoalRoomTodoContent("투두2"), new ToDoPeriod(today, threeDaysAfter)); + final GoalRoomToDo savedFirstGoalRoomToDo = goalRoomToDoRepository.save(firstGoalRoomTodo); + final GoalRoomToDo savedSecondGoalRoomToDo = goalRoomToDoRepository.save(secondGoalRoomTodo); + + final GoalRoomMember goalRoomMember = new GoalRoomMember( + GoalRoomRole.LEADER, LocalDateTime.now(), savedGoalRoom, creator.getId()); + final GoalRoomMember savedGoalRoomMember = goalRoomMemberRepository.save(goalRoomMember); + + // when + final List findGoalRoomToDos = goalRoomToDoRepository.findGoalRoomToDosByGoalRoomId( + savedGoalRoom.getId()); + + // then + assertThat(findGoalRoomToDos) + .usingRecursiveComparison() + .isEqualTo(List.of(savedFirstGoalRoomToDo, savedSecondGoalRoomToDo)); + } + + private RoadmapCategory 카테고리를_저장한다(final String name) { + final RoadmapCategory roadmapCategory = new RoadmapCategory(name); + return roadmapCategoryRepository.save(roadmapCategory); + } + + private Member 사용자를_생성한다(final String nickname, final String phoneNumber, final String identifier, + final String password) { + final MemberProfile memberProfile = new MemberProfile(Gender.MALE, "kirikiri1@email.com"); + final Member creator = new Member(new Identifier(identifier), + new EncryptedPassword(new Password(password)), new Nickname(nickname), null, memberProfile); + return memberRepository.save(creator); + } + + private RoadmapNode 로드맵_노드를_생성한다(final String title, final String content) { + return new RoadmapNode(title, content); + } + + private RoadmapContent 로드맵_본문을_생성한다(final List roadmapNodes) { + final RoadmapContent roadmapContent = new RoadmapContent("로드맵 본문"); + roadmapContent.addNodes(new RoadmapNodes(roadmapNodes)); + return roadmapContent; + } + + private Roadmap 로드맵을_생성한다(final Member creator, final RoadmapCategory category, + final RoadmapContent roadmapContent) { + final Roadmap roadmap = new Roadmap("로드맵 제목", "로드맵 소개글", 30, RoadmapDifficulty.DIFFICULT, + creator, category); + roadmap.addContent(roadmapContent); + return roadmapRepository.save(roadmap); + } + + private GoalRoomRoadmapNode 골룸_로드맵_노드를_생성한다(final LocalDate startDate, final LocalDate endDate, + final RoadmapNode roadmapNode) { + return new GoalRoomRoadmapNode(new Period(startDate, endDate), 1, roadmapNode.getId()); + } + + private GoalRoom 골룸을_생성한다(final String name, final Integer limitedMemberCount, final RoadmapContent roadmapContent, + final GoalRoomRoadmapNodes goalRoomRoadmapNodes, final Member member) { + final GoalRoom goalRoom = new GoalRoom(new GoalRoomName(name), new LimitedMemberCount(limitedMemberCount), + roadmapContent.getId(), member.getId()); + goalRoom.addAllGoalRoomRoadmapNodes(goalRoomRoadmapNodes); + return goalRoom; + } +} diff --git a/backend/kirikiri/src/test/java/co/kirikiri/todo/service/GoalRoomToDoServiceTest.java b/backend/kirikiri/src/test/java/co/kirikiri/todo/service/GoalRoomToDoServiceTest.java new file mode 100644 index 000000000..53da313ab --- /dev/null +++ b/backend/kirikiri/src/test/java/co/kirikiri/todo/service/GoalRoomToDoServiceTest.java @@ -0,0 +1,469 @@ +package co.kirikiri.todo.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.when; + +import co.kirikiri.common.exception.BadRequestException; +import co.kirikiri.common.exception.ForbiddenException; +import co.kirikiri.common.exception.NotFoundException; +import co.kirikiri.common.type.ImageContentType; +import co.kirikiri.domain.member.EncryptedPassword; +import co.kirikiri.domain.member.Gender; +import co.kirikiri.domain.member.Member; +import co.kirikiri.domain.member.MemberProfile; +import co.kirikiri.domain.member.vo.Identifier; +import co.kirikiri.domain.member.vo.Nickname; +import co.kirikiri.domain.member.vo.Password; +import co.kirikiri.domain.roadmap.Roadmap; +import co.kirikiri.domain.roadmap.RoadmapCategory; +import co.kirikiri.domain.roadmap.RoadmapContent; +import co.kirikiri.domain.roadmap.RoadmapContents; +import co.kirikiri.domain.roadmap.RoadmapDifficulty; +import co.kirikiri.domain.roadmap.RoadmapNode; +import co.kirikiri.domain.roadmap.RoadmapNodeImage; +import co.kirikiri.domain.roadmap.RoadmapNodeImages; +import co.kirikiri.domain.roadmap.RoadmapNodes; +import co.kirikiri.goalroom.domain.GoalRoom; +import co.kirikiri.goalroom.domain.GoalRoomMember; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNode; +import co.kirikiri.goalroom.domain.GoalRoomRoadmapNodes; +import co.kirikiri.goalroom.domain.GoalRoomRole; +import co.kirikiri.goalroom.domain.vo.GoalRoomName; +import co.kirikiri.goalroom.domain.vo.LimitedMemberCount; +import co.kirikiri.goalroom.domain.vo.Period; +import co.kirikiri.goalroom.persistence.GoalRoomMemberRepository; +import co.kirikiri.goalroom.persistence.GoalRoomRepository; +import co.kirikiri.persistence.member.MemberRepository; +import co.kirikiri.todo.domain.GoalRoomToDo; +import co.kirikiri.todo.domain.GoalRoomToDoCheck; +import co.kirikiri.todo.domain.vo.GoalRoomTodoContent; +import co.kirikiri.todo.domain.vo.ToDoPeriod; +import co.kirikiri.todo.persistence.GoalRoomToDoCheckRepository; +import co.kirikiri.todo.persistence.GoalRoomToDoRepository; +import co.kirikiri.todo.service.dto.request.GoalRoomTodoRequest; +import co.kirikiri.todo.service.dto.response.GoalRoomToDoCheckResponse; +import co.kirikiri.todo.service.dto.response.GoalRoomTodoResponse; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class GoalRoomToDoServiceTest { + + private static final LocalDate TODAY = LocalDate.now(); + private static final LocalDate TEN_DAY_LATER = TODAY.plusDays(10); + private static final LocalDate TWENTY_DAY_LATER = TODAY.plusDays(20); + private static final LocalDate THIRTY_DAY_LATER = TODAY.plusDays(30); + + private static Member member; + + @Mock + private GoalRoomRepository goalRoomRepository; + + @Mock + private GoalRoomMemberRepository goalRoomMemberRepository; + + @Mock + private MemberRepository memberRepository; + + @Mock + private GoalRoomToDoRepository goalRoomToDoRepository; + + @Mock + private GoalRoomToDoCheckRepository goalRoomToDoCheckRepository; + + @InjectMocks + private GoalRoomToDoService goalRoomToDoService; + + @BeforeAll + static void setUp() { + final Identifier identifier = new Identifier("identifier1"); + final Password password = new Password("password1!"); + final EncryptedPassword encryptedPassword = new EncryptedPassword(password); + final Nickname nickname = new Nickname("nickname"); + final String email = "kirikiri@email.com"; + final MemberProfile memberProfile = new MemberProfile(Gender.MALE, email); + member = new Member(identifier, encryptedPassword, nickname, null, memberProfile); + } + + @Test + void 정상적으로_골룸에_투두리스트를_추가한다() { + //given + final Member creator = 사용자를_생성한다(1L, "identifier1", "password1!", "시진이", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + final int limitedMemberCount = 20; + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, limitedMemberCount); + final GoalRoomToDo goalRoomTodo = new GoalRoomToDo(null, 1L, new GoalRoomTodoContent("goalRoomTodoContent"), + new ToDoPeriod(TODAY, TEN_DAY_LATER)); + + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.of(creator)); + given(goalRoomRepository.findById(anyLong())) + .willReturn(Optional.of(goalRoom)); + given(goalRoomToDoRepository.save(any())) + .willReturn(goalRoomTodo); + + final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest("goalRoomContent", TODAY, + TEN_DAY_LATER); + + //when + //then + assertDoesNotThrow(() -> goalRoomToDoService.addGoalRoomTodo(1L, "identifier1", goalRoomTodoRequest)); + } + + @Test + void 골룸에_투두리스트_추가시_회원을_찾지_못할_경우_예외를_던진다() { + //given + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.empty()); + + final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest("goalRoomContent", TODAY, + TEN_DAY_LATER); + + //when + //then + assertThatThrownBy(() -> goalRoomToDoService.addGoalRoomTodo(1L, "identifier1", goalRoomTodoRequest)) + .isInstanceOf(NotFoundException.class); + } + + @Test + void 골룸에_투두리스트_추가시_골룸을_찾지_못할_경우_예외를_던진다() { + //given + final Member creator = 사용자를_생성한다(1L, "identifier1", "password1!", "시진이", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + final int limitedMemberCount = 20; + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, limitedMemberCount); + + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.of(creator)); + given(goalRoomRepository.findById(anyLong())) + .willReturn(Optional.empty()); + + final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest("goalRoomContent", TODAY, + TEN_DAY_LATER); + + //when + //then + assertThatThrownBy(() -> goalRoomToDoService.addGoalRoomTodo(1L, "identifier1", goalRoomTodoRequest)) + .isInstanceOf(NotFoundException.class); + } + + @Test + void 골룸에_투두리스트_추가시_종료된_골룸일_경우_예외를_던진다() { + //given + final Member creator = 사용자를_생성한다(1L, "identifier1", "password1!", "시진이", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + final int limitedMemberCount = 20; + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, limitedMemberCount); + goalRoom.complete(); + + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.of(creator)); + given(goalRoomRepository.findById(anyLong())) + .willReturn(Optional.of(goalRoom)); + + final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest("goalRoomContent", TODAY, + TEN_DAY_LATER); + + //when + //then + assertThatThrownBy(() -> goalRoomToDoService.addGoalRoomTodo(1L, "identifier1", goalRoomTodoRequest)) + .isInstanceOf(BadRequestException.class); + } + + @Test + void 골룸에_투두리스트_추가시_리더가_아닐_경우_예외를_던진다() { + //given + final Member creator = 사용자를_생성한다(1L, "identifier1", "password1!", "시진이", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + final int limitedMemberCount = 20; + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, limitedMemberCount); + + given(memberRepository.findByIdentifier(any())) + .willReturn(Optional.of(member)); + given(goalRoomRepository.findById(anyLong())) + .willReturn(Optional.of(goalRoom)); + + final GoalRoomTodoRequest goalRoomTodoRequest = new GoalRoomTodoRequest("goalRoomContent", TODAY, + TEN_DAY_LATER); + + //when + //then + assertThatThrownBy(() -> goalRoomToDoService.addGoalRoomTodo(1L, "identifier2", goalRoomTodoRequest)) + .isInstanceOf(BadRequestException.class); + } + + @Test + void 투두리스트를_체크한다() { + // given + final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 10); + final GoalRoomToDo goalRoomToDo = new GoalRoomToDo(1L, goalRoom.getId(), new GoalRoomTodoContent("투두 1"), + new ToDoPeriod(TODAY, TODAY.plusDays(3))); + final GoalRoomMember goalRoomMember = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, + creator.getId()); + + when(goalRoomRepository.findById(anyLong())) + .thenReturn(Optional.of(goalRoom)); + when(goalRoomToDoRepository.findById(any())) + .thenReturn(Optional.of(goalRoomToDo)); + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(creator)); + when(goalRoomMemberRepository.findByGoalRoomAndMemberId(any(), any())) + .thenReturn(Optional.of(goalRoomMember)); + when(goalRoomToDoCheckRepository.findByGoalRoomTodoAndGoalRoomMemberId(any(), any())) + .thenReturn(Optional.empty()); + + // when + final GoalRoomToDoCheckResponse checkResponse = goalRoomToDoService.checkGoalRoomTodo(goalRoom.getId(), + goalRoomToDo.getId(), "cokirikiri"); + + // then + assertThat(checkResponse) + .isEqualTo(new GoalRoomToDoCheckResponse(true)); + } + + @Test + void 투두리스트_체크시_체크_이력이_있으면_제거한다() { + // given + final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 10); + final GoalRoomToDo goalRoomToDo = new GoalRoomToDo(1L, goalRoom.getId(), new GoalRoomTodoContent("투두 1"), + new ToDoPeriod(TODAY, TODAY.plusDays(3))); + + final GoalRoomMember goalRoomMember = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, + creator.getId()); + final GoalRoomToDoCheck goalRoomToDoCheck = new GoalRoomToDoCheck(goalRoomMember.getId(), goalRoomToDo); + + when(goalRoomRepository.findById(anyLong())) + .thenReturn(Optional.of(goalRoom)); + when(goalRoomToDoRepository.findById(any())) + .thenReturn(Optional.of(goalRoomToDo)); + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(creator)); + when(goalRoomMemberRepository.findByGoalRoomAndMemberId(any(), any())) + .thenReturn(Optional.of(goalRoomMember)); + when(goalRoomToDoCheckRepository.findByGoalRoomTodoAndGoalRoomMemberId(any(), any())) + .thenReturn(Optional.of(goalRoomToDoCheck)); + + // when + final GoalRoomToDoCheckResponse checkResponse = goalRoomToDoService.checkGoalRoomTodo(goalRoom.getId(), + goalRoomToDo.getId(), "cokirikiri"); + + // then + assertThat(checkResponse) + .isEqualTo(new GoalRoomToDoCheckResponse(false)); + } + + @Test + void 투두리스트_체크시_골룸이_존재하지_않으면_예외가_발생한다() { + // given + when(goalRoomRepository.findById(anyLong())) + .thenReturn(Optional.empty()); + + // expected + assertThatThrownBy(() -> goalRoomToDoService.checkGoalRoomTodo(1L, 1L, "cokirikiri")) + .isInstanceOf(NotFoundException.class) + .hasMessage("존재하지 않는 골룸입니다. goalRoomId = 1"); + } + + @Test + void 투두리스트_체크시_해당_투두가_존재하지_않으면_예외가_발생한다() { + // given + final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 10); + + when(goalRoomRepository.findById(anyLong())) + .thenReturn(Optional.of(goalRoom)); + + // expected + assertThatThrownBy(() -> goalRoomToDoService.checkGoalRoomTodo(1L, 2L, "cokirikiri")) + .isInstanceOf(NotFoundException.class) + .hasMessage("존재하지 않는 투두입니다. todoId = 2"); + } + + @Test + void 투두리스트_체크시_골룸에_사용자가_없으면_예외가_발생한다() { + // given + final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 10); + final GoalRoomToDo goalRoomToDo = new GoalRoomToDo(1L, goalRoom.getId(), new GoalRoomTodoContent("투두 1"), + new ToDoPeriod(TODAY, TODAY.plusDays(3))); + + when(goalRoomRepository.findById(anyLong())) + .thenReturn(Optional.of(goalRoom)); + when(goalRoomToDoRepository.findById(any())) + .thenReturn(Optional.of(goalRoomToDo)); + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(creator)); + when(goalRoomMemberRepository.findByGoalRoomAndMemberId(any(), any())) + .thenReturn(Optional.empty()); + + // expected + assertThatThrownBy(() -> goalRoomToDoService.checkGoalRoomTodo(1L, 1L, "cokirikiri")) + .isInstanceOf(NotFoundException.class) + .hasMessage("골룸에 사용자가 존재하지 않습니다. goalRoomId = 1 memberIdentifier = cokirikiri"); + } + + @Test + void 골룸의_전체_투두리스트를_조회한다() { + // given + final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 10); + + final GoalRoomToDo firstGoalRoomTodo = new GoalRoomToDo(1L, goalRoom.getId(), new GoalRoomTodoContent("투두 1"), + new ToDoPeriod(TODAY, TEN_DAY_LATER)); + final GoalRoomToDo secondGoalRoomTodo = new GoalRoomToDo(2L, goalRoom.getId(), new GoalRoomTodoContent("투두 2"), + new ToDoPeriod(TWENTY_DAY_LATER, THIRTY_DAY_LATER)); + + final GoalRoomMember goalRoomMember = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, + creator.getId()); + when(goalRoomRepository.findById(1L)) + .thenReturn(Optional.of(goalRoom)); + when(goalRoomToDoRepository.findGoalRoomToDosByGoalRoomId(anyLong())) + .thenReturn(List.of(firstGoalRoomTodo, secondGoalRoomTodo)); + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(creator)); + when(goalRoomMemberRepository.findByGoalRoomIdAndMemberId(anyLong(), any())) + .thenReturn(Optional.of(goalRoomMember)); + when(goalRoomToDoCheckRepository.findByGoalRoomIdAndGoalRoomMemberId(anyLong(), any())) + .thenReturn(List.of( + new GoalRoomToDoCheck(goalRoomMember.getId(), firstGoalRoomTodo) + )); + + // when + final List responses = goalRoomToDoService.findAllGoalRoomTodo(1L, "identifier"); + final List expected = List.of( + new GoalRoomTodoResponse(1L, "투두 1", TODAY, TEN_DAY_LATER, new GoalRoomToDoCheckResponse(true)), + new GoalRoomTodoResponse(2L, "투두 2", TWENTY_DAY_LATER, THIRTY_DAY_LATER, + new GoalRoomToDoCheckResponse(false))); + + // then + assertThat(responses) + .isEqualTo(expected); + } + + @Test + void 골룸의_투두리스트_조회시_존재하지_않는_골룸이면_예외가_발생한다() { + // given + when(goalRoomRepository.findById(1L)) + .thenReturn(Optional.empty()); + + // expected + assertThatThrownBy(() -> goalRoomToDoService.findAllGoalRoomTodo(1L, "identifier")) + .isInstanceOf(NotFoundException.class); + } + + @Test + void 골룸의_투두리스트_조회시_골룸에_참여하지_않은_사용자면_예외가_발생한다() { + // given + final Member creator = 사용자를_생성한다(1L, "cokirikiri", "password1!", "코끼리", "kirikiri1@email"); + final Roadmap roadmap = 로드맵을_생성한다(creator); + final RoadmapContents roadmapContents = roadmap.getContents(); + final RoadmapContent targetRoadmapContent = roadmapContents.getValues().get(0); + final GoalRoom goalRoom = 골룸을_생성한다(1L, creator, targetRoadmapContent, 10); + + when(goalRoomRepository.findById(1L)) + .thenReturn(Optional.of(goalRoom)); + when(memberRepository.findByIdentifier(any())) + .thenReturn(Optional.of(creator)); + when(goalRoomMemberRepository.findByGoalRoomIdAndMemberId(anyLong(), any())) + .thenReturn(Optional.empty()); + + // expected + assertThatThrownBy(() -> goalRoomToDoService.findAllGoalRoomTodo(1L, "identifier")) + .isInstanceOf(ForbiddenException.class); + } + + private Member 사용자를_생성한다(final Long memberId, final String identifier, final String password, final String nickname, + final String email) { + final MemberProfile memberProfile = new MemberProfile(Gender.MALE, email); + + return new Member(memberId, new Identifier(identifier), null, new EncryptedPassword(new Password(password)), + new Nickname(nickname), null, memberProfile); + } + + private Roadmap 로드맵을_생성한다(final Member creator) { + final RoadmapCategory category = new RoadmapCategory("게임"); + final List roadmapNodes = 로드맵_노드들을_생성한다(); + final RoadmapContent roadmapContent = 로드맵_본문을_생성한다(roadmapNodes); + final Roadmap roadmap = new Roadmap("로드맵 제목", "로드맵 소개글", 10, RoadmapDifficulty.NORMAL, creator, category); + roadmap.addContent(roadmapContent); + return roadmap; + } + + private List 로드맵_노드들을_생성한다() { + final RoadmapNode roadmapNode1 = new RoadmapNode("로드맵 1주차", "로드맵 1주차 내용"); + roadmapNode1.addImages(new RoadmapNodeImages(노드_이미지들을_생성한다())); + final RoadmapNode roadmapNode2 = new RoadmapNode("로드맵 2주차", "로드맵 2주차 내용"); + return List.of(roadmapNode1, roadmapNode2); + } + + private RoadmapContent 로드맵_본문을_생성한다(final List roadmapNodes) { + final RoadmapContent roadmapContent = new RoadmapContent("로드맵 본문"); + roadmapContent.addNodes(new RoadmapNodes(roadmapNodes)); + return roadmapContent; + } + + private List 노드_이미지들을_생성한다() { + return List.of( + new RoadmapNodeImage("node-image1.png", "node-image1-save-path", ImageContentType.PNG), + new RoadmapNodeImage("node-image2.png", "node-image2-save-path", ImageContentType.PNG) + ); + } + + private GoalRoom 골룸을_생성한다(final Long goalRoomId, final Member creator, final RoadmapContent roadmapContent, + final Integer limitedMemberCount) { + final GoalRoom goalRoom = new GoalRoom(goalRoomId, new GoalRoomName("골룸 이름"), + new LimitedMemberCount(limitedMemberCount), roadmapContent.getId(), creator.getId()); + goalRoom.addAllGoalRoomRoadmapNodes(골룸_로드맵_노드들을_생성한다(roadmapContent.getNodes())); + return goalRoom; + } + + private GoalRoomRoadmapNodes 골룸_로드맵_노드들을_생성한다(final RoadmapNodes roadmapNodes) { + return new GoalRoomRoadmapNodes(List.of( + new GoalRoomRoadmapNode(new Period(TODAY, TEN_DAY_LATER), 5, roadmapNodes.getValues().get(0).getId()), + new GoalRoomRoadmapNode(new Period(TEN_DAY_LATER.plusDays(1), TWENTY_DAY_LATER), 5, + roadmapNodes.getValues().get(1).getId())) + ); + } +}