import pytest from fastcore.basics import NotStr from fasthtml.components import * from components.tabs.components.MyTabs import Tab, MyTabs from components.tabs.constants import ROUTE_ROOT, Routes from tests.helpers import matches, find_first_match, search_elements_by_name, div_ellipsis @pytest.fixture def tabs_instance(): """Fixture to create an instance of tabs_instance with a mock session and ID.""" session = {'user_id': 'test_user'} _id = 'test_tabs' return MyTabs(session, _id) def test_initial_tabs_empty(tabs_instance): """Test that the tabs are initially empty.""" assert len(tabs_instance.tabs) == 0 def test_select_tab_empty(tabs_instance): """Test the select_tab method when no tabs are available.""" tabs_instance.select_tab_by_id("1") # Tab ID "1" doesn't exist assert len(tabs_instance.tabs) == 0 # No changes should occur def test_add_tab_and_select_tab(tabs_instance): """Test adding tabs and using the select_tab method.""" # Add some tabs tabs_instance.tabs = [ Tab("1", "Tab1", "Content 1"), Tab("2", "Tab2", "Content 2", active=True), Tab("3", "Tab3", "Content 3"), ] # Select a specific tab tabs_instance.select_tab_by_id("3") assert tabs_instance.tabs[0].active is False assert tabs_instance.tabs[1].active is False assert tabs_instance.tabs[2].active is True def test_add_tab_creates_a_new_tab(tabs_instance): title = "Test Tab" content = "This is a test content." tab_id = tabs_instance.add_tab(title=title, content=content) assert len(tabs_instance.tabs) == 1 assert tabs_instance.tabs[0].id == tab_id assert tabs_instance.tabs[0].title == title assert tabs_instance.tabs[0].content == content def test_add_tab_with_key_replaces_existing_tab(tabs_instance): key = "test_key" title1 = "Tab 1" content1 = "Content 1" title2 = "Tab 2" content2 = "Content 2" tab_id1 = tabs_instance.add_tab(title=title1, content=content1, key=key) tab_id2 = tabs_instance.add_tab(title=title2, content=content2, key=key) assert tab_id1 == tab_id2 assert len(tabs_instance.tabs) == 1 assert tabs_instance.tabs[0].title == title2 assert tabs_instance.tabs[0].content == content2 def test_add_tab_no_key_creates_unique_tabs(tabs_instance): title1 = "First Tab" content1 = "First Tab Content" title2 = "Second Tab" content2 = "Second Tab Content" tab_id1 = tabs_instance.add_tab(title=title1, content=content1) tab_id2 = tabs_instance.add_tab(title=title2, content=content2) assert tab_id1 != tab_id2 assert len(tabs_instance.tabs) == 2 assert tabs_instance.tabs[0].id == tab_id1 assert tabs_instance.tabs[1].id == tab_id2 def test_add_tab_selects_new_tab_active(tabs_instance): title = "Active Tab" content = "Active Tab Content" tabs_instance.add_tab(title=title, content=content) assert tabs_instance.get_active_tab_content() == content def test_add_tab_with_icon_attribute(tabs_instance): title = "Tab With Icon" content = "Tab Content" icon = "test_icon_path" tab_id = tabs_instance.add_tab(title=title, content=content, icon=icon) assert len(tabs_instance.tabs) == 1 assert tabs_instance.tabs[0].id == tab_id assert tabs_instance.tabs[0].icon == icon def test_remove_tab(tabs_instance): """Test the remove_tab method.""" # Add some tabs tabs_instance.tabs = [ Tab("1", "Tab1", "Content 1"), Tab("2", "Tab2", "Content 2", active=True), Tab("3", "Tab3", "Content 3"), ] # Remove a tab tabs_instance.remove_tab("2") assert len(tabs_instance.tabs) == 2 assert tabs_instance.tabs[0].id == "1" assert tabs_instance.tabs[1].id == "3" assert all(tab.id != "2" for tab in tabs_instance.tabs) def test_get_active_tab_content(tabs_instance): """Test the get_active_tab_content method.""" # Initially, no content should be active (empty tabs list) assert tabs_instance.get_active_tab_content() is None # Add some tabs tabs_instance.tabs = [ Tab("1", "Tab1", "Content 1"), Tab("2", "Tab2", "Content 2", active=True), Tab("3", "Tab3", "Content 3"), ] # Verify the content of the active tab assert tabs_instance.get_active_tab_content() == "Content 2" # Change the active tab to Tab1 and verify tabs_instance.select_tab_by_id("1") assert tabs_instance.get_active_tab_content() == "Content 1" # Remove all tabs and check active content is None tabs_instance.tabs.clear() assert tabs_instance.get_active_tab_content() is None def test_there_always_an_active_tab_after_removal(tabs_instance): tabs_instance.tabs = [ Tab("1", "Tab1", "Content 1"), Tab("2", "Tab2", "Content 2", active=True), Tab("3", "Tab3", "Content 3"), ] tabs_instance.remove_tab("2") assert tabs_instance.tabs[0].active is True assert tabs_instance.tabs[1].active is False def test_do_no_change_the_active_tab_if_another_tab_is_removed(tabs_instance): tabs_instance.tabs = [ Tab("1", "Tab1", "Content 1"), Tab("2", "Tab2", "Content 2"), Tab("3", "Tab3", "Content 3", active=True), ] tabs_instance.remove_tab("1") assert tabs_instance.tabs[0].active is False assert tabs_instance.tabs[1].active is True def test_render_empty_when_empty(tabs_instance): actual = tabs_instance.__ft__() expected = Div(id=tabs_instance._id) assert matches(actual, expected) def test_render_when_multiple_tabs(tabs_instance): tabs_instance.tabs = [ Tab("1", "Tab1", "Content 1"), Tab("2", "Tab2", "Content 2", active=True), Tab("3", "Tab3", "Content 3"), ] actual = tabs_instance.__ft__() to_compare = search_elements_by_name(actual, "div", {"id": tabs_instance._id}) expected = Div( Div( Span(cls="mmt-tabs-tab "), Span(cls="mmt-tabs-tab mmt-tabs-active"), Span(cls="mmt-tabs-tab "), cls="mmt-tabs-header" ), Div("Content 2", cls="mmt-tabs-content"), id=tabs_instance._id, cls="mmt-tabs", ) assert matches(to_compare[0], expected) def test_render_a_tab_header_with_its_name_and_the_cross_to_close(tabs_instance): tabs_instance.tabs = [ Tab("1", "Tab1", "Content 1"), ] actual = tabs_instance.__ft__() expected = Span( Label(div_ellipsis("Tab1"), hx_post=f"{ROUTE_ROOT}{Routes.SelectTab}"), Div(NotStr('