import { expect, tap } from '@git.zone/tstest/tapbundle'; import * as smartdns from '../ts_client/index.js'; let testDnsClient: smartdns.Smartdns; tap.test('should create an instance of Smartdns', async () => { testDnsClient = new smartdns.Smartdns({}); expect(testDnsClient).toBeInstanceOf(smartdns.Smartdns); }); tap.test('should get an A DNS Record (system)', async () => { const records = await testDnsClient.getRecordsA('google.com'); expect(records).toBeInstanceOf(Array); expect(records.length).toBeGreaterThan(0); expect(records[0]).toHaveProperty('name', 'google.com'); expect(records[0]).toHaveProperty('type', 'A'); expect(records[0]).toHaveProperty('value'); expect(records[0]).toHaveProperty('dnsSecEnabled'); }); tap.test('should get an AAAA Record (system)', async () => { const records = await testDnsClient.getRecordsAAAA('google.com'); expect(records).toBeInstanceOf(Array); expect(records.length).toBeGreaterThan(0); expect(records[0]).toHaveProperty('name', 'google.com'); expect(records[0]).toHaveProperty('type', 'AAAA'); expect(records[0]).toHaveProperty('value'); expect(records[0]).toHaveProperty('dnsSecEnabled'); }); tap.test('should get a txt record (system)', async () => { const records = await testDnsClient.getRecordsTxt('google.com'); expect(records).toBeInstanceOf(Array); expect(records.length).toBeGreaterThan(0); expect(records[0]).toHaveProperty('name', 'google.com'); expect(records[0]).toHaveProperty('type', 'TXT'); expect(records[0]).toHaveProperty('value'); expect(records[0]).toHaveProperty('dnsSecEnabled'); }); tap.test('should get a mx record for a domain (system)', async () => { const res = await testDnsClient.getRecords('bleu.de', 'MX'); console.log(res); }); tap.test('should check until DNS is available', async () => { const records = await testDnsClient.getRecordsTxt('google.com'); if (records.length > 0) { const result = await testDnsClient.checkUntilAvailable('google.com', 'TXT', records[0].value); expect(result).toBeTrue(); } }); tap.test('should check until DNS is available and return false if it fails', async () => { return expect( await testDnsClient.checkUntilAvailable('google.com', 'TXT', 'this-txt-record-does-not-exist') ).toBeFalse(); }); tap.test('should check until DNS is available and return false if it fails', async () => { return expect( await testDnsClient.checkUntilAvailable('nonexistent.example.com', 'TXT', 'sometext_txt2') ).toBeFalse(); }); tap.test('should get name server for hostname', async () => { let result = await testDnsClient.getNameServers('bleu.de'); console.log(result); }); tap.test('should detect DNSSEC via DoH (Rust)', async () => { const dohClient = new smartdns.Smartdns({ strategy: 'doh' }); const result = await dohClient.getRecordsA('lossless.com'); console.log(result[0]); expect(result[0].dnsSecEnabled).toBeTrue(); dohClient.destroy(); }); // ── New tests for UDP and Rust-based resolution ────────────────── tap.test('should resolve A record via UDP (Rust)', async () => { const udpClient = new smartdns.Smartdns({ strategy: 'udp' }); const records = await udpClient.getRecordsA('google.com'); expect(records).toBeInstanceOf(Array); expect(records.length).toBeGreaterThan(0); expect(records[0]).toHaveProperty('name', 'google.com'); expect(records[0]).toHaveProperty('type', 'A'); expect(records[0]).toHaveProperty('value'); console.log('UDP A record:', records[0]); udpClient.destroy(); }); tap.test('should resolve AAAA record via UDP (Rust)', async () => { const udpClient = new smartdns.Smartdns({ strategy: 'udp' }); const records = await udpClient.getRecordsAAAA('google.com'); expect(records).toBeInstanceOf(Array); expect(records.length).toBeGreaterThan(0); expect(records[0]).toHaveProperty('type', 'AAAA'); console.log('UDP AAAA record:', records[0]); udpClient.destroy(); }); tap.test('should resolve TXT record via DoH (Rust)', async () => { const dohClient = new smartdns.Smartdns({ strategy: 'doh' }); const records = await dohClient.getRecordsTxt('google.com'); expect(records).toBeInstanceOf(Array); expect(records.length).toBeGreaterThan(0); expect(records[0]).toHaveProperty('type', 'TXT'); expect(records[0]).toHaveProperty('value'); console.log('DoH TXT record:', records[0]); dohClient.destroy(); }); tap.test('should resolve with prefer-udp strategy', async () => { const client = new smartdns.Smartdns({ strategy: 'prefer-udp' }); const records = await client.getRecordsA('google.com'); expect(records).toBeInstanceOf(Array); expect(records.length).toBeGreaterThan(0); expect(records[0]).toHaveProperty('type', 'A'); console.log('prefer-udp A record:', records[0]); client.destroy(); }); tap.test('should detect DNSSEC AD flag via UDP (Rust)', async () => { const udpClient = new smartdns.Smartdns({ strategy: 'udp' }); const records = await udpClient.getRecordsA('lossless.com'); expect(records.length).toBeGreaterThan(0); // Note: AD flag from upstream depends on upstream resolver behavior // Cloudflare 1.1.1.1 sets AD for DNSSEC-signed domains console.log('UDP DNSSEC:', records[0]); udpClient.destroy(); }); tap.test('should cleanup via destroy()', async () => { const client = new smartdns.Smartdns({ strategy: 'udp' }); // Trigger bridge spawn await client.getRecordsA('google.com'); // Destroy should not throw client.destroy(); }); tap.test('cleanup default client', async () => { testDnsClient.destroy(); }); export default tap.start();