Skip to content

Commit 3ca3072

Browse files
authored
[refactor/#396] 팔로워/팔로잉 조회 API isPublic 필드 추가 (#397)
* refactor: 팔로워/팔로잉 조회 API isPublic 필드 추가 * refactor: 테스트 통과 목적 FollowRepository 코드 수정
1 parent bd0ef06 commit 3ca3072

3 files changed

Lines changed: 74 additions & 29 deletions

File tree

clokey-api/src/main/java/org/clokey/domain/member/dto/response/FollowMemberResponse.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ public record FollowMemberResponse(
1010
description = "팔로잉 or 팔로워의 PofileImageUrl",
1111
example = "https://example.com/profile/john.jpg")
1212
String profileImageUrl,
13+
@Schema(description = "해당 멤버가 공개 계정인지?", example = "true") boolean isPublic,
1314
@Schema(description = "요청자가 이 멤버를 팔로우하고 있는가?", example = "true") boolean isFollowingMember,
1415
@Schema(description = "해당 멤버가 본인(요청자)인가?", example = "false") boolean isMe) {}

clokey-api/src/main/java/org/clokey/domain/member/repository/FollowRepositoryImpl.java

Lines changed: 63 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,19 @@
33
import static org.clokey.member.entity.QFollow.follow;
44
import static org.clokey.member.entity.QMember.member;
55

6-
import com.querydsl.core.types.Projections;
6+
import com.querydsl.core.Tuple;
7+
import com.querydsl.core.types.Expression;
78
import com.querydsl.core.types.dsl.BooleanExpression;
89
import com.querydsl.core.types.dsl.Expressions;
910
import com.querydsl.jpa.JPAExpressions;
1011
import com.querydsl.jpa.impl.JPAQueryFactory;
12+
import java.util.ArrayList;
1113
import java.util.List;
1214
import lombok.RequiredArgsConstructor;
1315
import org.clokey.domain.member.dto.response.FollowMemberResponse;
1416
import org.clokey.member.entity.QBlock;
1517
import org.clokey.member.entity.QFollow;
18+
import org.clokey.member.enums.Visibility;
1619
import org.springframework.data.domain.PageRequest;
1720
import org.springframework.data.domain.Slice;
1821
import org.springframework.data.domain.SliceImpl;
@@ -28,23 +31,25 @@ public class FollowRepositoryImpl implements FollowRepositoryCustom {
2831
public Slice<FollowMemberResponse> findAllFollowingsByMemberId(
2932
Long currentId, Long targetId, Long lastFollowId, Integer size) {
3033
QFollow followSub = new QFollow("followSub");
34+
BooleanExpression isFollowingExpression =
35+
JPAExpressions.selectOne()
36+
.from(followSub)
37+
.where(
38+
followSub.followFrom.id.eq(currentId),
39+
followSub.followTo.id.eq(member.id))
40+
.exists();
41+
BooleanExpression isMeExpression = member.id.eq(currentId);
3142

32-
List<FollowMemberResponse> results =
43+
List<Tuple> tuples =
3344
queryFactory
3445
.select(
35-
Projections.constructor(
36-
FollowMemberResponse.class,
37-
follow.id,
38-
member.id,
39-
member.nickname,
40-
member.profileImageUrl,
41-
JPAExpressions.selectOne()
42-
.from(followSub)
43-
.where(
44-
followSub.followFrom.id.eq(currentId),
45-
followSub.followTo.id.eq(member.id))
46-
.exists(),
47-
member.id.eq(currentId)))
46+
follow.id,
47+
member.id,
48+
member.nickname,
49+
member.profileImageUrl,
50+
member.visibility,
51+
isFollowingExpression,
52+
isMeExpression)
4853
.from(follow)
4954
.join(follow.followTo, member)
5055
.where(
@@ -55,30 +60,35 @@ public Slice<FollowMemberResponse> findAllFollowingsByMemberId(
5560
.orderBy(follow.id.desc())
5661
.fetch();
5762

63+
List<FollowMemberResponse> results =
64+
mapToFollowMemberResponses(tuples, isFollowingExpression, isMeExpression);
65+
5866
return checkLastPage(size, results);
5967
}
6068

6169
@Override
6270
public Slice<FollowMemberResponse> findAllFollowersByMemberId(
6371
Long currentId, Long targetId, Long lastFollowId, Integer size) {
6472
QFollow followSub = new QFollow("followSub");
73+
BooleanExpression isFollowingExpression =
74+
JPAExpressions.selectOne()
75+
.from(followSub)
76+
.where(
77+
followSub.followFrom.id.eq(currentId),
78+
followSub.followTo.id.eq(member.id))
79+
.exists();
80+
BooleanExpression isMeExpression = member.id.eq(currentId);
6581

66-
List<FollowMemberResponse> results =
82+
List<Tuple> tuples =
6783
queryFactory
6884
.select(
69-
Projections.constructor(
70-
FollowMemberResponse.class,
71-
follow.id,
72-
member.id,
73-
member.nickname,
74-
member.profileImageUrl,
75-
JPAExpressions.selectOne()
76-
.from(followSub)
77-
.where(
78-
followSub.followFrom.id.eq(currentId),
79-
followSub.followTo.id.eq(member.id))
80-
.exists(),
81-
member.id.eq(currentId)))
85+
follow.id,
86+
member.id,
87+
member.nickname,
88+
member.profileImageUrl,
89+
member.visibility,
90+
isFollowingExpression,
91+
isMeExpression)
8292
.from(follow)
8393
.join(follow.followFrom, member)
8494
.where(
@@ -89,9 +99,33 @@ public Slice<FollowMemberResponse> findAllFollowersByMemberId(
8999
.orderBy(follow.id.desc())
90100
.fetch();
91101

102+
List<FollowMemberResponse> results =
103+
mapToFollowMemberResponses(tuples, isFollowingExpression, isMeExpression);
104+
92105
return checkLastPage(size, results);
93106
}
94107

108+
private List<FollowMemberResponse> mapToFollowMemberResponses(
109+
List<Tuple> tuples,
110+
Expression<Boolean> isFollowingExpression,
111+
Expression<Boolean> isMeExpression) {
112+
List<FollowMemberResponse> responses = new ArrayList<>(tuples.size());
113+
114+
for (Tuple tuple : tuples) {
115+
responses.add(
116+
new FollowMemberResponse(
117+
tuple.get(follow.id),
118+
tuple.get(member.id),
119+
tuple.get(member.nickname),
120+
tuple.get(member.profileImageUrl),
121+
Visibility.PUBLIC.equals(tuple.get(member.visibility)),
122+
Boolean.TRUE.equals(tuple.get(isFollowingExpression)),
123+
Boolean.TRUE.equals(tuple.get(isMeExpression))));
124+
}
125+
126+
return responses;
127+
}
128+
95129
private BooleanExpression blockFilter(Long currentId) {
96130
QBlock blockCheck = new QBlock("blockCheck");
97131

clokey-api/src/test/java/org/clokey/domain/member/controller/MemberControllerTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,13 +544,15 @@ class 팔로잉_팔로워_목록_조회_요청_시 {
544544
2L,
545545
"nickname1",
546546
"https://img.example.com/bg.jpg",
547+
true,
547548
false,
548549
false),
549550
new FollowMemberResponse(
550551
1L,
551552
1L,
552553
"nickname2",
553554
"https://img.example2.com/bg.jpg",
555+
false,
554556
true,
555557
false));
556558

@@ -569,7 +571,9 @@ class 팔로잉_팔로워_목록_조회_요청_시 {
569571
.andExpect(jsonPath("$.code").value("COMMON200"))
570572
.andExpect(jsonPath("$.message").value("성공입니다."))
571573
.andExpect(jsonPath("$.result.content[0].followId").value(2L))
574+
.andExpect(jsonPath("$.result.content[0].isPublic").value(true))
572575
.andExpect(jsonPath("$.result.content[1].followId").value(1L))
576+
.andExpect(jsonPath("$.result.content[1].isPublic").value(false))
573577
.andExpect(jsonPath("$.result.isLast").value(true));
574578
}
575579

@@ -584,13 +588,15 @@ class 팔로잉_팔로워_목록_조회_요청_시 {
584588
"nickname2",
585589
"https://img.example.com/bg.jpg",
586590
false,
591+
false,
587592
false),
588593
new FollowMemberResponse(
589594
1L,
590595
1L,
591596
"nickname1",
592597
"https://img.example2.com/bg.jpg",
593598
true,
599+
true,
594600
true));
595601

596602
given(memberService.getFollows(1L, null, false, 5))
@@ -608,7 +614,9 @@ class 팔로잉_팔로워_목록_조회_요청_시 {
608614
.andExpect(jsonPath("$.code").value("COMMON200"))
609615
.andExpect(jsonPath("$.message").value("성공입니다."))
610616
.andExpect(jsonPath("$.result.content[0].followId").value(2L))
617+
.andExpect(jsonPath("$.result.content[0].isPublic").value(false))
611618
.andExpect(jsonPath("$.result.content[1].followId").value(1L))
619+
.andExpect(jsonPath("$.result.content[1].isPublic").value(true))
612620
.andExpect(jsonPath("$.result.isLast").value(true));
613621
}
614622

@@ -623,6 +631,7 @@ class 팔로잉_팔로워_목록_조회_요청_시 {
623631
"nickname1",
624632
"https://img.example.com/bg.jpg",
625633
true,
634+
true,
626635
false));
627636

628637
given(memberService.getFollows(1L, null, true, 1))
@@ -641,6 +650,7 @@ class 팔로잉_팔로워_목록_조회_요청_시 {
641650
.andExpect(jsonPath("$.code").value("COMMON200"))
642651
.andExpect(jsonPath("$.message").value("성공입니다."))
643652
.andExpect(jsonPath("$.result.content[0].followId").value(2L))
653+
.andExpect(jsonPath("$.result.content[0].isPublic").value(true))
644654
.andExpect(jsonPath("$.result.isLast").value(false));
645655
}
646656

0 commit comments

Comments
 (0)