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

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 e90988c was 8353d90, checked in by Piotr Rozyczko <rozyczko@…>, 7 years ago

Assure the main window opens maximized and the welcome widget doesnt mess up the layout. SASVIEW-831

  • Property mode set to 100644
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
21from 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.