Add DNS lookup tool and tests
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
// Import Node's built-in test tools.
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert/strict");
|
||||
|
||||
// Import the DNS service.
|
||||
const {
|
||||
lookupDns,
|
||||
resolveRecord,
|
||||
RECORD_TYPES,
|
||||
} = require("../src/services/dnsService");
|
||||
|
||||
test("supports the expected DNS record types", () => {
|
||||
assert.deepEqual(
|
||||
RECORD_TYPES,
|
||||
["A", "AAAA", "CNAME", "MX", "TXT", "NS"]
|
||||
);
|
||||
});
|
||||
|
||||
test("resolves A records for example.com", async () => {
|
||||
const records = await resolveRecord("example.com", "A");
|
||||
|
||||
assert.equal(Array.isArray(records), true);
|
||||
assert.equal(records.length > 0, true);
|
||||
});
|
||||
|
||||
test("returns an array for a missing optional record type", async () => {
|
||||
const records = await resolveRecord(
|
||||
"example.com",
|
||||
"CNAME"
|
||||
);
|
||||
|
||||
assert.equal(Array.isArray(records), true);
|
||||
});
|
||||
|
||||
test("joins TXT record fragments into strings", async () => {
|
||||
const records = await resolveRecord("google.com", "TXT");
|
||||
|
||||
assert.equal(Array.isArray(records), true);
|
||||
|
||||
records.forEach((record) => {
|
||||
assert.equal(typeof record, "string");
|
||||
});
|
||||
});
|
||||
|
||||
test("returns all supported record groups", async () => {
|
||||
const result = await lookupDns("example.com");
|
||||
|
||||
assert.equal(result.hostname, "example.com");
|
||||
assert.equal(typeof result.checkedAt, "string");
|
||||
assert.equal(typeof result.records, "object");
|
||||
|
||||
RECORD_TYPES.forEach((recordType) => {
|
||||
assert.equal(
|
||||
Array.isArray(result.records[recordType]),
|
||||
true
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test("returns a valid ISO timestamp", async () => {
|
||||
const result = await lookupDns("example.com");
|
||||
const timestamp = Date.parse(result.checkedAt);
|
||||
|
||||
assert.equal(Number.isNaN(timestamp), false);
|
||||
});
|
||||
@@ -0,0 +1,115 @@
|
||||
// Import Node's built-in test tools.
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert/strict");
|
||||
|
||||
// Import the function we want to test.
|
||||
const {
|
||||
validateHostname,
|
||||
} = require("../src/middleware/validateHostname");
|
||||
|
||||
test("accepts a normal hostname", () => {
|
||||
assert.equal(validateHostname("example.com"), "example.com");
|
||||
});
|
||||
|
||||
test("normalizes uppercase letters", () => {
|
||||
assert.equal(validateHostname("EXAMPLE.COM"), "example.com");
|
||||
});
|
||||
|
||||
test("trims surrounding spaces", () => {
|
||||
assert.equal(validateHostname(" example.com "), "example.com");
|
||||
});
|
||||
|
||||
test("extracts the hostname from an HTTPS URL", () => {
|
||||
assert.equal(
|
||||
validateHostname("https://example.com/some/page"),
|
||||
"example.com"
|
||||
);
|
||||
});
|
||||
|
||||
test("extracts the hostname from an HTTP URL", () => {
|
||||
assert.equal(
|
||||
validateHostname("http://sub.example.com/path"),
|
||||
"sub.example.com"
|
||||
);
|
||||
});
|
||||
|
||||
test("removes a trailing period", () => {
|
||||
assert.equal(validateHostname("example.com."), "example.com");
|
||||
});
|
||||
|
||||
test("accepts subdomains", () => {
|
||||
assert.equal(
|
||||
validateHostname("api.tools.example.com"),
|
||||
"api.tools.example.com"
|
||||
);
|
||||
});
|
||||
|
||||
test("rejects an empty hostname", () => {
|
||||
assert.throws(
|
||||
() => validateHostname(""),
|
||||
/A hostname is required/
|
||||
);
|
||||
});
|
||||
|
||||
test("rejects whitespace-only input", () => {
|
||||
assert.throws(
|
||||
() => validateHostname(" "),
|
||||
/A hostname is required/
|
||||
);
|
||||
});
|
||||
|
||||
test("rejects non-string input", () => {
|
||||
assert.throws(
|
||||
() => validateHostname(null),
|
||||
/A hostname is required/
|
||||
);
|
||||
});
|
||||
|
||||
test("rejects malformed hostnames", () => {
|
||||
assert.throws(
|
||||
() => validateHostname("not a real hostname"),
|
||||
/Enter a valid public hostname/
|
||||
);
|
||||
});
|
||||
|
||||
test("rejects hostnames beginning with a hyphen", () => {
|
||||
assert.throws(
|
||||
() => validateHostname("-example.com"),
|
||||
/Enter a valid public hostname/
|
||||
);
|
||||
});
|
||||
|
||||
test("rejects hostnames ending with a hyphen", () => {
|
||||
assert.throws(
|
||||
() => validateHostname("example-.com"),
|
||||
/Enter a valid public hostname/
|
||||
);
|
||||
});
|
||||
|
||||
test("rejects localhost", () => {
|
||||
assert.throws(
|
||||
() => validateHostname("localhost"),
|
||||
/Enter a valid public hostname/
|
||||
);
|
||||
});
|
||||
|
||||
test("rejects localhost subdomains", () => {
|
||||
assert.throws(
|
||||
() => validateHostname("test.localhost"),
|
||||
/Local hostnames are not allowed/
|
||||
);
|
||||
});
|
||||
|
||||
test("rejects .local hostnames", () => {
|
||||
assert.throws(
|
||||
() => validateHostname("printer.local"),
|
||||
/Local hostnames are not allowed/
|
||||
);
|
||||
});
|
||||
|
||||
test("rejects an invalid URL", () => {
|
||||
assert.throws(
|
||||
() => validateHostname("https://"),
|
||||
/Enter a valid hostname or website URL/
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user