diff --git a/src/main/java/com/somemore/center/controller/CenterQueryApiController.java b/src/main/java/com/somemore/center/controller/CenterQueryApiController.java new file mode 100644 index 000000000..ef62e9d50 --- /dev/null +++ b/src/main/java/com/somemore/center/controller/CenterQueryApiController.java @@ -0,0 +1,32 @@ +package com.somemore.center.controller; + +import com.somemore.center.dto.response.CenterProfileResponseDto; +import com.somemore.center.usecase.query.CenterQueryUseCase; +import com.somemore.global.common.response.ApiResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.UUID; + +@RequiredArgsConstructor +@RestController +@RequestMapping("/api/center") +@Tag(name = "Center Query API", description = "기관 관련 조회 API를 제공합니다.") +public class CenterQueryApiController { + + private final CenterQueryUseCase centerQueryUseCase; + + @Operation(summary = "기관 프로필 조회 API") + @GetMapping("/profile/{centerId}") + public ApiResponse getCenterProfile(@PathVariable UUID centerId) { + + CenterProfileResponseDto responseDto = centerQueryUseCase.getCenterProfileByCenterId(centerId); + + return ApiResponse.ok(200, responseDto, "기관 프로필 조회 성공"); + } +} diff --git a/src/main/java/com/somemore/center/domain/Center.java b/src/main/java/com/somemore/center/domain/Center.java index a13f964f2..a957772fd 100644 --- a/src/main/java/com/somemore/center/domain/Center.java +++ b/src/main/java/com/somemore/center/domain/Center.java @@ -14,7 +14,7 @@ public class Center extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.UUID) - @Column(nullable = false, length = 16) + @Column(nullable = false, columnDefinition = "BINARY(16)") private UUID id; @Column(name = "name", nullable = false) diff --git a/src/main/java/com/somemore/center/dto/response/CenterProfileResponseDto.java b/src/main/java/com/somemore/center/dto/response/CenterProfileResponseDto.java index 7ccf73d63..5acb4713a 100644 --- a/src/main/java/com/somemore/center/dto/response/CenterProfileResponseDto.java +++ b/src/main/java/com/somemore/center/dto/response/CenterProfileResponseDto.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.annotation.JsonNaming; import com.somemore.center.domain.Center; import com.somemore.center.domain.PreferItem; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import java.util.List; @@ -12,12 +13,25 @@ @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) @Builder public record CenterProfileResponseDto( + @Schema(description = "센터 ID", example = "123e4567-e89b-12d3-a456-426614174000") UUID centerId, + + @Schema(description = "센터 이름", example = "서울 도서관") String name, + + @Schema(description = "연락처", example = "010-1234-5678") String contactNumber, + + @Schema(description = "센터 이미지 URL", example = "https://example.com/images/center.jpg") String imgUrl, + + @Schema(description = "센터 소개", example = "저희 도서관은 유명해요") String introduce, + + @Schema(description = "센터 홈페이지 링크", example = "https://fitnesscenter.com") String homepageLink, + + @Schema(description = "선호 물품 리스트") List preferItems ) { public static CenterProfileResponseDto of(Center center, List preferItemDtos) { diff --git a/src/main/java/com/somemore/global/exception/ExceptionMessage.java b/src/main/java/com/somemore/global/exception/ExceptionMessage.java index 9a2f41794..01176f829 100644 --- a/src/main/java/com/somemore/global/exception/ExceptionMessage.java +++ b/src/main/java/com/somemore/global/exception/ExceptionMessage.java @@ -8,7 +8,7 @@ @Getter public enum ExceptionMessage { - NOT_EXISTS_CENTER("존재하지 않는 기관 ID 입니다."), + NOT_EXISTS_CENTER("존재하지 않는 기관 입니다."), NOT_EXISTS_COMMUNITY_BOARD("존재하지 않는 게시글 입니다."), UNAUTHORIZED_COMMUNITY_BOARD("해당 게시글에 권한이 없습니다."), NOT_EXISTS_COMMUNITY_COMMENT("존재하지 않는 댓글 입니다."), diff --git a/src/test/java/com/somemore/ControllerTestSupport.java b/src/test/java/com/somemore/ControllerTestSupport.java new file mode 100644 index 000000000..27537fc4a --- /dev/null +++ b/src/test/java/com/somemore/ControllerTestSupport.java @@ -0,0 +1,21 @@ +package com.somemore; + + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; + +@ActiveProfiles("test") +@SpringBootTest +@AutoConfigureMockMvc +public abstract class ControllerTestSupport { + + @Autowired + protected MockMvc mockMvc; + + @Autowired + protected ObjectMapper objectMapper; +} diff --git a/src/test/java/com/somemore/center/controller/CenterQueryApiControllerTest.java b/src/test/java/com/somemore/center/controller/CenterQueryApiControllerTest.java new file mode 100644 index 000000000..904b231ea --- /dev/null +++ b/src/test/java/com/somemore/center/controller/CenterQueryApiControllerTest.java @@ -0,0 +1,93 @@ +package com.somemore.center.controller; + +import com.somemore.ControllerTestSupport; +import com.somemore.center.dto.response.CenterProfileResponseDto; +import com.somemore.center.usecase.query.CenterQueryUseCase; +import com.somemore.global.exception.BadRequestException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; + +import java.util.List; +import java.util.UUID; + +import static com.somemore.global.exception.ExceptionMessage.NOT_EXISTS_CENTER; +import static org.mockito.Mockito.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; + +class CenterQueryApiControllerTest extends ControllerTestSupport { + + @MockBean + protected CenterQueryUseCase centerQueryUseCase; + + private UUID centerId; + private CenterProfileResponseDto responseDto; + + @BeforeEach + void setUp() { + centerId = UUID.randomUUID(); + responseDto = CenterProfileResponseDto.builder() + .centerId(centerId) + .name("Test Center") + .contactNumber("010-1234-5678") + .imgUrl("http://example.com/image.jpg") + .introduce("This is a test center.") + .homepageLink("http://example.com") + .preferItems(List.of()) + .build(); + } + + @DisplayName("기관 ID로 기관 프로필을 조회할 수 있다. (controller)") + @Test + void getCenterProfile() throws Exception { + // given + when(centerQueryUseCase.getCenterProfileByCenterId(centerId)).thenReturn(responseDto); + + // when // then + mockMvc.perform( + get("/api/center/profile/{centerId}", centerId) + .contentType(MediaType.APPLICATION_JSON) + ) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value("200")) + .andExpect(jsonPath("$.message").value("기관 프로필 조회 성공")) + .andExpect(jsonPath("$.data.center_id").value(centerId.toString())) // center_id로 수정 + .andExpect(jsonPath("$.data.name").value("Test Center")) + .andExpect(jsonPath("$.data.contact_number").value("010-1234-5678")) // contact_number로 수정 + .andExpect(jsonPath("$.data.img_url").value("http://example.com/image.jpg")) // img_url로 수정 + .andExpect(jsonPath("$.data.introduce").value("This is a test center.")) + .andExpect(jsonPath("$.data.homepage_link").value("http://example.com")) // homepage_link로 수정 + .andExpect(jsonPath("$.data.prefer_items").isArray()); // prefer_items로 수정 + + verify(centerQueryUseCase, times(1)).getCenterProfileByCenterId(centerId); + } + + @DisplayName("존재하지 않는 기관 ID로 조회 시 예외가 발생한다. (controller)") + @Test + void getCenterProfile_NotFound() throws Exception { + // given + UUID nonExistentCenterId = UUID.randomUUID(); + when(centerQueryUseCase.getCenterProfileByCenterId(nonExistentCenterId)) + .thenThrow(new BadRequestException(NOT_EXISTS_CENTER.getMessage())); + + // when // then + mockMvc.perform( + get("/api/center/profile/{centerId}", nonExistentCenterId) + .contentType(MediaType.APPLICATION_JSON) + ) + .andDo(print()) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.status").value("400")) + .andExpect(jsonPath("$.detail").value("존재하지 않는 기관 입니다.")); + + verify(centerQueryUseCase, times(1)).getCenterProfileByCenterId(nonExistentCenterId); + } + +} +