diff --git a/.claude/hooks/.diagnostics_state.json b/.claude/hooks/.diagnostics_state.json new file mode 100644 index 00000000..3f6df996 --- /dev/null +++ b/.claude/hooks/.diagnostics_state.json @@ -0,0 +1 @@ +{"file": "/home/patrick/Projects/AIPass/src/aipass/api/tests/test_usage_tracker.py", "errors": [{"line": 372, "message": "E501: Line too long (139 > 120)"}, {"line": 387, "message": "E501: Line too long (126 > 120)"}, {"line": 394, "message": "E501: Line too long (139 > 120)"}, {"line": 408, "message": "E501: Line too long (123 > 120)"}, {"line": 415, "message": "E501: Line too long (139 > 120)"}, {"line": 438, "message": "E501: Line too long (139 > 120)"}]} \ No newline at end of file diff --git a/src/aipass/api/apps/__init__.py b/src/aipass/api/apps/__init__.py index 803548c8..de448f8b 100644 --- a/src/aipass/api/apps/__init__.py +++ b/src/aipass/api/apps/__init__.py @@ -1 +1,2 @@ # Apps package +from . import handlers # noqa: F401 diff --git a/src/aipass/api/tests/test_usage_tracker.py b/src/aipass/api/tests/test_usage_tracker.py index 638653eb..c1d95e86 100644 --- a/src/aipass/api/tests/test_usage_tracker.py +++ b/src/aipass/api/tests/test_usage_tracker.py @@ -356,24 +356,21 @@ def test_show_caller_usage_no_args(mock_agg, mock_header, mock_console, mock_err # ============================================= +@patch(f"{PATCH_ROOT}.Path") @patch(f"{PATCH_ROOT}.error") @patch(f"{PATCH_ROOT}.success") @patch(f"{PATCH_ROOT}.console") @patch(f"{PATCH_ROOT}.header") @patch(f"{PATCH_ROOT}.cleanup") -def test_cleanup_success(mock_cleanup_handler, mock_header, mock_console, mock_success, mock_error): +def test_cleanup_success(mock_cleanup_handler, mock_header, mock_console, mock_success, mock_error, mock_path_cls): """cleanup_data calls success() with count when handler returns > 0.""" from aipass.api.apps.modules import usage_tracker mock_cleanup_handler.cleanup_old_data.return_value = 5 + mock_data_path = MagicMock() + mock_data_path.exists.return_value = True + mock_path_cls.return_value.resolve.return_value.parent.parent.parent.__truediv__.return_value.__truediv__.return_value = mock_data_path - # The data_path.exists() check needs to pass - with patch(f"{PATCH_ROOT}.Path") as mock_path_cls: - mock_data_path = MagicMock() - mock_data_path.exists.return_value = True - mock_path_cls.return_value.resolve.return_value.parent.parent.parent.__truediv__.return_value.__truediv__.return_value = mock_data_path - - # Call directly -- cleanup handler is mocked, use real Path for API_JSON_DIR resolution usage_tracker.cleanup_data(["45"]) mock_cleanup_handler.cleanup_old_data.assert_called_once() @@ -381,16 +378,22 @@ def test_cleanup_success(mock_cleanup_handler, mock_header, mock_console, mock_s mock_error.assert_not_called() +@patch(f"{PATCH_ROOT}.Path") @patch(f"{PATCH_ROOT}.warning") @patch(f"{PATCH_ROOT}.success") @patch(f"{PATCH_ROOT}.console") @patch(f"{PATCH_ROOT}.header") @patch(f"{PATCH_ROOT}.cleanup") -def test_cleanup_nothing_to_clean(mock_cleanup_handler, mock_header, mock_console, mock_success, mock_warning): +def test_cleanup_nothing_to_clean( + mock_cleanup_handler, mock_header, mock_console, mock_success, mock_warning, mock_path_cls +): """cleanup_data calls success() with 'nothing to clean' when handler returns 0.""" from aipass.api.apps.modules import usage_tracker mock_cleanup_handler.cleanup_old_data.return_value = 0 + mock_data_path = MagicMock() + mock_data_path.exists.return_value = True + mock_path_cls.return_value.resolve.return_value.parent.parent.parent.__truediv__.return_value.__truediv__.return_value = mock_data_path usage_tracker.cleanup_data(["30"]) @@ -398,37 +401,45 @@ def test_cleanup_nothing_to_clean(mock_cleanup_handler, mock_header, mock_consol mock_success.assert_called_once_with("Nothing to clean — no entries older than 30 days") +@patch(f"{PATCH_ROOT}.Path") @patch(f"{PATCH_ROOT}.error") @patch(f"{PATCH_ROOT}.success") @patch(f"{PATCH_ROOT}.console") @patch(f"{PATCH_ROOT}.header") @patch(f"{PATCH_ROOT}.cleanup") -def test_cleanup_default_30_days(mock_cleanup_handler, mock_header, mock_console, mock_success, mock_error): +def test_cleanup_default_30_days( + mock_cleanup_handler, mock_header, mock_console, mock_success, mock_error, mock_path_cls +): """cleanup_data defaults to 30 days when no args provided.""" from aipass.api.apps.modules import usage_tracker mock_cleanup_handler.cleanup_old_data.return_value = 3 + mock_data_path = MagicMock() + mock_data_path.exists.return_value = True + mock_path_cls.return_value.resolve.return_value.parent.parent.parent.__truediv__.return_value.__truediv__.return_value = mock_data_path usage_tracker.cleanup_data([]) - # Verify the header shows 30 days mock_header.assert_called_once_with("Cleanup Old Data (retain 30 days)") - # Verify cleanup_old_data was called with days=30 args, kwargs = mock_cleanup_handler.cleanup_old_data.call_args assert args[1] == 30 mock_success.assert_called_once_with("Cleaned up 3 entries older than 30 days") +@patch(f"{PATCH_ROOT}.Path") @patch(f"{PATCH_ROOT}.error") @patch(f"{PATCH_ROOT}.success") @patch(f"{PATCH_ROOT}.console") @patch(f"{PATCH_ROOT}.header") @patch(f"{PATCH_ROOT}.cleanup") -def test_cleanup_custom_days(mock_cleanup_handler, mock_header, mock_console, mock_success, mock_error): +def test_cleanup_custom_days(mock_cleanup_handler, mock_header, mock_console, mock_success, mock_error, mock_path_cls): """cleanup_data parses custom days from args.""" from aipass.api.apps.modules import usage_tracker mock_cleanup_handler.cleanup_old_data.return_value = 7 + mock_data_path = MagicMock() + mock_data_path.exists.return_value = True + mock_path_cls.return_value.resolve.return_value.parent.parent.parent.__truediv__.return_value.__truediv__.return_value = mock_data_path usage_tracker.cleanup_data(["90"]) diff --git a/src/aipass/cli/apps/__init__.py b/src/aipass/cli/apps/__init__.py index 7d29d333..65548c26 100644 --- a/src/aipass/cli/apps/__init__.py +++ b/src/aipass/cli/apps/__init__.py @@ -17,3 +17,5 @@ Provides core application modules, handlers, and extension system for CLI branch Usage: from aipass.cli.apps import handlers """ + +from . import handlers # noqa: F401 diff --git a/src/aipass/drone/apps/__init__.py b/src/aipass/drone/apps/__init__.py index c288a799..392eb97f 100644 --- a/src/aipass/drone/apps/__init__.py +++ b/src/aipass/drone/apps/__init__.py @@ -1 +1,2 @@ # DRONE apps package +from . import handlers # noqa: F401 diff --git a/src/aipass/flow/apps/__init__.py b/src/aipass/flow/apps/__init__.py index 73ab12a7..9fa3b6bc 100644 --- a/src/aipass/flow/apps/__init__.py +++ b/src/aipass/flow/apps/__init__.py @@ -1 +1,2 @@ # Apps package - Branch application modules and handlers +from . import handlers # noqa: F401 diff --git a/src/aipass/seedgo/apps/__init__.py b/src/aipass/seedgo/apps/__init__.py index 3066b423..d836e0de 100644 --- a/src/aipass/seedgo/apps/__init__.py +++ b/src/aipass/seedgo/apps/__init__.py @@ -1 +1,2 @@ # SEEDGO apps package +from . import handlers # noqa: F401 diff --git a/src/aipass/spawn/apps/__init__.py b/src/aipass/spawn/apps/__init__.py index e69de29b..49dab47b 100644 --- a/src/aipass/spawn/apps/__init__.py +++ b/src/aipass/spawn/apps/__init__.py @@ -0,0 +1 @@ +from . import handlers # noqa: F401