Skip to content

Commit

Permalink
adding unit tests for navitem
Browse files Browse the repository at this point in the history
  • Loading branch information
nadijagraca committed Nov 7, 2023
1 parent df06b4b commit 4ff1100
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 152 deletions.
77 changes: 36 additions & 41 deletions vizro-core/tests/unit/vizro/models/_navigation/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ def accordion_from_pages_as_dict():


@pytest.fixture
def navbar_div_default():
def navbar_div_from_dict(accordion_from_page_as_list):
accordion = accordion_from_page_as_list
return html.Div(
children=[
html.Div(
Expand All @@ -120,58 +121,52 @@ def navbar_div_default():
href="/",
active=True,
),
dbc.Button(
id="nav_id_2",
children=[
html.Div(
children=[
html.Span("dashboard", className="material-symbols-outlined"),
html.Div(className="hidden"),
],
className="nav-icon-text",
),
None,
],
className="icon-button",
href="/page-2",
active=False,
),
],
className="nav-bar",
id="nav_bar_outer",
),
html.Div(hidden=True, id="nav_panel_outer"),
accordion,
]
)


@pytest.fixture
def navbar_div_from_dict(accordion_from_page_as_list):
accordion = accordion_from_page_as_list
return html.Div(
def nav_item_default():
return dbc.Button(
id="navitem",
children=[
html.Div(
children=[html.Span("dashboard", className="material-symbols-outlined"), html.Div(className="hidden")],
className="nav-icon-text",
),
None,
],
className="icon-button",
href="/",
active=True,
)


@pytest.fixture
def nav_item_with_optional():
return dbc.Button(
id="navitem",
children=[
html.Div(
children=[
dbc.Button(
id="nav_id_1",
children=[
html.Div(
children=[
html.Span("dashboard", className="material-symbols-outlined"),
html.Div(className="hidden"),
],
className="nav-icon-text",
),
None,
],
className="icon-button",
href="/",
active=True,
),
html.Span("home", className="material-symbols-outlined"),
html.Div(children=["This is "], className="icon-text"),
],
className="nav-bar",
id="nav_bar_outer",
className="nav-icon-text",
),
accordion,
]
dbc.Tooltip(
children=html.P("This is a long text input"),
target="navitem",
placement="bottom",
className="custom-tooltip",
),
],
className="icon-button",
href="/",
active=True,
)
154 changes: 43 additions & 111 deletions vizro-core/tests/unit/vizro/models/_navigation/test_nav_bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,38 @@
from pydantic import ValidationError

import vizro.models as vm
from dash import html


@pytest.mark.usefixtures("vizro_app", "dashboard_prebuild")
class TestNavBarInstantiation:
"""Tests accordion model instantiation."""
"""Tests NavBar model instantiation."""

def test_navbar_mandatory_only(self):
navigation = vm.NavBar()
assert hasattr(navigation, "id")
assert navigation.pages == ["Page 1", "Page 2"]
nav_bar = vm.NavBar()

assert hasattr(nav_bar, "id")
assert nav_bar.type == "navbar"
assert nav_bar.pages == ["Page 1", "Page 2"]

def test_navbar_valid_pages_as_list(self, pages_as_list):
nav_bar = vm.NavBar(pages=pages_as_list, id="nav_bar")

assert nav_bar.id == "nav_bar"
assert nav_bar.type == "navbar"
assert nav_bar.pages == pages_as_list

def test_navbar_valid_pages_as_dict(self, pages_as_dict):
nav_bar = vm.NavBar(pages=pages_as_dict, id="nav_bar")

assert nav_bar.id == "nav_bar"
assert nav_bar.type == "navbar"
assert nav_bar.pages == pages_as_dict

def test_navbar_valid_pages_not_all_included(self):
nav_bar = vm.NavBar(pages=["Page 1"], id="nav_bar")

assert nav_bar.id == "nav_bar"
assert nav_bar.type == "navbar"
assert nav_bar.pages == ["Page 1"]

def test_navbar_invalid_pages_empty_list(self):
Expand All @@ -46,120 +51,47 @@ def test_navbar_invalid_pages_unknown_page(self):


@pytest.mark.usefixtures("vizro_app", "dashboard_prebuild")
def test_navbar_build_default(navbar_div_default):
navbar = vm.NavBar()

navbar.items[0].id = "nav_id_1"
navbar.items[1].id = "nav_id_2"
result = json.loads(json.dumps(navbar.build(active_page_id="Page 1"), cls=plotly.utils.PlotlyJSONEncoder))
expected = json.loads(json.dumps(navbar_div_default, cls=plotly.utils.PlotlyJSONEncoder))

assert result == expected


@pytest.mark.usefixtures("vizro_app", "dashboard_prebuild")
def test_navbar_build_pages_as_list(navbar_div_default):
navbar = vm.NavBar(pages=["Page 1", "Page 2"])

navbar.items[0].id = "nav_id_1"
navbar.items[1].id = "nav_id_2"
result = json.loads(json.dumps(navbar.build(active_page_id="Page 1"), cls=plotly.utils.PlotlyJSONEncoder))
expected = json.loads(json.dumps(navbar_div_default, cls=plotly.utils.PlotlyJSONEncoder))

assert result == expected


@pytest.mark.usefixtures("vizro_app", "dashboard_prebuild")
def test_navbar_build_pages_as_dict(navbar_div_from_dict):
navbar = vm.NavBar(pages={"Icon": ["Page 1", "Page 2"]})

navbar.items[0].id = "accordion_list"
result = json.loads(json.dumps(navbar.build(active_page_id="Page 1"), cls=plotly.utils.PlotlyJSONEncoder))

print("result>>>>", result)
expected = json.loads(json.dumps(navbar_div_from_dict, cls=plotly.utils.PlotlyJSONEncoder))

assert result == expected


@pytest.mark.usefixtures("vizro_app", "dashboard_prebuild")
def test_navbar_build_items(navbar_div_default):
navbar = vm.NavBar(items=[vm.NavItem(pages=["Page 1"]), vm.NavItem(pages=["Page 2"])])
navbar.items[0].id = "nav_id_1"
navbar.items[1].id = "nav_id_2"
class TestNavBarBuildMethod:
"""Tests NavBar model build method."""

result = json.loads(json.dumps(navbar.build(active_page_id="Page 1"), cls=plotly.utils.PlotlyJSONEncoder))
expected = json.loads(json.dumps(navbar_div_default, cls=plotly.utils.PlotlyJSONEncoder))
def test_navbar_build_default(self, navbar_div_default):
navbar = vm.NavBar()
navbar.items[0].id, navbar.items[1].id = "nav_id_1", "nav_id_2"

assert result == expected
result = json.loads(json.dumps(navbar.build(active_page_id="Page 1"), cls=plotly.utils.PlotlyJSONEncoder))
expected = json.loads(json.dumps(navbar_div_default, cls=plotly.utils.PlotlyJSONEncoder))

assert result == expected

@pytest.mark.usefixtures("vizro_app", "dashboard_prebuild")
@pytest.mark.parametrize("pages", [(["Page 1", "Page 2"]), ([["Page 1"], ["Page 2"]])])
def test_navbar_and_navigation_build_default(navbar_div_default, pages):
if isinstance(pages[0], str):
@pytest.mark.parametrize(
"pages",
[
(["Page 1", "Page 2"]), # pages provided as list
({"Icon 1": ["Page 1"], "Icon 2": ["Page 2"]}), # pages provided as dict
],
)
def test_navbar_build_pages(self, navbar_div_default, pages):
navbar = vm.NavBar(pages=pages)
else:
navbar = vm.NavBar(items=[vm.NavItem(pages=pages[0]), vm.NavItem(pages=pages[1])])

navbar.items[0].id = "nav_id_1"
navbar.items[1].id = "nav_id_2"
result = json.loads(json.dumps(navbar.build(active_page_id="Page 1"), cls=plotly.utils.PlotlyJSONEncoder))
expected = json.loads(json.dumps(navbar_div_default, cls=plotly.utils.PlotlyJSONEncoder))
navbar.items[0].id, navbar.items[1].id = "nav_id_1", "nav_id_2"
navbar.items[0].selector.id, navbar.items[1].selector.id = "accordion_list", "accordion_list"

assert result == expected
result = json.loads(json.dumps(navbar.build(active_page_id="Page 1"), cls=plotly.utils.PlotlyJSONEncoder))
expected = json.loads(json.dumps(navbar_div_default, cls=plotly.utils.PlotlyJSONEncoder))

assert result == expected

@pytest.mark.usefixtures("vizro_app", "dashboard_prebuild")
@pytest.mark.parametrize(
"nav_pages, item_pages",
[
(["Page 1", "Page 2"], [["Page 1"], ["Page 2"]]),
(
{"title_1": ["Page 1", "Page 2"], "title_2": ["Page 1", "Page 2"]},
[["Page 1", "Page 2"], ["Page 1", "Page 2"]],
),
],
)
def test_navbar_and_navigation_build_equality(nav_pages, item_pages, nav_id_1="nav_id_1", nav_id_2="nav_id_2"):
navbar_with_pages = vm.NavBar(pages=nav_pages)
navbar_with_items = vm.NavBar(items=[vm.NavItem(pages=item_pages[0]), vm.NavItem(pages=item_pages[1])])

navbar_with_pages.items[0].id, navbar_with_pages.items[1].id = nav_id_1, nav_id_2
navbar_with_pages.items[0].selector.id, navbar_with_pages.items[1].selector.id = "accordion_1", "accordion_2"

navbar_with_items.items[0].id, navbar_with_items.items[1].id = nav_id_1, nav_id_2
navbar_with_items.items[0].selector.id, navbar_with_items.items[1].selector.id = "accordion_1", "accordion_2"

navbar_with_pages = json.loads(
json.dumps(navbar_with_pages.build(active_page_id="Page 1"), cls=plotly.utils.PlotlyJSONEncoder)
)
navbar_with_items = json.loads(
json.dumps(navbar_with_items.build(active_page_id="Page 1"), cls=plotly.utils.PlotlyJSONEncoder)
@pytest.mark.parametrize(
"nav_item_1, nav_item_2",
[
(["Page 1"], ["Page 2"]), # NavItem pages provided as list
({"Icon 1": ["Page 1"]}, {"Icon 2": ["Page 2"]}), # NavItem pages provided as dict
],
)
def test_navbar_build_items(self, navbar_div_default, nav_item_1, nav_item_2):
navbar = vm.NavBar(items=[vm.NavItem(pages=nav_item_1), vm.NavItem(pages=nav_item_2)])
navbar.items[0].id, navbar.items[1].id = "nav_id_1", "nav_id_2"

assert navbar_with_pages == navbar_with_items


@pytest.mark.usefixtures("vizro_app", "dashboard_prebuild")
@pytest.mark.parametrize(
"nav_pages, item_pages",
[
(["Page 1"], ["Page 1"]),
({"title_1": ["Page 1"]}, {"title_1": ["Page 1"]}),
],
)
def test_navbar_build_equality(nav_pages, item_pages, nav_id="nav_id"):
navbar_with_pages = vm.NavBar(pages=nav_pages)
navbar_with_items = vm.NavBar(items=[vm.NavItem(pages=item_pages, id=nav_id)])

navbar_with_pages.items[0].id = nav_id

navbar_with_pages = json.loads(
json.dumps(navbar_with_pages.build(active_page_id="Page 1"), cls=plotly.utils.PlotlyJSONEncoder)
)
navbar_with_items = json.loads(
json.dumps(navbar_with_items.build(active_page_id="Page 1"), cls=plotly.utils.PlotlyJSONEncoder)
)
result = json.loads(json.dumps(navbar.build(active_page_id="Page 1"), cls=plotly.utils.PlotlyJSONEncoder))
expected = json.loads(json.dumps(navbar_div_default, cls=plotly.utils.PlotlyJSONEncoder))

assert navbar_with_pages == navbar_with_items
assert result == expected
75 changes: 75 additions & 0 deletions vizro-core/tests/unit/vizro/models/_navigation/test_nav_item.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
"""Unit tests for vizro.models.NavItem."""
import json
import re

import plotly
import pytest
from pydantic import ValidationError

import vizro.models as vm


@pytest.mark.usefixtures("vizro_app", "dashboard_prebuild")
class TestNavItemInstantiation:
"""Tests NavItem model instantiation."""

def test_navitem_mandatory_only(self):
nav_item = vm.NavItem(pages=["Page 1", "Page 2"])

assert nav_item.type == "navitem"
assert nav_item.pages == ["Page 1", "Page 2"]
assert nav_item.icon == "dashboard"
assert nav_item.max_text_length == 8
assert hasattr(nav_item, "id")
assert hasattr(nav_item, "text")
assert hasattr(nav_item, "tooltip")
assert hasattr(nav_item, "selector")

def test_navitem_mandatory_and_optional(self):
nav_item = vm.NavItem(
pages=["Page 1", "Page 2"], id="nav_item", icon="home", text="Homepage", tooltip="Homepage icon"
)

assert nav_item.id == "nav_item"
assert nav_item.type == "navitem"
assert nav_item.pages == ["Page 1", "Page 2"]
assert nav_item.icon == "home"
assert nav_item.text == "Homepage"
assert nav_item.tooltip == "Homepage icon"

def test_navitem_text_validation(self):
nav_item = vm.NavItem(pages=["Page 1"], text="Homepage", tooltip="Homepage icon")
nav_item.set_text_and_tooltip()
assert nav_item.text == "Homepage"
assert nav_item.tooltip == "Homepage icon"

def test_navitem_invalid_pages_empty_list(self):
with pytest.raises(ValidationError, match="Ensure this value has at least 1 item."):
vm.NavItem(pages=[], id="nav_item")

def test_navitem_invalid_pages_unknown_page(self):
with pytest.raises(ValidationError, match=re.escape("Unknown page ID ['Test'] provided to argument 'pages'.")):
vm.NavItem(pages=["Test"], id="nav_item")


@pytest.mark.usefixtures("vizro_app", "dashboard_prebuild")
class TestNavItemBuildMethod:
"""Tests NavItem model build method."""

def test_navitem_build_mandatory_only(self, nav_item_default):
nav_item = vm.NavItem(pages=["Page 1", "Page 2"])
nav_item.id = "navitem"

result = json.loads(json.dumps(nav_item.build(active_page_id="Page 1"), cls=plotly.utils.PlotlyJSONEncoder))
expected = json.loads(json.dumps(nav_item_default, cls=plotly.utils.PlotlyJSONEncoder))

assert result == expected

def test_navitem_build_mandatory_and_optional(self, nav_item_with_optional):
nav_item = vm.NavItem(pages=["Page 1", "Page 2"], icon="home", text="This is a long text input")
nav_item.id = "navitem"

result = json.loads(json.dumps(nav_item.build(active_page_id="Page 1"), cls=plotly.utils.PlotlyJSONEncoder))
expected = json.loads(json.dumps(nav_item_with_optional, cls=plotly.utils.PlotlyJSONEncoder))

assert result == expected
Loading

0 comments on commit 4ff1100

Please sign in to comment.