package com.dalab.discovery.client.rest; import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mockito; 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.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Primary; import org.springframework.http.MediaType; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; import com.dalab.discovery.client.rest.dto.DiscoveryStatsDTO; import com.dalab.discovery.sd.config.TestDatabaseConfiguration; import com.dalab.discovery.stats.service.IDiscoveryStatsService; import com.fasterxml.jackson.databind.ObjectMapper; @SpringBootTest( classes = com.dalab.discovery.application.DADiscoveryAgent.class, properties = { "spring.autoconfigure.exclude=com.google.cloud.spring.autoconfigure.secretmanager.GcpSecretManagerAutoConfiguration,com.google.cloud.spring.autoconfigure.core.GcpAutoConfiguration", "server.port=0" } ) @AutoConfigureMockMvc @ActiveProfiles("test") @Import({TestWebSecurityConfiguration.class, TestDatabaseConfiguration.class}) class DiscoveryStatsControllerTest { @TestConfiguration static class StatsControllerTestConfiguration { @Bean @Primary public IDiscoveryStatsService statsServiceMock() { return Mockito.mock(IDiscoveryStatsService.class); } } @Autowired private MockMvc mockMvc; @Autowired private IDiscoveryStatsService statsService; @Autowired private ObjectMapper objectMapper; private DiscoveryStatsDTO statsDTO; @BeforeEach void setUp() { statsDTO = DiscoveryStatsDTO.builder() .totalScansSubmitted(100L) .scansSucceeded(90L) .scansFailed(5L) .scansRunning(3L) .scansPending(2L) .totalAssetsInCatalog(5000L) .assetsDiscoveredLast24h(200L) .averageScanDurationSeconds(120.5) .build(); } @Test @WithMockUser(authorities = "ROLE_ADMIN") void getDiscoveryStats_AsAdmin_ShouldReturnStats() throws Exception { when(statsService.getDiscoveryStats()).thenReturn(statsDTO); mockMvc.perform(get("/api/v1/discovery/stats") .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$.totalScansSubmitted").value(100L)) .andExpect(jsonPath("$.totalAssetsInCatalog").value(5000L)) .andExpect(jsonPath("$.averageScanDurationSeconds").value(120.5)); } @Test @WithMockUser(authorities = "ROLE_GUEST") void getDiscoveryStats_AsGuest_ShouldBeForbidden() throws Exception { when(statsService.getDiscoveryStats()).thenReturn(statsDTO); mockMvc.perform(get("/api/v1/discovery/stats") .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); } @Test @WithMockUser(authorities = "ROLE_USER") void getDiscoveryStats_AsUser_ShouldReturnStats() throws Exception { when(statsService.getDiscoveryStats()).thenReturn(statsDTO); mockMvc.perform(get("/api/v1/discovery/stats") .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$.totalScansSubmitted").value(100L)); } }