Skip to content

Commit ce915dc

Browse files
committed
feat: '카카오 ID를 통한 스토리 조회' API 구현
1 parent 83e557d commit ce915dc

File tree

3 files changed

+115
-0
lines changed

3 files changed

+115
-0
lines changed

src/main/java/eatda/controller/story/StoryController.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,13 @@ public ResponseEntity<StoryResponse> getStory(@PathVariable long storyId) {
4242
return ResponseEntity.status(HttpStatus.OK)
4343
.body(storyService.getStory(storyId));
4444
}
45+
46+
@GetMapping("/api/stories/kakao/{kakaoId}")
47+
public ResponseEntity<StoriesDetailResponse> getStoriesByKakaoId(
48+
@PathVariable String kakaoId,
49+
@RequestParam(defaultValue = "5") @Min(1) @Max(50) int size
50+
) {
51+
return ResponseEntity.status(HttpStatus.OK)
52+
.body(storyService.getPagedStoryDetails(kakaoId, size));
53+
}
4554
}

src/test/java/eatda/controller/story/StoryControllerTest.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import static org.mockito.Mockito.doThrow;
99

1010
import eatda.controller.BaseControllerTest;
11+
import eatda.controller.story.StoriesDetailResponse.StoryDetailResponse;
1112
import eatda.exception.BusinessErrorCode;
1213
import eatda.exception.BusinessException;
1314
import eatda.util.ImageUtils;
@@ -137,4 +138,38 @@ class GetStory {
137138
.body("message", equalTo(BusinessErrorCode.STORY_NOT_FOUND.getMessage()));
138139
}
139140
}
141+
142+
@Nested
143+
class GetPagedStoryDetailsByKakaoId {
144+
145+
@Test
146+
void 카카오ID로_스토리_목록을_조회할_수_있다() {
147+
String kakaoId = "123456";
148+
List<StoryDetailResponse> mockDetails = List.of(
149+
new StoryDetailResponse(1L, "https://s3.bucket.com/story/dummy/1.jpg", 5L, "커찬"),
150+
new StoryDetailResponse(2L, "https://s3.bucket.com/story/dummy/2.jpg", 2L, "지민")
151+
);
152+
153+
doReturn(new StoriesDetailResponse(mockDetails))
154+
.when(storyService)
155+
.getPagedStoryDetails(kakaoId, 5);
156+
157+
StoriesDetailResponse response = given()
158+
.pathParam("kakaoId", kakaoId)
159+
.queryParam("size", 5)
160+
.when()
161+
.get("/api/stories/kakao/{kakaoId}")
162+
.then().statusCode(200)
163+
.extract().as(StoriesDetailResponse.class);
164+
165+
assertAll(
166+
() -> assertThat(response.stories()).hasSize(2),
167+
() -> assertThat(response.stories().getFirst().storyId()).isEqualTo(1L),
168+
() -> assertThat(response.stories().getFirst().imageUrl()).isEqualTo(
169+
"https://s3.bucket.com/story/dummy/1.jpg"),
170+
() -> assertThat(response.stories().getFirst().memberId()).isEqualTo(5L),
171+
() -> assertThat(response.stories().getFirst().memberNickname()).isEqualTo("커찬")
172+
);
173+
}
174+
}
140175
}

src/test/java/eatda/document/story/StoryDocumentTest.java

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,15 @@
55
import static org.mockito.Mockito.doReturn;
66
import static org.mockito.Mockito.doThrow;
77
import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName;
8+
import static org.springframework.restdocs.payload.JsonFieldType.ARRAY;
9+
import static org.springframework.restdocs.payload.JsonFieldType.NUMBER;
10+
import static org.springframework.restdocs.payload.JsonFieldType.STRING;
811
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
912
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
1013
import static org.springframework.restdocs.request.RequestDocumentation.partWithName;
1114

15+
import eatda.controller.story.StoriesDetailResponse;
16+
import eatda.controller.story.StoriesDetailResponse.StoryDetailResponse;
1217
import eatda.controller.story.StoriesResponse;
1318
import eatda.controller.story.StoryRegisterRequest;
1419
import eatda.controller.story.StoryRegisterResponse;
@@ -26,6 +31,8 @@
2631
import java.util.List;
2732
import org.junit.jupiter.api.Nested;
2833
import org.junit.jupiter.api.Test;
34+
import org.junit.jupiter.params.ParameterizedTest;
35+
import org.junit.jupiter.params.provider.EnumSource;
2936
import org.springframework.http.HttpHeaders;
3037
import org.springframework.restdocs.restassured.RestDocumentationFilter;
3138

@@ -223,4 +230,68 @@ class GetStory {
223230
.body("message", equalTo(BusinessErrorCode.STORY_NOT_FOUND.getMessage()));
224231
}
225232
}
233+
234+
@Nested
235+
class GetStoriesByKakaoId {
236+
237+
RestDocsRequest requestDocument = request()
238+
.tag(Tag.STORY_API)
239+
.summary("카카오 ID로 스토리 목록 조회")
240+
.description("특정 카카오 ID에 해당하는 스토리 목록을 페이지네이션하여 조회합니다.")
241+
.pathParameter(
242+
parameterWithName("kakaoId").description("가게의 카카오 ID")
243+
)
244+
.queryParameter(
245+
parameterWithName("size").description("스토리 개수 (기본값: 5) (최소값: 1, 최대값: 50)").optional()
246+
);
247+
248+
RestDocsResponse responseDocument = response()
249+
.responseBodyField(
250+
fieldWithPath("stories").type(ARRAY).description("스토리 상세 리스트"),
251+
fieldWithPath("stories[].storyId").type(NUMBER).description("스토리 ID"),
252+
fieldWithPath("stories[].imageUrl").type(STRING).description("스토리 이미지 URL"),
253+
fieldWithPath("stories[].memberId").type(NUMBER).description("회원 ID"),
254+
fieldWithPath("stories[].memberNickname").type(STRING).description("회원 닉네임")
255+
);
256+
257+
@Test
258+
void 카카오_ID로_스토리_목록_조회_성공() {
259+
String kakaoId = "123456";
260+
int size = 5;
261+
StoriesDetailResponse response = new StoriesDetailResponse(List.of(
262+
new StoryDetailResponse(1L, "https://dummy-s3.com/story1.png", 1L, "커찬"),
263+
new StoryDetailResponse(2L, "https://dummy-s3.com/story2.png", 2L, "준환")
264+
));
265+
doReturn(response).when(storyService).getPagedStoryDetails(kakaoId, size);
266+
267+
var document = document("story/get-stories-by-kakao-id", 200)
268+
.request(requestDocument)
269+
.response(responseDocument)
270+
.build();
271+
272+
given(document)
273+
.queryParam("size", size)
274+
.header(HttpHeaders.AUTHORIZATION, accessToken())
275+
.when().get("/api/stories/kakao/{kakaoId}", kakaoId)
276+
.then().statusCode(200);
277+
}
278+
279+
@EnumSource(value = BusinessErrorCode.class, names = {"PRESIGNED_URL_GENERATION_FAILED"})
280+
@ParameterizedTest
281+
void 카카오_ID로_스토리_목록_조회_실패(BusinessErrorCode errorCode) {
282+
String kakaoId = "nonexistent";
283+
int size = 5;
284+
doThrow(new BusinessException(errorCode)).when(storyService).getPagedStoryDetails(kakaoId, size);
285+
286+
var document = document("story/get-stories-by-kakao-id", errorCode)
287+
.request(requestDocument)
288+
.response(ERROR_RESPONSE)
289+
.build();
290+
291+
given(document)
292+
.queryParam("size", size)
293+
.when().get("/api/stories/kakao/{kakaoId}", kakaoId)
294+
.then().statusCode(errorCode.getStatus().value());
295+
}
296+
}
226297
}

0 commit comments

Comments
 (0)