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
RevLine 
[488c49d]1import sys
[9e426c1]2import subprocess
[488c49d]3import unittest
[9e426c1]4import webbrowser
5import logging
[488c49d]6
[53c771e]7from PyQt5.QtGui import *
8from PyQt5.QtWidgets import *
9from PyQt5.QtTest import QTest
10from PyQt5.QtCore import *
11from PyQt5.QtWebKit import *
[7fb471d]12from unittest.mock import MagicMock
[488c49d]13
[31c5b58]14# set up import paths
15import path_prepare
16
[488c49d]17# Local
[83eb5208]18from sas.qtgui.MainWindow.DataExplorer import DataExplorerWindow
19from sas.qtgui.MainWindow.AboutBox import AboutBox
20from sas.qtgui.MainWindow.WelcomePanel import WelcomePanel
[8353d90]21from sas.qtgui.Utilities.IPythonWidget import IPythonWidget
[e540cd2]22
[83eb5208]23from sas.qtgui.MainWindow.GuiManager import Acknowledgements, GuiManager
24from sas.qtgui.MainWindow.MainWindow import MainSasViewWindow
25from sas.qtgui.UnitTesting.TestUtils import QtSignalSpy
[488c49d]26
[464cd07]27if not QApplication.instance():
28    app = QApplication(sys.argv)
[488c49d]29
30class GuiManagerTest(unittest.TestCase):
[5032ea68]31    '''Test the Main Window functionality'''
[488c49d]32    def setUp(self):
33        '''Create the tested object'''
[0fc37fea]34        class MainWindow(MainSasViewWindow):
[5032ea68]35            # Main window of the application
36            def __init__(self, reactor, parent=None):
[0fc37fea]37                super(MainWindow, self).__init__(parent)
[5032ea68]38       
39                # define workspace for dialogs.
[53c771e]40                self.workspace = QMdiArea(self)
[5032ea68]41                self.setCentralWidget(self.workspace)
[488c49d]42
[6fd4e36]43        self.manager = GuiManager(MainWindow(None))
[488c49d]44
45    def tearDown(self):
46        '''Destroy the GUI'''
47        self.manager = None
48
49    def testDefaults(self):
[e540cd2]50        """
51        Test the object in its default state
52        """
53        self.assertIsInstance(self.manager.filesWidget, DataExplorerWindow)
54        self.assertIsInstance(self.manager.dockedFilesWidget, QDockWidget)
[0cd8612]55        self.assertIsInstance(self.manager.dockedFilesWidget.widget(), DataExplorerWindow)
[e540cd2]56        self.assertEqual(self.manager.dockedFilesWidget.features(), QDockWidget.NoDockWidgetFeatures)
57        self.assertEqual(self.manager._workspace.dockWidgetArea(self.manager.dockedFilesWidget), Qt.LeftDockWidgetArea)
[0cd8612]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
[e540cd2]63        self.assertIsInstance(self.manager.ackWidget, Acknowledgements)
64        self.assertIsInstance(self.manager.aboutWidget, AboutBox)
65        self.assertIsInstance(self.manager.welcomePanel, WelcomePanel)
66
[31c5b58]67    def skip_testLogging(self):
[0cd8612]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"
[7fb471d]77        print(message)
[0cd8612]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
[ff49d4d]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
[488c49d]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
[9e426c1]119    def testQuitApplication(self):
120        """
121        Test that the custom exit method is called on shutdown
122        """
[64f1e93]123        self.manager._workspace.show()
124
[9e426c1]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
[6fd4e36]135        #self.assertTrue(QMessageBox.question.called)
[9e426c1]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
[6fd4e36]144        #self.assertTrue(QMessageBox.question.called)
[9e426c1]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', 
[8222f171]152                   'version'     : '4.1.2',
[9e426c1]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
[7fb471d]165        version_info = {'version' : '0.0.0'}
[9e426c1]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__
[7fb471d]175        version_info = {'version' : '0.0.1'}
[9e426c1]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__
[7fb471d]185        version_info = {'version' : '999.0.0'}
[9e426c1]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
[e540cd2]197        # 4. couldn't load version
[9e426c1]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
[488c49d]213    def testActions(self):
214        """
215        """
216        pass
217
[e540cd2]218    #### FILE ####
[5032ea68]219    def testActionLoadData(self):
220        """
221        Menu File/Load Data File(s)
222        """
223        # Mock the system file open method
[53c771e]224        QFileDialog.getOpenFileNames = MagicMock(return_value=('',''))
[5032ea68]225
226        # invoke the action
[9e426c1]227        self.manager.actionLoadData()
[5032ea68]228
229        # Test the getOpenFileName() dialog called once
[9e426c1]230        self.assertTrue(QFileDialog.getOpenFileNames.called)
[e540cd2]231
232    def testActionLoadDataFolder(self):
233        """
234        Menu File/Load Data Folder
235        """
236        # Mock the system file open method
[53c771e]237        QFileDialog.getExistingDirectory = MagicMock(return_value=('',''))
[e540cd2]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 ####
[53c771e]273    # test when PyQt5 works with html
[14ec91c5]274    def testActionDocumentation(self):
[9e426c1]275        """
276        Menu Help/Documentation
277        """
[14ec91c5]278        webbrowser.open = MagicMock()
[9e426c1]279
280        # Invoke the action
281        self.manager.actionDocumentation()
282
[14ec91c5]283        # see that webbrowser open was attempted
284        webbrowser.open.assert_called_once()
285
[9e426c1]286
[31c5b58]287    def skip_testActionTutorial(self):
[9e426c1]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        """
[f82ab8c]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())
[9e426c1]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()
[5032ea68]326
[9e426c1]327        self.assertTrue(self.manager.checkUpdate.called)
328             
[488c49d]329       
330if __name__ == "__main__":
331    unittest.main()
332
Note: See TracBrowser for help on using the repository browser.