source: sasview/src/sas/qtgui/MainWindow/UnitTesting/GuiManagerTest.py @ 53c771e

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 53c771e was 53c771e, checked in by Piotr Rozyczko <rozyczko@…>, 6 years ago

Converted unit tests

  • Property mode set to 100755
File size: 11.0 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
21#from 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 notestActionDocumentation(self):
275        """
276        Menu Help/Documentation
277        """
278        #Mock the QWebView method
279        QWebView.show = MagicMock()
280
281        # Assure the filename is correct
282        self.assertIn("index.html", self.manager._helpLocation)
283
284        # Invoke the action
285        self.manager.actionDocumentation()
286
287        # Check if show() got called
288        self.assertTrue(QWebView.show.called)
289
290    def skip_testActionTutorial(self):
291        """
292        Menu Help/Tutorial
293        """
294        # Mock subprocess.Popen
295        subprocess.Popen = MagicMock()
296
297        tested_location = self.manager._tutorialLocation
298
299        # Assure the filename is correct
300        self.assertIn("Tutorial.pdf", tested_location)
301
302        # Invoke the action
303        self.manager.actionTutorial()
304
305        # Check if popen() got called
306        self.assertTrue(subprocess.Popen.called)
307
308        #Check the popen() call arguments
309        subprocess.Popen.assert_called_with([tested_location], shell=True)
310
311    def testActionAcknowledge(self):
312        """
313        Menu Help/Acknowledge
314        """
315        self.manager.actionAcknowledge()
316
317        # Check if the window is actually opened.
318        self.assertTrue(self.manager.ackWidget.isVisible())
319        self.assertIn("developers@sasview.org", self.manager.ackWidget.label.text())
320
321    def testActionCheck_for_update(self):
322        """
323        Menu Help/Check for update
324        """
325        # Just make sure checkUpdate is called.
326        self.manager.checkUpdate = MagicMock()
327
328        self.manager.actionCheck_for_update()
329
330        self.assertTrue(self.manager.checkUpdate.called)
331             
332       
333if __name__ == "__main__":
334    unittest.main()
335
Note: See TracBrowser for help on using the repository browser.