feat: prepare sellable source delivery edition
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
package com.sshmanager.service;
|
||||
|
||||
import com.sshmanager.dto.BackupConnectionDto;
|
||||
import com.sshmanager.dto.BackupImportResponseDto;
|
||||
import com.sshmanager.dto.BackupPackageDto;
|
||||
import com.sshmanager.dto.ConnectionDto;
|
||||
import com.sshmanager.dto.SessionTreeLayoutDto;
|
||||
import com.sshmanager.dto.SessionTreeNodeDto;
|
||||
import com.sshmanager.entity.Connection;
|
||||
import com.sshmanager.repository.ConnectionRepository;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class BackupServiceTest {
|
||||
|
||||
@Mock
|
||||
private ConnectionRepository connectionRepository;
|
||||
|
||||
@Mock
|
||||
private ConnectionService connectionService;
|
||||
|
||||
@Mock
|
||||
private SessionTreeLayoutService sessionTreeLayoutService;
|
||||
|
||||
@InjectMocks
|
||||
private BackupService backupService;
|
||||
|
||||
@Test
|
||||
void exportBackupIncludesConnectionsAndSessionTree() {
|
||||
Connection connection = new Connection();
|
||||
connection.setId(11L);
|
||||
connection.setName("prod");
|
||||
connection.setHost("127.0.0.1");
|
||||
connection.setPort(22);
|
||||
connection.setUsername("root");
|
||||
connection.setAuthType(Connection.AuthType.PASSWORD);
|
||||
|
||||
SessionTreeLayoutDto layout = new SessionTreeLayoutDto(Arrays.asList(
|
||||
new SessionTreeNodeDto("node-1", "connection", "prod", null, 0, 11L, null, 1L, 2L)
|
||||
));
|
||||
|
||||
when(connectionRepository.findByUserIdOrderByUpdatedAtDesc(1L)).thenReturn(Collections.singletonList(connection));
|
||||
when(connectionService.getDecryptedPassword(connection)).thenReturn("secret");
|
||||
when(sessionTreeLayoutService.getLayout(1L)).thenReturn(layout);
|
||||
|
||||
BackupPackageDto result = backupService.exportBackup(1L);
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.getConnections().size());
|
||||
assertEquals(11L, result.getConnections().get(0).getSourceId().longValue());
|
||||
assertEquals("secret", result.getConnections().get(0).getPassword());
|
||||
assertEquals(layout, result.getSessionTree());
|
||||
}
|
||||
|
||||
@Test
|
||||
void importBackupReplacesConnectionsAndRemapsTreeIds() {
|
||||
BackupConnectionDto backupConnection = new BackupConnectionDto();
|
||||
backupConnection.setSourceId(7L);
|
||||
backupConnection.setName("prod");
|
||||
backupConnection.setHost("10.0.0.10");
|
||||
backupConnection.setPort(22);
|
||||
backupConnection.setUsername("root");
|
||||
backupConnection.setAuthType(Connection.AuthType.PASSWORD);
|
||||
backupConnection.setPassword("secret");
|
||||
|
||||
BackupPackageDto backupPackage = new BackupPackageDto();
|
||||
backupPackage.setConnections(Collections.singletonList(backupConnection));
|
||||
backupPackage.setSessionTree(new SessionTreeLayoutDto(Arrays.asList(
|
||||
new SessionTreeNodeDto("folder-1", "folder", "生产", null, 0, null, true, 1L, 2L),
|
||||
new SessionTreeNodeDto("conn-1", "connection", "prod", "folder-1", 1, 7L, null, 1L, 2L)
|
||||
)));
|
||||
|
||||
ConnectionDto created = new ConnectionDto();
|
||||
created.setId(101L);
|
||||
|
||||
when(connectionRepository.findByUserIdOrderByUpdatedAtDesc(1L)).thenReturn(Collections.emptyList());
|
||||
when(connectionService.create(any(), eq(1L))).thenReturn(created);
|
||||
|
||||
BackupImportResponseDto result = backupService.importBackup(1L, backupPackage);
|
||||
|
||||
assertEquals(1, result.getImportedConnections());
|
||||
assertEquals(2, result.getImportedTreeNodes());
|
||||
verify(connectionRepository).deleteAll(Collections.emptyList());
|
||||
|
||||
ArgumentCaptor<SessionTreeLayoutDto> captor = ArgumentCaptor.forClass(SessionTreeLayoutDto.class);
|
||||
verify(sessionTreeLayoutService).saveLayout(eq(1L), captor.capture());
|
||||
SessionTreeLayoutDto savedLayout = captor.getValue();
|
||||
assertEquals(2, savedLayout.getNodes().size());
|
||||
assertEquals(101L, savedLayout.getNodes().get(1).getConnectionId().longValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.sshmanager.service;
|
||||
|
||||
import com.sshmanager.dto.BatchCommandRequest;
|
||||
import com.sshmanager.dto.BatchCommandResponseDto;
|
||||
import com.sshmanager.entity.Connection;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class BatchCommandServiceTest {
|
||||
|
||||
@Mock
|
||||
private ConnectionService connectionService;
|
||||
|
||||
@Mock
|
||||
private SshService sshService;
|
||||
|
||||
@InjectMocks
|
||||
private BatchCommandService batchCommandService;
|
||||
|
||||
@Test
|
||||
void executeAggregatesSuccessAndFailure() throws Exception {
|
||||
Connection successConnection = new Connection();
|
||||
successConnection.setId(1L);
|
||||
successConnection.setUserId(99L);
|
||||
successConnection.setName("prod");
|
||||
|
||||
Connection failedConnection = new Connection();
|
||||
failedConnection.setId(2L);
|
||||
failedConnection.setUserId(99L);
|
||||
failedConnection.setName("test");
|
||||
|
||||
BatchCommandRequest request = new BatchCommandRequest();
|
||||
request.setConnectionIds(Arrays.asList(1L, 2L));
|
||||
request.setCommand("uptime");
|
||||
|
||||
when(connectionService.getConnectionForSsh(1L, 99L)).thenReturn(successConnection);
|
||||
when(connectionService.getConnectionForSsh(2L, 99L)).thenReturn(failedConnection);
|
||||
when(sshService.executeCommand(eq(successConnection), eq(null), eq(null), eq(null), eq("uptime"))).thenReturn("ok");
|
||||
when(sshService.executeCommand(eq(failedConnection), eq(null), eq(null), eq(null), eq("uptime"))).thenThrow(new RuntimeException("boom"));
|
||||
|
||||
BatchCommandResponseDto response = batchCommandService.execute(99L, request);
|
||||
|
||||
assertEquals(2, response.getTotal());
|
||||
assertEquals(1, response.getSuccessCount());
|
||||
assertEquals(1, response.getFailureCount());
|
||||
assertEquals("prod", response.getResults().get(0).getConnectionName());
|
||||
assertEquals("ok", response.getResults().get(0).getOutput());
|
||||
assertEquals("boom", response.getResults().get(1).getError());
|
||||
}
|
||||
|
||||
@Test
|
||||
void executeRejectsEmptyCommand() {
|
||||
BatchCommandRequest request = new BatchCommandRequest();
|
||||
request.setConnectionIds(Arrays.asList(1L));
|
||||
request.setCommand(" ");
|
||||
|
||||
IllegalArgumentException error = assertThrows(IllegalArgumentException.class, () -> batchCommandService.execute(1L, request));
|
||||
assertEquals("Command is required", error.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,7 @@ class SessionTreeLayoutServiceTest {
|
||||
SessionTreeLayoutDto result = sessionTreeLayoutService.getLayout(1L);
|
||||
|
||||
assertTrue(result.getNodes().isEmpty());
|
||||
assertEquals("manual", result.getSortMode());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -52,6 +53,7 @@ class SessionTreeLayoutServiceTest {
|
||||
SessionTreeLayoutDto parsed = new SessionTreeLayoutDto(Arrays.asList(
|
||||
new SessionTreeNodeDto("n1", "folder", "我的连接", null, 0, null, true, 1L, 1L)
|
||||
));
|
||||
parsed.setSortMode(null);
|
||||
|
||||
when(sessionTreeLayoutRepository.findByUserId(1L)).thenReturn(Optional.of(saved));
|
||||
when(objectMapper.readValue(saved.getLayoutJson(), SessionTreeLayoutDto.class)).thenReturn(parsed);
|
||||
@@ -60,12 +62,14 @@ class SessionTreeLayoutServiceTest {
|
||||
|
||||
assertEquals(1, result.getNodes().size());
|
||||
assertEquals("n1", result.getNodes().get(0).getId());
|
||||
assertEquals("manual", result.getSortMode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void saveLayoutNormalizesNullNodes() throws Exception {
|
||||
SessionTreeLayoutDto request = new SessionTreeLayoutDto();
|
||||
request.setNodes(null);
|
||||
request.setSortMode("unknown");
|
||||
|
||||
when(sessionTreeLayoutRepository.findByUserId(1L)).thenReturn(Optional.empty());
|
||||
when(objectMapper.writeValueAsString(any(SessionTreeLayoutDto.class))).thenReturn("{\"nodes\":[]}");
|
||||
@@ -73,6 +77,7 @@ class SessionTreeLayoutServiceTest {
|
||||
SessionTreeLayoutDto result = sessionTreeLayoutService.saveLayout(1L, request);
|
||||
|
||||
assertTrue(result.getNodes().isEmpty());
|
||||
assertEquals("manual", result.getSortMode());
|
||||
ArgumentCaptor<SessionTreeLayout> captor = ArgumentCaptor.forClass(SessionTreeLayout.class);
|
||||
verify(sessionTreeLayoutRepository).save(captor.capture());
|
||||
assertEquals(1L, captor.getValue().getUserId().longValue());
|
||||
@@ -87,5 +92,6 @@ class SessionTreeLayoutServiceTest {
|
||||
SessionTreeLayoutDto result = sessionTreeLayoutService.saveLayout(1L, null);
|
||||
|
||||
assertEquals(Collections.emptyList(), result.getNodes());
|
||||
assertEquals("manual", result.getSortMode());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user