diff --git a/build.gradle b/build.gradle
index 5da91ed50..5ba7f9aaa 100644
--- a/build.gradle
+++ b/build.gradle
@@ -115,7 +115,8 @@ def jacocoExcludePatterns = [
'**/auth/**',
'**/domain/*',
'**/domains/*',
- '**/fixture/*'
+ '**/fixture/*',
+ '**/*Factory*'
]
def jacocoExcludePatternsForVerify = [
@@ -130,7 +131,8 @@ def jacocoExcludePatternsForVerify = [
'*.auth.*',
'*.domain.*',
'*.domains.*',
- '*.fixture.*'
+ '*.fixture.*',
+ '*.*Factory*'
]
jacocoTestReport {
diff --git a/src/main/java/com/somemore/center/repository/CenterRepository.java b/src/main/java/com/somemore/center/repository/CenterRepository.java
index 946553a08..93d501b49 100644
--- a/src/main/java/com/somemore/center/repository/CenterRepository.java
+++ b/src/main/java/com/somemore/center/repository/CenterRepository.java
@@ -1,8 +1,10 @@
package com.somemore.center.repository;
import com.somemore.center.domain.Center;
+import com.somemore.center.repository.mapper.CenterOverviewInfo;
import org.springframework.stereotype.Repository;
+import java.util.List;
import java.util.Optional;
import java.util.UUID;
@@ -14,5 +16,6 @@ default boolean doesNotExistById(UUID id) {
return !existsById(id);
}
Optional
findCenterById(UUID id);
+ List findCenterOverviewsByIds(List ids);
void deleteAllInBatch();
}
diff --git a/src/main/java/com/somemore/center/repository/CenterRepositoryImpl.java b/src/main/java/com/somemore/center/repository/CenterRepositoryImpl.java
index 67224b14f..b71acda45 100644
--- a/src/main/java/com/somemore/center/repository/CenterRepositoryImpl.java
+++ b/src/main/java/com/somemore/center/repository/CenterRepositoryImpl.java
@@ -1,9 +1,14 @@
package com.somemore.center.repository;
+import com.querydsl.core.types.Projections;
+import com.querydsl.jpa.impl.JPAQueryFactory;
import com.somemore.center.domain.Center;
+import com.somemore.center.domain.QCenter;
+import com.somemore.center.repository.mapper.CenterOverviewInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
+import java.util.List;
import java.util.Optional;
import java.util.UUID;
@@ -11,6 +16,7 @@
@Repository
public class CenterRepositoryImpl implements CenterRepository {
+ private final JPAQueryFactory queryFactory;
private final CenterJpaRepository centerJpaRepository;
@Override
@@ -28,6 +34,23 @@ public Optional findCenterById(UUID id) {
return centerJpaRepository.findCenterById(id);
}
+ @Override
+ public List findCenterOverviewsByIds(List ids) {
+ QCenter center = QCenter.center;
+
+ return queryFactory
+ .select(Projections.constructor(
+ CenterOverviewInfo.class,
+ center.id,
+ center.name,
+ center.imgUrl
+ ))
+ .from(center)
+ .where(center.id.in(ids)
+ .and(center.deleted.eq(false)))
+ .fetch();
+ }
+
@Override
public void deleteAllInBatch() {
centerJpaRepository.deleteAllInBatch();
diff --git a/src/main/java/com/somemore/center/repository/mapper/CenterOverviewInfo.java b/src/main/java/com/somemore/center/repository/mapper/CenterOverviewInfo.java
new file mode 100644
index 000000000..d770935aa
--- /dev/null
+++ b/src/main/java/com/somemore/center/repository/mapper/CenterOverviewInfo.java
@@ -0,0 +1,12 @@
+package com.somemore.center.repository.mapper;
+
+
+import java.util.UUID;
+
+public record CenterOverviewInfo(
+ UUID centerId,
+ String centerName,
+ String imgUrl
+) {
+
+}
diff --git a/src/main/java/com/somemore/center/service/query/CenterQueryService.java b/src/main/java/com/somemore/center/service/query/CenterQueryService.java
index 29f0cfc4e..81a19f21b 100644
--- a/src/main/java/com/somemore/center/service/query/CenterQueryService.java
+++ b/src/main/java/com/somemore/center/service/query/CenterQueryService.java
@@ -1,6 +1,7 @@
package com.somemore.center.service.query;
import com.somemore.center.domain.Center;
+import com.somemore.center.repository.mapper.CenterOverviewInfo;
import com.somemore.center.dto.response.CenterProfileResponseDto;
import com.somemore.center.dto.response.PreferItemResponseDto;
import com.somemore.center.repository.CenterRepository;
@@ -33,6 +34,11 @@ public CenterProfileResponseDto getCenterProfileByCenterId(UUID centerId) {
return CenterProfileResponseDto.of(center, preferItemDtos);
}
+ @Override
+ public List getCenterOverviewsByIds(List centerIds) {
+ return centerRepository.findCenterOverviewsByIds(centerIds);
+ }
+
@Override
public void validateCenterExists(UUID id) {
if (centerRepository.doesNotExistById(id)) {
diff --git a/src/main/java/com/somemore/center/usecase/query/CenterQueryUseCase.java b/src/main/java/com/somemore/center/usecase/query/CenterQueryUseCase.java
index 7c12cb28c..3f381ec3c 100644
--- a/src/main/java/com/somemore/center/usecase/query/CenterQueryUseCase.java
+++ b/src/main/java/com/somemore/center/usecase/query/CenterQueryUseCase.java
@@ -1,11 +1,13 @@
package com.somemore.center.usecase.query;
+import com.somemore.center.repository.mapper.CenterOverviewInfo;
import com.somemore.center.dto.response.CenterProfileResponseDto;
+import java.util.List;
import java.util.UUID;
public interface CenterQueryUseCase {
-
CenterProfileResponseDto getCenterProfileByCenterId(UUID centerId);
+ List getCenterOverviewsByIds(List centerIds);
void validateCenterExists(UUID centerId);
}
diff --git a/src/main/java/com/somemore/interestcenter/controller/InterestCenterQueryApiController.java b/src/main/java/com/somemore/interestcenter/controller/InterestCenterQueryApiController.java
new file mode 100644
index 000000000..1b8cd43d2
--- /dev/null
+++ b/src/main/java/com/somemore/interestcenter/controller/InterestCenterQueryApiController.java
@@ -0,0 +1,32 @@
+package com.somemore.interestcenter.controller;
+
+import com.somemore.global.common.response.ApiResponse;
+import com.somemore.interestcenter.dto.response.InterestCentersResponseDto;
+import com.somemore.interestcenter.usecase.InterestCenterQueryUseCase;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.core.annotation.AuthenticationPrincipal;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+import java.util.UUID;
+
+@RequiredArgsConstructor
+@RestController
+@Tag(name = "Interest Center Query API", description = "관심 기관의 조회 API를 제공합니다")
+public class InterestCenterQueryApiController {
+
+ private final InterestCenterQueryUseCase interestCenterQueryUseCase;
+
+ @Operation(summary = "관심기관 목록 조회 API")
+ @GetMapping("/api/interest-centers")
+ public ApiResponse> getInterestCenters(@AuthenticationPrincipal String volunteerId) {
+
+ List responseDtos = interestCenterQueryUseCase.getInterestCenters(UUID.fromString(volunteerId));
+
+ return ApiResponse.ok(200, responseDtos, "관심기관 조회 성공");
+ }
+
+}
diff --git a/src/main/java/com/somemore/interestcenter/dto/response/InterestCentersResponseDto.java b/src/main/java/com/somemore/interestcenter/dto/response/InterestCentersResponseDto.java
new file mode 100644
index 000000000..0584550b2
--- /dev/null
+++ b/src/main/java/com/somemore/interestcenter/dto/response/InterestCentersResponseDto.java
@@ -0,0 +1,28 @@
+package com.somemore.interestcenter.dto.response;
+
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+import com.somemore.center.repository.mapper.CenterOverviewInfo;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Builder;
+
+import java.util.UUID;
+
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
+@Builder
+public record InterestCentersResponseDto(
+ @Schema(description = "관심기관의 ID", example = "123e4567-e89b-12d3-a456-426614174000")
+ UUID centerId,
+ @Schema(description = "관심기관의 이름", example = "서울 도서관")
+ String centerName,
+ @Schema(description = "관심기관의 프로필 이미지 링크", example = "~~/image.jpeg")
+ String imgUrl
+) {
+ public static InterestCentersResponseDto of(CenterOverviewInfo responseDto) {
+ return InterestCentersResponseDto.builder()
+ .centerId(responseDto.centerId())
+ .centerName(responseDto.centerName())
+ .imgUrl(responseDto.imgUrl())
+ .build();
+ }
+}
diff --git a/src/main/java/com/somemore/interestcenter/dto/response/RegisterInterestCenterResponseDto.java b/src/main/java/com/somemore/interestcenter/dto/response/RegisterInterestCenterResponseDto.java
index 4a20fa957..797c485c2 100644
--- a/src/main/java/com/somemore/interestcenter/dto/response/RegisterInterestCenterResponseDto.java
+++ b/src/main/java/com/somemore/interestcenter/dto/response/RegisterInterestCenterResponseDto.java
@@ -17,7 +17,7 @@ public record RegisterInterestCenterResponseDto(
@Schema(description = "봉사자 ID", example = "123e4567-e89b-12d3-a456-426614174000")
UUID volunteerId,
- @Schema(description = "센터 ID", example = "123e4567-e89b-12d3-a456-426614174000")
+ @Schema(description = "기관 ID", example = "123e4567-e89b-12d3-a456-426614174000")
UUID centerId
) {
public static RegisterInterestCenterResponseDto from(InterestCenter interestCenter) {
diff --git a/src/main/java/com/somemore/interestcenter/repository/InterestCenterRepository.java b/src/main/java/com/somemore/interestcenter/repository/InterestCenterRepository.java
index 14b07b2d2..4292d2c4f 100644
--- a/src/main/java/com/somemore/interestcenter/repository/InterestCenterRepository.java
+++ b/src/main/java/com/somemore/interestcenter/repository/InterestCenterRepository.java
@@ -3,6 +3,7 @@
import com.somemore.interestcenter.domain.InterestCenter;
import com.somemore.interestcenter.dto.response.RegisterInterestCenterResponseDto;
+import java.util.List;
import java.util.Optional;
import java.util.UUID;
@@ -10,5 +11,6 @@ public interface InterestCenterRepository {
InterestCenter save(InterestCenter interestCenter);
Optional findById(Long id);
Optional findInterestCenterResponseById(Long id);
+ List findInterestCenterIdsByVolunteerId(UUID volunteerId);
boolean existsByVolunteerIdAndCenterId(UUID volunteerId, UUID centerId);
}
diff --git a/src/main/java/com/somemore/interestcenter/repository/InterestCenterRepositoryImpl.java b/src/main/java/com/somemore/interestcenter/repository/InterestCenterRepositoryImpl.java
index 5667967b8..b5f10c65c 100644
--- a/src/main/java/com/somemore/interestcenter/repository/InterestCenterRepositoryImpl.java
+++ b/src/main/java/com/somemore/interestcenter/repository/InterestCenterRepositoryImpl.java
@@ -8,6 +8,7 @@
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
+import java.util.List;
import java.util.Optional;
import java.util.UUID;
@@ -61,6 +62,20 @@ public Optional findInterestCenterResponseByI
return Optional.ofNullable(result);
}
+ @Override
+ public List findInterestCenterIdsByVolunteerId(UUID volunteerId) {
+ QInterestCenter interestCenter = QInterestCenter.interestCenter;
+
+ return queryFactory
+ .select(interestCenter.centerId)
+ .from(interestCenter)
+ .where(
+ interestCenter.volunteerId.eq(volunteerId)
+ .and(interestCenter.deleted.eq(false))
+ )
+ .fetch();
+ }
+
@Override
public boolean existsByVolunteerIdAndCenterId(UUID volunteerId, UUID centerId) {
QInterestCenter interestCenter = QInterestCenter.interestCenter;
diff --git a/src/main/java/com/somemore/interestcenter/service/InterestCenterQueryService.java b/src/main/java/com/somemore/interestcenter/service/InterestCenterQueryService.java
new file mode 100644
index 000000000..ffd8b38fc
--- /dev/null
+++ b/src/main/java/com/somemore/interestcenter/service/InterestCenterQueryService.java
@@ -0,0 +1,34 @@
+package com.somemore.interestcenter.service;
+
+import com.somemore.center.repository.mapper.CenterOverviewInfo;
+import com.somemore.center.usecase.query.CenterQueryUseCase;
+import com.somemore.interestcenter.dto.response.InterestCentersResponseDto;
+import com.somemore.interestcenter.repository.InterestCenterRepository;
+import com.somemore.interestcenter.usecase.InterestCenterQueryUseCase;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.UUID;
+
+@RequiredArgsConstructor
+@Service
+public class InterestCenterQueryService implements InterestCenterQueryUseCase {
+
+ private final CenterQueryUseCase centerQueryUseCase;
+ private final InterestCenterRepository interestCenterRepository;
+
+ @Override
+ public List getInterestCenters(UUID volunteerId) {
+
+ List interestCenterIds = interestCenterRepository.findInterestCenterIdsByVolunteerId(volunteerId);
+ if (interestCenterIds.isEmpty()) {
+ return List.of();
+ }
+
+ List centerOverviews = centerQueryUseCase.getCenterOverviewsByIds(interestCenterIds);
+ return centerOverviews.stream()
+ .map(InterestCentersResponseDto::of)
+ .toList();
+ }
+}
diff --git a/src/main/java/com/somemore/interestcenter/usecase/InterestCenterQueryUseCase.java b/src/main/java/com/somemore/interestcenter/usecase/InterestCenterQueryUseCase.java
new file mode 100644
index 000000000..c3015f597
--- /dev/null
+++ b/src/main/java/com/somemore/interestcenter/usecase/InterestCenterQueryUseCase.java
@@ -0,0 +1,10 @@
+package com.somemore.interestcenter.usecase;
+
+import com.somemore.interestcenter.dto.response.InterestCentersResponseDto;
+
+import java.util.List;
+import java.util.UUID;
+
+public interface InterestCenterQueryUseCase {
+ List getInterestCenters(UUID volunteerId);
+}
diff --git a/src/test/java/com/somemore/CustomSecurityContextFactory.java b/src/test/java/com/somemore/CustomSecurityContextFactory.java
new file mode 100644
index 000000000..5ec7d1bd6
--- /dev/null
+++ b/src/test/java/com/somemore/CustomSecurityContextFactory.java
@@ -0,0 +1,26 @@
+package com.somemore;
+
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.test.context.support.WithSecurityContextFactory;
+
+import java.util.Collections;
+
+public class CustomSecurityContextFactory implements WithSecurityContextFactory {
+ @Override
+ public SecurityContext createSecurityContext(WithMockCustomUser annotation) {
+ SecurityContext context = SecurityContextHolder.createEmptyContext();
+
+ Authentication auth = new UsernamePasswordAuthenticationToken(
+ annotation.username(),
+ "password",
+ Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER"))
+ );
+
+ context.setAuthentication(auth);
+ return context;
+ }
+}
diff --git a/src/test/java/com/somemore/WithMockCustomUser.java b/src/test/java/com/somemore/WithMockCustomUser.java
new file mode 100644
index 000000000..da5e38c23
--- /dev/null
+++ b/src/test/java/com/somemore/WithMockCustomUser.java
@@ -0,0 +1,12 @@
+package com.somemore;
+
+import org.springframework.security.test.context.support.WithSecurityContext;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+@WithSecurityContext(factory = CustomSecurityContextFactory.class)
+public @interface WithMockCustomUser {
+ String username() default "123e4567-e89b-12d3-a456-426614174000";
+}
diff --git a/src/test/java/com/somemore/center/service/query/CenterQueryServiceTest.java b/src/test/java/com/somemore/center/service/query/CenterQueryServiceTest.java
index 2cff5e618..d21a9f8a4 100644
--- a/src/test/java/com/somemore/center/service/query/CenterQueryServiceTest.java
+++ b/src/test/java/com/somemore/center/service/query/CenterQueryServiceTest.java
@@ -3,7 +3,9 @@
import com.somemore.IntegrationTestSupport;
import com.somemore.center.domain.Center;
import com.somemore.center.domain.PreferItem;
+import com.somemore.center.repository.mapper.CenterOverviewInfo;
import com.somemore.center.dto.response.CenterProfileResponseDto;
+import com.somemore.center.repository.CenterJpaRepository;
import com.somemore.center.repository.CenterRepository;
import com.somemore.center.repository.PreferItemRepository;
import com.somemore.global.exception.BadRequestException;
@@ -17,9 +19,7 @@
import java.util.List;
import java.util.UUID;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatCode;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+import static org.assertj.core.api.Assertions.*;
@Transactional
class CenterQueryServiceTest extends IntegrationTestSupport {
@@ -29,6 +29,9 @@ class CenterQueryServiceTest extends IntegrationTestSupport {
@Autowired
private CenterRepository centerRepository;
+
+ @Autowired
+ private CenterJpaRepository centerJpaRepository;
@Autowired
private PreferItemRepository preferItemRepository;
@@ -37,15 +40,7 @@ class CenterQueryServiceTest extends IntegrationTestSupport {
@Test
void getCenterProfileById() {
// given
- Center center = Center.create(
- "기본 기관 이름",
- "010-1234-5678",
- "http://example.com/image.jpg",
- "기관 소개 내용",
- "http://example.com",
- "account123",
- "password123"
- );
+ Center center = createCenter();
Center foundCenter = centerRepository.save(center);
PreferItem preferItem = PreferItem.create(foundCenter.getId(), "어린이 동화책");
@@ -80,6 +75,30 @@ void getCenterProfileById() {
.containsExactly("어린이 동화책", "간식");
}
+ @DisplayName("기관 Id들로 기관의 오버뷰 정보를 조회할 수 있다.")
+ @Test
+ void getCenterOverviewsByIds() {
+ //given
+ Center center = createCenter();
+ Center center1 = createCenter();
+ Center center2 = createCenter();
+ centerJpaRepository.saveAll(List.of(center, center1, center2));
+ List ids = List.of(center.getId(),center1.getId(), center2.getId());
+
+ //when
+ List responseDtos = centerQueryService.getCenterOverviewsByIds(ids);
+
+ //then
+ assertThat(responseDtos)
+ .isNotNull()
+ .hasSize(3)
+ .extracting("centerId", "centerName", "imgUrl")
+ .containsExactlyInAnyOrder(
+ tuple(center.getId(), center.getName(), center.getImgUrl()),
+ tuple(center1.getId(), center1.getName(), center1.getImgUrl()),
+ tuple(center2.getId(), center2.getName(), center2.getImgUrl())
+ );
+ }
@DisplayName("존재하지 않는 기관 ID를 검증할 수 있다.")
@Test
@@ -118,4 +137,16 @@ void validateExistingCenter() {
// then
assertThatCode(callable).doesNotThrowAnyException();
}
+
+ private Center createCenter() {
+ return Center.create(
+ "기본 기관 이름",
+ "010-1234-5678",
+ "http://example.com/image.jpg",
+ "기관 소개 내용",
+ "http://example.com",
+ "account123",
+ "password123"
+ );
+ }
}
diff --git a/src/test/java/com/somemore/interestcenter/controller/InterestCenterQueryApiControllerTest.java b/src/test/java/com/somemore/interestcenter/controller/InterestCenterQueryApiControllerTest.java
new file mode 100644
index 000000000..80eabcea0
--- /dev/null
+++ b/src/test/java/com/somemore/interestcenter/controller/InterestCenterQueryApiControllerTest.java
@@ -0,0 +1,69 @@
+package com.somemore.interestcenter.controller;
+
+import com.somemore.ControllerTestSupport;
+import com.somemore.WithMockCustomUser;
+import com.somemore.interestcenter.dto.response.InterestCentersResponseDto;
+import com.somemore.interestcenter.usecase.InterestCenterQueryUseCase;
+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 org.mockito.BDDMockito.given;
+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;
+
+class InterestCenterQueryApiControllerTest extends ControllerTestSupport {
+
+ @MockBean
+ private InterestCenterQueryUseCase interestCenterQueryUseCase;
+
+ @DisplayName("봉사자 ID로 관심기관 목록을 조회할 수 있다.")
+ @Test
+ @WithMockCustomUser
+ void getInterestCenters_ShouldReturnInterestCentersList() throws Exception {
+ // given
+ UUID volunteerId = UUID.fromString("123e4567-e89b-12d3-a456-426614174000");
+ UUID centerId = UUID.fromString("123e4567-e89b-12d3-a456-426614174001");
+ List responseDtos = List.of(
+ new InterestCentersResponseDto(centerId, "센터1", "http://image1.jpg"),
+ new InterestCentersResponseDto(centerId, "센터2", "http://image2.jpg")
+ );
+
+ given(interestCenterQueryUseCase.getInterestCenters(volunteerId)).willReturn(responseDtos);
+
+ // when & then
+ mockMvc.perform(get("/api/interest-centers")
+ .accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$.message").value("관심기관 조회 성공"))
+ .andExpect(jsonPath("$.data").isArray())
+ .andExpect(jsonPath("$.data[0].center_name").value("센터1"))
+ .andExpect(jsonPath("$.data[0].img_url").value("http://image1.jpg"))
+ .andExpect(jsonPath("$.data[1].center_name").value("센터2"))
+ .andExpect(jsonPath("$.data[1].img_url").value("http://image2.jpg"));
+ }
+
+
+ @DisplayName("봉사자 ID로 관심기관이 없을 경우 빈 리스트를 반환한다.")
+ @Test
+ @WithMockCustomUser
+ void getInterestCenters_ShouldReturnEmptyList_WhenNoInterestCenters() throws Exception {
+ // given
+ UUID volunteerId = UUID.fromString("123e4567-e89b-12d3-a456-426614174000");
+
+ given(interestCenterQueryUseCase.getInterestCenters(volunteerId)).willReturn(List.of());
+
+ // when & then
+ mockMvc.perform(get("/api/interest-centers")
+ .param("volunteerId", volunteerId.toString()))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$.message").value("관심기관 조회 성공"))
+ .andExpect(jsonPath("$.data").isEmpty());
+ }
+}
+
diff --git a/src/test/java/com/somemore/interestcenter/service/InterestCenterQueryServiceTest.java b/src/test/java/com/somemore/interestcenter/service/InterestCenterQueryServiceTest.java
new file mode 100644
index 000000000..98aef2aa0
--- /dev/null
+++ b/src/test/java/com/somemore/interestcenter/service/InterestCenterQueryServiceTest.java
@@ -0,0 +1,108 @@
+package com.somemore.interestcenter.service;
+
+import com.somemore.IntegrationTestSupport;
+import com.somemore.center.domain.Center;
+import com.somemore.center.repository.CenterJpaRepository;
+import com.somemore.interestcenter.domain.InterestCenter;
+import com.somemore.interestcenter.dto.response.InterestCentersResponseDto;
+import com.somemore.interestcenter.repository.InterestCenterJpaRepository;
+import com.somemore.interestcenter.repository.InterestCenterRepository;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.UUID;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@Transactional
+class InterestCenterQueryServiceTest extends IntegrationTestSupport {
+
+
+ @Autowired
+ private InterestCenterQueryService interestCenterQueryService;
+
+ @Autowired
+ private InterestCenterRepository interestCenterRepository;
+
+ @Autowired
+ private InterestCenterJpaRepository interestCenterJpaRepository;
+
+ @Autowired
+ private CenterJpaRepository centerJpaRepository;
+
+ @DisplayName("봉사자 ID로 관심 센터 정보를 조회할 수 있다.")
+ @Test
+ void getInterestCenters() {
+ // given
+ UUID volunteerId = UUID.randomUUID();
+
+ Center center = createCenter();
+ Center center1 = createCenter();
+ Center center2 = createCenter();
+ centerJpaRepository.saveAll(List.of(center, center1, center2));
+
+ InterestCenter interestCenter = createInterestCenter(volunteerId, center.getId());
+ InterestCenter interestCenter1 = createInterestCenter(volunteerId, center1.getId());
+ InterestCenter interestCenter2 = createInterestCenter(volunteerId, center2.getId());
+ interestCenterJpaRepository.saveAll(List.of(interestCenter, interestCenter1, interestCenter2));
+
+ // when
+ List result = interestCenterQueryService.getInterestCenters(volunteerId);
+
+ // then
+ assertThat(result)
+ .hasSize(3)
+ .extracting("centerId")
+ .containsExactlyInAnyOrder(center.getId(), center1.getId(), center2.getId());
+
+ assertThat(result)
+ .extracting("centerName")
+ .containsExactlyInAnyOrder("기본 기관 이름", "기본 기관 이름", "기본 기관 이름");
+
+ assertThat(result)
+ .extracting("imgUrl")
+ .containsExactlyInAnyOrder("http://image.jpg", "http://image.jpg", "http://image.jpg");
+ }
+
+ @DisplayName("봉사자의 관심 센터가 없을 경우 빈 리스트를 반환한다.")
+ @Test
+ void getInterestCenters_ReturnsEmptyList_WhenNoInterestCenters() {
+ // given
+ UUID volunteerId = UUID.randomUUID();
+
+ Center center = createCenter();
+ centerJpaRepository.save(center);
+
+ InterestCenter unrelatedInterestCenter = createInterestCenter(UUID.randomUUID(), center.getId());
+ interestCenterJpaRepository.save(unrelatedInterestCenter);
+
+ // when
+ List result = interestCenterQueryService.getInterestCenters(volunteerId);
+
+ // then
+ assertThat(result).isEmpty();
+ }
+
+
+ private Center createCenter() {
+ return Center.create(
+ "기본 기관 이름",
+ "010-1234-5678",
+ "http://image.jpg",
+ "기관 소개 내용",
+ "http://example.com",
+ "account123",
+ "password123"
+ );
+ }
+
+ private InterestCenter createInterestCenter(UUID volunteerId, UUID centerId) {
+ return InterestCenter.builder()
+ .volunteerId(volunteerId)
+ .centerId(centerId)
+ .build();
+ }
+}
\ No newline at end of file