tldts-tests 7.3.0 → 7.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/src/tldts-tests.js +102 -0
- package/dist/cjs/src/tldts-tests.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/es6/src/tldts-tests.js +102 -0
- package/dist/es6/src/tldts-tests.js.map +1 -1
- package/dist/es6/tsconfig.bundle.tsbuildinfo +1 -1
- package/dist/types/src/tldts-tests.d.ts +1 -0
- package/package.json +3 -3
- package/src/tldts-tests.ts +149 -0
package/src/tldts-tests.ts
CHANGED
|
@@ -65,6 +65,7 @@ export default function test(
|
|
|
65
65
|
getPublicSuffix: (url: string, options?: Options) => string | null;
|
|
66
66
|
getHostname: (url: string, options?: Options) => string | null;
|
|
67
67
|
getDomain: (url: string, options?: Options) => string | null;
|
|
68
|
+
getFullDomain: (url: string, options?: Options) => string | null;
|
|
68
69
|
getSubdomain: (url: string, options?: Options) => string | null;
|
|
69
70
|
parse: (
|
|
70
71
|
url: string,
|
|
@@ -370,6 +371,25 @@ export default function test(
|
|
|
370
371
|
expect(tldts.getDomain('s_pf.google.com')).to.equal('google.com'); // middle '_' (reference case)
|
|
371
372
|
});
|
|
372
373
|
|
|
374
|
+
// A label must not BEGIN with a hyphen (RFC 1034 §3.5 / RFC 1035 §2.3.1 LDH;
|
|
375
|
+
// cf. WHATWG "valid domain" / UTS #46 CheckHyphens). validateHostname is on by
|
|
376
|
+
// default, so an invalid host yields a null parse — exercised here at the
|
|
377
|
+
// public-API level (the inline-validation fast path). @see issue #2395.
|
|
378
|
+
it('should reject labels that begin with a hyphen', () => {
|
|
379
|
+
expect(tldts.getHostname('foo.-example.com')).to.equal(null); // interior label
|
|
380
|
+
expect(tldts.getHostname('a.b.-c.com')).to.equal(null); // deeper interior label
|
|
381
|
+
expect(tldts.getHostname('foo.-com')).to.equal(null); // final label
|
|
382
|
+
expect(tldts.getDomain('foo.-example.com')).to.equal(null);
|
|
383
|
+
expect(tldts.getHostname('-example.com')).to.equal(null); // first label (already rejected)
|
|
384
|
+
// Interior hyphens and underscore-leading labels stay valid.
|
|
385
|
+
expect(tldts.getHostname('foo.ex-ample.com')).to.equal(
|
|
386
|
+
'foo.ex-ample.com',
|
|
387
|
+
);
|
|
388
|
+
expect(tldts.getHostname('_dmarc.example.com')).to.equal(
|
|
389
|
+
'_dmarc.example.com',
|
|
390
|
+
);
|
|
391
|
+
});
|
|
392
|
+
|
|
373
393
|
// @see https://github.com/oncletom/tld.js/issues/53
|
|
374
394
|
it('should correctly extract domain from paths including "@" in the path', () => {
|
|
375
395
|
const domain = tldts.getDomain(
|
|
@@ -415,6 +435,134 @@ export default function test(
|
|
|
415
435
|
});
|
|
416
436
|
});
|
|
417
437
|
|
|
438
|
+
describe('#getFullDomain', () => {
|
|
439
|
+
it('returns the full hostname (subdomain + domain) for a registrable domain', () => {
|
|
440
|
+
expect(tldts.getFullDomain('foo.bar.example.co.uk')).to.equal(
|
|
441
|
+
'foo.bar.example.co.uk',
|
|
442
|
+
);
|
|
443
|
+
expect(
|
|
444
|
+
tldts.getFullDomain('https://foo.bar.example.co.uk:8080/path?q=1'),
|
|
445
|
+
).to.equal('foo.bar.example.co.uk');
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
it('equals the domain when there is no subdomain', () => {
|
|
449
|
+
expect(tldts.getFullDomain('example.com')).to.equal('example.com');
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
it('normalises like the other extractors (lowercase, trailing dot, userinfo/port)', () => {
|
|
453
|
+
expect(tldts.getFullDomain('FOO.Example.COM.')).to.equal(
|
|
454
|
+
'foo.example.com',
|
|
455
|
+
);
|
|
456
|
+
expect(tldts.getFullDomain('https://user@a.b.example.com:443/')).to.equal(
|
|
457
|
+
'a.b.example.com',
|
|
458
|
+
);
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
it('returns null when there is no registrable domain', () => {
|
|
462
|
+
expect(tldts.getFullDomain('1.2.3.4')).to.equal(null); // IP
|
|
463
|
+
expect(tldts.getFullDomain('localhost')).to.equal(null); // single label
|
|
464
|
+
expect(tldts.getFullDomain('co.uk')).to.equal(null); // public suffix only
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
it('keeps subdomains that are not valid hostnames (#2322 DNS-record use case)', () => {
|
|
468
|
+
expect(
|
|
469
|
+
tldts.getFullDomain('___sip___._tcp.sipdbw06.rcs01.5gm.example.com'),
|
|
470
|
+
).to.equal('___sip___._tcp.sipdbw06.rcs01.5gm.example.com');
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
it('validateHostname:false skips character checks but still requires a public suffix', () => {
|
|
474
|
+
// '!' is rejected by the default hostname validation...
|
|
475
|
+
expect(tldts.getFullDomain('a!b.example.com')).to.equal(null);
|
|
476
|
+
// ...but the registrable domain is still found when validation is off.
|
|
477
|
+
expect(
|
|
478
|
+
tldts.getFullDomain('a!b.example.com', { validateHostname: false }),
|
|
479
|
+
).to.equal('a!b.example.com');
|
|
480
|
+
// A bare label has no registrable domain either way.
|
|
481
|
+
expect(
|
|
482
|
+
tldts.getFullDomain('foo_bar', { validateHostname: false }),
|
|
483
|
+
).to.equal(null);
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
it('is consistent with getHostname gated on getDomain', () => {
|
|
487
|
+
for (const input of [
|
|
488
|
+
'foo.bar.example.co.uk',
|
|
489
|
+
'https://a.b.c.example.com:8080/p',
|
|
490
|
+
'example.com',
|
|
491
|
+
'1.2.3.4',
|
|
492
|
+
'localhost',
|
|
493
|
+
'co.uk',
|
|
494
|
+
]) {
|
|
495
|
+
const expected =
|
|
496
|
+
tldts.getDomain(input) === null ? null : tldts.getHostname(input);
|
|
497
|
+
expect(tldts.getFullDomain(input)).to.equal(expected);
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
it('avoids the getSubdomain + getDomain join footgun', () => {
|
|
502
|
+
// The naive `getSubdomain(x) + '.' + getDomain(x)` recipe emits a spurious
|
|
503
|
+
// leading dot when there is no subdomain; getFullDomain does not.
|
|
504
|
+
expect(tldts.getFullDomain('example.com')).to.equal('example.com');
|
|
505
|
+
expect(
|
|
506
|
+
`${tldts.getSubdomain('example.com')}.${tldts.getDomain('example.com')}`,
|
|
507
|
+
).to.equal('.example.com'); // the footgun, shown for contrast
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
it('honors the validHosts option', () => {
|
|
511
|
+
expect(
|
|
512
|
+
tldts.getFullDomain('vhost.intranet', { validHosts: ['intranet'] }),
|
|
513
|
+
).to.equal('vhost.intranet');
|
|
514
|
+
expect(
|
|
515
|
+
tldts.getFullDomain('intranet', { validHosts: ['intranet'] }),
|
|
516
|
+
).to.equal('intranet');
|
|
517
|
+
// Without it, a bare unknown single label has no registrable domain.
|
|
518
|
+
expect(tldts.getFullDomain('intranet')).to.equal(null);
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
it('honors allowPrivateDomains (private-suffix gating)', () => {
|
|
522
|
+
// github.io is in the PRIVATE section: by default it is a registrable
|
|
523
|
+
// domain in every build.
|
|
524
|
+
expect(tldts.getFullDomain('github.io')).to.equal('github.io');
|
|
525
|
+
// Once private suffixes count it becomes a bare suffix (=> null). Only
|
|
526
|
+
// meaningful for builds that ship the PRIVATE section (not tldts-icann).
|
|
527
|
+
if (includePrivate) {
|
|
528
|
+
expect(
|
|
529
|
+
tldts.getFullDomain('github.io', { allowPrivateDomains: true }),
|
|
530
|
+
).to.equal(null);
|
|
531
|
+
expect(
|
|
532
|
+
tldts.getFullDomain('user.github.io', { allowPrivateDomains: true }),
|
|
533
|
+
).to.equal('user.github.io');
|
|
534
|
+
}
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
it('handles wildcard and exception public-suffix rules', () => {
|
|
538
|
+
expect(tldts.getFullDomain('foo.bar.ck')).to.equal('foo.bar.ck'); // *.ck
|
|
539
|
+
expect(tldts.getFullDomain('foo.ck')).to.equal(null); // bare *.ck suffix
|
|
540
|
+
expect(tldts.getFullDomain('a.www.ck')).to.equal('a.www.ck'); // !www.ck
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
it('preserves IDN / punycode labels without conversion', () => {
|
|
544
|
+
expect(tldts.getFullDomain('a.münchen.de')).to.equal('a.münchen.de');
|
|
545
|
+
expect(tldts.getFullDomain('a.xn--mnchen-3ya.de')).to.equal(
|
|
546
|
+
'a.xn--mnchen-3ya.de',
|
|
547
|
+
);
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
it('returns null for IP addresses (no registrable domain)', () => {
|
|
551
|
+
expect(tldts.getFullDomain('http://[2a01:e35::1]:443/x')).to.equal(null);
|
|
552
|
+
expect(tldts.getFullDomain('2a01:e35::1')).to.equal(null);
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
it('respects the 255-character hostname length limit', () => {
|
|
556
|
+
const label = 'a'.repeat(63);
|
|
557
|
+
const max = `${label}.${label}.${label}.${'a'.repeat(59)}.com`;
|
|
558
|
+
expect(max).to.have.lengthOf(255);
|
|
559
|
+
expect(tldts.getFullDomain(max)).to.equal(max);
|
|
560
|
+
const tooLong = `${label}.${label}.${label}.${'a'.repeat(60)}.com`;
|
|
561
|
+
expect(tooLong).to.have.lengthOf(256);
|
|
562
|
+
expect(tldts.getFullDomain(tooLong)).to.equal(null);
|
|
563
|
+
});
|
|
564
|
+
});
|
|
565
|
+
|
|
418
566
|
describe('#getPublicSuffix', () => {
|
|
419
567
|
if (includePrivate) {
|
|
420
568
|
describe('allowPrivateDomains', () => {
|
|
@@ -1722,6 +1870,7 @@ export default function test(
|
|
|
1722
1870
|
expect(tldts.parse(url)).to.deep.equal(tldts.parse(url, {}));
|
|
1723
1871
|
expect(tldts.getHostname(url)).to.equal(tldts.getHostname(url, {}));
|
|
1724
1872
|
expect(tldts.getDomain(url)).to.equal(tldts.getDomain(url, {}));
|
|
1873
|
+
expect(tldts.getFullDomain(url)).to.equal(tldts.getFullDomain(url, {}));
|
|
1725
1874
|
expect(tldts.getPublicSuffix(url)).to.equal(
|
|
1726
1875
|
tldts.getPublicSuffix(url, {}),
|
|
1727
1876
|
);
|