aeStatusPage/test/atomicJson.test.js
jmcqueen 007086caf6 Initial commit: status-page bridge with Webex bot management
Bridges third-party status pages into Webex spaces via RSS polling and
inbound webhooks (Statuspage / Status.io / Uptime Kuma / generic).

Includes an interactive Webex bot (websocket transport) that lets space
members register sources with an Adaptive Card instead of hand-editing
config/feeds.json: help, add, list, webhook <key>, remove <key>.

Ships with an atomic JSON store (per-file mutex, tmp+rename), parallel
RSS polling, and unit tests via node:test. All secrets are sourced from
environment variables (see .env.example); no credentials in the repo.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 16:08:34 -04:00

52 lines
1.9 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { readJSON, writeJSON } from '../src/atomicJson.js';
function tmpFile(name) {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'atomicjson-'));
return path.join(dir, name);
}
test('writeJSON persists and readJSON reads it back', async () => {
const file = tmpFile('a.json');
await writeJSON(file, { hello: 'world', n: 1 });
assert.deepEqual(readJSON(file), { hello: 'world', n: 1 });
});
test('concurrent writeJSON calls all land, none corrupt the target', async () => {
const file = tmpFile('b.json');
const writers = [];
for (let i = 0; i < 25; i++) {
writers.push(writeJSON(file, { i, at: Date.now() }));
}
await Promise.all(writers);
// File must be valid JSON with one of the written objects.
const parsed = readJSON(file);
assert.equal(typeof parsed.i, 'number');
assert.ok(parsed.i >= 0 && parsed.i < 25);
});
test('writeJSON removes tmp files on rename failure', async () => {
const file = tmpFile('c.json');
await writeJSON(file, { ok: true });
// Force a rename failure by pointing at a path whose parent does not exist.
const bad = path.join(file, 'nested', 'not', 'there.json');
await assert.rejects(writeJSON(bad, { x: 1 }));
// No tmp files should be left in the parent dir of `file`.
const dir = path.dirname(file);
const stray = fs.readdirSync(dir).filter(n => n.endsWith('.tmp'));
assert.deepEqual(stray, []);
});
test('writes to different paths do not block each other', async () => {
const f1 = tmpFile('d.json');
const f2 = tmpFile('e.json');
await Promise.all([writeJSON(f1, { a: 1 }), writeJSON(f2, { b: 2 })]);
assert.deepEqual(readJSON(f1), { a: 1 });
assert.deepEqual(readJSON(f2), { b: 2 });
});