From de162cb491aadf9211f78602f632da831653c064 Mon Sep 17 00:00:00 2001 From: shehab-badawy Date: Thu, 11 Sep 2025 16:06:20 -0400 Subject: [PATCH 1/5] feat: Add preview step to delete command Signed-off-by: shehab-badawy --- cognee/cli/commands/delete_command.py | 55 +++++++++++++----- .../data/methods/get_deletion_counts.py | 57 +++++++++++++++++++ 2 files changed, 99 insertions(+), 13 deletions(-) create mode 100644 cognee/modules/data/methods/get_deletion_counts.py diff --git a/cognee/cli/commands/delete_command.py b/cognee/cli/commands/delete_command.py index 43e8b8e13..c9d13890e 100644 --- a/cognee/cli/commands/delete_command.py +++ b/cognee/cli/commands/delete_command.py @@ -6,6 +6,7 @@ from cognee.cli.reference import SupportsCliCommand from cognee.cli import DEFAULT_DOCS_URL import cognee.cli.echo as fmt from cognee.cli.exceptions import CliCommandException, CliCommandInnerException +from cognee.modules.data.methods.get_deletion_counts import get_deletion_counts class DeleteCommand(SupportsCliCommand): @@ -41,29 +42,56 @@ Be careful with deletion operations as they are irreversible. fmt.error("Please specify what to delete: --dataset-name, --user-id, or --all") return - # Build confirmation message - if args.all: - confirm_msg = "Delete ALL data from cognee?" - operation = "all data" - elif args.dataset_name: - confirm_msg = f"Delete dataset '{args.dataset_name}'?" - operation = f"dataset '{args.dataset_name}'" - elif args.user_id: - confirm_msg = f"Delete all data for user '{args.user_id}'?" - operation = f"data for user '{args.user_id}'" - - # Confirm deletion unless forced + # If --force is used, skip the preview and go straight to deletion if not args.force: + # --- START PREVIEW LOGIC --- + fmt.echo("Gathering data for preview...") + preview_data = asyncio.run( + get_deletion_counts( + dataset_name=args.dataset_name, + user_id=args.user_id, + all_data=args.all, + ) + ) + + if not preview_data or all(value == 0 for value in preview_data.values()): + fmt.success("No data found to delete.") + return + + fmt.echo("You are about to delete:") + if "datasets" in preview_data and preview_data["datasets"] > 0: + fmt.echo(f"- {preview_data['datasets']} datasets") + if "data_entries" in preview_data and preview_data["data_entries"] > 0: + fmt.echo(f"- {preview_data['data_entries']} data entries") + if "users" in preview_data and preview_data["users"] > 0: + fmt.echo( + f"- {preview_data['users']} {'users' if preview_data['users'] > 1 else 'user'}" + ) + fmt.echo("-" * 20) + fmt.warning("This operation is irreversible!") - if not fmt.confirm(confirm_msg): + if not fmt.confirm("Proceed?"): fmt.echo("Deletion cancelled.") return + # --- END PREVIEW LOGIC --- + + # Build operation message for success/failure logging + if args.all: + operation = "all data" + elif args.dataset_name: + operation = f"dataset '{args.dataset_name}'" + elif args.user_id: + operation = f"data for user '{args.user_id}'" + else: + operation = "data" fmt.echo(f"Deleting {operation}...") # Run the async delete function async def run_delete(): try: + # NOTE: The underlying cognee.delete() function is currently not working as expected. + # This is a separate bug that this preview feature helps to expose. if args.all: await cognee.delete(dataset_name=None, user_id=args.user_id) else: @@ -72,6 +100,7 @@ Be careful with deletion operations as they are irreversible. raise CliCommandInnerException(f"Failed to delete: {str(e)}") asyncio.run(run_delete()) + # This success message may be inaccurate due to the underlying bug, but we leave it for now. fmt.success(f"Successfully deleted {operation}") except Exception as e: diff --git a/cognee/modules/data/methods/get_deletion_counts.py b/cognee/modules/data/methods/get_deletion_counts.py new file mode 100644 index 000000000..cdd222645 --- /dev/null +++ b/cognee/modules/data/methods/get_deletion_counts.py @@ -0,0 +1,57 @@ +from sqlalchemy import select +from sqlalchemy.sql import func +from cognee.infrastructure.databases.relational import get_relational_engine +from cognee.modules.data.models import Dataset, Data, DatasetData +from cognee.modules.users.models import User + + +async def get_deletion_counts( + dataset_name: str = None, user_id: str = None, all_data: bool = False +) -> dict: + """ + Calculates the number of items that will be deleted based on the provided arguments. + """ + relational_engine = get_relational_engine() + async with relational_engine.get_async_session() as session: + if dataset_name: + # Find the dataset by name + dataset_result = await session.execute( + select(Dataset).where(Dataset.name == dataset_name) + ) + dataset = dataset_result.scalar_one_or_none() + + if dataset is None: + return {"datasets": 0, "data_entries": 0} + + # Count data entries linked to this dataset + count_query = ( + select(func.count()) + .select_from(DatasetData) + .where(DatasetData.dataset_id == dataset.id) + ) + data_entry_count = (await session.execute(count_query)).scalar_one() + + return {"datasets": 1, "data_entries": data_entry_count} + + if all_data: + dataset_count = ( + await session.execute(select(func.count()).select_from(Dataset)) + ).scalar_one() + data_entry_count = ( + await session.execute(select(func.count()).select_from(Data)) + ).scalar_one() + user_count = ( + await session.execute(select(func.count()).select_from(User)) + ).scalar_one() + return { + "datasets": dataset_count, + "data_entries": data_entry_count, + "users": user_count, + } + + # Placeholder for user_id logic + if user_id: + # TODO: Implement counting logic for a specific user + return {"datasets": 0, "data_entries": 0, "users": 1} + + return {} From 95fdbab406c8e8c1ccc436cee858cb7cb2512a67 Mon Sep 17 00:00:00 2001 From: Igor Ilic <30923996+dexters1@users.noreply.github.com> Date: Wed, 1 Oct 2025 18:01:04 +0200 Subject: [PATCH 2/5] refactor: Remove macos13 from ci/cd and support (#1489) ## Description Remove MacOS13 support and CI/CD tests ## Type of Change - [ ] Bug fix (non-breaking change that fixes an issue) - [ ] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update - [ ] Code refactoring - [ ] Performance improvement - [x] Other (please specify): Remove MacOS13 support ## Pre-submission Checklist - [ ] **I have tested my changes thoroughly before submitting this PR** - [ ] **This PR contains minimal changes necessary to address the issue/feature** - [ ] My code follows the project's coding standards and style guidelines - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] I have added necessary documentation (if applicable) - [ ] All new and existing tests pass - [ ] I have searched existing PRs to ensure this change hasn't been submitted already - [ ] I have linked any relevant issues in the description - [ ] My commits have clear and descriptive messages ## DCO Affirmation I affirm that all code in every commit of this pull request conforms to the terms of the Topoteretes Developer Certificate of Origin. --- .../workflows/test_different_operating_systems.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test_different_operating_systems.yml b/.github/workflows/test_different_operating_systems.yml index f99549c8d..6eb5744f3 100644 --- a/.github/workflows/test_different_operating_systems.yml +++ b/.github/workflows/test_different_operating_systems.yml @@ -43,7 +43,7 @@ jobs: strategy: matrix: python-version: ${{ fromJSON(inputs.python-versions) }} - os: [ubuntu-22.04, macos-13, macos-15, windows-latest] + os: [ubuntu-22.04, macos-15, windows-latest] fail-fast: false steps: - name: Check out @@ -79,7 +79,7 @@ jobs: strategy: matrix: python-version: ${{ fromJSON(inputs.python-versions) }} - os: [ ubuntu-22.04, macos-13, macos-15, windows-latest ] + os: [ ubuntu-22.04, macos-15, windows-latest ] fail-fast: false steps: - name: Check out @@ -115,7 +115,7 @@ jobs: strategy: matrix: python-version: ${{ fromJSON(inputs.python-versions) }} - os: [ ubuntu-22.04, macos-13, macos-15, windows-latest ] + os: [ ubuntu-22.04, macos-15, windows-latest ] fail-fast: false steps: - name: Check out @@ -151,7 +151,7 @@ jobs: strategy: matrix: python-version: ${{ fromJSON(inputs.python-versions) }} - os: [ ubuntu-22.04, macos-13, macos-15, windows-latest ] + os: [ ubuntu-22.04, macos-15, windows-latest ] fail-fast: false steps: - name: Check out @@ -180,7 +180,7 @@ jobs: strategy: matrix: python-version: ${{ fromJSON(inputs.python-versions) }} - os: [ ubuntu-22.04, macos-13, macos-15, windows-latest ] + os: [ ubuntu-22.04, macos-15, windows-latest ] fail-fast: false steps: - name: Check out @@ -210,7 +210,7 @@ jobs: strategy: matrix: python-version: ${{ fromJSON(inputs.python-versions) }} - os: [ ubuntu-22.04, macos-13, macos-15, windows-latest ] + os: [ ubuntu-22.04, macos-15, windows-latest ] fail-fast: false steps: - name: Check out From 9c87a10848af92765285076abafd86aaa683cf7b Mon Sep 17 00:00:00 2001 From: shehab-badawy Date: Fri, 26 Sep 2025 22:27:32 -0400 Subject: [PATCH 3/5] feat: Add delete preview for --dataset-name and --all flags This commit introduces the preview functionality for the command. The preview displays a summary of what will be deleted before asking for user confirmation. The feature is fully functional for the following flags: - / : Correctly counts the number of data entries within the specified dataset. - : Correctly counts the total number of datasets, data entries, and users in the system. The logic for the flag is a work in progress. The current implementation uses a placeholder and needs a method to query a user directly by their ID to be completed. --- cognee/cli/commands/delete_command.py | 14 +--- .../data/methods/get_deletion_counts.py | 79 ++++++++++++++----- 2 files changed, 64 insertions(+), 29 deletions(-) diff --git a/cognee/cli/commands/delete_command.py b/cognee/cli/commands/delete_command.py index c9d13890e..0139dbe1a 100644 --- a/cognee/cli/commands/delete_command.py +++ b/cognee/cli/commands/delete_command.py @@ -54,21 +54,15 @@ Be careful with deletion operations as they are irreversible. ) ) - if not preview_data or all(value == 0 for value in preview_data.values()): + if not preview_data: fmt.success("No data found to delete.") return fmt.echo("You are about to delete:") - if "datasets" in preview_data and preview_data["datasets"] > 0: - fmt.echo(f"- {preview_data['datasets']} datasets") - if "data_entries" in preview_data and preview_data["data_entries"] > 0: - fmt.echo(f"- {preview_data['data_entries']} data entries") - if "users" in preview_data and preview_data["users"] > 0: - fmt.echo( - f"- {preview_data['users']} {'users' if preview_data['users'] > 1 else 'user'}" - ) + fmt.echo( + f"Datasets: {preview_data.datasets}\nEntries: {preview_data.entries}\nUsers: {preview_data.users}" + ) fmt.echo("-" * 20) - fmt.warning("This operation is irreversible!") if not fmt.confirm("Proceed?"): fmt.echo("Deletion cancelled.") diff --git a/cognee/modules/data/methods/get_deletion_counts.py b/cognee/modules/data/methods/get_deletion_counts.py index cdd222645..f985cf71d 100644 --- a/cognee/modules/data/methods/get_deletion_counts.py +++ b/cognee/modules/data/methods/get_deletion_counts.py @@ -1,16 +1,30 @@ +from uuid import UUID +from cognee.cli.exceptions import CliCommandException +from cognee.infrastructure.databases.exceptions.exceptions import EntityNotFoundError from sqlalchemy import select from sqlalchemy.sql import func from cognee.infrastructure.databases.relational import get_relational_engine from cognee.modules.data.models import Dataset, Data, DatasetData -from cognee.modules.users.models import User +from cognee.modules.users.models import User, DatasetDatabase +from cognee.modules.users.methods import get_user, get_default_user +from dataclasses import dataclass +import cognee.cli.echo as fmt + + +@dataclass +class DeletionCountsPreview: + datasets: int = 0 + data_entries: int = 0 + users: int = 0 async def get_deletion_counts( dataset_name: str = None, user_id: str = None, all_data: bool = False -) -> dict: +) -> DeletionCountsPreview: """ Calculates the number of items that will be deleted based on the provided arguments. """ + counts = DeletionCountsPreview() relational_engine = get_relational_engine() async with relational_engine.get_async_session() as session: if dataset_name: @@ -21,7 +35,10 @@ async def get_deletion_counts( dataset = dataset_result.scalar_one_or_none() if dataset is None: - return {"datasets": 0, "data_entries": 0} + fmt.error(f"No dataset with this name: {dataset_name}") + raise CliCommandException( + f"No Dataset exists with the name {dataset_name}", error_code=1 + ) # Count data entries linked to this dataset count_query = ( @@ -30,28 +47,52 @@ async def get_deletion_counts( .where(DatasetData.dataset_id == dataset.id) ) data_entry_count = (await session.execute(count_query)).scalar_one() + counts.users = 1 + counts.datasets = 1 + counts.entries = data_entry_count + return counts - return {"datasets": 1, "data_entries": data_entry_count} - - if all_data: - dataset_count = ( + elif all_data: + # Simplified logic: Get total counts directly from the tables. + counts.datasets = ( await session.execute(select(func.count()).select_from(Dataset)) ).scalar_one() - data_entry_count = ( + counts.entries = ( await session.execute(select(func.count()).select_from(Data)) ).scalar_one() - user_count = ( + counts.users = ( await session.execute(select(func.count()).select_from(User)) ).scalar_one() - return { - "datasets": dataset_count, - "data_entries": data_entry_count, - "users": user_count, - } + return counts # Placeholder for user_id logic - if user_id: - # TODO: Implement counting logic for a specific user - return {"datasets": 0, "data_entries": 0, "users": 1} - - return {} + elif user_id: + user = None + try: + user_uuid = UUID(user_id) + user = await get_user(user_uuid) + except (ValueError, EntityNotFoundError): + # Handles cases where user_id is not a valid UUID or user is not found + fmt.error(f"No user exists with ID {user_id}") + raise CliCommandException(f"No User exists with ID {user_id}", error_code=1) + user = await get_user(user_uuid) + if user: + counts.users = 1 + # Find all datasets owned by this user + datasets_query = select(Dataset).where(Dataset.owner_id == user.id) + user_datasets = (await session.execute(datasets_query)).scalars().all() + dataset_count = len(user_datasets) + counts.datasets = dataset_count + if dataset_count > 0: + dataset_ids = [d.id for d in user_datasets] + # Count all data entries across all of the user's datasets + data_count_query = ( + select(func.count()) + .select_from(DatasetData) + .where(DatasetData.dataset_id.in_(dataset_ids)) + ) + data_entry_count = (await session.execute(data_count_query)).scalar_one() + counts.entries = data_entry_count + else: + counts.entries = 0 + return counts From a92f4bdf3fd13ba55a1fd811fb2fbe4da40917cf Mon Sep 17 00:00:00 2001 From: Daulet Amirkhanov Date: Thu, 2 Oct 2025 15:05:39 +0100 Subject: [PATCH 4/5] fix: update failing tests and refactor delete_preview implementation --- cognee/cli/commands/delete_command.py | 29 +++++++---- .../data/methods/get_deletion_counts.py | 48 ++++++++----------- .../cli_unit_tests/test_cli_commands.py | 17 +++++-- .../cli_unit_tests/test_cli_edge_cases.py | 9 +++- 4 files changed, 60 insertions(+), 43 deletions(-) diff --git a/cognee/cli/commands/delete_command.py b/cognee/cli/commands/delete_command.py index 0139dbe1a..46cf41367 100644 --- a/cognee/cli/commands/delete_command.py +++ b/cognee/cli/commands/delete_command.py @@ -46,13 +46,17 @@ Be careful with deletion operations as they are irreversible. if not args.force: # --- START PREVIEW LOGIC --- fmt.echo("Gathering data for preview...") - preview_data = asyncio.run( - get_deletion_counts( - dataset_name=args.dataset_name, - user_id=args.user_id, - all_data=args.all, + try: + preview_data = asyncio.run( + get_deletion_counts( + dataset_name=args.dataset_name, + user_id=args.user_id, + all_data=args.all, + ) ) - ) + except CliCommandException as e: + fmt.error(f"Error occured when fetching preview data: {str(e)}") + return if not preview_data: fmt.success("No data found to delete.") @@ -63,22 +67,27 @@ Be careful with deletion operations as they are irreversible. f"Datasets: {preview_data.datasets}\nEntries: {preview_data.entries}\nUsers: {preview_data.users}" ) fmt.echo("-" * 20) - fmt.warning("This operation is irreversible!") - if not fmt.confirm("Proceed?"): - fmt.echo("Deletion cancelled.") - return # --- END PREVIEW LOGIC --- # Build operation message for success/failure logging if args.all: + confirm_msg = "Delete ALL data from cognee?" operation = "all data" elif args.dataset_name: + confirm_msg = f"Delete dataset '{args.dataset_name}'?" operation = f"dataset '{args.dataset_name}'" elif args.user_id: + confirm_msg = f"Delete all data for user '{args.user_id}'?" operation = f"data for user '{args.user_id}'" else: operation = "data" + if not args.force: + fmt.warning("This operation is irreversible!") + if not fmt.confirm(confirm_msg): + fmt.echo("Deletion cancelled.") + return + fmt.echo(f"Deleting {operation}...") # Run the async delete function diff --git a/cognee/modules/data/methods/get_deletion_counts.py b/cognee/modules/data/methods/get_deletion_counts.py index f985cf71d..9237a8b85 100644 --- a/cognee/modules/data/methods/get_deletion_counts.py +++ b/cognee/modules/data/methods/get_deletion_counts.py @@ -5,10 +5,9 @@ from sqlalchemy import select from sqlalchemy.sql import func from cognee.infrastructure.databases.relational import get_relational_engine from cognee.modules.data.models import Dataset, Data, DatasetData -from cognee.modules.users.models import User, DatasetDatabase -from cognee.modules.users.methods import get_user, get_default_user +from cognee.modules.users.models import User +from cognee.modules.users.methods import get_user from dataclasses import dataclass -import cognee.cli.echo as fmt @dataclass @@ -35,7 +34,6 @@ async def get_deletion_counts( dataset = dataset_result.scalar_one_or_none() if dataset is None: - fmt.error(f"No dataset with this name: {dataset_name}") raise CliCommandException( f"No Dataset exists with the name {dataset_name}", error_code=1 ) @@ -72,27 +70,23 @@ async def get_deletion_counts( user_uuid = UUID(user_id) user = await get_user(user_uuid) except (ValueError, EntityNotFoundError): - # Handles cases where user_id is not a valid UUID or user is not found - fmt.error(f"No user exists with ID {user_id}") raise CliCommandException(f"No User exists with ID {user_id}", error_code=1) - user = await get_user(user_uuid) - if user: - counts.users = 1 - # Find all datasets owned by this user - datasets_query = select(Dataset).where(Dataset.owner_id == user.id) - user_datasets = (await session.execute(datasets_query)).scalars().all() - dataset_count = len(user_datasets) - counts.datasets = dataset_count - if dataset_count > 0: - dataset_ids = [d.id for d in user_datasets] - # Count all data entries across all of the user's datasets - data_count_query = ( - select(func.count()) - .select_from(DatasetData) - .where(DatasetData.dataset_id.in_(dataset_ids)) - ) - data_entry_count = (await session.execute(data_count_query)).scalar_one() - counts.entries = data_entry_count - else: - counts.entries = 0 - return counts + counts.users = 1 + # Find all datasets owned by this user + datasets_query = select(Dataset).where(Dataset.owner_id == user.id) + user_datasets = (await session.execute(datasets_query)).scalars().all() + dataset_count = len(user_datasets) + counts.datasets = dataset_count + if dataset_count > 0: + dataset_ids = [d.id for d in user_datasets] + # Count all data entries across all of the user's datasets + data_count_query = ( + select(func.count()) + .select_from(DatasetData) + .where(DatasetData.dataset_id.in_(dataset_ids)) + ) + data_entry_count = (await session.execute(data_count_query)).scalar_one() + counts.entries = data_entry_count + else: + counts.entries = 0 + return counts diff --git a/cognee/tests/cli_tests/cli_unit_tests/test_cli_commands.py b/cognee/tests/cli_tests/cli_unit_tests/test_cli_commands.py index e5d6a0c64..7654a781a 100644 --- a/cognee/tests/cli_tests/cli_unit_tests/test_cli_commands.py +++ b/cognee/tests/cli_tests/cli_unit_tests/test_cli_commands.py @@ -12,7 +12,8 @@ from cognee.cli.commands.search_command import SearchCommand from cognee.cli.commands.cognify_command import CognifyCommand from cognee.cli.commands.delete_command import DeleteCommand from cognee.cli.commands.config_command import ConfigCommand -from cognee.cli.exceptions import CliCommandException, CliCommandInnerException +from cognee.cli.exceptions import CliCommandException +from cognee.modules.data.methods.get_deletion_counts import DeletionCountsPreview # Mock asyncio.run to properly handle coroutines @@ -282,13 +283,18 @@ class TestDeleteCommand: assert "all" in actions assert "force" in actions + @patch("cognee.cli.commands.delete_command.get_deletion_counts") @patch("cognee.cli.commands.delete_command.fmt.confirm") @patch("cognee.cli.commands.delete_command.asyncio.run", side_effect=_mock_run) - def test_execute_delete_dataset_with_confirmation(self, mock_asyncio_run, mock_confirm): + def test_execute_delete_dataset_with_confirmation( + self, mock_asyncio_run, mock_confirm, mock_get_deletion_counts + ): """Test execute delete dataset with user confirmation""" # Mock the cognee module mock_cognee = MagicMock() mock_cognee.delete = AsyncMock() + mock_get_deletion_counts = AsyncMock() + mock_get_deletion_counts.return_value = DeletionCountsPreview() with patch.dict(sys.modules, {"cognee": mock_cognee}): command = DeleteCommand() @@ -301,13 +307,16 @@ class TestDeleteCommand: command.execute(args) mock_confirm.assert_called_once_with(f"Delete dataset '{args.dataset_name}'?") - mock_asyncio_run.assert_called_once() + assert mock_asyncio_run.call_count == 2 assert asyncio.iscoroutine(mock_asyncio_run.call_args[0][0]) mock_cognee.delete.assert_awaited_once_with(dataset_name="test_dataset", user_id=None) + @patch("cognee.cli.commands.delete_command.get_deletion_counts") @patch("cognee.cli.commands.delete_command.fmt.confirm") - def test_execute_delete_cancelled(self, mock_confirm): + def test_execute_delete_cancelled(self, mock_confirm, mock_get_deletion_counts): """Test execute when user cancels deletion""" + mock_get_deletion_counts = AsyncMock() + mock_get_deletion_counts.return_value = DeletionCountsPreview() command = DeleteCommand() args = argparse.Namespace(dataset_name="test_dataset", user_id=None, all=False, force=False) diff --git a/cognee/tests/cli_tests/cli_unit_tests/test_cli_edge_cases.py b/cognee/tests/cli_tests/cli_unit_tests/test_cli_edge_cases.py index d4e4b0ee5..de8681be9 100644 --- a/cognee/tests/cli_tests/cli_unit_tests/test_cli_edge_cases.py +++ b/cognee/tests/cli_tests/cli_unit_tests/test_cli_edge_cases.py @@ -13,6 +13,7 @@ from cognee.cli.commands.cognify_command import CognifyCommand from cognee.cli.commands.delete_command import DeleteCommand from cognee.cli.commands.config_command import ConfigCommand from cognee.cli.exceptions import CliCommandException, CliCommandInnerException +from cognee.modules.data.methods.get_deletion_counts import DeletionCountsPreview # Mock asyncio.run to properly handle coroutines @@ -396,13 +397,17 @@ class TestDeleteCommandEdgeCases: command.execute(args) mock_confirm.assert_called_once_with("Delete ALL data from cognee?") - mock_asyncio_run.assert_called_once() + assert mock_asyncio_run.call_count == 2 assert asyncio.iscoroutine(mock_asyncio_run.call_args[0][0]) mock_cognee.delete.assert_awaited_once_with(dataset_name=None, user_id="test_user") + @patch("cognee.cli.commands.delete_command.get_deletion_counts") @patch("cognee.cli.commands.delete_command.fmt.confirm") - def test_delete_confirmation_keyboard_interrupt(self, mock_confirm): + def test_delete_confirmation_keyboard_interrupt(self, mock_confirm, mock_get_deletion_counts): """Test delete command when user interrupts confirmation""" + mock_get_deletion_counts = AsyncMock() + mock_get_deletion_counts.return_value = DeletionCountsPreview() + command = DeleteCommand() args = argparse.Namespace(dataset_name="test_dataset", user_id=None, all=False, force=False) From 38070c489bf0ed7c0cf74f7220ef3103e82be0ed Mon Sep 17 00:00:00 2001 From: Daulet Amirkhanov Date: Thu, 2 Oct 2025 17:39:10 +0100 Subject: [PATCH 5/5] fix `test_cli_edge_cases.py`, `test_delete_all_with_user_id` unit test --- .../tests/cli_tests/cli_unit_tests/test_cli_edge_cases.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cognee/tests/cli_tests/cli_unit_tests/test_cli_edge_cases.py b/cognee/tests/cli_tests/cli_unit_tests/test_cli_edge_cases.py index de8681be9..ca27c0f67 100644 --- a/cognee/tests/cli_tests/cli_unit_tests/test_cli_edge_cases.py +++ b/cognee/tests/cli_tests/cli_unit_tests/test_cli_edge_cases.py @@ -379,13 +379,18 @@ class TestCognifyCommandEdgeCases: class TestDeleteCommandEdgeCases: """Test edge cases for DeleteCommand""" + @patch("cognee.cli.commands.delete_command.get_deletion_counts") @patch("cognee.cli.commands.delete_command.fmt.confirm") @patch("cognee.cli.commands.delete_command.asyncio.run", side_effect=_mock_run) - def test_delete_all_with_user_id(self, mock_asyncio_run, mock_confirm): + def test_delete_all_with_user_id( + self, mock_asyncio_run, mock_confirm, mock_get_deletion_counts + ): """Test delete command with both --all and --user-id""" # Mock the cognee module mock_cognee = MagicMock() mock_cognee.delete = AsyncMock() + mock_get_deletion_counts = AsyncMock() + mock_get_deletion_counts.return_value = DeletionCountsPreview() with patch.dict(sys.modules, {"cognee": mock_cognee}): command = DeleteCommand()