UNPKG

whois-parsed

Version:

A wrapper for the fantastic whois module that parses whois data into consistent fields across multiple tlds

416 lines (369 loc) 17.4 kB
const chai = require('chai'); const expect = chai.expect; chai.use(require('chai-datetime')); const assert = chai.assert; var whoisParser = require('../index'); const punycode = require('punycode'); function randomString(length, chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') { var result = ''; for (var i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)]; return result; } function whoisWithRetries(domain, retriesLeft = 3, options = {}) { return new Promise(function(resolve, reject) { whoisParser.lookup(domain, options) .then ((results) => { return resolve(results); }) .catch ((error) => { if (retriesLeft > 0 && ((error.code && error.code === 'ECONNRESET') || error.message.match(/.*Bad WHOIS Data.*/) || error.message.match(/.*Rate Limited*/))) { console.warn('Retrying ' + domain + ' due to ' + error.message + ' error. Retries left: ' + retriesLeft); whoisWithRetries(domain, retriesLeft-1, options) .then((results) => { return resolve(results); }) .catch((err) => { return reject(err); }); } else { console.log(error); return reject(error); } }); }); } async function testNotAvailable (base, tld, options = {}) { var result = await whoisWithRetries(base + tld); // console.log (result); if (tld === '.рф') { // this gets translated to puny code expect(punycode.toUnicode(result['domainName'])).to.equal(base + tld); } else { expect(result['domainName']).to.equal(base + tld); } expect(result['isAvailable']).to.equal(false); if (!(options.hasOwnProperty('excludedFields') && options.excludedFields.includes('expirationDate'))) { assert.beforeDate(new Date(), new Date(result['expirationDate'])); } if (!(options.hasOwnProperty('excludedFields') && options.excludedFields.includes('creationDate'))) { assert.afterDate(new Date(), new Date(result['creationDate'])); } if (!(options.hasOwnProperty('excludedFields') && options.excludedFields.includes('updatedDate'))) { assert.afterDate(new Date(), new Date(result['updatedDate'])); } if (!(options.hasOwnProperty('excludedFields') && options.excludedFields.includes('status'))) { expect(result['status'].length).to.be.above(0); } if (!(options.hasOwnProperty('excludedFields') && options.excludedFields.includes('registrar'))) { expect(result.hasOwnProperty('registrar')).to.be.true; } expect(result.hasOwnProperty('dateFormat')).to.be.false; } async function testAvailable (tld) { var rString = randomString(32).toLowerCase(); var result = await whoisWithRetries(rString + tld); // console.log(result); expect(result['domainName']).to.equal(rString + tld); expect(result['isAvailable']).to.equal(true); expect(result.hasOwnProperty('creationDate')).to.be.false; expect(result.hasOwnProperty('updatedDate')).to.be.false; expect(result.hasOwnProperty('expirationDate')).to.be.false; expect(result.hasOwnProperty('registrar')).to.be.false; expect(result.hasOwnProperty('dateFormat')).to.be.false; } describe('#whoisParser integration tests', function() { this.timeout(250000); beforeEach(() => { // Pause 3 seconds in between requests to help prevent rate limiting return new Promise((resolve) => { setTimeout(() => { resolve(); }, 3000); }); }); it('known .com should not be available and have data', async function () { await testNotAvailable('google', '.com'); }); it('random .com domain should be available', async function() { await testAvailable('.com'); }); it('known .net should not be available and have data', async function () { await testNotAvailable('google', '.net'); }); it('random .net domain should be available', async function() { await testAvailable('.net'); }); it('known .org should not be available and have data', async function () { await testNotAvailable('google', '.org'); }); it('random .org domain should be available', async function() { await testAvailable('.org'); }); it('known .name should not be available and have data', async function () { await testNotAvailable('google', '.name', {excludedFields: ['creationDate', 'expirationDate', 'updatedDate']}); }); it('random .name domain should be available', async function() { await testAvailable('.name'); }); it('known .me should not be available and have data', async function () { await testNotAvailable('google', '.me'); }); it('random .me domain should be available', async function() { await testAvailable('.me'); }); // updatedDate is sometimes populated for .au domains, but not always. it('known .au should not be available and have data', async function () { await testNotAvailable('google.com', '.au', { excludedFields: ['creationDate', 'expirationDate', 'updatedDate']}); }); it('random .au domain should be available', async function() { await testAvailable('.com.au'); }); it('known .ru should not be available and have data', async function () { await testNotAvailable('google', '.ru', {excludedFields: ['updatedDate']}); }); it('random .ru domain should be available', async function() { await testAvailable('.ru'); }); it('known .us should not be available and have data', async function () { await testNotAvailable('google', '.us'); }); it('random .us domain should be available', async function() { await testAvailable('.us'); }); it('known .uk should not be available and have data', async function () { await testNotAvailable('google.co', '.uk', { excludedFields: ['status']}); }); it('random .uk domain should be available', async function() { await testAvailable('.co.uk'); }); it('known .fr should not be available and have data', async function () { await testNotAvailable('google', '.fr'); }); it('random .fr domain should be available', async function() { await testAvailable('.fr'); }); it('known .nl should not be available and have data', async function () { await testNotAvailable('google', '.nl', {excludedFields: ['creationDate', 'expirationDate', 'updatedDate']}); }); it('random .nl domain should be available', async function() { await testAvailable('.nl'); }); it('known .fi should not be available and have data', async function () { await testNotAvailable('google', '.fi'); }); it('random .fi domain should be available', async function() { await testAvailable('.fi'); }); it('known .jp should not be available and have data', async function () { await testNotAvailable('google', '.jp', {excludedFields: ['registrar']}); }); it('random .jp domain should be available', async function() { await testAvailable('.jp'); }); it('known .pl should not be available and have data', async function () { await testNotAvailable('google', '.pl', {excludedFields: ['status']}); }); it('random .pl domain should be available', async function() { await testAvailable('.pl'); }); it('known .br should not be available and have data', async function () { await testNotAvailable('google.com', '.br', {excludedFields: ['registrar']}); }); it('random .br domain should be available', async function() { await testAvailable('.com.br'); }); it('known .eu should not be available and have data', async function () { await testNotAvailable('google', '.eu', {excludedFields: ['creationDate', 'expirationDate', 'updatedDate', 'status']}); }); it('random .eu domain should be available', async function() { await testAvailable('.eu'); }); it('known .ee should not be available and have data', async function () { await testNotAvailable('google', '.ee'); }); it('random .ee domain should be available', async function() { await testAvailable('.ee'); }); it('known .kr should not be available and have data', async function () { await testNotAvailable('google', '.kr', {excludedFields: ['status']}); }); it('random .kr domain should be available', async function() { await testAvailable('.kr'); }); it('known .bg should not be available and have data', async function () { await testNotAvailable('google', '.bg', {excludedFields: ['creationDate', 'expirationDate', 'updatedDate', 'registrar']}); }); it('random .bg domain should be available', async function() { await testAvailable('.bg'); }); it('known .de should not be available and have data', async function () { await testNotAvailable('google', '.de', {excludedFields: ['creationDate', 'expirationDate', 'registrar']}); }); it('random .de domain should be available', async function() { await testAvailable('.de'); }); it('known .at should not be available and have data', async function () { await testNotAvailable('google', '.at', {excludedFields: ['creationDate', 'expirationDate', 'status']}); }); it('random .at domain should be available', async function() { await testAvailable('.at'); }); it('known .ca should not be available and have data', async function () { await testNotAvailable('google', '.ca'); }); it('random .ca domain should be available', async function() { await testAvailable('.ca'); }); it('known .be should not be available and have data', async function () { await testNotAvailable('google', '.be', {excludedFields: ['updatedDate', 'expirationDate']}); }); it('random .be domain should be available', async function() { await testAvailable('.be'); }); it('known .рф should not be available and have data', async function () { await testNotAvailable('президент', '.рф', {excludedFields: ['updatedDate']}); }); it('random .рф domain should be available', async function() { await testAvailable('.рф'); }); it('known .info should not be available and have data', async function () { await testNotAvailable('google', '.info'); }); it('random .info domain should be available', async function() { await testAvailable('.info'); }); it('known .su should not be available and have data', async function () { await testNotAvailable('google', '.su', {excludedFields: ['updatedDate']}); }); it('random .su domain should be available', async function() { await testAvailable('.su'); }); it('known .kg should not be available and have data', async function () { await testNotAvailable('google', '.kg', {excludedFields: ['status', 'registrar']}); }); it('random .kg domain should be available', async function() { await testAvailable('.kg'); }); it('known .biz should not be available and have data', async function () { await testNotAvailable('google', '.biz'); }); it('random .biz domain should be available', async function() { await testAvailable('.biz'); }); it('known .mobi should not be available and have data', async function () { await testNotAvailable('google', '.mobi'); }); it('random .mobi domain should be available', async function() { await testAvailable('.mobi'); }); it('known .id should not be available and have data', async function () { await testNotAvailable('google', '.id'); }); it('random .id domain should be available', async function() { await testAvailable('.id'); }); it('known .sk should not be available and have data', async function () { await testNotAvailable('google', '.sk'); }); it('random .sk domain should be available', async function() { await testAvailable('.sk'); }); it('known .se should not be available and have data', async function () { await testNotAvailable('google', '.se'); }); it('random .se domain should be available', async function() { await testAvailable('.se'); }); it('known .nu should not be available and have data', async function () { await testNotAvailable('google', '.nu'); }); it('random .se domain should be available', async function() { await testAvailable('.se'); }); it('known .is should not be available and have data', async function () { await testNotAvailable('google', '.is', {excludedFields: ['updatedDate', 'status', 'registrar']}); }); it('random .is domain should be available', async function() { await testAvailable('.is'); }); it('known generic tld domain (.bike) should not be available and have data', async function () { await testNotAvailable('red', '.bike', {excludedFields: ['status']}); }); it('random generic tld domain (.bike) should be available', async function() { await testAvailable('.bike'); }); it('known generic tld domain (.asia) should not be available and have data', async function () { await testNotAvailable('google', '.asia', {excludedFields: ['status']} ); }); it('random generic tld domain (.asia) should be available', async function() { await testAvailable('.asia'); }); it('known generic tld domain (.io) should not be available and have data', async function () { await testNotAvailable('google', '.io', {excludedFields: ['status']} ); }); it('random generic tld domain (.io) should be available', async function() { await testAvailable('.io'); }); it('known .co should not be available and have data', async function () { await testNotAvailable('google', '.co'); }); it('random .co domain should be available', async function() { await testAvailable('.co'); }); it('random tld domain should throw TLD not supported error', () => { return whoisWithRetries('google.sdiekdsoclsld') .then( () => Promise.reject(new Error('Expected call to reject.')), err => { assert.instanceOf(err, Error); assert.equal(err.message, 'TLD not supported'); } ); }); it('domains with multiple status values should list all statuses', async function () { var result = await whoisWithRetries('google.com'); expect(result['domainName']).to.equal('google.com'); expect(result['isAvailable']).to.equal(false); assert.beforeDate(new Date(), new Date(result['expirationDate'])); assert.afterDate(new Date(), new Date(result['creationDate'])); assert.afterDate(new Date(), new Date(result['updatedDate'])); expect(result['status'].length).to.be.above(2); expect(result.hasOwnProperty('registrar')).to.be.true; expect(result.hasOwnProperty('dateFormat')).to.be.false; }); it('domains with a broken registrar link should work', async function () { var result = await whoisWithRetries('st-andrews-school.org'); expect(result['domainName']).to.equal('st-andrews-school.org'); expect(result['isAvailable']).to.equal(false); assert.beforeDate(new Date(), new Date(result['expirationDate'])); assert.afterDate(new Date(), new Date(result['creationDate'])); assert.afterDate(new Date(), new Date(result['updatedDate'])); expect(result['status'].length).to.be.above(0); expect(result.hasOwnProperty('registrar')).to.be.true; expect(result.hasOwnProperty('dateFormat')).to.be.false; }); //TODO call something like https://api.getproxylist.com/proxy?lastTested=300&protocol[]=socks5 to test proxy it('proxy should work', async function () { var whoisOptions = { proxy: { host: '118.190.206.86', port: 9999, // userId: "optional", // password: "optional", type: 5, }, timeout: 30000, }; var result = await whoisWithRetries('google.com', 3, whoisOptions); expect(result['domainName']).to.equal('google.com'); expect(result['isAvailable']).to.equal(false); assert.beforeDate(new Date(), new Date(result['expirationDate'])); assert.afterDate(new Date(), new Date(result['creationDate'])); assert.afterDate(new Date(), new Date(result['updatedDate'])); expect(result['status'].length).to.be.above(0); expect(result.hasOwnProperty('registrar')).to.be.true; expect(result.hasOwnProperty('dateFormat')).to.be.false; }); });