Skip to content

Commit db051a0

Browse files
authored
fix: Prefix names starting with numbers with an underscore in slugify function (#359)
1 parent 89273b5 commit db051a0

File tree

3 files changed

+50
-5
lines changed

3 files changed

+50
-5
lines changed

changes/319.fixed

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed an incompatibility when slugifying capirca names that start with a number by prefixing the name with an underscore.

nautobot_firewall_models/tests/test_capirca.py

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,22 @@
22

33
# ruff: noqa: F403, F405
44
# pylint: disable=protected-access
5-
from unittest import skip
5+
import unittest
66
from unittest.mock import patch
77

88
from django.core.exceptions import ValidationError
9-
from django.test import TestCase
9+
from nautobot.apps.testing import TestCase
1010
from nautobot.dcim.models import Device, Platform
1111
from nautobot.extras.models import Status
1212
from nautobot.ipam.models import IPAddress, Namespace
1313

1414
from nautobot_firewall_models.models import * # pylint: disable=unused-wildcard-import, wildcard-import
15-
from nautobot_firewall_models.utils.capirca import DevicePolicyToCapirca, PolicyToCapirca, generate_capirca_config
15+
from nautobot_firewall_models.utils.capirca import (
16+
DevicePolicyToCapirca,
17+
PolicyToCapirca,
18+
_slugify,
19+
generate_capirca_config,
20+
)
1621

1722
from .fixtures import create_capirca_env
1823

@@ -280,6 +285,39 @@ def test_generate_capirca_config(self):
280285
self.assertEqual(actual_cfg, CFG)
281286

282287

288+
class TestSlugify(unittest.TestCase):
289+
"""Test models."""
290+
291+
def test_slugify_removes_accents(self):
292+
self.assertEqual(_slugify("Café"), "Cafe")
293+
self.assertEqual(_slugify("mañana"), "manana")
294+
295+
def test_slugify_removes_non_alphanumeric_characters(self):
296+
self.assertEqual(_slugify("Hello!! World??"), "Hello-World")
297+
self.assertEqual(_slugify("A*B&C(D)"), "ABCD")
298+
299+
def test_slugify_adds_leading_underscore_if_starts_with_digit(self):
300+
self.assertEqual(_slugify("123abc"), "_123abc")
301+
self.assertEqual(_slugify("9-lives"), "_9-lives")
302+
303+
def test_slugify_collapses_spaces_and_hyphens(self):
304+
self.assertEqual(_slugify("hello world"), "hello-world")
305+
self.assertEqual(_slugify("hello---world"), "hello-world")
306+
self.assertEqual(_slugify("hello_ - world"), "hello_-world")
307+
308+
def test_slugify_removes_unicode_symbols(self):
309+
self.assertEqual(_slugify("★Test☆string★"), "Teststring")
310+
311+
def test_value_is_integer(self):
312+
self.assertEqual(_slugify(1234), "_1234")
313+
314+
def test_clean_slug(self):
315+
self.assertEqual(_slugify("Clean-Slug_123"), "Clean-Slug_123")
316+
317+
def test_empty_string(self):
318+
self.assertEqual(_slugify(""), "")
319+
320+
283321
class TestPolicyToCapirca(TestCase): # pylint: disable=too-many-public-methods,too-many-instance-attributes
284322
"""Test models."""
285323

@@ -631,7 +669,7 @@ def setUp(self) -> None:
631669
create_capirca_env()
632670
self.device_obj = Device.objects.get(name="DFW02-WAN00")
633671

634-
@skip("Not implemented until policy method provided to merge queries provided")
672+
@unittest.skip("Not implemented until policy method provided to merge queries provided")
635673
def test_dynamic_group_and_device(self):
636674
"""Test that dynamic groups are created and device is added to it, disabled."""
637675

nautobot_firewall_models/utils/capirca.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,17 @@ def _slugify(value):
3333
dashes to single dashes. Remove characters that aren't alphanumerics,
3434
underscores, or hyphens. Convert to lowercase. Also strip leading and
3535
trailing whitespace, dashes, and underscores.
36+
Also adds a leading underscore to names starting with an number to circumvent a bug in the Capirca/Aerleon parser.
3637
"""
3738
value = str(value)
3839
value = unicodedata.normalize("NFKD", value).encode("ascii", "ignore").decode("ascii")
3940
value = re.sub(r"[^\w\s-]", "", value)
40-
return re.sub(r"[-\s]+", "-", value).strip("-_")
41+
value = re.sub(r"[-\s]+", "-", value).strip("-_")
42+
43+
if value[:1].isnumeric():
44+
value = "_" + value
45+
46+
return value
4147

4248

4349
def _list_slugify(values):

0 commit comments

Comments
 (0)