Files
MISF-Planner-Download/tests/test_grid_view.py
T

203 lines
6.5 KiB
Python

"""Unit tests for Planner Grid view helpers."""
from __future__ import annotations
from unittest.mock import MagicMock, patch
from selenium.webdriver.common.by import By
from onedrive_planner import (
_clean_grid_task_title,
_grid_row_status,
_grid_row_task_name,
_is_attachments_empty,
_is_panel_placeholder_text,
_is_status_sorted_descending,
_parse_status_blob,
_sort_descending_menu_selected,
)
def _grid_row(*, status_value: str = "", status_text: str = "", task_name: str = ""):
row = MagicMock()
row.is_displayed.return_value = True
row.text = task_name
status_btn = MagicMock()
status_btn.is_displayed.return_value = True
status_btn.get_attribute.side_effect = lambda name: (
status_value if name == "value" else ""
)
status_btn.text = status_text
name_cell = MagicMock()
name_cell.is_displayed.return_value = True
name_cell.get_attribute.return_value = f"Task Name {task_name}"
name_span = MagicMock()
name_span.is_displayed.return_value = True
name_span.text = task_name
def find_elements(by, xpath):
xp = xpath or ""
if "combobox" in xp:
return [status_btn]
if "gridcell" in xp and "span" not in xp:
return [name_cell]
if "span" in xp:
return [name_span]
return []
row.find_elements.side_effect = find_elements
name_cell.find_elements.side_effect = lambda by, xpath: [name_span]
return row
def test_grid_row_status_not_started():
row = _grid_row(status_value="notStarted", status_text="Not started")
assert _grid_row_status(row) == "not started"
def test_grid_row_status_reads_status_column_not_bucket():
row = MagicMock()
row.is_displayed.return_value = True
bucket_btn = MagicMock()
bucket_btn.is_displayed.return_value = True
bucket_btn.get_attribute.side_effect = lambda name: "todo" if name == "value" else ""
bucket_btn.text = "To do"
status_btn = MagicMock()
status_btn.is_displayed.return_value = True
status_btn.get_attribute.side_effect = lambda name: "notStarted" if name == "value" else ""
status_btn.text = "Not started"
status_cell = MagicMock()
status_cell.is_displayed.return_value = True
status_cell.get_attribute.return_value = "Status Not started"
status_cell.text = "Not started"
status_cell.find_elements.side_effect = lambda by, xpath: (
[status_btn] if "combobox" in xpath else []
)
bucket_cell = MagicMock()
bucket_cell.is_displayed.return_value = True
bucket_cell.get_attribute.return_value = "Bucket To do"
bucket_cell.text = "To do"
bucket_cell.find_elements.side_effect = lambda by, xpath: (
[bucket_btn] if "combobox" in xpath else []
)
def find_elements(by, xpath):
xp = xpath or ""
if "gridcell" in xp:
return [status_cell, bucket_cell]
if "combobox" in xp:
return [bucket_btn, status_btn]
return []
row.find_elements.side_effect = find_elements
assert _grid_row_status(row) == "not started"
def test_grid_row_status_in_progress():
row = _grid_row(status_value="inProgress", status_text="In progress")
assert _grid_row_status(row) == "in progress"
def test_grid_row_task_name_from_aria():
row = _grid_row(task_name="Missing Insurance Info")
assert _grid_row_task_name(row) == "Missing Insurance Info"
def test_clean_grid_task_title_strips_a11y_hint():
raw = "Missing Insurance Info. Press Alt + I to open task details, or pre"
assert _clean_grid_task_title(raw) == "Missing Insurance Info"
def test_grid_row_task_name_strips_a11y_from_span():
row = MagicMock()
row.is_displayed.return_value = True
row.text = ""
name_cell = MagicMock()
name_cell.is_displayed.return_value = True
name_cell.get_attribute.return_value = ""
name_span = MagicMock()
name_span.is_displayed.return_value = True
name_span.text = "6.10 priority :). Press Alt + I to open task details"
def find_elements(by, xpath):
xp = xpath or ""
if "combobox" in xp:
return []
if "gridcell" in xp and "span" not in xp:
return [name_cell]
if "span" in xp:
return [name_span]
return []
row.find_elements.side_effect = find_elements
name_cell.find_elements.side_effect = lambda by, xpath: [name_span]
assert _grid_row_task_name(row) == "6.10 priority :)"
def test_is_panel_placeholder_text():
assert _is_panel_placeholder_text("Type a description or add notes here")
assert not _is_panel_placeholder_text("Missing Insurance Info")
def test_is_status_sorted_descending():
header = MagicMock()
header.get_attribute.side_effect = lambda name: (
"descending" if name == "aria-sort" else ""
)
assert _is_status_sorted_descending(header) is True
header.get_attribute.side_effect = lambda name: (
"ascending" if name == "aria-sort" else ""
)
assert _is_status_sorted_descending(header) is False
header.get_attribute.side_effect = lambda name: "" if name == "aria-sort" else ""
assert _is_status_sorted_descending(header) is False
def test_sort_descending_menu_selected():
driver = MagicMock()
checked_btn = MagicMock()
checked_btn.is_displayed.return_value = True
driver.find_elements.side_effect = lambda by, xpath: (
[checked_btn]
if "aria-checked='true'" in xpath
else []
)
assert _sort_descending_menu_selected(driver) is True
driver.find_elements.side_effect = lambda by, xpath: []
assert _sort_descending_menu_selected(driver) is False
def test_parse_status_blob():
assert _parse_status_blob("Not started") == "not started"
assert _parse_status_blob("Status Completed") == "completed"
assert _parse_status_blob("To do") is None
def test_is_attachments_empty_detects_empty_panel():
driver = MagicMock()
panel = MagicMock()
panel.is_displayed.return_value = True
panel.text = "Select, upload, or add a link to a file or website\nAdd attachment"
driver.find_elements.return_value = [panel]
with patch("onedrive_planner._attachment_tab_count", return_value=0), patch(
"onedrive_planner._discover_listed_attachment_names", return_value=[]
), patch("onedrive_planner._list_attachment_rows", return_value=[]):
assert _is_attachments_empty(driver) is True
def test_is_attachments_empty_false_when_tab_count():
driver = MagicMock()
with patch("onedrive_planner._attachment_tab_count", return_value=2):
assert _is_attachments_empty(driver) is False