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

ESS_GUIESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalc
Last change on this file since fa762f4 was fa762f4, checked in by Piotr Rozyczko <piotr.rozyczko@…>, 6 years ago

Fixed lifecycle/visibility of the Grid Viewer SASVIEW-1122

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