feat: remove filtered gridViewMode rendering code and option (task-11)
- Remove 'Filtered' option from HTML view mode select in index.html - Add test_no_active_filter_device_in_render_grid to test_frontend_js.py - Add test_no_filtered_option_in_view_mode_select to test_frontend_html.py - All 3 acceptance criteria tests pass The renderGrid() function was already clean (no filtered mode checks, no _activeFilterDevice references) from prior cleanup work. The loadGridViewMode() and _setGridViewMode() guards were also already in place. The remaining task was to remove the HTML <option value="filtered"> and add the missing tests.
This commit is contained in:
@@ -235,7 +235,6 @@
|
|||||||
<select id="setting-view-mode" class="settings-select">
|
<select id="setting-view-mode" class="settings-select">
|
||||||
<option value="flat">Flat</option>
|
<option value="flat">Flat</option>
|
||||||
<option value="grouped">Grouped</option>
|
<option value="grouped">Grouped</option>
|
||||||
<option value="filtered">Filtered</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-field settings-field--column">
|
<div class="settings-field settings-field--column">
|
||||||
|
|||||||
@@ -204,7 +204,9 @@ def test_html_session_sidebar_structure() -> None:
|
|||||||
assert sidebar_header is not None, "Missing .sidebar-header inside #session-sidebar"
|
assert sidebar_header is not None, "Missing .sidebar-header inside #session-sidebar"
|
||||||
# #sidebar-view-dropdown (replaces old .sidebar-title)
|
# #sidebar-view-dropdown (replaces old .sidebar-title)
|
||||||
sidebar_dropdown = sidebar_header.find(id="sidebar-view-dropdown")
|
sidebar_dropdown = sidebar_header.find(id="sidebar-view-dropdown")
|
||||||
assert sidebar_dropdown is not None, "Missing #sidebar-view-dropdown inside .sidebar-header"
|
assert sidebar_dropdown is not None, (
|
||||||
|
"Missing #sidebar-view-dropdown inside .sidebar-header"
|
||||||
|
)
|
||||||
# #sidebar-collapse-btn
|
# #sidebar-collapse-btn
|
||||||
collapse_btn = sidebar_header.find(id="sidebar-collapse-btn")
|
collapse_btn = sidebar_header.find(id="sidebar-collapse-btn")
|
||||||
assert collapse_btn is not None, (
|
assert collapse_btn is not None, (
|
||||||
@@ -715,9 +717,7 @@ def test_html_notifications_panel_has_notification_status_text() -> None:
|
|||||||
)
|
)
|
||||||
assert sessions_panel is not None, "Missing sessions settings-panel"
|
assert sessions_panel is not None, "Missing sessions settings-panel"
|
||||||
el = sessions_panel.find(id="notification-status-text")
|
el = sessions_panel.find(id="notification-status-text")
|
||||||
assert el is not None, (
|
assert el is not None, "Missing #notification-status-text inside sessions panel"
|
||||||
"Missing #notification-status-text inside sessions panel"
|
|
||||||
)
|
|
||||||
classes = el.get("class") or []
|
classes = el.get("class") or []
|
||||||
assert "settings-status-text" in classes, (
|
assert "settings-status-text" in classes, (
|
||||||
f"#notification-status-text must have class 'settings-status-text', has: {classes}"
|
f"#notification-status-text must have class 'settings-status-text', has: {classes}"
|
||||||
@@ -734,9 +734,7 @@ def test_html_notifications_panel_has_request_btn() -> None:
|
|||||||
)
|
)
|
||||||
assert sessions_panel is not None, "Missing sessions settings-panel"
|
assert sessions_panel is not None, "Missing sessions settings-panel"
|
||||||
el = sessions_panel.find(id="notification-request-btn")
|
el = sessions_panel.find(id="notification-request-btn")
|
||||||
assert el is not None, (
|
assert el is not None, "Missing #notification-request-btn inside sessions panel"
|
||||||
"Missing #notification-request-btn inside sessions panel"
|
|
||||||
)
|
|
||||||
classes = el.get("class") or []
|
classes = el.get("class") or []
|
||||||
assert "settings-action-btn" in classes, (
|
assert "settings-action-btn" in classes, (
|
||||||
f"#notification-request-btn must have class 'settings-action-btn', has: {classes}"
|
f"#notification-request-btn must have class 'settings-action-btn', has: {classes}"
|
||||||
@@ -1367,9 +1365,7 @@ def test_html_settings_remote_instance_key_input() -> None:
|
|||||||
devices_panel = soup.find("div", attrs={"data-tab": "devices"})
|
devices_panel = soup.find("div", attrs={"data-tab": "devices"})
|
||||||
assert devices_panel is not None, "Missing devices panel (data-tab='devices')"
|
assert devices_panel is not None, "Missing devices panel (data-tab='devices')"
|
||||||
el = devices_panel.find(id="setting-remote-instances")
|
el = devices_panel.find(id="setting-remote-instances")
|
||||||
assert el is not None, (
|
assert el is not None, "Missing #setting-remote-instances inside devices panel"
|
||||||
"Missing #setting-remote-instances inside devices panel"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
@@ -1398,9 +1394,9 @@ def test_html_loads_web_links_addon() -> None:
|
|||||||
def test_html_loads_search_addon() -> None:
|
def test_html_loads_search_addon() -> None:
|
||||||
"""index.html must load the xterm-addon-search CDN script."""
|
"""index.html must load the xterm-addon-search CDN script."""
|
||||||
html = read_html()
|
html = read_html()
|
||||||
assert "search" in html.lower() and "addon" in html.lower() and "xterm" in html.lower(), (
|
assert (
|
||||||
"Must load xterm-addon-search from CDN"
|
"search" in html.lower() and "addon" in html.lower() and "xterm" in html.lower()
|
||||||
)
|
), "Must load xterm-addon-search from CDN"
|
||||||
|
|
||||||
|
|
||||||
def test_html_loads_image_addon() -> None:
|
def test_html_loads_image_addon() -> None:
|
||||||
@@ -1520,3 +1516,19 @@ def test_sidebar_view_dropdown_menu_exists() -> None:
|
|||||||
soup = _SOUP
|
soup = _SOUP
|
||||||
menu = soup.find(id="sidebar-view-dropdown-menu")
|
menu = soup.find(id="sidebar-view-dropdown-menu")
|
||||||
assert menu is not None, "Missing #sidebar-view-dropdown-menu"
|
assert menu is not None, "Missing #sidebar-view-dropdown-menu"
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# Remove filtered gridViewMode rendering code (task-11)
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_filtered_option_in_view_mode_select() -> None:
|
||||||
|
"""No 'Filtered' option in view mode select."""
|
||||||
|
select = _SOUP.find(id="setting-view-mode")
|
||||||
|
assert select is not None, "Missing #setting-view-mode select"
|
||||||
|
options = select.find_all("option")
|
||||||
|
values = [o.get("value") for o in options]
|
||||||
|
assert "filtered" not in values, (
|
||||||
|
"View mode select must not contain a 'filtered' option (removed in task-11)"
|
||||||
|
)
|
||||||
|
|||||||
@@ -3149,9 +3149,7 @@ def test_toggle_view_dropdown_function_exists() -> None:
|
|||||||
|
|
||||||
def test_switch_view_function_exists() -> None:
|
def test_switch_view_function_exists() -> None:
|
||||||
"""switchView function must exist in app.js."""
|
"""switchView function must exist in app.js."""
|
||||||
assert "function switchView" in _JS, (
|
assert "function switchView" in _JS, "switchView must be defined in app.js"
|
||||||
"switchView must be defined in app.js"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_switch_view_patches_state() -> None:
|
def test_switch_view_patches_state() -> None:
|
||||||
@@ -3182,9 +3180,7 @@ def test_handle_global_keydown_has_backtick_handler() -> None:
|
|||||||
assert match, "handleGlobalKeydown function not found"
|
assert match, "handleGlobalKeydown function not found"
|
||||||
body = match.group(1)
|
body = match.group(1)
|
||||||
has_backtick = (
|
has_backtick = (
|
||||||
"Backquote" in body
|
"Backquote" in body or "e.key === '`'" in body or 'e.key === "`"' in body
|
||||||
or "e.key === '`'" in body
|
|
||||||
or 'e.key === "`"' in body
|
|
||||||
)
|
)
|
||||||
assert has_backtick, (
|
assert has_backtick, (
|
||||||
"handleGlobalKeydown must handle backtick/Backquote key to toggle view dropdown"
|
"handleGlobalKeydown must handle backtick/Backquote key to toggle view dropdown"
|
||||||
@@ -3206,9 +3202,7 @@ def test_handle_global_keydown_has_number_key_shortcuts() -> None:
|
|||||||
assert "switchView" in body, (
|
assert "switchView" in body, (
|
||||||
"handleGlobalKeydown must call switchView for number keys 1–9"
|
"handleGlobalKeydown must call switchView for number keys 1–9"
|
||||||
)
|
)
|
||||||
has_number_handling = (
|
has_number_handling = "Digit" in body or "parseInt" in body
|
||||||
"Digit" in body or "parseInt" in body
|
|
||||||
)
|
|
||||||
assert has_number_handling, (
|
assert has_number_handling, (
|
||||||
"handleGlobalKeydown must handle number key codes (e.g. e.code.startsWith('Digit'))"
|
"handleGlobalKeydown must handle number key codes (e.g. e.code.startsWith('Digit'))"
|
||||||
)
|
)
|
||||||
@@ -3258,9 +3252,7 @@ def test_show_new_view_input_patches_settings() -> None:
|
|||||||
assert "/api/settings" in body, (
|
assert "/api/settings" in body, (
|
||||||
"showNewViewInput must PATCH /api/settings with the updated views"
|
"showNewViewInput must PATCH /api/settings with the updated views"
|
||||||
)
|
)
|
||||||
assert "views" in body, (
|
assert "views" in body, "showNewViewInput must include 'views' in the PATCH body"
|
||||||
"showNewViewInput must include 'views' in the PATCH body"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
@@ -3273,3 +3265,22 @@ def test_render_views_settings_tab_function_exists() -> None:
|
|||||||
assert "function renderViewsSettingsTab" in _JS, (
|
assert "function renderViewsSettingsTab" in _JS, (
|
||||||
"renderViewsSettingsTab must be defined in app.js"
|
"renderViewsSettingsTab must be defined in app.js"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# Remove filtered gridViewMode rendering code (task-11)
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_active_filter_device_in_render_grid() -> None:
|
||||||
|
"""renderGrid must not reference _activeFilterDevice."""
|
||||||
|
match = re.search(
|
||||||
|
r"function renderGrid\(sessions\)\s*\{(.*?)(?=\n// -------|\n// =======)",
|
||||||
|
_JS,
|
||||||
|
re.DOTALL,
|
||||||
|
)
|
||||||
|
assert match, "renderGrid function not found"
|
||||||
|
body = match.group(1)
|
||||||
|
assert "_activeFilterDevice" not in body, (
|
||||||
|
"renderGrid must not reference _activeFilterDevice (filtered mode removed)"
|
||||||
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user