fixed build libs

This commit is contained in:
Boki 2025-06-25 08:29:53 -04:00
parent b03231b849
commit 42baadae38
26 changed files with 981 additions and 541 deletions

View file

@ -1,254 +0,0 @@
import { beforeEach, describe, expect, it, mock } from 'bun:test';
import { SimpleProxyManager } from './simple-proxy-manager';
import type { ProxyConfig, ProxyInfo } from './types';
describe('ProxyManager', () => {
let manager: SimpleProxyManager;
const getMockProxies = (): ProxyInfo[] => [
{
id: 'proxy1',
host: '1.2.3.4',
port: 8080,
protocol: 'http',
username: 'user1',
password: 'pass1',
active: true,
},
{
id: 'proxy2',
host: '5.6.7.8',
port: 8080,
protocol: 'http',
username: 'user2',
password: 'pass2',
active: true,
},
{
id: 'proxy3',
host: '9.10.11.12',
port: 8080,
protocol: 'socks5',
active: false,
},
];
beforeEach(() => {
manager = new SimpleProxyManager();
});
describe('proxy management', () => {
it('should add proxies', () => {
const mockProxies = getMockProxies();
manager.addProxy(mockProxies[0]);
manager.addProxy(mockProxies[1]);
const proxies = manager.getProxies();
expect(proxies).toHaveLength(2);
expect(proxies[0].id).toBe('proxy1');
expect(proxies[1].id).toBe('proxy2');
});
it('should remove proxy by id', () => {
const mockProxies = getMockProxies();
manager.addProxy(mockProxies[0]);
manager.addProxy(mockProxies[1]);
manager.removeProxy('proxy1');
const proxies = manager.getProxies();
expect(proxies).toHaveLength(1);
expect(proxies[0].id).toBe('proxy2');
});
it('should update proxy status', () => {
const mockProxies = getMockProxies();
manager.addProxy(mockProxies[0]);
manager.updateProxyStatus('proxy1', false);
const proxies = manager.getProxies();
expect(proxies[0].active).toBe(false);
});
it('should get only active proxies', () => {
const mockProxies = getMockProxies();
mockProxies.forEach(proxy => manager.addProxy(proxy));
const activeProxies = manager.getActiveProxies();
expect(activeProxies).toHaveLength(2);
expect(activeProxies.every(p => p.active)).toBe(true);
});
});
describe('proxy rotation', () => {
it('should rotate through proxies', () => {
const mockProxies = getMockProxies();
manager.addProxy(mockProxies[0]);
manager.addProxy(mockProxies[1]);
const proxy1 = manager.getNextProxy();
const proxy2 = manager.getNextProxy();
const proxy3 = manager.getNextProxy();
expect(proxy1?.id).toBe('proxy1');
expect(proxy2?.id).toBe('proxy2');
expect(proxy3?.id).toBe('proxy1'); // Back to first
});
it('should skip inactive proxies', () => {
const mockProxies = getMockProxies();
mockProxies.forEach(proxy => manager.addProxy(proxy));
const proxy1 = manager.getNextProxy();
const proxy2 = manager.getNextProxy();
const proxy3 = manager.getNextProxy();
expect(proxy1?.id).toBe('proxy1');
expect(proxy2?.id).toBe('proxy2');
expect(proxy3?.id).toBe('proxy1'); // Skips proxy3 (inactive)
});
it('should return null when no active proxies', () => {
const mockProxies = getMockProxies();
manager.addProxy({ ...mockProxies[0], active: false });
const proxy = manager.getNextProxy();
expect(proxy).toBeNull();
});
});
describe('proxy configuration', () => {
it('should get proxy config for HTTP proxy', () => {
const mockProxies = getMockProxies();
manager.addProxy(mockProxies[0]);
const proxy = manager.getNextProxy();
const config = manager.getProxyConfig(proxy!);
expect(config).toEqual({
protocol: 'http',
host: '1.2.3.4',
port: 8080,
auth: {
username: 'user1',
password: 'pass1',
},
});
});
it('should get proxy config without auth', () => {
const mockProxies = getMockProxies();
manager.addProxy(mockProxies[2]);
manager.updateProxyStatus('proxy3', true); // Make it active
const proxy = manager.getNextProxy();
const config = manager.getProxyConfig(proxy!);
expect(config).toEqual({
protocol: 'socks5',
host: '9.10.11.12',
port: 8080,
});
});
it('should format proxy URL', () => {
const mockProxies = getMockProxies();
const url1 = manager.formatProxyUrl(mockProxies[0]);
expect(url1).toBe('http://user1:pass1@1.2.3.4:8080');
const url2 = manager.formatProxyUrl(mockProxies[2]);
expect(url2).toBe('socks5://9.10.11.12:8080');
});
});
describe('proxy validation', () => {
it('should validate proxy connectivity', async () => {
const mockProxies = getMockProxies();
// Mock fetch for validation
const mockFetch = mock(() => Promise.resolve({ ok: true }));
global.fetch = mockFetch as any;
manager.addProxy(mockProxies[0]);
const isValid = await manager.validateProxy('proxy1');
expect(mockFetch).toHaveBeenCalled();
expect(isValid).toBe(true);
});
it('should handle validation failure', async () => {
const mockProxies = getMockProxies();
const mockFetch = mock(() => Promise.reject(new Error('Connection failed')));
global.fetch = mockFetch as any;
manager.addProxy(mockProxies[0]);
const isValid = await manager.validateProxy('proxy1');
expect(isValid).toBe(false);
});
it('should validate all proxies', async () => {
const mockProxies = getMockProxies();
// Mock fetch to return different results for each proxy
let callCount = 0;
const mockFetch = mock(() => {
callCount++;
// First call succeeds, second fails
if (callCount === 1) {
return Promise.resolve({ ok: true });
} else {
return Promise.reject(new Error('Failed'));
}
});
global.fetch = mockFetch as any;
manager.addProxy(mockProxies[0]);
manager.addProxy(mockProxies[1]);
const results = await manager.validateAllProxies();
expect(results['proxy1']).toBe(true);
expect(results['proxy2']).toBe(false);
// Should disable failed proxy
const activeProxies = manager.getActiveProxies();
expect(activeProxies).toHaveLength(1);
expect(activeProxies[0].id).toBe('proxy1');
});
});
describe('statistics', () => {
it('should track proxy statistics', () => {
const mockProxies = getMockProxies();
mockProxies.forEach(proxy => manager.addProxy(proxy));
const stats = manager.getStatistics();
expect(stats).toEqual({
total: 3,
active: 2,
inactive: 1,
byProtocol: {
http: 2,
socks5: 1,
},
});
});
it('should clear all proxies', () => {
const mockProxies = getMockProxies();
manager.addProxy(mockProxies[0]);
manager.addProxy(mockProxies[1]);
manager.clear();
const proxies = manager.getProxies();
expect(proxies).toHaveLength(0);
});
});
});

View file

@ -1,14 +1,24 @@
import type { ProxyInfo, ProxyConfig } from './types';
import type { ProxyInfo } from './types';
export interface ProxyConfig {
protocol: string;
host: string;
port: number;
auth?: {
username: string;
password: string;
};
}
/**
* Simple proxy manager for testing
*/
export class SimpleProxyManager {
private proxies: ProxyInfo[] = [];
private proxies: Array<ProxyInfo & { id: string; active: boolean }> = [];
private currentIndex = 0;
private activeProxyIndex = 0;
addProxy(proxy: ProxyInfo): void {
addProxy(proxy: ProxyInfo & { id: string; active: boolean }): void {
this.proxies.push(proxy);
}
@ -23,15 +33,15 @@ export class SimpleProxyManager {
}
}
getProxies(): ProxyInfo[] {
getProxies(): Array<ProxyInfo & { id: string; active: boolean }> {
return [...this.proxies];
}
getActiveProxies(): ProxyInfo[] {
getActiveProxies(): Array<ProxyInfo & { id: string; active: boolean }> {
return this.proxies.filter(p => p.active);
}
getNextProxy(): ProxyInfo | null {
getNextProxy(): (ProxyInfo & { id: string; active: boolean }) | null {
const activeProxies = this.getActiveProxies();
if (activeProxies.length === 0) {
return null;
@ -39,10 +49,10 @@ export class SimpleProxyManager {
const proxy = activeProxies[this.activeProxyIndex % activeProxies.length];
this.activeProxyIndex++;
return proxy;
return proxy || null;
}
getProxyConfig(proxy: ProxyInfo): ProxyConfig {
getProxyConfig(proxy: ProxyInfo & { id: string; active: boolean }): ProxyConfig {
const config: ProxyConfig = {
protocol: proxy.protocol,
host: proxy.host,