|
5 | 5 | import static org.mockito.Mockito.doReturn; |
6 | 6 | import static org.mockito.Mockito.doThrow; |
7 | 7 | 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; |
8 | 11 | import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; |
9 | 12 | import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; |
10 | 13 | import static org.springframework.restdocs.request.RequestDocumentation.partWithName; |
11 | 14 |
|
| 15 | +import eatda.controller.story.StoriesDetailResponse; |
| 16 | +import eatda.controller.story.StoriesDetailResponse.StoryDetailResponse; |
12 | 17 | import eatda.controller.story.StoriesResponse; |
13 | 18 | import eatda.controller.story.StoryRegisterRequest; |
14 | 19 | import eatda.controller.story.StoryRegisterResponse; |
|
26 | 31 | import java.util.List; |
27 | 32 | import org.junit.jupiter.api.Nested; |
28 | 33 | import org.junit.jupiter.api.Test; |
| 34 | +import org.junit.jupiter.params.ParameterizedTest; |
| 35 | +import org.junit.jupiter.params.provider.EnumSource; |
29 | 36 | import org.springframework.http.HttpHeaders; |
30 | 37 | import org.springframework.restdocs.restassured.RestDocumentationFilter; |
31 | 38 |
|
@@ -162,21 +169,23 @@ class GetStory { |
162 | 169 |
|
163 | 170 | RestDocsResponse responseDocument = response() |
164 | 171 | .responseBodyField( |
165 | | - fieldWithPath("storeKakaoId").description("가게의 카카오 ID"), |
166 | | - fieldWithPath("category").description("가게 카테고리"), |
167 | | - fieldWithPath("storeName").description("가게 이름"), |
168 | | - fieldWithPath("storeDistrict").description("가게 주소의 구"), |
169 | | - fieldWithPath("storeNeighborhood").description("가게 주소의 동"), |
170 | | - fieldWithPath("description").description("스토리 내용"), |
171 | | - fieldWithPath("imageUrl").description("스토리 이미지 URL"), |
172 | | - fieldWithPath("memberId").description("회원 ID"), |
173 | | - fieldWithPath("memberNickname").description("회원 닉네임") |
| 172 | + fieldWithPath("storeId").type(NUMBER).description("가게의 카카오 ID (nullable)").optional(), |
| 173 | + fieldWithPath("storeKakaoId").type(STRING).description("가게의 카카오 ID"), |
| 174 | + fieldWithPath("category").type(STRING).description("가게 카테고리"), |
| 175 | + fieldWithPath("storeName").type(STRING).description("가게 이름"), |
| 176 | + fieldWithPath("storeDistrict").type(STRING).description("가게 주소의 구"), |
| 177 | + fieldWithPath("storeNeighborhood").type(STRING).description("가게 주소의 동"), |
| 178 | + fieldWithPath("description").type(STRING).description("스토리 내용"), |
| 179 | + fieldWithPath("imageUrl").type(STRING).description("스토리 이미지 URL"), |
| 180 | + fieldWithPath("memberId").type(NUMBER).description("회원 ID"), |
| 181 | + fieldWithPath("memberNickname").type(STRING).description("회원 닉네임") |
174 | 182 | ); |
175 | 183 |
|
176 | 184 | @Test |
177 | 185 | void 스토리_상세_조회_성공() { |
178 | 186 | long storyId = 1L; |
179 | 187 | StoryResponse response = new StoryResponse( |
| 188 | + null, |
180 | 189 | "123456", |
181 | 190 | "한식", |
182 | 191 | "진또곱창집", |
@@ -223,4 +232,68 @@ class GetStory { |
223 | 232 | .body("message", equalTo(BusinessErrorCode.STORY_NOT_FOUND.getMessage())); |
224 | 233 | } |
225 | 234 | } |
| 235 | + |
| 236 | + @Nested |
| 237 | + class GetStoriesByKakaoId { |
| 238 | + |
| 239 | + RestDocsRequest requestDocument = request() |
| 240 | + .tag(Tag.STORY_API) |
| 241 | + .summary("카카오 ID로 스토리 목록 조회") |
| 242 | + .description("특정 카카오 ID에 해당하는 스토리 목록을 페이지네이션하여 조회합니다.") |
| 243 | + .pathParameter( |
| 244 | + parameterWithName("kakaoId").description("가게의 카카오 ID") |
| 245 | + ) |
| 246 | + .queryParameter( |
| 247 | + parameterWithName("size").description("스토리 개수 (기본값: 5) (최소값: 1, 최대값: 50)").optional() |
| 248 | + ); |
| 249 | + |
| 250 | + RestDocsResponse responseDocument = response() |
| 251 | + .responseBodyField( |
| 252 | + fieldWithPath("stories").type(ARRAY).description("스토리 상세 리스트"), |
| 253 | + fieldWithPath("stories[].storyId").type(NUMBER).description("스토리 ID"), |
| 254 | + fieldWithPath("stories[].imageUrl").type(STRING).description("스토리 이미지 URL"), |
| 255 | + fieldWithPath("stories[].memberId").type(NUMBER).description("회원 ID"), |
| 256 | + fieldWithPath("stories[].memberNickname").type(STRING).description("회원 닉네임") |
| 257 | + ); |
| 258 | + |
| 259 | + @Test |
| 260 | + void 카카오_ID로_스토리_목록_조회_성공() { |
| 261 | + String kakaoId = "123456"; |
| 262 | + int size = 5; |
| 263 | + StoriesDetailResponse response = new StoriesDetailResponse(List.of( |
| 264 | + new StoryDetailResponse(1L, "https://dummy-s3.com/story1.png", 1L, "커찬"), |
| 265 | + new StoryDetailResponse(2L, "https://dummy-s3.com/story2.png", 2L, "준환") |
| 266 | + )); |
| 267 | + doReturn(response).when(storyService).getPagedStoryDetails(kakaoId, size); |
| 268 | + |
| 269 | + var document = document("story/get-stories-by-kakao-id", 200) |
| 270 | + .request(requestDocument) |
| 271 | + .response(responseDocument) |
| 272 | + .build(); |
| 273 | + |
| 274 | + given(document) |
| 275 | + .queryParam("size", size) |
| 276 | + .header(HttpHeaders.AUTHORIZATION, accessToken()) |
| 277 | + .when().get("/api/stories/kakao/{kakaoId}", kakaoId) |
| 278 | + .then().statusCode(200); |
| 279 | + } |
| 280 | + |
| 281 | + @EnumSource(value = BusinessErrorCode.class, names = {"PRESIGNED_URL_GENERATION_FAILED"}) |
| 282 | + @ParameterizedTest |
| 283 | + void 카카오_ID로_스토리_목록_조회_실패(BusinessErrorCode errorCode) { |
| 284 | + String kakaoId = "nonexistent"; |
| 285 | + int size = 5; |
| 286 | + doThrow(new BusinessException(errorCode)).when(storyService).getPagedStoryDetails(kakaoId, size); |
| 287 | + |
| 288 | + var document = document("story/get-stories-by-kakao-id", errorCode) |
| 289 | + .request(requestDocument) |
| 290 | + .response(ERROR_RESPONSE) |
| 291 | + .build(); |
| 292 | + |
| 293 | + given(document) |
| 294 | + .queryParam("size", size) |
| 295 | + .when().get("/api/stories/kakao/{kakaoId}", kakaoId) |
| 296 | + .then().statusCode(errorCode.getStatus().value()); |
| 297 | + } |
| 298 | + } |
226 | 299 | } |
0 commit comments