import test from "node:test"; import assert from "node:assert/strict"; import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs"; import { join } from "node:path"; import { tmpdir } from "node:os"; let tmpDir: string; let origHome: string | undefined; let origPath: string | undefined; test.before(() => { tmpDir = mkdtempSync(join(tmpdir(), "omniroute-tray-test-")); origHome = process.env.HOME; // Redirecionar HOME para tmpDir para isolar testes de autostart process.env.HOME = tmpDir; // HOME alone does NOT isolate this test: `enable()`/`disable()` shell out to // `systemctl --user enable|start` and `systemctl --user disable --now // omniroute.service`, which reach the caller's real systemd bus (XDG_RUNTIME_DIR, // not HOME) and therefore stopped and disabled the developer's REAL omniroute // service every time this suite ran. Shadow systemctl/loginctl with failing // stubs so `isSystemdUserAvailable()` is false and the systemd branch is skipped; // the XDG desktop-file branch still runs and is properly isolated by HOME. // Same rationale documented at length in tests/unit/cli/autostart-linux.test.ts. origPath = process.env.PATH; const stubBin = join(tmpDir, "stub-bin"); mkdirSync(stubBin, { recursive: true }); for (const name of ["systemctl", "loginctl"]) { writeFileSync(join(stubBin, name), "#!/bin/sh\nexit 1\n", { mode: 0o755 }); } process.env.PATH = `${stubBin}:${origPath ?? ""}`; }); test.after(() => { if (origHome === undefined) delete process.env.HOME; else process.env.HOME = origHome; if (origPath === undefined) delete process.env.PATH; else process.env.PATH = origPath; try { rmSync(tmpDir, { recursive: true, force: true }); } catch {} }); test("tray/index.mjs pode ser importado sem erro", async () => { const mod = await import("../../bin/cli/tray/index.mjs"); assert.equal(typeof mod.initTray, "function"); assert.equal(typeof mod.killTray, "function"); assert.equal(typeof mod.isTrayActive, "function"); assert.equal(typeof mod.isTraySupported, "function"); }); test("isTraySupported retorna boolean", async () => { const { isTraySupported } = await import("../../bin/cli/tray/index.mjs"); assert.equal(typeof isTraySupported(), "boolean"); }); test("isTrayActive retorna false antes de iniciar", async () => { const { isTrayActive } = await import("../../bin/cli/tray/index.mjs"); assert.equal(isTrayActive(), false); }); test("tray/autostart.mjs pode ser importado sem erro", async () => { const mod = await import("../../bin/cli/tray/autostart.mjs"); assert.equal(typeof mod.enable, "function"); assert.equal(typeof mod.disable, "function"); assert.equal(typeof mod.isAutostartEnabled, "function"); }); test("autostart.isAutostartEnabled retorna boolean", async () => { const { isAutostartEnabled } = await import("../../bin/cli/tray/autostart.mjs"); const result = isAutostartEnabled(); assert.equal(typeof result, "boolean"); assert.equal(result, false, "autostart não deve estar habilitado em tmpDir isolado"); }); test("autostart.enable registers Linux autostart (systemd and/or desktop)", async () => { if (process.platform !== "linux") return; const { enable, isAutostartEnabled, disable, getAutostartStatus } = await import("../../bin/cli/tray/autostart.mjs"); const ok = enable(); assert.equal(typeof ok, "boolean"); if (ok) { assert.equal(isAutostartEnabled(), true, "isAutostartEnabled deve ser true após enable"); const status = getAutostartStatus(); assert.ok( status.mechanism === "systemd-user" || status.mechanism === "xdg-desktop", "expected systemd-user or xdg-desktop mechanism" ); } disable(); assert.equal(isAutostartEnabled(), false, "isAutostartEnabled deve ser false após disable"); }); test("commands/tray.mjs pode ser importado sem erro", async () => { const mod = await import("../../bin/cli/commands/tray.mjs"); assert.equal(typeof mod.registerTray, "function"); }); test("commands/autostart.mjs pode ser importado sem erro", async () => { const mod = await import("../../bin/cli/commands/autostart.mjs"); assert.equal(typeof mod.registerAutostart, "function"); });