# #region TestTestDatasetDashboardRelations [C:2] [TYPE Module] [SEMANTICS test,dataset,dashboard,superset] # @BRIEF Tests for test_dataset_dashboard_relations script (mocked Superset API, no real connection). # @RELATION BINDS_TO -> [test_dataset_dashboard_relations_script] # @TEST_EDGE: script_has_if_name_guard -> Module executes only under __main__ # @TEST_EDGE: test_function_calls_client -> Verifies client authentication and API calls # @TEST_EDGE: dashboard_response_parsing -> Handles slices in dashboard # @TEST_EDGE: dataset_response_parsing -> Handles dataset structure # @TEST_EDGE: related_objects_dashboards -> Parses dashboards from related_objects # @TEST_EDGE: related_objects_wrapped_result -> Handles result wrapper # @TEST_EDGE: no_slices_in_dashboard -> Warns when slices missing # @TEST_EDGE: related_objects_exception -> Logs error without crashing import sys from pathlib import Path from unittest.mock import MagicMock, patch, call import json import pytest sys.path.insert(0, str(Path(__file__).parent.parent.parent / "src")) class TestTestDatasetDashboardRelations: """Tests for test_dataset_dashboard_relations module.""" def test_module_has_if_name_guard(self): """Structural: module has __main__ guard.""" src_path = Path(__file__).parent.parent.parent / "src" / "scripts" / "test_dataset_dashboard_relations.py" source = src_path.read_text(encoding="utf-8") # Check that `if __name__ == "__main__":` or equivalent guard exists assert 'if __name__ == "__main__":' in source, "Module must have if __name__ guard" @patch("src.scripts.test_dataset_dashboard_relations.ConfigManager") @patch("src.scripts.test_dataset_dashboard_relations.SupersetClient") def test_test_function_calls_client_authenticate( self, MockSupersetClient, MockConfigManager ): """Happy: test_dashboard_dataset_relations authenticates and fetches dashboard/dataset.""" from src.scripts.test_dataset_dashboard_relations import test_dashboard_dataset_relations # Mock environments env_mock = MagicMock() env_mock.name = "test-env" env_mock.url = "http://superset.test" MockConfigManager.return_value.get_environments.return_value = [env_mock] # Mock client mock_client = MagicMock() # Dashboard response with slices mock_client.network.request.side_effect = [ # First call: GET /dashboard/13 { "id": 13, "dashboard_title": "Test Dashboard", "published": True, "slices": [ {"slice_id": 1, "slice_name": "Chart 1", "datasource_id": 26, "datasource_type": "table"} ], "position_json": '{"DASHBOARD_VERSION_KEY": "v2"}', }, # Second call: GET /dataset/26/related_objects { "dashboards": [ {"id": 13, "dashboard_title": "Test Dashboard"}, {"id": 14, "dashboard_title": "Another Dashboard"}, ] }, ] # get_dataset response mock_client.get_dataset.return_value = { "id": 26, "table_name": "test_table", "schema": "public", "database": {"database_name": "test_db"}, } MockSupersetClient.return_value = mock_client # Patch sys.stdout to suppress prints with patch("sys.stdout"): test_dashboard_dataset_relations() mock_client.authenticate.assert_called_once() # Check that dashboard and dataset were fetched assert mock_client.network.request.call_count >= 2 @patch("src.scripts.test_dataset_dashboard_relations.ConfigManager") @patch("src.scripts.test_dataset_dashboard_relations.SupersetClient") def test_no_slices_in_dashboard_warns( self, MockSupersetClient, MockConfigManager ): """Edge: dashboard without slices field logs warning.""" from src.scripts.test_dataset_dashboard_relations import test_dashboard_dataset_relations env_mock = MagicMock() env_mock.name = "test-env" env_mock.url = "http://superset.test" MockConfigManager.return_value.get_environments.return_value = [env_mock] mock_client = MagicMock() mock_client.network.request.side_effect = [ # Dashboard without slices key { "id": 13, "dashboard_title": "No Slices Dashboard", "published": True, }, # related_objects {"dashboards": []}, ] mock_client.get_dataset.return_value = { "id": 26, "table_name": "test_table", } MockSupersetClient.return_value = mock_client with patch("sys.stdout"): test_dashboard_dataset_relations() # Should not crash — just warns about missing slices mock_client.authenticate.assert_called_once() @patch("src.scripts.test_dataset_dashboard_relations.ConfigManager") @patch("src.scripts.test_dataset_dashboard_relations.SupersetClient") def test_related_objects_wrapped_in_result( self, MockSupersetClient, MockConfigManager ): """Edge: related_objects response wrapped in 'result' key.""" from src.scripts.test_dataset_dashboard_relations import test_dashboard_dataset_relations env_mock = MagicMock() env_mock.name = "test-env" MockConfigManager.return_value.get_environments.return_value = [env_mock] mock_client = MagicMock() mock_client.network.request.side_effect = [ {"id": 13, "dashboard_title": "Test", "slices": []}, {"result": {"dashboards": [{"id": 13, "dashboard_title": "Wrapped"}]}}, ] mock_client.get_dataset.return_value = {"id": 26, "table_name": "t"} MockSupersetClient.return_value = mock_client with patch("sys.stdout"): test_dashboard_dataset_relations() mock_client.authenticate.assert_called_once() @patch("src.scripts.test_dataset_dashboard_relations.ConfigManager") @patch("src.scripts.test_dataset_dashboard_relations.SupersetClient") def test_related_objects_exception_handled( self, MockSupersetClient, MockConfigManager ): """Edge: exception in related_objects fetch is caught, not propagated.""" from src.scripts.test_dataset_dashboard_relations import test_dashboard_dataset_relations env_mock = MagicMock() env_mock.name = "test-env" MockConfigManager.return_value.get_environments.return_value = [env_mock] mock_client = MagicMock() def request_side_effect(method=None, endpoint=None, **kwargs): if "related_objects" in (endpoint or ""): raise RuntimeError("API unavailable") return {"id": 13, "dashboard_title": "Test", "slices": []} mock_client.network.request.side_effect = request_side_effect mock_client.get_dataset.return_value = {"id": 26, "table_name": "t"} MockSupersetClient.return_value = mock_client with patch("sys.stdout"): # Should not raise — exception is caught and logged test_dashboard_dataset_relations() mock_client.authenticate.assert_called_once() @patch("src.scripts.test_dataset_dashboard_relations.ConfigManager") @patch("src.scripts.test_dataset_dashboard_relations.SupersetClient") def test_no_environments_logs_error( self, MockSupersetClient, MockConfigManager ): """Edge: no configured environments logs error and returns.""" from src.scripts.test_dataset_dashboard_relations import test_dashboard_dataset_relations MockConfigManager.return_value.get_environments.return_value = [] with patch("sys.stdout"): test_dashboard_dataset_relations() # Should not crash, but authenticate should NOT be called MockSupersetClient.return_value.authenticate.assert_not_called() # #endregion TestTestDatasetDashboardRelations