mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-29 06:35:24 +00:00
feat: move terminal settings, look and ssh tools into ssh-terminal plugin
This commit is contained in:
1 parent
ffa872ebd3
commit
d9bba10612
242 files changed
+25071
-7207
No files matched your search
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
* The SSH connection options moving out of ssh_data.terminal_config into
|
||||
* the core ssh_options column, against a real SQLite database through the
|
||||
* same raw SQL helpers the boot path uses.
|
||||
*/
|
||||
|
||||
import Database from "better-sqlite3";
|
||||
import { drizzle } from "drizzle-orm/better-sqlite3";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const state = vi.hoisted(() => ({ db: null as unknown }));
|
||||
|
||||
vi.mock("../../../database/db/index.js", () => ({ getDb: () => state.db }));
|
||||
vi.mock("../../../utils/logger.js", () => ({
|
||||
databaseLogger: { info: vi.fn(), warn: vi.fn() },
|
||||
}));
|
||||
|
||||
const { runSshOptionsMigration } =
|
||||
await import("../../../utils/crypto-migration/ssh-options-migration.js");
|
||||
|
||||
let sqlite: Database.Database;
|
||||
|
||||
beforeEach(() => {
|
||||
sqlite = new Database(":memory:");
|
||||
sqlite.exec(`
|
||||
CREATE TABLE ssh_data (
|
||||
id INTEGER PRIMARY KEY,
|
||||
terminal_config TEXT,
|
||||
ssh_options TEXT
|
||||
);
|
||||
`);
|
||||
state.db = drizzle(sqlite);
|
||||
});
|
||||
|
||||
function insert(id: number, terminalConfig: unknown, sshOptions?: string) {
|
||||
sqlite
|
||||
.prepare(
|
||||
"INSERT INTO ssh_data (id, terminal_config, ssh_options) VALUES (?, ?, ?)",
|
||||
)
|
||||
.run(
|
||||
id,
|
||||
terminalConfig === null ? null : JSON.stringify(terminalConfig),
|
||||
sshOptions ?? null,
|
||||
);
|
||||
}
|
||||
|
||||
function options(id: number): unknown {
|
||||
const row = sqlite
|
||||
.prepare("SELECT ssh_options FROM ssh_data WHERE id = ?")
|
||||
.get(id) as { ssh_options: string | null };
|
||||
return row.ssh_options === null ? null : JSON.parse(row.ssh_options);
|
||||
}
|
||||
|
||||
describe("runSshOptionsMigration", () => {
|
||||
it("copies only the connection options, leaving the look and old tunnel keys", async () => {
|
||||
insert(1, {
|
||||
theme: "dracula",
|
||||
fontSize: 16,
|
||||
keepaliveInterval: 30,
|
||||
keepaliveCountMax: 3,
|
||||
allowLegacyAlgorithms: false,
|
||||
agentSocketPath: "/run/agent.sock",
|
||||
agentIdentity: "work",
|
||||
agentForwarding: true,
|
||||
environmentVariables: [{ key: "LANG", value: "C" }],
|
||||
startupSnippetId: 4,
|
||||
cfAccessClientId: "old",
|
||||
cfTunnelHostname: "old.example.com",
|
||||
});
|
||||
|
||||
const result = await runSshOptionsMigration();
|
||||
|
||||
expect(result.hostsMoved).toBe(1);
|
||||
expect(options(1)).toEqual({
|
||||
keepaliveInterval: 30,
|
||||
keepaliveCountMax: 3,
|
||||
allowLegacyAlgorithms: false,
|
||||
agentSocketPath: "/run/agent.sock",
|
||||
agentIdentity: "work",
|
||||
agentForwarding: true,
|
||||
environmentVariables: [{ key: "LANG", value: "C" }],
|
||||
});
|
||||
const terminalConfig = sqlite
|
||||
.prepare("SELECT terminal_config FROM ssh_data WHERE id = 1")
|
||||
.get() as { terminal_config: string };
|
||||
expect(JSON.parse(terminalConfig.terminal_config).keepaliveInterval).toBe(
|
||||
30,
|
||||
);
|
||||
});
|
||||
|
||||
it("marks a host with no options as done and skips hosts with no config", async () => {
|
||||
insert(1, { theme: "dracula" });
|
||||
insert(2, null);
|
||||
|
||||
const result = await runSshOptionsMigration();
|
||||
|
||||
expect(result.hostsMoved).toBe(0);
|
||||
expect(options(1)).toEqual({});
|
||||
expect(options(2)).toBeNull();
|
||||
});
|
||||
|
||||
it("changes nothing on a second run, even after the options were edited", async () => {
|
||||
insert(1, { keepaliveInterval: 30 });
|
||||
insert(
|
||||
2,
|
||||
{ keepaliveInterval: 45 },
|
||||
JSON.stringify({ keepaliveCountMax: 9 }),
|
||||
);
|
||||
await runSshOptionsMigration();
|
||||
|
||||
sqlite
|
||||
.prepare("UPDATE ssh_data SET ssh_options = ? WHERE id = 1")
|
||||
.run(JSON.stringify({ keepaliveInterval: 90 }));
|
||||
const second = await runSshOptionsMigration();
|
||||
|
||||
expect(second.hostsMoved).toBe(0);
|
||||
expect(options(1)).toEqual({ keepaliveInterval: 90 });
|
||||
expect(options(2)).toEqual({ keepaliveCountMax: 9 });
|
||||
});
|
||||
|
||||
it("does not throw on a database without the column", async () => {
|
||||
sqlite = new Database(":memory:");
|
||||
sqlite.exec("CREATE TABLE ssh_data (id INTEGER PRIMARY KEY)");
|
||||
state.db = drizzle(sqlite);
|
||||
await expect(runSshOptionsMigration()).resolves.toEqual({
|
||||
hostsMoved: 0,
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user