Skip to content

Commit 664f4b4

Browse files
committed
Fix test_views_init for deferred typed-tab registration
Update TestRegisterTabs to reflect the two-phase init: - register_tabs() now only registers combined tabs immediately - typed tabs are deferred to _deferred_typed_init() via request_started - Add dedicated test for the deferred handler
1 parent 5bf09c3 commit 664f4b4

1 file changed

Lines changed: 43 additions & 8 deletions

File tree

tests/test_views_init.py

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@ def test_unknown_specific_model_logs_warning_no_exception(self, caplog):
5454

5555

5656
class TestRegisterTabs:
57-
def test_dispatches_combined_and_typed_tabs(self):
57+
def test_dispatches_combined_tabs_immediately_and_defers_typed(self):
58+
"""register_tabs() registers combined tabs in ready() and defers typed tabs."""
5859
from netbox_custom_objects_tab import views
5960

6061
combined_models = [MagicMock()]
61-
typed_models = [MagicMock()]
6262

6363
config_map = {
6464
"combined_models": ["dcim.device"],
@@ -70,14 +70,52 @@ def test_dispatches_combined_and_typed_tabs(self):
7070

7171
with (
7272
patch.object(views, "get_plugin_config", side_effect=lambda _plugin, key: config_map[key]),
73-
patch.object(views, "_resolve_model_labels", side_effect=[combined_models, typed_models]),
73+
patch.object(views, "_resolve_model_labels", return_value=combined_models),
7474
patch.object(views, "register_combined_tabs") as register_combined,
7575
patch.object(views, "register_typed_tabs") as register_typed,
76+
patch("django.core.signals.request_started") as mock_signal,
7677
):
7778
views.register_tabs()
7879

80+
# Combined tabs registered immediately
7981
register_combined.assert_called_once_with(combined_models, "Custom Objects", 2000)
80-
register_typed.assert_called_once_with(typed_models, 2100)
82+
# Typed tabs NOT called during register_tabs() — deferred to first request
83+
register_typed.assert_not_called()
84+
# Signal handler connected for deferred init
85+
mock_signal.connect.assert_called_once()
86+
87+
def test_deferred_init_dispatches_typed_tabs(self):
88+
"""_deferred_typed_init() resolves labels and registers typed tabs."""
89+
from netbox_custom_objects_tab import views
90+
91+
typed_models = [MagicMock()]
92+
typed_models[0]._meta.app_label = "ipam"
93+
94+
# Reset the deferred state so the handler can run
95+
views._deferred_init_done = False
96+
views._deferred_config.update(
97+
{
98+
"combined_models": [],
99+
"typed_labels": ["ipam.prefix"],
100+
"typed_weight": 2100,
101+
}
102+
)
103+
104+
try:
105+
with (
106+
patch.object(views, "_resolve_model_labels", return_value=typed_models),
107+
patch.object(views, "register_typed_tabs") as register_typed,
108+
patch.object(views, "_inject_co_urls"),
109+
patch.object(views, "_deduplicate_registry"),
110+
patch("django.core.signals.request_started"),
111+
):
112+
views._deferred_typed_init()
113+
114+
register_typed.assert_called_once_with(typed_models, 2100)
115+
finally:
116+
# Clean up global state
117+
views._deferred_init_done = False
118+
views._deferred_config.clear()
81119

82120
def test_skips_dispatch_when_configured_model_lists_are_empty(self):
83121
from netbox_custom_objects_tab import views
@@ -94,25 +132,22 @@ def test_skips_dispatch_when_configured_model_lists_are_empty(self):
94132
patch.object(views, "get_plugin_config", side_effect=lambda _plugin, key: config_map[key]),
95133
patch.object(views, "_resolve_model_labels") as resolve_labels,
96134
patch.object(views, "register_combined_tabs") as register_combined,
97-
patch.object(views, "register_typed_tabs") as register_typed,
135+
patch("django.core.signals.request_started"),
98136
):
99137
views.register_tabs()
100138

101139
resolve_labels.assert_not_called()
102140
register_combined.assert_not_called()
103-
register_typed.assert_not_called()
104141

105142
def test_config_exception_is_handled(self, caplog):
106143
from netbox_custom_objects_tab import views
107144

108145
with (
109146
patch.object(views, "get_plugin_config", side_effect=RuntimeError("boom")),
110147
patch.object(views, "register_combined_tabs") as register_combined,
111-
patch.object(views, "register_typed_tabs") as register_typed,
112148
):
113149
with caplog.at_level(logging.ERROR, logger="netbox_custom_objects_tab"):
114150
views.register_tabs()
115151

116152
register_combined.assert_not_called()
117-
register_typed.assert_not_called()
118153
assert any("Could not read netbox_custom_objects_tab plugin config" in r.message for r in caplog.records)

0 commit comments

Comments
 (0)