This commit is contained in:
2026-06-25 12:05:53 -05:00
commit b58e50e423
141 changed files with 28190 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
import './setup.mjs';
import test from 'node:test';
import assert from 'node:assert/strict';
import { load } from './setup.mjs';
const { analyzeInstaller, listInstallerTechnologies } = await load('../services/installerIntelService.js');
const { buildDetectionRule } = await load('../services/detectionRuleService.js');
// --- installer detection + silent switches --------------------------------
test('MSI is detected with high confidence and product-code uninstall', () => {
const result = analyzeInstaller({ fileName: 'ContosoVpn.msi', productCode: '{12345678-1234-1234-1234-123456789012}' });
assert.equal(result.confidence, 'high');
assert.equal(result.primary.id, 'msi');
assert.ok(result.primary.install.includes('/qn'));
assert.ok(result.primary.uninstall.includes('{12345678-1234-1234-1234-123456789012}'));
});
test('MSIX is detected from its extension', () => {
const result = analyzeInstaller({ fileName: 'App_1.0.0.0_x64.msixbundle' });
assert.equal(result.primary.id, 'msix');
assert.ok(result.primary.install.includes('Add-AppxProvisionedPackage'));
});
test('EXE with a name hint matches the technology at medium confidence', () => {
const result = analyzeInstaller({ fileName: 'app-nsis-setup.exe' });
assert.equal(result.confidence, 'medium');
assert.equal(result.primary.id, 'nsis');
assert.equal(result.primary.install, '"app-nsis-setup.exe" /S');
});
test('ambiguous EXE falls back to generic and offers candidates', () => {
const result = analyzeInstaller({ fileName: 'installer.exe' });
assert.equal(result.confidence, 'low');
assert.equal(result.primary.id, 'exe');
const ids = result.candidates.map((c) => c.id);
assert.ok(ids.includes('inno') && ids.includes('installshield'));
assert.equal(ids[ids.length - 1], 'exe', 'generic EXE is offered last');
});
test('unknown extension reports unknown', () => {
const result = analyzeInstaller({ fileName: 'notes.txt' });
assert.equal(result.confidence, 'unknown');
assert.equal(result.primary, null);
});
test('listInstallerTechnologies exposes the catalog', () => {
const list = listInstallerTechnologies();
assert.ok(list.find((t) => t.id === 'inno'));
assert.ok(list.every((t) => Array.isArray(t.extensions)));
});
// --- detection rule generation --------------------------------------------
test('MSI detection maps to a product-code rule', () => {
const rule = buildDetectionRule({ type: 'msi', productCode: '{abc}' });
assert.equal(rule.detectionType, 'msi-product-code');
assert.equal(rule.detectionRule, '{abc}');
});
test('file detection generates a versioned PowerShell script', () => {
const rule = buildDetectionRule({ type: 'file', path: 'C:\\Program Files\\App\\app.exe', version: '2.0.0' });
assert.equal(rule.detectionType, 'custom-script');
assert.ok(rule.detectionRule.includes('Test-Path'));
assert.ok(rule.detectionRule.includes("[version]'2.0.0'"));
assert.ok(rule.detectionRule.includes("Write-Output 'Detected'"));
});
test('registry detection with a value comparison', () => {
const rule = buildDetectionRule({ type: 'registry', keyPath: 'HKLM:\\SOFTWARE\\Contoso', valueName: 'Version', valueData: '2.0' });
assert.equal(rule.detectionType, 'custom-script');
assert.ok(rule.detectionRule.includes('HKLM:\\SOFTWARE\\Contoso'));
assert.ok(rule.detectionRule.includes("-eq '2.0'"));
});
test('detection generator validates required inputs', () => {
assert.throws(() => buildDetectionRule({ type: 'msi' }));
assert.throws(() => buildDetectionRule({ type: 'file' }));
assert.throws(() => buildDetectionRule({ type: 'bogus' }));
});