Skip to content

Commit

Permalink
[Feature] - 자신이 좋아요를 누른 게시글을 조회하는 기능 구현 (#540)
Browse files Browse the repository at this point in the history
* feat: 내가 좋아요 한 여행기 조회 기능 구현

* test: 내가 좋아요 한 여행기 조회 테스트 코드 추가

* refactor: 다른 dto 와 형식 통일
  • Loading branch information
nak-honest authored Oct 20, 2024
1 parent c0d4c0b commit ff555a3
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import kr.touroot.global.auth.dto.MemberAuth;
import kr.touroot.global.exception.dto.ExceptionResponse;
import kr.touroot.member.dto.request.ProfileUpdateRequest;
import kr.touroot.member.dto.response.MyLikeTravelogueResponse;
import kr.touroot.member.dto.response.MyTravelogueResponse;
import kr.touroot.member.dto.response.ProfileResponse;
import kr.touroot.member.service.MyPageFacadeService;
Expand Down Expand Up @@ -103,6 +104,30 @@ public ResponseEntity<Page<PlanResponse>> readTravelPlans(
return ResponseEntity.ok(data);
}

@Operation(summary = "내가 좋아요 한 여행기 조회")
@ApiResponses(value = {
@ApiResponse(
responseCode = "200",
description = "내가 좋아요 한 여행기 조회에 성공했을 때"
),
@ApiResponse(
responseCode = "401",
description = "로그인하지 않은 사용자가 조회를 시도할 때",
content = @Content(schema = @Schema(implementation = ExceptionResponse.class))
)
})
@PageableAsQueryParam
@GetMapping("/likes")
public ResponseEntity<Page<MyLikeTravelogueResponse>> readLikes(
@NotNull MemberAuth memberAuth,
@Parameter(hidden = true)
@PageableDefault(size = 5, sort = "id", direction = Sort.Direction.DESC)
Pageable pageable
) {
Page<MyLikeTravelogueResponse> data = myPageFacadeService.readLikes(memberAuth, pageable);
return ResponseEntity.ok(data);
}

@Operation(summary = "나의 프로필 정보 수정")
@ApiResponses(value = {
@ApiResponse(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package kr.touroot.member.dto.response;

import java.time.format.DateTimeFormatter;
import kr.touroot.travelogue.domain.Travelogue;
import lombok.Builder;

@Builder
public record MyLikeTravelogueResponse(
long id,
String title,
String thumbnailUrl,
String createdAt,
String authorName,
String authorProfileImageUrl
) {

public static MyLikeTravelogueResponse from(Travelogue travelogue) {
String createdAt = travelogue.getCreatedAt()
.toLocalDate()
.format(DateTimeFormatter.ofPattern("yyyy.MM.dd"));

return MyLikeTravelogueResponse.builder()
.id(travelogue.getId())
.title(travelogue.getTitle())
.thumbnailUrl(travelogue.getThumbnail())
.createdAt(createdAt)
.authorName(travelogue.getAuthorNickname())
.authorProfileImageUrl(travelogue.getAuthorProfileImageUrl())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
import kr.touroot.global.auth.dto.MemberAuth;
import kr.touroot.member.domain.Member;
import kr.touroot.member.dto.request.ProfileUpdateRequest;
import kr.touroot.member.dto.response.MyLikeTravelogueResponse;
import kr.touroot.member.dto.response.MyTravelogueResponse;
import kr.touroot.member.dto.response.ProfileResponse;
import kr.touroot.travelogue.domain.Travelogue;
import kr.touroot.travelogue.domain.TravelogueLike;
import kr.touroot.travelogue.service.TravelogueLikeService;
import kr.touroot.travelogue.service.TravelogueService;
import kr.touroot.travelplan.domain.TravelPlan;
import kr.touroot.travelplan.dto.response.PlanResponse;
Expand All @@ -23,6 +26,7 @@ public class MyPageFacadeService {
private final MemberService memberService;
private final TravelogueService travelogueService;
private final TravelPlanService travelPlanService;
private final TravelogueLikeService travelogueLikeService;

@Transactional(readOnly = true)
public ProfileResponse readProfile(MemberAuth memberAuth) {
Expand All @@ -46,6 +50,15 @@ public Page<PlanResponse> readTravelPlans(MemberAuth memberAuth, Pageable pageab
return travelPlans.map(PlanResponse::from);
}

@Transactional(readOnly = true)
public Page<MyLikeTravelogueResponse> readLikes(MemberAuth memberAuth, Pageable pageable) {
Member member = memberService.getMemberById(memberAuth.memberId());

return travelogueLikeService.findByLiker(member, pageable)
.map(TravelogueLike::getTravelogue)
.map(MyLikeTravelogueResponse::from);
}

@Transactional
public ProfileResponse updateProfile(ProfileUpdateRequest request, MemberAuth memberAuth) {
return memberService.updateProfile(request, memberAuth);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
import kr.touroot.member.domain.Member;
import kr.touroot.travelogue.domain.Travelogue;
import kr.touroot.travelogue.domain.TravelogueLike;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;

public interface TravelogueLikeRepository extends JpaRepository<TravelogueLike, Long> {

Page<TravelogueLike> findAllByLiker(Member liker, Pageable pageable);

boolean existsByTravelogueAndLiker(Travelogue travelogue, Member liker);

void deleteAllByTravelogue(Travelogue travelogue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import kr.touroot.travelogue.domain.TravelogueLike;
import kr.touroot.travelogue.repository.TravelogueLikeRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -14,6 +16,11 @@ public class TravelogueLikeService {

private final TravelogueLikeRepository travelogueLikeRepository;

@Transactional(readOnly = true)
public Page<TravelogueLike> findByLiker(Member liker, Pageable pageable) {
return travelogueLikeRepository.findAllByLiker(liker, pageable);
}

@Transactional(readOnly = true)
public boolean existByTravelogueAndMember(Travelogue travelogue, Member liker) {
return travelogueLikeRepository.existsByTravelogueAndLiker(travelogue, liker);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,25 @@ void readTravelPlans() {
.body("content.size()", is(2));
}

@DisplayName("마이 페이지 컨트롤러는 내가 좋아요 한 여행기 조회 시 요청이 들어오면 로그인한 사용자의 여행 계획을 조회한다.")
@Test
void readLikeTravelogues() {
// given
travelogueTestHelper.initTravelogueTestDataWithLike(member);
travelogueTestHelper.initTravelogueTestDataWithLike(member);
travelogueTestHelper.initTravelogueTestData();

// when & then
RestAssured.given().log().all()
.contentType(ContentType.JSON)
.header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken)
.when().log().all()
.get("/api/v1/member/me/likes")
.then().log().all()
.statusCode(200)
.body("content.size()", is(2));
}

@DisplayName("마이 페이지 컨트롤러는 내 프로필 수정 요청이 들어오면 로그인한 사용자의 프로필을 수정한다.")
@Test
void updateProfile() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Import;
import org.springframework.data.domain.Pageable;

@DisplayName("여행기 좋아요 서비스")
@Import(value = {TravelogueLikeService.class, TravelogueTestHelper.class})
@ServiceTest
class TravelogueLikeServiceTest {

public static final int BASIC_PAGE_SIZE = 5;

private final TravelogueLikeService travelogueLikeService;
private final DatabaseCleaner databaseCleaner;
private final TravelogueTestHelper testHelper;
Expand All @@ -38,6 +41,20 @@ void setUp() {
databaseCleaner.executeTruncate();
}

@DisplayName("특정 멤버가 좋아요 한 여행기를 조회할 수 있다.")
@Test
void findByLiker() {
// given
Member liker = testHelper.initKakaoMemberTestData();
testHelper.initTravelogueTestDataWithLike(liker);
testHelper.initTravelogueTestDataWithLike(liker);
testHelper.initTravelogueTestData();

// when & then
assertThat(travelogueLikeService.findByLiker(liker, Pageable.ofSize(BASIC_PAGE_SIZE)))
.hasSize(2);
}

@DisplayName("특정 여행기에 특정 멤버가 좋아요 했는지 알 수 있다")
@Test
void existByTravelogueAndMember() {
Expand Down

0 comments on commit ff555a3

Please sign in to comment.