Skip to content

Commit

Permalink
[#137] : 내가 찜한 가게 리스트 받아오기 API 구현 (#196)
Browse files Browse the repository at this point in the history
* feat[#137] : 찜한 Shop 조회 API 구현

* test[#137] : 찜한 가게 조회 테스트

* refactor[#137] :  category 별로 fetch를 보내도록 API 구현

* test[#137] : 테스트 수정

* refactor[#137] : 포매팅 적용

* feat[#137] : 페이징 기능 추가

* test[#137] : 페이징 테스트 추가

* feat[#137] : 페이징 적용

- data jpa 에서 제공하는 메서드를 통해 구현하였다.

* refactor[#137] : 포매팅 적용
  • Loading branch information
gomster96 authored Aug 29, 2022
1 parent f656727 commit 8c98cde
Show file tree
Hide file tree
Showing 10 changed files with 221 additions and 8 deletions.
14 changes: 12 additions & 2 deletions backend/src/main/java/com/handong/rebon/member/domain/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.persistence.*;

import com.handong.rebon.category.domain.Category;
import com.handong.rebon.common.BaseEntity;
import com.handong.rebon.review.domain.empathy.Empathy;
import com.handong.rebon.shop.domain.Shop;
import com.handong.rebon.shop.domain.like.Likes;

import lombok.*;
Expand Down Expand Up @@ -82,7 +86,13 @@ public String getNickName() {
return profile.getNickname();
}

public String getEmail() { return profile.getEmail(); }
public String getEmail() {return profile.getEmail();}

public String getImage() { return profile.getImage(); }
public String getImage() {return profile.getImage();}

public List<Likes> filterByCategory(Category category) {
return likes.stream()
.filter(like -> like.isSameCategory(category))
.collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
import org.springframework.data.jpa.repository.JpaRepository;

public interface MemberRepository extends JpaRepository<Member, Long> {

Optional<Member> findByProfileEmailAndOauthProvider(String email, String oauthProvider);

boolean existsByProfileNickname(String nickname);

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,4 @@ public interface ReviewRepository extends JpaRepository<Review, Long>, ReviewRep
Page<Review> findAllByMember(Member member, Pageable pageable);

Page<Review> findAllByShop(Shop shop, Pageable pageable);

}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.handong.rebon.tag.domain.Tag;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
Expand Down Expand Up @@ -186,6 +187,21 @@ private ShopImages changeImages(Shop shop, ShopRequestDto shopRequestDto) {
return saveImages(shopRequestDto.getImages());
}

@Transactional(readOnly = true)
public List<ShopSimpleResponseDto> findLikeShops(Long memberId, Long categoryId, Pageable pageable) {

Category category = categoryService.findById(categoryId);
Member member = memberService.findById(memberId);


Page<Shop> shops = shopRepository.findByCategoryAndLikesMember(category, member, pageable);
return shops.get()
.map(ShopSimpleResponseDto::from)
.collect(Collectors.toList());

}


@Transactional(readOnly = true)
public boolean isLike(Long id, LoginMember loginMember) {
Shop shop = findById(id);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.handong.rebon.shop.application.dto.response;

import java.util.List;
import java.util.stream.Collectors;

import com.handong.rebon.auth.domain.LoginMember;
import com.handong.rebon.shop.application.dto.response.tag.ShopTagResponseDto;
import com.handong.rebon.shop.domain.Shop;
import com.handong.rebon.shop.domain.like.Likes;

import lombok.AccessLevel;
import lombok.Builder;
Expand Down Expand Up @@ -35,17 +35,26 @@ public ShopSimpleResponseDto(Long id, String name, double star, int reviewCount,
}

public static ShopSimpleResponseDto of(Shop shop, LoginMember loginMember) {
List<ShopTagResponseDto> tags = shop.getShopTags().stream()
.map(shopTag -> ShopTagResponseDto.from(shopTag.getTag()))
.collect(Collectors.toList());

return ShopSimpleResponseDto.builder()
.id(shop.getId())
.name(shop.getName())
.star(shop.getStar())
.reviewCount(shop.getReviewCount())
.like(shop.containLike(loginMember))
.tags(tags)
.tags(ShopTagResponseDto.toDtos(shop))
.image(shop.getMainImage())
.build();
}

public static ShopSimpleResponseDto from(Shop shop) {

return ShopSimpleResponseDto.builder()
.id(shop.getId())
.name(shop.getName())
.star(shop.getStar())
.like(true)
.tags(ShopTagResponseDto.toDtos(shop))
.image(shop.getMainImage())
.build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.handong.rebon.shop.application.dto.response.tag;

import java.util.List;
import java.util.stream.Collectors;

import com.handong.rebon.shop.domain.Shop;
import com.handong.rebon.tag.domain.Tag;

import lombok.AccessLevel;
Expand All @@ -20,4 +24,10 @@ public ShopTagResponseDto(Long id, String name) {
public static ShopTagResponseDto from(Tag tag) {
return new ShopTagResponseDto(tag.getId(), tag.getName());
}

public static List<ShopTagResponseDto> toDtos(Shop shop) {
return shop.getShopTags().stream()
.map(shopTag -> ShopTagResponseDto.from(shopTag.getTag()))
.collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
import java.util.Objects;
import javax.persistence.*;

import com.handong.rebon.category.domain.Category;
import com.handong.rebon.member.domain.Member;
import com.handong.rebon.shop.domain.Shop;

import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@NoArgsConstructor
public class Likes {

Expand Down Expand Up @@ -45,4 +48,8 @@ public boolean equals(Object o) {
public int hashCode() {
return Objects.hash(member, shop);
}

public boolean isSameCategory(Category category) {
return shop.sameCategory(category);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@
import java.util.Optional;

import com.handong.rebon.category.domain.Category;
import com.handong.rebon.member.domain.Member;
import com.handong.rebon.shop.domain.Shop;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

public interface ShopRepository extends JpaRepository<Shop, Long>, ShopRepositoryCustom {
List<Shop> findByCategory(Category category);


Page<Shop> findByCategoryAndLikesMember(Category category, Member member, Pageable pageable);
Optional<Shop> findByNaverId(Long naverId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,21 @@ public ResponseEntity<ShopLikeResponse> unlike(
return ResponseEntity.ok(ShopLikeResponse.from(shopLikeResponseDto));
}


@RequiredLogin
@GetMapping("/shops/likes")
public ResponseEntity<List<ShopSimpleResponse>> getLikeShops(
@Login LoginMember loginMember,
@RequestParam Long categoryId,
@PageableDefault Pageable pageable
) {
List<ShopSimpleResponseDto> responses = shopService.findLikeShops(loginMember.getId(), categoryId, pageable);
return ResponseEntity.ok(ShopSimpleResponse.convert(responses));

@PostMapping("/shops/naver")
public ResponseEntity<Void> naverShops(@RequestBody NaverShopRequest shopRequest) {
shopService.createNaverShops(shopRequest.getKeyword(), shopRequest.getDisplayCount(), shopRequest.getPage());
return ResponseEntity.ok().build();

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package com.handong.rebon.acceptance.shop;

import java.time.LocalTime;
import java.util.*;

import com.handong.rebon.acceptance.AcceptanceTest;
import com.handong.rebon.category.domain.Category;
import com.handong.rebon.common.admin.AdminCategoryRegister;
import com.handong.rebon.common.admin.AdminShopRegister;
import com.handong.rebon.common.admin.AdminTagRegister;
import com.handong.rebon.shop.domain.Shop;
import com.handong.rebon.shop.presentation.dto.response.ShopSimpleResponse;
import com.handong.rebon.tag.domain.Tag;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import io.restassured.RestAssured;
import io.restassured.common.mapper.TypeRef;
import io.restassured.response.ExtractableResponse;
import io.restassured.response.Response;

import static com.handong.rebon.acceptance.AcceptanceUtils.getRequestSpecification;
import static com.handong.rebon.acceptance.shop.ShopLikeAcceptanceTest._좋아요;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;


public class LikeShopReadAcceptanceTest extends AcceptanceTest {
@Autowired
private AdminTagRegister adminTagRegister;

@Autowired
private AdminCategoryRegister adminCategoryRegister;

@Autowired
private AdminShopRegister adminShopRegister;

private Map<String, Tag> tags = new HashMap<>();
private Map<String, Category> categories = new HashMap<>();
private Map<String, Shop> shops = new HashMap<>();

@BeforeEach
void setUp() {
tags = adminTagRegister.register("포항", "영일대", "한동대", "양덕");
categories = adminCategoryRegister.registerMain("식당", "숙소", "카페");
categories.putAll(adminCategoryRegister.registerSubs(categories.get("식당"), "한식", "분식", "일식", "양식"));
categories.putAll(adminCategoryRegister.registerSubs(categories.get("카페"), "프랜차이즈", "개인카페"));
shops.clear();
shops.put("티타", adminShopRegister.CafeRegisterWithMenu(
"티타",
categories.get("카페"),
Collections.singletonList(categories.get("개인카페")),
Arrays.asList(tags.get("포항"), tags.get("양덕")),
LocalTime.MIN,
LocalTime.MAX
));
shops.put("설빙", adminShopRegister.CafeRegisterWithMenu(
"설빙",
categories.get("카페"),
Collections.singletonList(categories.get("프랜차이즈")),
Arrays.asList(tags.get("포항"), tags.get("양덕")),
LocalTime.MIN,
LocalTime.MAX
));
shops.put("인브리즈", adminShopRegister.CafeRegisterWithMenu(
"인브리즈",
categories.get("카페"),
Collections.singletonList(categories.get("개인카페")),
Arrays.asList(tags.get("포항"), tags.get("한동대")),
LocalTime.MIN,
LocalTime.MAX
));
shops.put("예소드", adminShopRegister.CafeRegisterWithMenu(
"예소드",
categories.get("카페"),
Collections.singletonList(categories.get("개인카페")),
Arrays.asList(tags.get("포항"), tags.get("한동대")),
LocalTime.MIN,
LocalTime.MAX
));
}

@Test
@DisplayName("내가 찜한 가게 리스트 조회")
public void getLikeShops() {
//given
ExtractableResponse<Response> registerResponse = 회원입("[email protected]", "test");
String token = extractedToken(registerResponse);
_좋아요(token, shops.get("티타"));
_좋아요(token, shops.get("설빙"));
Long categoryId = categories.get("카페").getId();
//when
ExtractableResponse<Response> response = 찜한_가_조회(token, categoryId, 0,2);
List<ShopSimpleResponse> result = response.as(new TypeRef<>() {});
//then
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value());
assertThat(result.size()).isEqualTo(2);
assertThat(result).extracting("name")
.containsOnly("티타", "설빙");

}

@Test
@DisplayName("내가 찜한 가게 리스트 다음페이지 조회")
public void getLikeShopsWithPaging() {
//given
ExtractableResponse<Response> registerResponse = 회원입("[email protected]", "test");
String token = extractedToken(registerResponse);
_좋아요(token, shops.get("티타"));
_좋아요(token, shops.get("설빙"));
_좋아요(token, shops.get("인브리즈"));
_좋아요(token, shops.get("예소드"));
Long categoryId = categories.get("카페").getId();
//when
ExtractableResponse<Response> response = 찜한_가_조회(token, categoryId, 1,2);
List<ShopSimpleResponse> result = response.as(new TypeRef<>() {});
//then
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value());
assertThat(result.size()).isEqualTo(2);
assertThat(result).extracting("name")
.containsOnly("인브리즈", "예소드");

}

private ExtractableResponse<Response> 찜한_가_조회(String token, Long categoryId, int pageNum, int pageSize) {
return RestAssured.given(getRequestSpecification())
.log().all()
.header("Authorization", "Bearer " + token)
.contentType(APPLICATION_JSON_VALUE)
.when()
.get("/api/shops/likes?categoryId=" + categoryId
+ "&page=" + pageNum + "&size=" + pageSize)
.then()
.log().all()
.extract();
}
}

0 comments on commit 8c98cde

Please sign in to comment.