From 714b0b404e86e1efe38252855fde0bfc55198d9e Mon Sep 17 00:00:00 2001 From: Aday Bujeda Date: Mon, 12 Sep 2022 20:10:51 +0100 Subject: [PATCH] Full navigation configuration - improved test coverage (#2275) --- apps/dashboard/app/apps/nav_bar.rb | 7 ++- apps/dashboard/test/apps/nav_bar_test.rb | 46 ++++++++++++++- .../integration/custom_navigation_test.rb | 57 ++++++++++++++----- 3 files changed, 94 insertions(+), 16 deletions(-) diff --git a/apps/dashboard/app/apps/nav_bar.rb b/apps/dashboard/app/apps/nav_bar.rb index 9d7193a9a8..143757e69f 100644 --- a/apps/dashboard/app/apps/nav_bar.rb +++ b/apps/dashboard/app/apps/nav_bar.rb @@ -39,13 +39,16 @@ def self.nav_menu(hash_item) item = { apps: item } end - group_title = item.fetch(:group, group_title) if item.fetch(:url, nil) nav_link(item, menu_title, group_title) elsif item.fetch(:apps, nil) nav_apps(item, menu_title, group_title) elsif item.fetch(:profile, nil) nav_profile(item, menu_title, group_title) + else + # Update subcategory if title was provided + group_title = item.fetch(:group, group_title) + next nil end end.flatten.compact @@ -84,7 +87,7 @@ def self.item_from_token(token) matched_apps = Router.pinned_apps_from_token(token, SysRouter.apps) if matched_apps.size == 1 - extend_link(matched_apps.first.links.first) + extend_link(matched_apps.first.links.first) if matched_apps.first.links.first elsif matched_apps.size > 1 extend_group(OodAppGroup.groups_for(apps: matched_apps).first) else diff --git a/apps/dashboard/test/apps/nav_bar_test.rb b/apps/dashboard/test/apps/nav_bar_test.rb index 227ef89dd2..04186cbde4 100644 --- a/apps/dashboard/test/apps/nav_bar_test.rb +++ b/apps/dashboard/test/apps/nav_bar_test.rb @@ -26,6 +26,18 @@ def setup assert_equal "/batch_connect/sys/bc_jupyter/session_contexts/new", result[0].url end + test "NavBar.items should ignore nav_items when is a string and matching app has no links" do + mock_app = stub() + mock_app.stubs(:links).returns([]) + Router.stubs(:pinned_apps_from_token).returns([mock_app]) + + assert_equal [], NavBar.items(["test/token"]) + end + + test "NavBar.items should ignore nav_items when is a string and does not match any sys applications" do + assert_equal [], NavBar.items(["sys/not_found"]) + end + test "NavBar.items should return navigation group when nav_item is a string matching multiple app tokens" do nav_item = "sys/bc_*" @@ -36,7 +48,7 @@ def setup assert_equal 4, result[0].apps.size end - test "NavBar.items should return navigation group when nav_item is a string matching an sys application category" do + test "NavBar.items should return navigation group when nav_item is a string matching a sys application category" do nav_item = "Interactive Apps" result = NavBar.items([nav_item]) @@ -46,6 +58,16 @@ def setup assert_equal 4, result[0].apps.size end + test "nav_item string category matching should be case insensitive" do + nav_item = "intEractivE APPs" + + result = NavBar.items([nav_item]) + assert_equal 1, result.size + assert_equal "layouts/nav/group", result[0].partial_path + assert_equal "Interactive Apps", result[0].title + assert_equal 4, result[0].apps.size + end + test "NavBar.items should return navigation group when nav_item has links property" do nav_item = { title: "menu title", @@ -58,6 +80,28 @@ def setup assert_equal "menu title", result[0].title end + test "NavBar.items should set subcategory to groups inside links when nav_item only known property is group" do + nav_item = { + title: "menu title", + links: [ + {group: "subcategory1"}, + "sys/bc_jupyter", + {group: "subcategory2"}, + "sys/bc_jupyter" + ] + } + + result = NavBar.items([nav_item]) + assert_equal 1, result.size + assert_equal "layouts/nav/group", result[0].partial_path + assert_equal "menu title", result[0].title + assert_equal 2, result[0].apps.size + assert_equal "menu title", result[0].apps[0].category + assert_equal "subcategory1", result[0].apps[0].subcategory + assert_equal "menu title", result[0].apps[1].category + assert_equal "subcategory2", result[0].apps[1].subcategory + end + test "NavBar.items should return navigation link when nav_item has url property" do nav_item = { title: "link title", diff --git a/apps/dashboard/test/integration/custom_navigation_test.rb b/apps/dashboard/test/integration/custom_navigation_test.rb index f003f20897..a5a538013c 100644 --- a/apps/dashboard/test/integration/custom_navigation_test.rb +++ b/apps/dashboard/test/integration/custom_navigation_test.rb @@ -3,22 +3,29 @@ class CustomNavigationTest < ActionDispatch::IntegrationTest test "should render a custom navigation menu when nav_bar is defined in UserConfiguration" do # Mock the sys installed applications - SysRouter.stubs(:base_path).returns(Rails.root.join("test/fixtures/sys")) + OodAppkit.stubs(:clusters).returns(OodCore::Clusters.load_file('test/fixtures/config/clusters.d')) + SysRouter.stubs(:base_path).returns(Rails.root.join("test/fixtures/sys_with_interactive_apps")) # Test a navigation item of each type stub_user_configuration({nav_bar: [ {title: "Custom Menu", links: [ {group: "Custom Menu Dropdown Header"}, {title: "Menu Link", - url: "/menu/link"} + url: "/menu/link", + new_tab: false}, + {title: "Profile Link", + profile: "profile1"} ]}, {title: "Custom Apps", links: [ {group: "Custom Apps Dropdown Header"}, - {apps: "sys/systemstatus"} + {apps: ["sys/bc_jupyter"]} ]}, {title: "Custom Link", - url: "/custom/link"}, + url: "/custom/link", + icon_uri: "fa://desktop", + new_tab: true}, + "sys/bc_paraview", "all_apps", ]}) @@ -27,25 +34,43 @@ class CustomNavigationTest < ActionDispatch::IntegrationTest # Check nav menus assert_select "#navbar li.dropdown[title]", 3 # +1 here is 'Help' # Check nav links - assert_select "#navbar > ul > a.nav-link[title]", 1 + assert_select "#navbar > ul > a.nav-link[title]", 2 assert_select nav_menu(1), text: "Custom Menu" assert_select nav_menu_header("Custom Menu"), text: "Custom Menu Dropdown Header" - assert_select nav_menu_link("Custom Menu", 1), text: "Menu Link" - assert_select nav_menu_link("Custom Menu", 1) do |link| - assert_equal "/menu/link", link.first['href'] + assert_select nav_menu_links("Custom Menu") do |elements| + assert_match /Menu Link/, elements[0].text + assert_equal "/menu/link", elements[0]['href'] + assert_nil elements[0]['target'] + check_icon(elements[0], "fa-cog") + + assert_match /Profile Link/, elements[1].text + assert_equal "/settings?settings%5Bprofile%5D=profile1", elements[1]['href'] + assert_nil elements[1]['target'] + check_icon(elements[1], "fa-cog") end assert_select nav_menu(2), text: "Custom Apps" assert_select nav_menu_header("Custom Apps"), text: "Custom Apps Dropdown Header" - assert_select nav_menu_link("Custom Apps", 1), text: "System Status" - assert_select nav_menu_link("Custom Apps", 1) do |link| - assert_equal "/apps/show/systemstatus", link.first['href'] + assert_select nav_menu_links("Custom Apps") do |elements| + assert_match /Jupyter Notebook/, elements[0].text + assert_equal "/batch_connect/sys/bc_jupyter/session_contexts/new", elements[0]['href'] + assert_nil elements[0]['target'] + check_icon(elements[0], "fa-gear") + end + + assert_select nav_link("Paraview"), text: "Paraview" + assert_select nav_link("Paraview") do |link| + assert_equal "/batch_connect/sys/bc_paraview/session_contexts/new", link.first['href'] + assert_nil link.first['target'] + check_icon(link.first, "fa-gear") end assert_select nav_link("Custom Link"), text: "Custom Link" assert_select nav_link("Custom Link") do |link| assert_equal "/custom/link", link.first['href'] + assert_equal "_blank", link.first['target'] + check_icon(link.first, "fa-desktop") end # Check all_apps static link. @@ -56,8 +81,8 @@ def nav_menu(order) "#navbar .navbar-nav li.dropdown:nth-of-type(#{order}) a" end - def nav_menu_link(title, order) - "#navbar .navbar-nav li.dropdown[title='#{title}'] ul.dropdown-menu a:nth-of-type(#{order})" + def nav_menu_links(title) + "#navbar .navbar-nav li.dropdown[title='#{title}'] ul.dropdown-menu a" end def nav_menu_header(title) @@ -67,4 +92,10 @@ def nav_menu_header(title) def nav_link(title) "#navbar .navbar-nav a.nav-link[title='#{title}']" end + + def check_icon(parent_element, icon_class) + assert_select parent_element, "i" do |icons| + assert_equal true, icons.first['class'].include?(icon_class) + end + end end