Coverage for tld/tests/test_core.py: 91%

289 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-05-27 05:40 +0000

1# -*- coding: utf-8 -*- 

2 

3import copy 

4import logging 

5import unittest 

6from os.path import abspath, join 

7from tempfile import gettempdir 

8from typing import Type 

9from urllib.parse import SplitResult, urlsplit 

10 

11from faker import Faker # type: ignore 

12 

13from .. import defaults 

14from ..base import BaseTLDSourceParser, Registry 

15from ..conf import get_setting, reset_settings, set_setting 

16from ..exceptions import ( 

17 TldBadUrl, 

18 TldDomainNotFound, 

19 TldImproperlyConfigured, 

20 TldIOError, 

21) 

22from ..helpers import project_dir 

23from ..utils import ( 

24 BaseMozillaTLDSourceParser, 

25 MozillaTLDSourceParser, 

26 get_fld, 

27 get_tld, 

28 get_tld_names, 

29 get_tld_names_container, 

30 is_tld, 

31 parse_tld, 

32 reset_tld_names, 

33 update_tld_names, 

34 update_tld_names_cli, 

35) 

36from .base import internet_available_only, log_info 

37 

38__author__ = "Artur Barseghyan" 

39__copyright__ = "2013-2023 Artur Barseghyan" 

40__license__ = "MPL-1.1 OR GPL-2.0-only OR LGPL-2.1-or-later" 

41__all__ = ("TestCore",) 

42 

43LOGGER = logging.getLogger(__name__) 

44 

45 

46class TestCore(unittest.TestCase): 

47 """Core tld functionality tests.""" 

48 

49 @classmethod 

50 def setUpClass(cls): 

51 cls.faker = Faker() 

52 cls.temp_dir = gettempdir() 

53 

54 def setUp(self): 

55 """Set up.""" 

56 self.good_patterns = [ 

57 { 

58 "url": "http://www.google.co.uk", 

59 "fld": "google.co.uk", 

60 "subdomain": "www", 

61 "domain": "google", 

62 "suffix": "co.uk", 

63 "tld": "co.uk", 

64 "kwargs": {"fail_silently": True}, 

65 }, 

66 { 

67 "url": "http://www.v2.google.co.uk", 

68 "fld": "google.co.uk", 

69 "subdomain": "www.v2", 

70 "domain": "google", 

71 "suffix": "co.uk", 

72 "tld": "co.uk", 

73 "kwargs": {"fail_silently": True}, 

74 }, 

75 # No longer valid 

76 # { 

77 # 'url': 'http://www.me.congresodelalengua3.ar', 

78 # 'tld': 'me.congresodelalengua3.ar', 

79 # 'subdomain': 'www', 

80 # 'domain': 'me', 

81 # 'suffix': 'congresodelalengua3.ar', 

82 # }, 

83 { 

84 "url": "http://хром.гугл.рф", 

85 "fld": "гугл.рф", 

86 "subdomain": "хром", 

87 "domain": "гугл", 

88 "suffix": "рф", 

89 "tld": "рф", 

90 "kwargs": {"fail_silently": True}, 

91 }, 

92 { 

93 "url": "http://www.google.co.uk:8001/lorem-ipsum/", 

94 "fld": "google.co.uk", 

95 "subdomain": "www", 

96 "domain": "google", 

97 "suffix": "co.uk", 

98 "tld": "co.uk", 

99 "kwargs": {"fail_silently": True}, 

100 }, 

101 { 

102 "url": "http://www.me.cloudfront.net", 

103 "fld": "me.cloudfront.net", 

104 "subdomain": "www", 

105 "domain": "me", 

106 "suffix": "cloudfront.net", 

107 "tld": "cloudfront.net", 

108 "kwargs": {"fail_silently": True}, 

109 }, 

110 { 

111 "url": "http://www.v2.forum.tech.google.co.uk:8001/" 

112 "lorem-ipsum/", 

113 "fld": "google.co.uk", 

114 "subdomain": "www.v2.forum.tech", 

115 "domain": "google", 

116 "suffix": "co.uk", 

117 "tld": "co.uk", 

118 "kwargs": {"fail_silently": True}, 

119 }, 

120 { 

121 "url": "https://pantheon.io/", 

122 "fld": "pantheon.io", 

123 "subdomain": "", 

124 "domain": "pantheon", 

125 "suffix": "io", 

126 "tld": "io", 

127 "kwargs": {"fail_silently": True}, 

128 }, 

129 { 

130 "url": "v2.www.google.com", 

131 "fld": "google.com", 

132 "subdomain": "v2.www", 

133 "domain": "google", 

134 "suffix": "com", 

135 "tld": "com", 

136 "kwargs": {"fail_silently": True, "fix_protocol": True}, 

137 }, 

138 { 

139 "url": "//v2.www.google.com", 

140 "fld": "google.com", 

141 "subdomain": "v2.www", 

142 "domain": "google", 

143 "suffix": "com", 

144 "tld": "com", 

145 "kwargs": {"fail_silently": True, "fix_protocol": True}, 

146 }, 

147 { 

148 "url": "http://foo@bar.com", 

149 "fld": "bar.com", 

150 "subdomain": "", 

151 "domain": "bar", 

152 "suffix": "com", 

153 "tld": "com", 

154 "kwargs": {"fail_silently": True}, 

155 }, 

156 { 

157 "url": "http://user:foo@bar.com", 

158 "fld": "bar.com", 

159 "subdomain": "", 

160 "domain": "bar", 

161 "suffix": "com", 

162 "tld": "com", 

163 "kwargs": {"fail_silently": True}, 

164 }, 

165 { 

166 "url": "https://faguoren.xn--fiqs8s", 

167 "fld": "faguoren.xn--fiqs8s", 

168 "subdomain": "", 

169 "domain": "faguoren", 

170 "suffix": "xn--fiqs8s", 

171 "tld": "xn--fiqs8s", 

172 "kwargs": {"fail_silently": True}, 

173 }, 

174 { 

175 "url": "blogs.lemonde.paris", 

176 "fld": "lemonde.paris", 

177 "subdomain": "blogs", 

178 "domain": "lemonde", 

179 "suffix": "paris", 

180 "tld": "paris", 

181 "kwargs": {"fail_silently": True, "fix_protocol": True}, 

182 }, 

183 { 

184 "url": "axel.brighton.ac.uk", 

185 "fld": "brighton.ac.uk", 

186 "subdomain": "axel", 

187 "domain": "brighton", 

188 "suffix": "ac.uk", 

189 "tld": "ac.uk", 

190 "kwargs": {"fail_silently": True, "fix_protocol": True}, 

191 }, 

192 { 

193 "url": "m.fr.blogspot.com.au", 

194 "fld": "fr.blogspot.com.au", 

195 "subdomain": "m", 

196 "domain": "fr", 

197 "suffix": "blogspot.com.au", 

198 "tld": "blogspot.com.au", 

199 "kwargs": {"fail_silently": True, "fix_protocol": True}, 

200 }, 

201 { 

202 "url": "help.www.福岡.jp", 

203 "fld": "www.福岡.jp", 

204 "subdomain": "help", 

205 "domain": "www", 

206 "suffix": "福岡.jp", 

207 "tld": "福岡.jp", 

208 "kwargs": {"fail_silently": True, "fix_protocol": True}, 

209 }, 

210 { 

211 "url": "syria.arabic.variant.سوريا", 

212 "fld": "variant.سوريا", 

213 "subdomain": "syria.arabic", 

214 "domain": "variant", 

215 "suffix": "سوريا", 

216 "tld": "سوريا", 

217 "kwargs": {"fail_silently": True, "fix_protocol": True}, 

218 }, 

219 { 

220 "url": "http://www.help.kawasaki.jp", 

221 "fld": "www.help.kawasaki.jp", 

222 "subdomain": "", 

223 "domain": "www", 

224 "suffix": "help.kawasaki.jp", 

225 "tld": "help.kawasaki.jp", 

226 "kwargs": {"fail_silently": True}, 

227 }, 

228 { 

229 "url": "http://www.city.kawasaki.jp", 

230 "fld": "city.kawasaki.jp", 

231 "subdomain": "www", 

232 "domain": "city", 

233 "suffix": "kawasaki.jp", 

234 "tld": "kawasaki.jp", 

235 "kwargs": {"fail_silently": True}, 

236 }, 

237 { 

238 "url": "http://fedoraproject.org", 

239 "fld": "fedoraproject.org", 

240 "subdomain": "", 

241 "domain": "fedoraproject", 

242 "suffix": "org", 

243 "tld": "org", 

244 "kwargs": {"fail_silently": True}, 

245 }, 

246 { 

247 "url": "http://www.cloud.fedoraproject.org", 

248 "fld": "www.cloud.fedoraproject.org", 

249 "subdomain": "", 

250 "domain": "www", 

251 "suffix": "cloud.fedoraproject.org", 

252 "tld": "cloud.fedoraproject.org", 

253 "kwargs": {"fail_silently": True}, 

254 }, 

255 { 

256 "url": "https://www.john.app.os.fedoraproject.org", 

257 "fld": "john.app.os.fedoraproject.org", 

258 "subdomain": "www", 

259 "domain": "john", 

260 "suffix": "app.os.fedoraproject.org", 

261 "tld": "app.os.fedoraproject.org", 

262 "kwargs": {"fail_silently": True}, 

263 }, 

264 { 

265 "url": "ftp://www.xn--mxail5aa.xn--11b4c3d", 

266 "fld": "xn--mxail5aa.xn--11b4c3d", 

267 "subdomain": "www", 

268 "domain": "xn--mxail5aa", 

269 "suffix": "xn--11b4c3d", 

270 "tld": "xn--11b4c3d", 

271 "kwargs": {"fail_silently": True}, 

272 }, 

273 { 

274 "url": "http://cloud.fedoraproject.org", 

275 "fld": "cloud.fedoraproject.org", 

276 "subdomain": "", 

277 "domain": "cloud.fedoraproject.org", 

278 "suffix": "cloud.fedoraproject.org", 

279 "tld": "cloud.fedoraproject.org", 

280 "kwargs": {"fail_silently": True}, 

281 }, 

282 { 

283 "url": "github.io", 

284 "fld": "github.io", 

285 "subdomain": "", 

286 "domain": "github.io", 

287 "suffix": "github.io", 

288 "tld": "github.io", 

289 "kwargs": {"fail_silently": True, "fix_protocol": True}, 

290 }, 

291 { 

292 "url": urlsplit("http://lemonde.fr/article.html"), 

293 "fld": "lemonde.fr", 

294 "subdomain": "", 

295 "domain": "lemonde", 

296 "suffix": "fr", 

297 "tld": "fr", 

298 "kwargs": {"fail_silently": True}, 

299 }, 

300 { 

301 "url": "https://github.com....../barseghyanartur/tld/", 

302 "fld": "github.com", 

303 "subdomain": "", 

304 "domain": "github", 

305 "suffix": "com", 

306 "tld": "com", 

307 "kwargs": {"fail_silently": True}, 

308 }, 

309 ] 

310 

311 self.bad_patterns = { 

312 "v2.www.google.com": { 

313 "exception": TldBadUrl, 

314 }, 

315 "/index.php?a=1&b=2": { 

316 "exception": TldBadUrl, 

317 }, 

318 "http://www.tld.doesnotexist": { 

319 "exception": TldDomainNotFound, 

320 }, 

321 "https://2001:0db8:0000:85a3:0000:0000:ac1f:8001": { 

322 "exception": TldDomainNotFound, 

323 }, 

324 "http://192.169.1.1": { 

325 "exception": TldDomainNotFound, 

326 }, 

327 "http://localhost:8080": { 

328 "exception": TldDomainNotFound, 

329 }, 

330 "https://localhost": { 

331 "exception": TldDomainNotFound, 

332 }, 

333 "https://localhost2": { 

334 "exception": TldImproperlyConfigured, 

335 "kwargs": {"search_public": False, "search_private": False}, 

336 }, 

337 } 

338 

339 self.invalid_tlds = { 

340 "v2.www.google.com", 

341 "tld.doesnotexist", 

342 "2001:0db8:0000:85a3:0000:0000:ac1f", 

343 "192.169.1.1", 

344 "localhost", 

345 "google.com", 

346 } 

347 

348 self.tld_names_local_path_custom = project_dir( 

349 join("tests", "res", "effective_tld_names_custom.dat.txt") 

350 ) 

351 self.good_patterns_custom_parser = [ 

352 { 

353 "url": "http://www.foreverchild", 

354 "fld": "www.foreverchild", 

355 "subdomain": "", 

356 "domain": "www", 

357 "suffix": "foreverchild", 

358 "tld": "foreverchild", 

359 "kwargs": { 

360 "fail_silently": True, 

361 # 'parser_class': self.get_custom_parser_class(), 

362 }, 

363 }, 

364 { 

365 "url": "http://www.v2.foreverchild", 

366 "fld": "v2.foreverchild", 

367 "subdomain": "www", 

368 "domain": "v2", 

369 "suffix": "foreverchild", 

370 "tld": "foreverchild", 

371 "kwargs": { 

372 "fail_silently": True, 

373 # 'parser_class': self.get_custom_parser_class(), 

374 }, 

375 }, 

376 ] 

377 reset_settings() 

378 

379 def tearDown(self): 

380 """Tear down.""" 

381 reset_settings() 

382 Registry.reset() 

383 

384 @property 

385 def good_url(self): 

386 return self.good_patterns[0]["url"] 

387 

388 @property 

389 def bad_url(self): 

390 return list(self.bad_patterns.keys())[0] 

391 

392 def get_custom_parser_class( 

393 self, 

394 uid: str = "custom_mozilla", 

395 source_url: str = None, 

396 local_path: str = "tests/res/effective_tld_names_custom.dat.txt", 

397 ) -> Type[BaseTLDSourceParser]: 

398 # Define a custom TLD source parser class 

399 parser_class = type( 

400 "CustomMozillaTLDSourceParser", 

401 (BaseMozillaTLDSourceParser,), 

402 { 

403 "uid": uid, 

404 "source_url": source_url, 

405 "local_path": local_path, 

406 }, 

407 ) 

408 return parser_class 

409 

410 @log_info 

411 def test_0_tld_names_loaded(self): 

412 """Test if tld names are loaded.""" 

413 get_fld("http://www.google.co.uk") 

414 from ..utils import tld_names 

415 

416 res = len(tld_names) > 0 

417 self.assertTrue(res) 

418 return res 

419 

420 @internet_available_only 

421 @log_info 

422 def test_1_update_tld_names(self): 

423 """Test updating the tld names (re-fetch mozilla source).""" 

424 res = update_tld_names(fail_silently=False) 

425 self.assertTrue(res) 

426 return res 

427 

428 @log_info 

429 def test_2_fld_good_patterns_pass(self): 

430 """Test good URL patterns.""" 

431 res = [] 

432 for data in self.good_patterns: 

433 _res = get_fld(data["url"], **data["kwargs"]) 

434 self.assertEqual(_res, data["fld"]) 

435 res.append(_res) 

436 return res 

437 

438 @log_info 

439 def test_3_fld_bad_patterns_pass(self): 

440 """Test bad URL patterns.""" 

441 res = [] 

442 for url, params in self.bad_patterns.items(): 

443 _res = get_fld(url, fail_silently=True) 

444 self.assertEqual(_res, None) 

445 res.append(_res) 

446 return res 

447 

448 @log_info 

449 def test_4_override_settings(self): 

450 """Testing settings override.""" 

451 

452 def override_settings(): 

453 """Override settings.""" 

454 return get_setting("DEBUG") 

455 

456 self.assertEqual(defaults.DEBUG, override_settings()) 

457 

458 set_setting("DEBUG", True) 

459 

460 self.assertEqual(True, override_settings()) 

461 

462 return override_settings() 

463 

464 @log_info 

465 def test_5_tld_good_patterns_pass_parsed_object(self): 

466 """Test good URL patterns.""" 

467 res = [] 

468 for data in self.good_patterns: 

469 kwargs = copy.copy(data["kwargs"]) 

470 kwargs["as_object"] = True 

471 _res = get_tld(data["url"], **kwargs) 

472 self.assertEqual(_res.tld, data["tld"]) 

473 self.assertEqual(_res.subdomain, data["subdomain"]) 

474 self.assertEqual(_res.domain, data["domain"]) 

475 self.assertEqual(_res.suffix, data["suffix"]) 

476 self.assertEqual(_res.fld, data["fld"]) 

477 

478 self.assertEqual( 

479 str(_res).encode("utf8"), data["tld"].encode("utf8") 

480 ) 

481 

482 self.assertEqual( 

483 _res.__dict__, 

484 { 

485 "tld": _res.tld, 

486 "domain": _res.domain, 

487 "subdomain": _res.subdomain, 

488 "fld": _res.fld, 

489 "parsed_url": _res.parsed_url, 

490 }, 

491 ) 

492 

493 res.append(_res) 

494 return res 

495 

496 @log_info 

497 def test_6_override_full_names_path(self): 

498 default = project_dir("dummy.txt") 

499 override_base = "/tmp/test" 

500 set_setting("NAMES_LOCAL_PATH_PARENT", override_base) 

501 modified = project_dir("dummy.txt") 

502 self.assertNotEqual(default, modified) 

503 self.assertEqual(modified, abspath("/tmp/test/dummy.txt")) 

504 

505 @log_info 

506 def test_7_public_private(self): 

507 res = get_fld( 

508 "http://silly.cc.ua", 

509 fail_silently=True, 

510 search_private=False, 

511 parser_class=MozillaTLDSourceParser, 

512 ) 

513 self.assertEqual(res, None) 

514 

515 res = get_fld( 

516 "http://silly.cc.ua", fail_silently=True, search_private=False 

517 ) 

518 self.assertEqual(res, "cc.ua") 

519 

520 res = get_fld( 

521 "http://silly.cc.ua", fail_silently=True, search_private=True 

522 ) 

523 self.assertEqual(res, "silly.cc.ua") 

524 

525 res = get_fld( 

526 "mercy.compute.amazonaws.com", 

527 fail_silently=True, 

528 search_private=False, 

529 fix_protocol=True, 

530 parser_class=MozillaTLDSourceParser, 

531 ) 

532 self.assertEqual(res, None) 

533 

534 res = get_fld( 

535 "mercy.compute.amazonaws.com", 

536 fail_silently=True, 

537 search_private=False, 

538 fix_protocol=True, 

539 ) 

540 self.assertEqual(res, "amazonaws.com") 

541 

542 res = get_fld( 

543 "http://whatever.com", fail_silently=True, search_public=False 

544 ) 

545 self.assertEqual(res, None) 

546 

547 @log_info 

548 def test_8_fld_bad_patterns_exceptions(self): 

549 """Test exceptions.""" 

550 res = [] 

551 for url, params in self.bad_patterns.items(): 

552 kwargs = params["kwargs"] if "kwargs" in params else {} 

553 kwargs["fail_silently"] = False 

554 with self.assertRaises(params["exception"]): 

555 _res = get_fld(url, **kwargs) 

556 res.append(_res) 

557 return res 

558 

559 @log_info 

560 def test_9_tld_good_patterns_pass(self): 

561 """Test `get_tld` good URL patterns.""" 

562 res = [] 

563 for data in self.good_patterns: 

564 _res = get_tld(data["url"], **data["kwargs"]) 

565 self.assertEqual(_res, data["tld"]) 

566 res.append(_res) 

567 return res 

568 

569 @log_info 

570 def test_10_tld_bad_patterns_pass(self): 

571 """Test `get_tld` bad URL patterns.""" 

572 res = [] 

573 for url, params in self.bad_patterns.items(): 

574 _res = get_tld(url, fail_silently=True) 

575 self.assertEqual(_res, None) 

576 res.append(_res) 

577 return res 

578 

579 @log_info 

580 def test_11_parse_tld_good_patterns(self): 

581 """Test `parse_tld` good URL patterns.""" 

582 res = [] 

583 for data in self.good_patterns: 

584 _res = parse_tld(data["url"], **data["kwargs"]) 

585 self.assertEqual( 

586 _res, (data["tld"], data["domain"], data["subdomain"]) 

587 ) 

588 res.append(_res) 

589 return res 

590 

591 @log_info 

592 def test_12_is_tld_good_patterns(self): 

593 """Test `is_tld` good URL patterns.""" 

594 for data in self.good_patterns: 

595 self.assertTrue(is_tld(data["tld"])) 

596 

597 @log_info 

598 def test_13_is_tld_bad_patterns(self): 

599 """Test `is_tld` bad URL patterns.""" 

600 for _tld in self.invalid_tlds: 

601 self.assertFalse(is_tld(_tld)) 

602 

603 @log_info 

604 def test_14_fail_update_tld_names(self): 

605 """Test fail `update_tld_names`.""" 

606 parser_class = self.get_custom_parser_class( 

607 uid="custom_mozilla_2", source_url="i-do-not-exist" 

608 ) 

609 # Assert raise TldIOError on wrong NAMES_SOURCE_URL 

610 with self.assertRaises(TldIOError): 

611 update_tld_names(fail_silently=False, parser_uid=parser_class.uid) 

612 

613 # Assert return False on wrong NAMES_SOURCE_URL 

614 self.assertFalse( 

615 update_tld_names(fail_silently=True, parser_uid=parser_class.uid) 

616 ) 

617 

618 @log_info 

619 def test_15_fail_get_tld_names(self): 

620 """Test fail `update_tld_names`.""" 

621 parser_class = self.get_custom_parser_class( 

622 uid="custom_mozilla_3", 

623 source_url="i-do-not-exist", 

624 local_path="/srv/tests/res/effective_tld_names_custom_3.dat.txt", 

625 ) 

626 reset_tld_names() 

627 # Assert raise TldIOError on wrong NAMES_SOURCE_URL 

628 for params in self.good_patterns: 

629 kwargs = {"url": params["url"]} 

630 kwargs.update(params["kwargs"]) 

631 kwargs["fail_silently"] = False 

632 kwargs["parser_class"] = parser_class 

633 with self.assertRaises(TldIOError): 

634 get_tld(**kwargs) 

635 

636 @log_info 

637 def test_16_fail_get_fld_wrong_kwargs(self): 

638 """Test fail `get_fld` with wrong kwargs.""" 

639 with self.assertRaises(TldImproperlyConfigured): 

640 get_fld(self.good_url, as_object=True) 

641 

642 @log_info 

643 def test_17_fail_parse_tld(self): 

644 """Test fail `parse_tld`. 

645 

646 Assert raise TldIOError on wrong `NAMES_SOURCE_URL` for `parse_tld`. 

647 """ 

648 parser_class = self.get_custom_parser_class(source_url="i-do-not-exist") 

649 parsed_tld = parse_tld( 

650 self.bad_url, fail_silently=False, parser_class=parser_class 

651 ) 

652 self.assertEqual(parsed_tld, (None, None, None)) 

653 

654 @log_info 

655 def test_18_get_tld_names_and_reset_tld_names(self): 

656 """Test fail `get_tld_names` and repair using `reset_tld_names`.""" 

657 tmp_filename = join(gettempdir(), f"{self.faker.uuid4()}.dat.txt") 

658 parser_class = self.get_custom_parser_class( 

659 source_url="i-do-not-exist", local_path=tmp_filename 

660 ) 

661 reset_tld_names() 

662 

663 with self.subTest("Assert raise TldIOError"): 

664 # Assert raise TldIOError on wrong NAMES_SOURCE_URL for 

665 # `get_tld_names` 

666 with self.assertRaises(TldIOError): 

667 get_tld_names(fail_silently=False, parser_class=parser_class) 

668 

669 tmp_filename = join(gettempdir(), f"{self.faker.uuid4()}.dat.txt") 

670 parser_class_2 = self.get_custom_parser_class( 

671 source_url="i-do-not-exist-2", local_path=tmp_filename 

672 ) 

673 reset_tld_names() 

674 

675 with self.subTest("Assert get None"): 

676 # Assert get None on wrong `NAMES_SOURCE_URL` for `get_tld_names` 

677 self.assertIsNone( 

678 get_tld_names(fail_silently=True, parser_class=parser_class_2) 

679 ) 

680 

681 @internet_available_only 

682 @log_info 

683 def test_19_update_tld_names_cli(self): 

684 """Test the return code of the CLI version of `update_tld_names`.""" 

685 reset_tld_names() 

686 res = update_tld_names_cli() 

687 self.assertEqual(res, 0) 

688 

689 @log_info 

690 def test_20_parse_tld_custom_tld_names_good_patterns(self): 

691 """Test `parse_tld` good URL patterns for custom tld names.""" 

692 res = [] 

693 

694 for data in self.good_patterns_custom_parser: 

695 kwargs = copy.copy(data["kwargs"]) 

696 kwargs["parser_class"] = self.get_custom_parser_class() 

697 _res = parse_tld(data["url"], **kwargs) 

698 self.assertEqual( 

699 _res, (data["tld"], data["domain"], data["subdomain"]) 

700 ) 

701 res.append(_res) 

702 return res 

703 

704 @log_info 

705 def test_21_tld_custom_tld_names_good_patterns_pass_parsed_object(self): 

706 """Test `get_tld` good URL patterns for custom tld names.""" 

707 res = [] 

708 for data in self.good_patterns_custom_parser: 

709 kwargs = copy.copy(data["kwargs"]) 

710 kwargs.update( 

711 { 

712 "as_object": True, 

713 "parser_class": self.get_custom_parser_class(), 

714 } 

715 ) 

716 _res = get_tld(data["url"], **kwargs) 

717 self.assertEqual(_res.tld, data["tld"]) 

718 self.assertEqual(_res.subdomain, data["subdomain"]) 

719 self.assertEqual(_res.domain, data["domain"]) 

720 self.assertEqual(_res.suffix, data["suffix"]) 

721 self.assertEqual(_res.fld, data["fld"]) 

722 

723 self.assertEqual( 

724 str(_res).encode("utf8"), data["tld"].encode("utf8") 

725 ) 

726 

727 self.assertEqual( 

728 _res.__dict__, 

729 { 

730 "tld": _res.tld, 

731 "domain": _res.domain, 

732 "subdomain": _res.subdomain, 

733 "fld": _res.fld, 

734 "parsed_url": _res.parsed_url, 

735 }, 

736 ) 

737 

738 res.append(_res) 

739 return res 

740 

741 @log_info 

742 def test_22_reset_tld_names_for_custom_parser(self): 

743 """Test `reset_tld_names` for `tld_names_local_path`.""" 

744 res = [] 

745 parser_class = self.get_custom_parser_class() 

746 for data in self.good_patterns_custom_parser: 

747 kwargs = copy.copy(data["kwargs"]) 

748 kwargs.update( 

749 { 

750 "as_object": True, 

751 "parser_class": self.get_custom_parser_class(), 

752 } 

753 ) 

754 _res = get_tld(data["url"], **kwargs) 

755 self.assertEqual(_res.tld, data["tld"]) 

756 self.assertEqual(_res.subdomain, data["subdomain"]) 

757 self.assertEqual(_res.domain, data["domain"]) 

758 self.assertEqual(_res.suffix, data["suffix"]) 

759 self.assertEqual(_res.fld, data["fld"]) 

760 

761 self.assertEqual( 

762 str(_res).encode("utf8"), data["tld"].encode("utf8") 

763 ) 

764 

765 self.assertEqual( 

766 _res.__dict__, 

767 { 

768 "tld": _res.tld, 

769 "domain": _res.domain, 

770 "subdomain": _res.subdomain, 

771 "fld": _res.fld, 

772 "parsed_url": _res.parsed_url, 

773 }, 

774 ) 

775 

776 res.append(_res) 

777 

778 tld_names = get_tld_names_container() 

779 self.assertIn(parser_class.local_path, tld_names) 

780 reset_tld_names(parser_class.local_path) 

781 self.assertNotIn(parser_class.local_path, tld_names) 

782 

783 return res 

784 

785 @log_info 

786 def test_23_fail_define_custom_parser_class_without_uid(self): 

787 """Test fail define custom parser class without `uid`.""" 

788 

789 class CustomParser(BaseTLDSourceParser): 

790 pass 

791 

792 class AnotherCustomParser(BaseTLDSourceParser): 

793 

794 uid = "another-custom-parser" 

795 

796 # Assert raise TldImproperlyConfigured 

797 with self.assertRaises(TldImproperlyConfigured): 

798 CustomParser.get_tld_names() 

799 

800 # Assert raise NotImplementedError 

801 with self.assertRaises(NotImplementedError): 

802 AnotherCustomParser.get_tld_names() 

803 

804 @log_info 

805 def test_24_len_trie_nodes(self): 

806 """Test len of the trie nodes.""" 

807 get_tld("http://delusionalinsanity.com") 

808 tld_names = get_tld_names_container() 

809 self.assertGreater(len(tld_names[MozillaTLDSourceParser.local_path]), 0) 

810 

811 @log_info 

812 def test_25_get_tld_names_no_arguments(self): 

813 """Test len of the trie nodes.""" 

814 tld_names = get_tld_names() 

815 self.assertGreater(len(tld_names), 0) 

816 

817 @log_info 

818 def test_26_case(self): 

819 res = get_tld( 

820 "https://MyDomain.com/AsDrFt?QUeRY=12aA", 

821 fail_silently=True, 

822 search_private=False, 

823 as_object=True, 

824 ) 

825 self.assertEqual(res.tld, "com") 

826 self.assertEqual(res.domain, "mydomain") 

827 self.assertEqual(res.subdomain, "") 

828 self.assertEqual(res.fld, "mydomain.com") 

829 self.assertEqual( 

830 res.parsed_url, 

831 SplitResult( 

832 scheme="https", 

833 netloc="MyDomain.com", 

834 path="/AsDrFt", 

835 query="QUeRY=12aA", 

836 fragment="", 

837 ), 

838 ) 

839 

840 @log_info 

841 def test_27_tld_fail_silently_pass(self): 

842 """Test `get_tld` bad URL patterns that would raise exception 

843 if `fail_silently` isn't `True`. 

844 """ 

845 res = [] 

846 bad_url = ["https://user:password[@host.com", "https://user[@host.com"] 

847 for url in bad_url: 

848 _res = get_tld(url, fail_silently=True) 

849 self.assertEqual(_res, None) 

850 res.append(_res) 

851 return res