'use strict' const assert = require('node:assert/strict') const fs = require('node:fs') const os = require('node:os') const path = require('node:path') const test = require('node:test') const { AUTOSTART_FILE, resolveAutostartFile, isAutostartEnabled, setAutostart } = require('./autostart') // 用绝对路径字符串拼测试目录,避免依赖运行平台的盘符写法 const HOME = path.resolve('/home/operator') function makeRoot(t) { const root = fs.mkdtempSync(path.join(os.tmpdir(), 'scoreboard-autostart-')) t.after(() => fs.rmSync(root, { recursive: true, force: true })) return root } test('自启文件在 $XDG_CONFIG_HOME/autostart 下,缺省用 ~/.config/autostart', () => { const xdg = path.resolve('/xdg/config') assert.equal( resolveAutostartFile({ platform: 'linux', env: { XDG_CONFIG_HOME: xdg } }), path.join(xdg, 'autostart', AUTOSTART_FILE) ) assert.equal( resolveAutostartFile({ platform: 'linux', env: { HOME } }), path.join(HOME, '.config', 'autostart', AUTOSTART_FILE) ) }) test('非 Linux 平台没有这个文件(Windows/macOS 走系统登录项)', () => { assert.equal(resolveAutostartFile({ platform: 'win32', env: { HOME } }), null) assert.equal(resolveAutostartFile({ platform: 'darwin', env: { HOME } }), null) assert.throws( () => setAutostart({ platform: 'win32', env: { HOME }, exePath: '/x/Scoreboard_Console', enabled: true }), /Linux/ ) }) test('开:写出 .desktop,Exec 指向 Console 自己;关:把文件删掉', (t) => { const root = makeRoot(t) const env = { XDG_CONFIG_HOME: root } const exePath = path.join(root, 'install', 'Scoreboard_Console') const file = resolveAutostartFile({ platform: 'linux', env }) assert.equal(isAutostartEnabled({ platform: 'linux', env }), false) assert.equal(fs.existsSync(file), false) setAutostart({ platform: 'linux', env, exePath, enabled: true }) assert.equal(isAutostartEnabled({ platform: 'linux', env }), true) const text = fs.readFileSync(file, 'utf8') assert.match(text, /^\[Desktop Entry\]$/m) assert.match(text, /^Type=Application$/m) assert.match(text, /^Exec=.*Scoreboard_Console.*$/m) assert.match(text, /^X-GNOME-Autostart-enabled=true$/m) // 重复开一次是幂等的(每次启动 Console 都会按配置重写一遍) setAutostart({ platform: 'linux', env, exePath, enabled: true }) assert.equal(fs.readFileSync(file, 'utf8'), text) assert.equal(isAutostartEnabled({ platform: 'linux', env }), true) setAutostart({ platform: 'linux', env, exePath, enabled: false }) assert.equal(fs.existsSync(file), false) assert.equal(isAutostartEnabled({ platform: 'linux', env }), false) // 关两次不报错:现场连点开关、或文件本来就不在(目录也一并没了) setAutostart({ platform: 'linux', env, exePath, enabled: false }) }) test('安装路径带空格时 Exec 加引号,否则自启会被拆成两个参数', (t) => { const root = makeRoot(t) const env = { XDG_CONFIG_HOME: root } const exePath = path.join(root, 'Scoreboard Console', 'Scoreboard_Console') setAutostart({ platform: 'linux', env, exePath, enabled: true }) const text = fs.readFileSync(resolveAutostartFile({ platform: 'linux', env }), 'utf8') assert.match(text, new RegExp(`^Exec="${exePath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}"$`, 'm')) }) test('文件被标了 Hidden=true(别的桌面环境关闭自启时的写法)视为关闭', (t) => { const root = makeRoot(t) const env = { XDG_CONFIG_HOME: root } const file = resolveAutostartFile({ platform: 'linux', env }) setAutostart({ platform: 'linux', env, exePath: '/x/Scoreboard_Console', enabled: true }) assert.equal(isAutostartEnabled({ platform: 'linux', env }), true) // 现场从桌面环境的「启动应用程序」里关掉自启时,各家的写法不一致: // XDG 规范里 Hidden=true 就是「忽略这个文件」,必须认出来 fs.writeFileSync(file, fs.readFileSync(file, 'utf8').replace('Hidden=false', 'Hidden=true'), 'utf8') assert.equal(isAutostartEnabled({ platform: 'linux', env }), false) }) test('拿不到 $XDG_CONFIG_HOME 也拿不到 $HOME 时开关都报错,不静默当成功', () => { const env = {} assert.equal(resolveAutostartFile({ platform: 'linux', env }), null) assert.equal(isAutostartEnabled({ platform: 'linux', env }), false) assert.throws(() => setAutostart({ platform: 'linux', env, exePath: '/x/Scoreboard_Console', enabled: true }), /XDG_CONFIG_HOME/) assert.throws(() => setAutostart({ platform: 'linux', env, exePath: '/x/Scoreboard_Console', enabled: false }), /XDG_CONFIG_HOME/) }) test('拿不到 Console 自身路径时不写一个空 Exec 出去', (t) => { const root = makeRoot(t) const env = { XDG_CONFIG_HOME: root } assert.throws(() => setAutostart({ platform: 'linux', env, exePath: '', enabled: true }), /路径/) assert.equal(isAutostartEnabled({ platform: 'linux', env }), false) })