테스트 코드 추가:
eapim-portal CI / build (push) Has been cancelled
eapim-portal Test / test (push) Has been cancelled

- API 상태 관련 서비스 테스트 클래스 신규 작성 (총 7개)
- 테스트 코드에서 `visibleApiIds` 필터 적용 확인 및 조회 로직 검증 포함
- `TestCleanupService` 확장: 그룹 제한 데이터 관련 신규 Fixture 및 Mock 추가
This commit is contained in:
Rinjae
2026-08-26 17:44:48 +09:00
parent e55b7a6bf2
commit 28017fd83c
18 changed files with 962 additions and 35 deletions
@@ -0,0 +1,143 @@
package com.eactive.apim.portal.apps.auth.service;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when;
import com.eactive.apim.portal.apps.apis.dto.ApiSpecInfoDto;
import com.eactive.apim.portal.apps.apiservice.dto.ApiServiceDTO;
import com.eactive.apim.portal.apps.user.dto.PortalOrgDTO;
import com.eactive.apim.portal.common.user.PortalAuthenticatedUser;
import com.eactive.apim.portal.common.util.SecurityUtil;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
/**
* org 축·role 축은 각자 독립적으로 선택적 제한이며 AND 로 합쳐야 한다.
*
* <p>과거 OR 합성 결함: displayRoleCode 를 비워두면(=역할 제한 없음) roleMatch 가
* "로그인만 했으면" 무조건 true 가 되어, displayOrg 만 설정한 법인전용 API 가 다른 법인
* 로그인 사용자에게도 그대로 보였다 — 오직 비로그인 사용자만 걸러졌다.</p>
*/
class ApiPermissionFilterTest {
private static final String ORG_A = "org-a";
private static final String ORG_B = "org-b";
private static final String ROLE_MANAGER = "ROLE_CORP_MANAGER";
private static final String ROLE_USER = "ROLE_CORP_USER";
// ── checkApiPermissions (ApiSpecInfoDto) ──────────────────────────
@Test
void checkApiPermissions_noRestriction_visibleToAnonymous() {
ApiSpecInfoDto spec = apiSpec(null, null);
assertTrue(ApiPermissionFilter.checkApiPermissions(spec, false, null, null));
}
@Test
void checkApiPermissions_orgOnlyRestriction_hiddenFromAnonymous() {
ApiSpecInfoDto spec = apiSpec(ORG_A, null);
assertFalse(ApiPermissionFilter.checkApiPermissions(spec, false, null, null));
}
@Test
void checkApiPermissions_orgOnlyRestriction_visibleToMatchingOrg() {
ApiSpecInfoDto spec = apiSpec(ORG_A, null);
assertTrue(ApiPermissionFilter.checkApiPermissions(spec, true, ORG_A, ROLE_MANAGER));
}
@Test
void checkApiPermissions_orgOnlyRestriction_hiddenFromDifferentOrg() {
// 회귀 케이스 — 과거 OR 버그에서는 displayRoleCode 가 비어 roleMatch=true 가 되어 여기서 true 가 나왔다.
ApiSpecInfoDto spec = apiSpec(ORG_A, null);
assertFalse(ApiPermissionFilter.checkApiPermissions(spec, true, ORG_B, ROLE_MANAGER));
}
@Test
void checkApiPermissions_roleOnlyRestriction_hiddenFromNonMatchingRole() {
ApiSpecInfoDto spec = apiSpec(null, ROLE_MANAGER);
assertFalse(ApiPermissionFilter.checkApiPermissions(spec, true, ORG_A, ROLE_USER));
}
@Test
void checkApiPermissions_roleOnlyRestriction_visibleRegardlessOfOrg() {
ApiSpecInfoDto spec = apiSpec(null, ROLE_MANAGER);
assertTrue(ApiPermissionFilter.checkApiPermissions(spec, true, ORG_B, ROLE_MANAGER));
}
@Test
void checkApiPermissions_bothRestrictions_requireIntersection() {
ApiSpecInfoDto spec = apiSpec(ORG_A, ROLE_MANAGER);
assertTrue(ApiPermissionFilter.checkApiPermissions(spec, true, ORG_A, ROLE_MANAGER));
// org 는 맞지만 role 이 안 맞음 → 여전히 숨겨져야 한다(AND)
assertFalse(ApiPermissionFilter.checkApiPermissions(spec, true, ORG_A, ROLE_USER));
// role 은 맞지만 org 가 안 맞음
assertFalse(ApiPermissionFilter.checkApiPermissions(spec, true, ORG_B, ROLE_MANAGER));
}
// ── checkServicePermissions (ApiServiceDTO, 현재 호출부 없음 — 동일 규칙 유지 확인) ──
@Test
void checkServicePermissions_orgOnlyRestriction_hiddenFromDifferentOrg() {
ApiServiceDTO spec = new ApiServiceDTO();
spec.setDisplayOrg(ORG_A);
assertFalse(ApiPermissionFilter.checkServicePermissions(spec, true, ORG_B, ROLE_MANAGER));
assertTrue(ApiPermissionFilter.checkServicePermissions(spec, true, ORG_A, ROLE_MANAGER));
}
// ── filterApisByPermissions (SecurityUtil 정적 메서드 경유 통합 경로) ──
@Test
void filterApisByPermissions_orgOnlyRestriction_excludesAuthenticatedDifferentOrg() {
ApiSpecInfoDto visibleToOrgA = apiSpec(ORG_A, null);
visibleToOrgA.setApiId("API-ORG-A");
ApiSpecInfoDto publicApi = apiSpec(null, null);
publicApi.setApiId("API-PUBLIC");
List<ApiSpecInfoDto> apis = Arrays.asList(visibleToOrgA, publicApi);
PortalAuthenticatedUser user = org.mockito.Mockito.mock(PortalAuthenticatedUser.class);
PortalOrgDTO userOrg = new PortalOrgDTO();
userOrg.setId(ORG_B);
try (MockedStatic<SecurityUtil> securityUtil = mockStatic(SecurityUtil.class)) {
securityUtil.when(SecurityUtil::isAuthenticated).thenReturn(true);
securityUtil.when(SecurityUtil::getPortalAuthenticatedUser).thenReturn(user);
securityUtil.when(SecurityUtil::getUserOrg).thenReturn(userOrg);
when(user.getRoleCode()).thenReturn(com.eactive.apim.portal.portaluser.entity.PortalUserEnums.RoleCode.ROLE_CORP_MANAGER);
List<ApiSpecInfoDto> filtered = ApiPermissionFilter.filterApisByPermissions(apis);
assertEquals(1, filtered.size());
assertEquals("API-PUBLIC", filtered.get(0).getApiId());
}
}
@Test
void filterApisByPermissions_anonymous_onlyPublicApisVisible() {
ApiSpecInfoDto restricted = apiSpec(ORG_A, null);
restricted.setApiId("API-ORG-A");
ApiSpecInfoDto publicApi = apiSpec(null, null);
publicApi.setApiId("API-PUBLIC");
try (MockedStatic<SecurityUtil> securityUtil = mockStatic(SecurityUtil.class)) {
securityUtil.when(SecurityUtil::isAuthenticated).thenReturn(false);
List<ApiSpecInfoDto> filtered =
ApiPermissionFilter.filterApisByPermissions(Arrays.asList(restricted, publicApi));
assertEquals(1, filtered.size());
assertEquals("API-PUBLIC", filtered.get(0).getApiId());
}
}
private ApiSpecInfoDto apiSpec(String displayOrg, String displayRoleCode) {
ApiSpecInfoDto dto = new ApiSpecInfoDto();
dto.setDisplayOrg(displayOrg);
dto.setDisplayRoleCode(displayRoleCode);
return dto;
}
}
@@ -0,0 +1,69 @@
package com.eactive.apim.portal.djb.apistatus.service;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.eactive.apim.portal.apispec.repository.ApiSpecInfoRepository;
import com.eactive.apim.portal.djb.apistatus.incident.entity.IncidentKind;
import com.eactive.apim.portal.djb.apistatus.incident.repository.DjbApistatusIncidentApiRepository;
import com.eactive.apim.portal.djb.apistatus.repository.ApiStatusIncidentQueryRepository;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Set;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
/**
* API 개별 현재상태(P11, 정상/점검/지연/장애) 판정이 진행 중 장애·점검·최근 이슈를
* 모두 현재 사용자의 조회가능 API 집합으로 필터링해서 조회하는지 검증한다.
* {@code apiId} 를 직접 지정해 호출하는 {@code /apistatus/current.json} 도 이 경로를 탄다 -
* 조회 권한 없는 apiId 를 직접 넣어도 실제 상태(장애 여부)가 새어나가지 않아야 한다.
*/
@ExtendWith(MockitoExtension.class)
class ApiCurrentStatusServiceTest {
@Mock private ApiStatusIncidentQueryRepository incidentQueryRepository;
@Mock private DjbApistatusIncidentApiRepository incidentApiRepository;
@Mock private ApiSpecInfoRepository apiSpecInfoRepository;
@Mock private ApiStatusUptimeService uptimeService;
@Mock private ApiStatusCatalogService catalogService;
private ApiCurrentStatusService service;
private Set<String> visibleApiIds;
@BeforeEach
void setUp() {
service = new ApiCurrentStatusService(
incidentQueryRepository, incidentApiRepository, apiSpecInfoRepository, uptimeService, catalogService);
visibleApiIds = Collections.singleton("API-PUBLIC");
when(catalogService.getVisibleApiIdsForQuery()).thenReturn(visibleApiIds);
when(catalogService.getWindowDays()).thenReturn(90);
}
@Test
void resolveStatuses_passesVisibleApiIdsToOpenMaintenanceAndOverlapQueries() {
when(incidentQueryRepository.findVisibleOpenIncidents(
eq(IncidentKind.DEGRADING), any(), eq(visibleApiIds)))
.thenReturn(Collections.emptyList());
when(incidentQueryRepository.findVisibleOngoingMaintenance(
eq(IncidentKind.MAINTENANCE), any(LocalDateTime.class), eq(visibleApiIds)))
.thenReturn(Collections.emptyList());
when(incidentQueryRepository.findVisibleOverlapping(
any(LocalDateTime.class), any(LocalDateTime.class), eq(visibleApiIds)))
.thenReturn(Collections.emptyList());
service.resolveStatuses(Collections.singleton("API1"));
verify(incidentQueryRepository).findVisibleOpenIncidents(
eq(IncidentKind.DEGRADING), any(), eq(visibleApiIds));
verify(incidentQueryRepository).findVisibleOngoingMaintenance(
eq(IncidentKind.MAINTENANCE), any(LocalDateTime.class), eq(visibleApiIds));
verify(incidentQueryRepository).findVisibleOverlapping(
any(LocalDateTime.class), any(LocalDateTime.class), eq(visibleApiIds));
}
}
@@ -0,0 +1,78 @@
package com.eactive.apim.portal.djb.apistatus.service;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import com.eactive.apim.gateway.data.statistics.repository.GwApiStatusRepository;
import com.eactive.apim.portal.apps.apis.dto.ApiSpecInfoDto;
import com.eactive.apim.portal.apps.apis.service.ApiSearchFacade;
import com.eactive.apim.portal.apps.apiservice.dto.ApiGroupSearch;
import com.eactive.apim.portal.portalproperty.service.PortalPropertyService;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
/**
* getVisibleApiIdsForQuery() 는 ApiStatusIncidentQueryRepository 의 {@code :visibleApiIds}
* 바인딩 소스다. API 그룹 공개범위(ApiSearchFacade → ApiPermissionFilter 경로)를 그대로
* 재사용하는지, 조회 가능한 API 가 하나도 없을 때 Oracle {@code IN ()} 구문 오류를 피하는
* 더미값으로 대체하는지를 검증한다.
*/
@ExtendWith(MockitoExtension.class)
class ApiStatusCatalogServiceTest {
@Mock private ApiSearchFacade apiSearchFacade;
@Mock private PortalPropertyService portalPropertyService;
@Mock private GwApiStatusRepository gwApiStatusRepository;
private ApiStatusCatalogService service;
@BeforeEach
void setUp() {
service = new ApiStatusCatalogService(apiSearchFacade, portalPropertyService, gwApiStatusRepository);
}
@Test
void getVisibleApiIdsForQuery_returnsApiIdsVisibleToCurrentUser() {
stubSearchApis(apiSpec("API1", "결제 API"), apiSpec("API2", "조회 API"));
Collection<String> visibleApiIds = service.getVisibleApiIdsForQuery();
assertEquals(2, visibleApiIds.size());
assertTrue(visibleApiIds.contains("API1"));
assertTrue(visibleApiIds.contains("API2"));
}
@Test
void getVisibleApiIdsForQuery_whenNothingVisible_returnsDummyThatMatchesNoRealApiId() {
stubSearchApis();
Collection<String> visibleApiIds = service.getVisibleApiIdsForQuery();
assertEquals(1, visibleApiIds.size());
assertFalse(visibleApiIds.contains("API1"));
assertFalse(visibleApiIds.isEmpty());
}
private void stubSearchApis(ApiSpecInfoDto... apis) {
Map<String, Object> result = new HashMap<>();
result.put("apis", Arrays.asList(apis));
when(apiSearchFacade.searchApis(any(ApiGroupSearch.class))).thenReturn(result);
}
private ApiSpecInfoDto apiSpec(String apiId, String apiName) {
ApiSpecInfoDto dto = new ApiSpecInfoDto();
dto.setApiId(apiId);
dto.setApiName(apiName);
return dto;
}
}
@@ -0,0 +1,93 @@
package com.eactive.apim.portal.djb.apistatus.service;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.eactive.apim.portal.djb.apistatus.repository.ApiStatusIncidentQueryRepository;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Set;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.domain.PageRequest;
/**
* 전체 장애 이력 페이지(P8) 의 일자 인덱스(P9)·목록(P10) 조회가 현재 사용자의
* 조회가능 API 집합을 {@link ApiStatusIncidentQueryRepository} 에 그대로 전달하는지 검증한다.
* 이 테스트가 다루는 대상이 원 분석에서 지적된 "그룹 전용 API 장애가 전체 사용자에게
* 노출되던" 경로다.
*
* <p>mock 이라 JPQL 자체의 필터링 정확성은 검증 범위 밖이다 - 실제 쿼리 실행 검증은
* 별도 통합 테스트(@DataJpaTest 등)가 필요하다.</p>
*/
@ExtendWith(MockitoExtension.class)
class ApiStatusIssueHistoryServiceTest {
@Mock private ApiStatusIncidentQueryRepository incidentQueryRepository;
@Mock private ApiStatusAssembler assembler;
@Mock private ApiStatusCatalogService catalogService;
private ApiStatusIssueHistoryService service;
private Set<String> visibleApiIds;
@BeforeEach
void setUp() {
service = new ApiStatusIssueHistoryService(incidentQueryRepository, assembler, catalogService);
visibleApiIds = Collections.singleton("API-PUBLIC");
when(catalogService.getVisibleApiIdsForQuery()).thenReturn(visibleApiIds);
}
@Test
void getIssueDates_withoutApiFilter_passesVisibleApiIdsToOverlapQuery() {
when(incidentQueryRepository.findVisibleOverlapping(
any(LocalDateTime.class), any(LocalDateTime.class), eq(visibleApiIds)))
.thenReturn(Collections.emptyList());
service.getIssueDates(30, null, null);
verify(incidentQueryRepository).findVisibleOverlapping(
any(LocalDateTime.class), any(LocalDateTime.class), eq(visibleApiIds));
}
@Test
void getIssueDates_withApiFilter_apiIdItselfMustBeVisibleTooOrRowsAreExcluded() {
when(incidentQueryRepository.findVisibleOverlappingByApi(
any(LocalDateTime.class), any(LocalDateTime.class), eq("API-RESTRICTED"), eq(visibleApiIds)))
.thenReturn(Collections.emptyList());
service.getIssueDates(30, "API-RESTRICTED", null);
verify(incidentQueryRepository).findVisibleOverlappingByApi(
any(LocalDateTime.class), any(LocalDateTime.class), eq("API-RESTRICTED"), eq(visibleApiIds));
}
@Test
void getIssues_withoutApiFilter_passesVisibleApiIdsToOverlapQuery() {
when(incidentQueryRepository.findVisibleOverlapping(
any(LocalDateTime.class), any(LocalDateTime.class), eq(visibleApiIds)))
.thenReturn(Collections.emptyList());
service.getIssues(null, null, null, PageRequest.of(0, 20));
verify(incidentQueryRepository).findVisibleOverlapping(
any(LocalDateTime.class), any(LocalDateTime.class), eq(visibleApiIds));
}
@Test
void getIssues_withApiFilter_passesVisibleApiIdsToPerApiQuery() {
when(incidentQueryRepository.findVisibleOverlappingByApi(
any(LocalDateTime.class), any(LocalDateTime.class), eq("API-RESTRICTED"), eq(visibleApiIds)))
.thenReturn(Collections.emptyList());
service.getIssues(LocalDate.now(), "API-RESTRICTED", null, PageRequest.of(0, 20));
verify(incidentQueryRepository).findVisibleOverlappingByApi(
any(LocalDateTime.class), any(LocalDateTime.class), eq("API-RESTRICTED"), eq(visibleApiIds));
}
}
@@ -0,0 +1,102 @@
package com.eactive.apim.portal.djb.apistatus.service;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.eactive.apim.portal.djb.apistatus.incident.entity.DjbApistatusIncident;
import com.eactive.apim.portal.djb.apistatus.incident.entity.IncidentKind;
import com.eactive.apim.portal.djb.apistatus.repository.ApiStatusIncidentQueryRepository;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
/**
* API Status 메인 화면(P3 진행중 장애 / P5 점검 / P6 최근 이슈 / P7 상세) 조회가
* 현재 사용자의 조회가능 API 집합({@link ApiStatusCatalogService#getVisibleApiIdsForQuery()})을
* {@link ApiStatusIncidentQueryRepository} 에 그대로 전달하는지 검증한다.
*
* <p>mock 이라 JPQL 자체의 필터링 정확성(그룹 전용 API 의 인시던트가 실제로 걸러지는지)은
* 검증 범위 밖이다 - 실제 쿼리 실행 검증은 별도 통합 테스트가 필요하다.</p>
*/
@ExtendWith(MockitoExtension.class)
class ApiStatusQueryServiceTest {
@Mock private ApiStatusIncidentQueryRepository incidentQueryRepository;
@Mock private ApiStatusAssembler assembler;
@Mock private ApiStatusCatalogService catalogService;
private ApiStatusQueryService service;
private Set<String> visibleApiIds;
@BeforeEach
void setUp() {
service = new ApiStatusQueryService(incidentQueryRepository, assembler, catalogService);
visibleApiIds = Collections.singleton("API-PUBLIC");
when(catalogService.getVisibleApiIdsForQuery()).thenReturn(visibleApiIds);
}
@Test
void getActiveIncidents_passesVisibleApiIds() {
when(incidentQueryRepository.findVisibleOpenIncidents(
eq(IncidentKind.DEGRADING), eq(ApiStatusSupport.CLOSED_STATES), eq(visibleApiIds)))
.thenReturn(Collections.emptyList());
when(assembler.toActiveIncidents(anyList(), any(LocalDateTime.class)))
.thenReturn(Collections.emptyList());
service.getActiveIncidents();
verify(incidentQueryRepository).findVisibleOpenIncidents(
eq(IncidentKind.DEGRADING), eq(ApiStatusSupport.CLOSED_STATES), eq(visibleApiIds));
}
@Test
void getOngoingMaintenance_passesVisibleApiIds() {
when(incidentQueryRepository.findVisibleOngoingMaintenance(
eq(IncidentKind.MAINTENANCE), any(LocalDateTime.class), eq(visibleApiIds)))
.thenReturn(Collections.emptyList());
when(assembler.toMaintenanceCards(anyList())).thenReturn(Collections.emptyList());
service.getOngoingMaintenance();
verify(incidentQueryRepository).findVisibleOngoingMaintenance(
eq(IncidentKind.MAINTENANCE), any(LocalDateTime.class), eq(visibleApiIds));
}
@Test
void getRecentClosedIssues_passesVisibleApiIds() {
List<DjbApistatusIncident> empty = Collections.emptyList();
when(incidentQueryRepository.findVisibleClosedIssues(
eq(ApiStatusSupport.CLOSED_STATES), any(LocalDateTime.class), eq(visibleApiIds),
eq(PageRequest.of(0, 5))))
.thenReturn(new PageImpl<>(empty));
when(assembler.toPastIssueCards(anyList())).thenReturn(Collections.emptyList());
service.getRecentClosedIssues(0);
verify(incidentQueryRepository).findVisibleClosedIssues(
eq(ApiStatusSupport.CLOSED_STATES), any(LocalDateTime.class), eq(visibleApiIds),
eq(PageRequest.of(0, 5)));
}
@Test
void getIssueDetail_passesVisibleApiIds() {
when(incidentQueryRepository.findVisibleById(eq(1L), eq(visibleApiIds)))
.thenReturn(Optional.empty());
service.getIssueDetail(1L);
verify(incidentQueryRepository).findVisibleById(eq(1L), eq(visibleApiIds));
}
}
@@ -0,0 +1,64 @@
package com.eactive.apim.portal.djb.apistatus.service;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.eactive.apim.portal.djb.apistatus.incident.repository.DjbApistatusIncidentApiRepository;
import com.eactive.apim.portal.djb.apistatus.repository.ApiStatusIncidentQueryRepository;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Set;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
/**
* 90일 가동률 집계(P2) 가 인시던트 조회를 현재 사용자의 조회가능 API 집합으로
* 필터링하는지 검증한다. 필터링 전에는 그룹 전용 API 의 장애가 전체 가동률과
* 일자별 이슈 제목({@code DailyStatDTO.issues})에 그대로 섞여 들어갔다.
*/
@ExtendWith(MockitoExtension.class)
class ApiStatusUptimeServiceTest {
@Mock private ApiStatusIncidentQueryRepository incidentQueryRepository;
@Mock private DjbApistatusIncidentApiRepository incidentApiRepository;
@Mock private ApiStatusCatalogService catalogService;
private ApiStatusUptimeService service;
private Set<String> visibleApiIds;
@BeforeEach
void setUp() {
service = new ApiStatusUptimeService(incidentQueryRepository, incidentApiRepository, catalogService);
visibleApiIds = Collections.singleton("API-PUBLIC");
when(catalogService.getVisibleApiIdsForQuery()).thenReturn(visibleApiIds);
}
@Test
void getDailyStats_passesVisibleApiIds() {
when(incidentQueryRepository.findVisibleOverlapping(
any(LocalDateTime.class), any(LocalDateTime.class), eq(visibleApiIds)))
.thenReturn(Collections.emptyList());
service.getDailyStats(7);
verify(incidentQueryRepository).findVisibleOverlapping(
any(LocalDateTime.class), any(LocalDateTime.class), eq(visibleApiIds));
}
@Test
void getApiUptimeRatios_passesVisibleApiIds() {
when(incidentQueryRepository.findVisibleOverlapping(
any(LocalDateTime.class), any(LocalDateTime.class), eq(visibleApiIds)))
.thenReturn(Collections.emptyList());
service.getApiUptimeRatios(Collections.singleton("API1"), 7);
verify(incidentQueryRepository).findVisibleOverlapping(
any(LocalDateTime.class), any(LocalDateTime.class), eq(visibleApiIds));
}
}
@@ -23,6 +23,9 @@ import com.eactive.apim.portal.apps.community.partnership.repository.Partnership
import com.eactive.apim.portal.apps.community.qna.repository.InquiryRepository;
import com.eactive.apim.portal.apps.user.repository.PortalOrgRepository;
import com.eactive.apim.portal.apps.user.service.PortalUserService;
import com.eactive.apim.portal.apispec.repository.ApiSpecInfoRepository;
import com.eactive.apim.portal.djb.apistatus.incident.repository.DjbApistatusIncidentApiRepository;
import com.eactive.apim.portal.djb.apistatus.incident.repository.DjbApistatusIncidentRepository;
import com.eactive.apim.portal.djb.community.qna.comment.repository.InquiryCommentRepository;
import com.eactive.apim.portal.djb.webhook.repository.WebhookRequestApiRepository;
import com.eactive.apim.portal.djb.webhook.repository.WebhookRequestEventRepository;
@@ -77,6 +80,10 @@ class TestCleanupServiceTest {
@Mock private TestCleanupNativeQueries nativeQueries;
@Mock private PortalUserService portalUserService;
@Mock private PasswordEncoder passwordEncoder;
@Mock private ApiSpecInfoRepository apiSpecInfoRepository;
@Mock private DjbApistatusIncidentRepository djbApistatusIncidentRepository;
@Mock private DjbApistatusIncidentApiRepository djbApistatusIncidentApiRepository;
@Mock private com.eactive.apim.portal.apps.apis.service.ApiSearchFacade apiSearchFacade;
private TestCleanupService service;
@@ -94,7 +101,9 @@ class TestCleanupServiceTest {
userLogRepository, credentialRepository, appRequestRepository, approvalService,
webhookRequestRepository, webhookRequestApiRepository,
webhookRequestEventRepository, webhookService, userInvitationRepository, fileService,
nativeQueries, portalUserService, passwordEncoder);
nativeQueries, portalUserService, passwordEncoder,
apiSpecInfoRepository, djbApistatusIncidentRepository, djbApistatusIncidentApiRepository,
apiSearchFacade);
when(environment.acceptsProfiles(Profiles.of("stage", "prod"))).thenReturn(false);
}