import os os.environ.setdefault('QT_QPA_PLATFORM', 'offscreen') import time import unittest try: from PySide6.QtWidgets import QApplication from server_buddy.ui.window import MainWindow except ImportError: QApplication = None @unittest.skipIf(QApplication is None, 'PySide6 not installed') class UITests(unittest.TestCase): @classmethod def setUpClass(cls): cls.app = QApplication.instance() or QApplication([]) def test_navigation_collection_and_environment_errors(self): window = MainWindow() window.show() self.assertEqual(window.tabs.count(), 10) for index in range(6): window.nav.setCurrentRow(index) self.assertEqual(window.pages.currentIndex(), index) window.hostname.setText('host;bad') window.start_collection() self.assertIn('Enter a hostname', window.status.text()) window.hostname.setText('demo-web-01.example.test') window.environment.setCurrentIndex(1) window.start_collection() self.assertIn('not implemented', window.status.text()) window.environment.setCurrentIndex(0) window.start_collection() deadline = time.monotonic() + 5 while window.job is not None and time.monotonic() < deadline: self.app.processEvents() time.sleep(.01) self.assertIsNone(window.job) self.assertEqual(len(window.history), 2) self.assertTrue(window.analyze_button.isEnabled()) self.assertIn('Complete', window.status.text()) window.close() def test_linux_demo_collection(self): window = MainWindow() window.target.setCurrentIndex(1) self.assertEqual(window.hostname.text(), 'demo-rhel-01.example.test') window.start_collection() deadline = time.monotonic() + 5 while window.job is not None and time.monotonic() < deadline: self.app.processEvents() time.sleep(.01) self.assertIsNone(window.job) self.assertEqual(window.data['server']['platform'], 'linux') self.assertIn('SYNTHETIC', window.banner.text()) self.assertEqual(window.tabs.count(), 10) window.close() def test_local_collection_source_and_report(self): from unittest.mock import patch from server_buddy.collectors.demo import collect_demo, LINUX_DEMO_HOST data = collect_demo(LINUX_DEMO_HOST) data['synthetic'] = False data['server']['collection_source'] = 'Local Linux read-only collection' with patch('server_buddy.ui.window.platform.system', return_value='Linux'), patch('server_buddy.ui.window.collect_local_linux', return_value=data): window = MainWindow() # Local collection does not validate or contact the hostname field. window.hostname.setText('not-a-remote-target;') window.local_button.click() self.assertFalse(window.analyze_button.isEnabled()) self.assertTrue(window.cancel_button.isEnabled()) deadline = time.monotonic() + 5 while window.job is not None and time.monotonic() < deadline: self.app.processEvents() time.sleep(.01) self.assertIsNone(window.job) self.assertIn('LOCAL LINUX', window.banner.text()) self.assertEqual(window.history[-1]['source'], 'Local Linux read-only collection') self.assertTrue(window.local_button.isEnabled()) self.assertFalse(window.cancel_button.isEnabled()) import tempfile from pathlib import Path with tempfile.TemporaryDirectory() as folder: report = Path(folder) / 'local.html' with patch('server_buddy.ui.window.QFileDialog.getSaveFileName', return_value=(str(report), '')), patch('server_buddy.ui.window.QMessageBox.information'): window.save_report('html') self.assertIn('LOCAL LINUX INVENTORY', report.read_text()) window.close()