diff --git a/src/test/java/com/eactive/eai/agent/inflow/ReloadInflowClientControlCommandTest.java b/src/test/java/com/eactive/eai/agent/inflow/ReloadInflowClientControlCommandTest.java new file mode 100644 index 0000000..0e2021f --- /dev/null +++ b/src/test/java/com/eactive/eai/agent/inflow/ReloadInflowClientControlCommandTest.java @@ -0,0 +1,108 @@ +package com.eactive.eai.agent.inflow; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.test.util.ReflectionTestUtils; + +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.agent.command.ReloadInflowClientControlCommand; +import com.eactive.eai.common.inflow.InflowControlManager; +import com.eactive.eai.common.inflow.InflowControlUtil; +import com.eactive.eai.custom.inflow.ClientDualInflowControlManager; + +/** + * ReloadInflowClientControlCommand 단위 테스트. + * + *

InflowControlUtil의 cachedInflowControlManager 필드에 mock을 직접 주입하여 + * PropManager/ApplicationContext 없이 동작을 검증한다. + */ +class ReloadInflowClientControlCommandTest { + + private ClientDualInflowControlManager mockDualManager; + + @BeforeEach + void setUp() { + mockDualManager = mock(ClientDualInflowControlManager.class); + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", null); + } + + @AfterEach + void tearDown() { + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", null); + } + + private ReloadInflowClientControlCommand commandWith(Object args) { + ReloadInflowClientControlCommand cmd = new ReloadInflowClientControlCommand(); + cmd.setArgs(args); + return cmd; + } + + // ========================================================================= + // args 타입 검증 실패 + // ========================================================================= + + @Test + void execute_argsIsInteger_throwsCommandException() { + // args 검증이 getInflowControlManager() 호출 이전에 발생하므로 캐시 설정 불필요 + assertThrows(CommandException.class, commandWith(Integer.valueOf(1))::execute); + } + + // ========================================================================= + // ClientDualInflowControlManager 비활성 + // ========================================================================= + + @Test + void execute_notClientDualManager_throwsCommandException() { + InflowControlManager baseMgr = mock(InflowControlManager.class); + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", baseMgr); + + assertThrows(CommandException.class, commandWith("CLIENT_A")::execute); + } + + // ========================================================================= + // 전체 재로드 (ALL) + // ========================================================================= + + @Test + void execute_argsIsALL_callsReloadClientNoArgs() throws Exception { + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", mockDualManager); + + Object result = commandWith("ALL").execute(); + + assertEquals("success", result); + verify(mockDualManager).reloadClient(); + verify(mockDualManager, never()).reloadClient(anyString()); + } + + // ========================================================================= + // 개별 재로드 (ClientId) + // ========================================================================= + + @Test + void execute_argsIsClientId_callsReloadClientWithId() throws Exception { + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", mockDualManager); + + Object result = commandWith("CLIENT_A").execute(); + + assertEquals("success", result); + verify(mockDualManager).reloadClient("CLIENT_A"); + verify(mockDualManager, never()).reloadClient(); + } + + @Test + void execute_differentClientId_callsReloadClientWithThatId() throws Exception { + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", mockDualManager); + + commandWith("CLIENT_B").execute(); + + verify(mockDualManager).reloadClient("CLIENT_B"); + } +} diff --git a/src/test/java/com/eactive/eai/agent/inflow/RemoveInflowClientControlCommandTest.java b/src/test/java/com/eactive/eai/agent/inflow/RemoveInflowClientControlCommandTest.java new file mode 100644 index 0000000..940d8da --- /dev/null +++ b/src/test/java/com/eactive/eai/agent/inflow/RemoveInflowClientControlCommandTest.java @@ -0,0 +1,101 @@ +package com.eactive.eai.agent.inflow; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.test.util.ReflectionTestUtils; + +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.agent.command.RemoveInflowClientControlCommand; +import com.eactive.eai.common.inflow.InflowControlManager; +import com.eactive.eai.common.inflow.InflowControlUtil; +import com.eactive.eai.custom.inflow.ClientDualInflowControlManager; + +/** + * RemoveInflowClientControlCommand 단위 테스트. + * + *

InflowControlUtil의 cachedInflowControlManager 필드에 mock을 직접 주입하여 + * PropManager/ApplicationContext 없이 동작을 검증한다. + */ +class RemoveInflowClientControlCommandTest { + + private ClientDualInflowControlManager mockDualManager; + + @BeforeEach + void setUp() { + mockDualManager = mock(ClientDualInflowControlManager.class); + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", null); + } + + @AfterEach + void tearDown() { + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", null); + } + + private RemoveInflowClientControlCommand commandWith(Object args) { + RemoveInflowClientControlCommand cmd = new RemoveInflowClientControlCommand(); + cmd.setArgs(args); + return cmd; + } + + // ========================================================================= + // args 타입 검증 실패 + // ========================================================================= + + @Test + void execute_argsIsInteger_throwsCommandException() { + assertThrows(CommandException.class, commandWith(Integer.valueOf(1))::execute); + } + + // ========================================================================= + // ClientDualInflowControlManager 비활성 + // ========================================================================= + + @Test + void execute_notClientDualManager_throwsCommandException() { + InflowControlManager baseMgr = mock(InflowControlManager.class); + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", baseMgr); + + assertThrows(CommandException.class, commandWith("CLIENT_A")::execute); + } + + // ========================================================================= + // 정상 제거 + // ========================================================================= + + @Test + void execute_validClientId_callsRemoveClient() throws CommandException { + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", mockDualManager); + + Object result = commandWith("CLIENT_A").execute(); + + assertEquals("success", result); + verify(mockDualManager).removeClient("CLIENT_A"); + } + + @Test + void execute_differentClientId_callsRemoveClientWithThatId() throws Exception { + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", mockDualManager); + + commandWith("CLIENT_B").execute(); + + verify(mockDualManager).removeClient("CLIENT_B"); + } + + @Test + void execute_validClientId_doesNotCallReload() throws Exception { + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", mockDualManager); + + commandWith("CLIENT_A").execute(); + + verify(mockDualManager, never()).reloadClient(); + verify(mockDualManager, never()).reloadClient(anyString()); + } +}