Skip to content

Commit

Permalink
[Refactor] 챌린지 함께 기록(친구) 페이지네이션 조회 API (#246)
Browse files Browse the repository at this point in the history
* [Refactor] 챌린지 함께하기(친구) 페이지네이션 조회 API

* [Refactor] 챌린지 함께하기(친구) 페이지네이션 문서화용 테스트 변경사항 반영

* [Fix] 네이밍 수정

* [Refactor] Friends로 네이밍 변경
  • Loading branch information
heoboseong7 authored Mar 12, 2023
1 parent b088384 commit 5c28358
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Component
Expand Down Expand Up @@ -164,13 +163,14 @@ public FinishedChallengeCountResponse toFinishedChallengeCountResponse(Long coun
return FinishedChallengeCountResponse.of(count);
}

public TogetherChallengerResponse toTogetherChallengerResponse(ChallengeParticipation participation, Long current) {
public FriendResponse toFriendResponse(ChallengeParticipation participation, Long current, boolean isFollowing) {
User challenger = participation.getChallenger();
return TogetherChallengerResponse.of(
return FriendResponse.of(
challenger.getNickname(),
challenger.getProfilePhotoURL(),
current,
participation.getTotalInsightNumber());
participation.getTotalInsightNumber(),
isFollowing);
}

public ChallengerCountResponse toChallengerCountResponse(Long countParticipatingUser) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import ccc.keewecore.consts.KeeweConsts;
import ccc.keewedomain.persistence.repository.utils.CursorPageable;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

Expand Down Expand Up @@ -48,9 +50,11 @@ public ApiResponse<WeekProgressResponse> getMyThisWeekProgress() {
return ApiResponse.ok(challengeApiService.getWeekProgress());
}

@GetMapping("/{challengeId}/challengers")
public ApiResponse<List<TogetherChallengerResponse>> getTogetherChallengers(@PathVariable Long challengeId) {
return ApiResponse.ok(challengeApiService.getTogetherChallengers(challengeId));
@GetMapping("/{challengeId}/friends")
public ApiResponse<List<FriendResponse>> paginateFriends(
@PathVariable Long challengeId,
@PageableDefault(page = 0, size = 10) Pageable pageable) {
return ApiResponse.ok(challengeApiService.paginateFriends(challengeId, pageable));
}

@GetMapping("/{challengeId}/challengers/count")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@

@Getter
@AllArgsConstructor(staticName = "of")
public class TogetherChallengerResponse {
public class FriendResponse {
private String nickname;
private String imageURL;
private long currentRecord;
private long goalRecord;
private boolean isFollowing;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import ccc.keeweapi.dto.challenge.ParticipatingChallengeDetailResponse;
import ccc.keeweapi.dto.challenge.ParticipatingChallengeResponse;
import ccc.keeweapi.dto.challenge.ParticipationCheckResponse;
import ccc.keeweapi.dto.challenge.TogetherChallengerResponse;
import ccc.keeweapi.dto.challenge.FriendResponse;
import ccc.keeweapi.dto.challenge.WeekProgressResponse;
import ccc.keeweapi.utils.SecurityUtil;
import ccc.keewecore.consts.KeeweRtnConsts;
Expand All @@ -24,15 +24,20 @@
import ccc.keewedomain.service.challenge.command.ChallengeCommandDomainService;
import ccc.keewedomain.service.challenge.query.ChallengeParticipateQueryDomainService;
import ccc.keewedomain.service.challenge.query.ChallengeQueryDomainService;
import ccc.keewedomain.service.user.ProfileDomainService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import ccc.keewedomain.service.insight.query.InsightQueryDomainService;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


@Service
Expand All @@ -44,6 +49,7 @@ public class ChallengeApiService {
private final ChallengeQueryDomainService challengeQueryDomainService;
private final ChallengeCommandDomainService challengeCommandDomainService;
private final InsightQueryDomainService insightQueryDomainService;
private final ProfileDomainService profileDomainService;
private final ChallengeAssembler challengeAssembler;

@Transactional
Expand Down Expand Up @@ -133,16 +139,23 @@ private List<String> datesOfWeek(LocalDate startDate) {
}

@Transactional(readOnly = true)
public List<TogetherChallengerResponse> getTogetherChallengers(Long challengeId) {
public List<FriendResponse> paginateFriends(Long challengeId, Pageable pageable) {
User user = SecurityUtil.getUser();
Challenge challenge = challengeQueryDomainService.getByIdOrElseThrow(challengeId);
List<ChallengeParticipation> participations = challengeParticipateQueryDomainService.findTogetherChallengeParticipations(challenge, user);
List<ChallengeParticipation> participations = challengeParticipateQueryDomainService.findFriendsParticipations(challenge, user, pageable);
if(participations.isEmpty()) {
return Collections.emptyList();
}

List<User> challengers = participations.stream().map(ChallengeParticipation::getChallenger).collect(Collectors.toList());
Set<Long> followingIdSet = profileDomainService.getFollowingTargetIdSet(SecurityUtil.getUser(), challengers);
Map<Long, Long> insightCountPerParticipation = insightQueryDomainService.getInsightCountPerParticipation(participations);

return participations.stream()
.map(participation -> challengeAssembler.toTogetherChallengerResponse(
.map(participation -> challengeAssembler.toFriendResponse(
participation,
insightCountPerParticipation.getOrDefault(participation.getId(), 0L))
insightCountPerParticipation.getOrDefault(participation.getId(), 0L),
followingIdSet.contains(participation.getChallenger().getId()))
)
.collect(Collectors.toList());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,26 +241,32 @@ void home_my_challenge() throws Exception {
@Test
@DisplayName("챌린지 상세 함께 기록 조회 API")
void get_together() throws Exception {
List<TogetherChallengerResponse> response = List.of(
TogetherChallengerResponse.of("닉네임1", "이미지 URL1", 1L, 4L),
TogetherChallengerResponse.of("닉네임2", "이미지 URL2", 2L, 4L),
TogetherChallengerResponse.of("닉네임3", "이미지 URL3", 3L, 4L)
List<FriendResponse> response = List.of(
FriendResponse.of("닉네임1", "이미지 URL1", 1L, 4L, true),
FriendResponse.of("닉네임2", "이미지 URL2", 2L, 4L, false),
FriendResponse.of("닉네임3", "이미지 URL3", 3L, 4L, false)
);

when(challengeApiService.getTogetherChallengers(anyLong())).thenReturn(response);
when(challengeApiService.paginateFriends(anyLong(), any())).thenReturn(response);

ResultActions resultActions = mockMvc.perform(get("/api/v1/challenge/{challengeId}/challengers", 1L)
ResultActions resultActions = mockMvc.perform(get("/api/v1/challenge/{challengeId}/friends", 1L)
.header(HttpHeaders.AUTHORIZATION, "Bearer " + JWT)
.param("page", "0")
.param("size", "10")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());

resultActions.andDo(restDocs.document(resource(
ResourceSnippetParameters.builder()
.description("챌린지 상세 함께 기록 조회 API 입니다.")
.summary("챌린지 상세 함께 기록 조회 API")
.description("함께 기록(친구) 조회 API 입니다.")
.summary("함께 기록(친구) 조회 API")
.requestHeaders(
headerWithName("Authorization").description("유저의 JWT")
)
.requestParameters(
parameterWithName("page").description("페이지 번호. 미 입력시 기본 0").optional(),
parameterWithName("size").description("페이지 당 결과 개수. 미 입력시 기본 10").optional()
)
.pathParameters(parameterWithName("challengeId").description("챌린지의 ID"))
.responseFields(
fieldWithPath("message").description("요청 결과 메세지"),
Expand All @@ -269,7 +275,8 @@ void get_together() throws Exception {
fieldWithPath("data[].nickname").description("참가자의 닉네임"),
fieldWithPath("data[].imageURL").description("참가자의 프로필 이미지 URL"),
fieldWithPath("data[].currentRecord").description("현재 기록한 개수"),
fieldWithPath("data[].goalRecord").description("전체 기록해야 하는 개수")
fieldWithPath("data[].goalRecord").description("전체 기록해야 하는 개수"),
fieldWithPath("data[].following").description("팔로우 여부")
)
.tag("ChallengeParticipation")
.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.context.annotation.Import;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
import org.springframework.restdocs.RestDocumentationContextProvider;
import org.springframework.restdocs.RestDocumentationExtension;
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
Expand Down Expand Up @@ -39,6 +40,7 @@ static void restDocSetup() {
public void setup(Object controller, RestDocumentationContextProvider provider) {
mockMvc = MockMvcBuilders.standaloneSetup(controller)
.apply(MockMvcRestDocumentation.documentationConfiguration(provider))
.setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver())
.alwaysDo(print())
.alwaysDo(restDocs)
.addFilters(new CharacterEncodingFilter("UTF-8", true))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
Expand Down Expand Up @@ -86,8 +87,7 @@ public List<ChallengeParticipation> findFinishedParticipation(User challenger, L
.fetch();
}


public List<ChallengeParticipation> findFollowingChallengerParticipations(Challenge targetChallenge, User targetUser) {
public List<ChallengeParticipation> findByChallengeOrderByFollowing(Challenge targetChallenge, User targetUser, Pageable pageable) {
return queryFactory.select(challengeParticipation)
.from(challengeParticipation)
.innerJoin(challengeParticipation.challenger, user)
Expand All @@ -98,7 +98,8 @@ public List<ChallengeParticipation> findFollowingChallengerParticipations(Challe
.where(follow.follower.eq(targetUser).or(follow.follower.isNull()))
.orderBy(follow.follower.id.asc().nullsLast())
.orderBy(challengeParticipation.createdAt.asc())
.limit(5)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand Down Expand Up @@ -60,8 +61,8 @@ public Long countFinishedParticipation(User user) {
}

@Transactional(readOnly = true)
public List<ChallengeParticipation> findTogetherChallengeParticipations(Challenge challenge, User user) {
return challengeParticipationQueryRepository.findFollowingChallengerParticipations(challenge, user);
public List<ChallengeParticipation> findFriendsParticipations(Challenge challenge, User user, Pageable pageable) {
return challengeParticipationQueryRepository.findByChallengeOrderByFollowing(challenge, user, pageable);
}

public List<ChallengeParticipation> getFinishedParticipation(User user, Long size) {
Expand Down

0 comments on commit 5c28358

Please sign in to comment.