mirror of
https://github.com/Quad4-Software/MeshChatX.git
synced 2026-08-18 09:49:09 -04:00
69 lines
3 KiB
JavaScript
69 lines
3 KiB
JavaScript
import { describe, expect, it } from "vitest";
|
|
import fs from "node:fs";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import {
|
|
buildDataCleanupGuide,
|
|
getCrashRecoveryInfo,
|
|
listRecoveryBackups,
|
|
pickPreferredRestoreBackup,
|
|
} from "../../electron/offlineRecovery.js";
|
|
|
|
describe("electron/offlineRecovery", () => {
|
|
it("lists automatic and snapshot backups newest first", () => {
|
|
const storageDir = fs.mkdtempSync(path.join(os.tmpdir(), "meshchatx-recovery-"));
|
|
try {
|
|
const autoDir = path.join(storageDir, "database-backups");
|
|
const snapshotDir = path.join(storageDir, "snapshots");
|
|
fs.mkdirSync(autoDir, { recursive: true });
|
|
fs.mkdirSync(snapshotDir, { recursive: true });
|
|
fs.writeFileSync(path.join(autoDir, "backup-old.zip"), "a");
|
|
fs.writeFileSync(path.join(autoDir, "backup-new.zip"), "ab");
|
|
fs.writeFileSync(path.join(snapshotDir, "manual.zip"), "abc");
|
|
|
|
const now = Date.now();
|
|
fs.utimesSync(path.join(autoDir, "backup-old.zip"), now / 1000 - 120, now / 1000 - 120);
|
|
fs.utimesSync(path.join(autoDir, "backup-new.zip"), now / 1000, now / 1000);
|
|
fs.utimesSync(path.join(snapshotDir, "manual.zip"), now / 1000 - 30, now / 1000 - 30);
|
|
|
|
const backups = listRecoveryBackups(storageDir);
|
|
expect(backups.map((entry) => entry.name)).toEqual(["backup-new.zip", "manual.zip", "backup-old.zip"]);
|
|
} finally {
|
|
fs.rmSync(storageDir, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
it("prefers non-suspicious backups for restore", () => {
|
|
const backups = [
|
|
{ name: "backup-SUSPICIOUS-1.zip", suspicious: true, createdAt: "2026-01-02T00:00:00.000Z" },
|
|
{ name: "backup-2.zip", suspicious: false, createdAt: "2026-01-01T00:00:00.000Z" },
|
|
];
|
|
expect(pickPreferredRestoreBackup(backups)?.name).toBe("backup-2.zip");
|
|
});
|
|
|
|
it("builds cleanup guide with storage and reticulum paths", () => {
|
|
const guide = buildDataCleanupGuide({
|
|
storageDir: "/home/user/.reticulum-meshchatx",
|
|
reticulumConfigDir: "/home/user/.reticulum",
|
|
platform: "linux",
|
|
portableExecutableDir: null,
|
|
});
|
|
expect(guide).toContain("/home/user/.reticulum-meshchatx");
|
|
expect(guide).toContain("/home/user/.reticulum");
|
|
expect(guide).toContain("Quit MeshChatX");
|
|
});
|
|
|
|
it("detects database corruption in crash recovery info", () => {
|
|
const info = getCrashRecoveryInfo({
|
|
storageDir: "/tmp/meshchatx",
|
|
reticulumConfigDir: "/tmp/reticulum",
|
|
platform: "linux",
|
|
portableExecutableDir: null,
|
|
stderr: "sqlite3.DatabaseError: database disk image is malformed",
|
|
stdout: "",
|
|
exitCode: 1,
|
|
});
|
|
expect(info.diagnosis.category).toBe("database");
|
|
expect(info.cleanupGuide).toContain("Complete MeshChatX / Reticulum data reset");
|
|
});
|
|
});
|