From 2e764112951929c8a2221f414961ad51fc9cfd62 Mon Sep 17 00:00:00 2001 From: jun Date: Wed, 3 Jan 2024 01:22:18 +0900 Subject: [PATCH 1/9] =?UTF-8?q?:sparkles:=20[API=20=EC=B6=94=EA=B0=80]=20?= =?UTF-8?q?=EC=9D=B8=EA=B8=B0=20=EC=8A=A4=ED=84=B0=EB=94=94=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - @GetMapping을 사용하여 /rank 에 인기 스터디 목록 조회 API 구현 - RankParams를 통해 전달된 조건에 따라 목록 반환 --- .../steady/controller/SteadyController.java | 12 +++++++ .../dev/steady/steady/dto/RankCondition.java | 15 ++++++++ .../java/dev/steady/steady/dto/RankType.java | 13 +++++++ .../steady/steady/dto/request/RankParams.java | 21 +++++++++++ .../dto/response/SteadyRankResponse.java | 35 +++++++++++++++++++ 5 files changed, 96 insertions(+) create mode 100644 src/main/java/dev/steady/steady/dto/RankCondition.java create mode 100644 src/main/java/dev/steady/steady/dto/RankType.java create mode 100644 src/main/java/dev/steady/steady/dto/request/RankParams.java create mode 100644 src/main/java/dev/steady/steady/dto/response/SteadyRankResponse.java diff --git a/src/main/java/dev/steady/steady/controller/SteadyController.java b/src/main/java/dev/steady/steady/controller/SteadyController.java index 82b953f..72ee010 100644 --- a/src/main/java/dev/steady/steady/controller/SteadyController.java +++ b/src/main/java/dev/steady/steady/controller/SteadyController.java @@ -5,6 +5,7 @@ import dev.steady.global.auth.UserInfo; import dev.steady.steady.domain.SteadyStatus; import dev.steady.steady.dto.FilterConditionDto; +import dev.steady.steady.dto.request.RankParams; import dev.steady.steady.dto.request.SteadyCreateRequest; import dev.steady.steady.dto.request.SteadyPageRequest; import dev.steady.steady.dto.request.SteadyQuestionUpdateRequest; @@ -13,9 +14,11 @@ import dev.steady.steady.dto.response.MySteadyResponse; import dev.steady.steady.dto.response.PageResponse; import dev.steady.steady.dto.response.ParticipantsResponse; +import dev.steady.steady.dto.RankCondition; import dev.steady.steady.dto.response.SteadyDetailResponse; import dev.steady.steady.dto.response.SteadyQueryResponse; import dev.steady.steady.dto.response.SteadyQuestionsResponse; +import dev.steady.steady.dto.response.SteadyRankResponse; import dev.steady.steady.service.SteadyService; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -32,6 +35,7 @@ import org.springframework.web.bind.annotation.RestController; import java.net.URI; +import java.util.List; @RestController @RequiredArgsConstructor @@ -67,6 +71,14 @@ public ResponseEntity> getSteadies(@Auth(requi return ResponseEntity.ok(response); } + @GetMapping("/rank") + public ResponseEntity> getPopularStudy(@Valid RankParams params) { + RankCondition condition = params.toCondition(); + List popularStudy = steadyService.getPopularStudy(condition); + + return ResponseEntity.ok(popularStudy); + } + @GetMapping("/{steadyId}") public ResponseEntity getDetailSteady(@PathVariable Long steadyId, @Auth(required = false) UserInfo userInfo) { diff --git a/src/main/java/dev/steady/steady/dto/RankCondition.java b/src/main/java/dev/steady/steady/dto/RankCondition.java new file mode 100644 index 0000000..bbc905d --- /dev/null +++ b/src/main/java/dev/steady/steady/dto/RankCondition.java @@ -0,0 +1,15 @@ +package dev.steady.steady.dto; + +import java.time.LocalDate; + +public record RankCondition( + LocalDate date, + int limit, + RankType type +) { + + public static RankCondition of(LocalDate date, int limit, String type) { + return new RankCondition(date, limit, RankType.from(type)); + } + +} diff --git a/src/main/java/dev/steady/steady/dto/RankType.java b/src/main/java/dev/steady/steady/dto/RankType.java new file mode 100644 index 0000000..ef81b1c --- /dev/null +++ b/src/main/java/dev/steady/steady/dto/RankType.java @@ -0,0 +1,13 @@ +package dev.steady.steady.dto; + +public enum RankType { + + ALL, + STUDY, + PROJECT; + + public static RankType from(String type) { + return valueOf(type.toUpperCase()); + } + +} diff --git a/src/main/java/dev/steady/steady/dto/request/RankParams.java b/src/main/java/dev/steady/steady/dto/request/RankParams.java new file mode 100644 index 0000000..24019ea --- /dev/null +++ b/src/main/java/dev/steady/steady/dto/request/RankParams.java @@ -0,0 +1,21 @@ +package dev.steady.steady.dto.request; + +import dev.steady.steady.dto.RankCondition; +import jakarta.validation.constraints.Max; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDate; + +public record RankParams( + @DateTimeFormat(pattern = "yyyy-MM-dd") + LocalDate date, + @Max(value = 10, message = "인기글은 최대 10개까지 조회가 가능합니다.") + int limit, + String type +) { + + public RankCondition toCondition() { + return RankCondition.of(date, limit, type); + } + +} diff --git a/src/main/java/dev/steady/steady/dto/response/SteadyRankResponse.java b/src/main/java/dev/steady/steady/dto/response/SteadyRankResponse.java new file mode 100644 index 0000000..760ee97 --- /dev/null +++ b/src/main/java/dev/steady/steady/dto/response/SteadyRankResponse.java @@ -0,0 +1,35 @@ +package dev.steady.steady.dto.response; + +import dev.steady.steady.domain.Steady; +import dev.steady.steady.domain.SteadyStatus; +import dev.steady.steady.domain.SteadyType; + +import java.time.LocalDate; + +public record SteadyRankResponse( + Long steadyId, + String title, + SteadyType type, + SteadyStatus status, + LocalDate deadline, + int participantLimit, + int numberOfParticipants, + int viewCount, + int likeCount +) { + + public static SteadyRankResponse from(Steady steady) { + return new SteadyRankResponse( + steady.getId(), + steady.getTitle(), + steady.getType(), + steady.getStatus(), + steady.getDeadline(), + steady.getParticipantLimit(), + steady.getNumberOfParticipants(), + steady.getViewCount(), + steady.getLikeCount() + ); + } + +} From 166497f1b6c8776c5cc7e632d01be9a8d62544fd Mon Sep 17 00:00:00 2001 From: jun Date: Wed, 3 Jan 2024 01:28:16 +0900 Subject: [PATCH 2/9] =?UTF-8?q?:sparkles:=20=EC=9D=B8=EA=B8=B0=20=EC=8A=A4?= =?UTF-8?q?=ED=84=B0=EB=94=94=20=EC=A1=B0=ED=9A=8C=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `steadyRepository`의 `findPopularStudyInCondition` 메소드를 사용하여 조건에 맞는 인기 스터디 --- .../dev/steady/steady/service/SteadyService.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/java/dev/steady/steady/service/SteadyService.java b/src/main/java/dev/steady/steady/service/SteadyService.java index 8622169..01e54f3 100644 --- a/src/main/java/dev/steady/steady/service/SteadyService.java +++ b/src/main/java/dev/steady/steady/service/SteadyService.java @@ -5,6 +5,7 @@ import dev.steady.application.dto.response.SliceResponse; import dev.steady.global.auth.UserInfo; import dev.steady.global.exception.InvalidStateException; +import dev.steady.steady.dto.RankCondition; import dev.steady.steady.domain.Participant; import dev.steady.steady.domain.Steady; import dev.steady.steady.domain.SteadyPosition; @@ -28,6 +29,7 @@ import dev.steady.steady.dto.response.SteadyDetailResponse; import dev.steady.steady.dto.response.SteadyQueryResponse; import dev.steady.steady.dto.response.SteadyQuestionsResponse; +import dev.steady.steady.dto.response.SteadyRankResponse; import dev.steady.user.domain.Position; import dev.steady.user.domain.Stack; import dev.steady.user.domain.User; @@ -87,6 +89,14 @@ public PageResponse getSteadies(UserInfo userInfo, FilterCo return PageResponse.from(searchResponses); } + @Transactional(readOnly = true) + public List getPopularStudy(RankCondition condition) { + List steadies = steadyRepository.findPopularStudyInCondition(condition); + return steadies.stream() + .map(SteadyRankResponse::from) + .toList(); + } + @Transactional public SteadyDetailResponse getDetailSteady(Long steadyId, UserInfo userInfo) { Steady steady = steadyRepository.getSteady(steadyId); @@ -133,7 +143,7 @@ public void updateSteady(Long steadyId, SteadyUpdateRequest request, UserInfo us steady.update(user, request.name(), request.bio(), - request.contact(), + request.contact(), request.type(), request.status(), request.participantLimit(), From 1c54f7a3326a8e8137067221d2074c606c6c58f5 Mon Sep 17 00:00:00 2001 From: jun Date: Wed, 3 Jan 2024 01:32:27 +0900 Subject: [PATCH 3/9] =?UTF-8?q?:sparkles:=20[=EA=B0=9C=EC=84=A0]=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=EC=97=90=20=EB=A7=9E=EB=8A=94=20=EC=9D=B8?= =?UTF-8?q?=EA=B8=B0=20=EC=8A=A4=ED=84=B0=EB=94=94=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EB=A9=94=EC=86=8C=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 프로모션 날짜, 스터디 유형 조건으로 필터링 및 좋아요와 조회수로 정렬 --- .../SteadySearchRepository.java | 5 ++++ .../SteadySearchRepositoryImpl.java | 27 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/main/java/dev/steady/steady/infrastructure/SteadySearchRepository.java b/src/main/java/dev/steady/steady/infrastructure/SteadySearchRepository.java index 511ee33..f9cc934 100644 --- a/src/main/java/dev/steady/steady/infrastructure/SteadySearchRepository.java +++ b/src/main/java/dev/steady/steady/infrastructure/SteadySearchRepository.java @@ -1,6 +1,7 @@ package dev.steady.steady.infrastructure; import dev.steady.global.auth.UserInfo; +import dev.steady.steady.dto.RankCondition; import dev.steady.steady.domain.Steady; import dev.steady.steady.domain.SteadyStatus; import dev.steady.steady.dto.FilterConditionDto; @@ -10,10 +11,14 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; +import java.util.List; + public interface SteadySearchRepository { Page findAllByFilterCondition(UserInfo userInfo, FilterConditionDto condition, Pageable pageable); Slice findMySteadies(SteadyStatus status, User user, Pageable pageable); + List findPopularStudyInCondition(RankCondition condition); + } diff --git a/src/main/java/dev/steady/steady/infrastructure/SteadySearchRepositoryImpl.java b/src/main/java/dev/steady/steady/infrastructure/SteadySearchRepositoryImpl.java index 4def1bf..7e1ce9e 100644 --- a/src/main/java/dev/steady/steady/infrastructure/SteadySearchRepositoryImpl.java +++ b/src/main/java/dev/steady/steady/infrastructure/SteadySearchRepositoryImpl.java @@ -8,7 +8,10 @@ import dev.steady.steady.domain.Participant; import dev.steady.steady.domain.Steady; import dev.steady.steady.domain.SteadyStatus; +import dev.steady.steady.domain.SteadyType; import dev.steady.steady.dto.FilterConditionDto; +import dev.steady.steady.dto.RankCondition; +import dev.steady.steady.dto.RankType; import dev.steady.steady.dto.response.MySteadyQueryResponse; import dev.steady.steady.uitl.Cursor; import dev.steady.user.domain.User; @@ -33,6 +36,8 @@ import static dev.steady.steady.domain.SteadyStatus.CLOSED; import static dev.steady.steady.domain.SteadyStatus.FINISHED; import static dev.steady.steady.domain.SteadyStatus.RECRUITING; +import static dev.steady.steady.dto.RankType.PROJECT; +import static dev.steady.steady.dto.RankType.STUDY; import static dev.steady.steady.infrastructure.util.DynamicQueryUtils.filterCondition; import static dev.steady.steady.infrastructure.util.DynamicQueryUtils.orderBySort; @@ -90,6 +95,18 @@ public Slice findMySteadies(SteadyStatus status, User use return new SliceImpl<>(content, pageable, hasNext); } + @Override + public List findPopularStudyInCondition(RankCondition condition) { + return jpaQueryFactory.selectFrom(steady) + .where(steady.promotion.promotedAt + .after(condition.date().atStartOfDay()), + steadyTypeCond(condition.type()) + ) + .orderBy(steady.likeCount.desc(), steady.viewCount.desc()) + .limit(condition.limit()) + .fetch(); + } + private BooleanExpression isParticipantUserIdEqual(User user) { return participant.user.id.eq(user.getId()); } @@ -113,6 +130,16 @@ private BooleanExpression isWorkSteady(SteadyStatus status) { return null; } + private BooleanExpression steadyTypeCond(RankType type) { + if (type == PROJECT) { + return steady.type.eq(SteadyType.PROJECT); + } + if (type == STUDY) { + return steady.type.eq(SteadyType.STUDY); + } + return null; + } + private BooleanBuilder filterConditionBuilder(UserInfo userInfo, FilterConditionDto condition) { BooleanBuilder booleanBuilder = new BooleanBuilder(); From 2962984760471ce7b62c4befc9a75e526078d95c Mon Sep 17 00:00:00 2001 From: jun Date: Wed, 3 Jan 2024 16:20:13 +0900 Subject: [PATCH 4/9] =?UTF-8?q?:recycle:=20[=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD]=20=EC=BB=A8=EB=B2=A4=EC=85=98?= =?UTF-8?q?=EC=97=90=20=EB=A7=9E=EA=B2=8C=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - getXXX -> findXXX --- .../java/dev/steady/steady/controller/SteadyController.java | 4 ++-- src/main/java/dev/steady/steady/service/SteadyService.java | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/dev/steady/steady/controller/SteadyController.java b/src/main/java/dev/steady/steady/controller/SteadyController.java index 72ee010..664a209 100644 --- a/src/main/java/dev/steady/steady/controller/SteadyController.java +++ b/src/main/java/dev/steady/steady/controller/SteadyController.java @@ -72,9 +72,9 @@ public ResponseEntity> getSteadies(@Auth(requi } @GetMapping("/rank") - public ResponseEntity> getPopularStudy(@Valid RankParams params) { + public ResponseEntity> findPopularStudies(@Valid RankParams params) { RankCondition condition = params.toCondition(); - List popularStudy = steadyService.getPopularStudy(condition); + List popularStudy = steadyService.findPopularStudies(condition); return ResponseEntity.ok(popularStudy); } diff --git a/src/main/java/dev/steady/steady/service/SteadyService.java b/src/main/java/dev/steady/steady/service/SteadyService.java index 01e54f3..0879c99 100644 --- a/src/main/java/dev/steady/steady/service/SteadyService.java +++ b/src/main/java/dev/steady/steady/service/SteadyService.java @@ -90,8 +90,9 @@ public PageResponse getSteadies(UserInfo userInfo, FilterCo } @Transactional(readOnly = true) - public List getPopularStudy(RankCondition condition) { + public List findPopularStudies(RankCondition condition) { List steadies = steadyRepository.findPopularStudyInCondition(condition); + return steadies.stream() .map(SteadyRankResponse::from) .toList(); From 87afebfafe3d9ea6cda883b5c11c45cb7f09bdc9 Mon Sep 17 00:00:00 2001 From: jun Date: Wed, 3 Jan 2024 16:21:02 +0900 Subject: [PATCH 5/9] =?UTF-8?q?:recycle:=20=EC=8A=A4=ED=85=8C=EB=94=94=20?= =?UTF-8?q?=EC=B0=B8=EC=97=AC=EC=9E=90=20fetch=20Lazy=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Eager -> Lazy --- src/main/java/dev/steady/steady/domain/Participants.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/dev/steady/steady/domain/Participants.java b/src/main/java/dev/steady/steady/domain/Participants.java index f3a1453..d81e560 100644 --- a/src/main/java/dev/steady/steady/domain/Participants.java +++ b/src/main/java/dev/steady/steady/domain/Participants.java @@ -5,6 +5,7 @@ import dev.steady.user.domain.User; import jakarta.persistence.CascadeType; import jakarta.persistence.Embeddable; +import jakarta.persistence.FetchType; import jakarta.persistence.OneToMany; import lombok.AccessLevel; import lombok.NoArgsConstructor; @@ -20,7 +21,7 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Participants { - @OneToMany(mappedBy = "steady", cascade = CascadeType.ALL, orphanRemoval = true) + @OneToMany(mappedBy = "steady", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) private final List steadyParticipants = new ArrayList<>(); private int participantLimit; From 73cdb8967c642eed75233ec2324f353374bab80c Mon Sep 17 00:00:00 2001 From: jun Date: Wed, 3 Jan 2024 16:22:16 +0900 Subject: [PATCH 6/9] =?UTF-8?q?:recycle:=20=EC=9D=B8=EA=B8=B0=20=EA=B2=8C?= =?UTF-8?q?=EC=8B=9C=EB=AC=BC=20=EC=A1=B0=ED=9A=8C=20=EB=B0=98=ED=99=98?= =?UTF-8?q?=EC=8A=A4=ED=8E=99=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/steady/steady/dto/response/SteadyRankResponse.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/dev/steady/steady/dto/response/SteadyRankResponse.java b/src/main/java/dev/steady/steady/dto/response/SteadyRankResponse.java index 760ee97..9de0f12 100644 --- a/src/main/java/dev/steady/steady/dto/response/SteadyRankResponse.java +++ b/src/main/java/dev/steady/steady/dto/response/SteadyRankResponse.java @@ -12,8 +12,6 @@ public record SteadyRankResponse( SteadyType type, SteadyStatus status, LocalDate deadline, - int participantLimit, - int numberOfParticipants, int viewCount, int likeCount ) { @@ -25,8 +23,6 @@ public static SteadyRankResponse from(Steady steady) { steady.getType(), steady.getStatus(), steady.getDeadline(), - steady.getParticipantLimit(), - steady.getNumberOfParticipants(), steady.getViewCount(), steady.getLikeCount() ); From 778feb4d17ccfbdce0cc4f6c398bf7621aa25ba7 Mon Sep 17 00:00:00 2001 From: jun Date: Wed, 3 Jan 2024 16:22:45 +0900 Subject: [PATCH 7/9] =?UTF-8?q?:white=5Fcheck=5Fmark:=20=EC=9D=B8=EA=B8=B0?= =?UTF-8?q?=20=EA=B2=8C=EC=8B=9C=EB=AC=BC=20=EC=A1=B0=ED=9A=8C=20=ED=94=BD?= =?UTF-8?q?=EC=8A=A4=EC=B2=98=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../steady/fixture/SteadyFixturesV2.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/test/java/dev/steady/steady/fixture/SteadyFixturesV2.java b/src/test/java/dev/steady/steady/fixture/SteadyFixturesV2.java index 28b3e50..16172c1 100644 --- a/src/test/java/dev/steady/steady/fixture/SteadyFixturesV2.java +++ b/src/test/java/dev/steady/steady/fixture/SteadyFixturesV2.java @@ -15,6 +15,7 @@ import dev.steady.steady.dto.response.SteadyQueryResponse; import dev.steady.steady.dto.response.SteadyQuestionResponse; import dev.steady.steady.dto.response.SteadyQuestionsResponse; +import dev.steady.steady.dto.response.SteadyRankResponse; import dev.steady.user.domain.Position; import dev.steady.user.domain.Stack; import dev.steady.user.domain.User; @@ -28,9 +29,11 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; +import java.util.stream.IntStream; import static dev.steady.steady.domain.ScheduledPeriod.FIVE_MONTH; import static dev.steady.steady.domain.SteadyMode.ONLINE; +import static dev.steady.steady.domain.SteadyStatus.CLOSED; import static dev.steady.steady.domain.SteadyType.STUDY; import static dev.steady.user.fixture.UserFixturesV2.generateStackEntity; import static org.instancio.Select.field; @@ -80,6 +83,19 @@ public static Steady createSteady(User leader, List stacks) { .build(); } + public static List createSteadiesWithLikeCount(User leader, List stacks, int likeCount) { + return IntStream.rangeClosed(0, likeCount) + .mapToObj(count -> createSteadyWithLikeCount(leader, stacks, count)) + .toList(); + } + + public static List createSteadyRankResponses() { + return List.of( + new SteadyRankResponse(2L, "스테디 제목2", STUDY, CLOSED, LocalDate.of(2023, 12, 31), 10, 1), + new SteadyRankResponse(2L, "스테디 제목2", STUDY, CLOSED, LocalDate.of(2023, 12, 15), 10, 3) + ); + } + public static Steady createSteadyWithStatus(User leader, List stacks, SteadyStatus status) { Steady steady = Steady.builder() .name("테스트 스테디") @@ -196,4 +212,10 @@ public static SliceResponse createMySteadyResponse() { ); } + private static Steady createSteadyWithLikeCount(User leader, List stacks, int likeCount) { + Steady steady = createSteady(leader, stacks); + ReflectionTestUtils.setField(steady, "likeCount", likeCount); + return steady; + } + } From 9e7f890ed9883050f5738862460e130ab5492f5c Mon Sep 17 00:00:00 2001 From: jun Date: Wed, 3 Jan 2024 16:23:11 +0900 Subject: [PATCH 8/9] =?UTF-8?q?:white=5Fcheck=5Fmark:=20=EC=9D=B8=EA=B8=B0?= =?UTF-8?q?=20=EA=B2=8C=EC=8B=9C=EB=AC=BC=20=EC=A1=B0=ED=9A=8C=20=EB=B9=84?= =?UTF-8?q?=EC=A6=88=EB=8B=88=EC=8A=A4=20=EB=A1=9C=EC=A7=81=EC=84=B1?= =?UTF-8?q?=EA=B3=B5=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../steady/service/SteadyServiceTest.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/test/java/dev/steady/steady/service/SteadyServiceTest.java b/src/test/java/dev/steady/steady/service/SteadyServiceTest.java index 60ac47e..db0d28f 100644 --- a/src/test/java/dev/steady/steady/service/SteadyServiceTest.java +++ b/src/test/java/dev/steady/steady/service/SteadyServiceTest.java @@ -17,6 +17,7 @@ import dev.steady.steady.domain.repository.SteadyRepository; import dev.steady.steady.domain.repository.SteadyStackRepository; import dev.steady.steady.dto.FilterConditionDto; +import dev.steady.steady.dto.RankCondition; import dev.steady.steady.dto.request.SteadyCreateRequest; import dev.steady.steady.dto.request.SteadyQuestionUpdateRequest; import dev.steady.steady.dto.request.SteadySearchRequest; @@ -27,6 +28,7 @@ import dev.steady.steady.dto.response.SteadyDetailResponse; import dev.steady.steady.dto.response.SteadyQueryResponse; import dev.steady.steady.dto.response.SteadyQuestionsResponse; +import dev.steady.steady.dto.response.SteadyRankResponse; import dev.steady.user.domain.Position; import dev.steady.user.domain.Stack; import dev.steady.user.domain.User; @@ -45,6 +47,7 @@ import org.springframework.data.domain.Sort; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; @@ -54,6 +57,7 @@ import static dev.steady.steady.domain.SteadyStatus.RECRUITING; import static dev.steady.steady.fixture.SteadyFixturesV2.createDefaultSteadySearchRequest; import static dev.steady.steady.fixture.SteadyFixturesV2.createOrderByDeadLineSteadySearchRequest; +import static dev.steady.steady.fixture.SteadyFixturesV2.createSteadiesWithLikeCount; import static dev.steady.steady.fixture.SteadyFixturesV2.createSteady; import static dev.steady.steady.fixture.SteadyFixturesV2.createSteadyQuestion; import static dev.steady.steady.fixture.SteadyFixturesV2.createSteadyWithStatus; @@ -166,6 +170,23 @@ void getSteadiesSearchTest() { ); } + @Test + @DisplayName("랭킹 조건의 따른 스테디 인기글 조회") + void getPopularSteadiesTest() { + //given + var steadies = createSteadiesWithLikeCount(leader, List.of(stack), 3); + steadyRepository.saveAll(steadies); + var rankCondition = RankCondition.of(LocalDate.now().minusDays(1), 3, "ALL"); + + //when + List popularSteadies = steadyService.findPopularStudies(rankCondition); + + //then + int firstRank = popularSteadies.get(0).likeCount(); + int secondRank = popularSteadies.get(1).likeCount(); + assertThat(firstRank).isGreaterThan(secondRank); + } + @Test @DisplayName("마감임박순 조건을 통해 페이징 처리된 응답을 반환할 수 있다.") void getSteadiesSearchOrderByDeadlineTest() { From 8c74715defa014d3f3bf6e386986f65a914a26a0 Mon Sep 17 00:00:00 2001 From: jun Date: Wed, 3 Jan 2024 16:23:32 +0900 Subject: [PATCH 9/9] =?UTF-8?q?:white=5Fcheck=5Fmark:=20=EC=9D=B8=EA=B8=B0?= =?UTF-8?q?=20=EA=B2=8C=EC=8B=9C=EB=AC=BC=20=EC=A1=B0=ED=9A=8C=20=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1=20=EB=B0=8F=20=EB=AC=B8=EC=84=9C=ED=99=94=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/SteadyControllerTest.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/test/java/dev/steady/steady/controller/SteadyControllerTest.java b/src/test/java/dev/steady/steady/controller/SteadyControllerTest.java index 2bb2c0a..098d6e6 100644 --- a/src/test/java/dev/steady/steady/controller/SteadyControllerTest.java +++ b/src/test/java/dev/steady/steady/controller/SteadyControllerTest.java @@ -6,18 +6,22 @@ import dev.steady.global.auth.UserInfo; import dev.steady.global.config.ControllerTestConfig; import dev.steady.steady.dto.FilterConditionDto; +import dev.steady.steady.dto.RankCondition; +import dev.steady.steady.dto.request.RankParams; import dev.steady.steady.dto.request.SteadyPageRequest; import dev.steady.steady.dto.request.SteadyQuestionUpdateRequest; import dev.steady.steady.dto.response.MySteadyResponse; import dev.steady.steady.dto.response.ParticipantsResponse; import dev.steady.steady.dto.response.SteadyDetailResponse; import dev.steady.steady.dto.response.SteadyQuestionsResponse; +import dev.steady.steady.dto.response.SteadyRankResponse; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.data.domain.Pageable; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; +import java.time.LocalDate; import java.util.List; import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; @@ -31,6 +35,7 @@ import static dev.steady.steady.fixture.SteadyFixturesV2.createSteadyPageResponse; import static dev.steady.steady.fixture.SteadyFixturesV2.createSteadyPosition; import static dev.steady.steady.fixture.SteadyFixturesV2.createSteadyQuestionsResponse; +import static dev.steady.steady.fixture.SteadyFixturesV2.createSteadyRankResponses; import static dev.steady.steady.fixture.SteadyFixturesV2.generateSteadyCreateRequest; import static dev.steady.steady.fixture.SteadyFixturesV2.generateSteadyUpdateRequest; import static dev.steady.user.fixture.UserFixturesV2.generatePositionEntity; @@ -148,6 +153,42 @@ void findMySteadiesTest() throws Exception { .andExpect(content().string(objectMapper.writeValueAsString(response))); } + @Test + @DisplayName("조건에 맞는 인기 게시물 리스트를 반환합니다.") + void findPopularStudyTest() throws Exception { + // given + var params = new RankParams(LocalDate.of(2023, 12, 31), 10, "ALL"); + + RankCondition condition = params.toCondition(); + List response = createSteadyRankResponses(); + given(steadyService.findPopularStudies(condition)).willReturn(response); + + // when & then + mockMvc.perform(get("/api/v1/steadies/rank") + .param("date", "2023-12-31") + .param("limit", "10") + .param("type", "ALL") + ) + .andDo(document("popular-steady", + queryParameters( + parameterWithName("date").description("기준 날짜 이후 생성 스테디"), + parameterWithName("limit").description("제한 10개 이하 가능"), + parameterWithName("type").description("ALL, STUDY, PROJECT") + ), + responseFields( + fieldWithPath("[].steadyId").type(NUMBER).description("스테디 식별자"), + fieldWithPath("[].title").type(STRING).description("스테디 제목"), + fieldWithPath("[].type").type(STRING).description("스테디 타입"), + fieldWithPath("[].status").type(STRING).description("스테디 상태"), + fieldWithPath("[].deadline").type(STRING).description("마감일"), + fieldWithPath("[].viewCount").type(NUMBER).description("조회수"), + fieldWithPath("[].likeCount").type(NUMBER).description("좋아요 수") + ) + )) + .andExpect(status().isOk()) + .andExpect(content().string(objectMapper.writeValueAsString(response))); + } + @Test @DisplayName("검색 조건에 따른 전체 조회 결과를 반환한다.") void getSteadiesByConditionTest() throws Exception {