feat(llm-security): wire JetBrains branch into scanOneExtension
This commit is contained in:
parent
ca43fb8dd1
commit
aa269ed6d8
2 changed files with 109 additions and 16 deletions
|
|
@ -423,3 +423,70 @@ describe('blocklist matching', () => {
|
|||
assert.equal(crit.length, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('scanOneExtension JetBrains dispatch', () => {
|
||||
// Fixture-free verification: synthesize an ExtensionRecord with type:'jetbrains'
|
||||
// and a minimal plugin dir (lib/<jar> with META-INF/plugin.xml) at runtime via
|
||||
// tests/helpers/zip-writer.mjs. Does not depend on Step 13/14 fixtures.
|
||||
it('dispatches JetBrains records to parseIntelliJPlugin + runJetBrainsChecks', async () => {
|
||||
const { mkdtemp, mkdir, writeFile, rm } = await import('node:fs/promises');
|
||||
const { join } = await import('node:path');
|
||||
const { tmpdir } = await import('node:os');
|
||||
const { createZip } = await import('../helpers/zip-writer.mjs');
|
||||
|
||||
const pluginRoot = await mkdtemp(join(tmpdir(), 'llmsec-jb-disp-'));
|
||||
try {
|
||||
const libDir = join(pluginRoot, 'lib');
|
||||
await mkdir(libDir, { recursive: true });
|
||||
const pluginXml = `<idea-plugin>
|
||||
<id>com.example.dispatch</id>
|
||||
<name>Dispatch Test</name>
|
||||
<version>1.0.0</version>
|
||||
<vendor>Example</vendor>
|
||||
<idea-version since-build="241.0"/>
|
||||
</idea-plugin>`;
|
||||
const jarBuf = createZip([
|
||||
{ name: 'META-INF/plugin.xml', data: pluginXml },
|
||||
]);
|
||||
await writeFile(join(libDir, 'main.jar'), jarBuf);
|
||||
|
||||
const ext = {
|
||||
id: 'com.example.dispatch',
|
||||
version: '1.0.0',
|
||||
type: 'jetbrains',
|
||||
location: pluginRoot,
|
||||
publisher: 'Example',
|
||||
source: 'installed',
|
||||
isBuiltin: false,
|
||||
signed: false,
|
||||
};
|
||||
|
||||
const result = await scannerInternals.scanOneExtension(ext, { targetBase: pluginRoot });
|
||||
assert.equal(result.id, 'com.example.dispatch');
|
||||
assert.equal(result.type, 'jetbrains');
|
||||
// IDE result must exist — dispatch produced findings (possibly empty array, but scanner ran)
|
||||
assert.ok(result.scanner_results.IDE, 'IDE scanner did not run');
|
||||
assert.equal(result.scanner_results.IDE.status, 'ok');
|
||||
// Manifest was parsed via parseIntelliJPlugin (not parseVSCodeExtension) —
|
||||
// the scanner wouldn't have a successful IDE result if it had tried to read
|
||||
// package.json from a dir that only has lib/main.jar.
|
||||
assert.ok(!result.warnings.some(w => String(w).includes('failed to parse manifest')),
|
||||
`parse failed: ${result.warnings.join('; ')}`);
|
||||
} finally {
|
||||
await rm(pluginRoot, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it('VS Code records still route through parseVSCodeExtension (regression guard)', async () => {
|
||||
const env = await scan('all', { rootsOverride: [ROOT_BENIGN], vscodeOnly: true });
|
||||
// Two VS Code extensions parsed successfully from the existing benign fixture.
|
||||
assert.equal(env.meta.extensions_discovered.vscode, 2);
|
||||
// None of them should be tagged as jetbrains.
|
||||
assert.ok(env.extensions.every(e => e.type !== 'jetbrains'));
|
||||
// Each has a functioning IDE scanner result (VS Code path intact).
|
||||
for (const ext of env.extensions) {
|
||||
assert.ok(ext.scanner_results.IDE, `missing IDE result for ${ext.id}`);
|
||||
assert.equal(ext.scanner_results.IDE.status, 'ok');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue