From 122c2dcdb04dfdd7cb0c21de5c30a4721f3f4298 Mon Sep 17 00:00:00 2001 From: pparkjs Date: Sat, 19 Oct 2024 14:56:26 +0900 Subject: [PATCH 1/5] =?UTF-8?q?=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=B6=94?= =?UTF-8?q?=EC=B2=9C=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EC=A0=95=EC=B1=85=20=EB=B3=80=EA=B2=BD=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B9=84=ED=9A=8C=EC=9B=90=EB=8F=84=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=9E=90=20=EC=B6=94=EC=B2=9C=20=EB=82=98=ED=83=80=EB=82=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20API=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...sponse.java => UsersRecommendedResponse.java} | 6 +++--- .../user/application/service/UserService.java | 16 +++++++++++----- .../user/presentation/UserController.java | 10 +++++----- .../custom/impl/CustomUserRepositoryImpl.java | 12 ++++++++++-- 4 files changed, 29 insertions(+), 15 deletions(-) rename src/main/java/com/listywave/user/application/dto/{RecommendUsersResponse.java => UsersRecommendedResponse.java} (71%) diff --git a/src/main/java/com/listywave/user/application/dto/RecommendUsersResponse.java b/src/main/java/com/listywave/user/application/dto/UsersRecommendedResponse.java similarity index 71% rename from src/main/java/com/listywave/user/application/dto/RecommendUsersResponse.java rename to src/main/java/com/listywave/user/application/dto/UsersRecommendedResponse.java index 259ac0f3..340853db 100644 --- a/src/main/java/com/listywave/user/application/dto/RecommendUsersResponse.java +++ b/src/main/java/com/listywave/user/application/dto/UsersRecommendedResponse.java @@ -4,14 +4,14 @@ import lombok.Builder; @Builder -public record RecommendUsersResponse( +public record UsersRecommendedResponse( Long id, String nickname, String profileImageUrl ) { - public static RecommendUsersResponse of(User user) { - return RecommendUsersResponse.builder() + public static UsersRecommendedResponse of(User user) { + return UsersRecommendedResponse.builder() .id(user.getId()) .nickname(user.getNickname()) .profileImageUrl(user.getProfileImageUrl()) diff --git a/src/main/java/com/listywave/user/application/service/UserService.java b/src/main/java/com/listywave/user/application/service/UserService.java index 41f60da7..2367562b 100644 --- a/src/main/java/com/listywave/user/application/service/UserService.java +++ b/src/main/java/com/listywave/user/application/service/UserService.java @@ -11,7 +11,7 @@ import com.listywave.user.application.domain.User; import com.listywave.user.application.dto.FollowersResponse; import com.listywave.user.application.dto.FollowingsResponse; -import com.listywave.user.application.dto.RecommendUsersResponse; +import com.listywave.user.application.dto.UsersRecommendedResponse; import com.listywave.user.application.dto.UserInfoResponse; import com.listywave.user.application.dto.UserProflieUpdateCommand; import com.listywave.user.application.dto.search.UserElasticSearchResponse; @@ -121,18 +121,24 @@ public FollowersResponse getFollowers(Long userId, Pageable pageable, String sea } @Transactional(readOnly = true) - public List getRecommendUsers(Long loginUserId) { + public List getRecommendedUsers(Long loginUserId) { + if(loginUserId == null){ + List recommendUsers = userRepository.getRecommendUsers(List.of(), null); + return toUsersRecommendedResponse(recommendUsers); + } User user = userRepository.getById(loginUserId); List follows = followRepository.getAllByFollowerUser(user); - List myFollowingUsers = follows.stream() .map(Follow::getFollowingUser) .filter(followingUser -> !followingUser.isDelete()) .toList(); - List recommendUsers = userRepository.getRecommendUsers(myFollowingUsers, user); + return toUsersRecommendedResponse(recommendUsers); + } + + private List toUsersRecommendedResponse(List recommendUsers) { return recommendUsers.stream() - .map(RecommendUsersResponse::of) + .map(UsersRecommendedResponse::of) .toList(); } diff --git a/src/main/java/com/listywave/user/presentation/UserController.java b/src/main/java/com/listywave/user/presentation/UserController.java index 41d285f0..526ccf77 100644 --- a/src/main/java/com/listywave/user/presentation/UserController.java +++ b/src/main/java/com/listywave/user/presentation/UserController.java @@ -4,7 +4,7 @@ import com.listywave.common.auth.OptionalAuth; import com.listywave.user.application.dto.FollowersResponse; import com.listywave.user.application.dto.FollowingsResponse; -import com.listywave.user.application.dto.RecommendUsersResponse; +import com.listywave.user.application.dto.UsersRecommendedResponse; import com.listywave.user.application.dto.UserInfoResponse; import com.listywave.user.application.dto.search.UserElasticSearchResponse; import com.listywave.user.application.dto.search.UserSearchResponse; @@ -87,11 +87,11 @@ ResponseEntity unfollow( return ResponseEntity.noContent().build(); } - @GetMapping("/users/recommend") - ResponseEntity> getRecommendUsers( - @Auth Long loginUserId + @GetMapping("/users/recommended") + ResponseEntity> getRecommendedUsers( + @OptionalAuth Long loginUserId ) { - List recommendUsers = userService.getRecommendUsers(loginUserId); + List recommendUsers = userService.getRecommendedUsers(loginUserId); return ResponseEntity.ok(recommendUsers); } diff --git a/src/main/java/com/listywave/user/repository/user/custom/impl/CustomUserRepositoryImpl.java b/src/main/java/com/listywave/user/repository/user/custom/impl/CustomUserRepositoryImpl.java index 8d902948..5b7a7bf6 100644 --- a/src/main/java/com/listywave/user/repository/user/custom/impl/CustomUserRepositoryImpl.java +++ b/src/main/java/com/listywave/user/repository/user/custom/impl/CustomUserRepositoryImpl.java @@ -33,8 +33,8 @@ public List getRecommendUsers(List myFollowingUsers, User me) { .from(listEntity) .rightJoin(listEntity.user, user) .where( - user.id.ne(me.getId()), - user.id.notIn(myFollowingUserIds), + userIdNe(me), + userIdNotIn(myFollowingUserIds), user.isDelete.isFalse() ) .groupBy(user) @@ -43,6 +43,14 @@ public List getRecommendUsers(List myFollowingUsers, User me) { .fetch(); } + private BooleanExpression userIdNotIn(List myFollowingUserIds) { + return myFollowingUserIds.isEmpty() ? null : user.id.notIn(myFollowingUserIds); + } + + private BooleanExpression userIdNe(User me) { + return me == null ? null : user.id.ne(me.getId()); + } + @Override public Long countBySearch(String search, Long loginUserId) { if (search.isEmpty()) { From a108181bd7598e9a7b6b942fa34e39ea9c707e06 Mon Sep 17 00:00:00 2001 From: pparkjs Date: Sat, 19 Oct 2024 14:57:08 +0900 Subject: [PATCH 2/5] =?UTF-8?q?test:=20=EB=B9=84=ED=9A=8C=EC=9B=90?= =?UTF-8?q?=EB=8F=84=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=B6=94=EC=B2=9C=20?= =?UTF-8?q?=EB=82=98=ED=83=80=EB=82=98=EB=8F=84=EB=A1=9D=20API=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=ED=95=98=EC=97=AC=20=EC=9D=B8=EC=88=98=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BC=80=EC=9D=B4=EC=8A=A4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../acceptance/user/UserAcceptanceTest.java | 19 +++++++++++++++++-- .../user/UserAcceptanceTestHelper.java | 11 +++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/listywave/acceptance/user/UserAcceptanceTest.java b/src/test/java/com/listywave/acceptance/user/UserAcceptanceTest.java index b3acbb74..d8240ee9 100644 --- a/src/test/java/com/listywave/acceptance/user/UserAcceptanceTest.java +++ b/src/test/java/com/listywave/acceptance/user/UserAcceptanceTest.java @@ -11,7 +11,7 @@ import static org.springframework.http.HttpStatus.*; import com.listywave.acceptance.common.AcceptanceTest; -import com.listywave.user.application.dto.RecommendUsersResponse; +import com.listywave.user.application.dto.UsersRecommendedResponse; import com.listywave.user.application.dto.UserInfoResponse; import com.listywave.user.application.dto.search.UserSearchResponse; import io.restassured.common.mapper.TypeRef; @@ -148,7 +148,7 @@ class 회원_검색 { var 동호_액세스_토큰 = 액세스_토큰을_발급한다(동호); // when - List 결과 = 추천_사용자_조회(동호_액세스_토큰).as(new TypeRef<>() { + List 결과 = 회원_추천_사용자_조회_API_요청(동호_액세스_토큰).as(new TypeRef<>() { }); // then @@ -156,6 +156,21 @@ class 회원_검색 { assertThat(결과.get(0).nickname()).isEqualTo(유진.getNickname()); } + @Test + void 비회원이_추천_사용자_조회한다() { + // given + 회원을_저장한다(동호()); + 회원을_저장한다(정수()); + 회원을_저장한다(유진()); + + // when + List 결과 = 비회원_추천_사용자_조회_API_요청().as(new TypeRef<>() { + }); + + // then + assertThat(결과).hasSize(3); + } + @Nested class 프로필_수정 { diff --git a/src/test/java/com/listywave/acceptance/user/UserAcceptanceTestHelper.java b/src/test/java/com/listywave/acceptance/user/UserAcceptanceTestHelper.java index 946c3f80..ce88d859 100644 --- a/src/test/java/com/listywave/acceptance/user/UserAcceptanceTestHelper.java +++ b/src/test/java/com/listywave/acceptance/user/UserAcceptanceTestHelper.java @@ -58,10 +58,17 @@ public abstract class UserAcceptanceTestHelper { .extract(); } - public static ExtractableResponse 추천_사용자_조회(String accessToken) { + public static ExtractableResponse 회원_추천_사용자_조회_API_요청(String accessToken) { return given() .header(AUTHORIZATION, "Bearer " + accessToken) - .when().get("/users/recommend") + .when().get("/users/recommended") + .then().log().all() + .extract(); + } + + public static ExtractableResponse 비회원_추천_사용자_조회_API_요청() { + return given() + .when().get("/users/recommended") .then().log().all() .extract(); } From 3f53702ba1d9d43cfede13982b2fd7ea60f015be Mon Sep 17 00:00:00 2001 From: pparkjs Date: Wed, 23 Oct 2024 16:15:11 +0900 Subject: [PATCH 3/5] =?UTF-8?q?refactor:=20=EC=BD=94=EB=93=9C=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=EB=A5=BC=20=ED=86=B5=ED=95=9C=20=EB=84=A4=EC=9D=B4?= =?UTF-8?q?=EB=B0=8D=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BC=80=EC=9D=B4=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/presentation/UserController.java | 13 +-- .../custom/impl/CustomUserRepositoryImpl.java | 6 +- .../acceptance/user/UserAcceptanceTest.java | 105 ++++++++++++------ .../user/UserAcceptanceTestHelper.java | 9 +- 4 files changed, 81 insertions(+), 52 deletions(-) diff --git a/src/main/java/com/listywave/user/presentation/UserController.java b/src/main/java/com/listywave/user/presentation/UserController.java index 526ccf77..f5dd6989 100644 --- a/src/main/java/com/listywave/user/presentation/UserController.java +++ b/src/main/java/com/listywave/user/presentation/UserController.java @@ -4,8 +4,8 @@ import com.listywave.common.auth.OptionalAuth; import com.listywave.user.application.dto.FollowersResponse; import com.listywave.user.application.dto.FollowingsResponse; -import com.listywave.user.application.dto.UsersRecommendedResponse; import com.listywave.user.application.dto.UserInfoResponse; +import com.listywave.user.application.dto.UsersRecommendedResponse; import com.listywave.user.application.dto.search.UserElasticSearchResponse; import com.listywave.user.application.dto.search.UserSearchResponse; import com.listywave.user.application.service.UserService; @@ -15,14 +15,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.web.PageableDefault; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PatchMapping; -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.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RestController @RequiredArgsConstructor @@ -87,7 +80,7 @@ ResponseEntity unfollow( return ResponseEntity.noContent().build(); } - @GetMapping("/users/recommended") + @GetMapping("/users/recommend") ResponseEntity> getRecommendedUsers( @OptionalAuth Long loginUserId ) { diff --git a/src/main/java/com/listywave/user/repository/user/custom/impl/CustomUserRepositoryImpl.java b/src/main/java/com/listywave/user/repository/user/custom/impl/CustomUserRepositoryImpl.java index 5b7a7bf6..b40e13f4 100644 --- a/src/main/java/com/listywave/user/repository/user/custom/impl/CustomUserRepositoryImpl.java +++ b/src/main/java/com/listywave/user/repository/user/custom/impl/CustomUserRepositoryImpl.java @@ -33,7 +33,7 @@ public List getRecommendUsers(List myFollowingUsers, User me) { .from(listEntity) .rightJoin(listEntity.user, user) .where( - userIdNe(me), + userIdNotEqual(me), userIdNotIn(myFollowingUserIds), user.isDelete.isFalse() ) @@ -44,10 +44,10 @@ public List getRecommendUsers(List myFollowingUsers, User me) { } private BooleanExpression userIdNotIn(List myFollowingUserIds) { - return myFollowingUserIds.isEmpty() ? null : user.id.notIn(myFollowingUserIds); + return myFollowingUserIds.isEmpty() ? null : user.id.notIn(myFollowingUserIds); } - private BooleanExpression userIdNe(User me) { + private BooleanExpression userIdNotEqual(User me) { return me == null ? null : user.id.ne(me.getId()); } diff --git a/src/test/java/com/listywave/acceptance/user/UserAcceptanceTest.java b/src/test/java/com/listywave/acceptance/user/UserAcceptanceTest.java index d8240ee9..ba436c5b 100644 --- a/src/test/java/com/listywave/acceptance/user/UserAcceptanceTest.java +++ b/src/test/java/com/listywave/acceptance/user/UserAcceptanceTest.java @@ -2,17 +2,17 @@ import static com.listywave.acceptance.common.CommonAcceptanceHelper.HTTP_상태_코드를_검증한다; import static com.listywave.acceptance.follow.FollowAcceptanceTestHelper.팔로우_요청_API; +import static com.listywave.acceptance.list.ListAcceptanceTestHelper.*; import static com.listywave.acceptance.user.UserAcceptanceTestHelper.*; -import static com.listywave.user.fixture.UserFixture.동호; -import static com.listywave.user.fixture.UserFixture.유진; -import static com.listywave.user.fixture.UserFixture.정수; +import static com.listywave.user.fixture.UserFixture.*; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; import static org.springframework.http.HttpStatus.*; import com.listywave.acceptance.common.AcceptanceTest; -import com.listywave.user.application.dto.UsersRecommendedResponse; +import com.listywave.list.application.dto.response.ListCreateResponse; import com.listywave.user.application.dto.UserInfoResponse; +import com.listywave.user.application.dto.UsersRecommendedResponse; import com.listywave.user.application.dto.search.UserSearchResponse; import io.restassured.common.mapper.TypeRef; import java.util.List; @@ -138,37 +138,74 @@ class 회원_검색 { ; } - @Test - void 회원이_추천_사용자_조회한다_추천_사용자는_팔로잉하지_않는_유저여야한다() { - // given - var 동호 = 회원을_저장한다(동호()); - var 정수 = 회원을_저장한다(정수()); - var 유진 = 회원을_저장한다(유진()); - 팔로우_요청_API(액세스_토큰을_발급한다(동호), 정수.getId()); - var 동호_액세스_토큰 = 액세스_토큰을_발급한다(동호); - - // when - List 결과 = 회원_추천_사용자_조회_API_요청(동호_액세스_토큰).as(new TypeRef<>() { - }); - - // then - assertThat(결과).hasSize(1); - assertThat(결과.get(0).nickname()).isEqualTo(유진.getNickname()); - } + @Nested + class 추천_사용자 { - @Test - void 비회원이_추천_사용자_조회한다() { - // given - 회원을_저장한다(동호()); - 회원을_저장한다(정수()); - 회원을_저장한다(유진()); - - // when - List 결과 = 비회원_추천_사용자_조회_API_요청().as(new TypeRef<>() { - }); - - // then - assertThat(결과).hasSize(3); + @Test + void 회원이_추천_사용자_조회한다_추천_사용자는_팔로잉하지_않는_유저여야한다() { + // given + var 동호 = 회원을_저장한다(동호()); + var 정수 = 회원을_저장한다(정수()); + var 유진 = 회원을_저장한다(유진()); + 팔로우_요청_API(액세스_토큰을_발급한다(동호), 정수.getId()); + var 동호_액세스_토큰 = 액세스_토큰을_발급한다(동호); + + // when + List 결과 = 회원_추천_API(동호_액세스_토큰).as(new TypeRef<>() { + }); + + // then + assertThat(결과).hasSize(1); + assertThat(결과.get(0).nickname()).isEqualTo(유진.getNickname()); + } + + @Test + void 비회원이_추천_사용자_조회한다() { + // given + 회원을_저장한다(동호()); + 회원을_저장한다(정수()); + 회원을_저장한다(유진()); + + // when + List 결과 = 비회원_추천_API().as(new TypeRef<>() { + }); + + // then + assertThat(결과).hasSize(3); + } + + @Test + void 가장_최근에_리스트_생성_또는_수정한_사용자_순위대로_추천_사용자_조회한다() { + // given + var 동호 = 회원을_저장한다(동호()); + var 정수 = 회원을_저장한다(정수()); + var 유진 = 회원을_저장한다(유진()); + var 동호_액세스_토큰 = 액세스_토큰을_발급한다(동호); + var 정수_액세스_토큰 = 액세스_토큰을_발급한다(정수); + var 유진_액세스_토큰 = 액세스_토큰을_발급한다(유진); + + var 리스트_생성_요청_데이터 = 가장_좋아하는_견종_TOP3_생성_요청_데이터(List.of()); + var 동호_리스트_ID = 리스트_저장_API_호출(리스트_생성_요청_데이터, 동호_액세스_토큰) + .as(ListCreateResponse.class) + .listId(); + 리스트_저장_API_호출(리스트_생성_요청_데이터, 정수_액세스_토큰); + 리스트_저장_API_호출(리스트_생성_요청_데이터, 유진_액세스_토큰); + + var 리스트_수정_요청_데이터 = 아이템_순위와_라벨을_바꾼_좋아하는_견종_TOP3_요청_데이터(List.of(유진.getId())); + 리스트_수정_API_호출(리스트_수정_요청_데이터, 동호_액세스_토큰, 동호_리스트_ID); + + // when + List 결과 = 비회원_추천_API().as(new TypeRef<>() { + }); + + // then + assertAll( + () -> assertThat(결과).hasSize(3), + () -> assertThat(결과.get(0).nickname()).isEqualTo(동호.getNickname()), + () -> assertThat(결과.get(1).nickname()).isEqualTo(유진.getNickname()), + () -> assertThat(결과.get(2).nickname()).isEqualTo(정수.getNickname()) + ); + } } @Nested diff --git a/src/test/java/com/listywave/acceptance/user/UserAcceptanceTestHelper.java b/src/test/java/com/listywave/acceptance/user/UserAcceptanceTestHelper.java index ce88d859..856f3cbc 100644 --- a/src/test/java/com/listywave/acceptance/user/UserAcceptanceTestHelper.java +++ b/src/test/java/com/listywave/acceptance/user/UserAcceptanceTestHelper.java @@ -3,7 +3,6 @@ import static com.listywave.acceptance.common.CommonAcceptanceHelper.given; import static org.springframework.http.HttpHeaders.AUTHORIZATION; -import com.listywave.user.presentation.dto.ListVisibilityUpdateRequest; import com.listywave.user.presentation.dto.UserProfileUpdateRequest; import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; @@ -58,17 +57,17 @@ public abstract class UserAcceptanceTestHelper { .extract(); } - public static ExtractableResponse 회원_추천_사용자_조회_API_요청(String accessToken) { + public static ExtractableResponse 회원_추천_API(String accessToken) { return given() .header(AUTHORIZATION, "Bearer " + accessToken) - .when().get("/users/recommended") + .when().get("/users/recommend") .then().log().all() .extract(); } - public static ExtractableResponse 비회원_추천_사용자_조회_API_요청() { + public static ExtractableResponse 비회원_추천_API() { return given() - .when().get("/users/recommended") + .when().get("/users/recommend") .then().log().all() .extract(); } From 3de5741bb3ae31ca1578cf8cff1d9567762e4662 Mon Sep 17 00:00:00 2001 From: pparkjs Date: Fri, 25 Oct 2024 20:04:39 +0900 Subject: [PATCH 4/5] =?UTF-8?q?=EB=82=98=EC=9D=98=20=EC=BD=9C=EB=A0=89?= =?UTF-8?q?=EC=85=98=20=EC=A1=B0=ED=9A=8C=20=EC=9D=91=EB=8B=B5=EC=97=90=20?= =?UTF-8?q?=ED=8F=B4=EB=8D=94=20=EC=9D=B4=EB=A6=84=EB=8F=84=20=EC=9D=91?= =?UTF-8?q?=EB=8B=B5=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/dto/CollectionResponse.java | 12 +++++++++--- .../application/service/CollectionService.java | 4 ++-- .../custom/impl/CustomCollectionRepositoryImpl.java | 1 - 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/listywave/collection/application/dto/CollectionResponse.java b/src/main/java/com/listywave/collection/application/dto/CollectionResponse.java index 4588ff72..3e55e35d 100644 --- a/src/main/java/com/listywave/collection/application/dto/CollectionResponse.java +++ b/src/main/java/com/listywave/collection/application/dto/CollectionResponse.java @@ -10,11 +10,17 @@ public record CollectionResponse( Long cursorId, Boolean hasNext, - List collectionLists + List collectionLists, + String folderName ) { - public static CollectionResponse of(Long cursorId, Boolean hasNext, List collects) { - return new CollectionResponse(cursorId, hasNext, toList(collects)); + public static CollectionResponse of( + Long cursorId, + Boolean hasNext, + List collects, + String folderName + ) { + return new CollectionResponse(cursorId, hasNext, toList(collects), folderName); } public static List toList(List collects) { diff --git a/src/main/java/com/listywave/collection/application/service/CollectionService.java b/src/main/java/com/listywave/collection/application/service/CollectionService.java index cb2fba37..a2ea3389 100644 --- a/src/main/java/com/listywave/collection/application/service/CollectionService.java +++ b/src/main/java/com/listywave/collection/application/service/CollectionService.java @@ -62,7 +62,7 @@ private void addCollect(ListEntity list, User user, Folder folder) { public CollectionResponse getCollection(Long loginUserId, Long cursorId, Pageable pageable, Long folderId) { User user = userRepository.getById(loginUserId); - folderRepository.getById(folderId); + Folder folder = folderRepository.getById(folderId); Slice result = collectionRepository.getAllCollectionList(cursorId, pageable, user.getId(), folderId); List collectionList = result.getContent(); @@ -70,7 +70,7 @@ public CollectionResponse getCollection(Long loginUserId, Long cursorId, Pageabl if (!collectionList.isEmpty()) { cursorId = collectionList.get(collectionList.size() - 1).getId(); } - return CollectionResponse.of(cursorId, result.hasNext(), collectionList); + return CollectionResponse.of(cursorId, result.hasNext(), collectionList, folder.getFolderName()); } public List getCategoriesOfCollection(Long loginUserId) { diff --git a/src/main/java/com/listywave/collection/repository/custom/impl/CustomCollectionRepositoryImpl.java b/src/main/java/com/listywave/collection/repository/custom/impl/CustomCollectionRepositoryImpl.java index c2d4d864..ad5289c0 100644 --- a/src/main/java/com/listywave/collection/repository/custom/impl/CustomCollectionRepositoryImpl.java +++ b/src/main/java/com/listywave/collection/repository/custom/impl/CustomCollectionRepositoryImpl.java @@ -2,7 +2,6 @@ import static com.listywave.collection.application.domain.QCollect.collect; import static com.listywave.common.util.PaginationUtils.checkEndPage; -import static com.listywave.list.application.domain.category.CategoryType.ENTIRE; import static com.listywave.list.application.domain.item.QItem.item; import static com.listywave.list.application.domain.list.QListEntity.listEntity; import static com.listywave.user.application.domain.QUser.user; From 9b6bd6c0d99c77952e01ab6a21d62912d94a5b04 Mon Sep 17 00:00:00 2001 From: pparkjs Date: Sun, 27 Oct 2024 20:26:25 +0900 Subject: [PATCH 5/5] =?UTF-8?q?refactor:=20=EC=A0=84=EC=B2=B4=20=ED=8F=B4?= =?UTF-8?q?=EB=8D=94=EC=97=90=20=EB=8C=80=ED=95=9C=20=EC=BD=9C=EB=A0=89?= =?UTF-8?q?=EC=85=98=20=EC=A1=B0=ED=9A=8C=20=EC=B6=94=EA=B0=80=20=EB=B0=8F?= =?UTF-8?q?=20=EC=BD=94=EB=93=9C=EB=A6=AC=EB=B7=B0=EC=97=90=20=EC=9D=98?= =?UTF-8?q?=ED=95=9C=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ponse.java => CollectionFindResponse.java} | 42 ++++++------- .../service/CollectionService.java | 16 +++-- .../controller/CollectionController.java | 16 +++-- .../impl/CustomCollectionRepositoryImpl.java | 4 +- .../collection/CollectionAcceptanceTest.java | 63 ++++++++++++++----- .../acceptance/user/UserAcceptanceTest.java | 38 +++++------ 6 files changed, 111 insertions(+), 68 deletions(-) rename src/main/java/com/listywave/collection/application/dto/{CollectionResponse.java => CollectionFindResponse.java} (64%) diff --git a/src/main/java/com/listywave/collection/application/dto/CollectionResponse.java b/src/main/java/com/listywave/collection/application/dto/CollectionFindResponse.java similarity index 64% rename from src/main/java/com/listywave/collection/application/dto/CollectionResponse.java rename to src/main/java/com/listywave/collection/application/dto/CollectionFindResponse.java index 3e55e35d..8e0be44d 100644 --- a/src/main/java/com/listywave/collection/application/dto/CollectionResponse.java +++ b/src/main/java/com/listywave/collection/application/dto/CollectionFindResponse.java @@ -7,44 +7,44 @@ import java.util.List; import lombok.Builder; -public record CollectionResponse( +public record CollectionFindResponse( Long cursorId, Boolean hasNext, - List collectionLists, + List collectionLists, String folderName ) { - public static CollectionResponse of( + public static CollectionFindResponse of( Long cursorId, Boolean hasNext, List collects, String folderName ) { - return new CollectionResponse(cursorId, hasNext, toList(collects), folderName); + return new CollectionFindResponse(cursorId, hasNext, toList(collects), folderName); } - public static List toList(List collects) { + public static List toList(List collects) { return collects.stream() - .map(CollectionListsResponse::of) + .map(CollectionDto::of) .toList(); } - public record CollectionListsResponse( + public record CollectionDto( Long id, - ListsResponse list + ListsDto list ) { - public static CollectionListsResponse of(Collect collect) { - return new CollectionListsResponse(collect.getId(), toResponse(collect.getList())); + public static CollectionDto of(Collect collect) { + return new CollectionDto(collect.getId(), toResponse(collect.getList())); } - public static ListsResponse toResponse(ListEntity list) { - return ListsResponse.of(list); + public static ListsDto toResponse(ListEntity list) { + return ListsDto.of(list); } } @Builder - public record ListsResponse( + public record ListsDto( Long id, String backgroundColor, String title, @@ -54,11 +54,11 @@ public record ListsResponse( String representativeImageUrl, String category, LocalDateTime updatedDate, - List listItems + List listItems ) { - public static ListsResponse of(ListEntity list) { - return ListsResponse.builder() + public static ListsDto of(ListEntity list) { + return ListsDto.builder() .id(list.getId()) .backgroundColor(list.getBackgroundColor().name()) .title(list.getTitle().getValue()) @@ -72,23 +72,23 @@ public static ListsResponse of(ListEntity list) { .build(); } - public static List toList(List items) { + public static List toList(List items) { return items.stream() - .map(ListItemsResponse::of) + .map(ListItemsDto::of) .toList(); } } @Builder - public record ListItemsResponse( + public record ListItemsDto( Long id, int rank, String title, String imageUrl ) { - public static ListItemsResponse of(Item item) { - return ListItemsResponse.builder() + public static ListItemsDto of(Item item) { + return ListItemsDto.builder() .id(item.getId()) .rank(item.getRanking()) .title(item.getTitle().getValue()) diff --git a/src/main/java/com/listywave/collection/application/service/CollectionService.java b/src/main/java/com/listywave/collection/application/service/CollectionService.java index a2ea3389..931fcb1a 100644 --- a/src/main/java/com/listywave/collection/application/service/CollectionService.java +++ b/src/main/java/com/listywave/collection/application/service/CollectionService.java @@ -3,7 +3,7 @@ import com.listywave.alarm.application.domain.AlarmCreateEvent; import com.listywave.collection.application.domain.Collect; import com.listywave.collection.application.domain.Folder; -import com.listywave.collection.application.dto.CollectionResponse; +import com.listywave.collection.application.dto.CollectionFindResponse; import com.listywave.collection.repository.CollectionRepository; import com.listywave.collection.repository.FolderRepository; import com.listywave.list.application.domain.category.CategoryType; @@ -32,6 +32,8 @@ public class CollectionService { private final CollectionRepository collectionRepository; private final ApplicationEventPublisher applicationEventPublisher; + private final static String FOLDER_ENTIRE_NAME = "전체"; + public void collectOrCancel(Long listId, Long folderId, Long userId) { User user = userRepository.getById(userId); ListEntity list = listRepository.getById(listId); @@ -60,9 +62,13 @@ private void addCollect(ListEntity list, User user, Folder folder) { applicationEventPublisher.publishEvent(AlarmCreateEvent.collect(user, list)); } - public CollectionResponse getCollection(Long loginUserId, Long cursorId, Pageable pageable, Long folderId) { - User user = userRepository.getById(loginUserId); - Folder folder = folderRepository.getById(folderId); + public CollectionFindResponse getCollection(Long userId, Long cursorId, Pageable pageable, Long folderId) { + User user = userRepository.getById(userId); + String folderName = FOLDER_ENTIRE_NAME; + if (folderId != 0L) { + Folder folder = folderRepository.getById(folderId); + folderName = folder.getFolderName(); + } Slice result = collectionRepository.getAllCollectionList(cursorId, pageable, user.getId(), folderId); List collectionList = result.getContent(); @@ -70,7 +76,7 @@ public CollectionResponse getCollection(Long loginUserId, Long cursorId, Pageabl if (!collectionList.isEmpty()) { cursorId = collectionList.get(collectionList.size() - 1).getId(); } - return CollectionResponse.of(cursorId, result.hasNext(), collectionList, folder.getFolderName()); + return CollectionFindResponse.of(cursorId, result.hasNext(), collectionList, folderName); } public List getCategoriesOfCollection(Long loginUserId) { diff --git a/src/main/java/com/listywave/collection/presentation/controller/CollectionController.java b/src/main/java/com/listywave/collection/presentation/controller/CollectionController.java index 2a97d509..6e85ec53 100644 --- a/src/main/java/com/listywave/collection/presentation/controller/CollectionController.java +++ b/src/main/java/com/listywave/collection/presentation/controller/CollectionController.java @@ -1,17 +1,21 @@ package com.listywave.collection.presentation.controller; -import com.listywave.collection.application.dto.CollectionResponse; +import com.listywave.collection.application.dto.CollectionFindResponse; import com.listywave.collection.application.service.CollectionService; import com.listywave.collection.presentation.dto.FolderSelectionRequest; import com.listywave.common.auth.Auth; import com.listywave.list.application.dto.response.CategoryTypeResponse; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Pageable; import org.springframework.data.web.PageableDefault; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -import java.util.List; +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.RequestParam; +import org.springframework.web.bind.annotation.RestController; @RestController @RequiredArgsConstructor @@ -30,13 +34,13 @@ ResponseEntity collectOrCancel( } @GetMapping("/folder/{folderId}/collections") - ResponseEntity getCollection( + ResponseEntity getCollection( @Auth Long loginUserId, @PathVariable("folderId") Long folderId, @RequestParam(name = "cursorId", required = false) Long cursorId, @PageableDefault(size = 10) Pageable pageable ) { - CollectionResponse collection = collectionService.getCollection(loginUserId, cursorId, pageable, folderId); + CollectionFindResponse collection = collectionService.getCollection(loginUserId, cursorId, pageable, folderId); return ResponseEntity.ok(collection); } diff --git a/src/main/java/com/listywave/collection/repository/custom/impl/CustomCollectionRepositoryImpl.java b/src/main/java/com/listywave/collection/repository/custom/impl/CustomCollectionRepositoryImpl.java index ad5289c0..4d469afe 100644 --- a/src/main/java/com/listywave/collection/repository/custom/impl/CustomCollectionRepositoryImpl.java +++ b/src/main/java/com/listywave/collection/repository/custom/impl/CustomCollectionRepositoryImpl.java @@ -12,10 +12,10 @@ import com.listywave.user.application.domain.User; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.impl.JPAQueryFactory; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; -import java.util.List; @RequiredArgsConstructor public class CustomCollectionRepositoryImpl implements CustomCollectionRepository { @@ -42,7 +42,7 @@ public Slice getAllCollectionList(Long cursorId, Pageable pageable, Lon } private BooleanExpression folderIdEq(Long folderId) { - return collect.folder.id.eq(folderId); + return folderId == 0L ? null : collect.folder.id.eq(folderId); } private BooleanExpression collectIdLt(Long cursorId) { diff --git a/src/test/java/com/listywave/acceptance/collection/CollectionAcceptanceTest.java b/src/test/java/com/listywave/acceptance/collection/CollectionAcceptanceTest.java index 335718be..c0fa209d 100644 --- a/src/test/java/com/listywave/acceptance/collection/CollectionAcceptanceTest.java +++ b/src/test/java/com/listywave/acceptance/collection/CollectionAcceptanceTest.java @@ -1,21 +1,14 @@ package com.listywave.acceptance.collection; -import com.listywave.acceptance.common.AcceptanceTest; -import com.listywave.collection.application.dto.CollectionResponse; -import com.listywave.collection.application.dto.CollectionResponse.CollectionListsResponse; -import com.listywave.list.application.domain.list.ListEntity; -import com.listywave.list.application.dto.response.ListCreateResponse; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import java.util.List; -import java.util.stream.Collectors; - import static com.listywave.acceptance.collection.CollectionAcceptanceTestHelper.나의_콜렉션_조회_API_호출; import static com.listywave.acceptance.collection.CollectionAcceptanceTestHelper.콜렉트_또는_콜렉트취소_API_호출; import static com.listywave.acceptance.common.CommonAcceptanceHelper.HTTP_상태_코드를_검증한다; -import static com.listywave.acceptance.folder.FolderAcceptanceTestHelper.*; -import static com.listywave.acceptance.list.ListAcceptanceTestHelper.*; +import static com.listywave.acceptance.folder.FolderAcceptanceTestHelper.폴더_생성_API_호출; +import static com.listywave.acceptance.folder.FolderAcceptanceTestHelper.폴더_생성_요청_데이터; +import static com.listywave.acceptance.folder.FolderAcceptanceTestHelper.폴더_선택_요청_데이터; +import static com.listywave.acceptance.list.ListAcceptanceTestHelper.가장_좋아하는_견종_TOP3_생성_요청_데이터; +import static com.listywave.acceptance.list.ListAcceptanceTestHelper.리스트_저장_API_호출; +import static com.listywave.acceptance.list.ListAcceptanceTestHelper.회원용_리스트_상세_조회_API_호출; import static com.listywave.list.fixture.ListFixture.지정된_개수만큼_리스트를_생성한다; import static com.listywave.user.fixture.UserFixture.동호; import static com.listywave.user.fixture.UserFixture.정수; @@ -23,6 +16,15 @@ import static org.springframework.http.HttpStatus.FORBIDDEN; import static org.springframework.http.HttpStatus.NO_CONTENT; +import com.listywave.acceptance.common.AcceptanceTest; +import com.listywave.collection.application.dto.CollectionFindResponse; +import com.listywave.list.application.domain.list.ListEntity; +import com.listywave.list.application.dto.response.ListCreateResponse; +import java.util.List; +import java.util.stream.Collectors; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + @DisplayName("콜렉션 관련 인수테스트") public class CollectionAcceptanceTest extends AcceptanceTest { @@ -112,9 +114,40 @@ public class CollectionAcceptanceTest extends AcceptanceTest { // when var 결과 = 나의_콜렉션_조회_API_호출(정수_엑세스_토큰, 1L) - .as(CollectionResponse.class) + .as(CollectionFindResponse.class) + .collectionLists().stream() + .map(CollectionFindResponse.CollectionDto::list) + .collect(Collectors.toList()); + + // then + assertThat(결과).usingRecursiveComparison() + .comparingOnlyFields("id") + .isEqualTo(생성한_리스트.stream().map(ListEntity::getId).toList()); + } + + @Test + void 나의_전체_콜렉션을_조회한다() { + // given + var 동호 = 회원을_저장한다(동호()); + var 정수 = 회원을_저장한다(정수()); + var 정수_엑세스_토큰 = 액세스_토큰을_발급한다(정수); + var 생성한_리스트 = 지정된_개수만큼_리스트를_생성한다(동호, 2); + 리스트를_모두_저장한다(생성한_리스트); + + var 폴더_생성_요청_데이터1 = 폴더_생성_요청_데이터("맛집"); + var 폴더_생성_요청_데이터2 = 폴더_생성_요청_데이터("예카"); + var 폴더_선택_데이터1 = 폴더_선택_요청_데이터(1L); + var 폴더_선택_데이터2 = 폴더_선택_요청_데이터(2L); + 폴더_생성_API_호출(정수_엑세스_토큰, 폴더_생성_요청_데이터1); + 폴더_생성_API_호출(정수_엑세스_토큰, 폴더_생성_요청_데이터2); + 콜렉트_또는_콜렉트취소_API_호출(정수_엑세스_토큰, 1L, 폴더_선택_데이터1); + 콜렉트_또는_콜렉트취소_API_호출(정수_엑세스_토큰, 2L, 폴더_선택_데이터2); + + // when + var 결과 = 나의_콜렉션_조회_API_호출(정수_엑세스_토큰, 0L) + .as(CollectionFindResponse.class) .collectionLists().stream() - .map(CollectionListsResponse::list) + .map(CollectionFindResponse.CollectionDto::list) .collect(Collectors.toList()); // then diff --git a/src/test/java/com/listywave/acceptance/user/UserAcceptanceTest.java b/src/test/java/com/listywave/acceptance/user/UserAcceptanceTest.java index ba436c5b..ac5402d3 100644 --- a/src/test/java/com/listywave/acceptance/user/UserAcceptanceTest.java +++ b/src/test/java/com/listywave/acceptance/user/UserAcceptanceTest.java @@ -2,12 +2,27 @@ import static com.listywave.acceptance.common.CommonAcceptanceHelper.HTTP_상태_코드를_검증한다; import static com.listywave.acceptance.follow.FollowAcceptanceTestHelper.팔로우_요청_API; -import static com.listywave.acceptance.list.ListAcceptanceTestHelper.*; -import static com.listywave.acceptance.user.UserAcceptanceTestHelper.*; -import static com.listywave.user.fixture.UserFixture.*; +import static com.listywave.acceptance.list.ListAcceptanceTestHelper.가장_좋아하는_견종_TOP3_생성_요청_데이터; +import static com.listywave.acceptance.list.ListAcceptanceTestHelper.리스트_수정_API_호출; +import static com.listywave.acceptance.list.ListAcceptanceTestHelper.리스트_저장_API_호출; +import static com.listywave.acceptance.list.ListAcceptanceTestHelper.아이템_순위와_라벨을_바꾼_좋아하는_견종_TOP3_요청_데이터; +import static com.listywave.acceptance.user.UserAcceptanceTestHelper.닉네임_중복_체크_요청; +import static com.listywave.acceptance.user.UserAcceptanceTestHelper.비회원_추천_API; +import static com.listywave.acceptance.user.UserAcceptanceTestHelper.비회원_회원_정보_조회_요청; +import static com.listywave.acceptance.user.UserAcceptanceTestHelper.비회원이_사용자_검색; +import static com.listywave.acceptance.user.UserAcceptanceTestHelper.프로필_수정_요청; +import static com.listywave.acceptance.user.UserAcceptanceTestHelper.프로필_수정_요청_데이터; +import static com.listywave.acceptance.user.UserAcceptanceTestHelper.회원_추천_API; +import static com.listywave.acceptance.user.UserAcceptanceTestHelper.회원이_사용자_검색; +import static com.listywave.acceptance.user.UserAcceptanceTestHelper.회원이_회원_정보_조회_요청; +import static com.listywave.user.fixture.UserFixture.동호; +import static com.listywave.user.fixture.UserFixture.유진; +import static com.listywave.user.fixture.UserFixture.정수; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; -import static org.springframework.http.HttpStatus.*; +import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.FORBIDDEN; +import static org.springframework.http.HttpStatus.NO_CONTENT; import com.listywave.acceptance.common.AcceptanceTest; import com.listywave.list.application.dto.response.ListCreateResponse; @@ -159,21 +174,6 @@ class 추천_사용자 { assertThat(결과.get(0).nickname()).isEqualTo(유진.getNickname()); } - @Test - void 비회원이_추천_사용자_조회한다() { - // given - 회원을_저장한다(동호()); - 회원을_저장한다(정수()); - 회원을_저장한다(유진()); - - // when - List 결과 = 비회원_추천_API().as(new TypeRef<>() { - }); - - // then - assertThat(결과).hasSize(3); - } - @Test void 가장_최근에_리스트_생성_또는_수정한_사용자_순위대로_추천_사용자_조회한다() { // given