Skip to content

Commit e88169e

Browse files
committed
test: fix non-deterministic assertions and improve test quality
1 parent a099adb commit e88169e

2 files changed

Lines changed: 31 additions & 15 deletions

File tree

netbox_interface_name_rules/tests/test_coverage_extras.py

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -328,9 +328,7 @@ def test_returns_false_when_token_missing(self):
328328
# Already False before this test; just verify the type
329329
self.assertIsInstance(result, bool)
330330
finally:
331-
if had_attr and original is not None:
332-
dc.MODULE_PATH_TOKEN = original
333-
elif had_attr:
331+
if had_attr:
334332
dc.MODULE_PATH_TOKEN = original
335333

336334

@@ -406,28 +404,31 @@ def test_post_no_interfaces_selected_warns(self):
406404
"""POST apply with no interface_ids warns and redirects (lines 408-409)."""
407405
url = self._url(self.rule.pk)
408406
response = self.client.post(url, {"action": "apply"})
409-
self.assertIn(response.status_code, [200, 302])
407+
self.assertEqual(response.status_code, 302)
410408

411409
def test_post_apply_with_interface_ids_calls_apply(self):
412410
"""POST apply with interface_ids calls apply_rule_to_existing (lines 410-412)."""
413411
url = self._url(self.rule.pk)
414-
response = self.client.post(url, {"action": "apply", "interface_ids": ["1", "2"]})
415-
self.assertIn(response.status_code, [302])
412+
with patch("netbox_interface_name_rules.engine.apply_rule_to_existing", return_value=2) as mock_apply:
413+
response = self.client.post(url, {"action": "apply", "interface_ids": ["1", "2"]})
414+
self.assertEqual(response.status_code, 302)
415+
mock_apply.assert_called_once()
416416

417417
def test_post_background_action_enqueues_job(self):
418418
"""POST background action tries to enqueue ApplyRuleJob (lines 388-403)."""
419419
url = self._url(self.rule.pk)
420-
with patch("netbox_interface_name_rules.jobs.ApplyRuleJob.enqueue", side_effect=Exception("no rq")):
420+
with patch("netbox_interface_name_rules.jobs.ApplyRuleJob.enqueue", side_effect=Exception("no rq")) as mock_enq:
421421
response = self.client.post(url, {"action": "background"})
422-
self.assertIn(response.status_code, [302])
422+
self.assertEqual(response.status_code, 302)
423+
mock_enq.assert_called_once()
423424

424425
def test_post_no_change_permission_raises_forbidden(self):
425426
"""POST apply without dcim.change_interface permission raises PermissionDenied (line 382-383)."""
426427
User.objects.create_user(username="noperm_apply_user", password="testpass123")
427428
self.client.login(username="noperm_apply_user", password="testpass123")
428429
url = self._url(self.rule.pk)
429430
response = self.client.post(url, {"action": "apply"})
430-
self.assertIn(response.status_code, [403, 302])
431+
self.assertEqual(response.status_code, 403)
431432

432433

433434
class RuleToggleNoPermissionNonAjaxTest(ViewTestBase2):
@@ -736,6 +737,7 @@ class EngineBuildModuleQsPlatformTest(TestCase):
736737
def setUpTestData(cls):
737738
manufacturer = Manufacturer.objects.create(name="PlatXMfg", slug="platxmfg")
738739
cls.platform = Platform.objects.create(name="PLATX-IOS", slug="platx-ios")
740+
other_platform = Platform.objects.create(name="PLATX-NXOS", slug="platx-nxos")
739741
cls.module_type = ModuleType.objects.create(
740742
manufacturer=manufacturer, model="PLATX-SFP", part_number="PLATX-SFP"
741743
)
@@ -744,14 +746,29 @@ def setUpTestData(cls):
744746
platform=cls.platform,
745747
name_template="et-0/0/{bay_position}",
746748
)
749+
device_type = DeviceType.objects.create(manufacturer=manufacturer, model="PLATX-Dev", slug="platx-dev")
750+
ModuleBayTemplate.objects.create(device_type=device_type, name="PLBay 0", position="0")
751+
role = DeviceRole.objects.create(name="PlatXRole", slug="platxrole")
752+
site = Site.objects.create(name="PlatXSite", slug="platxsite")
753+
device_match = Device.objects.create(
754+
name="platx-dev-match", device_type=device_type, role=role, site=site, platform=cls.platform
755+
)
756+
device_other = Device.objects.create(
757+
name="platx-dev-other", device_type=device_type, role=role, site=site, platform=other_platform
758+
)
759+
bay_match = ModuleBay.objects.get(device=device_match)
760+
bay_other = ModuleBay.objects.get(device=device_other)
761+
cls.module_match = Module.objects.create(device=device_match, module_bay=bay_match, module_type=cls.module_type)
762+
cls.module_other = Module.objects.create(device=device_other, module_bay=bay_other, module_type=cls.module_type)
747763

748764
def test_platform_filter_applied(self):
749-
"""_build_module_qs applies rule.platform filter when set (line 588)."""
765+
"""_build_module_qs applies rule.platform filter — matching device is included, other is excluded."""
750766
from netbox_interface_name_rules.engine import _build_module_qs
751767

752768
qs = _build_module_qs(self.rule)
753-
# Verify the filter was applied by checking the queryset SQL
754-
self.assertIn("platform", str(qs.query).lower())
769+
pks = list(qs.values_list("pk", flat=True))
770+
self.assertIn(self.module_match.pk, pks)
771+
self.assertNotIn(self.module_other.pk, pks)
755772

756773

757774
# ---------------------------------------------------------------------------
@@ -1158,5 +1175,4 @@ def test_limit_reached_returns_true(self):
11581175
processed_pks=set(),
11591176
)
11601177
# If the entry was added and limit=1 reached, should_stop should be True
1161-
# (or the entry might already be renamed; in any case we check the logic ran)
1162-
self.assertIsInstance(should_stop, bool)
1178+
self.assertTrue(should_stop)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ source = ["netbox_interface_name_rules"]
7676
omit = ["*/migrations/*", "*/tests/*"]
7777

7878
[tool.coverage.report]
79-
fail_under = 95
79+
fail_under = 97
8080
show_missing = true
8181

8282
[tool.semantic_release]

0 commit comments

Comments
 (0)