mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-11-05 12:48:14 +00:00
Conversation reference: https://chatgpt.com/share/6908642f-29cc-800f-89ec-fd6de9892b44
118 lines
4.5 KiB
Python
118 lines
4.5 KiB
Python
import os
|
|
import sys
|
|
import unittest
|
|
from importlib import import_module
|
|
|
|
# Compute repo root (…/tests/unit/roles/web-app-desktop/lookup_plugins/docker_cards_grouped.py -> repo root)
|
|
_THIS_DIR = os.path.dirname(__file__)
|
|
_REPO_ROOT = os.path.abspath(os.path.join(_THIS_DIR, "../../../../.."))
|
|
|
|
# Add the lookup_plugins directory to sys.path so we can import the plugin as a plain module
|
|
_LOOKUP_DIR = os.path.join(_REPO_ROOT, "roles", "web-app-desktop", "lookup_plugins")
|
|
if _LOOKUP_DIR not in sys.path:
|
|
sys.path.insert(0, _LOOKUP_DIR)
|
|
|
|
# Import the plugin module
|
|
plugin = import_module("docker_cards_grouped")
|
|
LookupModule = plugin.LookupModule
|
|
|
|
try:
|
|
from ansible.errors import AnsibleError
|
|
except Exception: # Fallback for environments without full Ansible
|
|
class AnsibleError(Exception):
|
|
pass
|
|
|
|
|
|
class TestDockerCardsGroupedLookup(unittest.TestCase):
|
|
def setUp(self):
|
|
self.lookup = LookupModule()
|
|
|
|
# Menu categories with mixed-case names to verify case-insensitive sort
|
|
self.menu_categories = {
|
|
"B-Group": {"tags": ["b", "beta"]},
|
|
"a-Group": {"tags": ["a", "alpha"]},
|
|
"Zeta": {"tags": ["z"]},
|
|
}
|
|
|
|
# Cards with tags; one should end up uncategorized
|
|
self.cards = [
|
|
{"title": "Alpha Tool", "tags": ["a"]},
|
|
{"title": "Beta Widget", "tags": ["beta"]},
|
|
{"title": "Zed App", "tags": ["z"]},
|
|
{"title": "Unmatched Thing", "tags": ["x"]},
|
|
]
|
|
|
|
def _run(self, cards=None, menu_categories=None):
|
|
result = self.lookup.run(
|
|
[cards or self.cards, menu_categories or self.menu_categories]
|
|
)
|
|
# Plugin returns a single-element list containing the result dict
|
|
self.assertIsInstance(result, list)
|
|
self.assertEqual(len(result), 1)
|
|
self.assertIsInstance(result[0], dict)
|
|
return result[0]
|
|
|
|
def test_categorization_and_uncategorized(self):
|
|
data = self._run()
|
|
self.assertIn("categorized", data)
|
|
self.assertIn("uncategorized", data)
|
|
|
|
categorized = data["categorized"]
|
|
uncategorized = data["uncategorized"]
|
|
|
|
# Each matching card is placed into the proper category
|
|
self.assertIn("a-Group", categorized)
|
|
self.assertIn("B-Group", categorized)
|
|
self.assertIn("Zeta", categorized)
|
|
|
|
titles_in_a = [c["title"] for c in categorized["a-Group"]]
|
|
titles_in_b = [c["title"] for c in categorized["B-Group"]]
|
|
titles_in_z = [c["title"] for c in categorized["Zeta"]]
|
|
|
|
self.assertEqual(titles_in_a, ["Alpha Tool"])
|
|
self.assertEqual(titles_in_b, ["Beta Widget"])
|
|
self.assertEqual(titles_in_z, ["Zed App"])
|
|
|
|
# Unmatched card should be in 'uncategorized'
|
|
self.assertEqual(len(uncategorized), 1)
|
|
self.assertEqual(uncategorized[0]["title"], "Unmatched Thing")
|
|
|
|
def test_categories_sorted_alphabetically_case_insensitive(self):
|
|
data = self._run()
|
|
categorized = data["categorized"]
|
|
|
|
# Verify order is alphabetical by key, case-insensitive
|
|
keys = list(categorized.keys())
|
|
self.assertEqual(keys, ["a-Group", "B-Group", "Zeta"])
|
|
|
|
def test_multiple_tags_match_first_category_encountered(self):
|
|
# A card that matches multiple categories should be placed
|
|
# into the first matching category based on menu_categories iteration order.
|
|
# Here "Dual Match" has both 'a' and 'b' tags; since "a-Group" is alphabetically
|
|
# before "B-Group" only after sorting happens at RETURN time, we need to ensure the
|
|
# assignment is based on menu_categories order (insertion order).
|
|
menu_categories = {
|
|
"B-Group": {"tags": ["b"]},
|
|
"a-Group": {"tags": ["a"]},
|
|
}
|
|
cards = [{"title": "Dual Match", "tags": ["a", "b"]}]
|
|
# The plugin iterates menu_categories in insertion order and breaks on first match,
|
|
# so this card should end up in "B-Group".
|
|
data = self._run(cards=cards, menu_categories=menu_categories)
|
|
categorized = data["categorized"]
|
|
|
|
self.assertIn("B-Group", categorized)
|
|
self.assertEqual([c["title"] for c in categorized["B-Group"]], ["Dual Match"])
|
|
self.assertNotIn("a-Group", categorized) # no card added there
|
|
|
|
def test_missing_arguments_raises(self):
|
|
with self.assertRaises(AnsibleError):
|
|
self.lookup.run([]) # no args
|
|
|
|
with self.assertRaises(AnsibleError):
|
|
self.lookup.run([[]]) # only one arg
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|