package com.sshmanager.service; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.Session; import com.jcraft.jsch.SftpATTRS; import com.jcraft.jsch.SftpException; import com.sshmanager.entity.Connection; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; class SftpServiceTest { private SftpService sftpService; private ExecutorService executorService; @BeforeEach void setUp() { executorService = Executors.newFixedThreadPool(2); sftpService = new SftpService(); sftpService.setExecutorService(executorService); } @Test void testPasswordAuthenticationRequiredWithValidConnection() { Exception exception = assertThrows(Exception.class, () -> { Connection conn = new Connection(); conn.setHost("127.0.0.1"); conn.setPort(22); conn.setUsername("test"); conn.setAuthType(Connection.AuthType.PASSWORD); sftpService.connect(conn, "", null, null); }); assertTrue(exception.getMessage().contains("Password is required") || exception instanceof IllegalArgumentException); } @Test void testPasswordAuthenticationRequiredWithNullConn() { Exception exception = assertThrows(Exception.class, () -> { sftpService.connect(null, "", null, null); }); assertTrue(exception instanceof NullPointerException || exception instanceof IllegalArgumentException); } @Test void testExecutorServiceShutdown() throws Exception { executorService.shutdown(); assertTrue(executorService.isTerminated() || executorService.isShutdown()); } @Test void statIfExistsReturnsNullWhenRemotePathIsMissing() throws Exception { Session session = mock(Session.class); ChannelSftp channel = mock(ChannelSftp.class); when(channel.stat("/missing.txt")).thenThrow(new SftpException(ChannelSftp.SSH_FX_NO_SUCH_FILE, "missing")); SftpService.PathInfo result = sftpService.statIfExists(new SftpService.SftpSession(session, channel), "/missing.txt"); assertNull(result); } @Test void statIfExistsReturnsDirectoryFlagForExistingPath() throws Exception { Session session = mock(Session.class); ChannelSftp channel = mock(ChannelSftp.class); SftpATTRS attrs = mock(SftpATTRS.class); when(channel.stat("/existing")).thenReturn(attrs); when(attrs.isDir()).thenReturn(true); SftpService.PathInfo result = sftpService.statIfExists(new SftpService.SftpSession(session, channel), "/existing"); assertNotNull(result); assertTrue(result.directory); } }