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

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

More code review changes

  • Property mode set to 100644
File size: 10.8 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.dockedFilesWidget.features(), QDockWidget.NoDockWidgetFeatures)
56        self.assertEqual(self.manager._workspace.dockWidgetArea(self.manager.dockedFilesWidget), Qt.LeftDockWidgetArea)
[0cd8612]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
[e540cd2]62        self.assertIsInstance(self.manager.ackWidget, Acknowledgements)
63        self.assertIsInstance(self.manager.aboutWidget, AboutBox)
64        self.assertIsInstance(self.manager.welcomePanel, WelcomePanel)
65
[31c5b58]66    def skip_testLogging(self):
[0cd8612]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"
[7fb471d]76        print(message)
[0cd8612]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
[ff49d4d]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
[488c49d]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
[9e426c1]118    def testQuitApplication(self):
119        """
120        Test that the custom exit method is called on shutdown
121        """
[64f1e93]122        self.manager._workspace.show()
123
[9e426c1]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
[6fd4e36]134        #self.assertTrue(QMessageBox.question.called)
[9e426c1]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
[6fd4e36]143        #self.assertTrue(QMessageBox.question.called)
[9e426c1]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', 
[8222f171]151                   'version'     : '4.1.2',
[9e426c1]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
[7fb471d]164        version_info = {'version' : '0.0.0'}
[9e426c1]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__
[7fb471d]174        version_info = {'version' : '0.0.1'}
[9e426c1]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__
[7fb471d]184        version_info = {'version' : '999.0.0'}
[9e426c1]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
[e540cd2]196        # 4. couldn't load version
[9e426c1]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
[488c49d]212    def testActions(self):
213        """
214        """
215        pass
216
[e540cd2]217    #### FILE ####
[5032ea68]218    def testActionLoadData(self):
219        """
220        Menu File/Load Data File(s)
221        """
222        # Mock the system file open method
[53c771e]223        QFileDialog.getOpenFileNames = MagicMock(return_value=('',''))
[5032ea68]224
225        # invoke the action
[9e426c1]226        self.manager.actionLoadData()
[5032ea68]227
228        # Test the getOpenFileName() dialog called once
[9e426c1]229        self.assertTrue(QFileDialog.getOpenFileNames.called)
[e540cd2]230
231    def testActionLoadDataFolder(self):
232        """
233        Menu File/Load Data Folder
234        """
235        # Mock the system file open method
[53c771e]236        QFileDialog.getExistingDirectory = MagicMock(return_value=('',''))
[e540cd2]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 ####
[53c771e]272    # test when PyQt5 works with html
[14ec91c5]273    def testActionDocumentation(self):
[9e426c1]274        """
275        Menu Help/Documentation
276        """
[14ec91c5]277        webbrowser.open = MagicMock()
[9e426c1]278
279        # Invoke the action
280        self.manager.actionDocumentation()
281
[14ec91c5]282        # see that webbrowser open was attempted
283        webbrowser.open.assert_called_once()
284
[9e426c1]285
[31c5b58]286    def skip_testActionTutorial(self):
[9e426c1]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        """
[f82ab8c]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())
[9e426c1]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()
[5032ea68]325
[9e426c1]326        self.assertTrue(self.manager.checkUpdate.called)
327             
[488c49d]328       
329if __name__ == "__main__":
330    unittest.main()
331
Note: See TracBrowser for help on using the repository browser.