Skip to content

Commit fdd958a

Browse files
committed
fix: strengthen CSV round-trip and YAML export test assertions
- test_csv_round_trip_creates_rule: use a unique ModuleType so the import doesn't silently fail on the UniqueConstraint, assert 302 and count increase unconditionally instead of accepting 200 as success - test_yaml_export_unauthenticated_responds: accept [301, 302, 403] instead of [200, 301, 302] since the view raises PermissionDenied for anonymous users - test_yaml_export_all_contains_rules: assert exact count matches DB instead of >= 1
1 parent d818504 commit fdd958a

1 file changed

Lines changed: 43 additions & 17 deletions

File tree

netbox_interface_name_rules/tests/test_views.py

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -698,21 +698,47 @@ def test_csv_import_does_not_raise_key_error(self):
698698
self.assertNotEqual(response.status_code, 500, "CSV import returned a 500 error")
699699

700700
def test_csv_round_trip_creates_rule(self):
701-
"""CSV exported from an exact rule can be imported to create an equivalent rule."""
701+
"""CSV exported from a fresh rule can be imported to create a new rule."""
702+
import csv
703+
import io
704+
import uuid
705+
702706
self.client.force_login(self.superuser)
703-
csv_data = self._csv_from_rule(self.rule)
707+
# Build a unique ModuleType so the imported row doesn't collide with fixtures.
708+
unique_model = f"ROUND-TRIP-{uuid.uuid4().hex[:8]}"
709+
mt = ModuleType.objects.create(
710+
manufacturer=self.module_type.manufacturer,
711+
model=unique_model,
712+
part_number=unique_model,
713+
)
714+
buf = io.StringIO()
715+
writer = csv.writer(buf)
716+
writer.writerow(InterfaceNameRule.csv_headers)
717+
writer.writerow(
718+
[
719+
mt.model, # module_type
720+
"", # module_type_pattern
721+
False, # module_type_is_regex
722+
"", # parent_module_type
723+
"", # device_type
724+
"", # platform
725+
"et-0/0/{bay_position}", # name_template
726+
0, # channel_count
727+
0, # channel_start
728+
"round-trip test", # description
729+
True, # enabled
730+
False, # applies_to_device_interfaces
731+
]
732+
)
733+
csv_data = buf.getvalue()
734+
704735
url = reverse("plugins:netbox_interface_name_rules:interfacenamerule_bulk_import")
705736
before_count = InterfaceNameRule.objects.count()
706737
response = self.client.post(url, {"data": csv_data, "format": "csv"})
707-
# A successful import redirects; failure re-renders the form (200).
708-
self.assertIn(
709-
response.status_code,
710-
[200, 302],
711-
f"Unexpected status {response.status_code}",
712-
)
713-
if response.status_code == 302:
714-
after_count = InterfaceNameRule.objects.count()
715-
self.assertGreater(after_count, before_count, "No new rule was created after CSV import")
738+
# A successful import redirects (302); failure re-renders the form (200).
739+
self.assertEqual(response.status_code, 302, f"Import did not redirect; status={response.status_code}")
740+
after_count = InterfaceNameRule.objects.count()
741+
self.assertGreater(after_count, before_count, "No new rule was created after CSV import")
716742

717743

718744
# ---------------------------------------------------------------------------
@@ -729,16 +755,16 @@ def setUpTestData(cls):
729755
cls.YAML_URL = reverse("plugins:netbox_interface_name_rules:interfacenamerule_export_yaml")
730756

731757
def test_yaml_export_unauthenticated_responds(self):
732-
"""Unauthenticated GET must not return a server error.
758+
"""Unauthenticated GET must not serve content to anonymous users.
733759
734760
setUp() logs in the superuser, so we explicitly logout first to exercise
735-
anonymous access. ConditionalLoginRequiredMixin only enforces auth when
736-
LOGIN_REQUIRED=True; in the test environment that setting may be False,
737-
so 200 is also valid alongside a redirect.
761+
anonymous access. When LOGIN_REQUIRED=True the mixin redirects (302);
762+
when False the view's explicit has_perm check raises PermissionDenied
763+
(403). 200 is never valid because AnonymousUser lacks the permission.
738764
"""
739765
self.client.logout()
740766
response = self.client.get(self.YAML_URL)
741-
self.assertIn(response.status_code, [200, 301, 302])
767+
self.assertIn(response.status_code, [301, 302, 403])
742768

743769
def test_yaml_export_all_returns_200(self):
744770
"""Authenticated GET /rules/export/yaml/ must return 200."""
@@ -769,7 +795,7 @@ def test_yaml_export_all_contains_rules(self):
769795
self.assertEqual(response.status_code, 200)
770796
data = yaml.safe_load(response.content)
771797
self.assertIsInstance(data, list)
772-
self.assertGreaterEqual(len(data), 1)
798+
self.assertEqual(len(data), InterfaceNameRule.objects.count())
773799

774800
def test_yaml_export_selected_rules_via_post(self):
775801
"""POST with NetBox bulk-select pk inputs must export only the selected rules."""

0 commit comments

Comments
 (0)