mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 22:25:24 +00:00
feat: convert tmux monitoring into a plugin (B10)
This commit is contained in:
1 parent
79d77678c9
commit
708eedb861
145 files changed
+30308
-4458
No files matched your search
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* The tmux monitor host-column migration.
|
||||
*
|
||||
* An upgrade must be lossless: a host with the monitor on must keep it on
|
||||
* once the ssh_data column is dropped. Running it twice must not duplicate
|
||||
* or clobber what it moved.
|
||||
*/
|
||||
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
interface HostRow {
|
||||
id: number;
|
||||
enable_tmux_monitor: boolean;
|
||||
}
|
||||
|
||||
interface SettingsRow {
|
||||
pluginId: string;
|
||||
scope: string;
|
||||
scopeId: string | null;
|
||||
key: string;
|
||||
value: string | null;
|
||||
}
|
||||
|
||||
const hostRows: HostRow[] = [];
|
||||
const settingsRows: SettingsRow[] = [];
|
||||
|
||||
const find = (
|
||||
pluginId: string,
|
||||
scope: string,
|
||||
scopeId: string | null,
|
||||
key: string,
|
||||
) =>
|
||||
settingsRows.find(
|
||||
(row) =>
|
||||
row.pluginId === pluginId &&
|
||||
row.scope === scope &&
|
||||
row.scopeId === scopeId &&
|
||||
row.key === key,
|
||||
);
|
||||
|
||||
const pluginSettingsRepository = {
|
||||
get: async (
|
||||
pluginId: string,
|
||||
scope: string,
|
||||
scopeId: string | null,
|
||||
key: string,
|
||||
) => find(pluginId, scope, scopeId, key) ?? null,
|
||||
set: async (
|
||||
pluginId: string,
|
||||
scope: string,
|
||||
scopeId: string | null,
|
||||
key: string,
|
||||
value: string | null,
|
||||
) => {
|
||||
const existing = find(pluginId, scope, scopeId, key);
|
||||
if (existing) {
|
||||
existing.value = value;
|
||||
return;
|
||||
}
|
||||
settingsRows.push({ pluginId, scope, scopeId, key, value });
|
||||
},
|
||||
};
|
||||
|
||||
vi.mock("../../database/repositories/factory.js", () => ({
|
||||
createCurrentPluginSettingsRepository: () => pluginSettingsRepository,
|
||||
}));
|
||||
|
||||
vi.mock("../../database/db/index.js", () => ({
|
||||
getDb: () => ({
|
||||
all: async () => hostRows.filter((row) => row.enable_tmux_monitor),
|
||||
}),
|
||||
}));
|
||||
|
||||
const { runTmuxMonitorSettingsMigration } =
|
||||
await import("../../utils/crypto-migration/tmux-monitor-settings-migration.js");
|
||||
|
||||
function storedValue(hostId: number, key: string): unknown {
|
||||
const row = settingsRows.find(
|
||||
(entry) => entry.scopeId === String(hostId) && entry.key === key,
|
||||
);
|
||||
return row?.value === null || row?.value === undefined
|
||||
? undefined
|
||||
: JSON.parse(row.value);
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
hostRows.length = 0;
|
||||
settingsRows.length = 0;
|
||||
});
|
||||
|
||||
describe("runTmuxMonitorSettingsMigration", () => {
|
||||
it("moves a host's enabled switch into plugin settings", async () => {
|
||||
hostRows.push({ id: 1, enable_tmux_monitor: true });
|
||||
|
||||
const result = await runTmuxMonitorSettingsMigration();
|
||||
|
||||
expect(result.moved).toBe(1);
|
||||
expect(storedValue(1, "enableTmuxMonitor")).toBe(true);
|
||||
expect(settingsRows.every((row) => row.pluginId === "tmux-monitor")).toBe(
|
||||
true,
|
||||
);
|
||||
expect(settingsRows.every((row) => row.scope === "host")).toBe(true);
|
||||
});
|
||||
|
||||
it("leaves a disabled host untouched", async () => {
|
||||
hostRows.push({ id: 3, enable_tmux_monitor: false });
|
||||
|
||||
const result = await runTmuxMonitorSettingsMigration();
|
||||
|
||||
expect(result.moved).toBe(0);
|
||||
expect(storedValue(3, "enableTmuxMonitor")).toBeUndefined();
|
||||
});
|
||||
|
||||
it("does nothing on a fresh install", async () => {
|
||||
const result = await runTmuxMonitorSettingsMigration();
|
||||
|
||||
expect(result.moved).toBe(0);
|
||||
expect(settingsRows).toEqual([]);
|
||||
});
|
||||
|
||||
it("is idempotent: a second run changes nothing", async () => {
|
||||
hostRows.push({ id: 2, enable_tmux_monitor: true });
|
||||
|
||||
await runTmuxMonitorSettingsMigration();
|
||||
const afterFirst = JSON.parse(JSON.stringify(settingsRows));
|
||||
|
||||
const second = await runTmuxMonitorSettingsMigration();
|
||||
|
||||
expect(second.moved).toBe(0);
|
||||
expect(second.skipped).toBe(1);
|
||||
expect(settingsRows).toEqual(afterFirst);
|
||||
});
|
||||
|
||||
it("does not overwrite a value the plugin already saved", async () => {
|
||||
hostRows.push({ id: 5, enable_tmux_monitor: true });
|
||||
await pluginSettingsRepository.set(
|
||||
"tmux-monitor",
|
||||
"host",
|
||||
"5",
|
||||
"enableTmuxMonitor",
|
||||
"false",
|
||||
);
|
||||
|
||||
const result = await runTmuxMonitorSettingsMigration();
|
||||
|
||||
expect(result.skipped).toBe(1);
|
||||
expect(storedValue(5, "enableTmuxMonitor")).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user