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

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

Unit test update after latest round of commits.

  • Property mode set to 100644
File size: 10.7 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._workspace.dockWidgetArea(self.manager.dockedFilesWidget), Qt.LeftDockWidgetArea)
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
61        self.assertIsInstance(self.manager.ackWidget, Acknowledgements)
62        self.assertIsInstance(self.manager.aboutWidget, AboutBox)
63        #self.assertIsInstance(self.manager.welcomePanel, WelcomePanel)
64
65    def skip_testLogging(self):
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"
75        print(message)
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
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
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
117    def testQuitApplication(self):
118        """
119        Test that the custom exit method is called on shutdown
120        """
121        self.manager._workspace.show()
122
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
133        #self.assertTrue(QMessageBox.question.called)
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
142        #self.assertTrue(QMessageBox.question.called)
143
144    def testCheckUpdate(self):
145        """
146        Tests the SasView website version polling
147        """
148        self.manager.processVersion = MagicMock()
149        version = {'version'     : '4.2.1',
150                   'update_url'  : 'http://www.sasview.org/sasview.latestversion', 
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
163        version_info = {'version' : '0.0.0'}
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__
173        version_info = {'version' : '0.0.1'}
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__
183        version_info = {'version' : '999.0.0'}
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
195        # 4. couldn't load version
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
211    def testActions(self):
212        """
213        """
214        pass
215
216    #### FILE ####
217    def testActionLoadData(self):
218        """
219        Menu File/Load Data File(s)
220        """
221        # Mock the system file open method
222        QFileDialog.getOpenFileNames = MagicMock(return_value=('',''))
223
224        # invoke the action
225        self.manager.actionLoadData()
226
227        # Test the getOpenFileName() dialog called once
228        self.assertTrue(QFileDialog.getOpenFileNames.called)
229
230    def testActionLoadDataFolder(self):
231        """
232        Menu File/Load Data Folder
233        """
234        # Mock the system file open method
235        QFileDialog.getExistingDirectory = MagicMock(return_value=('',''))
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
252        self.assertFalse(self.manager._workspace.toolBar.isVisible())
253        self.assertEqual('Show Toolbar', self.manager._workspace.actionHide_Toolbar.text())
254
255        # Invoke action
256        self.manager.actionHide_Toolbar()
257
258        # Assure changes propagated correctly
259        self.assertTrue(self.manager._workspace.toolBar.isVisible())
260        self.assertEqual('Hide Toolbar', self.manager._workspace.actionHide_Toolbar.text())
261
262        # Revert
263        self.manager.actionHide_Toolbar()
264
265        # Assure the original values are back
266        self.assertFalse(self.manager._workspace.toolBar.isVisible())
267        self.assertEqual('Show Toolbar', self.manager._workspace.actionHide_Toolbar.text())
268
269
270    #### HELP ####
271    # test when PyQt5 works with html
272    def testActionDocumentation(self):
273        """
274        Menu Help/Documentation
275        """
276        webbrowser.open = MagicMock()
277
278        # Invoke the action
279        self.manager.actionDocumentation()
280
281        # see that webbrowser open was attempted
282        webbrowser.open.assert_called_once()
283
284
285    def skip_testActionTutorial(self):
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        """
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_3.text())
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()
324
325        self.assertTrue(self.manager.checkUpdate.called)
326             
327       
328if __name__ == "__main__":
329    unittest.main()
330
Note: See TracBrowser for help on using the repository browser.