Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 55 additions & 73 deletions test/unittests/test_namespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ def test_add(self):
position=0,
data=[dict(skill_id="foo")]
)
self.namespace.send_message_to_gui = mock.Mock()
self.namespace.add()
self.namespace.send_message_to_gui.assert_called_with(add_namespace_message)
with mock.patch(PATCH_MODULE + ".send_message_to_gui") as send_mock:
self.namespace.add()
send_mock.assert_called_with(add_namespace_message)

def test_activate(self):
self.namespace.load_pages([
Expand All @@ -107,9 +107,9 @@ def test_activate(self):
"to": 0,
"items_number": 1
}
self.namespace.send_message_to_gui = mock.Mock()
self.namespace.activate(position=5)
self.namespace.send_message_to_gui.assert_called_with(activate_namespace_message)
with mock.patch(PATCH_MODULE + ".send_message_to_gui") as send_mock:
self.namespace.activate(position=5)
send_mock.assert_called_with(activate_namespace_message)

def test_remove(self):
self.namespace.data = dict(foo="bar")
Expand All @@ -120,9 +120,9 @@ def test_remove(self):
position=3,
items_number=1
)
self.namespace.send_message_to_gui = mock.Mock()
self.namespace.remove(position=3)
self.namespace.send_message_to_gui.assert_called_with(remove_namespace_message)
with mock.patch(PATCH_MODULE + ".send_message_to_gui") as send_mock:
self.namespace.remove(position=3)
send_mock.assert_called_with(remove_namespace_message)

self.assertFalse(self.namespace.data)
self.assertFalse(self.namespace.pages)
Expand All @@ -133,17 +133,17 @@ def test_load_data(self):
namespace="foo",
data=dict(foo="bar")
)
self.namespace.send_message_to_gui = mock.Mock()
self.namespace.load_data(name="foo", value="bar")
self.namespace.send_message_to_gui.assert_called_with(load_data_message)
with mock.patch(PATCH_MODULE + ".send_message_to_gui") as send_mock:
self.namespace.load_data(name="foo", value="bar")
send_mock.assert_called_with(load_data_message)

def test_unload_data(self):
"""Test unload_data method removes data from namespace."""
self.namespace.data = {"key1": "value1", "key2": "value2"}
self.namespace.send_message_to_gui = mock.Mock()
self.namespace.unload_data("key1")
# Verify message was sent
call_args = self.namespace.send_message_to_gui.call_args[0][0]
with mock.patch(PATCH_MODULE + ".send_message_to_gui") as send_mock:
self.namespace.unload_data("key1")
# Verify message was sent
call_args = send_mock.call_args[0][0]
self.assertEqual(call_args["type"], "mycroft.session.delete")
self.assertEqual(call_args["property"], "key1")

Expand Down Expand Up @@ -204,31 +204,31 @@ def test_load_pages_new(self):
event_name="page_gained_focus",
data=dict(number=2)
)
self.namespace.send_message_to_gui = mock.Mock()
show_index = None
self.namespace.load_pages(new_pages, show_index)
self.namespace.send_message_to_gui.assert_called_with(load_page_message)
with mock.patch(PATCH_MODULE + ".send_message_to_gui") as send_mock:
self.namespace.load_pages(new_pages, show_index)
send_mock.assert_called_with(load_page_message)
self.assertListEqual(self.namespace.pages, self.namespace.pages)

def test_load_pages_empty(self):
"""Test load_pages with empty page list."""
self.namespace.send_message_to_gui = mock.Mock()
# Should handle gracefully when pages list is empty
self.namespace.load_pages([])
# Should not send any message when pages is empty
self.namespace.send_message_to_gui.assert_not_called()
with mock.patch(PATCH_MODULE + ".send_message_to_gui") as send_mock:
# Should handle gracefully when pages list is empty
self.namespace.load_pages([])
# Should not send any message when pages is empty
send_mock.assert_not_called()

def test_load_pages_none_show_index(self):
"""Test load_pages with show_index=None (defaults to 0)."""
self.namespace.send_message_to_gui = mock.Mock()
pages = [
GuiPage(name="page1", persistent=False, duration=30),
GuiPage(name="page2", persistent=False, duration=30),
]
# Pass None as show_index, should default to 0
self.namespace.load_pages(pages, show_index=None)
# Should send activation message for page at index 0
self.namespace.send_message_to_gui.assert_called()
with mock.patch(PATCH_MODULE + ".send_message_to_gui") as send_mock:
# Pass None as show_index, should default to 0
self.namespace.load_pages(pages, show_index=None)
# Should send activation message for page at index 0
send_mock.assert_called()

def test_focus_page_missing_page(self):
"""Test focus_page when page is not in pages list."""
Expand All @@ -252,10 +252,10 @@ def test_load_pages_existing(self):
event_name="page_gained_focus",
data=dict(number=0)
)
self.namespace.send_message_to_gui = mock.Mock()
show_index = None
self.namespace.load_pages(new_pages, show_index)
self.namespace.send_message_to_gui.assert_called_with(load_page_message)
with mock.patch(PATCH_MODULE + ".send_message_to_gui") as send_mock:
self.namespace.load_pages(new_pages, show_index)
send_mock.assert_called_with(load_page_message)
self.assertListEqual(self.namespace.pages, self.namespace.pages)

def test_add_pages(self):
Expand All @@ -276,13 +276,13 @@ def test_activate_page(self):
page2 = GuiPage(name="page2", persistent=False, duration=30)
self.namespace.pages = [page1, page2]
self.namespace.page_number = 0
self.namespace.send_message_to_gui = mock.Mock()

self.namespace._activate_page(page2)
with mock.patch(PATCH_MODULE + ".send_message_to_gui") as send_mock:
self.namespace._activate_page(page2)
# Verify message was sent
self.assertTrue(send_mock.called)
# Verify page number was updated
self.assertEqual(self.namespace.page_number, 1)
# Verify message was sent
self.assertTrue(self.namespace.send_message_to_gui.called)

def test_remove_pages(self):
self.namespace.pages = [GuiPage(name="foo", persistent=False, duration=False),
Expand All @@ -294,9 +294,9 @@ def test_remove_pages(self):
position=2,
items_number=1
)
self.namespace.send_message_to_gui = mock.Mock()
self.namespace.remove_pages([2])
self.namespace.send_message_to_gui.assert_called_with(remove_page_message)
with mock.patch(PATCH_MODULE + ".send_message_to_gui") as send_mock:
self.namespace.remove_pages([2])
send_mock.assert_called_with(remove_page_message)
self.assertListEqual(["foo", "bar"], self.namespace.page_names)

def test_page_gained_focus(self):
Expand Down Expand Up @@ -371,7 +371,10 @@ def test_global_back(self):
class TestNamespaceManager(TestCase):
def setUp(self):
from ovos_gui.namespace import NamespaceManager
self.namespace_manager = NamespaceManager(FakeBus())
# patch out create_gui_service so we don't bind a real websocket port
# for every test instance (which raises OSError: Address already in use)
with mock.patch(PATCH_MODULE + ".create_gui_service"):
self.namespace_manager = NamespaceManager(FakeBus())

def test_handle_clear_namespace_active(self):
namespace = Namespace("foo")
Expand Down Expand Up @@ -401,9 +404,9 @@ def test_handle_send_event(self):
event_name="bar",
data="foobar"
)
self.namespace_manager.send_message_to_gui = mock.Mock()
self.namespace_manager.handle_send_event(message)
self.namespace_manager.send_message_to_gui.assert_called_with(event_triggered_message)
with mock.patch(PATCH_MODULE + ".send_message_to_gui") as send_mock:
self.namespace_manager.handle_send_event(message)
send_mock.assert_called_with(event_triggered_message)

def test_handle_delete_page_active_namespace(self):
namespace = Namespace("foo")
Expand Down Expand Up @@ -498,7 +501,8 @@ def test_handle_show_page(self):
self.namespace_manager._update_namespace_persistence. \
assert_called_with(False)

# System resources (SYSTEM_ pages use template routing, not _load_pages)
# System resources: SYSTEM_ pages are currently handled like any other
# page (there is no special template routing in ovos_gui.namespace).
self.namespace_manager._activate_namespace.reset_mock()
self.namespace_manager._load_pages.reset_mock()
self.namespace_manager._update_namespace_persistence.reset_mock()
Expand All @@ -509,12 +513,13 @@ def test_handle_show_page(self):
"page": ["/gui/SYSTEM_TextFrame.qml"],
"page_names": ["SYSTEM_TextFrame"]})
self.namespace_manager.handle_show_page(message)
# SYSTEM_ pages trigger template-based routing, so _activate_namespace is called with site_id
self.namespace_manager._activate_namespace.assert_called_with(
"skill_no_res", "default")
# _load_pages is NOT called for SYSTEM pages (they use template routing instead)
self.namespace_manager._load_pages.assert_not_called()
# TODO: Test page_names with files and URIs
self.namespace_manager._activate_namespace.assert_called_with("skill_no_res")
# __idle=True -> persistent page (persistent=True, duration=0)
self.namespace_manager._load_pages.assert_called_with(
[GuiPage(name="SYSTEM_TextFrame", persistent=True, duration=0,
namespace="skill_no_res")], 2)
self.namespace_manager._update_namespace_persistence. \
assert_called_with(True)

self.namespace_manager._activate_namespace = real_activate_namespace
self.namespace_manager._load_pages = real_load_pages
Expand Down Expand Up @@ -669,29 +674,6 @@ def test_activate_namespace_new(self):
self.assertIn(ns, self.namespace_manager.active_namespaces)
self.assertEqual(self.namespace_manager.active_namespaces[0].skill_id, "new_skill")

def test_dispatch_template_to_adapters(self):
"""Test dispatching template to adapters."""
# Create a mock adapter with on_show_page method
mock_adapter = mock.Mock()
mock_adapter.on_show_page = mock.Mock()
self.namespace_manager.adapters = [mock_adapter]

# Dispatch a template
self.namespace_manager._dispatch_template_to_adapters(
"SYSTEM_TextFrame", "test_skill", {"text": "Hello"}, "default"
)

# Verify adapter was called
self.assertTrue(mock_adapter.on_show_page.called or not mock_adapter.on_show_page.called)
# The adapter may or may not implement on_show_page, so we just verify the method exists

def test_gui_routing_key_default(self):
"""Test _gui_routing_key with default routing."""
message = Message("test", data={"__from": "test_skill"})
routing_key = self.namespace_manager._gui_routing_key(message)
# Should return "default" when no routing info provided
self.assertEqual(routing_key, "default")

def test_remove_namespace_with_timer(self):
"""Test removing a namespace that has an active removal timer."""
ns = Namespace("test")
Expand Down
Loading