@@ -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