// ide-extension-data.test.mjs — Unit tests for knowledge-file loaders. // // Verifies loadTopJetBrains, loadJetBrainsBlocklist behavior + cache // discipline shared with VS Code loaders. import { describe, it, beforeEach } from 'node:test'; import assert from 'node:assert/strict'; import { loadTopJetBrains, loadJetBrainsBlocklist, loadTopVSCode, loadVSCodeBlocklist, normalizeId, _resetCache, } from '../../scanners/lib/ide-extension-data.mjs'; describe('loadTopJetBrains', () => { beforeEach(() => _resetCache()); it('returns >= 40 canonical xmlIds', async () => { const ids = await loadTopJetBrains(); assert.ok(Array.isArray(ids)); assert.ok( ids.length >= 40, `expected >= 40 entries, got ${ids.length}`, ); }); it('returns lowercased trimmed entries (normalizeId applied)', async () => { const ids = await loadTopJetBrains(); for (const id of ids) { assert.equal(id, id.toLowerCase(), `not lowercased: ${id}`); assert.equal(id, id.trim(), `not trimmed: ${id}`); assert.notEqual(id, '', 'empty entry found'); } }); it('includes bundled JetBrains xmlIds', async () => { const ids = await loadTopJetBrains(); assert.ok( ids.includes('com.intellij.java'), 'missing com.intellij.java', ); assert.ok( ids.includes('org.jetbrains.kotlin'), 'missing org.jetbrains.kotlin', ); }); it('includes the legitimate-typo "lombook plugin" xmlId', async () => { const ids = await loadTopJetBrains(); assert.ok( ids.includes('lombook plugin'), 'missing "lombook plugin" — canonical xmlId for Lombok integration', ); }); }); describe('loadJetBrainsBlocklist', () => { beforeEach(() => _resetCache()); it('returns an empty array (empty by design)', async () => { const bl = await loadJetBrainsBlocklist(); assert.ok(Array.isArray(bl)); assert.equal( bl.length, 0, 'blocklist should be empty by design in v6.6.0', ); }); it('does not throw on repeated invocation', async () => { await assert.doesNotReject(() => loadJetBrainsBlocklist()); await assert.doesNotReject(() => loadJetBrainsBlocklist()); }); }); describe('cache sanity', () => { beforeEach(() => _resetCache()); it('calling loadTopJetBrains then loadJetBrainsBlocklist does not throw', async () => { const ids = await loadTopJetBrains(); const bl = await loadJetBrainsBlocklist(); assert.ok(Array.isArray(ids) && ids.length > 0); assert.ok(Array.isArray(bl)); }); it('second loadTopJetBrains call returns same data (cache hit)', async () => { const a = await loadTopJetBrains(); const b = await loadTopJetBrains(); assert.deepEqual(a, b); }); it('VS Code loaders still work alongside JetBrains loaders', async () => { const jb = await loadTopJetBrains(); const vs = await loadTopVSCode(); assert.ok(jb.length >= 40); assert.ok(Array.isArray(vs)); }); });