diff --git a/src/main/java/eatda/controller/story/StoryResponse.java b/src/main/java/eatda/controller/story/StoryResponse.java index 7a075362..b2df9ca9 100644 --- a/src/main/java/eatda/controller/story/StoryResponse.java +++ b/src/main/java/eatda/controller/story/StoryResponse.java @@ -1,6 +1,9 @@ package eatda.controller.story; +import org.springframework.lang.Nullable; + public record StoryResponse( + @Nullable Long storeId, String storeKakaoId, String category, String storeName, @@ -11,4 +14,5 @@ public record StoryResponse( long memberId, String memberNickname ) { + } diff --git a/src/main/java/eatda/service/story/StoryService.java b/src/main/java/eatda/service/story/StoryService.java index 9a406465..caebd506 100644 --- a/src/main/java/eatda/service/story/StoryService.java +++ b/src/main/java/eatda/service/story/StoryService.java @@ -11,10 +11,12 @@ import eatda.domain.ImageDomain; import eatda.domain.ImageKey; import eatda.domain.member.Member; +import eatda.domain.store.Store; import eatda.domain.story.Story; import eatda.exception.BusinessErrorCode; import eatda.exception.BusinessException; import eatda.repository.member.MemberRepository; +import eatda.repository.store.StoreRepository; import eatda.repository.story.StoryRepository; import eatda.storage.image.ImageStorage; import java.util.List; @@ -35,6 +37,7 @@ public class StoryService { private final ImageStorage imageStorage; private final MapClient mapClient; private final StoryRepository storyRepository; + private final StoreRepository storeRepository; private final MemberRepository memberRepository; @Transactional @@ -93,8 +96,12 @@ public StoriesResponse getPagedStoryPreviews(int size) { public StoryResponse getStory(long storyId) { Story story = storyRepository.findById(storyId) .orElseThrow(() -> new BusinessException(BusinessErrorCode.STORY_NOT_FOUND)); + Long storeId = storeRepository.findByKakaoId(story.getStoreKakaoId()) + .map(Store::getId) + .orElse(null); return new StoryResponse( + storeId, story.getStoreKakaoId(), story.getStoreCategory().getCategoryName(), story.getStoreName(), diff --git a/src/test/java/eatda/controller/story/StoryControllerTest.java b/src/test/java/eatda/controller/story/StoryControllerTest.java index 4a3dfde4..8084412b 100644 --- a/src/test/java/eatda/controller/story/StoryControllerTest.java +++ b/src/test/java/eatda/controller/story/StoryControllerTest.java @@ -90,6 +90,7 @@ class GetStory { long storyId = 1L; doReturn(new StoryResponse( + 5L, "123456", "한식", "진또곱창집", @@ -110,6 +111,7 @@ class GetStory { .extract().as(StoryResponse.class); assertAll( + () -> assertThat(response.storeId()).isEqualTo(5L), () -> assertThat(response.storeKakaoId()).isEqualTo("123456"), () -> assertThat(response.category()).isEqualTo("한식"), () -> assertThat(response.storeName()).isEqualTo("진또곱창집"), diff --git a/src/test/java/eatda/document/story/StoryDocumentTest.java b/src/test/java/eatda/document/story/StoryDocumentTest.java index a3f76ec2..a9169935 100644 --- a/src/test/java/eatda/document/story/StoryDocumentTest.java +++ b/src/test/java/eatda/document/story/StoryDocumentTest.java @@ -5,6 +5,8 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.payload.JsonFieldType.NUMBER; +import static org.springframework.restdocs.payload.JsonFieldType.STRING; import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; import static org.springframework.restdocs.request.RequestDocumentation.partWithName; @@ -162,21 +164,23 @@ class GetStory { RestDocsResponse responseDocument = response() .responseBodyField( - fieldWithPath("storeKakaoId").description("가게의 카카오 ID"), - fieldWithPath("category").description("가게 카테고리"), - fieldWithPath("storeName").description("가게 이름"), - fieldWithPath("storeDistrict").description("가게 주소의 구"), - fieldWithPath("storeNeighborhood").description("가게 주소의 동"), - fieldWithPath("description").description("스토리 내용"), - fieldWithPath("imageUrl").description("스토리 이미지 URL"), - fieldWithPath("memberId").description("회원 ID"), - fieldWithPath("memberNickname").description("회원 닉네임") + fieldWithPath("storeId").type(NUMBER).description("가게의 카카오 ID (nullable)").optional(), + fieldWithPath("storeKakaoId").type(STRING).description("가게의 카카오 ID"), + fieldWithPath("category").type(STRING).description("가게 카테고리"), + fieldWithPath("storeName").type(STRING).description("가게 이름"), + fieldWithPath("storeDistrict").type(STRING).description("가게 주소의 구"), + fieldWithPath("storeNeighborhood").type(STRING).description("가게 주소의 동"), + fieldWithPath("description").type(STRING).description("스토리 내용"), + fieldWithPath("imageUrl").type(STRING).description("스토리 이미지 URL"), + fieldWithPath("memberId").type(NUMBER).description("회원 ID"), + fieldWithPath("memberNickname").type(STRING).description("회원 닉네임") ); @Test void 스토리_상세_조회_성공() { long storyId = 1L; StoryResponse response = new StoryResponse( + null, "123456", "한식", "진또곱창집", diff --git a/src/test/java/eatda/service/story/StoryServiceTest.java b/src/test/java/eatda/service/story/StoryServiceTest.java index 6e29e374..04d2c1f8 100644 --- a/src/test/java/eatda/service/story/StoryServiceTest.java +++ b/src/test/java/eatda/service/story/StoryServiceTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertAll; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -12,6 +13,7 @@ import eatda.controller.story.StoryResponse; import eatda.domain.ImageKey; import eatda.domain.member.Member; +import eatda.domain.store.Store; import eatda.domain.store.StoreCategory; import eatda.domain.story.Story; import eatda.exception.BusinessErrorCode; @@ -107,7 +109,7 @@ class GetPagedStoryPreviews { class GetStory { @Test - void 스토리_상세_정보를_조회할_수_있다() { + void 스토리_상세_정보를_조회할_때_스토어ID가_없으면_NULL로_반환된다() { Member member = memberGenerator.generate("99999"); Story story = Story.builder() @@ -120,7 +122,41 @@ class GetStory { .description("곱창은 여기") .imageKey(new ImageKey("story-image-key")) .build(); + storyRepository.save(story); + + when(externalImageStorage.getPreSignedUrl(new ImageKey("story-image-key"))) + .thenReturn("https://s3.bucket.com/story/dummy/1.jpg"); + + StoryResponse response = storyService.getStory(story.getId()); + assertAll( + () -> assertThat(response.storeId()).isNull(), + () -> assertThat(response.storeKakaoId()).isEqualTo("123456"), + () -> assertThat(response.category()).isEqualTo("한식"), + () -> assertThat(response.storeName()).isEqualTo("진또곱창집"), + () -> assertThat(response.storeDistrict()).isEqualTo("성동구"), + () -> assertThat(response.storeNeighborhood()).isEqualTo("성수동1가"), + () -> assertThat(response.description()).isEqualTo("곱창은 여기"), + () -> assertThat(response.imageUrl()).isEqualTo("https://s3.bucket.com/story/dummy/1.jpg"), + () -> assertThat(response.memberId()).isEqualTo(member.getId()), + () -> assertThat(response.memberNickname()).isEqualTo(member.getNickname()) + ); + } + + @Test + void 스토리_상세_정보를_조회할_때_스토어ID가_있으면_해당_ID값을_반환한다() { + Member member = memberGenerator.generate("99999"); + Store store = storeGenerator.generate("123456", "서울시 성북구 장위동 123-45"); + Story story = Story.builder() + .member(member) + .storeKakaoId("123456") + .storeName("진또곱창집") + .storeRoadAddress("서울시 성동구 왕십리로 1길 12") + .storeLotNumberAddress("서울시 성동구 성수동1가 685-12") + .storeCategory(StoreCategory.KOREAN) + .description("곱창은 여기") + .imageKey(new ImageKey("story-image-key")) + .build(); storyRepository.save(story); when(externalImageStorage.getPreSignedUrl(new ImageKey("story-image-key"))) @@ -128,13 +164,18 @@ class GetStory { StoryResponse response = storyService.getStory(story.getId()); - assertThat(response.storeKakaoId()).isEqualTo("123456"); - assertThat(response.category()).isEqualTo("한식"); - assertThat(response.storeName()).isEqualTo("진또곱창집"); - assertThat(response.storeDistrict()).isEqualTo("성동구"); - assertThat(response.storeNeighborhood()).isEqualTo("성수동1가"); - assertThat(response.description()).isEqualTo("곱창은 여기"); - assertThat(response.imageUrl()).isEqualTo("https://s3.bucket.com/story/dummy/1.jpg"); + assertAll( + () -> assertThat(response.storeId()).isEqualTo(store.getId()), + () -> assertThat(response.storeKakaoId()).isEqualTo("123456"), + () -> assertThat(response.category()).isEqualTo("한식"), + () -> assertThat(response.storeName()).isEqualTo("진또곱창집"), + () -> assertThat(response.storeDistrict()).isEqualTo("성동구"), + () -> assertThat(response.storeNeighborhood()).isEqualTo("성수동1가"), + () -> assertThat(response.description()).isEqualTo("곱창은 여기"), + () -> assertThat(response.imageUrl()).isEqualTo("https://s3.bucket.com/story/dummy/1.jpg"), + () -> assertThat(response.memberId()).isEqualTo(member.getId()), + () -> assertThat(response.memberNickname()).isEqualTo(member.getNickname()) + ); } @Test