diff --git a/pyproject.toml b/pyproject.toml index f29ecc69d61..b7a85f799d2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -212,6 +212,7 @@ development = [ "pyinstrument>=4.0.2,<5", "pylint", "pytest<8.0.0", # hairy issue with pytest >=8 where current_app proxies are not set in time + "pytest-asyncio", "pytest-cov", "pytest-mock", "python-ldap>=3.4.4", diff --git a/pytest.ini b/pytest.ini index 37ee2f0dd81..21945fb6a57 100644 --- a/pytest.ini +++ b/pytest.ini @@ -19,3 +19,4 @@ testpaths = tests python_files = *_test.py test_*.py *_tests.py *viz/utils.py addopts = -p no:warnings +asyncio_mode = auto diff --git a/requirements/development.txt b/requirements/development.txt index 99f02729df7..04c37be6b0b 100644 --- a/requirements/development.txt +++ b/requirements/development.txt @@ -775,8 +775,11 @@ pytest==7.4.4 # via # apache-superset # apache-superset-extensions-cli + # pytest-asyncio # pytest-cov # pytest-mock +pytest-asyncio==0.23.8 + # via apache-superset pytest-cov==6.0.0 # via # apache-superset diff --git a/tests/unit_tests/mcp_service/dataset/tool/test_dataset_tools.py b/tests/unit_tests/mcp_service/dataset/tool/test_dataset_tools.py index c01992f7472..30828b075b8 100644 --- a/tests/unit_tests/mcp_service/dataset/tool/test_dataset_tools.py +++ b/tests/unit_tests/mcp_service/dataset/tool/test_dataset_tools.py @@ -1160,37 +1160,32 @@ class TestDatasetSortableColumns: assert "database_name" not in SORTABLE_DATASET_COLUMNS assert "uuid" not in SORTABLE_DATASET_COLUMNS - @patch("superset.daos.dataset.DatasetDAO") + @patch("superset.daos.dataset.DatasetDAO.list") @patch("superset.mcp_service.auth.get_user_from_request") @pytest.mark.asyncio async def test_list_datasets_with_valid_order_column( - self, mock_get_user, mock_dataset_dao + self, mock_get_user, mock_dataset_list ): """Test list_datasets with valid order column.""" from superset.mcp_service.dataset.tool.list_datasets import list_datasets mock_get_user.return_value = MagicMock(id=1) - mock_tool = MagicMock() - mock_tool.run_tool.return_value = MagicMock(datasets=[], count=0) + # Mock the DAO to return empty list and count + mock_dataset_list.return_value = ([], 0) mock_ctx = MagicMock() mock_ctx.info = AsyncMock() mock_ctx.debug = AsyncMock() + mock_ctx.error = AsyncMock() - with patch( - "superset.mcp_service.dataset.tool.list_datasets.ModelListCore", - return_value=mock_tool, - ): - # Test with valid sortable column - request = ListDatasetsRequest( - order_column="table_name", order_direction="asc" - ) - await list_datasets.fn(request, mock_ctx) + # Test with valid sortable column + request = ListDatasetsRequest(order_column="table_name", order_direction="asc") + await list_datasets(request, mock_ctx) - # Verify the tool was called with the correct order column - mock_tool.run_tool.assert_called_once() - call_args = mock_tool.run_tool.call_args[1] - assert call_args["order_column"] == "table_name" - assert call_args["order_direction"] == "asc" + # Verify the DAO was called with the correct order column + mock_dataset_list.assert_called_once() + call_args = mock_dataset_list.call_args[1] + assert call_args["order_column"] == "table_name" + assert call_args["order_direction"] == "asc" def test_sortable_columns_in_docstring(self): """Test that sortable columns are documented in tool docstring.""" @@ -1205,27 +1200,28 @@ class TestDatasetSortableColumns: for col in SORTABLE_DATASET_COLUMNS: assert col in list_datasets.__doc__ + @patch("superset.daos.dataset.DatasetDAO.list") + @patch("superset.mcp_service.auth.get_user_from_request") @pytest.mark.asyncio - async def test_default_ordering(self): + async def test_default_ordering(self, mock_get_user, mock_dataset_list): """Test default ordering behavior for datasets.""" from superset.mcp_service.dataset.tool.list_datasets import list_datasets - # Test that when no order_column is specified, None is passed - with patch( - "superset.mcp_service.dataset.tool.list_datasets.ModelListCore" - ) as mock_tool: - with patch("superset.mcp_service.auth.get_user_from_request"): - mock_tool.return_value.run_tool.return_value = MagicMock( - datasets=[], count=0 - ) - mock_ctx = MagicMock() - mock_ctx.info = AsyncMock() - mock_ctx.debug = AsyncMock() - request = ListDatasetsRequest() # No order specified - await list_datasets.fn(request, mock_ctx) + mock_get_user.return_value = MagicMock(id=1) + # Mock the DAO to return empty list and count + mock_dataset_list.return_value = ([], 0) + mock_ctx = MagicMock() + mock_ctx.info = AsyncMock() + mock_ctx.debug = AsyncMock() + mock_ctx.error = AsyncMock() + request = ListDatasetsRequest() # No order specified + await list_datasets(request, mock_ctx) - call_args = mock_tool.return_value.run_tool.call_args[1] - assert call_args["order_column"] is None # None when not specified - assert ( - call_args["order_direction"] == "desc" - ) # From ListDatasetsRequest default + # When order_column is None, the default "changed_on" is used by ModelListCore + call_args = mock_dataset_list.call_args[1] + assert ( + call_args["order_column"] == "changed_on" + ) # Default applied by ModelListCore + assert ( + call_args["order_direction"] == "desc" + ) # From ListDatasetsRequest default