test_that("layout_combo enforces dark theme on sidebar and filters theme li when requested", { theme_a <- a(href = "#", "T") theme_li <- li(class = "mt-auto", theme_a) ul <- ul(theme_li, li(a(href = "#", "Item"))) aside_side <- aside( class = "navbar navbar-vertical", div( class = "container-fluid", div(class = "collapse navbar-collapse", id = "sidebar-menu", ul) ) ) # Pass list(navbar = list(side = aside_side)) to ensure combo sets data-bs-theme out <- layout_combo(list(top = NULL, side = aside_side), NULL, body("C"), NULL) out_str <- as.character(out) # Sidebar should have data-bs-theme="dark" expect_true(grepl('data-bs-theme="dark"', out_str)) expect_true(grepl("Item", out_str)) }) test_that("layout_combo adds data-bs-theme dark to sidebar and filters theme li when show_theme_button=FALSE", { theme_a <- a(href = "?theme=dark", class = "hide-theme-dark") theme_li <- li(class = "mt-auto", theme_a) li_item <- li(a(href = "#", "LinkC")) ul <- ul(li_item, theme_li) aside_side <- aside( class = "navbar navbar-vertical", div(class = "container-fluid", div(class = "collapse navbar-collapse", id = "sidebar-menu", ul)) ) out <- layout_combo(list(top = NULL, side = aside_side), NULL, body("Body"), NULL, show_theme_button = FALSE) s <- as.character(out) expect_true(grepl('data-bs-theme="dark"', s)) # theme li should be filtered out when show_theme_button is FALSE expect_false(grepl("hide-theme-dark", s)) }) test_that("layout_combo accepts a header as top_nav and removes theme li via filter_theme_li", { # Build a header-like top_nav that contains a theme li theme_a <- a(href = "?theme=dark", class = "hide-theme-dark") theme_li <- li(class = "mt-auto", theme_a) top_ul <- ul(li(a(href = "#", "TopLink")), theme_li) header_tag <- header(div(class = "container-xl", div(class = "collapse navbar-collapse", id = "navbar-menu", top_ul))) out <- layout_combo(header_tag, NULL, body("B"), NULL, show_theme_button = FALSE) s <- as.character(out) # Theme toggle should be removed from resulting header expect_false(grepl("hide-theme-dark", s)) expect_true(grepl("TopLink", s)) }) test_that("layout_combo builds top navbar when navbar is an aside and excludes theme items from top", { # aside used as top_nav: normal li should appear in top navbar, theme li should be excluded theme_a <- a(href = "?theme=dark", class = "hide-theme-dark") theme_li <- li(class = "mt-auto", theme_a) normal_li <- li(a(href = "#", "Normal")) ul <- ul(normal_li, theme_li) top_aside <- aside( class = "navbar navbar-vertical", div(class = "container-fluid", div(class = "collapse navbar-collapse", id = "sidebar-menu", ul)) ) out <- layout_combo(top_aside, NULL, body("X"), NULL, show_theme_button = TRUE) s <- as.character(out) # Top navbar should contain Normal but should NOT contain theme anchor text expect_true(grepl("Normal", s)) }) test_that("layout_combo with sidebar keeps theme anchors when show_theme_button=TRUE", { theme_a <- a(href = "?theme=dark", class = "hide-theme-dark") theme_li <- li(class = "mt-auto", theme_a) li_item <- li(a(href = "#", "SideLink")) ul <- ul(li_item, theme_li) aside_side <- aside( class = "navbar navbar-vertical navbar-expand-lg", div(class = "container-fluid", div(class = "collapse navbar-collapse", id = "sidebar-menu", ul)) ) out <- layout_combo(list(top = NULL, side = aside_side), NULL, body("Body"), NULL, show_theme_button = TRUE) s <- as.character(out) # Sidebar should be marked dark and should still contain the theme toggle anchor expect_true(grepl('data-bs-theme="dark"', s)) expect_true(grepl("hide-theme-dark", s)) expect_true(grepl("SideLink", s)) }) test_that("layout_combo does not force dark theme on non-vertical sidebar", { # If sidebar is not navbar-vertical, it should not get data-bs-theme added aside_side <- aside( class = "navbar", # missing navbar-vertical div( class = "container-fluid", div( class = "collapse navbar-collapse", id = "sidebar-menu", ul( li(a(href = "#", "A")) ) ) ) ) out <- layout_combo(list(top = NULL, side = aside_side), NULL, body("Body"), NULL, show_theme_button = TRUE) s <- as.character(out) expect_false(grepl('data-bs-theme="dark"', s)) # Should not have navbar-expand-lg added when not vertical expect_false(grepl("navbar-expand-lg", s)) }) test_that("layout_combo adds navbar-expand-lg when sidebar is vertical but missing expand class", { # vertical sidebar without navbar-expand-lg should get it appended and data-bs-theme dark aside_side <- aside( class = "navbar navbar-vertical", # vertical but missing expand div( class = "container-fluid", div( class = "collapse navbar-collapse", id = "sidebar-menu", ul( li(a(href = "#", "B")) ) ) ) ) out <- layout_combo(list(top = NULL, side = aside_side), NULL, body("Body"), NULL, show_theme_button = TRUE) s <- as.character(out) expect_true(grepl('data-bs-theme="dark"', s)) expect_true(grepl("navbar-expand-lg", s)) }) test_that("layout_combo preserves arbitrary navbar tags (non-header/non-aside)", { # If navbar is a generic tag (e.g.