source: sasview/src/sas/qtgui/MainWindow/UnitTesting/GuiManagerTest.py @ 14ec91c5

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalc
Last change on this file since 14ec91c5 was 14ec91c5, checked in by Piotr Rozyczko <rozyczko@…>, 6 years ago

More code review related fixes

  • Property mode set to 100644
File size: 10.9 KB
Line 
1import sys
2import subprocess
3import unittest
4import webbrowser
5import logging
6
7from PyQt5.QtGui import *
8from PyQt5.QtWidgets import *
9from PyQt5.QtTest import QTest
10from PyQt5.QtCore import *
11from PyQt5.QtWebKit import *
12from unittest.mock import MagicMock
13
14# set up import paths
15import path_prepare
16
17# Local
18from sas.qtgui.MainWindow.DataExplorer import DataExplorerWindow
19from sas.qtgui.MainWindow.AboutBox import AboutBox
20from sas.qtgui.MainWindow.WelcomePanel import WelcomePanel
21from sas.qtgui.Utilities.IPythonWidget import IPythonWidget
22
23from sas.qtgui.MainWindow.GuiManager import Acknowledgements, GuiManager
24from sas.qtgui.MainWindow.MainWindow import MainSasViewWindow
25from sas.qtgui.UnitTesting.TestUtils import QtSignalSpy
26
27if not QApplication.instance():
28    app = QApplication(sys.argv)
29
30class GuiManagerTest(unittest.TestCase):
31    '''Test the Main Window functionality'''
32    def setUp(self):
33        '''Create the tested object'''
34        class MainWindow(MainSasViewWindow):
35            # Main window of the application
36            def __init__(self, reactor, parent=None):
37                super(MainWindow, self).__init__(parent)
38       
39                # define workspace for dialogs.
40                self.workspace = QMdiArea(self)
41                self.setCentralWidget(self.workspace)
42
43        self.manager = GuiManager(MainWindow(None))
44
45    def tearDown(self):
46        '''Destroy the GUI'''
47        self.manager = None
48
49    def testDefaults(self):
50        """
51        Test the object in its default state
52        """
53        self.assertIsInstance(self.manager.filesWidget, DataExplorerWindow)
54        self.assertIsInstance(self.manager.dockedFilesWidget, QDockWidget)
55        self.assertIsInstance(self.manager.dockedFilesWidget.widget(), DataExplorerWindow)
56        self.assertEqual(self.manager.dockedFilesWidget.features(), QDockWidget.NoDockWidgetFeatures)
57        self.assertEqual(self.manager._workspace.dockWidgetArea(self.manager.dockedFilesWidget), Qt.LeftDockWidgetArea)
58
59        self.assertIsInstance(self.manager.logDockWidget, QDockWidget)
60        self.assertIsInstance(self.manager.logDockWidget.widget(), QTextBrowser)
61        self.assertEqual(self.manager._workspace.dockWidgetArea(self.manager.logDockWidget), Qt.BottomDockWidgetArea)
62
63        self.assertIsInstance(self.manager.ackWidget, Acknowledgements)
64        self.assertIsInstance(self.manager.aboutWidget, AboutBox)
65        self.assertIsInstance(self.manager.welcomePanel, WelcomePanel)
66
67    def skip_testLogging(self):
68        """
69        Test logging of stdout, stderr and log messages
70        """
71        # See if the log window is empty
72        self.assertEqual(self.manager.logDockWidget.widget().toPlainText(), "")
73
74        # Now, send some message to stdout.
75        # We are in the MainWindow scope, so simple 'print' will work
76        message = "from stdout"
77        print(message)
78        self.assertIn(message, self.manager.logDockWidget.widget().toPlainText())
79
80        # Send some message to stderr
81        message = "from stderr"
82        sys.stderr.write(message)
83        self.assertIn(message, self.manager.logDockWidget.widget().toPlainText())
84
85        # And finally, send a log message
86        import logging
87        message = "from logging"
88        message_logged = "ERROR: " + message
89        logging.error(message)
90        self.assertIn(message_logged, self.manager.logDockWidget.widget().toPlainText())
91
92    def testConsole(self):
93        """
94        Test the docked QtConsole
95        """
96        # Invoke the console action
97        self.manager.actionPython_Shell_Editor()
98
99        # Test the widegt properties
100        self.assertIsInstance(self.manager.ipDockWidget, QDockWidget)
101        self.assertIsInstance(self.manager.ipDockWidget.widget(), IPythonWidget)
102        self.assertEqual(self.manager._workspace.dockWidgetArea(self.manager.ipDockWidget), Qt.RightDockWidgetArea)
103
104    def testUpdatePerspective(self):
105        """
106        """
107        pass
108
109    def testUpdateStatusBar(self):
110        """
111        """
112        pass
113
114    def testSetData(self):
115        """
116        """
117        pass
118
119    def testQuitApplication(self):
120        """
121        Test that the custom exit method is called on shutdown
122        """
123        self.manager._workspace.show()
124
125        # Must mask sys.exit, otherwise the whole testing process stops.
126        sys.exit = MagicMock()
127
128        # Say No to the close dialog
129        QMessageBox.question = MagicMock(return_value=QMessageBox.No)
130
131        # Open, then close the manager
132        self.manager.quitApplication()
133
134        # See that the MessageBox method got called
135        #self.assertTrue(QMessageBox.question.called)
136
137        # Say Yes to the close dialog
138        QMessageBox.question = MagicMock(return_value=QMessageBox.Yes)
139
140        # Open, then close the manager
141        self.manager.quitApplication()
142
143        # See that the MessageBox method got called
144        #self.assertTrue(QMessageBox.question.called)
145
146    def testCheckUpdate(self):
147        """
148        Tests the SasView website version polling
149        """
150        self.manager.processVersion = MagicMock()
151        version = {'update_url'  : 'http://www.sasview.org/sasview.latestversion', 
152                   'version'     : '4.1.2',
153                   'download_url': 'https://github.com/SasView/sasview/releases'}
154        self.manager.checkUpdate()
155
156        self.manager.processVersion.assert_called_with(version)
157
158        pass
159
160    def testProcessVersion(self):
161        """
162        Tests the version checker logic
163        """
164        # 1. version = 0.0.0
165        version_info = {'version' : '0.0.0'}
166        spy_status_update = QtSignalSpy(self.manager, self.manager.communicate.statusBarUpdateSignal)
167
168        self.manager.processVersion(version_info)
169
170        self.assertEqual(spy_status_update.count(), 1)
171        message = 'Could not connect to the application server. Please try again later.'
172        self.assertIn(message, str(spy_status_update.signal(index=0)))
173
174        # 2. version < LocalConfig.__version__
175        version_info = {'version' : '0.0.1'}
176        spy_status_update = QtSignalSpy(self.manager, self.manager.communicate.statusBarUpdateSignal)
177
178        self.manager.processVersion(version_info)
179
180        self.assertEqual(spy_status_update.count(), 1)
181        message = 'You have the latest version of SasView'
182        self.assertIn(message, str(spy_status_update.signal(index=0)))
183
184        # 3. version > LocalConfig.__version__
185        version_info = {'version' : '999.0.0'}
186        spy_status_update = QtSignalSpy(self.manager, self.manager.communicate.statusBarUpdateSignal)
187        webbrowser.open = MagicMock()
188
189        self.manager.processVersion(version_info)
190
191        self.assertEqual(spy_status_update.count(), 1)
192        message = 'Version 999.0.0 is available!'
193        self.assertIn(message, str(spy_status_update.signal(index=0)))
194
195        webbrowser.open.assert_called_with("https://github.com/SasView/sasview/releases")
196
197        # 4. couldn't load version
198        version_info = {}
199        logging.error = MagicMock()
200        spy_status_update = QtSignalSpy(self.manager, self.manager.communicate.statusBarUpdateSignal)
201
202        self.manager.processVersion(version_info)
203
204        # Retrieve and compare arguments of the mocked call
205        message = "guiframe: could not get latest application version number"
206        args, _ = logging.error.call_args
207        self.assertIn(message, args[0])
208
209        # Check the signal message
210        message = 'Could not connect to the application server.'
211        self.assertIn(message, str(spy_status_update.signal(index=0)))
212
213    def testActions(self):
214        """
215        """
216        pass
217
218    #### FILE ####
219    def testActionLoadData(self):
220        """
221        Menu File/Load Data File(s)
222        """
223        # Mock the system file open method
224        QFileDialog.getOpenFileNames = MagicMock(return_value=('',''))
225
226        # invoke the action
227        self.manager.actionLoadData()
228
229        # Test the getOpenFileName() dialog called once
230        self.assertTrue(QFileDialog.getOpenFileNames.called)
231
232    def testActionLoadDataFolder(self):
233        """
234        Menu File/Load Data Folder
235        """
236        # Mock the system file open method
237        QFileDialog.getExistingDirectory = MagicMock(return_value=('',''))
238
239        # invoke the action
240        self.manager.actionLoad_Data_Folder()
241
242        # Test the getOpenFileName() dialog called once
243        self.assertTrue(QFileDialog.getExistingDirectory.called)
244
245    #### VIEW ####
246    def testActionHideToolbar(self):
247        """
248        Menu View/Hide Toolbar
249        """
250        # Need to display the main window to initialize the toolbar.
251        self.manager._workspace.show()
252
253        # Check the initial state
254        self.assertTrue(self.manager._workspace.toolBar.isVisible())
255        self.assertEqual('Hide Toolbar', self.manager._workspace.actionHide_Toolbar.text())
256
257        # Invoke action
258        self.manager.actionHide_Toolbar()
259
260        # Assure changes propagated correctly
261        self.assertFalse(self.manager._workspace.toolBar.isVisible())
262        self.assertEqual('Show Toolbar', self.manager._workspace.actionHide_Toolbar.text())
263
264        # Revert
265        self.manager.actionHide_Toolbar()
266
267        # Assure the original values are back
268        self.assertTrue(self.manager._workspace.toolBar.isVisible())
269        self.assertEqual('Hide Toolbar', self.manager._workspace.actionHide_Toolbar.text())
270
271
272    #### HELP ####
273    # test when PyQt5 works with html
274    def testActionDocumentation(self):
275        """
276        Menu Help/Documentation
277        """
278        webbrowser.open = MagicMock()
279
280        # Invoke the action
281        self.manager.actionDocumentation()
282
283        # see that webbrowser open was attempted
284        webbrowser.open.assert_called_once()
285
286
287    def skip_testActionTutorial(self):
288        """
289        Menu Help/Tutorial
290        """
291        # Mock subprocess.Popen
292        subprocess.Popen = MagicMock()
293
294        tested_location = self.manager._tutorialLocation
295
296        # Assure the filename is correct
297        self.assertIn("Tutorial.pdf", tested_location)
298
299        # Invoke the action
300        self.manager.actionTutorial()
301
302        # Check if popen() got called
303        self.assertTrue(subprocess.Popen.called)
304
305        #Check the popen() call arguments
306        subprocess.Popen.assert_called_with([tested_location], shell=True)
307
308    def testActionAcknowledge(self):
309        """
310        Menu Help/Acknowledge
311        """
312        self.manager.actionAcknowledge()
313
314        # Check if the window is actually opened.
315        self.assertTrue(self.manager.ackWidget.isVisible())
316        self.assertIn("developers@sasview.org", self.manager.ackWidget.label.text())
317
318    def testActionCheck_for_update(self):
319        """
320        Menu Help/Check for update
321        """
322        # Just make sure checkUpdate is called.
323        self.manager.checkUpdate = MagicMock()
324
325        self.manager.actionCheck_for_update()
326
327        self.assertTrue(self.manager.checkUpdate.called)
328             
329       
330if __name__ == "__main__":
331    unittest.main()
332
Note: See TracBrowser for help on using the repository browser.