From 16e0bd06751e2f0179be06fd1812faced4be662d Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Sat, 20 Aug 2022 11:55:19 -0700 Subject: [PATCH] Testing of Zone and Record name/decoded_name handling --- octodns/zone.py | 4 ++-- tests/test_octodns_record.py | 13 +++++++++++++ tests/test_octodns_zone.py | 29 +++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/octodns/zone.py b/octodns/zone.py index 726373c..6ec54fb 100644 --- a/octodns/zone.py +++ b/octodns/zone.py @@ -13,7 +13,7 @@ from collections import defaultdict from logging import getLogger import re -from .idna import idna_decode +from .idna import idna_decode, idna_encode from .record import Create, Delete @@ -36,7 +36,7 @@ class Zone(object): if not name[-1] == '.': raise Exception(f'Invalid zone name {name}, missing ending dot') # internally everything is idna - self.name = str(name).lower() if name else name + self.name = idna_encode(str(name)) if name else name # we'll keep a decoded version around for logs and errors self.decoded_name = idna_decode(self.name) self.sub_zones = sub_zones diff --git a/tests/test_octodns_record.py b/tests/test_octodns_record.py index 7ad2f82..75b4675 100644 --- a/tests/test_octodns_record.py +++ b/tests/test_octodns_record.py @@ -11,6 +11,7 @@ from __future__ import ( from unittest import TestCase +from octodns.idna import idna_encode from octodns.record import ( ARecord, AaaaRecord, @@ -83,6 +84,18 @@ class TestRecord(TestCase): ) self.assertEqual('mixedcase', record.name) + def test_utf8(self): + zone = Zone('natación.mx.', []) + utf8 = 'niño' + encoded = idna_encode(utf8) + record = ARecord( + zone, utf8, {'ttl': 30, 'type': 'A', 'value': '1.2.3.4'} + ) + self.assertEqual(encoded, record.name) + self.assertEqual(utf8, record.decoded_name) + self.assertTrue(f'{encoded}.{zone.name}', record.fqdn) + self.assertTrue(f'{utf8}.{zone.decoded_name}', record.decoded_fqdn) + def test_alias_lowering_value(self): upper_record = AliasRecord( self.zone, diff --git a/tests/test_octodns_zone.py b/tests/test_octodns_zone.py index 37e893f..5245735 100644 --- a/tests/test_octodns_zone.py +++ b/tests/test_octodns_zone.py @@ -11,6 +11,7 @@ from __future__ import ( from unittest import TestCase +from octodns.idna import idna_encode from octodns.record import ( ARecord, AaaaRecord, @@ -35,6 +36,13 @@ class TestZone(TestCase): zone = Zone('UniT.TEsTs.', []) self.assertEqual('unit.tests.', zone.name) + def test_utf8(self): + utf8 = 'grüßen.de.' + encoded = idna_encode(utf8) + zone = Zone(utf8, []) + self.assertEqual(encoded, zone.name) + self.assertEqual(utf8, zone.decoded_name) + def test_hostname_from_fqdn(self): zone = Zone('unit.tests.', []) for hostname, fqdn in ( @@ -46,6 +54,27 @@ class TestZone(TestCase): ('foo.bar', 'foo.bar.unit.tests'), ('foo.unit.tests', 'foo.unit.tests.unit.tests.'), ('foo.unit.tests', 'foo.unit.tests.unit.tests'), + ('déjà', 'déjà.unit.tests'), + ('déjà.foo', 'déjà.foo.unit.tests'), + ('bar.déjà', 'bar.déjà.unit.tests'), + ('bar.déjà.foo', 'bar.déjà.foo.unit.tests'), + ): + self.assertEqual(hostname, zone.hostname_from_fqdn(fqdn)) + + zone = Zone('grüßen.de.', []) + for hostname, fqdn in ( + ('', 'grüßen.de.'), + ('', 'grüßen.de'), + ('foo', 'foo.grüßen.de.'), + ('foo', 'foo.grüßen.de'), + ('foo.bar', 'foo.bar.grüßen.de.'), + ('foo.bar', 'foo.bar.grüßen.de'), + ('foo.grüßen.de', 'foo.grüßen.de.grüßen.de.'), + ('foo.grüßen.de', 'foo.grüßen.de.grüßen.de'), + ('déjà', 'déjà.grüßen.de'), + ('déjà.foo', 'déjà.foo.grüßen.de'), + ('bar.déjà', 'bar.déjà.grüßen.de'), + ('bar.déjà.foo', 'bar.déjà.foo.grüßen.de'), ): self.assertEqual(hostname, zone.hostname_from_fqdn(fqdn))