84 lines
2.6 KiB
JavaScript
84 lines
2.6 KiB
JavaScript
|
|
const { test, beforeEach, afterEach } = require('node:test');
|
||
|
|
const assert = require('node:assert/strict');
|
||
|
|
const fs = require('node:fs');
|
||
|
|
const os = require('node:os');
|
||
|
|
const path = require('node:path');
|
||
|
|
|
||
|
|
const config = require('../src/config');
|
||
|
|
|
||
|
|
const ENV_KEYS = [
|
||
|
|
'STOKE_CONFIG_DIR', 'STOKE_CONFIG_FILE',
|
||
|
|
'FORGEJO_CONFIG_DIR', 'FORGEJO_CONFIG_FILE',
|
||
|
|
'XDG_CONFIG_HOME',
|
||
|
|
];
|
||
|
|
|
||
|
|
let savedEnv;
|
||
|
|
let tmpDir;
|
||
|
|
|
||
|
|
beforeEach(() => {
|
||
|
|
savedEnv = {};
|
||
|
|
for (const key of ENV_KEYS) {
|
||
|
|
savedEnv[key] = process.env[key];
|
||
|
|
delete process.env[key];
|
||
|
|
}
|
||
|
|
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'stoke-test-'));
|
||
|
|
});
|
||
|
|
|
||
|
|
afterEach(() => {
|
||
|
|
for (const key of ENV_KEYS) {
|
||
|
|
if (savedEnv[key] === undefined) delete process.env[key];
|
||
|
|
else process.env[key] = savedEnv[key];
|
||
|
|
}
|
||
|
|
fs.rmSync(tmpDir, { recursive: true, force: true });
|
||
|
|
});
|
||
|
|
|
||
|
|
test('default config path lives under ~/.config/stoke', () => {
|
||
|
|
assert.equal(config.getConfigPath(), path.join(os.homedir(), '.config', 'stoke', 'config.json'));
|
||
|
|
});
|
||
|
|
|
||
|
|
test('XDG_CONFIG_HOME replaces ~/.config entirely', () => {
|
||
|
|
process.env.XDG_CONFIG_HOME = tmpDir;
|
||
|
|
assert.equal(config.getConfigPath(), path.join(tmpDir, 'stoke', 'config.json'));
|
||
|
|
});
|
||
|
|
|
||
|
|
test('STOKE_CONFIG_FILE overrides everything', () => {
|
||
|
|
process.env.XDG_CONFIG_HOME = '/elsewhere';
|
||
|
|
process.env.STOKE_CONFIG_FILE = path.join(tmpDir, 'custom.json');
|
||
|
|
assert.equal(config.getConfigPath(), path.join(tmpDir, 'custom.json'));
|
||
|
|
});
|
||
|
|
|
||
|
|
test('config path is resolved lazily (STOKE_CONFIG_FILE set after require)', () => {
|
||
|
|
const first = path.join(tmpDir, 'a.json');
|
||
|
|
const second = path.join(tmpDir, 'b.json');
|
||
|
|
process.env.STOKE_CONFIG_FILE = first;
|
||
|
|
assert.equal(config.getConfigPath(), first);
|
||
|
|
process.env.STOKE_CONFIG_FILE = second;
|
||
|
|
assert.equal(config.getConfigPath(), second);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('save/load/clear round-trip with restrictive permissions', () => {
|
||
|
|
process.env.STOKE_CONFIG_FILE = path.join(tmpDir, 'nested', 'config.json');
|
||
|
|
|
||
|
|
assert.equal(config.loadConfig(), null);
|
||
|
|
|
||
|
|
const data = { url: 'https://example.test', token: 'abc', tokenId: 1 };
|
||
|
|
config.saveConfig(data);
|
||
|
|
assert.deepEqual(config.loadConfig(), data);
|
||
|
|
|
||
|
|
if (process.platform !== 'win32') {
|
||
|
|
const mode = fs.statSync(config.getConfigPath()).mode & 0o777;
|
||
|
|
assert.equal(mode, 0o600);
|
||
|
|
}
|
||
|
|
|
||
|
|
config.clearConfig();
|
||
|
|
assert.equal(config.loadConfig(), null);
|
||
|
|
// clearing twice must not throw
|
||
|
|
config.clearConfig();
|
||
|
|
});
|
||
|
|
|
||
|
|
test('loadConfig surfaces corrupt config files as errors', () => {
|
||
|
|
process.env.STOKE_CONFIG_FILE = path.join(tmpDir, 'corrupt.json');
|
||
|
|
fs.writeFileSync(process.env.STOKE_CONFIG_FILE, 'not-json');
|
||
|
|
assert.throws(() => config.loadConfig(), /Failed to read config/);
|
||
|
|
});
|