This commit is contained in:
2025-04-02 15:19:18 +00:00
commit fcc11dd5f6
30 changed files with 14854 additions and 0 deletions

102
test/config.ts Normal file
View File

@ -0,0 +1,102 @@
import { NamecheapClient } from '../ts/index.js';
import * as qenv from '@push.rocks/qenv';
// Define the auth interface to match what the client expects
interface INamecheapAuth {
apiUser: string;
apiKey: string;
userName: string; // Make userName required to match the client's expectation
clientIp: string;
}
// Test domains - use these in your tests
export const TEST_DOMAINS = {
// Use this domain for availability checks (should be available in sandbox)
CHECK: 'test-domain-availability-check.com',
// Use this domain for domain info tests (should exist in your sandbox account)
INFO: 'bleu.de',
// Use this domain for DNS tests (should exist in your sandbox account)
DNS: 'bleu.de',
// Use this for domain registration tests
REGISTER: 'test-domain-registration.net'
};
// Load environment variables from .nogit directory
const testQenv = new qenv.Qenv('./', '.nogit/');
// Initialize sandbox configuration with default values
let sandboxConfig: INamecheapAuth = {
apiUser: '',
apiKey: '',
userName: '',
clientIp: '127.0.0.1'
};
// Load sandbox configuration asynchronously
async function loadSandboxConfig() {
try {
const username = await testQenv.getEnvVarOnDemand('SANDBOX_USERNAME');
const apiKey = await testQenv.getEnvVarOnDemand('SANDBOX_APIKEY');
const clientIp = await testQenv.getEnvVarOnDemand('CLIENT_IP') || '127.0.0.1';
sandboxConfig = {
apiUser: username,
apiKey: apiKey,
userName: username,
clientIp: clientIp
};
console.log('Sandbox configuration loaded successfully');
} catch (error) {
console.warn('Failed to load sandbox configuration:', error);
}
}
// Try to load sandbox configuration immediately
loadSandboxConfig().catch(console.error);
// Default mock configuration (for tests that don't need real API access)
const mockConfig: INamecheapAuth = {
apiUser: 'testuser',
apiKey: 'testapikey',
userName: 'testuser',
clientIp: '127.0.0.1'
};
/**
* Get API configuration for tests
* @param useMock If true, returns mock config even if real credentials are available
* @returns Namecheap API configuration
*/
export function getApiConfig(useMock: boolean = false): INamecheapAuth {
// If mock config is requested or no real credentials are available, use mock config
if (useMock || !hasRealCredentials()) {
return mockConfig;
}
// Otherwise use sandbox configuration
return sandboxConfig;
}
/**
* Check if we have real API credentials
* @returns True if real credentials are available
*/
export function hasRealCredentials(): boolean {
return !!(sandboxConfig.apiUser &&
sandboxConfig.apiKey &&
sandboxConfig.clientIp);
}
/**
* Create a Namecheap client for testing
* @param useMock If true, uses mock config instead of real credentials
* @returns Configured Namecheap client
*/
export function createTestClient(useMock: boolean = false): NamecheapClient {
const config = getApiConfig(useMock);
return new NamecheapClient(config, true); // Always use sandbox mode for tests
}

View File

@ -0,0 +1,110 @@
/**
* Test file for Namecheap domain availability checks
*/
import { expect, tap } from '@push.rocks/tapbundle';
import { createTestClient, TEST_DOMAINS, hasRealCredentials } from './config.js';
// Skip live API tests if no real credentials
const skipLiveTests = !hasRealCredentials();
// Always run this test to ensure the file doesn't fail when all other tests are skipped
tap.test('Availability - Basic Client Test', async () => {
// Create a client with mock credentials
const client = createTestClient(true);
// Verify the client has the expected methods
expect(client.domains.check).toBeTypeOf('function');
// This test always passes
expect(true).toBeTrue();
});
// Test domain availability checks
if (skipLiveTests) {
tap.skip.test('Domain Availability - Check Single Domain', async () => {
// This test is skipped when no real credentials are available
console.log('Skipping domain availability test - no credentials');
});
} else {
tap.test('Domain Availability - Check Single Domain', async (tools) => {
// Set a timeout for the test
tools.timeout(10000); // 10 seconds timeout
// Create a new client instance
const client = createTestClient();
// Check a single domain
const result = await client.domains.check(TEST_DOMAINS.CHECK);
// Validate the result
expect(result).toBeTypeOf('object');
expect(Array.isArray(result)).toBeTrue();
expect(result.length).toEqual(1);
const domainInfo = result[0];
expect(domainInfo.domain).toEqual(TEST_DOMAINS.CHECK);
expect(domainInfo.available).toBeTypeOf('boolean');
// Log the result with colored output
console.log(await tools.coloredString(
`Domain ${domainInfo.domain} is ${domainInfo.available ? 'available' : 'not available'} for registration`,
domainInfo.available ? 'green' : 'blue'
));
if (domainInfo.isPremium) {
console.log(await tools.coloredString(
`Premium domain details:
- Registration price: ${domainInfo.premiumRegistrationPrice}
- Renewal price: ${domainInfo.premiumRenewalPrice}
- ICANN fee: ${domainInfo.icannFee}
`,
'blue'
));
}
});
}
// Test multiple domains
if (skipLiveTests) {
tap.skip.test('Domain Availability - Check Multiple Domains', async () => {
// This test is skipped when no real credentials are available
console.log('Skipping multiple domains test - no credentials');
});
} else {
tap.test('Domain Availability - Check Multiple Domains', async (tools) => {
// Set a timeout for the test
tools.timeout(10000); // 10 seconds timeout
// Create a new client instance
const client = createTestClient();
// Check multiple domains
const domains = [
TEST_DOMAINS.CHECK,
'example.com',
'test-multiple-domains.org'
];
const results = await client.domains.check(domains);
// Validate the results
expect(Array.isArray(results)).toBeTrue();
expect(results.length).toEqual(domains.length);
// Each result should have the correct structure
results.forEach(async (result) => {
expect(result.domain).toBeTypeOf('string');
expect(result.available).toBeTypeOf('boolean');
expect(result.errorNo).toBeTypeOf('number');
// Log the result with colored output
console.log(await tools.coloredString(
`Domain ${result.domain} is ${result.available ? 'available' : 'not available'} for registration`,
result.available ? 'green' : 'blue'
));
});
});
}
// Start the tests
tap.start();

View File

@ -0,0 +1,249 @@
/**
* Test file for Namecheap domain contact management
*/
import { expect, tap } from '@push.rocks/tapbundle';
import { createTestClient, TEST_DOMAINS, hasRealCredentials } from './config.js';
// Define a simplified contact info interface for the test
interface IContactInfo {
FirstName?: string;
LastName?: string;
Address1?: string;
Address2?: string;
City?: string;
StateProvince?: string;
PostalCode?: string;
Country?: string;
Phone?: string;
EmailAddress?: string;
[key: string]: string | undefined;
}
// Skip live API tests if no real credentials
const skipLiveTests = !hasRealCredentials();
// Always run this test to ensure the file doesn't fail when all other tests are skipped
tap.test('Contacts - Basic Client Test', async () => {
// Create a client with mock credentials
const client = createTestClient(true);
// Verify the client has the expected methods
expect(client.domains.getContacts).toBeTypeOf('function');
expect(client.domains.setContacts).toBeTypeOf('function');
// This test always passes
expect(true).toBeTrue();
});
// Test getting domain contacts
if (skipLiveTests) {
tap.skip.test('Contacts - Get Domain Contacts', async () => {
console.log('Skipping get contacts test - no credentials');
});
} else {
tap.test('Contacts - Get Domain Contacts', async (tools) => {
// Set a timeout for the test
tools.timeout(15000); // 15 seconds timeout
// Create a new client instance
const client = createTestClient();
try {
console.log(await tools.coloredString(
`Getting contacts for domain: ${TEST_DOMAINS.INFO}`,
'cyan'
));
// Get contact information for a domain
const contacts = await client.domains.getContacts(TEST_DOMAINS.INFO);
// Validate the result
expect(contacts).toBeTypeOf('object');
expect(contacts.registrant).toBeTypeOf('object');
expect(contacts.tech).toBeTypeOf('object');
expect(contacts.admin).toBeTypeOf('object');
expect(contacts.auxBilling).toBeTypeOf('object');
// Log the contact information with colored output
console.log(await tools.coloredString('Registrant Contact:', 'green'));
logContactInfo(tools, contacts.registrant);
console.log(await tools.coloredString('Technical Contact:', 'green'));
logContactInfo(tools, contacts.tech);
console.log(await tools.coloredString('Administrative Contact:', 'green'));
logContactInfo(tools, contacts.admin);
console.log(await tools.coloredString('Billing Contact:', 'green'));
logContactInfo(tools, contacts.auxBilling);
} catch (error) {
console.error('Error getting domain contacts:', error);
throw error;
}
});
}
// Test setting domain contacts
if (skipLiveTests) {
tap.skip.test('Contacts - Set Domain Contacts', async () => {
console.log('Skipping set contacts test - no credentials');
});
} else {
tap.test('Contacts - Set Domain Contacts', async (tools) => {
// Set a timeout for the test
tools.timeout(30000); // 30 seconds timeout
// Create a new client instance
const client = createTestClient();
try {
// First, get the current contacts to use as a base
console.log(await tools.coloredString(
`Getting current contacts for domain: ${TEST_DOMAINS.INFO}`,
'cyan'
));
const currentContacts = await client.domains.getContacts(TEST_DOMAINS.INFO);
// Make a copy of the contacts to modify
const updatedContacts = {
registrant: { ...currentContacts.registrant },
tech: { ...currentContacts.tech },
admin: { ...currentContacts.admin },
auxBilling: { ...currentContacts.auxBilling }
};
// Update the phone number for all contacts
// This is a safe change that shouldn't cause issues
const timestamp = Date.now();
const newPhone = `+1.555${timestamp.toString().slice(-7)}`;
updatedContacts.registrant.Phone = newPhone;
updatedContacts.tech.Phone = newPhone;
updatedContacts.admin.Phone = newPhone;
updatedContacts.auxBilling.Phone = newPhone;
console.log(await tools.coloredString(
`Updating contacts with new phone number: ${newPhone}`,
'cyan'
));
// Set the updated contacts
const success = await client.domains.setContacts(TEST_DOMAINS.INFO, updatedContacts);
// Validate the result
expect(success).toBeTrue();
console.log(await tools.coloredString(
'Successfully updated domain contacts',
'green'
));
// Verify the changes
console.log(await tools.coloredString(
'Verifying contact changes...',
'cyan'
));
const verifyContacts = await client.domains.getContacts(TEST_DOMAINS.INFO);
expect(verifyContacts.registrant.Phone).toEqual(newPhone);
expect(verifyContacts.tech.Phone).toEqual(newPhone);
expect(verifyContacts.admin.Phone).toEqual(newPhone);
expect(verifyContacts.auxBilling.Phone).toEqual(newPhone);
console.log(await tools.coloredString(
'Contact changes verified successfully',
'green'
));
} catch (error) {
console.error('Error setting domain contacts:', error);
throw error;
}
});
}
// Test validation of contact information
tap.test('Contacts - Validate Contact Information', async () => {
// Create a client with mock credentials
const client = createTestClient(true);
// Create incomplete contact information
const incompleteContacts = {
registrant: {
FirstName: 'Test',
LastName: 'User'
// Missing required fields
}
};
// Attempt to set contacts with incomplete information
let validationError: Error | null = null;
try {
await client.domains.setContacts('example.com', incompleteContacts);
// If we get here, the validation failed to catch the incomplete information
expect(false).toBeTrue(); // This should never execute
} catch (error) {
validationError = error as Error;
}
// Verify we got an error
expect(validationError).not.toBeNull();
// Create complete contact information
const completeContacts = {
registrant: {
FirstName: 'Test',
LastName: 'User',
Address1: '123 Test St',
City: 'Test City',
StateProvince: 'CA',
PostalCode: '12345',
Country: 'US',
Phone: '+1.5555555555',
EmailAddress: 'test@example.com'
}
};
// This should not throw a validation error
// (though it will fail at the API level since we're using mock credentials)
let apiError: Error | null = null;
try {
await client.domains.setContacts('example.com', completeContacts);
} catch (error) {
apiError = error as Error;
}
// Verify we got an error (API error, not validation error)
expect(apiError).not.toBeNull();
});
// Helper function to log contact information
async function logContactInfo(tools: any, contact: IContactInfo): Promise<void> {
if (!contact) {
console.log(await tools.coloredString('No contact information available', 'blue'));
return;
}
if (contact.FirstName && contact.LastName) {
console.log(await tools.coloredString(`Name: ${contact.FirstName} ${contact.LastName}`, 'blue'));
}
if (contact.EmailAddress) {
console.log(await tools.coloredString(`Email: ${contact.EmailAddress}`, 'blue'));
}
if (contact.Phone) {
console.log(await tools.coloredString(`Phone: ${contact.Phone}`, 'blue'));
}
if (contact.Address1) {
console.log(await tools.coloredString(
`Address: ${contact.Address1}${contact.Address2 ? ', ' + contact.Address2 : ''}, ${contact.City}, ${contact.StateProvince}, ${contact.PostalCode}, ${contact.Country}`,
'blue'
));
}
}
// Start the tests
tap.start();

196
test/test.domains.dns.ts Normal file
View File

@ -0,0 +1,196 @@
/**
* Test file for Namecheap DNS operations
*/
import { expect, tap } from '@push.rocks/tapbundle';
import { createTestClient, TEST_DOMAINS, hasRealCredentials } from './config.js';
// Skip live API tests if no real credentials
const skipLiveTests = !hasRealCredentials();
// Always run this test to ensure the file doesn't fail when all other tests are skipped
tap.test('DNS - Basic Client Test', async () => {
// Create a client with mock credentials
const client = createTestClient(true);
// Verify the client has the expected methods
expect(client.dns.getHosts).toBeTypeOf('function');
expect(client.dns.setHosts).toBeTypeOf('function');
expect(client.dns.setCustom).toBeTypeOf('function');
expect(client.dns.getEmailForwarding).toBeTypeOf('function');
expect(client.dns.setEmailForwarding).toBeTypeOf('function');
expect(client.dns.getList).toBeTypeOf('function');
// This test always passes
expect(true).toBeTrue();
});
// Test DNS host records retrieval
if (skipLiveTests) {
tap.skip.test('DNS - Get Host Records', async () => {
console.log('Skipping DNS host records test - no credentials');
});
} else {
tap.test('DNS - Get Host Records', async (tools) => {
// Set a timeout for the test
tools.timeout(15000); // 15 seconds timeout
// Create a new client instance
const client = createTestClient();
// Get DNS host records for a domain
const hosts = await client.dns.getHosts(TEST_DOMAINS.DNS);
// Validate the result
expect(Array.isArray(hosts)).toBeTrue();
// Log the host records with colored output
console.log(await tools.coloredString(
`Found ${hosts.length} DNS records for ${TEST_DOMAINS.DNS}`,
'cyan'
));
for (const host of hosts) {
console.log(await tools.coloredString(
`- ${host.name} (${host.type}): ${host.address} (TTL: ${host.ttl})`,
host.type === 'A' ? 'green' :
host.type === 'CNAME' ? 'blue' :
host.type === 'MX' ? 'red' : 'cyan'
));
}
});
}
// Test DNS host records modification
if (skipLiveTests) {
tap.skip.test('DNS - Set Host Records', async () => {
console.log('Skipping DNS host modification test - no credentials');
});
} else {
tap.test('DNS - Set Host Records', async (tools) => {
// Set a timeout for the test
tools.timeout(30000); // 30 seconds timeout
// Create a new client instance
const client = createTestClient();
try {
// First, get the current host records
const currentHosts = await client.dns.getHosts(TEST_DOMAINS.DNS);
// Create a new test record
const testRecordName = `test-${Date.now()}`;
const newHosts = [
{
hostName: testRecordName,
recordType: 'A' as const,
address: '192.168.1.1',
ttl: 300
},
// Include all existing records to avoid losing them
...currentHosts.map(host => ({
hostName: host.name,
recordType: host.type as any,
address: host.address,
mxPref: host.type === 'MX' ? host.mxPref : undefined,
ttl: host.ttl
}))
];
console.log(await tools.coloredString(
`Adding test record: ${testRecordName}.${TEST_DOMAINS.DNS} -> 192.168.1.1`,
'cyan'
));
// Set the host records
const success = await client.dns.setHosts(TEST_DOMAINS.DNS, newHosts);
// Validate the result
expect(success).toBeTrue();
// Verify the new record was added
const updatedHosts = await client.dns.getHosts(TEST_DOMAINS.DNS);
const newRecord = updatedHosts.find(host => host.name === testRecordName);
expect(newRecord).toBeDefined();
expect(newRecord?.address).toEqual('192.168.1.1');
expect(newRecord?.ttl).toEqual(300);
console.log(await tools.coloredString(
`Successfully added test record: ${testRecordName}`,
'green'
));
// Clean up by removing the test record
const cleanupHosts = currentHosts.map(host => ({
hostName: host.name,
recordType: host.type as any,
address: host.address,
mxPref: host.type === 'MX' ? host.mxPref : undefined,
ttl: host.ttl
}));
console.log(await tools.coloredString(
`Cleaning up test record: ${testRecordName}`,
'cyan'
));
// Restore the original host records
const cleanupSuccess = await client.dns.setHosts(TEST_DOMAINS.DNS, cleanupHosts);
expect(cleanupSuccess).toBeTrue();
console.log(await tools.coloredString(
`Successfully cleaned up test record`,
'green'
));
} catch (error) {
console.error('Error in DNS host records test:', error);
throw error;
}
});
}
// Test email forwarding
if (skipLiveTests) {
tap.skip.test('DNS - Get Email Forwarding', async () => {
console.log('Skipping email forwarding test - no credentials');
});
} else {
tap.test('DNS - Get Email Forwarding', async (tools) => {
// Set a timeout for the test
tools.timeout(15000); // 15 seconds timeout
// Create a new client instance
const client = createTestClient();
try {
// Get email forwarding settings
const forwardings = await client.dns.getEmailForwarding(TEST_DOMAINS.DNS);
// Validate the result
expect(Array.isArray(forwardings)).toBeTrue();
// Log the email forwardings with colored output
console.log(await tools.coloredString(
`Found ${forwardings.length} email forwardings for ${TEST_DOMAINS.DNS}`,
'cyan'
));
for (const forward of forwardings) {
console.log(await tools.coloredString(
`- ${forward.from}@${TEST_DOMAINS.DNS}${forward.to}`,
'green'
));
}
} catch (error) {
// Email forwarding might not be enabled for the domain
console.log(await tools.coloredString(
`Email forwarding not available for ${TEST_DOMAINS.DNS}`,
'blue'
));
console.log(error);
}
});
}
// Start the tests
tap.start();

155
test/test.domains.info.ts Normal file
View File

@ -0,0 +1,155 @@
/**
* Test file for Namecheap domain information retrieval
*/
import { expect, tap } from '@push.rocks/tapbundle';
import { createTestClient, TEST_DOMAINS, hasRealCredentials } from './config.js';
// Skip live API tests if no real credentials
const skipLiveTests = !hasRealCredentials();
// Always run this test to ensure the file doesn't fail when all other tests are skipped
tap.test('Info - Basic Client Test', async () => {
// Create a client with mock credentials
const client = createTestClient(true);
// Verify the client has the expected methods
expect(client.domains.getList).toBeTypeOf('function');
expect(client.domains.getInfo).toBeTypeOf('function');
expect(client.domains.getContacts).toBeTypeOf('function');
// This test always passes
expect(true).toBeTrue();
});
// Test domain list retrieval
if (skipLiveTests) {
tap.skip.test('Domain Info - Get Domain List', async () => {
console.log('Skipping domain list test - no credentials');
});
} else {
tap.test('Domain Info - Get Domain List', async (tools) => {
// Set a timeout for the test
tools.timeout(15000); // 15 seconds timeout
// Create a new client instance
const client = createTestClient();
// Get list of domains
const result = await client.domains.getList();
// Validate the result
expect(result).toBeTypeOf('object');
expect(Array.isArray(result.domains)).toBeTrue();
expect(result.paging).toBeTypeOf('object');
// Log the results with colored output
console.log(await tools.coloredString(
`Found ${result.domains.length} domains in your account`,
'cyan'
));
console.log(await tools.coloredString(
`Page ${result.paging.currentPage} of ${Math.ceil(result.paging.totalItems / result.paging.pageSize)}`,
'cyan'
));
// Display the first few domains
for (const domain of result.domains.slice(0, 3)) {
console.log(await tools.coloredString(
`- ${domain.Name} (expires: ${domain.Expires})`,
'green'
));
}
});
}
// Test domain info retrieval
if (skipLiveTests) {
tap.skip.test('Domain Info - Get Domain Info', async () => {
console.log('Skipping domain info test - no credentials');
});
} else {
tap.test('Domain Info - Get Domain Info', async (tools) => {
// Set a timeout for the test
tools.timeout(15000); // 15 seconds timeout
// Create a new client instance
const client = createTestClient();
// Get information about a specific domain
const domainInfo = await client.domains.getInfo(TEST_DOMAINS.INFO);
// Validate the result
expect(domainInfo).toBeTypeOf('object');
expect(domainInfo.domainName).toEqual(TEST_DOMAINS.INFO);
expect(domainInfo.status).toBeTypeOf('string');
expect(domainInfo.createdDate).toBeTypeOf('string');
expect(domainInfo.expiredDate).toBeTypeOf('string');
// Log the domain information with colored output
console.log(await tools.coloredString(`Domain: ${domainInfo.domainName}`, 'cyan'));
console.log(await tools.coloredString(`Status: ${domainInfo.status}`, 'cyan'));
console.log(await tools.coloredString(`Created: ${domainInfo.createdDate}`, 'cyan'));
console.log(await tools.coloredString(`Expires: ${domainInfo.expiredDate}`, 'cyan'));
console.log(await tools.coloredString(
`WhoisGuard: ${domainInfo.whoisGuard.enabled ? 'Enabled' : 'Disabled'}`,
domainInfo.whoisGuard.enabled ? 'green' : 'blue'
));
});
}
// Test domain contacts retrieval
if (skipLiveTests) {
tap.skip.test('Domain Info - Get Domain Contacts', async () => {
console.log('Skipping domain contacts test - no credentials');
});
} else {
tap.test('Domain Info - Get Domain Contacts', async (tools) => {
// Set a timeout for the test
tools.timeout(15000); // 15 seconds timeout
// Create a new client instance
const client = createTestClient();
// Get contact information for a domain
const contacts = await client.domains.getContacts(TEST_DOMAINS.INFO);
// Validate the result
expect(contacts).toBeTypeOf('object');
expect(contacts.registrant).toBeTypeOf('object');
// Log the registrant contact information with colored output
console.log(await tools.coloredString('Registrant Contact Information:', 'cyan'));
if (contacts.registrant.FirstName && contacts.registrant.LastName) {
console.log(await tools.coloredString(
`Name: ${contacts.registrant.FirstName} ${contacts.registrant.LastName}`,
'green'
));
}
if (contacts.registrant.EmailAddress) {
console.log(await tools.coloredString(
`Email: ${contacts.registrant.EmailAddress}`,
'green'
));
}
if (contacts.registrant.Phone) {
console.log(await tools.coloredString(
`Phone: ${contacts.registrant.Phone}`,
'green'
));
}
if (contacts.registrant.Address1 && contacts.registrant.City) {
console.log(await tools.coloredString(
`Address: ${contacts.registrant.Address1}, ${contacts.registrant.City}, ${contacts.registrant.StateProvince || ''}, ${contacts.registrant.PostalCode || ''}, ${contacts.registrant.Country}`,
'green'
));
}
});
}
// Start the tests
tap.start();

View File

@ -0,0 +1,217 @@
/**
* Test file for Namecheap nameserver operations
*/
import { expect, tap } from '@push.rocks/tapbundle';
import { createTestClient, TEST_DOMAINS, hasRealCredentials } from './config.js';
// Skip live API tests if no real credentials
const skipLiveTests = !hasRealCredentials();
// Always run this test to ensure the file doesn't fail when all other tests are skipped
tap.test('Nameservers - Basic Client Test', async () => {
// Create a client with mock credentials
const client = createTestClient(true);
// Verify the client has the expected methods
expect(client.ns.create).toBeTypeOf('function');
expect(client.ns.delete).toBeTypeOf('function');
expect(client.ns.getInfo).toBeTypeOf('function');
expect(client.ns.update).toBeTypeOf('function');
// This test always passes
expect(true).toBeTrue();
});
// Parse domain into SLD and TLD
function parseDomain(domain: string): { sld: string, tld: string } {
const parts = domain.split('.');
const tld = parts.pop() || '';
const sld = parts.join('.');
return { sld, tld };
}
// Test nameserver creation and deletion
if (skipLiveTests) {
tap.skip.test('Nameservers - Create and Delete Custom Nameserver', async () => {
console.log('Skipping nameserver creation test - no credentials');
});
} else {
tap.test('Nameservers - Create and Delete Custom Nameserver', async (tools) => {
// Set a timeout for the test
tools.timeout(60000); // 60 seconds timeout
// Create a new client instance
const client = createTestClient();
// Parse the test domain
const { sld, tld } = parseDomain(TEST_DOMAINS.DNS);
// Create a unique nameserver name
const nsName = `ns${Date.now()}.${TEST_DOMAINS.DNS}`;
const nsIp = '192.168.1.1';
try {
console.log(await tools.coloredString(
`Creating nameserver: ${nsName} with IP: ${nsIp}`,
'cyan'
));
// Create a new nameserver
const createResult = await client.ns.create(sld, tld, nsName, nsIp);
// Validate the result
expect(createResult).toBeTrue();
console.log(await tools.coloredString(
`Successfully created nameserver: ${nsName} with IP: ${nsIp}`,
'green'
));
// Get nameserver info
const nsInfo = await client.ns.getInfo(sld, tld, nsName);
// Validate the info
expect(nsInfo).toBeTypeOf('object');
expect(nsInfo.nameserver).toEqual(nsName);
expect(nsInfo.ip).toEqual(nsIp);
console.log(await tools.coloredString(
`Nameserver info:
- Name: ${nsInfo.nameserver}
- IP: ${nsInfo.ip}
- Statuses: ${nsInfo.statuses.join(', ')}
`,
'green'
));
// Update the nameserver IP
const newIp = '192.168.1.2';
console.log(await tools.coloredString(
`Updating nameserver IP from ${nsIp} to ${newIp}`,
'cyan'
));
const updateResult = await client.ns.update(sld, tld, nsName, nsIp, newIp);
// Validate the update result
expect(updateResult).toBeTrue();
console.log(await tools.coloredString(
`Successfully updated nameserver IP from ${nsIp} to ${newIp}`,
'green'
));
// Verify the update
const updatedInfo = await client.ns.getInfo(sld, tld, nsName);
expect(updatedInfo.ip).toEqual(newIp);
// Delete the nameserver
console.log(await tools.coloredString(
`Deleting nameserver: ${nsName}`,
'cyan'
));
const deleteResult = await client.ns.delete(sld, tld, nsName);
// Validate the delete result
expect(deleteResult).toBeTrue();
console.log(await tools.coloredString(
`Successfully deleted nameserver: ${nsName}`,
'green'
));
} catch (error) {
console.error('Error in nameserver operations:', error);
throw error;
}
});
}
// Test custom nameservers for domain
if (skipLiveTests) {
tap.skip.test('Nameservers - Set Custom Nameservers for Domain', async () => {
console.log('Skipping custom nameservers test - no credentials');
});
} else {
tap.test('Nameservers - Set Custom Nameservers for Domain', async (tools) => {
// Set a timeout for the test
tools.timeout(60000); // 60 seconds timeout
// Create a new client instance
const client = createTestClient();
// Get current DNS settings to restore later
const currentHosts = await client.dns.getHosts(TEST_DOMAINS.DNS);
try {
// Set custom nameservers
const customNameservers = [
'dns1.namecheaphosting.com',
'dns2.namecheaphosting.com'
];
console.log(await tools.coloredString(
`Setting custom nameservers for ${TEST_DOMAINS.DNS}: ${customNameservers.join(', ')}`,
'cyan'
));
const result = await client.dns.setCustom(TEST_DOMAINS.DNS, customNameservers);
// Validate the result
expect(result).toBeTrue();
console.log(await tools.coloredString(
`Successfully set custom nameservers for ${TEST_DOMAINS.DNS}`,
'green'
));
// Now restore the original DNS settings
console.log(await tools.coloredString(
`Restoring original DNS settings for ${TEST_DOMAINS.DNS}`,
'cyan'
));
const restoreResult = await client.dns.setHosts(
TEST_DOMAINS.DNS,
currentHosts.map(host => ({
hostName: host.name,
recordType: host.type as any,
address: host.address,
mxPref: host.type === 'MX' ? host.mxPref : undefined,
ttl: host.ttl
}))
);
expect(restoreResult).toBeTrue();
console.log(await tools.coloredString(
`Successfully restored original DNS settings for ${TEST_DOMAINS.DNS}`,
'green'
));
} catch (error) {
console.error('Error in custom nameserver operations:', error);
// Try to restore original settings if there was an error
try {
await client.dns.setHosts(
TEST_DOMAINS.DNS,
currentHosts.map(host => ({
hostName: host.name,
recordType: host.type as any,
address: host.address,
mxPref: host.type === 'MX' ? host.mxPref : undefined,
ttl: host.ttl
}))
);
console.log(await tools.coloredString(
'Restored original DNS settings after error',
'yellow'
));
} catch (restoreError) {
console.error('Failed to restore original DNS settings:', restoreError);
}
throw error;
}
});
}
// Start the tests
tap.start();

View File

@ -0,0 +1,198 @@
/**
* Test file for Namecheap domain registration operations
*
* IMPORTANT: These tests can incur charges even in sandbox mode!
* Only run these tests if you understand the implications.
*/
import { expect, tap } from '@push.rocks/tapbundle';
import { createTestClient, TEST_DOMAINS, hasRealCredentials } from './config.js';
// Skip live API tests if no real credentials or if ENABLE_REGISTRATION_TESTS is not set
const skipLiveTests = !hasRealCredentials() || process.env.ENABLE_REGISTRATION_TESTS !== 'true';
// Always run this test to ensure the file doesn't fail when all other tests are skipped
tap.test('Registration - Basic Client Test', async () => {
// Create a client with mock credentials
const client = createTestClient(true);
// Verify the client has the expected methods
expect(client.domains.create).toBeTypeOf('function');
expect(client.domains.renew).toBeTypeOf('function');
expect(client.domains.reactivate).toBeTypeOf('function');
expect(client.domains.getTldList).toBeTypeOf('function');
// This test always passes
expect(true).toBeTrue();
});
// Test TLD list retrieval
if (skipLiveTests) {
tap.skip.test('Registration - Check TLD List', async () => {
console.log('Skipping TLD list test - no credentials or registration tests disabled');
});
} else {
tap.test('Registration - Check TLD List', async (tools) => {
// Set a timeout for the test
tools.timeout(15000); // 15 seconds timeout
// Create a new client instance
const client = createTestClient();
// Get list of available TLDs
const tlds = await client.domains.getTldList();
// Validate the result
expect(Array.isArray(tlds)).toBeTrue();
expect(tlds.length).toBeGreaterThan(0);
// Log some of the available TLDs with colored output
console.log(await tools.coloredString(
`Available TLDs: ${tlds.slice(0, 10).join(', ')}...`,
'cyan'
));
});
}
// Test domain registration
// This test is always skipped by default because it costs money
tap.skip.test('Registration - Register Domain', async (tools) => {
// Set a timeout for the test
tools.timeout(60000); // 60 seconds timeout
// Create a new client instance
const client = createTestClient();
// Sample contact information (required for registration)
const contacts = {
registrant: {
FirstName: 'Test',
LastName: 'User',
Address1: '123 Test St',
City: 'Test City',
StateProvince: 'CA',
PostalCode: '12345',
Country: 'US',
Phone: '+1.5555555555',
EmailAddress: 'test@example.com'
},
tech: {
FirstName: 'Test',
LastName: 'User',
Address1: '123 Test St',
City: 'Test City',
StateProvince: 'CA',
PostalCode: '12345',
Country: 'US',
Phone: '+1.5555555555',
EmailAddress: 'test@example.com'
},
admin: {
FirstName: 'Test',
LastName: 'User',
Address1: '123 Test St',
City: 'Test City',
StateProvince: 'CA',
PostalCode: '12345',
Country: 'US',
Phone: '+1.5555555555',
EmailAddress: 'test@example.com'
},
auxBilling: {
FirstName: 'Test',
LastName: 'User',
Address1: '123 Test St',
City: 'Test City',
StateProvince: 'CA',
PostalCode: '12345',
Country: 'US',
Phone: '+1.5555555555',
EmailAddress: 'test@example.com'
}
};
console.log(await tools.coloredString(
`Registering domain: ${TEST_DOMAINS.REGISTER}`,
'cyan'
));
// Register a new domain
const result = await client.domains.create({
domainName: TEST_DOMAINS.REGISTER,
years: 1,
contacts,
nameservers: ['dns1.namecheaphosting.com', 'dns2.namecheaphosting.com'],
addFreeWhoisguard: true,
whoisguardPrivacy: true
});
// Validate the result
expect(result).toBeTypeOf('object');
expect(result.registered).toBeTrue();
expect(result.domain).toEqual(TEST_DOMAINS.REGISTER);
// Log the registration result with colored output
console.log(await tools.coloredString(
`Domain ${result.domain} registered successfully`,
'green'
));
console.log(await tools.coloredString(
`Transaction ID: ${result.transactionId}`,
'green'
));
console.log(await tools.coloredString(
`Order ID: ${result.orderId}`,
'green'
));
console.log(await tools.coloredString(
`Charged Amount: ${result.chargedAmount}`,
'green'
));
});
// Test domain renewal
// This test is always skipped by default because it costs money
tap.skip.test('Registration - Renew Domain', async (tools) => {
// Set a timeout for the test
tools.timeout(60000); // 60 seconds timeout
// Create a new client instance
const client = createTestClient();
console.log(await tools.coloredString(
`Renewing domain: ${TEST_DOMAINS.INFO}`,
'cyan'
));
// Renew a domain
const result = await client.domains.renew(TEST_DOMAINS.INFO, 1);
// Validate the result
expect(result).toBeTypeOf('object');
expect(result.renewed).toBeTrue();
expect(result.domainName).toEqual(TEST_DOMAINS.INFO);
// Log the renewal result with colored output
console.log(await tools.coloredString(
`Domain ${result.domainName} renewed successfully`,
'green'
));
console.log(await tools.coloredString(
`Transaction ID: ${result.transactionId}`,
'green'
));
console.log(await tools.coloredString(
`Order ID: ${result.orderId}`,
'green'
));
console.log(await tools.coloredString(
`Charged Amount: ${result.chargedAmount}`,
'green'
));
console.log(await tools.coloredString(
`New Expiry Date: ${result.expireDate}`,
'green'
));
});
// Start the tests
tap.start();

View File

@ -0,0 +1,186 @@
/**
* Test file for Namecheap domain transfer operations
*
* IMPORTANT: These tests can incur charges even in sandbox mode!
* Only run these tests if you understand the implications.
*/
import { expect, tap } from '@push.rocks/tapbundle';
import { createTestClient, hasRealCredentials } from './config.js';
// Skip live API tests if no real credentials or if ENABLE_TRANSFER_TESTS is not set
const skipLiveTests = !hasRealCredentials() || process.env.ENABLE_TRANSFER_TESTS !== 'true';
// Always run this test to ensure the file doesn't fail when all other tests are skipped
tap.test('Transfer - Basic Client Test', async () => {
// Create a client with mock credentials
const client = createTestClient(true);
// Verify the client has the expected methods
expect(client.transfer.getList).toBeTypeOf('function');
expect(client.transfer.getStatus).toBeTypeOf('function');
expect(client.transfer.create).toBeTypeOf('function');
expect(client.transfer.updateStatus).toBeTypeOf('function');
expect(client.transfer.getInfo).toBeTypeOf('function');
// This test always passes
expect(true).toBeTrue();
});
// Test transfer list retrieval
if (skipLiveTests) {
tap.skip.test('Transfer - Get Transfer List', async () => {
console.log('Skipping transfer list test - no credentials or transfer tests disabled');
});
} else {
tap.test('Transfer - Get Transfer List', async (tools) => {
// Set a timeout for the test
tools.timeout(15000); // 15 seconds timeout
// Create a new client instance
const client = createTestClient();
// Get list of domain transfers
const result = await client.transfer.getList();
// Validate the result
expect(result).toBeTypeOf('object');
expect(Array.isArray(result.transfers)).toBeTrue();
expect(result.paging).toBeTypeOf('object');
// Log the results with colored output
console.log(await tools.coloredString(
`Found ${result.transfers.length} domain transfers in your account`,
'cyan'
));
// Display the first few transfers
for (const transfer of result.transfers.slice(0, 3)) {
console.log(await tools.coloredString(
`- ${transfer.domainName} (Status: ${transfer.status})`,
transfer.status.toLowerCase().includes('success') ? 'green' :
transfer.status.toLowerCase().includes('fail') ? 'red' : 'blue'
));
}
});
}
// Test domain transfer creation
// This test is always skipped by default because it costs money
tap.skip.test('Transfer - Create Transfer', async (tools) => {
// Set a timeout for the test
tools.timeout(60000); // 60 seconds timeout
// Create a new client instance
const client = createTestClient();
console.log(await tools.coloredString(
`Initiating transfer for domain: domain-to-transfer.com`,
'cyan'
));
// Create a domain transfer
// You need a valid EPP/Auth code from the current registrar
const result = await client.transfer.create(
'domain-to-transfer.com', // Domain to transfer
1, // Number of years to renew for
'EPP_AUTH_CODE_HERE', // EPP/Auth code from current registrar
{
addFreeWhoisguard: true,
whoisguardEnable: true
}
);
// Validate the result
expect(result).toBeTypeOf('object');
expect(result.isSuccess).toBeTrue();
// Log the transfer result with colored output
console.log(await tools.coloredString(
`Domain transfer initiated successfully`,
'green'
));
console.log(await tools.coloredString(
`Transfer ID: ${result.transferId}`,
'green'
));
console.log(await tools.coloredString(
`Order ID: ${result.transferOrderId}`,
'green'
));
console.log(await tools.coloredString(
`Status: ${result.transferStatus}`,
'green'
));
console.log(await tools.coloredString(
`Description: ${result.statusDescription}`,
'green'
));
console.log(await tools.coloredString(
`Charged Amount: ${result.chargedAmount}`,
'green'
));
});
// Test transfer status retrieval
if (skipLiveTests) {
tap.skip.test('Transfer - Get Transfer Status', async () => {
console.log('Skipping transfer status test - no credentials or transfer tests disabled');
});
} else {
tap.test('Transfer - Get Transfer Status', async (tools) => {
// This test requires an existing transfer ID
// If you don't have one, it will be skipped
const transferId = process.env.TEST_TRANSFER_ID ? parseInt(process.env.TEST_TRANSFER_ID) : null;
if (!transferId) {
console.log(await tools.coloredString(
'Skipping transfer status test - no TEST_TRANSFER_ID provided',
'blue'
));
return;
}
// Set a timeout for the test
tools.timeout(15000); // 15 seconds timeout
// Create a new client instance
const client = createTestClient();
console.log(await tools.coloredString(
`Getting status for transfer ID: ${transferId}`,
'cyan'
));
// Get transfer status
const status = await client.transfer.getStatus(transferId);
// Validate the result
expect(status).toBeTypeOf('object');
expect(status.id).toEqual(transferId);
// Log the transfer status with colored output
console.log(await tools.coloredString(
`Transfer ID: ${status.id}`,
'green'
));
console.log(await tools.coloredString(
`Domain: ${status.domainName}`,
'green'
));
console.log(await tools.coloredString(
`Status: ${status.status}`,
'green'
));
console.log(await tools.coloredString(
`Description: ${status.statusDescription}`,
'green'
));
console.log(await tools.coloredString(
`Date: ${status.date}`,
'green'
));
});
}
// Start the tests
tap.start();

130
test/test.ts Normal file
View File

@ -0,0 +1,130 @@
import { expect, expectAsync, tap } from '@push.rocks/tapbundle';
import { createTestClient, TEST_DOMAINS, hasRealCredentials } from './config.js';
const testDomain = TEST_DOMAINS.INFO; // Use the test domain from config
// Skip live API tests if no real credentials
const skipLiveTests = !hasRealCredentials();
// Test suite for Namecheap API client
tap.test('Namecheap API Client - Configuration', async () => {
// Create a new client instance
const client = createTestClient()
// Test that the client was created successfully
expect(client).toBeTypeOf('object');
expect(client.domains).toBeTypeOf('object');
expect(client.dns).toBeTypeOf('object');
expect(client.ns).toBeTypeOf('object');
expect(client.transfer).toBeTypeOf('object');
// Test configuration methods
expect(client.enableSandbox).toBeTypeOf('function');
expect(client.disableSandbox).toBeTypeOf('function');
expect(client.setTimeout).toBeTypeOf('function');
});
tap.test('Namecheap API Client - Domain Methods', async () => {
// Create a new client instance
const client = createTestClient();
// Test that domain methods exist
expect(client.domains.getList).toBeTypeOf('function');
expect(client.domains.check).toBeTypeOf('function');
expect(client.domains.getInfo).toBeTypeOf('function');
expect(client.domains.getContacts).toBeTypeOf('function');
expect(client.domains.setContacts).toBeTypeOf('function');
expect(client.domains.create).toBeTypeOf('function');
expect(client.domains.renew).toBeTypeOf('function');
expect(client.domains.reactivate).toBeTypeOf('function');
expect(client.domains.getRegistrarLock).toBeTypeOf('function');
expect(client.domains.setRegistrarLock).toBeTypeOf('function');
expect(client.domains.getTldList).toBeTypeOf('function');
});
tap.test('Namecheap API Client - DNS Methods', async () => {
// Create a new client instance
const client = createTestClient();
// Test that DNS methods exist
expect(client.dns.getHosts).toBeTypeOf('function');
expect(client.dns.setHosts).toBeTypeOf('function');
expect(client.dns.setCustom).toBeTypeOf('function');
expect(client.dns.getEmailForwarding).toBeTypeOf('function');
expect(client.dns.setEmailForwarding).toBeTypeOf('function');
expect(client.dns.getList).toBeTypeOf('function');
});
tap.test('Namecheap API Client - Nameserver Methods', async () => {
// Create a new client instance
const client = createTestClient();
// Test that nameserver methods exist
expect(client.ns.create).toBeTypeOf('function');
expect(client.ns.delete).toBeTypeOf('function');
expect(client.ns.getInfo).toBeTypeOf('function');
expect(client.ns.update).toBeTypeOf('function');
});
tap.test('Namecheap API Client - Transfer Methods', async () => {
// Create a new client instance
const client = createTestClient();
// Test that transfer methods exist
expect(client.transfer.getList).toBeTypeOf('function');
expect(client.transfer.getStatus).toBeTypeOf('function');
expect(client.transfer.create).toBeTypeOf('function');
expect(client.transfer.updateStatus).toBeTypeOf('function');
expect(client.transfer.getInfo).toBeTypeOf('function');
});
// This test uses expectAsync to demonstrate async testing
tap.test('Namecheap API Client - Async Test', async () => {
// Create a simple async function that returns a string
const asyncFunction = async () => {
return `Testing domain: ${testDomain}`;
};
// Use expectAsync to test the async function
const result = await asyncFunction();
expect(result).toEqual(`Testing domain: ${testDomain}`);
// Test that the function returns a Promise
expectAsync(asyncFunction());
});
// Domain availability tests
if (skipLiveTests) {
tap.skip.test('Domain Availability - Check Single Domain', async () => {
// This test is skipped when no real credentials are available
console.log('Skipping domain availability test - no credentials');
});
} else {
tap.test('Domain Availability - Check Single Domain', async (tools) => {
// Set a timeout for the test
tools.timeout(10000); // 10 seconds timeout
// Log test information with colored output
console.log(await tools.coloredString(`Testing domain: ${testDomain}`, 'cyan'));
// Create a new client instance with real credentials
const client = createTestClient();
// Check if the test domain is available
const availability = await client.domains.check(testDomain);
// Log the result
const isAvailable = availability[0].available;
console.log(await tools.coloredString(
`Domain ${testDomain} is ${isAvailable ? 'available' : 'not available'} for registration`,
isAvailable ? 'green' : 'blue'
));
// We don't assert on the result since availability can change
// Just verify that the call completes without errors
expect(availability).toBeTypeOf('object');
expect(availability.length).toBeGreaterThan(0);
});
}
tap.start();