-
Notifications
You must be signed in to change notification settings - Fork 1
[Feat] 스토리 상세 조회 기능 구현 #87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 9 commits
c0496da
f83b17c
e3b3cb9
ff219ec
b3a2677
b12c6aa
2975c17
f006ada
1547759
e23c6e3
a65f46b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |||||||||
| import eatda.controller.story.FilteredSearchResult; | ||||||||||
| import eatda.controller.story.StoriesResponse; | ||||||||||
| import eatda.controller.story.StoryRegisterRequest; | ||||||||||
| import eatda.controller.story.StoryResponse; | ||||||||||
| import eatda.domain.member.Member; | ||||||||||
| import eatda.domain.story.Story; | ||||||||||
| import eatda.exception.BusinessErrorCode; | ||||||||||
|
|
@@ -26,7 +27,6 @@ | |||||||||
| @RequiredArgsConstructor | ||||||||||
| public class StoryService { | ||||||||||
| private static final int PAGE_START_NUMBER = 0; | ||||||||||
| private static final int PAGE_SIZE = 5; | ||||||||||
|
|
||||||||||
| private final StoreService storeService; | ||||||||||
| private final ImageService imageService; | ||||||||||
|
|
@@ -67,8 +67,8 @@ private FilteredSearchResult filteredSearchResponse(List<StoreSearchResult> resp | |||||||||
| } | ||||||||||
|
|
||||||||||
| @Transactional(readOnly = true) | ||||||||||
| public StoriesResponse getPagedStoryPreviews() { | ||||||||||
| Pageable pageable = PageRequest.of(PAGE_START_NUMBER, PAGE_SIZE); | ||||||||||
| public StoriesResponse getPagedStoryPreviews(int size) { | ||||||||||
| Pageable pageable = PageRequest.of(PAGE_START_NUMBER, size); | ||||||||||
|
Comment on lines
+72
to
+73
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [제안]
Suggested change
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 좋은 제안 감사합니다! 1차 배포후에 다른 페이지가 필요하다고 할수도 있으니... 지금은 이대로 가겠습니다! |
||||||||||
| Page<Story> orderByPage = storyRepository.findAllByOrderByCreatedAtDesc(pageable); | ||||||||||
|
|
||||||||||
| return new StoriesResponse( | ||||||||||
|
|
@@ -80,4 +80,19 @@ public StoriesResponse getPagedStoryPreviews() { | |||||||||
| .toList() | ||||||||||
| ); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| @Transactional(readOnly = true) | ||||||||||
| public StoryResponse getStory(long storyId) { | ||||||||||
| Story story = storyRepository.findById(storyId) | ||||||||||
| .orElseThrow(() -> new BusinessException(BusinessErrorCode.STORY_NOT_FOUND)); | ||||||||||
|
|
||||||||||
| return new StoryResponse( | ||||||||||
| story.getStoreKakaoId(), | ||||||||||
| story.getStoreCategory(), | ||||||||||
| story.getStoreName(), | ||||||||||
| story.getStoreAddress(), | ||||||||||
| story.getDescription(), | ||||||||||
| imageService.getPresignedUrl(story.getImageKey()) | ||||||||||
| ); | ||||||||||
| } | ||||||||||
| } | ||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| INSERT INTO story (member_id, store_kakao_id, store_name, store_address, | ||
| store_category, description, image_key) | ||
| VALUES (1, '99999999999', '맛있는 한식집', '서울시 강남구 역삼동 123-45', 'KOREAN', '진짜 여기 곱창 맛집임. 다시 또 갈 듯!', 'story/preview/1.jpg'), | ||
| (2, '99999999998', '아름다운 양식집', '서울시 강남구 역삼동 67-89', 'WESTERN', '스테이크가 부드럽고 서비스도 좋아요.', 'story/preview/2.jpg'), | ||
| (3, '99999999997', '정통 중식당', '서울시 강남구 역삼동 101-112', 'CHINESE', '짜장면이 정통의 맛. 강력 추천.', 'story/preview/3.jpg'); | ||
| VALUES (1, '99999999999', '맛있는 한식집', '서울시 강남구 역삼동 123-45', 'KOREAN', '진짜 여기 곱창 맛집임. 다시 또 갈 듯!', 'story/dummy/1.jpg'), | ||
| (2, '99999999998', '아름다운 양식집', '서울시 강남구 역삼동 67-89', 'WESTERN', '스테이크가 부드럽고 서비스도 좋아요.', 'story/dummy/2.jpg'), | ||
| (3, '99999999997', '정통 중식당', '서울시 강남구 역삼동 101-112', 'CHINESE', '짜장면이 정통의 맛. 강력 추천.', 'story/dummy/3.jpg'); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,9 @@ | ||
| INSERT INTO story (member_id, store_kakao_id, store_name, store_address, | ||
| store_category, description, image_key) | ||
| VALUES (1, '99999999999', '맛있는 한식집', '서울시 강남구 역삼동 123-45', 'KOREAN', '진짜 여기 곱창 맛집임. 다시 또 갈 듯!', 'story/preview/1.jpg'), | ||
| (2, '99999999998', '아름다운 양식집', '서울시 강남구 역삼동 67-89', 'WESTERN', '스테이크가 부드럽고 서비스도 좋아요.', 'story/preview/2.jpg'), | ||
| (3, '99999999997', '정통 중식당', '서울시 강남구 역삼동 101-112', 'CHINESE', '짜장면이 정통의 맛. 강력 추천.', 'story/preview/3.jpg'), | ||
| (4, '99999999996', '고급 양식 레스토랑', '서울시 강남구 역삼동 131-415', 'WESTERN', '분위기가 연인 데이트하기 좋아요.', 'story/preview/4.jpg'), | ||
| (5, '99999999995', '달콤한 디저트 카페', '서울시 강남구 역삼동 161-718', 'ETC', '케이크가 촉촉하고 맛있어요.', 'story/preview/5.jpg'), | ||
| (6, '99999999994', '아늑한 카페', '서울시 강남구 역삼동 192-021', 'ETC', '조용해서 공부하기 좋아요.', 'story/preview/6.jpg'), | ||
| (7, '99999999993', '빠른 패스트푸드점', '서울시 강남구 역삼동 222-324', 'ETC', '햄버거 나오는데 3분도 안 걸림. 굿.', 'story/preview/7.jpg'); | ||
| VALUES (1, '99999999999', '맛있는 한식집', '서울시 강남구 역삼동 123-45', 'KOREAN', '진짜 여기 곱창 맛집임. 다시 또 갈 듯!', 'story/dummy/1.jpg'), | ||
| (2, '99999999998', '아름다운 양식집', '서울시 강남구 역삼동 67-89', 'WESTERN', '스테이크가 부드럽고 서비스도 좋아요.', 'story/dummy/2.jpg'), | ||
| (3, '99999999997', '정통 중식당', '서울시 강남구 역삼동 101-112', 'CHINESE', '짜장면이 정통의 맛. 강력 추천.', 'story/dummy/3.jpg'), | ||
| (4, '99999999996', '고급 양식 레스토랑', '서울시 강남구 역삼동 131-415', 'WESTERN', '분위기가 연인 데이트하기 좋아요.', 'story/dummy/4.jpg'), | ||
| (5, '99999999995', '달콤한 디저트 카페', '서울시 강남구 역삼동 161-718', 'ETC', '케이크가 촉촉하고 맛있어요.', 'story/dummy/5.jpg'), | ||
| (6, '99999999994', '아늑한 카페', '서울시 강남구 역삼동 192-021', 'ETC', '조용해서 공부하기 좋아요.', 'story/dummy/6.jpg'), | ||
| (7, '99999999993', '빠른 패스트푸드점', '서울시 강남구 역삼동 222-324', 'ETC', '햄버거 나오는데 3분도 안 걸림. 굿.', 'story/dummy/7.jpg'); |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2,12 +2,13 @@ | |||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| import static org.hamcrest.Matchers.equalTo; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import static org.mockito.ArgumentMatchers.any; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import static org.mockito.ArgumentMatchers.eq; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import static org.mockito.Mockito.doNothing; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import static org.mockito.Mockito.doReturn; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import static org.mockito.Mockito.doThrow; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| import eatda.controller.BaseControllerTest; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import eatda.service.common.ImageDomain; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import eatda.exception.BusinessErrorCode; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import eatda.exception.BusinessException; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import io.restassured.response.Response; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import java.nio.charset.StandardCharsets; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.List; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -25,7 +26,7 @@ void setUpMock() { | |||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| @Nested | ||||||||||||||||||||||||||||||||||||||||||||||||
| class SearchStores { | ||||||||||||||||||||||||||||||||||||||||||||||||
| class RegisterStory { | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| @Test | ||||||||||||||||||||||||||||||||||||||||||||||||
| void 스토리를_등록할_수_있다() { | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -51,25 +52,80 @@ class SearchStores { | |||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| @Test | ||||||||||||||||||||||||||||||||||||||||||||||||
| void 스토리_목록을_조회할_수_있다() { | ||||||||||||||||||||||||||||||||||||||||||||||||
| StoriesResponse mockResponse = new StoriesResponse(List.of( | ||||||||||||||||||||||||||||||||||||||||||||||||
| new StoriesResponse.StoryPreview(1L, "https://dummy-s3.com/story1.png"), | ||||||||||||||||||||||||||||||||||||||||||||||||
| new StoriesResponse.StoryPreview(2L, "https://dummy-s3.com/story2.png") | ||||||||||||||||||||||||||||||||||||||||||||||||
| )); | ||||||||||||||||||||||||||||||||||||||||||||||||
| @Nested | ||||||||||||||||||||||||||||||||||||||||||||||||
| class GetStories { | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| doReturn(mockResponse) | ||||||||||||||||||||||||||||||||||||||||||||||||
| .when(storyService) | ||||||||||||||||||||||||||||||||||||||||||||||||
| .getPagedStoryPreviews(); | ||||||||||||||||||||||||||||||||||||||||||||||||
| @Test | ||||||||||||||||||||||||||||||||||||||||||||||||
| void 스토리_목록을_조회할_수_있다() { | ||||||||||||||||||||||||||||||||||||||||||||||||
| StoriesResponse mockResponse = new StoriesResponse(List.of( | ||||||||||||||||||||||||||||||||||||||||||||||||
| new StoriesResponse.StoryPreview(1L, "https://s3.bucket.com/story/dummy/1.jpg"), | ||||||||||||||||||||||||||||||||||||||||||||||||
| new StoriesResponse.StoryPreview(2L, "https://s3.bucket.com/story/dummy/2.jpg") | ||||||||||||||||||||||||||||||||||||||||||||||||
| )); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| doReturn(mockResponse) | ||||||||||||||||||||||||||||||||||||||||||||||||
| .when(storyService) | ||||||||||||||||||||||||||||||||||||||||||||||||
| .getPagedStoryPreviews(5); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| Response response = given() | ||||||||||||||||||||||||||||||||||||||||||||||||
| .queryParam("size", 5) | ||||||||||||||||||||||||||||||||||||||||||||||||
| .when() | ||||||||||||||||||||||||||||||||||||||||||||||||
| .get("/api/stories"); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| response.then() | ||||||||||||||||||||||||||||||||||||||||||||||||
| .statusCode(200) | ||||||||||||||||||||||||||||||||||||||||||||||||
| .body("stories.size()", equalTo(2)) | ||||||||||||||||||||||||||||||||||||||||||||||||
| .body("stories[0].storyId", equalTo(1)) | ||||||||||||||||||||||||||||||||||||||||||||||||
| .body("stories[0].imageUrl", equalTo("https://s3.bucket.com/story/dummy/1.jpg")); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
| Response response = given() | |
| .queryParam("size", 5) | |
| .when() | |
| .get("/api/stories"); | |
| response.then() | |
| .statusCode(200) | |
| .body("stories.size()", equalTo(2)) | |
| .body("stories[0].storyId", equalTo(1)) | |
| .body("stories[0].imageUrl", equalTo("https://s3.bucket.com/story/dummy/1.jpg")); | |
| } | |
| StoriesResponse response = given() | |
| .queryParam("size", 5) | |
| .when() | |
| .get("/api/stories") | |
| .then().statusCode(200) | |
| .extract().as(StoriesResponse.class); | |
| assertAll( | |
| () -> assertThat(response.stories()).hasSize(2), | |
| .... | |
| ); | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 DTO로 역직렬화 해서 사용하는 방식이군요!
이게 더 깔끔하고 좋은것 같아요!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍