import pytest from unittest.mock import MagicMock, patch from src.gui_2 import App, C_LBL, C_VAL from src.models import Ticket def test_render_mma_dashboard_progress(): # Create a mock for the imgui module used in gui_2 mock_imgui = MagicMock() # Configure ImVec4 and ImVec2 mock_imgui.ImVec2 = MagicMock(side_effect=lambda x, y: (float(x), float(y))) mock_imgui.ImVec4 = MagicMock(side_effect=lambda r, g, b, a: (float(r), float(g), float(b), float(a))) # Configure calls that return tuples mock_imgui.input_text_multiline.return_value = (False, "") mock_imgui.input_text.return_value = (False, "") mock_imgui.checkbox.return_value = (False, False) mock_imgui.begin_combo.return_value = (False, "") mock_imgui.selectable.return_value = (False, False) mock_imgui.begin_table.return_value = True mock_imgui.collapsing_header.return_value = False # Patch where it is actually used with patch('src.gui_2.imgui', mock_imgui), \ patch('src.gui_2.cost_tracker.estimate_cost', return_value=0.0): # Mock App instance - no spec because of delegation app = MagicMock() # Setup mock state app.active_track = MagicMock() app.active_track.description = "Test Track" # Mock self.active_track.tickets as a list of src.models.Ticket objects app.active_track.tickets = [ Ticket(id='T1', description='desc', status='completed'), Ticket(id='T2', description='desc', status='in_progress'), Ticket(id='T3', description='desc', status='blocked'), Ticket(id='T4', description='desc', status='todo') ] app.is_viewing_prior_session = False app.perf_profiling_enabled = False app.mma_tier_usage = {} app.mma_status = "idle" app.active_tier = None app._pending_mma_spawn = None app._pending_mma_approval = None app._pending_ask_dialog = False app.tracks = [] app.ui_epic_input = "" app.ui_conductor_setup_summary = "" app.ui_new_track_name = "" app.ui_new_track_desc = "" app.ui_new_track_type = "feature" app.mma_step_mode = False app.node_editor_ctx = None app._avg_ticket_time = 60 # Call the method App._render_mma_dashboard(app) # Assertions # 1 completed out of 4 tickets = 25.0% progress # Update assertions: imgui.progress_bar is called with (0.25, (-1.0, 0.0), '25.0%') mock_imgui.progress_bar.assert_any_call(0.25, (-1.0, 0.0), "25.0%") # Verify status breakdown counts are asserted via imgui.text_colored calls mock_imgui.text_colored.assert_any_call(C_LBL, "Completed:") mock_imgui.text_colored.assert_any_call(C_VAL, "1") mock_imgui.text_colored.assert_any_call(C_LBL, "In Progress:") mock_imgui.text_colored.assert_any_call(C_VAL, "1") mock_imgui.text_colored.assert_any_call(C_LBL, "Blocked:") mock_imgui.text_colored.assert_any_call(C_VAL, "1") mock_imgui.text_colored.assert_any_call(C_LBL, "Todo:") mock_imgui.text_colored.assert_any_call(C_VAL, "1")