source: sasview/src/sas/qtgui/MainWindow/UnitTesting/GuiManagerTest.py @ 32f6cdd

ESS_GUIESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalc
Last change on this file since 32f6cdd was 725d9c06, checked in by Piotr Rozyczko <rozyczko@…>, 7 years ago

More code review changes

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