fix(gui): correct create_project call - use metadata not description
- ProjectManager.create_project signature: (name, project_type, metadata=None)
- GUI was incorrectly passing description as 3rd arg
- Now passes metadata={'description': description}
- Add test_gui_simple.py for quick integration testing
This commit is contained in:
parent
d283de84ee
commit
e2388dadaf
|
|
@ -0,0 +1,131 @@
|
|||
"""
|
||||
Tests for GUI integration with core modules.
|
||||
Verifies MainWindow properly integrates with ProjectManager, LogWatcher, etc.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from unittest.mock import Mock, MagicMock, patch
|
||||
|
||||
# Add project to path
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
|
||||
class TestProjectDataCompatibility:
|
||||
"""Test that GUI uses correct ProjectData attributes."""
|
||||
|
||||
def test_project_data_has_required_fields(self):
|
||||
"""Verify ProjectData has fields used by GUI."""
|
||||
from core.project_manager import ProjectData
|
||||
|
||||
project = ProjectData(
|
||||
id=1,
|
||||
name="Test Project",
|
||||
type="hunt",
|
||||
status="active"
|
||||
)
|
||||
|
||||
# Fields used by GUI
|
||||
assert hasattr(project, 'id')
|
||||
assert hasattr(project, 'name')
|
||||
assert hasattr(project, 'type')
|
||||
assert hasattr(project, 'status')
|
||||
|
||||
# Fields NOT in ProjectData (GUI was incorrectly using these)
|
||||
assert not hasattr(project, 'session_count')
|
||||
assert not hasattr(project, 'description')
|
||||
|
||||
def test_project_manager_methods_exist(self):
|
||||
"""Verify ProjectManager has methods called by GUI."""
|
||||
from core.project_manager import ProjectManager
|
||||
|
||||
pm = ProjectManager()
|
||||
|
||||
# Methods GUI uses
|
||||
assert hasattr(pm, 'list_projects')
|
||||
assert hasattr(pm, 'load_project')
|
||||
assert hasattr(pm, 'create_project')
|
||||
assert hasattr(pm, 'start_session')
|
||||
assert hasattr(pm, 'end_session')
|
||||
assert hasattr(pm, 'record_loot')
|
||||
|
||||
# Methods GUI should NOT call (old placeholder names)
|
||||
assert not hasattr(pm, 'get_all_projects')
|
||||
assert not hasattr(pm, 'get_project')
|
||||
|
||||
|
||||
class TestLogWatcherCompatibility:
|
||||
"""Test LogWatcher integration."""
|
||||
|
||||
def test_log_watcher_has_subscribe(self):
|
||||
"""Verify LogWatcher has subscribe method."""
|
||||
from core.log_watcher import LogWatcher
|
||||
|
||||
# Can't instantiate without file, but can check class
|
||||
assert hasattr(LogWatcher, 'subscribe')
|
||||
assert hasattr(LogWatcher, 'start')
|
||||
assert hasattr(LogWatcher, 'stop')
|
||||
|
||||
|
||||
class TestMainWindowIntegration:
|
||||
"""Test MainWindow integration with core modules."""
|
||||
|
||||
@pytest.fixture
|
||||
def mock_qapp(self):
|
||||
"""Create mock QApplication."""
|
||||
with patch('PyQt6.QtWidgets.QApplication') as mock_app:
|
||||
mock_instance = Mock()
|
||||
mock_app.instance.return_value = mock_instance
|
||||
yield mock_instance
|
||||
|
||||
def test_main_window_imports(self, mock_qapp):
|
||||
"""Test MainWindow can import without errors."""
|
||||
with patch('ui.main_window.DatabaseManager') as mock_db, \
|
||||
patch('ui.main_window.ProjectManager') as mock_pm, \
|
||||
patch('ui.main_window.HUDOverlay'), \
|
||||
patch('ui.main_window.QMainWindow'):
|
||||
|
||||
mock_db_instance = Mock()
|
||||
mock_db_instance.initialize.return_value = True
|
||||
mock_db.return_value = mock_db_instance
|
||||
|
||||
mock_pm_instance = Mock()
|
||||
mock_pm_instance.list_projects.return_value = []
|
||||
mock_pm.return_value = mock_pm_instance
|
||||
|
||||
from ui.main_window import MainWindow
|
||||
# Should not raise ImportError or AttributeError
|
||||
|
||||
|
||||
class TestProjectManagerMethodSignatures:
|
||||
"""Test ProjectManager method signatures match GUI expectations."""
|
||||
|
||||
def test_create_project_signature(self):
|
||||
"""Test create_project accepts correct arguments."""
|
||||
from core.project_manager import ProjectManager
|
||||
import inspect
|
||||
|
||||
sig = inspect.signature(ProjectManager.create_project)
|
||||
params = list(sig.parameters.keys())
|
||||
|
||||
# Should have: self, name, project_type, description=""
|
||||
assert 'name' in params
|
||||
assert 'project_type' in params
|
||||
assert 'description' in params
|
||||
|
||||
def test_list_projects_signature(self):
|
||||
"""Test list_projects has correct signature."""
|
||||
from core.project_manager import ProjectManager
|
||||
import inspect
|
||||
|
||||
sig = inspect.signature(ProjectManager.list_projects)
|
||||
params = list(sig.parameters.keys())
|
||||
|
||||
# Should have optional filters
|
||||
assert 'project_type' in params
|
||||
assert 'status' in params
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__, "-v"])
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Simple test runner for GUI integration - no pytest required.
|
||||
Run: python tests/test_gui_simple.py
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Add project to path
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
def test_project_data_fields():
|
||||
"""Test ProjectData has fields GUI uses."""
|
||||
from core.project_manager import ProjectData
|
||||
|
||||
project = ProjectData(
|
||||
id=1,
|
||||
name="Test Project",
|
||||
type="hunt",
|
||||
status="active"
|
||||
)
|
||||
|
||||
# Required fields
|
||||
assert hasattr(project, 'id'), "Missing: id"
|
||||
assert hasattr(project, 'name'), "Missing: name"
|
||||
assert hasattr(project, 'type'), "Missing: type"
|
||||
assert hasattr(project, 'status'), "Missing: status"
|
||||
|
||||
# These fields caused AttributeErrors
|
||||
assert not hasattr(project, 'session_count'), "Unexpected: session_count"
|
||||
assert not hasattr(project, 'description'), "Unexpected: description"
|
||||
|
||||
print("✅ ProjectData fields correct")
|
||||
return True
|
||||
|
||||
def test_project_manager_methods():
|
||||
"""Test ProjectManager has methods GUI calls."""
|
||||
from core.project_manager import ProjectManager
|
||||
|
||||
pm = ProjectManager()
|
||||
|
||||
# Required methods
|
||||
assert hasattr(pm, 'list_projects'), "Missing: list_projects"
|
||||
assert hasattr(pm, 'load_project'), "Missing: load_project"
|
||||
assert hasattr(pm, 'create_project'), "Missing: create_project"
|
||||
assert hasattr(pm, 'start_session'), "Missing: start_session"
|
||||
assert hasattr(pm, 'end_session'), "Missing: end_session"
|
||||
assert hasattr(pm, 'record_loot'), "Missing: record_loot"
|
||||
|
||||
# These were wrong method names
|
||||
assert not hasattr(pm, 'get_all_projects'), "Should not have: get_all_projects"
|
||||
assert not hasattr(pm, 'get_project'), "Should not have: get_project"
|
||||
|
||||
print("✅ ProjectManager methods correct")
|
||||
return True
|
||||
|
||||
def test_create_project_signature():
|
||||
"""Test create_project has correct signature."""
|
||||
from core.project_manager import ProjectManager
|
||||
import inspect
|
||||
|
||||
sig = inspect.signature(ProjectManager.create_project)
|
||||
params = list(sig.parameters.keys())
|
||||
|
||||
# Correct signature: create_project(name, project_type, metadata=None)
|
||||
assert 'name' in params, "Missing: name"
|
||||
assert 'project_type' in params, "Missing: project_type"
|
||||
assert 'metadata' in params, "Missing: metadata"
|
||||
|
||||
print("✅ create_project signature correct")
|
||||
return True
|
||||
|
||||
def test_list_projects_signature():
|
||||
"""Test list_projects returns list."""
|
||||
from core.project_manager import ProjectManager
|
||||
|
||||
pm = ProjectManager()
|
||||
projects = pm.list_projects()
|
||||
|
||||
assert isinstance(projects, list), "list_projects should return list"
|
||||
|
||||
print(f"✅ list_projects works (found {len(projects)} projects)")
|
||||
return True
|
||||
|
||||
def test_log_watcher_methods():
|
||||
"""Test LogWatcher has required methods."""
|
||||
from core.log_watcher import LogWatcher
|
||||
|
||||
assert hasattr(LogWatcher, 'subscribe'), "Missing: subscribe"
|
||||
assert hasattr(LogWatcher, 'start'), "Missing: start"
|
||||
assert hasattr(LogWatcher, 'stop'), "Missing: stop"
|
||||
|
||||
print("✅ LogWatcher methods correct")
|
||||
return True
|
||||
|
||||
def run_all_tests():
|
||||
"""Run all tests."""
|
||||
print("="*60)
|
||||
print("GUI INTEGRATION TESTS")
|
||||
print("="*60)
|
||||
print()
|
||||
|
||||
tests = [
|
||||
test_project_data_fields,
|
||||
test_project_manager_methods,
|
||||
test_create_project_signature,
|
||||
test_list_projects_signature,
|
||||
test_log_watcher_methods,
|
||||
]
|
||||
|
||||
passed = 0
|
||||
failed = 0
|
||||
|
||||
for test in tests:
|
||||
try:
|
||||
if test():
|
||||
passed += 1
|
||||
except Exception as e:
|
||||
print(f"❌ {test.__name__} FAILED: {e}")
|
||||
failed += 1
|
||||
|
||||
print()
|
||||
print("="*60)
|
||||
print(f"RESULTS: {passed} passed, {failed} failed")
|
||||
print("="*60)
|
||||
|
||||
return failed == 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = run_all_tests()
|
||||
sys.exit(0 if success else 1)
|
||||
|
|
@ -797,7 +797,8 @@ class MainWindow(QMainWindow):
|
|||
dialog = NewProjectDialog(self)
|
||||
if dialog.exec() == QDialog.DialogCode.Accepted:
|
||||
name, description = dialog.get_project_data()
|
||||
project = self.project_manager.create_project(name, 'hunt', description)
|
||||
metadata = {"description": description} if description else None
|
||||
project = self.project_manager.create_project(name, 'hunt', metadata)
|
||||
self.refresh_project_list()
|
||||
self.log_info("ProjectManager", f"Created project: {project.name}")
|
||||
self.status_bar.showMessage(f"Project '{name}' created", 3000)
|
||||
|
|
|
|||
Loading…
Reference in New Issue