2025-05-26 08:53:25 +00:00
|
|
|
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
2022-07-16 18:15:23 +02:00
|
|
|
import * as detector from '../ts/index.js';
|
2021-04-12 19:00:08 +00:00
|
|
|
|
2021-04-13 08:30:33 +00:00
|
|
|
let testDetector: detector.Detector;
|
|
|
|
|
|
2025-05-26 09:48:42 +00:00
|
|
|
tap.test('should create a detector instance', async () => {
|
2021-04-13 08:30:33 +00:00
|
|
|
testDetector = new detector.Detector();
|
2022-07-16 18:15:23 +02:00
|
|
|
expect(testDetector).toBeInstanceOf(detector.Detector);
|
2021-04-13 08:30:33 +00:00
|
|
|
});
|
|
|
|
|
|
2025-05-26 09:48:42 +00:00
|
|
|
// Basic port detection tests
|
|
|
|
|
tap.test('should detect a closed port on localhost', async () => {
|
2021-04-14 11:47:51 +00:00
|
|
|
const result = await testDetector.isActive('http://localhost:3008');
|
2025-05-26 09:40:16 +00:00
|
|
|
expect(result.isActive).toBeFalse();
|
2025-05-26 09:48:42 +00:00
|
|
|
expect(result.serviceType).toBeUndefined();
|
2021-04-14 11:47:51 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('should detect an open port on a remote domain', async () => {
|
2021-04-13 08:30:33 +00:00
|
|
|
const result = await testDetector.isActive('https://lossless.com');
|
2025-05-26 09:40:16 +00:00
|
|
|
expect(result.isActive).toBeTrue();
|
2021-04-12 19:00:08 +00:00
|
|
|
});
|
|
|
|
|
|
2025-05-26 09:48:42 +00:00
|
|
|
// Backward compatibility tests
|
|
|
|
|
tap.test('should support backward compatibility with isActiveSimple', async () => {
|
|
|
|
|
const result = await testDetector.isActiveSimple('https://example.com');
|
|
|
|
|
expect(result).toBeTypeofBoolean();
|
|
|
|
|
expect(result).toBeTrue();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('should return false for closed port with isActiveSimple', async () => {
|
|
|
|
|
const result = await testDetector.isActiveSimple('http://localhost:3008');
|
|
|
|
|
expect(result).toBeFalse();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Service detection tests
|
|
|
|
|
tap.test('should detect HTTP service on port 80', async () => {
|
2025-05-26 09:40:16 +00:00
|
|
|
const result = await testDetector.isActive('http://example.com', { detectServiceType: true });
|
|
|
|
|
expect(result.isActive).toBeTrue();
|
|
|
|
|
expect(result.serviceType).toEqual(detector.ServiceType.HTTP);
|
|
|
|
|
});
|
|
|
|
|
|
2025-05-26 09:48:42 +00:00
|
|
|
tap.test('should detect HTTPS service on port 443', async () => {
|
2025-05-26 09:40:16 +00:00
|
|
|
const result = await testDetector.isActive('https://example.com', { detectServiceType: true });
|
|
|
|
|
expect(result.isActive).toBeTrue();
|
|
|
|
|
expect(result.serviceType).toEqual(detector.ServiceType.HTTPS);
|
|
|
|
|
});
|
|
|
|
|
|
2025-05-26 09:48:42 +00:00
|
|
|
tap.test('should detect SSH service on GitHub', async () => {
|
2025-05-26 09:40:16 +00:00
|
|
|
const sshType = await testDetector.detectType('ssh://github.com:22');
|
|
|
|
|
expect(sshType).toEqual(detector.ServiceType.SSH);
|
|
|
|
|
});
|
|
|
|
|
|
2025-05-26 09:48:42 +00:00
|
|
|
tap.test('should detect HTTPS on non-standard port', async () => {
|
2025-05-26 12:57:15 +00:00
|
|
|
const result = await testDetector.isActive('https://lossless.com:443', {
|
|
|
|
|
detectServiceType: true,
|
|
|
|
|
});
|
2025-05-26 09:48:42 +00:00
|
|
|
if (result.isActive) {
|
|
|
|
|
expect(result.serviceType).toEqual(detector.ServiceType.HTTPS);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Direct detectType tests
|
|
|
|
|
tap.test('should detect common services by port number', async () => {
|
|
|
|
|
// Test FTP port
|
|
|
|
|
const ftpType = await testDetector.detectType('ftp://localhost:21');
|
|
|
|
|
// Since localhost:21 is likely not running, it will try detection
|
|
|
|
|
expect(ftpType).toBeTypeofString();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('should return UNKNOWN for non-standard ports', async () => {
|
2025-05-26 09:40:16 +00:00
|
|
|
const result = await testDetector.isActive('http://localhost:9999', { detectServiceType: true });
|
|
|
|
|
if (result.isActive) {
|
|
|
|
|
expect(result.serviceType).toEqual(detector.ServiceType.UNKNOWN);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2025-05-26 09:48:42 +00:00
|
|
|
// Edge cases
|
|
|
|
|
tap.test('should handle invalid URLs gracefully', async () => {
|
|
|
|
|
try {
|
|
|
|
|
await testDetector.isActive('not-a-valid-url');
|
|
|
|
|
} catch (error) {
|
|
|
|
|
expect(error).toBeInstanceOf(Error);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('should handle localhost with detectServiceType', async () => {
|
|
|
|
|
const result = await testDetector.isActive('http://localhost:8080', { detectServiceType: true });
|
|
|
|
|
expect(result).toHaveProperty('isActive');
|
|
|
|
|
expect(result).toHaveProperty('serviceType');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Multiple service checks
|
|
|
|
|
tap.test('should correctly identify multiple HTTPS services', async () => {
|
|
|
|
|
const services = [
|
|
|
|
|
{ url: 'https://google.com', expected: detector.ServiceType.HTTPS },
|
|
|
|
|
{ url: 'https://github.com', expected: detector.ServiceType.HTTPS },
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
for (const service of services) {
|
|
|
|
|
const result = await testDetector.isActive(service.url, { detectServiceType: true });
|
|
|
|
|
if (result.isActive) {
|
|
|
|
|
expect(result.serviceType).toEqual(service.expected);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Performance test
|
|
|
|
|
tap.test('should complete detection within reasonable time', async () => {
|
|
|
|
|
const startTime = Date.now();
|
|
|
|
|
await testDetector.isActive('https://example.com', { detectServiceType: true });
|
|
|
|
|
const duration = Date.now() - startTime;
|
|
|
|
|
// Should complete within 10 seconds
|
|
|
|
|
expect(duration).toBeLessThan(10000);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Test without service detection
|
|
|
|
|
tap.test('should work without service detection option', async () => {
|
|
|
|
|
const result = await testDetector.isActive('https://example.com');
|
|
|
|
|
expect(result.isActive).toBeTrue();
|
|
|
|
|
expect(result.serviceType).toBeUndefined();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Test specific ports
|
|
|
|
|
tap.test('should handle MySQL default port', async () => {
|
|
|
|
|
const mysqlType = await testDetector.detectType('mysql://localhost:3306');
|
|
|
|
|
// Will return MYSQL based on port, but actual detection depends on service running
|
|
|
|
|
expect([detector.ServiceType.MYSQL, detector.ServiceType.UNKNOWN]).toContain(mysqlType);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('should handle Redis default port', async () => {
|
|
|
|
|
const redisType = await testDetector.detectType('redis://localhost:6379');
|
|
|
|
|
expect([detector.ServiceType.REDIS, detector.ServiceType.UNKNOWN]).toContain(redisType);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Local port tests
|
|
|
|
|
tap.test('should detect commonly used local development ports', async () => {
|
|
|
|
|
const localPorts = [
|
|
|
|
|
{ url: 'http://localhost:3000', name: 'Node.js dev server' },
|
|
|
|
|
{ url: 'http://localhost:4200', name: 'Angular dev server' },
|
|
|
|
|
{ url: 'http://localhost:8080', name: 'Common web server' },
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
for (const port of localPorts) {
|
|
|
|
|
const result = await testDetector.isActive(port.url);
|
|
|
|
|
// Just check that it returns a valid result structure
|
|
|
|
|
expect(result).toHaveProperty('isActive');
|
|
|
|
|
expect(result.isActive).toBeTypeofBoolean();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2025-05-26 12:57:15 +00:00
|
|
|
export default tap.start();
|