import { tap, expect } from '@git.zone/tstest/tapbundle'; import { IPReputationChecker, ReputationThreshold } from '../ts/security/classes.ipreputationchecker.js'; import { RustSecurityBridge } from '../ts/security/classes.rustsecuritybridge.js'; let bridge: RustSecurityBridge; // Start the Rust bridge before tests tap.test('setup - start Rust security bridge', async () => { bridge = RustSecurityBridge.getInstance(); const ok = await bridge.start(); expect(ok).toEqual(true); }); // Test instantiation tap.test('IPReputationChecker - should be instantiable', async () => { const checker = IPReputationChecker.getInstance({ enableLocalCache: false }); expect(checker).toBeTruthy(); }); // Test singleton pattern tap.test('IPReputationChecker - should use singleton pattern', async () => { const checker1 = IPReputationChecker.getInstance(); const checker2 = IPReputationChecker.getInstance(); expect(checker1 === checker2).toEqual(true); }); // Test IP validation tap.test('IPReputationChecker - should validate IP address format', async () => { const checker = IPReputationChecker.getInstance(); // Invalid IP should fail with error const invalidResult = await checker.checkReputation('invalid.ip'); expect(invalidResult.error).toBeTruthy(); }); // Test reputation check via Rust bridge tap.test('IPReputationChecker - should check IP reputation via Rust', async () => { const testInstance = new IPReputationChecker({ enableLocalCache: false, maxCacheSize: 10 }); // Check a public IP (Google DNS) — should get a result with a score const result = await testInstance.checkReputation('8.8.8.8'); expect(result).toBeTruthy(); expect(result.score).toBeGreaterThan(0); expect(result.score).toBeLessThanOrEqual(100); expect(typeof result.isSpam).toEqual('boolean'); expect(typeof result.isProxy).toEqual('boolean'); expect(typeof result.isTor).toEqual('boolean'); expect(typeof result.isVPN).toEqual('boolean'); expect(result.timestamp).toBeGreaterThan(0); }); // Test caching behavior tap.test('IPReputationChecker - should cache reputation results', async () => { const testInstance = new IPReputationChecker({ enableLocalCache: false, maxCacheSize: 10 }); const ip = '1.1.1.1'; // First check should add to cache const result1 = await testInstance.checkReputation(ip); expect(result1).toBeTruthy(); // Verify it's in cache const hasInCache = (testInstance as any).reputationCache.has(ip); expect(hasInCache).toEqual(true); // Call again, should use cache const result2 = await testInstance.checkReputation(ip); expect(result2).toBeTruthy(); // Results should be identical (from cache) expect(result1.score).toEqual(result2.score); expect(result1.isSpam).toEqual(result2.isSpam); }); // Test risk level classification tap.test('IPReputationChecker - should classify risk levels correctly', async () => { expect(IPReputationChecker.getRiskLevel(10)).toEqual('high'); expect(IPReputationChecker.getRiskLevel(30)).toEqual('medium'); expect(IPReputationChecker.getRiskLevel(60)).toEqual('low'); expect(IPReputationChecker.getRiskLevel(90)).toEqual('trusted'); }); // Test error handling for error result tap.test('IPReputationChecker - should handle errors gracefully', async () => { const testInstance = new IPReputationChecker({ enableLocalCache: false, maxCacheSize: 5 }); // Invalid format should return error result with neutral score const result = await testInstance.checkReputation('not-an-ip'); expect(result.score).toEqual(50); expect(result.error).toBeTruthy(); expect(result.isSpam).toEqual(false); }); // Stop bridge tap.test('cleanup - stop Rust security bridge', async () => { await bridge.stop(); }); tap.test('stop', async () => { await tap.stopForcefully(); }); export default tap.start();