import { describe, test, before, after } from 'node:test'; import assert from 'node:assert/strict'; import { mkdtempSync, rmSync, existsSync } from 'node:fs'; import { join } from 'node:path'; import { tmpdir } from 'node:os'; // M0-5: queue-manager must resolve its queue under the EXTERNAL data root // (getDataRoot('drafts')), never the plugin tree. The module binds QUEUE_FILE at // load time, so LINKEDIN_STUDIO_DATA is stubbed BEFORE the dynamic import. A // separate PLUGIN_ROOT tempdir lets us assert the queue does NOT land in the // plugin tree without polluting the real working tree (the old default would // have written there). // Pattern: data-root.test.mjs env-stub + personalization-score.test.mjs tempdir. describe('queue-manager — external data root (M0-5)', () => { let dataDir, pluginDir, qm; const saved = { LINKEDIN_STUDIO_DATA: process.env.LINKEDIN_STUDIO_DATA, PLUGIN_ROOT: process.env.PLUGIN_ROOT, }; before(async () => { dataDir = mkdtempSync(join(tmpdir(), 'lis-queue-data-')); pluginDir = mkdtempSync(join(tmpdir(), 'lis-queue-plugin-')); process.env.LINKEDIN_STUDIO_DATA = dataDir; process.env.PLUGIN_ROOT = pluginDir; qm = await import('../queue-manager.mjs'); }); after(() => { for (const d of [dataDir, pluginDir]) { if (d && existsSync(d)) rmSync(d, { recursive: true, force: true }); } for (const [k, v] of Object.entries(saved)) { if (v === undefined) delete process.env[k]; else process.env[k] = v; } }); test('an empty queue materializes under /drafts/queue.json', () => { assert.deepEqual(qm.queueRead(), []); assert.ok( existsSync(join(dataDir, 'drafts', 'queue.json')), 'queue file must be created under the external drafts dir', ); }); test('queueAdd persists to the external root, never the plugin tree', () => { qm.queueAdd('m0-5', '/tmp/draft.md', '2026-06-20', '09:00', 'ai', 'text', 'hook', 1234); const entries = qm.queueRead(); assert.equal(entries.length, 1); assert.equal(entries[0].id, 'm0-5'); assert.ok( !existsSync(join(pluginDir, 'assets', 'drafts', 'queue.json')), 'queue must NOT land in the plugin tree (PLUGIN_ROOT default removed)', ); }); });