78 lines
2.8 KiB
TypeScript
78 lines
2.8 KiB
TypeScript
import { describe, expect, test } from 'vitest';
|
|
import fc from 'fast-check';
|
|
import {
|
|
isDnsDomain,
|
|
normalizeDomain,
|
|
validateDnsDomain,
|
|
} from '../../bin/utils/domainValidator';
|
|
|
|
describe('domainValidator', () => {
|
|
test('normalizes protocol and a single trailing slash', () => {
|
|
expect(normalizeDomain('https://example.com/')).toBe('example.com');
|
|
expect(normalizeDomain('http://demo.pinme/')).toBe('demo.pinme');
|
|
expect(normalizeDomain('xhttps://example.com/')).toBe(
|
|
'xhttps://example.com',
|
|
);
|
|
expect(normalizeDomain('https://example.com/path/')).toBe(
|
|
'example.com/path',
|
|
);
|
|
});
|
|
|
|
test('detects DNS domains after normalization', () => {
|
|
expect(isDnsDomain('https://example.com/')).toBe(true);
|
|
expect(isDnsDomain('my-site')).toBe(false);
|
|
});
|
|
|
|
test('accepts complete DNS domains', () => {
|
|
expect(validateDnsDomain('example.com')).toEqual({ valid: true });
|
|
expect(validateDnsDomain('sub.example.co')).toEqual({ valid: true });
|
|
});
|
|
|
|
test('rejects incomplete and malformed DNS domains', () => {
|
|
expect(validateDnsDomain('localhost').valid).toBe(false);
|
|
expect(validateDnsDomain('example..com').message).toMatch(/Consecutive/);
|
|
expect(validateDnsDomain('-example.com').message).toMatch(/hyphens/);
|
|
expect(validateDnsDomain('example-.com').message).toMatch(/hyphens/);
|
|
expect(validateDnsDomain('exa_mple.com').message).toMatch(
|
|
/letters, numbers, and hyphens/,
|
|
);
|
|
expect(validateDnsDomain('example.com.evil1').valid).toBe(false);
|
|
expect(validateDnsDomain('prefix example.com').valid).toBe(false);
|
|
expect(validateDnsDomain('example.com/path').valid).toBe(false);
|
|
expect(validateDnsDomain('example.com?x=1').valid).toBe(false);
|
|
});
|
|
|
|
test('rejects labels longer than 63 characters', () => {
|
|
const maxLabel = 'a'.repeat(63);
|
|
const longLabel = 'a'.repeat(64);
|
|
expect(validateDnsDomain(`${maxLabel}.com`).valid).toBe(true);
|
|
expect(validateDnsDomain(`${longLabel}.com`).message).toMatch(
|
|
/63 characters/,
|
|
);
|
|
});
|
|
|
|
test('rejects empty labels in multiple positions', () => {
|
|
expect(validateDnsDomain('.example.com').message).toMatch(/Consecutive/);
|
|
expect(validateDnsDomain('example.com.').message).toMatch(/Consecutive/);
|
|
expect(validateDnsDomain('example...com').message).toMatch(/Consecutive/);
|
|
});
|
|
|
|
test('property: valid simple domains are accepted', () => {
|
|
fc.assert(
|
|
fc.property(
|
|
fc.array(fc.stringMatching(/^[a-z0-9]([a-z0-9-]{0,10}[a-z0-9])?$/), {
|
|
minLength: 1,
|
|
maxLength: 3,
|
|
}),
|
|
fc.stringMatching(/^[a-z]{2,10}$/),
|
|
(labels, tld) => {
|
|
fc.pre(labels.every((label) => label.length > 0));
|
|
expect(validateDnsDomain([...labels, tld].join('.')).valid).toBe(
|
|
true,
|
|
);
|
|
},
|
|
),
|
|
);
|
|
});
|
|
});
|