"""Tests for GUI components""" import unittest from unittest.mock import Mock, patch, MagicMock from pathlib import Path import sys project_root = Path(__file__).parent.parent sys.path.insert(0, str(project_root)) from PyQt6.QtWidgets import QApplication from gui import MainWindow, JobsTab, HistoryTab, DashboardTab, JobDialog class TestGUI(unittest.TestCase): """Test GUI components""" @classmethod def setUpClass(cls): """Create QApplication once for all tests""" cls.app = QApplication.instance() if cls.app is None: cls.app = QApplication([]) def test_main_window_creation(self): """Test main window can be created""" window = MainWindow() self.assertEqual(window.windowTitle(), "DaemonControl") self.assertEqual(window.tabs.count(), 3) def test_jobs_tab_creation(self): """Test jobs tab can be created""" tab = JobsTab() self.assertIsNotNone(tab.table) self.assertEqual(tab.table.columnCount(), 6) def test_history_tab_creation(self): """Test history tab can be created""" tab = HistoryTab() self.assertIsNotNone(tab.table) self.assertEqual(tab.table.columnCount(), 7) def test_dashboard_tab_creation(self): """Test dashboard tab can be created""" tab = DashboardTab() self.assertIsNotNone(tab.active_jobs_list) self.assertIsNotNone(tab.recent_exec_list) def test_job_dialog_create_mode(self): """Test job dialog in create mode""" dialog = JobDialog() self.assertEqual(dialog.windowTitle(), "New Job") self.assertFalse(dialog.is_edit_mode) @patch('gui.job_dialog.DatabaseManager') def test_job_dialog_edit_mode(self, mock_db): """Test job dialog in edit mode""" # Mock database response mock_conn = MagicMock() mock_cursor = MagicMock() mock_cursor.fetchone.side_effect = [ { 'id': 1, 'name': 'Test Job', 'job_type': 'script', 'executable_path': '/test/script.sh', 'working_directory': '/test', 'timeout': 3600, 'description': 'Test description' }, None # No schedule ] mock_conn.cursor.return_value = mock_cursor mock_conn.__enter__ = Mock(return_value=mock_conn) mock_conn.__exit__ = Mock(return_value=False) mock_db.return_value.get_connection.return_value = mock_conn dialog = JobDialog(job_id=1) self.assertEqual(dialog.windowTitle(), "Edit Job") self.assertTrue(dialog.is_edit_mode) def test_jobs_tab_button_states(self): """Test jobs tab buttons are disabled without selection""" tab = JobsTab() self.assertFalse(tab.edit_btn.isEnabled()) self.assertFalse(tab.delete_btn.isEnabled()) self.assertFalse(tab.toggle_btn.isEnabled()) self.assertFalse(tab.execute_btn.isEnabled()) def test_main_window_tabs(self): """Test main window has correct tabs""" window = MainWindow() self.assertEqual(window.tabs.tabText(0), "📊 Dashboard") self.assertEqual(window.tabs.tabText(1), "⚙️ Jobs") self.assertEqual(window.tabs.tabText(2), "📜 History") def test_jobs_tab_has_new_button(self): """Test jobs tab has new job button""" tab = JobsTab() self.assertIsNotNone(tab.new_btn) self.assertTrue(tab.new_btn.isEnabled()) def test_history_tab_filters(self): """Test history tab has filter dropdowns""" tab = HistoryTab() self.assertIsNotNone(tab.job_filter) self.assertIsNotNone(tab.status_filter) self.assertIsNotNone(tab.period_filter) def test_dashboard_has_stats_labels(self): """Test dashboard has statistics labels""" tab = DashboardTab() self.assertIsNotNone(tab.total_jobs_label) self.assertIsNotNone(tab.enabled_jobs_label) self.assertIsNotNone(tab.total_exec_label) if __name__ == '__main__': unittest.main()