import { tap, expect } from '@git.zone/tstest/tapbundle'; import { startTestSmtpServer } from '../../helpers/server.loader.js'; import * as dns from 'dns'; import { promisify } from 'util'; const resolveMx = promisify(dns.resolveMx); const resolve4 = promisify(dns.resolve4); const resolve6 = promisify(dns.resolve6); let testServer: any; tap.test('setup test SMTP server', async () => { testServer = await startTestSmtpServer(); expect(testServer).toBeTruthy(); expect(testServer.port).toBeGreaterThan(0); }); tap.test('CCM-08: DNS resolution and MX record lookup', async () => { // Test basic DNS resolution try { const ipv4Addresses = await resolve4('example.com'); expect(ipv4Addresses).toBeArray(); expect(ipv4Addresses.length).toBeGreaterThan(0); console.log('IPv4 addresses for example.com:', ipv4Addresses); } catch (error) { console.log('IPv4 resolution failed (may be expected in test environment):', error.message); } // Test IPv6 resolution try { const ipv6Addresses = await resolve6('example.com'); expect(ipv6Addresses).toBeArray(); console.log('IPv6 addresses for example.com:', ipv6Addresses); } catch (error) { console.log('IPv6 resolution failed (common for many domains):', error.message); } // Test MX record lookup try { const mxRecords = await resolveMx('example.com'); expect(mxRecords).toBeArray(); if (mxRecords.length > 0) { expect(mxRecords[0]).toHaveProperty('priority'); expect(mxRecords[0]).toHaveProperty('exchange'); console.log('MX records for example.com:', mxRecords); } } catch (error) { console.log('MX record lookup failed (may be expected in test environment):', error.message); } // Test local resolution (should work in test environment) try { const localhostIpv4 = await resolve4('localhost'); expect(localhostIpv4).toContain('127.0.0.1'); } catch (error) { // Fallback for environments where localhost doesn't resolve via DNS console.log('Localhost DNS resolution not available, using direct IP'); } // Test invalid domain handling try { await resolve4('this-domain-definitely-does-not-exist-12345.com'); expect(true).toBeFalsy(); // Should not reach here } catch (error) { expect(error.code).toMatch(/ENOTFOUND|ENODATA/); } // Test MX record priority sorting const mockMxRecords = [ { priority: 20, exchange: 'mx2.example.com' }, { priority: 10, exchange: 'mx1.example.com' }, { priority: 30, exchange: 'mx3.example.com' } ]; const sortedRecords = mockMxRecords.sort((a, b) => a.priority - b.priority); expect(sortedRecords[0].exchange).toEqual('mx1.example.com'); expect(sortedRecords[1].exchange).toEqual('mx2.example.com'); expect(sortedRecords[2].exchange).toEqual('mx3.example.com'); }); tap.test('CCM-08: DNS caching behavior', async () => { const startTime = Date.now(); // First resolution (cold cache) try { await resolve4('example.com'); } catch (error) { // Ignore errors, we're testing timing } const firstResolutionTime = Date.now() - startTime; // Second resolution (potentially cached) const secondStartTime = Date.now(); try { await resolve4('example.com'); } catch (error) { // Ignore errors, we're testing timing } const secondResolutionTime = Date.now() - secondStartTime; console.log(`First resolution: ${firstResolutionTime}ms, Second resolution: ${secondResolutionTime}ms`); // Note: We can't guarantee caching behavior in all environments // so we just log the times for manual inspection }); tap.test('CCM-08: Multiple A record handling', async () => { // Test handling of domains with multiple A records try { const googleIps = await resolve4('google.com'); if (googleIps.length > 1) { expect(googleIps).toBeArray(); expect(googleIps.length).toBeGreaterThan(1); console.log('Multiple A records found for google.com:', googleIps); // Verify all are valid IPv4 addresses const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/; for (const ip of googleIps) { expect(ip).toMatch(ipv4Regex); } } } catch (error) { console.log('Could not resolve google.com:', error.message); } }); tap.test('cleanup test SMTP server', async () => { if (testServer) { await testServer.stop(); } }); export default tap.start();