# #region Test.Maintenance.BannerRenderer.Coverage [C:3] [TYPE Module] [SEMANTICS test, maintenance, banner, coverage, REMOVED] # @BRIEF Tests for banner renderer uncovered paths — rebuild_banner with no text but chart_id present, update exception. # @RELATION BINDS_TO -> [MaintenanceBannerRenderer] import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent / "src")) from unittest.mock import AsyncMock, MagicMock, patch import pytest from src.models.maintenance import ( MaintenanceDashboardBanner, MaintenanceDashboardBannerStatus, MaintenanceDashboardState, MaintenanceEvent, MaintenanceEventStatus, MaintenanceSettings, ) class TestRebuildBannerCoverage: """Cover the 'no active events → mark REMOVED' path with chart_id set.""" @pytest.mark.asyncio async def test_no_active_events_with_chart_id_marks_removed(self): """banner_text empty but chart_id set → status set to REMOVED, returns True.""" from src.services.maintenance._banner_renderer import rebuild_banner db = MagicMock() banner = MaintenanceDashboardBanner( id="b1", status=MaintenanceDashboardBannerStatus.ACTIVE, chart_id=456, dashboard_id=1, environment_id="e1", banner_text="" ) settings = MaintenanceSettings(id="default", banner_template="Tpl", display_timezone="UTC") # Build per-model query mock objects banner_q = MagicMock() banner_q.filter.return_value.first.return_value = banner settings_q = MagicMock() settings_q.filter.return_value.first.return_value = settings state_q = MagicMock() state_q.filter.return_value.all.return_value = [] def query_side(model): if model == MaintenanceDashboardBanner: return banner_q if model == MaintenanceSettings: return settings_q if model == MaintenanceDashboardState: return state_q return MagicMock() db.query.side_effect = query_side result = await rebuild_banner("b1", db, AsyncMock()) assert result is True assert banner.status == MaintenanceDashboardBannerStatus.REMOVED @pytest.mark.asyncio async def test_update_banner_exception(self): """update_banner_on_dashboard raises → returns False.""" from src.services.maintenance._banner_renderer import rebuild_banner db = MagicMock() banner = MaintenanceDashboardBanner( id="b1", status=MaintenanceDashboardBannerStatus.ACTIVE, chart_id=123, dashboard_id=1, environment_id="e1", banner_text="" ) settings = MaintenanceSettings(id="default", banner_template="Msg: {message}", display_timezone="UTC") state = MaintenanceDashboardState(event_id="evt1", dashboard_id=1, banner_id="b1") ev = MaintenanceEvent(id="evt1", message="Hello", status=MaintenanceEventStatus.ACTIVE) # _build_banner_text_for_dashboard does: # .filter(banner_id == x, status == y).all() # (single .filter() call with TWO args, not two chained calls) state_q = MagicMock() state_q.filter.return_value.all.return_value = [state] # Build other query mocks def query_side(model): if model == MaintenanceDashboardBanner: m = MagicMock() m.filter.return_value.first.return_value = banner return m if model == MaintenanceSettings: m = MagicMock() m.filter.return_value.first.return_value = settings return m if model == MaintenanceDashboardState: return state_q if model == MaintenanceEvent: m = MagicMock() m.filter.return_value.first.return_value = ev return m return MagicMock() db.query.side_effect = query_side mock_superset = AsyncMock() mock_superset.update_banner_on_dashboard.side_effect = Exception("Update failed") result = await rebuild_banner("b1", db, mock_superset) assert result is False # #endregion Test.Maintenance.BannerRenderer.Coverage